mirror of
https://github.com/containers/podman.git
synced 2025-05-21 00:56:36 +08:00
Add --no-trunc
flag to maintain original annotation length
Adds a `--no-trunc` flag to `podman kube generate` preventing the annotations from being trimmed at 63 characters. However, due to the fact the annotations will not be trimmed, any annotation that is longer than 63 characters means this YAML will no longer be Kubernetes compatible. However, these YAML files can still be used with `podman kube play` due to the addition of the new flag below. Adds a `--no-trunc` flag to `podman kube play` supporting YAML files with annotations that were not truncated to the Kubernetes maximum length of 63 characters. Signed-off-by: Jake Correnti <jakecorrenti+github@proton.me>
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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")))
|
||||
})
|
||||
})
|
||||
|
@ -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))
|
||||
})
|
||||
})
|
||||
|
@ -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" {
|
||||
|
Reference in New Issue
Block a user