Allow users to generate a kubernetes yaml off non running containers

Currently if you attempt to create a kube.yaml file off of a non running
container where the container runs as a specific User, the creation
fails because the storage container is not mounted. Podman is supposed to
read the /etc/passwd entry inside of the container but since the
container is not mounted, the c.State.Mountpoint == "".  Podman
incorrectly attempts to read /etc/passwd on the host, and fails if the
specified user is not in the hosts /etc/passwd.

This PR mounts the storage container, if it was not mounted so the read
succeeds.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2021-03-07 06:11:54 -05:00
parent b7c00f2cc0
commit 0e36e65eaa
2 changed files with 43 additions and 1 deletions

View File

@ -676,8 +676,18 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) {
return nil, errors.Wrapf(err, "unable to sync container during YAML generation")
}
mountpoint := c.state.Mountpoint
if mountpoint == "" {
var err error
mountpoint, err = c.mount()
if err != nil {
return nil, errors.Wrapf(err, "failed to mount %s mountpoint", c.ID())
}
defer c.unmount(false)
}
logrus.Debugf("Looking in container for user: %s", c.User())
execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.User(), nil)
execUser, err := lookup.GetUserGroupInfo(mountpoint, c.User(), nil)
if err != nil {
return nil, err
}

View File

@ -734,4 +734,36 @@ ENTRYPOINT /bin/sleep`
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
})
It("podman generate kube based on user in container", func() {
// Build an image with an entrypoint.
containerfile := `FROM quay.io/libpod/alpine:latest
RUN adduser -u 10001 -S test1
USER test1`
targetPath, err := CreateTempDirInTempDir()
Expect(err).To(BeNil())
containerfilePath := filepath.Join(targetPath, "Containerfile")
err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644)
Expect(err).To(BeNil())
image := "generatekube:test"
session := podmanTest.Podman([]string{"build", "-f", containerfilePath, "-t", image})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"create", "--pod", "new:testpod", image, "test1"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
kube := podmanTest.Podman([]string{"generate", "kube", "testpod"})
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
pod := new(v1.Pod)
err = yaml.Unmarshal(kube.Out.Contents(), pod)
Expect(err).To(BeNil())
Expect(*pod.Spec.Containers[0].SecurityContext.RunAsUser).To(Equal(int64(10001)))
})
})