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
daemon: allow setting OCI annotations on containers #45025
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
ed04ebe
to
9141b45
Compare
This comment was marked as outdated.
This comment was marked as 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.
And does this mean that an image containing these labels will set them at runtime on the container?
Yes. This could arguably be a feature.
This looks like an attack vector.
Specifying annotations should require a new API/CLI like
docker run --annotation=com.example.foo=bar
.
(similar to podman run --annotation
)
9141b45
to
45a23c1
Compare
45a23c1
to
a2aa9c3
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.
SGTM
But need to update the API history doc and openapi yaml.
Signed-off-by: Cory Snider <csnider@mirantis.com>
a2aa9c3
to
8656719
Compare
if hostConfig != nil && versions.LessThan(version, "1.43") { | ||
// Ignore OCIAnnotations because it was added in API v1.43. | ||
hostConfig.OCIAnnotations = nil | ||
} |
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'm following past precedent by ignoring the field on create for older API versions but unconditionally including it in the /containers/{}/json
response for all API versions.
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.
("requesting changes" just to have a quick check per my comment - changes otherwise look good to me)
api/types/container/hostconfig.go
Outdated
VolumeDriver string // Name of the volume driver used to mount volumes | ||
VolumesFrom []string // List of volumes to take from other container | ||
ConsoleSize [2]uint // Initial console size (height,width) | ||
OCIAnnotations map[string]string `json:",omitempty"` // Annotations to pass along to OCI runtime |
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.
Before we merge; quick check on the naming. Wondering if OCI
prefix is needed in our API here. I get where we're coming from; mostly thinking along the lines of "(almost) every option we have in our API leads to <something>
OCI spec.
So wondering if we should keep the abstraction - call it Annotations
, and keep the fact that that (currently) gets passed on to the OCI to the description only.
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'm coming around to dropping the OCI
prefix and adopting essentially the same semantics as Kubernetes Annotations
. And by that I mean documenting that Engine API clients can also leverage annotations to attach and consume metadata on containers for their own purposes. Perhaps we should also follow their lead and enforce a particular syntax for annotation keys so that the namespace of an annotation is unambiguous. We could always loosen validation later but can't make it more restrictive.
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.
Let's discuss / brainstorm in the call later Today (I also need to get my head around all of that). Quick comment;
- Yes, I think Annotations could be useful for "our side" as well
- I like namespaces / prefixes as they can definitely help prevent ambiguity (I think I may actually have been the one originally getting them into the "labels" definition 🤔 )
- ^^^ w.r.t. namespaces: I always keep in the back of my mind that
API !== UX
; namespaces are awkward to use, but are (in most cases) not meant for humans. So if we decide to use namespaces, we can still make the UX "different" (docker run --foo=bar
doingdocker run --annotation=awkwardly-long-namespace.option=bar
behind the scenes)
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 I like about how K8s goes about namespacing annotations is that it makes namespace prefixes optional and reserves the no-namespace "namespace" for users.
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.
Yup, that was part of my original suggestion for labels; no-namespace is for users; don't use them for automation as they can easily conflict. For automation / tools, always use a prefix
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.
For those interested; here's the PR with all the fun (well, there's been multiple before that, but that's the one that made it, and that one is already 200+ comments 🤣)
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.
Decisions from today's maintainer call:
- Drop the
OCI
prefix from the field name - Any annotation which is valid per the OCI Runtime spec is permitted
- Keys can be any JSON string except for the empty string
- Values can be any JSON string, including the empty string
- Keys and values can be arbitrarily long
Allow clients to set annotations on a container which will applied to the container's OCI spec. Signed-off-by: Cory Snider <csnider@mirantis.com>
8656719
to
0ffaa6c
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.
LGTM, thanks!
@@ -305,6 +305,11 @@ func validateHostConfig(hostConfig *containertypes.HostConfig) error { | |||
if !hostConfig.Isolation.IsValid() { | |||
return errors.Errorf("invalid isolation '%s' on %s", hostConfig.Isolation, runtime.GOOS) | |||
} | |||
for k := range hostConfig.Annotations { | |||
if k == "" { | |||
return errors.Errorf("invalid Annotations: the empty string is not permitted as an annotation key") |
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 had a look if we should be using an errdefs.InvalidParameter()
here (and noticed other errors didn't), but it looks like we wrap any errors returned here on the call sites, such as
Lines 65 to 68 in 2f0e308
warnings, err := daemon.verifyContainerSettings(opts.params.HostConfig, opts.params.Config, false) | |
if err != nil { | |
return containertypes.CreateResponse{Warnings: warnings}, errdefs.InvalidParameter(err) | |
} |
So in either case; it's good (currently) to not use an errdefs, but we could (should?) look at these at some points to assign error-types in these locations.
@cpuguy83 LGTY? (I see there's a "change requested" from you, and didn't want to dismiss it) |
@corhere Do you have a PR for the CLI? |
@AkihiroSuda no, I am not working on a CLI PR as my motivation is unblocking support for alternative runtimes in cri-dockerd. |
Opened a PR for the CLI: |
- What I did
Allow API clients to set and retrieve OCI annotations on a container.
- How I did it
Added a field to
HostConfig
and plumbed it into the OCI spec generation code.- How to verify it
Create a container with annotations and start it. Inspect the running container using
ctr
and verify that the annotations are listed in the container spec.A new integration test verifies that annotations can be round-tripped through the Engine API.
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)