mirror of
https://github.com/containers/podman.git
synced 2025-05-21 09:05:56 +08:00
Merge pull request #19256 from ygalblum/quadlet-working-dir
Quadlet - Allow setting Service WorkingDirectory for Kube units
This commit is contained in:
@ -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:
|
Valid options for `[Kube]` are listed below:
|
||||||
|
|
||||||
| **[Kube] options** | **podman kube play equivalent** |
|
| **[Kube] options** | **podman kube play equivalent** |
|
||||||
| ----------------------------------- | ------------------------------------------------ |
|
| ----------------------------------- | -----------------------------------------------------------------|
|
||||||
| AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" |
|
| AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" |
|
||||||
| ConfigMap=/tmp/config.map | --config-map /tmp/config.map |
|
| ConfigMap=/tmp/config.map | --config-map /tmp/config.map |
|
||||||
| LogDriver=journald | --log-driver journald |
|
| LogDriver=journald | --log-driver journald |
|
||||||
| Network=host | --net host |
|
| Network=host | --net host |
|
||||||
| PodmanArgs=\-\-annotation=key=value | --annotation=key=value |
|
| PodmanArgs=\-\-annotation=key=value | --annotation=key=value |
|
||||||
| PublishPort=59-60 | --publish=59-60 |
|
| PublishPort=59-60 | --publish=59-60 |
|
||||||
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
| SetWorkingDirectory=yaml | Set `WorkingDirectory` of unit file to location of the YAML file |
|
||||||
| Yaml=/tmp/kube.yaml | podman kube play /tmp/kube.yaml |
|
| 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:
|
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.
|
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=`
|
### `Unmask=`
|
||||||
|
|
||||||
Specify the paths to unmask separated by a colon. unmask=ALL or /path/1:/path/2, or shell expanded paths (/proc/*):
|
Specify the paths to unmask separated by a colon. unmask=ALL or /path/1:/path/2, or shell expanded paths (/proc/*):
|
||||||
|
@ -35,6 +35,11 @@ const (
|
|||||||
XVolumeGroup = "X-Volume"
|
XVolumeGroup = "X-Volume"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Systemd Unit file keys
|
||||||
|
const (
|
||||||
|
ServiceKeyWorkingDirectory = "WorkingDirectory"
|
||||||
|
)
|
||||||
|
|
||||||
// All the supported quadlet keys
|
// All the supported quadlet keys
|
||||||
const (
|
const (
|
||||||
KeyAddCapability = "AddCapability"
|
KeyAddCapability = "AddCapability"
|
||||||
@ -103,6 +108,7 @@ const (
|
|||||||
KeySecurityLabelNested = "SecurityLabelNested"
|
KeySecurityLabelNested = "SecurityLabelNested"
|
||||||
KeySecurityLabelType = "SecurityLabelType"
|
KeySecurityLabelType = "SecurityLabelType"
|
||||||
KeySecret = "Secret"
|
KeySecret = "Secret"
|
||||||
|
KeySetWorkingDirectory = "SetWorkingDirectory"
|
||||||
KeySysctl = "Sysctl"
|
KeySysctl = "Sysctl"
|
||||||
KeyTimezone = "Timezone"
|
KeyTimezone = "Timezone"
|
||||||
KeyTmpfs = "Tmpfs"
|
KeyTmpfs = "Tmpfs"
|
||||||
@ -226,6 +232,7 @@ var (
|
|||||||
KeyRemapUID: true,
|
KeyRemapUID: true,
|
||||||
KeyRemapUIDSize: true,
|
KeyRemapUIDSize: true,
|
||||||
KeyRemapUsers: true,
|
KeyRemapUsers: true,
|
||||||
|
KeySetWorkingDirectory: true,
|
||||||
KeyUserNS: true,
|
KeyUserNS: true,
|
||||||
KeyYaml: true,
|
KeyYaml: true,
|
||||||
}
|
}
|
||||||
@ -1019,6 +1026,11 @@ func ConvertKube(kube *parser.UnitFile, names map[string]string, isUser bool) (*
|
|||||||
execStop.add(yamlPath)
|
execStop.add(yamlPath)
|
||||||
service.AddCmdline(ServiceGroup, "ExecStopPost", execStop.Args)
|
service.AddCmdline(ServiceGroup, "ExecStopPost", execStop.Args)
|
||||||
|
|
||||||
|
err = handleSetWorkingDirectory(kube, service)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return service, nil
|
return service, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,3 +1300,38 @@ func handlePodmanArgs(unitFile *parser.UnitFile, groupName string, podman *Podma
|
|||||||
podman.add(podmanArgs...)
|
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
|
||||||
|
}
|
||||||
|
8
test/e2e/quadlet/workingdir-service.kube
Normal file
8
test/e2e/quadlet/workingdir-service.kube
Normal 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
|
5
test/e2e/quadlet/workingdir-unit.kube
Normal file
5
test/e2e/quadlet/workingdir-unit.kube
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## assert-key-is-regex "Service" "WorkingDirectory" ".*/podman_test.*/quadlet"
|
||||||
|
|
||||||
|
[Kube]
|
||||||
|
Yaml=deployment.yml
|
||||||
|
SetWorkingDirectory=unit
|
5
test/e2e/quadlet/workingdir-yaml-abs.kube
Normal file
5
test/e2e/quadlet/workingdir-yaml-abs.kube
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## assert-key-is "Service" "WorkingDirectory" "/etc/containers/systemd"
|
||||||
|
|
||||||
|
[Kube]
|
||||||
|
Yaml=/etc/containers/systemd/deployment.yml
|
||||||
|
SetWorkingDirectory=yaml
|
5
test/e2e/quadlet/workingdir-yaml-rel.kube
Normal file
5
test/e2e/quadlet/workingdir-yaml-rel.kube
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## assert-key-is-regex "Service" "WorkingDirectory" ".*/podman_test.*/quadlet/myservice"
|
||||||
|
|
||||||
|
[Kube]
|
||||||
|
Yaml=./myservice/deployment.yml
|
||||||
|
SetWorkingDirectory=yaml
|
@ -624,6 +624,10 @@ BOGUS=foo
|
|||||||
Entry("Kube - User Remap Auto", "remap-auto.kube", 0, ""),
|
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("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("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 - Basic", "basic.network", 0, ""),
|
||||||
Entry("Network - Disable DNS", "disable-dns.network", 0, ""),
|
Entry("Network - Disable DNS", "disable-dns.network", 0, ""),
|
||||||
|
@ -923,4 +923,64 @@ EOF
|
|||||||
run_podman rmi $(pause_image)
|
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
|
# vim: filetype=sh
|
||||||
|
Reference in New Issue
Block a user