Merge pull request #19102 from jakecorrenti/kube-generate-print-annotations

Add `--no-trunc` flag to maintain original annotation length
This commit is contained in:
OpenShift Merge Robot
2023-07-10 22:41:39 -04:00
committed by GitHub
20 changed files with 269 additions and 42 deletions

View File

@ -81,6 +81,9 @@ func generateFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig) {
flags.Int32VarP(&generateOptions.Replicas, replicasFlagName, "r", 1, "Set the replicas number for Deployment kind")
_ = cmd.RegisterFlagCompletionFunc(replicasFlagName, completion.AutocompleteNone)
noTruncAnnotationsFlagName := "no-trunc"
flags.BoolVar(&generateOptions.UseLongAnnotations, noTruncAnnotationsFlagName, false, "Don't truncate annotations to Kubernetes length (63 chars)")
flags.SetNormalizeFunc(utils.AliasFlags)
}

View File

@ -165,6 +165,9 @@ func playFlags(cmd *cobra.Command) {
flags.StringSliceVar(&playOptions.ConfigMaps, configmapFlagName, []string{}, "`Pathname` of a YAML file containing a kubernetes configmap")
_ = cmd.RegisterFlagCompletionFunc(configmapFlagName, completion.AutocompleteDefault)
noTruncFlagName := "no-trunc"
flags.BoolVar(&playOptions.UseLongAnnotations, noTruncFlagName, false, "Use annotations that are not truncated to the Kubernetes maximum length of 63 characters")
if !registry.IsRemote() {
certDirFlagName := "cert-dir"
flags.StringVar(&playOptions.CertDir, certDirFlagName, "", "`Pathname` of a directory containing TLS certificates and keys")
@ -240,7 +243,7 @@ func play(cmd *cobra.Command, args []string) error {
playOptions.Annotations = make(map[string]string)
}
annotation := splitN[1]
if len(annotation) > define.MaxKubeAnnotation {
if len(annotation) > define.MaxKubeAnnotation && !playOptions.UseLongAnnotations {
return fmt.Errorf("annotation exceeds maximum size, %d, of kubernetes annotation: %s", define.MaxKubeAnnotation, annotation)
}
playOptions.Annotations[splitN[0]] = annotation

View File

@ -34,6 +34,11 @@ Note that the generated Kubernetes YAML file can be used to re-run the deploymen
Output to the given file instead of STDOUT. If the file already exists, `kube generate` refuses to replace it and returns an error.
#### **--no-trunc**
Don't truncate annotations to the Kubernetes maximum length of 63 characters.
Note: enabling this flag means the generated YAML file is not Kubernetes compatible and can only be used with `podman kube play`
#### **--replicas**, **-r**=*replica count*
The value to set `replicas` to when generating a **Deployment** kind.

View File

@ -214,6 +214,10 @@ When no network option is specified and *host* network mode is not configured in
This option conflicts with host added in the Kubernetes YAML.
#### **--no-trunc**
Use annotations that are not truncated to the Kubernetes maximum length of 63 characters
#### **--publish**=*[[ip:][hostPort]:]containerPort[/protocol]*
Define or override a port definition in the YAML file.

View File

@ -34,14 +34,14 @@ import (
// GenerateForKube takes a slice of libpod containers and generates
// one v1.Pod description that includes just a single container.
func GenerateForKube(ctx context.Context, ctrs []*Container, getService bool) (*v1.Pod, error) {
func GenerateForKube(ctx context.Context, ctrs []*Container, getService, useLongAnnotations bool) (*v1.Pod, error) {
// Generate the v1.Pod yaml description
return simplePodWithV1Containers(ctx, ctrs, getService)
return simplePodWithV1Containers(ctx, ctrs, getService, useLongAnnotations)
}
// GenerateForKube takes a slice of libpod containers and generates
// one v1.Pod description
func (p *Pod) GenerateForKube(ctx context.Context, getService bool) (*v1.Pod, []v1.ServicePort, error) {
func (p *Pod) GenerateForKube(ctx context.Context, getService, useLongAnnotations bool) (*v1.Pod, []v1.ServicePort, error) {
// Generate the v1.Pod yaml description
var (
ports []v1.ContainerPort
@ -91,7 +91,7 @@ func (p *Pod) GenerateForKube(ctx context.Context, getService bool) (*v1.Pod, []
hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
hostUsers = infraContainer.IDMappings().HostUIDMapping && infraContainer.IDMappings().HostGIDMapping
}
pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork, hostUsers, getService)
pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork, hostUsers, getService, useLongAnnotations)
if err != nil {
return nil, servicePorts, err
}
@ -370,9 +370,9 @@ func newServicePortState() servicePortState {
}
}
func TruncateKubeAnnotation(str string) string {
func truncateKubeAnnotation(str string, useLongAnnotations bool) string {
str = strings.TrimSpace(str)
if utf8.RuneCountInString(str) < define.MaxKubeAnnotation {
if useLongAnnotations || utf8.RuneCountInString(str) < define.MaxKubeAnnotation {
return str
}
trunc := string([]rune(str)[:define.MaxKubeAnnotation])
@ -426,7 +426,7 @@ func containersToServicePorts(containers []v1.Container) ([]v1.ServicePort, erro
return sps, nil
}
func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork, hostUsers, getService bool) (*v1.Pod, error) {
func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork, hostUsers, getService, useLongAnnotations bool) (*v1.Pod, error) {
deDupPodVolumes := make(map[string]*v1.Volume)
first := true
podContainers := make([]v1.Container, 0, len(containers))
@ -445,11 +445,11 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
if define.IsReservedAnnotation(k) || annotations.IsReservedAnnotation(k) {
continue
}
podAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = TruncateKubeAnnotation(v)
podAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = truncateKubeAnnotation(v, useLongAnnotations)
}
// Convert auto-update labels into kube annotations
for k, v := range getAutoUpdateAnnotations(ctr.Name(), ctr.Labels()) {
podAnnotations[k] = TruncateKubeAnnotation(v)
for k, v := range getAutoUpdateAnnotations(ctr.Name(), ctr.Labels(), useLongAnnotations) {
podAnnotations[k] = truncateKubeAnnotation(v, useLongAnnotations)
}
isInit := ctr.IsInitCtr()
// Since hostname is only set at pod level, set the hostname to the hostname of the first container we encounter
@ -466,7 +466,7 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
return nil, err
}
for k, v := range annotations {
podAnnotations[define.BindMountPrefix] = TruncateKubeAnnotation(k + ":" + v)
podAnnotations[define.BindMountPrefix] = truncateKubeAnnotation(k+":"+v, useLongAnnotations)
}
// Since port bindings for the pod are handled by the
// infra container, wipe them here only if we are sharing the net namespace
@ -574,7 +574,7 @@ func newPodObject(podName string, annotations map[string]string, initCtrs, conta
// simplePodWithV1Containers is a function used by inspect when kube yaml needs to be generated
// for a single container. we "insert" that container description in a pod.
func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getService bool) (*v1.Pod, error) {
func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getService, useLongAnnotations bool) (*v1.Pod, error) {
kubeCtrs := make([]v1.Container, 0, len(ctrs))
kubeInitCtrs := []v1.Container{}
kubeVolumes := make([]v1.Volume, 0)
@ -591,12 +591,12 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getServic
if define.IsReservedAnnotation(k) || annotations.IsReservedAnnotation(k) {
continue
}
kubeAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = TruncateKubeAnnotation(v)
kubeAnnotations[fmt.Sprintf("%s/%s", k, removeUnderscores(ctr.Name()))] = truncateKubeAnnotation(v, useLongAnnotations)
}
// Convert auto-update labels into kube annotations
for k, v := range getAutoUpdateAnnotations(ctr.Name(), ctr.Labels()) {
kubeAnnotations[k] = TruncateKubeAnnotation(v)
for k, v := range getAutoUpdateAnnotations(ctr.Name(), ctr.Labels(), useLongAnnotations) {
kubeAnnotations[k] = truncateKubeAnnotation(v, useLongAnnotations)
}
isInit := ctr.IsInitCtr()
@ -643,7 +643,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getServic
return nil, err
}
for k, v := range annotations {
kubeAnnotations[define.BindMountPrefix] = TruncateKubeAnnotation(k + ":" + v)
kubeAnnotations[define.BindMountPrefix] = truncateKubeAnnotation(k+":"+v, useLongAnnotations)
}
if isInit {
kubeInitCtrs = append(kubeInitCtrs, kubeCtr)
@ -1266,7 +1266,7 @@ func removeUnderscores(s string) string {
// getAutoUpdateAnnotations searches for auto-update container labels
// and returns them as kube annotations
func getAutoUpdateAnnotations(ctrName string, ctrLabels map[string]string) map[string]string {
func getAutoUpdateAnnotations(ctrName string, ctrLabels map[string]string, useLongAnnotations bool) map[string]string {
autoUpdateLabel := "io.containers.autoupdate"
annotations := make(map[string]string)
@ -1276,7 +1276,7 @@ func getAutoUpdateAnnotations(ctrName string, ctrLabels map[string]string) map[s
// since labels can variate between containers within a pod, they will be
// identified with the container name when converted into kube annotations
kc := fmt.Sprintf("%s/%s", k, ctrName)
annotations[kc] = TruncateKubeAnnotation(v)
annotations[kc] = truncateKubeAnnotation(v, useLongAnnotations)
}
}

View File

@ -93,6 +93,7 @@ func GenerateKube(w http.ResponseWriter, r *http.Request) {
Service bool `schema:"service"`
Type string `schema:"type"`
Replicas int32 `schema:"replicas"`
NoTrunc bool `schema:"noTrunc"`
}{
// Defaults would go here.
Replicas: 1,
@ -115,7 +116,12 @@ func GenerateKube(w http.ResponseWriter, r *http.Request) {
}
containerEngine := abi.ContainerEngine{Libpod: runtime}
options := entities.GenerateKubeOptions{Service: query.Service, Type: generateType, Replicas: query.Replicas}
options := entities.GenerateKubeOptions{
Service: query.Service,
Type: generateType,
Replicas: query.Replicas,
UseLongAnnotations: query.NoTrunc,
}
report, err := containerEngine.GenerateKube(r.Context(), query.Names, options)
if err != nil {
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("generating YAML: %w", err))

View File

@ -29,6 +29,7 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
StaticMACs []string `schema:"staticMACs"`
NoHosts bool `schema:"noHosts"`
PublishPorts []string `schema:"publishPorts"`
NoTrunc bool `schema:"noTrunc"`
Wait bool `schema:"wait"`
ServiceContainer bool `schema:"serviceContainer"`
}{
@ -85,21 +86,22 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
containerEngine := abi.ContainerEngine{Libpod: runtime}
options := entities.PlayKubeOptions{
Annotations: query.Annotations,
Authfile: authfile,
Username: username,
Password: password,
Networks: query.Network,
NoHosts: query.NoHosts,
Quiet: true,
LogDriver: logDriver,
LogOptions: query.LogOptions,
StaticIPs: staticIPs,
StaticMACs: staticMACs,
IsRemote: true,
PublishPorts: query.PublishPorts,
Wait: query.Wait,
ServiceContainer: query.ServiceContainer,
Annotations: query.Annotations,
Authfile: authfile,
Username: username,
Password: password,
Networks: query.Network,
NoHosts: query.NoHosts,
Quiet: true,
LogDriver: logDriver,
LogOptions: query.LogOptions,
StaticIPs: staticIPs,
StaticMACs: staticMACs,
IsRemote: true,
PublishPorts: query.PublishPorts,
Wait: query.Wait,
ServiceContainer: query.ServiceContainer,
UseLongAnnotations: query.NoTrunc,
}
if _, found := r.URL.Query()["tlsVerify"]; found {
options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)

View File

@ -58,6 +58,11 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error {
// type: boolean
// default: false
// description: Clean up all objects created when a SIGTERM is received or pods exit.
// - in: query
// name: noTrunc
// type: boolean
// default: false
// description: use annotations that are not truncated to the Kubernetes maximum length of 63 characters
// - in: body
// name: request
// description: Kubernetes YAML file.
@ -125,6 +130,11 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error {
// format: int32
// default: 0
// description: Set the replica number for Deployment kind.
// - in: query
// name: noTrunc
// type: boolean
// default: false
// description: don't truncate annotations to the Kubernetes maximum length of 63 characters
// produces:
// - text/vnd.yaml
// - application/json

View File

@ -10,6 +10,8 @@ type KubeOptions struct {
Type *string
// Replicas - the value to set in the replicas field for a Deployment
Replicas *int32
// NoTrunc - don't truncate annotations to the Kubernetes maximum length of 63 characters
NoTrunc *bool
}
// SystemdOptions are optional options for generating systemd files

View File

@ -61,3 +61,18 @@ func (o *KubeOptions) GetReplicas() int32 {
}
return *o.Replicas
}
// WithNoTrunc set field NoTrunc to given value
func (o *KubeOptions) WithNoTrunc(value bool) *KubeOptions {
o.NoTrunc = &value
return o
}
// GetNoTrunc returns value of field NoTrunc
func (o *KubeOptions) GetNoTrunc() bool {
if o.NoTrunc == nil {
var z bool
return z
}
return *o.NoTrunc
}

View File

@ -44,6 +44,9 @@ type PlayOptions struct {
LogOptions *[]string
// Start - don't start the pod if false
Start *bool
// NoTrunc - use annotations that were not truncated to the
// Kubernetes maximum of 63 characters
NoTrunc *bool
// Userns - define the user namespace to use.
Userns *string
// Force - remove volumes on --down

View File

@ -273,6 +273,21 @@ func (o *PlayOptions) GetStart() bool {
return *o.Start
}
// WithNoTrunc set field NoTrunc to given value
func (o *PlayOptions) WithNoTrunc(value bool) *PlayOptions {
o.NoTrunc = &value
return o
}
// GetNoTrunc returns value of field NoTrunc
func (o *PlayOptions) GetNoTrunc() bool {
if o.NoTrunc == nil {
var z bool
return z
}
return *o.NoTrunc
}
// WithUserns set field Userns to given value
func (o *PlayOptions) WithUserns(value string) *PlayOptions {
o.Userns = &value

View File

@ -35,6 +35,8 @@ type GenerateKubeOptions struct {
Type string
// Replicas - the value to set in the replicas field for a Deployment
Replicas int32
// UseLongAnnotations - don't truncate annotations to the Kubernetes maximum length of 63 characters
UseLongAnnotations bool
}
type KubeGenerateOptions = GenerateKubeOptions

View File

@ -59,6 +59,9 @@ type PlayKubeOptions struct {
Start types.OptionalBool
// ServiceContainer - creates a service container that is started before and is stopped after all pods.
ServiceContainer bool
// UseLongAnnotations - use annotations that were not truncated to the
// Kubernetes maximum length of 63 characters
UseLongAnnotations bool
// Userns - define the user namespace to use.
Userns string
// IsRemote - was the request triggered by running podman-remote

View File

@ -207,7 +207,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
// Generate the kube pods from containers.
if len(ctrs) >= 1 {
po, err := libpod.GenerateForKube(ctx, ctrs, options.Service)
po, err := libpod.GenerateForKube(ctx, ctrs, options.Service, options.UseLongAnnotations)
if err != nil {
return nil, err
}
@ -273,7 +273,7 @@ func getKubePods(ctx context.Context, pods []*libpod.Pod, options entities.Gener
svcs := [][]byte{}
for _, p := range pods {
po, sp, err := p.GenerateForKube(ctx, options.Service)
po, sp, err := p.GenerateForKube(ctx, options.Service, options.UseLongAnnotations)
if err != nil {
return nil, nil, err
}

View File

@ -229,8 +229,8 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
podTemplateSpec.ObjectMeta = podYAML.ObjectMeta
podTemplateSpec.Spec = podYAML.Spec
for name, val := range podYAML.Annotations {
if len(val) > define.MaxKubeAnnotation {
return nil, fmt.Errorf("invalid annotation %q=%q value length exceeds Kubernetetes max %d", name, val, define.MaxKubeAnnotation)
if len(val) > define.MaxKubeAnnotation && !options.UseLongAnnotations {
return nil, fmt.Errorf("annotation %q=%q value length exceeds Kubernetes max %d", name, val, define.MaxKubeAnnotation)
}
}
for name, val := range options.Annotations {

View File

@ -46,7 +46,7 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
//
// Note: Caller is responsible for closing returned Reader
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, opts entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
options := new(generate.KubeOptions).WithService(opts.Service).WithType(opts.Type).WithReplicas(opts.Replicas)
options := new(generate.KubeOptions).WithService(opts.Service).WithType(opts.Type).WithReplicas(opts.Replicas).WithNoTrunc(opts.UseLongAnnotations)
return generate.Kube(ic.ClientCtx, nameOrIDs, options)
}
@ -73,6 +73,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, opts en
options.WithStart(start == types.OptionalBoolTrue)
}
options.WithPublishPorts(opts.PublishPorts)
options.WithNoTrunc(opts.UseLongAnnotations)
return play.KubeWithBody(ic.ClientCtx, body, options)
}

View File

@ -1559,4 +1559,102 @@ USER test1`
Expect(pod.Name).To(Equal("testpod"))
Expect(pod.Spec.Hostname).To(Equal(""))
})
It("podman kube generate --no-trunc on container with long annotation", func() {
ctrName := "demo"
vol1 := filepath.Join(podmanTest.TempDir, RandomString(99))
err := os.MkdirAll(vol1, 0755)
Expect(err).ToNot(HaveOccurred())
session := podmanTest.Podman([]string{"create", "-v", vol1 + ":/tmp/foo:Z", "--name", ctrName, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
kube := podmanTest.Podman([]string{"kube", "generate", "--no-trunc", ctrName})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
pod := new(v1.Pod)
err = yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(HaveKeyWithValue(define.BindMountPrefix, vol1+":Z"))
Expect(pod.Annotations).To(Not(HaveKeyWithValue(define.BindMountPrefix, vol1[:define.MaxKubeAnnotation])))
})
It("podman kube generate on container with long annotation", func() {
ctrName := "demo"
vol1 := filepath.Join(podmanTest.TempDir, RandomString(99))
err := os.MkdirAll(vol1, 0755)
Expect(err).ToNot(HaveOccurred())
session := podmanTest.Podman([]string{"create", "-v", vol1 + ":/tmp/foo:Z", "--name", ctrName, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
kube := podmanTest.Podman([]string{"kube", "generate", ctrName})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
pod := new(v1.Pod)
err = yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(HaveKeyWithValue(define.BindMountPrefix, vol1[:define.MaxKubeAnnotation]))
Expect(pod.Annotations).To(Not(HaveKeyWithValue(define.BindMountPrefix, vol1+":Z")))
})
It("podman kube generate --no-trunc on pod with long annotation", func() {
ctrName := "demoCtr"
podName := "demoPod"
vol1 := filepath.Join(podmanTest.TempDir, RandomString(99))
err := os.MkdirAll(vol1, 0755)
Expect(err).ToNot(HaveOccurred())
session := podmanTest.Podman([]string{"pod", "create", podName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
session = podmanTest.Podman([]string{"create", "-v", vol1 + ":/tmp/foo:Z", "--name", ctrName, "--pod", podName, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
kube := podmanTest.Podman([]string{"kube", "generate", "--no-trunc", podName})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
pod := new(v1.Pod)
err = yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(HaveKeyWithValue(define.BindMountPrefix, vol1+":Z"))
Expect(pod.Annotations).To(Not(HaveKeyWithValue(define.BindMountPrefix, vol1[:define.MaxKubeAnnotation])))
})
It("podman kube generate on pod with long annotation", func() {
ctrName := "demoCtr"
podName := "demoPod"
vol1 := filepath.Join(podmanTest.TempDir, RandomString(99))
err := os.MkdirAll(vol1, 0755)
Expect(err).ToNot(HaveOccurred())
session := podmanTest.Podman([]string{"pod", "create", podName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
session = podmanTest.Podman([]string{"create", "-v", vol1 + ":/tmp/foo:Z", "--name", ctrName, "--pod", podName, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
kube := podmanTest.Podman([]string{"kube", "generate", podName})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
pod := new(v1.Pod)
err = yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).ToNot(HaveOccurred())
Expect(pod.Annotations).To(HaveKeyWithValue(define.BindMountPrefix, vol1[:define.MaxKubeAnnotation]))
Expect(pod.Annotations).To(Not(HaveKeyWithValue(define.BindMountPrefix, vol1+":Z")))
})
})

View File

@ -5341,4 +5341,44 @@ spec:
Expect(kube).Should(Exit(125))
Expect(kube.ErrorToString()).To(ContainSubstring("since Network Namespace set to host: invalid argument"))
})
It("podman kube play test with --no-trunc", func() {
ctrName := "demo"
vol1 := filepath.Join(podmanTest.TempDir, RandomString(99))
err := os.MkdirAll(vol1, 0755)
Expect(err).ToNot(HaveOccurred())
session := podmanTest.Podman([]string{"run", "-v", vol1 + ":/tmp/foo:Z", "--name", ctrName, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
file := filepath.Join(podmanTest.TempDir, ctrName+".yml")
session = podmanTest.Podman([]string{"kube", "generate", "--no-trunc", "-f", file, ctrName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
session = podmanTest.Podman([]string{"kube", "play", "--no-trunc", file})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
})
It("podman kube play test with long annotation", func() {
ctrName := "demo"
vol1 := filepath.Join(podmanTest.TempDir, RandomString(99))
err := os.MkdirAll(vol1, 0755)
Expect(err).ToNot(HaveOccurred())
session := podmanTest.Podman([]string{"run", "-v", vol1 + ":/tmp/foo:Z", "--name", ctrName, ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
file := filepath.Join(podmanTest.TempDir, ctrName+".yml")
session = podmanTest.Podman([]string{"kube", "generate", "--no-trunc", "-f", file, ctrName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
session = podmanTest.Podman([]string{"kube", "play", file})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(125))
})
})

View File

@ -431,12 +431,27 @@ _EOF
assert "$output" =~ "annotation exceeds maximum size, 63, of kubernetes annotation:" "Expected to fail with Length greater than 63"
}
@test "podman play --no-trunc --annotation > Max" {
TESTDIR=$PODMAN_TMPDIR/testdir
RANDOMSTRING=$(random_string 65)
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman play kube --no-trunc --annotation "name=$RANDOMSTRING" $PODMAN_TMPDIR/test.yaml
}
@test "podman play Yaml with annotation > Max" {
RANDOMSTRING=$(random_string 65)
_write_test_yaml "annotations=test: ${RANDOMSTRING}" command=id
run_podman 125 play kube - < $PODMAN_TMPDIR/test.yaml
assert "$output" =~ "invalid annotation \"test\"=\"$RANDOMSTRING\"" "Expected to fail with annotation length greater than 63"
run_podman 125 play kube - < $PODMAN_TMPDIR/test.yaml
assert "$output" =~ "annotation \"test\"=\"$RANDOMSTRING\" value length exceeds Kubernetes max 63" "Expected to fail with annotation length greater than 63"
}
@test "podman play Yaml --no-trunc with annotation > Max" {
RANDOMSTRING=$(random_string 65)
_write_test_yaml "annotations=test: ${RANDOMSTRING}" command=id
run_podman play kube --no-trunc - < $PODMAN_TMPDIR/test.yaml
}
@test "podman kube play - default log driver" {