-
Notifications
You must be signed in to change notification settings - Fork 604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for running container from OCI archive #3537
Add support for running container from OCI archive #3537
Conversation
bc97ccd
to
b3e38d1
Compare
If maintainers would prefer, I can break 79e4e24 into its own PR. The change was trivial at first before I added docs changes and integration test. LMK your thoughts. |
@@ -409,12 +409,17 @@ func processContainerCreateOptions(cmd *cobra.Command) (types.ContainerCreateOpt | |||
if err != nil { | |||
return opt, err | |||
} | |||
quiet, err := cmd.Flags().GetBool("quiet") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Docker or Podman have this flag?
Otherwise —pull-quiet might be less confusing? idk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏼 Opened #3551
Docker has --quiet across load, run, and create.
@@ -361,6 +363,33 @@ func runAction(cmd *cobra.Command, args []string) error { | |||
return err | |||
} | |||
|
|||
if imageRef := args[0]; strings.HasPrefix(imageRef, "oci-archive://") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be supported in nerdctl create
too (See ipfs:// code)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks will take a look.
|
||
// Running multi-image OCI archives is not yet supported. | ||
if len(images) != 1 { | ||
return errors.New("multiple images in OCI archive found") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about just defaulting to the first one? (With a warning)
func TestRunFromOCIArchive(t *testing.T) { | ||
testutil.RequiresBuild(t) | ||
testutil.RegisterBuildCacheCleanup(t) | ||
testutil.DockerIncompatible(t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a comment
docs/command-reference.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oci-archive:// needs docs too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in d669f3d. Added documentation for both create and run.
b3e38d1
to
2159e7f
Compare
Going to let this CI run finish before rebasing for #3551 |
d4a5e21
to
d669f3d
Compare
pkg/cmd/container/create.go
Outdated
@@ -123,6 +124,37 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa | |||
} | |||
opts = append(opts, platformOpts...) | |||
|
|||
if imageRef := args[0]; strings.HasPrefix(imageRef, "oci-archive://") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Protocol prefixes should be parsed in the same place as ipfs://
func Parse(rawRef string) (*ImageReference, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reference. I missed this when looking at the ipfs code.
d669f3d
to
006e403
Compare
006e403
to
971d297
Compare
Path: "/tmp/build/saved-image.tar", | ||
Error: "", | ||
String: "/tmp/build/saved-image.tar", | ||
Suggested: "oci-archive-/tmp/-abcde", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You likely need to do something for the suggested name of oci-archive://.
This suggested name is not valid for a container name (it is used when you do not specify a name for your container).
Maybe something in the line of:
func (ir *ImageReference) SuggestContainerName(suffix string) string {
name := "untitled"
if ir.Protocol != "" && ir.Domain == "" {
if ir.Protocol == OCIArchive {
name = string(ir.Protocol) + "-" + path.Base(ir.Path)[:shortIDLength]
}else{
name = string(ir.Protocol) + "-" + ir.String()[:shortIDLength]
}
} else if ir.Path != "" {
name = path.Base(ir.Path)
}
return name + "-" + suffix[:5]
}
... although that is likely not sufficient, as filesystem might allow characters that are not safe to use as image identifiers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we keep it simple and only suggest ‘oci-archive-container-id’ so that we do not have to deal with local path sanitization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @apostasie. Let me take another look here. We load the image from the archive before and reset the image ref to the name in the image manifest before calling parse again on that reference. I shouldn't have just made this test work though. Maybe it would be better to have another type for oci-archive image references which doesn't support suggested container name as it doesn't make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ll have a look around as well on how this is used.
thanks @austinvazquez !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be addressed with 4034998. @apostasie, I took another look and changed how I was looking at the problem. When parsing an raw image reference which is a path for an OCI archive, we should fail and let the caller (pkg/create
) know the reference is a path to an image archive and needs to be loaded before (re)parsing. This should resolve the quirkiness of having a image reference object which was not really a valid image reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, reading through - it is a bit weird indeed, because, yep, it is not really an image ref, it is a filesystem location... - I think it is ok as you put it now.
pkg/cmd/container/create.go
Outdated
image := images[0].Name | ||
// Multi-image archive provided, default to first image found. | ||
if len(images) != 1 { | ||
log.L.Warnf("multi-image OCI archive provided, defaulting to image %s...", image) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.L.Warnf("multi-image OCI archive provided, defaulting to image %s...", image) | |
log.L.Warnf("multiple images are found for the platform, defaulting to image %s...", image) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied in 932bfaf
pkg/imgutil/load/load.go
Outdated
if options.Input != "" { | ||
f, err := os.Open(options.Input) | ||
if err != nil { | ||
return []images.Image{}, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not return nil, err
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like I picked this up early in my Go learning (maybe a project I worked did this) but yeah looks like nil is recommended to avoid memory alloc. Will update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in d8ab512
Signed-off-by: Austin Vazquez <macedonv@amazon.com>
Signed-off-by: Austin Vazquez <macedonv@amazon.com>
932bfaf
to
4034998
Compare
containerName := testutil.Identifier(t) | ||
|
||
teardown := func() { | ||
base.Cmd("rm", containerName).Run() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-f
for both rm and rmi would be better in teardown.
imageName := testutil.Identifier(t) | ||
|
||
teardown := func() { | ||
base.Cmd("rmi", imageName).Run() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-f
@@ -273,6 +273,10 @@ func TestReferenceUtil(t *testing.T) { | |||
Tag: "latest", | |||
ExplicitTag: "", | |||
}, | |||
"oci-archive:///tmp/build/saved-image.tar": { | |||
Protocol: "oci-archive", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Protocol is not necessary here, since the test stops as it errors (and since your latest version does not set the protocol)
@austinvazquez thanks! - I left a few nits comments. |
Signed-off-by: Austin Vazquez <macedonv@amazon.com>
4034998
to
a4b2959
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
Issue
Proposal for #3536
Description
This change adds the ability to create and run containers from OCI archive without performing separate load step.
Testing
As this behavior is not provided by Docker, this change adds a nerdctl-only test for this behavior.