Skip to content

image save: make output tarball OCI compliant#44598

Merged
thaJeztah merged 2 commits intomoby:masterfrom
cpuguy83:save_tar_oci
Jun 9, 2023
Merged

image save: make output tarball OCI compliant#44598
thaJeztah merged 2 commits intomoby:masterfrom
cpuguy83:save_tar_oci

Conversation

@cpuguy83
Copy link
Copy Markdown
Member

@cpuguy83 cpuguy83 commented Dec 7, 2022

  • Moves blobs for the tarball into the OCI compliant paths (blobs/<alg>/<digest>)
  • Removes old VERSION file which has no meaning and can't be used anyway in the new format
  • Adds oci-layout, oci manifest, and index files to the outputted tars

For the new files this just goes ahead and uses OCI media types (instead of old docker types) since these are new and should not break anything.

All this works because the old docker layout is dependent on the manifest.json file at the root of the tar which has paths to each of the blobs in the tarball. The change updates the paths in the manifest to point to the new paths.

This is the same technique used by buildkit to support both OCI tar formats as well as legacy docker ones.

@cpuguy83 cpuguy83 requested review from tianon and tonistiigi December 7, 2022 00:25
@thaJeztah
Copy link
Copy Markdown
Member

Looks like there's some tests to adjust (or perhaps separate tests)

=== FAIL: amd64.integration-cli TestDockerCLISaveLoadSuite/TestSaveCheckTimes (0.04s)
    docker_cli_save_load_test.go:127: assertion failed: error is not nil: exit status 1: failed to save repo with image ID and 'repositories' file: , exit status 1
    --- FAIL: TestDockerCLISaveLoadSuite/TestSaveCheckTimes (0.04s)

=== FAIL: amd64.integration-cli TestDockerCLISaveLoadSuite/TestSaveDirectoryPermissions (0.79s)
    docker_cli_save_load_test.go:302: assertion failed: error is not nil: open /tmp/save-layers-with-directories3203220919/image-extraction-dir/blobs/layer.tar: no such file or directory: failed to open /tmp/save-layers-with-directories3203220919/image-extraction-dir/blobs/layer.tar: open /tmp/save-layers-with-directories3203220919/image-extraction-dir/blobs/layer.tar: no such file or directory
    --- FAIL: TestDockerCLISaveLoadSuite/TestSaveDirectoryPermissions (0.79s)

=== FAIL: amd64.integration-cli TestDockerCLISaveLoadSuite/TestSaveRepoWithMultipleImages (0.84s)
    docker_cli_save_load_test.go:266: assertion failed: 
        --- actual
        +++ expected
          []string(
        - 	nil,
        + 	{
        + 		"1c35c441208254cb7c3844ba95a96485388cef9ccc0646d562c7fc026e04c807",
        + 		"af4544b16613a2573c47ad04472359062ae9a0968bd5cfb9fe271861df9fe286",
        + 		"c4305557e19f493d6f6eec7a544c2ae248ab17528a8b34fe9339cba8d70059e4",
        + 	},
          )
        : archive does not contains the right layers: got [], expected [1c35c441208254cb7c3844ba95a96485388cef9ccc0646d562c7fc026e04c807 af4544b16613a2573c47ad04472359062ae9a0968bd5cfb9fe271861df9fe286 c4305557e19f493d6f6eec7a544c2ae248ab17528a8b34fe9339cba8d70059e4], output: "sha256:1c35c441208254cb7c3844ba95a96485388cef9ccc0646d562c7fc026e04c807"
    --- FAIL: TestDockerCLISaveLoadSuite/TestSaveRepoWithMultipleImages (0.84s)

ociLayoutFilename = "oci-layout"
ociLayoutContent = `{"imageLayoutVersion": "1.0.0"}`
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just use https://github.com/containerd/containerd/blob/main/images/archive/exporter.go ?
For containerd-integration mode.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that's the plan.

Copy link
Copy Markdown
Member

@tianon tianon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks OK to me! I made a couple minor comments, but I don't think it's anything very serious. I'm both looking forward to having/using this and to this code going away with the containerd integration. 😄

Comment thread image/tarexport/save.go Outdated
Comment thread image/tarexport/save.go
Comment thread image/tarexport/save.go Outdated
This moves the blobs around so they follow the OCI spec.
Note that because docker reads paths from the manifest.json inside the
tar this is not a breaking change.

