Skip to content

Commit

Permalink
Merge pull request #20887 from ygalblum/quadlet-pod-quadlet-based-keys
Browse files Browse the repository at this point in the history
Quadlet - add support for keys that may refer to other Quadlet units in `.pod` files
  • Loading branch information
openshift-merge-bot[bot] authored Dec 4, 2023
2 parents 70bcf3e + 7e2a8d5 commit 093868b
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 34 deletions.
2 changes: 1 addition & 1 deletion cmd/quadlet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ func process() error {
warnIfAmbiguousName(unit, quadlet.ImageGroup)
service, name, err = quadlet.ConvertImage(unit)
case strings.HasSuffix(unit.Filename, ".pod"):
service, err = quadlet.ConvertPod(unit, unit.Filename, podsInfoMap)
service, err = quadlet.ConvertPod(unit, unit.Filename, podsInfoMap, resourceNames)
default:
Logf("Unsupported file type %q", unit.Filename)
continue
Expand Down
29 changes: 29 additions & 0 deletions docs/source/markdown/podman-systemd.unit.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,10 @@ Valid options for `[Pod]` are listed below:
|-------------------------------------|----------------------------------------|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
| GlobalArgs=--log-level=debug | --log-level=debug |
| Network=host | --network host |
| PodmanArgs=\-\-cpus=2 | --cpus=2 |
| PodName=name | --name=name |
| Volume=/source:/dest | --volume /source:/dest |

Supported keys in the `[Pod]` section are:

Expand All @@ -732,6 +734,19 @@ escaped to allow inclusion of whitespace and other control characters.

This key can be listed multiple times.

### `Network=`

Specify a custom network for the pod.
This has the same format as the `--network` option to `podman pod create`.
For example, use `host` to use the host network in the pod, or `none` to not set up networking in the pod.

As a special case, if the `name` of the network ends with `.network`, Quadlet will look for the corresponding `.network` Quadlet unit.
If found, Quadlet will use the name of the Network set in the Unit, otherwise, `systemd-$name` is used.
The generated systemd service contains a dependency on the service unit generated for that `.network` unit,
or on `$name-network.service` if the `.network` unit is not found

This key can be listed multiple times.

### `PodmanArgs=`

This key contains a list of arguments passed directly to the end of the `podman pod create` command
Expand All @@ -753,6 +768,20 @@ prefix to avoid conflicts with user-managed containers.
Please note that pods and containers cannot have the same name.
So, if PodName is set, it must not conflict with any container.

### `Volume=`

Mount a volume in the pod. This is equivalent to the Podman `--volume` option, and
generally has the form `[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]`.

If `SOURCE-VOLUME` starts with `.`, Quadlet resolves the path relative to the location of the unit file.

As a special case, if `SOURCE-VOLUME` ends with `.volume`, Quadlet will look for the corresponding `.volume` Quadlet unit.
If found, Quadlet will use the name of the Volume set in the Unit, otherwise, `systemd-$name` is used.
The generated systemd service contains a dependency on the service unit generated for that `.volume` unit,
or on `$name-volume.service` if the `.volume` unit is not found

This key can be listed multiple times.

## Kube units [Kube]

Kube units are named with a `.kube` extension and contain a `[Kube]` section describing
Expand Down
82 changes: 49 additions & 33 deletions pkg/systemd/quadlet/quadlet.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,10 @@ var (
supportedPodKeys = map[string]bool{
KeyContainersConfModule: true,
KeyGlobalArgs: true,
KeyNetwork: true,
KeyPodmanArgs: true,
KeyPodName: true,
KeyVolume: true,
}
)

Expand Down Expand Up @@ -666,37 +668,8 @@ func ConvertContainer(container *parser.UnitFile, names map[string]string, isUse
podman.add("--tmpfs", tmpfs)
}

volumes := container.LookupAll(ContainerGroup, KeyVolume)
for _, volume := range volumes {
parts := strings.SplitN(volume, ":", 3)

source := ""
var dest string
options := ""
if len(parts) >= 2 {
source = parts[0]
dest = parts[1]
} else {
dest = parts[0]
}
if len(parts) >= 3 {
options = ":" + parts[2]
}

if source != "" {
var err error
source, err = handleStorageSource(container, service, source, names)
if err != nil {
return nil, err
}
}

podman.add("-v")
if source == "" {
podman.add(dest)
} else {
podman.addf("%s:%s%s", source, dest, options)
}
if err := addVolumes(container, service, ContainerGroup, names, podman); err != nil {
return nil, err
}

update, ok := container.Lookup(ContainerGroup, KeyAutoUpdate)
Expand Down Expand Up @@ -1253,14 +1226,14 @@ func GetPodServiceName(podUnit *parser.UnitFile) string {
return replaceExtension(podUnit.Filename, "", "", "-pod")
}

func ConvertPod(podUnit *parser.UnitFile, name string, podsInfoMap map[string]*PodInfo) (*parser.UnitFile, error) {
func ConvertPod(podUnit *parser.UnitFile, name string, podsInfoMap map[string]*PodInfo, names map[string]string) (*parser.UnitFile, error) {
podInfo, ok := podsInfoMap[podUnit.Filename]
if !ok {
return nil, fmt.Errorf("internal error while processing pod %s", podUnit.Filename)
}

service := podUnit.Dup()
service.Filename = replaceExtension(podInfo.ServiceName, ".service", "", "")
service.Filename = fmt.Sprintf("%s.service", podInfo.ServiceName)

if podUnit.Path != "" {
service.Add(UnitGroup, "SourcePath", podUnit.Path)
Expand Down Expand Up @@ -1322,6 +1295,12 @@ func ConvertPod(podUnit *parser.UnitFile, name string, podsInfoMap map[string]*P
"--replace",
)

addNetworks(podUnit, PodGroup, service, names, execStartPre)

if err := addVolumes(podUnit, service, PodGroup, names, execStartPre); err != nil {
return nil, err
}

execStartPre.addf("--name=%s", podName)

handlePodmanArgs(podUnit, PodGroup, execStartPre)
Expand Down Expand Up @@ -1821,3 +1800,40 @@ func handlePod(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName stri
}
return nil
}

func addVolumes(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName string, names map[string]string, podman *PodmanCmdline) error {
volumes := quadletUnitFile.LookupAll(groupName, KeyVolume)
for _, volume := range volumes {
parts := strings.SplitN(volume, ":", 3)

source := ""
var dest string
options := ""
if len(parts) >= 2 {
source = parts[0]
dest = parts[1]
} else {
dest = parts[0]
}
if len(parts) >= 3 {
options = ":" + parts[2]
}

if source != "" {
var err error
source, err = handleStorageSource(quadletUnitFile, serviceUnitFile, source, names)
if err != nil {
return err
}
}

podman.add("-v")
if source == "" {
podman.add(dest)
} else {
podman.addf("%s:%s%s", source, dest, options)
}
}

return nil
}
4 changes: 4 additions & 0 deletions test/e2e/quadlet/network.pod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## assert-podman-pre-args "--network=host"

[Pod]
Network=host
6 changes: 6 additions & 0 deletions test/e2e/quadlet/network.quadlet.pod
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## assert-podman-pre-args "--network=systemd-basic"
## assert-key-is "Unit" "Requires" "basic-network.service"
## assert-key-is "Unit" "After" "basic-network.service"

[Pod]
Network=basic.network
15 changes: 15 additions & 0 deletions test/e2e/quadlet/volume.pod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## assert-podman-pre-args -v /host/dir:/container/volume
## assert-podman-pre-args -v /host/dir2:/container/volume2:Z
## assert-podman-pre-args-regex -v .*/podman_test.*/quadlet/host/dir3:/container/volume3
## assert-podman-pre-args -v named:/container/named
## assert-podman-pre-args -v systemd-quadlet:/container/quadlet
## assert-podman-pre-args -v %h/container:/container/volume4

[Pod]
Volume=/host/dir:/container/volume
Volume=/host/dir2:/container/volume2:Z
Volume=./host/dir3:/container/volume3
Volume=/container/empty
Volume=named:/container/named
Volume=quadlet.volume:/container/quadlet
Volume=%h/container:/container/volume4
3 changes: 3 additions & 0 deletions test/e2e/quadlet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,10 @@ BOGUS=foo

Entry("basic.pod", "basic.pod", 0, ""),
Entry("name.pod", "name.pod", 0, ""),
Entry("network.pod", "network.pod", 0, ""),
Entry("network-quadlet.pod", "network.quadlet.pod", 0, ""),
Entry("podmanargs.pod", "podmanargs.pod", 0, ""),
Entry("volume.pod", "volume.pod", 0, ""),
)

})

0 comments on commit 093868b

Please sign in to comment.