diff --git a/cmd/quadlet/main.go b/cmd/quadlet/main.go index 18e46c07f5..1e17ace588 100644 --- a/cmd/quadlet/main.go +++ b/cmd/quadlet/main.go @@ -336,7 +336,7 @@ func main() { case strings.HasSuffix(name, ".volume"): service, err = quadlet.ConvertVolume(unit, name) case strings.HasSuffix(name, ".kube"): - service, err = quadlet.ConvertKube(unit) + service, err = quadlet.ConvertKube(unit, isUser) default: Logf("Unsupported file type '%s'", name) continue diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 97a66ba4c4..f78dd32453 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -101,7 +101,11 @@ var supportedVolumeKeys = map[string]bool{ // Supported keys in "Kube" group var supportedKubeKeys = map[string]bool{ - KeyYaml: true, + KeyYaml: true, + KeyRemapUID: true, + KeyRemapGID: true, + KeyRemapUsers: true, + KeyRemapUIDSize: true, } func replaceExtension(name string, extension string, extraPrefix string, extraSuffix string) string { @@ -351,48 +355,8 @@ func ConvertContainer(container *parser.UnitFile, isUser bool) (*parser.UnitFile } } - uidMaps := container.LookupAllStrv(ContainerGroup, KeyRemapUID) - gidMaps := container.LookupAllStrv(ContainerGroup, KeyRemapGID) - - remapUsers, ok := container.LookupLast(ContainerGroup, KeyRemapUsers) - if ok && remapUsers != "" { - switch remapUsers { - case "": - if len(uidMaps) > 0 { - return nil, fmt.Errorf("UidMap set without RemapUsers") - } - if len(gidMaps) > 0 { - return nil, fmt.Errorf("GidMap set without RemapUsers") - } - case "manual": - for _, uidMap := range uidMaps { - podman.addf("--uidmap=%s", uidMap) - } - for _, gidMap := range gidMaps { - podman.addf("--gidmap=%s", gidMap) - } - case "auto": - autoOpts := make([]string, 0) - for _, uidMap := range uidMaps { - autoOpts = append(autoOpts, "uidmapping="+uidMap) - } - for _, gidMap := range gidMaps { - autoOpts = append(autoOpts, "gidmapping="+gidMap) - } - uidSize := container.LookupUint32(ContainerGroup, KeyRemapUIDSize, 0) - if uidSize > 0 { - autoOpts = append(autoOpts, fmt.Sprintf("size=%v", uidSize)) - } - - podman.addf("--userns=" + usernsOpts("auto", autoOpts)) - case "keep-id": - if !isUser { - return nil, fmt.Errorf("RemapUsers=keep-id is unsupported for system units") - } - podman.addf("--userns=keep-id") - default: - return nil, fmt.Errorf("unsupported RemapUsers option '%s'", remapUsers) - } + if err := handleUserRemap(container, ContainerGroup, podman, isUser, true); err != nil { + return nil, err } volumes := container.LookupAll(ContainerGroup, KeyVolume) @@ -593,7 +557,7 @@ func ConvertVolume(volume *parser.UnitFile, name string) (*parser.UnitFile, erro return service, nil } -func ConvertKube(kube *parser.UnitFile) (*parser.UnitFile, error) { +func ConvertKube(kube *parser.UnitFile, isUser bool) (*parser.UnitFile, error) { service := kube.Dup() service.Filename = replaceExtension(kube.Filename, ".service", "", "") @@ -660,6 +624,10 @@ func ConvertKube(kube *parser.UnitFile) (*parser.UnitFile, error) { "--service-container=true", ) + if err := handleUserRemap(kube, KubeGroup, execStart, isUser, false); err != nil { + return nil, err + } + execStart.add(yamlPath) service.AddCmdline(ServiceGroup, "ExecStart", execStart.Args) @@ -670,3 +638,52 @@ func ConvertKube(kube *parser.UnitFile) (*parser.UnitFile, error) { return service, nil } + +func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline, isUser, supportManual bool) error { + uidMaps := unitFile.LookupAllStrv(groupName, KeyRemapUID) + gidMaps := unitFile.LookupAllStrv(groupName, KeyRemapGID) + remapUsers, _ := unitFile.LookupLast(groupName, KeyRemapUsers) + switch remapUsers { + case "": + if len(uidMaps) > 0 { + return fmt.Errorf("UidMap set without RemapUsers") + } + if len(gidMaps) > 0 { + return fmt.Errorf("GidMap set without RemapUsers") + } + case "manual": + if supportManual { + for _, uidMap := range uidMaps { + podman.addf("--uidmap=%s", uidMap) + } + for _, gidMap := range gidMaps { + podman.addf("--gidmap=%s", gidMap) + } + } else { + return fmt.Errorf("RemapUsers=manual is not supported") + } + case "auto": + autoOpts := make([]string, 0) + for _, uidMap := range uidMaps { + autoOpts = append(autoOpts, "uidmapping="+uidMap) + } + for _, gidMap := range gidMaps { + autoOpts = append(autoOpts, "gidmapping="+gidMap) + } + uidSize := unitFile.LookupUint32(groupName, KeyRemapUIDSize, 0) + if uidSize > 0 { + autoOpts = append(autoOpts, fmt.Sprintf("size=%v", uidSize)) + } + + podman.addf("--userns=" + usernsOpts("auto", autoOpts)) + case "keep-id": + if !isUser { + return fmt.Errorf("RemapUsers=keep-id is unsupported for system units") + } + podman.addf("--userns=keep-id") + default: + return fmt.Errorf("unsupported RemapUsers option '%s'", remapUsers) + } + + return nil +} diff --git a/test/e2e/quadlet/remap-auto.kube b/test/e2e/quadlet/remap-auto.kube new file mode 100644 index 0000000000..95189573f2 --- /dev/null +++ b/test/e2e/quadlet/remap-auto.kube @@ -0,0 +1,5 @@ +## assert-podman-args --userns=auto + +[Kube] +Yaml=/opt/k8s/deployment.yml +RemapUsers=auto diff --git a/test/e2e/quadlet/remap-auto2.kube b/test/e2e/quadlet/remap-auto2.kube new file mode 100644 index 0000000000..bc37033c2a --- /dev/null +++ b/test/e2e/quadlet/remap-auto2.kube @@ -0,0 +1,10 @@ +## assert-podman-args "--userns=auto:uidmapping=0:10000:10,uidmapping=10:20000:10,gidmapping=0:10000:10,gidmapping=10:20000:10,size=20" + +[Kube] +Yaml=/opt/k8s/deployment.yml +RemapUsers=auto +RemapUid=0:10000:10 +RemapUid=10:20000:10 +RemapGid=0:10000:10 +RemapGid=10:20000:10 +RemapUidSize=20 diff --git a/test/e2e/quadlet/remap-manual.kube b/test/e2e/quadlet/remap-manual.kube new file mode 100644 index 0000000000..a676e66b10 --- /dev/null +++ b/test/e2e/quadlet/remap-manual.kube @@ -0,0 +1,10 @@ +## assert-failed +## assert-stderr-contains "RemapUsers=manual is not supported" + +[Kube] +Yaml=/opt/k8s/deployment.yml +RemapUsers=manual +RemapUid=0:10000:10 +RemapUid=10:20000:10 +RemapGid=0:10000:10 +RemapGid=10:20000:10 diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index 8c14d712b4..ec91ed61c9 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -359,6 +359,9 @@ var _ = Describe("quadlet system generator", func() { Entry("Basic kube", "basic.kube"), Entry("Syslog Identifier", "syslog.identifier.kube"), Entry("Absolute Path", "absolute.path.kube"), + Entry("Kube - User Remap Manual", "remap-manual.kube"), + Entry("Kube - User Remap Auto", "remap-auto.kube"), + Entry("Kube - User Remap Auto with IDs", "remap-auto2.kube"), ) })