Merge pull request #45025 from corhere/oci-annotation-passthru

This commit is contained in:
Brian Goff 2023-02-24 16:27:11 +00:00 committed by GitHub
commit 0021339b92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 12219 additions and 11 deletions

View file

@ -563,6 +563,11 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
hostConfig.ConsoleSize = [2]uint{0, 0} hostConfig.ConsoleSize = [2]uint{0, 0}
} }
if hostConfig != nil && versions.LessThan(version, "1.43") {
// Ignore Annotations because it was added in API v1.43.
hostConfig.Annotations = nil
}
var platform *specs.Platform var platform *specs.Platform
if versions.GreaterThanOrEqualTo(version, "1.41") { if versions.GreaterThanOrEqualTo(version, "1.41") {
if v := r.Form.Get("platform"); v != "" { if v := r.Form.Get("platform"); v != "" {

View file

@ -377,16 +377,17 @@ type UpdateConfig struct {
// Portable information *should* appear in Config. // Portable information *should* appear in Config.
type HostConfig struct { type HostConfig struct {
// Applicable to all platforms // Applicable to all platforms
Binds []string // List of volume bindings for this container Binds []string // List of volume bindings for this container
ContainerIDFile string // File (path) where the containerId is written ContainerIDFile string // File (path) where the containerId is written
LogConfig LogConfig // Configuration of the logs for this container LogConfig LogConfig // Configuration of the logs for this container
NetworkMode NetworkMode // Network mode to use for the container NetworkMode NetworkMode // Network mode to use for the container
PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host
RestartPolicy RestartPolicy // Restart policy to be used for the container RestartPolicy RestartPolicy // Restart policy to be used for the container
AutoRemove bool // Automatically remove container when it exits AutoRemove bool // Automatically remove container when it exits
VolumeDriver string // Name of the volume driver used to mount volumes VolumeDriver string // Name of the volume driver used to mount volumes
VolumesFrom []string // List of volumes to take from other container VolumesFrom []string // List of volumes to take from other container
ConsoleSize [2]uint // Initial console size (height,width) ConsoleSize [2]uint // Initial console size (height,width)
Annotations map[string]string `json:",omitempty"` // Arbitrary non-identifying metadata attached to container and provided to the runtime
// Applicable to UNIX platforms // Applicable to UNIX platforms
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container CapAdd strslice.StrSlice // List of kernel capabilities to add to the container

View file

@ -305,6 +305,11 @@ func validateHostConfig(hostConfig *containertypes.HostConfig) error {
if !hostConfig.Isolation.IsValid() { if !hostConfig.Isolation.IsValid() {
return errors.Errorf("invalid isolation '%s' on %s", hostConfig.Isolation, runtime.GOOS) 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")
}
}
return nil return nil
} }

View file

@ -1026,6 +1026,7 @@ func (daemon *Daemon) createSpec(ctx context.Context, c *container.Container) (r
WithApparmor(c), WithApparmor(c),
WithSelinux(c), WithSelinux(c),
WithOOMScore(&c.HostConfig.OomScoreAdj), WithOOMScore(&c.HostConfig.OomScoreAdj),
coci.WithAnnotations(c.HostConfig.Annotations),
) )
if daemon.UsesSnapshotter() { if daemon.UsesSnapshotter() {
s.Root = &specs.Root{ s.Root = &specs.Root{

View file

@ -8,6 +8,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
coci "github.com/containerd/containerd/oci"
containertypes "github.com/docker/docker/api/types/container" containertypes "github.com/docker/docker/api/types/container"
imagetypes "github.com/docker/docker/api/types/image" imagetypes "github.com/docker/docker/api/types/image"
"github.com/docker/docker/container" "github.com/docker/docker/container"
@ -37,6 +38,10 @@ func (daemon *Daemon) createSpec(ctx context.Context, c *container.Container) (*
s := oci.DefaultSpec() s := oci.DefaultSpec()
if err := coci.WithAnnotations(c.HostConfig.Annotations)(ctx, nil, nil, &s); err != nil {
return nil, err
}
linkedEnv, err := daemon.setupLinkedContainers(c) linkedEnv, err := daemon.setupLinkedContainers(c)
if err != nil { if err != nil {
return nil, err return nil, err

12160
docs/api/v1.43.yaml Normal file

File diff suppressed because it is too large Load diff

View file

@ -17,7 +17,9 @@ keywords: "API, Docker, rcli, REST, documentation"
[Docker Engine API v1.43](https://docs.docker.com/engine/api/v1.43/) documentation [Docker Engine API v1.43](https://docs.docker.com/engine/api/v1.43/) documentation
* TODO add API changes for v1.43 here when they arrive. * `POST /containers/create` now accepts `Annotations` as part of `HostConfig`.
Can be used to attach arbitrary metadata to the container, which will also be
passed to the runtime when the container is started.
## v1.42 API changes ## v1.42 API changes

View file

@ -561,6 +561,11 @@ func TestCreateInvalidHostConfig(t *testing.T) {
hc: containertypes.HostConfig{UTSMode: "invalid"}, hc: containertypes.HostConfig{UTSMode: "invalid"},
expectedErr: "Error response from daemon: invalid UTS mode: invalid", expectedErr: "Error response from daemon: invalid UTS mode: invalid",
}, },
{
doc: "invalid Annotations",
hc: containertypes.HostConfig{Annotations: map[string]string{"": "a"}},
expectedErr: "Error response from daemon: invalid Annotations: the empty string is not permitted as an annotation key",
},
} }
for _, tc := range testCases { for _, tc := range testCases {

View file

@ -47,3 +47,27 @@ func TestInspectCpusetInConfigPre120(t *testing.T) {
_, ok = cfg["Cpuset"] _, ok = cfg["Cpuset"]
assert.Check(t, is.Equal(true, ok), "API version 1.19 expected to include Cpuset in 'Config'") assert.Check(t, is.Equal(true, ok), "API version 1.19 expected to include Cpuset in 'Config'")
} }
func TestInspectAnnotations(t *testing.T) {
defer setupTest(t)()
client := request.NewAPIClient(t)
ctx := context.Background()
annotations := map[string]string{
"hello": "world",
"foo": "bar",
}
name := strings.ToLower(t.Name())
id := container.Create(ctx, t, client,
container.WithName(name),
container.WithCmd("true"),
func(c *container.TestContainerConfig) {
c.HostConfig.Annotations = annotations
},
)
inspect, err := client.ContainerInspect(ctx, id)
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(inspect.HostConfig.Annotations, annotations))
}