aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2021-10-18 11:54:44 -0400
committerDaniel J Walsh <dwalsh@redhat.com>2021-10-19 08:31:35 -0400
commit517b56b02dbcdd76ef42919a22cd335364246eb6 (patch)
tree36cf5968b1495614d97a46dcf793469501459ccf
parente0ffc431fe7f016124fdcb36819698a90fe448a9 (diff)
downloadpodman-517b56b02dbcdd76ef42919a22cd335364246eb6.tar.gz
podman-517b56b02dbcdd76ef42919a22cd335364246eb6.tar.bz2
podman-517b56b02dbcdd76ef42919a22cd335364246eb6.zip
Generate Kube should not print default structs
If podman uses Workdir="/" or the workdir specified in the image, it should not add it to the yaml. If Podman find environment variables in the image, they should not get added to the yaml. If the container or pod do not have changes to SELinux we should not print seLinuxOpt{} If the container or pod do not change any dns options the yaml should not have a dnsOption={} If the container is not privileged it should not have privileged=false in the yaml. Fixes: https://github.com/containers/podman/issues/11995 Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
-rw-r--r--docs/source/markdown/podman-generate-kube.1.md56
-rw-r--r--libpod/kube.go64
-rw-r--r--test/e2e/generate_kube_test.go9
3 files changed, 55 insertions, 74 deletions
diff --git a/docs/source/markdown/podman-generate-kube.1.md b/docs/source/markdown/podman-generate-kube.1.md
index 9ae3941ec..a583afcf9 100644
--- a/docs/source/markdown/podman-generate-kube.1.md
+++ b/docs/source/markdown/podman-generate-kube.1.md
@@ -54,13 +54,7 @@ spec:
- docker-entrypoint.sh
- mysqld
env:
- - name: PATH
- value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- - name: TERM
- value: xterm
- name: HOSTNAME
- - name: container
- value: podman
- name: GOSU_VERSION
value: "1.10"
- name: GPG_KEYS
@@ -77,14 +71,14 @@ spec:
ports:
- containerPort: 3306
hostPort: 36533
- protocol: TCP
resources: {}
securityContext:
- allowPrivilegeEscalation: true
- privileged: false
- readOnlyRootFilesystem: false
+ capabilities:
+ drop:
+ - CAP_MKNOD
+ - CAP_NET_RAW
+ - CAP_AUDIT_WRITE
tty: true
- workingDir: /
status: {}
```
@@ -106,31 +100,18 @@ spec:
containers:
- command:
- /bin/sh
- env:
- - name: PATH
- value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- - name: TERM
- value: xterm
- - name: container
- value: podman
image: docker.io/library/alpine:latest
name: test-bind-mount
resources: {}
securityContext:
- allowPrivilegeEscalation: true
capabilities:
drop:
- CAP_MKNOD
- CAP_NET_RAW
- CAP_AUDIT_WRITE
- privileged: false
- readOnlyRootFilesystem: false
- seLinuxOptions: {}
volumeMounts:
- mountPath: /volume
name: home-user-my-data-host
- workingDir: /
- dnsConfig: {}
restartPolicy: Never
volumes:
- hostPath:
@@ -158,31 +139,18 @@ spec:
containers:
- command:
- /bin/sh
- env:
- - name: PATH
- value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- - name: TERM
- value: xterm
- - name: container
- value: podman
image: docker.io/library/alpine:latest
name: test-bind-mount
resources: {}
securityContext:
- allowPrivilegeEscalation: true
capabilities:
drop:
- CAP_MKNOD
- CAP_NET_RAW
- CAP_AUDIT_WRITE
- privileged: false
- readOnlyRootFilesystem: false
- seLinuxOptions: {}
volumeMounts:
- mountPath: /volume
name: priceless-data-pvc
- workingDir: /
- dnsConfig: {}
restartPolicy: Never
volumes:
- name: priceless-data-pvc
@@ -210,22 +178,9 @@ spec:
- command:
- python3
- /root/code/graph.py
- env:
- - name: PATH
- value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- - name: TERM
- value: xterm
- - name: HOSTNAME
- - name: container
- value: podman
image: quay.io/baude/demoweb:latest
name: practicalarchimedes
resources: {}
- securityContext:
- allowPrivilegeEscalation: true
- capabilities: {}
- privileged: false
- readOnlyRootFilesystem: false
tty: true
workingDir: /root/code
status: {}
@@ -242,7 +197,6 @@ spec:
- name: "8050"
nodePort: 31269
port: 8050
- protocol: TCP
targetPort: 0
selector:
app: demoweb
diff --git a/libpod/kube.go b/libpod/kube.go
index d47f47f1c..02ac8ed98 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -332,7 +332,7 @@ func newPodObject(podName string, annotations map[string]string, initCtrs, conta
InitContainers: initCtrs,
Volumes: volumes,
}
- if dnsOptions != nil {
+ if dnsOptions != nil && (len(dnsOptions.Nameservers)+len(dnsOptions.Searches)+len(dnsOptions.Options) > 0) {
ps.DNSConfig = dnsOptions
}
p := v1.Pod{
@@ -447,11 +447,6 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []
kubeVolumes = append(kubeVolumes, volumes...)
}
- envVariables, err := libpodEnvVarsToKubeEnvVars(c.config.Spec.Process.Env)
- if err != nil {
- return kubeContainer, kubeVolumes, nil, annotations, err
- }
-
portmappings, err := c.PortMappings()
if err != nil {
return kubeContainer, kubeVolumes, nil, annotations, err
@@ -489,15 +484,23 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []
kubeContainer.Command = nil
}
+ if c.WorkingDir() != "/" && imgData.Config.WorkingDir != c.WorkingDir() {
+ kubeContainer.WorkingDir = c.WorkingDir()
+ }
+
if imgData.User == c.User() {
kubeSec.RunAsGroup, kubeSec.RunAsUser = nil, nil
}
- kubeContainer.WorkingDir = c.WorkingDir()
+ envVariables, err := libpodEnvVarsToKubeEnvVars(c.config.Spec.Process.Env, imgData.Config.Env)
+ if err != nil {
+ return kubeContainer, kubeVolumes, nil, annotations, err
+ }
+ kubeContainer.Env = envVariables
+
kubeContainer.Ports = ports
// This should not be applicable
//container.EnvFromSource =
- kubeContainer.Env = envVariables
kubeContainer.SecurityContext = kubeSec
kubeContainer.StdinOnce = false
kubeContainer.TTY = c.config.Spec.Process.Terminal
@@ -600,9 +603,14 @@ func ocicniPortMappingToContainerPort(portMappings []types.OCICNIPortMapping) ([
}
// libpodEnvVarsToKubeEnvVars converts a key=value string slice to []v1.EnvVar
-func libpodEnvVarsToKubeEnvVars(envs []string) ([]v1.EnvVar, error) {
+func libpodEnvVarsToKubeEnvVars(envs []string, imageEnvs []string) ([]v1.EnvVar, error) {
defaultEnv := env.DefaultEnvVariables()
envVars := make([]v1.EnvVar, 0, len(envs))
+ imageMap := make(map[string]string, len(imageEnvs))
+ for _, ie := range envs {
+ split := strings.SplitN(ie, "=", 2)
+ imageMap[split[0]] = split[1]
+ }
for _, e := range envs {
split := strings.SplitN(e, "=", 2)
if len(split) != 2 {
@@ -611,6 +619,9 @@ func libpodEnvVarsToKubeEnvVars(envs []string) ([]v1.EnvVar, error) {
if defaultEnv[split[0]] == split[1] {
continue
}
+ if imageMap[split[0]] == split[1] {
+ continue
+ }
ev := v1.EnvVar{
Name: split[0],
Value: split[1],
@@ -808,33 +819,42 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) {
capabilities = newCaps
}
+ sc := v1.SecurityContext{
+ // RunAsNonRoot is an optional parameter; our first implementations should be root only; however
+ // I'm leaving this as a bread-crumb for later
+ //RunAsNonRoot: &nonRoot,
+ }
+ if capabilities != nil {
+ sc.Capabilities = capabilities
+ }
var selinuxOpts v1.SELinuxOptions
opts := strings.SplitN(c.config.Spec.Annotations[define.InspectAnnotationLabel], ":", 2)
- if len(opts) == 2 {
+ switch len(opts) {
+ case 2:
switch opts[0] {
case "type":
selinuxOpts.Type = opts[1]
+ sc.SELinuxOptions = &selinuxOpts
case "level":
selinuxOpts.Level = opts[1]
+ sc.SELinuxOptions = &selinuxOpts
}
- }
- if len(opts) == 1 {
+ case 1:
if opts[0] == "disable" {
selinuxOpts.Type = "spc_t"
+ sc.SELinuxOptions = &selinuxOpts
}
}
- sc := v1.SecurityContext{
- Capabilities: capabilities,
- Privileged: &privileged,
- SELinuxOptions: &selinuxOpts,
- // RunAsNonRoot is an optional parameter; our first implementations should be root only; however
- // I'm leaving this as a bread-crumb for later
- //RunAsNonRoot: &nonRoot,
- ReadOnlyRootFilesystem: &ro,
- AllowPrivilegeEscalation: &allowPrivEscalation,
+ if !allowPrivEscalation {
+ sc.AllowPrivilegeEscalation = &allowPrivEscalation
+ }
+ if privileged {
+ sc.Privileged = &privileged
+ }
+ if ro {
+ sc.ReadOnlyRootFilesystem = &ro
}
-
if c.User() != "" {
if !c.batched {
c.lock.Lock()
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 69941494b..cd382eba9 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -67,6 +67,10 @@ var _ = Describe("Podman generate kube", func() {
err := yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).To(BeNil())
Expect(pod.Spec.HostNetwork).To(Equal(false))
+ Expect(pod.Spec.SecurityContext).To(BeNil())
+ Expect(pod.Spec.DNSConfig).To(BeNil())
+ Expect(pod.Spec.Containers[0].WorkingDir).To(Equal(""))
+ Expect(pod.Spec.Containers[0].Env).To(BeNil())
numContainers := 0
for range pod.Spec.Containers {
@@ -103,6 +107,7 @@ var _ = Describe("Podman generate kube", func() {
err = yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).To(BeNil())
Expect(kube.OutputToString()).To(ContainSubstring("type: spc_t"))
+
})
It("podman generate service kube on container with --security-opt type", func() {
@@ -1079,7 +1084,7 @@ USER test1`
top1.WaitWithDefaultTimeout()
Expect(top1).Should(Exit(0))
- top2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top2", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", ALPINE, "top"})
+ top2 := podmanTest.Podman([]string{"run", "-dt", "--name", "top2", "--workdir", "/root", "--pod", "pod1", "--label", "io.containers.autoupdate=registry", "--label", "io.containers.autoupdate.authfile=/some/authfile.json", ALPINE, "top"})
top2.WaitWithDefaultTimeout()
Expect(top2).Should(Exit(0))
@@ -1090,6 +1095,8 @@ USER test1`
pod := new(v1.Pod)
err := yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).To(BeNil())
+ Expect(pod.Spec.Containers[0].WorkingDir).To(Equal(""))
+ Expect(pod.Spec.Containers[1].WorkingDir).To(Equal("/root"))
for _, ctr := range []string{"top1", "top2"} {
v, ok := pod.GetAnnotations()["io.containers.autoupdate/"+ctr]