Add flag to add annotations to a container

Also add annotations from the image the container was created
from.

Signed-off-by: Matthew Heon <matthew.heon@gmail.com>

Closes: #886
Approved by: rhatdan
This commit is contained in:
Matthew Heon 2018-06-03 14:05:54 -04:00 committed by Atomic Bot
parent 3416e9f194
commit 6d52ebdd13
9 changed files with 52 additions and 53 deletions

View File

@ -79,6 +79,10 @@ var createFlags = []cli.Flag{
Name: "add-host",
Usage: "Add a custom host-to-IP mapping (host:ip) (default [])",
},
cli.StringSliceFlag{
Name: "annotation",
Usage: "Add annotations to container (key:value) (default [])",
},
cli.StringSliceFlag{
Name: "attach, a",
Usage: "Attach to STDIN, STDOUT or STDERR (default [])",

View File

@ -19,6 +19,7 @@ import (
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image"
ann "github.com/projectatomic/libpod/pkg/annotations"
"github.com/projectatomic/libpod/pkg/inspect"
cc "github.com/projectatomic/libpod/pkg/spec"
"github.com/projectatomic/libpod/pkg/util"
@ -377,6 +378,27 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
}
}
// ANNOTATIONS
annotations := make(map[string]string)
// First, add our default annotations
annotations[ann.ContainerType] = "sandbox"
annotations[ann.TTY] = "false"
if tty {
annotations[ann.TTY] = "true"
}
// Next, add annotations from the image
for key, value := range data.Annotations {
annotations[key] = value
}
// Last, add user annotations
for _, annotation := range c.StringSlice("annotation") {
splitAnnotation := strings.SplitN(annotation, "=", 2)
if len(splitAnnotation) < 2 {
return nil, errors.Errorf("Annotations must be formatted KEY=VALUE")
}
annotations[splitAnnotation[0]] = splitAnnotation[1]
}
// WORKING DIRECTORY
workDir := "/"
if c.IsSet("workdir") {
@ -463,6 +485,7 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
config := &cc.CreateConfig{
Runtime: runtime,
Annotations: annotations,
BuiltinImgVolumes: ImageVolumes,
ConmonPidFile: c.String("conmon-pidfile"),
ImageVolumeType: c.String("image-volume"),

View File

@ -1134,6 +1134,7 @@ _podman_push() {
_podman_container_run() {
local options_with_args="
--add-host
--annotation
--attach -a
--blkio-weight
--blkio-weight-device

View File

@ -23,6 +23,10 @@ The initial status of the container created with **podman create** is 'created'.
Add a line to /etc/hosts. The format is hostname:ip. The **--add-host**
option can be set multiple times.
**--annotation**=[]
Add an annotation to the container. The format is key=value.
The **--annotation** option can be set multiple times.
**-a**, **--attach**=[]
Attach to STDIN, STDOUT or STDERR.

View File

@ -35,6 +35,10 @@ is located at `/run/.containerenv`.
Add a line to /etc/hosts. The format is hostname:ip. The **--add-host**
option can be set multiple times.
**--annotation**=[]
Add an annotation to the container. The format is key=value.
The **--annotation** option can be set multiple times.
**-a**, **--attach**=[]
Attach to STDIN, STDOUT or STDERR.

View File

@ -16,7 +16,6 @@ import (
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/libpod"
ann "github.com/projectatomic/libpod/pkg/annotations"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@ -67,6 +66,7 @@ type CreateResourceConfig struct {
// CreateConfig is a pre OCI spec structure. It represents user input from varlink or the CLI
type CreateConfig struct {
Runtime *libpod.Runtime
Annotations map[string]string
Args []string
CapAdd []string // cap-add
CapDrop []string // cap-drop
@ -219,51 +219,6 @@ func makeThrottleArray(throttleInput []string, rateType int) ([]spec.LinuxThrott
return ltds, nil
}
// GetAnnotations returns the all the annotations for the container
func (c *CreateConfig) GetAnnotations() map[string]string {
a := getDefaultAnnotations()
// TODO - Which annotations do we want added by default
// TODO - This should be added to the DB long term
if c.Tty {
a["io.kubernetes.cri-o.TTY"] = "true"
}
return a
}
func getDefaultAnnotations() map[string]string {
var annotations map[string]string
annotations = make(map[string]string)
annotations[ann.Annotations] = ""
annotations[ann.ContainerID] = ""
annotations[ann.ContainerName] = ""
annotations[ann.ContainerType] = "sandbox"
annotations[ann.Created] = ""
annotations[ann.HostName] = ""
annotations[ann.IP] = ""
annotations[ann.Image] = ""
annotations[ann.ImageName] = ""
annotations[ann.ImageRef] = ""
annotations[ann.KubeName] = ""
annotations[ann.Labels] = ""
annotations[ann.LogPath] = ""
annotations[ann.Metadata] = ""
annotations[ann.Name] = ""
annotations[ann.PrivilegedRuntime] = ""
annotations[ann.ResolvPath] = ""
annotations[ann.HostnamePath] = ""
annotations[ann.SandboxID] = ""
annotations[ann.SandboxName] = ""
annotations[ann.ShmPath] = ""
annotations[ann.MountPoint] = ""
annotations[ann.TrustedSandbox] = ""
annotations[ann.TTY] = "false"
annotations[ann.Stdin] = ""
annotations[ann.StdinOnce] = ""
annotations[ann.Volumes] = ""
return annotations
}
//GetVolumeMounts takes user provided input for bind mounts and creates Mount structs
func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, error) {
var m []spec.Mount

View File

@ -58,7 +58,7 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
g.SetProcessArgs(config.Command)
g.SetProcessTerminal(config.Tty)
for key, val := range config.GetAnnotations() {
for key, val := range config.Annotations {
g.AddAnnotation(key, val)
}
g.SetRootReadonly(config.ReadOnlyRootfs)

View File

@ -23,12 +23,6 @@ func TestCreateConfig_GetVolumeMounts(t *testing.T) {
assert.True(t, reflect.DeepEqual(data, specMount[0]))
}
func TestCreateConfig_GetAnnotations(t *testing.T) {
config := CreateConfig{}
annotations := config.GetAnnotations()
assert.True(t, reflect.DeepEqual("sandbox", annotations["io.kubernetes.cri-o.ContainerType"]))
}
func TestCreateConfig_GetTmpfsMounts(t *testing.T) {
data := spec.Mount{
Destination: "/homer",

View File

@ -54,4 +54,18 @@ var _ = Describe("Podman create", func() {
Expect(session.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
})
It("podman create adds annotation", func() {
session := podmanTest.Podman([]string{"create", "--annotation", "HELLO=WORLD", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
check := podmanTest.Podman([]string{"inspect", "-l"})
check.WaitWithDefaultTimeout()
data := check.InspectContainerToJSON()
value, ok := data[0].Config.Annotations["HELLO"]
Expect(ok).To(BeTrue())
Expect(value).To(Equal("WORLD"))
})
})