diff options
author | Daniel J Walsh <dwalsh@redhat.com> | 2022-03-09 17:30:01 -0500 |
---|---|---|
committer | Daniel J Walsh <dwalsh@redhat.com> | 2022-03-09 17:30:01 -0500 |
commit | feaa1a134a4fd0a7d25bab485708a201321bfb56 (patch) | |
tree | 080fa2a13998bc0b9f3c0689df6317f736aa8d02 | |
parent | acfcecf2ae41528d1d7ecd43d37d8fd554f587bc (diff) | |
download | podman-feaa1a134a4fd0a7d25bab485708a201321bfb56.tar.gz podman-feaa1a134a4fd0a7d25bab485708a201321bfb56.tar.bz2 podman-feaa1a134a4fd0a7d25bab485708a201321bfb56.zip |
Add podman play kube --annotation
Allow users to add annotions in the podman play kube command.
This PR Also fixes the fact that annotations in the pod spec were
not being passed down to containers.
Fixes: https://github.com/containers/podman/issues/12968
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
-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 +} |