Merge pull request #19256 from ygalblum/quadlet-working-dir

Quadlet - Allow setting Service WorkingDirectory for Kube units
This commit is contained in:
OpenShift Merge Robot
2023-07-19 13:45:42 +02:00
committed by GitHub
8 changed files with 155 additions and 10 deletions

View File

@ -517,16 +517,17 @@ There is only one required key, `Yaml`, which defines the path to the Kubernetes
Valid options for `[Kube]` are listed below:
| **[Kube] options** | **podman kube play equivalent** |
| ----------------------------------- | ------------------------------------------------ |
| AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" |
| ConfigMap=/tmp/config.map | --config-map /tmp/config.map |
| LogDriver=journald | --log-driver journald |
| Network=host | --net host |
| PodmanArgs=\-\-annotation=key=value | --annotation=key=value |
| PublishPort=59-60 | --publish=59-60 |
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
| Yaml=/tmp/kube.yaml | podman kube play /tmp/kube.yaml |
| **[Kube] options** | **podman kube play equivalent** |
| ----------------------------------- | -----------------------------------------------------------------|
| AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" |
| ConfigMap=/tmp/config.map | --config-map /tmp/config.map |
| LogDriver=journald | --log-driver journald |
| Network=host | --net host |
| PodmanArgs=\-\-annotation=key=value | --annotation=key=value |
| PublishPort=59-60 | --publish=59-60 |
| SetWorkingDirectory=yaml | Set `WorkingDirectory` of unit file to location of the YAML file |
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
| Yaml=/tmp/kube.yaml | podman kube play /tmp/kube.yaml |
Supported keys in the `[Kube]` section are:
@ -609,6 +610,16 @@ entry from the unit file takes precedence
This key can be listed multiple times.
### `SetWorkingDirectory=`
Set the `WorkingDirectory` field of the `Service` group of the Systemd service unit file.
Used to allow `podman kube play` to correctly resolve relative paths.
Supported values are `yaml` and `unit` to set the working directory to that of the YAML or Quadlet Unit file respectively.
Alternatively, users can explicitly set the `WorkingDirectory` field of the `Service` group in the `.kube` file.
Please note that if the `WorkingDirectory` field of the `Service` group is set,
Quadlet will not set it even if `SetWorkingDirectory` is set
### `Unmask=`
Specify the paths to unmask separated by a colon. unmask=ALL or /path/1:/path/2, or shell expanded paths (/proc/*):

View File

@ -35,6 +35,11 @@ const (
XVolumeGroup = "X-Volume"
)
// Systemd Unit file keys
const (
ServiceKeyWorkingDirectory = "WorkingDirectory"
)
// All the supported quadlet keys
const (
KeyAddCapability = "AddCapability"
@ -103,6 +108,7 @@ const (
KeySecurityLabelNested = "SecurityLabelNested"
KeySecurityLabelType = "SecurityLabelType"
KeySecret = "Secret"
KeySetWorkingDirectory = "SetWorkingDirectory"
KeySysctl = "Sysctl"
KeyTimezone = "Timezone"
KeyTmpfs = "Tmpfs"
@ -226,6 +232,7 @@ var (
KeyRemapUID: true,
KeyRemapUIDSize: true,
KeyRemapUsers: true,
KeySetWorkingDirectory: true,
KeyUserNS: true,
KeyYaml: true,
}
@ -1019,6 +1026,11 @@ func ConvertKube(kube *parser.UnitFile, names map[string]string, isUser bool) (*
execStop.add(yamlPath)
service.AddCmdline(ServiceGroup, "ExecStopPost", execStop.Args)
err = handleSetWorkingDirectory(kube, service)
if err != nil {
return nil, err
}
return service, nil
}
@ -1288,3 +1300,38 @@ func handlePodmanArgs(unitFile *parser.UnitFile, groupName string, podman *Podma
podman.add(podmanArgs...)
}
}
func handleSetWorkingDirectory(kube, serviceUnitFile *parser.UnitFile) error {
// If WorkingDirectory is already set in the Service section do not change it
workingDir, ok := kube.Lookup(ServiceGroup, ServiceKeyWorkingDirectory)
if ok && len(workingDir) > 0 {
return nil
}
setWorkingDirectory, ok := kube.Lookup(KubeGroup, KeySetWorkingDirectory)
if !ok || len(setWorkingDirectory) == 0 {
return nil
}
var relativeToFile string
switch strings.ToLower(setWorkingDirectory) {
case "yaml":
relativeToFile, ok = kube.Lookup(KubeGroup, KeyYaml)
if !ok {
return fmt.Errorf("no Yaml key specified")
}
case "unit":
relativeToFile = kube.Path
default:
return fmt.Errorf("unsupported value for %s: %s ", ServiceKeyWorkingDirectory, setWorkingDirectory)
}
fileInWorkingDir, err := getAbsolutePath(kube, relativeToFile)
if err != nil {
return err
}
serviceUnitFile.Add(ServiceGroup, ServiceKeyWorkingDirectory, filepath.Dir(fileInWorkingDir))
return nil
}

View File

@ -0,0 +1,8 @@
## assert-key-is-regex "Service" "WorkingDirectory" "/etc/containers/systemd"
[Service]
WorkingDirectory=/etc/containers/systemd
[Kube]
Yaml=deployment.yml
SetWorkingDirectory=unit

View File

@ -0,0 +1,5 @@
## assert-key-is-regex "Service" "WorkingDirectory" ".*/podman_test.*/quadlet"
[Kube]
Yaml=deployment.yml
SetWorkingDirectory=unit

View File

@ -0,0 +1,5 @@
## assert-key-is "Service" "WorkingDirectory" "/etc/containers/systemd"
[Kube]
Yaml=/etc/containers/systemd/deployment.yml
SetWorkingDirectory=yaml

View File

@ -0,0 +1,5 @@
## assert-key-is-regex "Service" "WorkingDirectory" ".*/podman_test.*/quadlet/myservice"
[Kube]
Yaml=./myservice/deployment.yml
SetWorkingDirectory=yaml

View File

@ -624,6 +624,10 @@ BOGUS=foo
Entry("Kube - User Remap Auto", "remap-auto.kube", 0, ""),
Entry("Kube - User Remap Manual", "remap-manual.kube", 1, "converting \"remap-manual.kube\": RemapUsers=manual is not supported"),
Entry("Syslog Identifier", "syslog.identifier.kube", 0, ""),
Entry("Kube - Working Directory YAML Absolute Path", "workingdir-yaml-abs.kube", 0, ""),
Entry("Kube - Working Directory YAML Relative Path", "workingdir-yaml-rel.kube", 0, ""),
Entry("Kube - Working Directory Unit", "workingdir-unit.kube", 0, ""),
Entry("Kube - Working Directory already in Service", "workingdir-service.kube", 0, ""),
Entry("Network - Basic", "basic.network", 0, ""),
Entry("Network - Disable DNS", "disable-dns.network", 0, ""),

View File

@ -923,4 +923,64 @@ EOF
run_podman rmi $(pause_image)
}
@test "quadlet kube - Working Directory" {
yaml_source="$PODMAN_TMPDIR/basic_$(random_string).yaml"
local_path=local_path$(random_string)
pod_name=test_pod
container_name=test
cat >$yaml_source <<EOF
apiVersion: v1
kind: Pod
metadata:
labels:
app: test
name: $pod_name
spec:
containers:
- command:
- "sh"
args:
- "-c"
- "echo STARTED CONTAINER; top -b"
image: $IMAGE
name: $container_name
volumeMounts:
- mountPath: /test
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: ./$local_path
# this field is optional
type: DirectoryOrCreate
EOF
# Create the Quadlet file
local quadlet_file=$PODMAN_TMPDIR/basic_$(random_string).kube
cat > $quadlet_file <<EOF
[Kube]
Yaml=${yaml_source}
SetWorkingDirectory=yaml
EOF
run_quadlet "$quadlet_file"
service_setup $QUADLET_SERVICE_NAME
# Ensure we have output.
wait_for_output "STARTED CONTAINER" $pod_name-$container_name
run_podman container inspect --format "{{.State.Status}}" $pod_name-$container_name
is "$output" "running" "container should be started by systemd and hence be running"
run_podman ps
run_podman exec $pod_name-$container_name /bin/sh -c "echo hello > /test/test.txt"
is $(cat $PODMAN_TMPDIR/$local_path/test.txt) "hello"
service_cleanup $QUADLET_SERVICE_NAME inactive
run_podman rmi $(pause_image)
}
# vim: filetype=sh