mirror of
https://github.com/containers/podman.git
synced 2026-10-20 08:55:09 -04:00
Add support for RunAsUser and RunAsGroup
Currently podman generate kube does not generate the correct RunAsUser and RunAsGroup options in the yaml file. This patch fixes this. This patch also make `podman play kube` use the RunAdUser and RunAsGroup options if they are specified in the yaml file. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
4 files changed
+95
-43
No files matched your search
+6
-3
@@ -487,13 +487,16 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) {
|
||||
if err := c.syncContainer(); err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to sync container during YAML generation")
|
||||
}
|
||||
|
||||
logrus.Debugf("Looking in container for user: %s", c.User())
|
||||
u, err := lookup.GetUser(c.state.Mountpoint, c.User())
|
||||
execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.User(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user := int64(u.Uid)
|
||||
sc.RunAsUser = &user
|
||||
uid := int64(execUser.Uid)
|
||||
gid := int64(execUser.Gid)
|
||||
sc.RunAsUser = &uid
|
||||
sc.RunAsGroup = &gid
|
||||
}
|
||||
return &sc, nil
|
||||
}
|
||||
|
||||
+53
-40
@@ -666,6 +666,58 @@ func getPodPorts(containers []v1.Container) []ocicni.PortMapping {
|
||||
return infraPorts
|
||||
}
|
||||
|
||||
func setupSecurityContext(containerConfig *createconfig.CreateConfig, containerYAML v1.Container) {
|
||||
if containerYAML.SecurityContext == nil {
|
||||
return
|
||||
}
|
||||
if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
|
||||
containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
|
||||
}
|
||||
if containerYAML.SecurityContext.Privileged != nil {
|
||||
containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
|
||||
}
|
||||
|
||||
if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
|
||||
containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
|
||||
}
|
||||
|
||||
if seopt := containerYAML.SecurityContext.SELinuxOptions; seopt != nil {
|
||||
if seopt.User != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=user:%s", seopt.User))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("user:%s", seopt.User))
|
||||
}
|
||||
if seopt.Role != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=role:%s", seopt.Role))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("role:%s", seopt.Role))
|
||||
}
|
||||
if seopt.Type != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=type:%s", seopt.Type))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("type:%s", seopt.Type))
|
||||
}
|
||||
if seopt.Level != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=level:%s", seopt.Level))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("level:%s", seopt.Level))
|
||||
}
|
||||
}
|
||||
if caps := containerYAML.SecurityContext.Capabilities; caps != nil {
|
||||
for _, capability := range caps.Add {
|
||||
containerConfig.CapAdd = append(containerConfig.CapAdd, string(capability))
|
||||
}
|
||||
for _, capability := range caps.Drop {
|
||||
containerConfig.CapDrop = append(containerConfig.CapDrop, string(capability))
|
||||
}
|
||||
}
|
||||
if containerYAML.SecurityContext.RunAsUser != nil {
|
||||
containerConfig.User = fmt.Sprintf("%d", *containerYAML.SecurityContext.RunAsUser)
|
||||
}
|
||||
if containerYAML.SecurityContext.RunAsGroup != nil {
|
||||
if containerConfig.User == "" {
|
||||
containerConfig.User = "0"
|
||||
}
|
||||
containerConfig.User = fmt.Sprintf("%s:%d", containerConfig.User, *containerYAML.SecurityContext.RunAsGroup)
|
||||
}
|
||||
}
|
||||
|
||||
// kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container
|
||||
func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string, podID string) (*createconfig.CreateConfig, error) {
|
||||
var (
|
||||
@@ -690,47 +742,8 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
|
||||
containerConfig.User = imageData.Config.User
|
||||
}
|
||||
|
||||
if containerYAML.SecurityContext != nil {
|
||||
if containerConfig.SecurityOpts != nil {
|
||||
if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
|
||||
containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
|
||||
}
|
||||
if containerYAML.SecurityContext.Privileged != nil {
|
||||
containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
|
||||
}
|
||||
setupSecurityContext(&containerConfig, containerYAML)
|
||||
|
||||
if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
|
||||
containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
|
||||
}
|
||||
|
||||
}
|
||||
if seopt := containerYAML.SecurityContext.SELinuxOptions; seopt != nil {
|
||||
if seopt.User != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=user:%s", seopt.User))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("user:%s", seopt.User))
|
||||
}
|
||||
if seopt.Role != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=role:%s", seopt.Role))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("role:%s", seopt.Role))
|
||||
}
|
||||
if seopt.Type != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=type:%s", seopt.Type))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("type:%s", seopt.Type))
|
||||
}
|
||||
if seopt.Level != "" {
|
||||
containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=level:%s", seopt.Level))
|
||||
containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("level:%s", seopt.Level))
|
||||
}
|
||||
}
|
||||
if caps := containerYAML.SecurityContext.Capabilities; caps != nil {
|
||||
for _, capability := range caps.Add {
|
||||
containerConfig.CapAdd = append(containerConfig.CapAdd, string(capability))
|
||||
}
|
||||
for _, capability := range caps.Drop {
|
||||
containerConfig.CapDrop = append(containerConfig.CapDrop, string(capability))
|
||||
}
|
||||
}
|
||||
}
|
||||
var err error
|
||||
containerConfig.SeccompProfilePath, err = libpod.DefaultSeccompPath()
|
||||
if err != nil {
|
||||
|
||||
@@ -208,6 +208,39 @@ var _ = Describe("Podman generate kube", func() {
|
||||
Expect(psOut).To(ContainSubstring("test2"))
|
||||
})
|
||||
|
||||
It("podman generate with user and reimport kube on pod", func() {
|
||||
podName := "toppod"
|
||||
_, rc, _ := podmanTest.CreatePod(podName)
|
||||
Expect(rc).To(Equal(0))
|
||||
|
||||
session := podmanTest.Podman([]string{"create", "--pod", podName, "--name", "test1", "--user", "100:200", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "test1"})
|
||||
inspect.WaitWithDefaultTimeout()
|
||||
Expect(inspect.ExitCode()).To(Equal(0))
|
||||
Expect(inspect.OutputToString()).To(ContainSubstring("100:200"))
|
||||
|
||||
outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml")
|
||||
kube := podmanTest.Podman([]string{"generate", "kube", "-f", outputFile, podName})
|
||||
kube.WaitWithDefaultTimeout()
|
||||
Expect(kube.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "rm", "-af"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"play", "kube", outputFile})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
inspect1 := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "test1"})
|
||||
inspect1.WaitWithDefaultTimeout()
|
||||
Expect(inspect1.ExitCode()).To(Equal(0))
|
||||
Expect(inspect1.OutputToString()).To(ContainSubstring(inspect.OutputToString()))
|
||||
})
|
||||
|
||||
It("podman generate kube with volume", func() {
|
||||
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
|
||||
err := os.MkdirAll(vol1, 0755)
|
||||
|
||||
@@ -24,6 +24,9 @@ spec:
|
||||
name: test
|
||||
resources: {}
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 3000
|
||||
fsGroup: 2000
|
||||
allowPrivilegeEscalation: true
|
||||
capabilities: {}
|
||||
privileged: false
|
||||
|
||||
Reference in new issue
Block a user