mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-09-19 06:07:50 +00: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:
parent
581a7ec298
commit
a6108f1c19
4 changed files with 95 additions and 43 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue