diff options
-rw-r--r-- | cmd/podman/play/kube.go | 21 | ||||
-rw-r--r-- | docs/source/markdown/podman-play-kube.1.md | 5 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/play.go | 38 | ||||
-rw-r--r-- | pkg/bindings/play/types.go | 2 | ||||
-rw-r--r-- | pkg/bindings/play/types_kube_options.go | 15 | ||||
-rw-r--r-- | pkg/domain/entities/play.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/play.go | 7 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/play.go | 3 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/kube.go | 6 | ||||
-rw-r--r-- | test/system/700-play.bats | 13 |
10 files changed, 93 insertions, 19 deletions
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go index 563a6251c..3067f0d54 100644 --- a/cmd/podman/play/kube.go +++ b/cmd/podman/play/kube.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "os" + "strings" "github.com/containers/common/pkg/auth" "github.com/containers/common/pkg/completion" @@ -31,7 +32,8 @@ type playKubeOptionsWrapper struct { } var ( - macs []string + annotations []string + macs []string // https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/ defaultSeccompRoot = "/var/lib/kubelet/seccomp" kubeOptions = playKubeOptionsWrapper{} @@ -61,6 +63,13 @@ func init() { flags := kubeCmd.Flags() flags.SetNormalizeFunc(utils.AliasFlags) + annotationFlagName := "annotation" + flags.StringSliceVar( + &annotations, + annotationFlagName, []string{}, + "Add annotations to pods (key=value)", + ) + _ = kubeCmd.RegisterFlagCompletionFunc(annotationFlagName, completion.AutocompleteNone) credsFlagName := "creds" flags.StringVar(&kubeOptions.CredentialsCLI, credsFlagName, "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") _ = kubeCmd.RegisterFlagCompletionFunc(credsFlagName, completion.AutocompleteNone) @@ -161,6 +170,16 @@ func kube(cmd *cobra.Command, args []string) error { kubeOptions.Password = creds.Password } + for _, annotation := range annotations { + splitN := strings.SplitN(annotation, "=", 2) + if len(splitN) > 2 { + return errors.Errorf("annotation %q must include an '=' sign", annotation) + } + if kubeOptions.Annotations == nil { + kubeOptions.Annotations = make(map[string]string) + } + kubeOptions.Annotations[splitN[0]] = splitN[1] + } yamlfile := args[0] if yamlfile == "-" { yamlfile = "/dev/stdin" diff --git a/docs/source/markdown/podman-play-kube.1.md b/docs/source/markdown/podman-play-kube.1.md index 328210d34..310bade34 100644 --- a/docs/source/markdown/podman-play-kube.1.md +++ b/docs/source/markdown/podman-play-kube.1.md @@ -105,6 +105,11 @@ and as a result environment variable `FOO` will be set to `bar` for container `c ## OPTIONS +#### **--annotation**=*key=value* + +Add an annotation to the container or pod. The format is key=value. +The **--annotation** option can be set multiple times. + #### **--authfile**=*path* Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`. diff --git a/pkg/api/handlers/libpod/play.go b/pkg/api/handlers/libpod/play.go index 515d0e5cf..aed889298 100644 --- a/pkg/api/handlers/libpod/play.go +++ b/pkg/api/handlers/libpod/play.go @@ -23,14 +23,15 @@ func PlayKube(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { - Network []string `schema:"network"` - TLSVerify bool `schema:"tlsVerify"` - LogDriver string `schema:"logDriver"` - LogOptions []string `schema:"logOptions"` - Start bool `schema:"start"` - StaticIPs []string `schema:"staticIPs"` - StaticMACs []string `schema:"staticMACs"` - NoHosts bool `schema:"noHosts"` + Annotations map[string]string `schema:"annotations"` + Network []string `schema:"network"` + TLSVerify bool `schema:"tlsVerify"` + LogDriver string `schema:"logDriver"` + LogOptions []string `schema:"logOptions"` + Start bool `schema:"start"` + StaticIPs []string `schema:"staticIPs"` + StaticMACs []string `schema:"staticMACs"` + NoHosts bool `schema:"noHosts"` }{ TLSVerify: true, Start: true, @@ -97,16 +98,17 @@ func PlayKube(w http.ResponseWriter, r *http.Request) { containerEngine := abi.ContainerEngine{Libpod: runtime} options := entities.PlayKubeOptions{ - Authfile: authfile, - Username: username, - Password: password, - Networks: query.Network, - NoHosts: query.NoHosts, - Quiet: true, - LogDriver: query.LogDriver, - LogOptions: query.LogOptions, - StaticIPs: staticIPs, - StaticMACs: staticMACs, + Annotations: query.Annotations, + Authfile: authfile, + Username: username, + Password: password, + Networks: query.Network, + NoHosts: query.NoHosts, + Quiet: true, + LogDriver: query.LogDriver, + LogOptions: query.LogOptions, + StaticIPs: staticIPs, + StaticMACs: staticMACs, } if _, found := r.URL.Query()["tlsVerify"]; found { options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) diff --git a/pkg/bindings/play/types.go b/pkg/bindings/play/types.go index ca639e46b..dbff4304b 100644 --- a/pkg/bindings/play/types.go +++ b/pkg/bindings/play/types.go @@ -7,6 +7,8 @@ import ( //go:generate go run ../generator/generator.go KubeOptions // KubeOptions are optional options for replaying kube YAML files type KubeOptions struct { + // Annotations - Annotations to add to Pods + Annotations map[string]string // Authfile - path to an authentication file. Authfile *string // CertDir - to a directory containing TLS certifications and keys. diff --git a/pkg/bindings/play/types_kube_options.go b/pkg/bindings/play/types_kube_options.go index 83a6f1566..d7a452ea2 100644 --- a/pkg/bindings/play/types_kube_options.go +++ b/pkg/bindings/play/types_kube_options.go @@ -18,6 +18,21 @@ func (o *KubeOptions) ToParams() (url.Values, error) { return util.ToParams(o) } +// WithAnnotations set field Annotations to given value +func (o *KubeOptions) WithAnnotations(value map[string]string) *KubeOptions { + o.Annotations = value + return o +} + +// GetAnnotations returns value of field Annotations +func (o *KubeOptions) GetAnnotations() map[string]string { + if o.Annotations == nil { + var z map[string]string + return z + } + return o.Annotations +} + // WithAuthfile set field Authfile to given value func (o *KubeOptions) WithAuthfile(value string) *KubeOptions { o.Authfile = &value diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go index 7614a4012..c9dc3f08c 100644 --- a/pkg/domain/entities/play.go +++ b/pkg/domain/entities/play.go @@ -8,6 +8,8 @@ import ( // PlayKubeOptions controls playing kube YAML files. type PlayKubeOptions struct { + // Annotations - Annotations to add to Pods + Annotations map[string]string // Authfile - path to an authentication file. Authfile string // Indicator to build all images with Containerfile or Dockerfile diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 155b06105..3242e64a2 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -79,6 +79,13 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en podTemplateSpec.ObjectMeta = podYAML.ObjectMeta podTemplateSpec.Spec = podYAML.Spec + for name, val := range options.Annotations { + if podYAML.Annotations == nil { + podYAML.Annotations = make(map[string]string) + } + podYAML.Annotations[name] = val + } + r, err := ic.playKubePod(ctx, podTemplateSpec.ObjectMeta.Name, &podTemplateSpec, options, &ipIndex, podYAML.Annotations, configMaps) if err != nil { return nil, err diff --git a/pkg/domain/infra/tunnel/play.go b/pkg/domain/infra/tunnel/play.go index 55844730b..cd51262d0 100644 --- a/pkg/domain/infra/tunnel/play.go +++ b/pkg/domain/infra/tunnel/play.go @@ -16,6 +16,9 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entit if len(opts.LogOptions) > 0 { options.WithLogOptions(opts.LogOptions) } + if opts.Annotations != nil { + options.WithAnnotations(opts.Annotations) + } options.WithNoHosts(opts.NoHosts) if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined { options.WithSkipTLSVerify(s == types.OptionalBoolTrue) diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 5e6671231..e0331b0a6 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -277,7 +277,13 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener } annotations := make(map[string]string) + if opts.Annotations != nil { + annotations = opts.Annotations + } if opts.PodInfraID != "" { + if annotations == nil { + + } annotations[ann.SandboxID] = opts.PodInfraID annotations[ann.ContainerType] = ann.ContainerTypeContainer } diff --git a/test/system/700-play.bats b/test/system/700-play.bats index 07c5d124f..8af4cd25b 100644 --- a/test/system/700-play.bats +++ b/test/system/700-play.bats @@ -220,3 +220,16 @@ _EOF run_podman pod rm -t 0 -f test_pod run_podman rmi -f userimage:latest } + +@test "podman play --annotation" { + TESTDIR=$PODMAN_TMPDIR/testdir + RANDOMSTRING=$(random_string 15) + mkdir -p $TESTDIR + echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml + run_podman play kube --annotation "name=$RANDOMSTRING" $PODMAN_TMPDIR/test.yaml + run_podman inspect --format "{{ .Config.Annotations }}" test_pod-test + is "$output" ".*name:$RANDOMSTRING" "Annotation should be added to pod" + + run_podman stop -a -t 0 + run_podman pod rm -t 0 -f test_pod +} |