Merge pull request #45025 from corhere/oci-annotation-passthru
This commit is contained in:
commit
0021339b92
9 changed files with 12219 additions and 11 deletions
|
@ -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 != "" {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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
12160
docs/api/v1.43.yaml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue