mirror of
https://github.com/containers/podman
synced 2024-10-19 08:44:11 +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
|
@ -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…
Reference in a new issue