c8d: Fix `docker diff`
- fixes https://github.com/moby/moby/issues/46607

**- What I did**

Diffing a container yielded some extra changes that come from the files/directories that we mount inside the container (/etc/resolv.conf for example). To avoid that we create an intermediate snapshot that has these files, with this we can now diff the container fs with its parent and only get the differences that were made inside the container.

**- How I did it**

Added a layer for the base snapshot of a container containing the files that are created by the runtime.

**- How to verify it**

Run `TestDiff`

```console
$ make DOCKER_GRAPHDRIVER=overlayfs TEST_FILTER=TestDiff TEST_INTEGRATION_USE_SNAPSHOTTER=1 TEST_IGNORE_CGROUP_CHECK=1 test-integration
```

**- Description for the changelog**
<!--
Write a short (one line) summary that describes the changes in this
pull request for inclusion in the changelog:
-->
- containerd integration: Fixed `docker diff` containing extra differences

**- A picture of a cute animal (not mandatory but encouraged)**


integration/container/diff_test.go
package container // import "github.com/docker/docker/integration/container"

import (
	"testing"
	"time"

	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/integration/internal/container"
	"gotest.tools/v3/assert"
	"gotest.tools/v3/poll"
	"gotest.tools/v3/skip"
)

func TestDiff(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
	ctx := setupTest(t)
	apiClient := testEnv.APIClient()

	cID := container.Run(ctx, t, apiClient, container.WithCmd("sh", "-c", `mkdir /foo; echo xyzzy > /foo/bar`))

	// Wait for it to exit as cannot diff a running container on Windows, and
	// it will take a few seconds to exit. Also there's no way in Windows to
	// differentiate between an Add or a Modify, and all files are under
	// a "Files/" prefix.
	expected := []containertypes.FilesystemChange{
		{Kind: containertypes.ChangeAdd, Path: "/foo"},
		{Kind: containertypes.ChangeAdd, Path: "/foo/bar"},
	}
	if testEnv.DaemonInfo.OSType == "windows" {
		poll.WaitOn(t, container.IsInState(ctx, apiClient, cID, "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(60*time.Second))
		expected = []containertypes.FilesystemChange{
			{Kind: containertypes.ChangeModify, Path: "Files/foo"},
			{Kind: containertypes.ChangeModify, Path: "Files/foo/bar"},
		}
	}

	items, err := apiClient.ContainerDiff(ctx, cID)
	assert.NilError(t, err)
	assert.DeepEqual(t, expected, items)
}

package container // import "github.com/docker/docker/integration/container"

import (
	"testing"
	"time"

	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/integration/internal/container"
	"gotest.tools/v3/assert"
	"gotest.tools/v3/poll"
	"gotest.tools/v3/skip"
)

func TestDiff(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "cannot diff a running container on Windows")
	ctx := setupTest(t)
	apiClient := testEnv.APIClient()

	cID := container.Run(ctx, t, apiClient, container.WithCmd("sh", "-c", `mkdir /foo; echo xyzzy > /foo/bar`))

	expected := []containertypes.FilesystemChange{
		{Kind: containertypes.ChangeAdd, Path: "/foo"},
		{Kind: containertypes.ChangeAdd, Path: "/foo/bar"},
	}

	items, err := apiClient.ContainerDiff(ctx, cID)
	assert.NilError(t, err)
	assert.DeepEqual(t, expected, items)
}

func TestDiffStoppedContainer(t *testing.T) {
	// There's no way in Windows to differentiate between an Add or a Modify,
	// and all files are under a "Files/" prefix.
	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
	ctx := setupTest(t)
	apiClient := testEnv.APIClient()

	cID := container.Run(ctx, t, apiClient, container.WithCmd("sh", "-c", `mkdir /foo; echo xyzzy > /foo/bar`))

	poll.WaitOn(t, container.IsInState(ctx, apiClient, cID, "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(60*time.Second))

	expected := []containertypes.FilesystemChange{
		{Kind: containertypes.ChangeAdd, Path: "/foo"},
		{Kind: containertypes.ChangeAdd, Path: "/foo/bar"},
	}
	if testEnv.DaemonInfo.OSType == "windows" {
		expected = []containertypes.FilesystemChange{
			{Kind: containertypes.ChangeModify, Path: "Files/foo"},
			{Kind: containertypes.ChangeModify, Path: "Files/foo/bar"},
		}
	}

	items, err := apiClient.ContainerDiff(ctx, cID)
	assert.NilError(t, err)
	assert.DeepEqual(t, expected, items)
}

> Would this comment still be useful (as it gives some context)?

It will yeah, I moved these tests a bit too much but yeah, the comment is useful