This does, however, remove the old layer "VERSION" file which had a big
"why is this even here" in the code comments. I suspect it does not
matter at all even for really old versions of Docker. In any case it is
a useless file for any even relatively modern version of Docker.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
@cpuguy83 cpuguy83 force-pushed the save_tar_oci branch 4 times, most recently from f8f7e23 to 8c5db61 Compare May 24, 2023 01:16
assert.NilError(c, err, "failed to save repo with image ID and 'repositories' file: %s, %v", out, err)
}

func (s *DockerCLISaveLoadSuite) TestSaveCheckTimes(c *testing.T) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, these tests were incorrectly poking at the saved tarball (assuming a file location instead of looking at the manifest).
I had to do major surgery on these so I just moved them over to integration/.

Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through some of the changes (but perhaps need to take another look later); left some comments / suggestions / questions inline, but overall looking 👍

Comment thread integration/image/save_test.go
f, err := tarfs.Open(p)
assert.NilError(t, err)

entries, err := listTar(f)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if this listTar could (not for this PR) also handled by your tar2go (fs.Glob(tarfs, "dev/*") and/or fs.WalkDir(tarfs)) 🤩

Comment thread image/tarexport/save.go Outdated
Comment thread image/image.go Outdated
Comment thread image/image.go
Comment thread image/tarexport/save.go Outdated
Comment thread image/tarexport/save.go Outdated
Comment thread image/tarexport/save.go Outdated
Comment thread image/tarexport/save.go Outdated
This makes the output of `docker save` fully OCI compliant.

When using the containerd image store, this code is not used. That
exporter will just use containerd's export method and should give us the
output we want for multi-arch images.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
@cpuguy83
Copy link
Copy Markdown
Member Author

This is all updated.

Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread image/tarexport/save.go
Size: int64(len(imageDescr.image.RawJSON())),
Platform: &imgPlat,
},
Layers: foreign,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-foreign layers were accidentally dropped?

tixxdz added a commit to cilium/tetragon that referenced this pull request Feb 28, 2024
Starting from Docker 25.0 , the save command will dump the image
layers in OCI compatible format: moby/moby#44598

This breaks our tarball build that was using the 'layer.tar' file to
contruct the final tarball.

Let's make the target a bit smart so it can handle all variants by
parsing the docker manifest.json file to find the layer and use it.

The 'make tarball' now requires jq for simplicity.

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
tixxdz added a commit to cilium/tetragon that referenced this pull request Feb 28, 2024
Starting from Docker 25.0 , the save command will dump the image
layers in OCI compatible format: moby/moby#44598

This breaks our tarball build that was using the 'layer.tar' file to
construct the final tarball.

Let's make the target a bit smart so it can handle all variants by
parsing the docker manifest.json file to find the layer and use it.

The 'make tarball' now requires jq for simplicity.

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
tixxdz added a commit to cilium/tetragon that referenced this pull request Feb 28, 2024
Starting from Docker 25.0 , the save command will dump the image
layers in OCI compatible format: moby/moby#44598

This breaks our tarball build that was using the 'layer.tar' file to
construct the final tarball.

Let's make the target a bit smart so it can handle all variants by
parsing the docker manifest.json file to find the layer and use it.

The 'make tarball' now requires jq for simplicity.

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
tixxdz added a commit to cilium/tetragon that referenced this pull request Jun 24, 2024
[ Upstream main 5cc9bce ]

Starting from Docker 25.0 , the save command will dump the image
layers in OCI compatible format: moby/moby#44598

This breaks our tarball build that was using the 'layer.tar' file to
construct the final tarball.

Let's make the target a bit smart so it can handle all variants by
parsing the docker manifest.json file to find the layer and use it.

The 'make tarball' now requires jq for simplicity.

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
tixxdz added a commit to cilium/tetragon that referenced this pull request Jun 24, 2024
[ Upstream main 5cc9bce ]

Starting from Docker 25.0 , the save command will dump the image
layers in OCI compatible format: moby/moby#44598

This breaks our tarball build that was using the 'layer.tar' file to
construct the final tarball.

Let's make the target a bit smart so it can handle all variants by
parsing the docker manifest.json file to find the layer and use it.

The 'make tarball' now requires jq for simplicity.

Signed-off-by: Djalal Harouni <tixxdz@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants