diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index df0fca37c3..b87cd6af18 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -412,6 +412,23 @@ Set one or more OCI labels on the volume. The format is a list of This key can be listed multiple times. +#### `Device=` + +The path of a device which should be mounted for the volume. + +#### `Type=` + +The filesystem type of `Device` as used by the **mount(8)** commands `-t` option. + +#### `Options=` + +The mount options to use for a filesystem as used by the **mount(8)** command `-o` option. + +#### `Copy=` (default to `yes`) + +If enabled, the content of the image located at the mountpoint of the volume is copied into the +volume on the first run. + ### Network units Network files are named with a `.network` extension and contain a section `[Network]` describing the diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 5254e2c956..d138a0dd15 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -50,6 +50,10 @@ const ( KeyPublishPort = "PublishPort" KeyUser = "User" KeyGroup = "Group" + KeyDevice = "Device" + KeyType = "Type" + KeyOptions = "Options" + KeyCopy = "Copy" KeyVolume = "Volume" KeyPodmanArgs = "PodmanArgs" KeyLabel = "Label" @@ -111,9 +115,13 @@ var ( // Supported keys in "Volume" group supportedVolumeKeys = map[string]bool{ - KeyUser: true, - KeyGroup: true, - KeyLabel: true, + KeyUser: true, + KeyGroup: true, + KeyDevice: true, + KeyType: true, + KeyOptions: true, + KeyCopy: true, + KeyLabel: true, } // Supported keys in "Volume" group @@ -622,6 +630,44 @@ func ConvertVolume(volume *parser.UnitFile, name string) (*parser.UnitFile, erro opts.WriteString(fmt.Sprintf("gid=%d", gid)) } + copy, ok := volume.LookupBoolean(VolumeGroup, KeyCopy) + if ok { + if copy { + podman.add("--opt", "copy") + } else { + podman.add("--opt", "nocopy") + } + } + + devValid := false + + dev, ok := volume.Lookup(VolumeGroup, KeyDevice) + if ok && len(dev) != 0 { + podman.add("--opt", fmt.Sprintf("device=%s", dev)) + devValid = true + } + + devType, ok := volume.Lookup(VolumeGroup, KeyType) + if ok && len(devType) != 0 { + if devValid { + podman.add("--opt", fmt.Sprintf("type=%s", devType)) + } else { + return nil, fmt.Errorf("key Type can't be used without Device") + } + } + + mountOpts, ok := volume.Lookup(VolumeGroup, KeyOptions) + if ok && len(mountOpts) != 0 { + if devValid { + if opts.Len() > 2 { + opts.WriteString(",") + } + opts.WriteString(mountOpts) + } else { + return nil, fmt.Errorf("key Options can't be used without Device") + } + } + if opts.Len() > 2 { podman.add("--opt", opts.String()) } diff --git a/test/e2e/quadlet/device-copy.volume b/test/e2e/quadlet/device-copy.volume new file mode 100644 index 0000000000..0e7405e222 --- /dev/null +++ b/test/e2e/quadlet/device-copy.volume @@ -0,0 +1,13 @@ +## assert-key-contains Service ExecStart " --opt o=uid=0,gid=11,rw,compress=zstd " +## assert-key-contains Service ExecStart " --opt type=btrfs " +## assert-key-contains Service ExecStart " --opt device=/dev/vda1 " +## assert-key-contains Service ExecStart " --opt copy " + +[Volume] +# Test usernames too +User=root +Group=11 +Device=/dev/vda1 +Type=btrfs +Options=rw,compress=zstd +Copy=yes diff --git a/test/e2e/quadlet/device.volume b/test/e2e/quadlet/device.volume new file mode 100644 index 0000000000..4e742a38c4 --- /dev/null +++ b/test/e2e/quadlet/device.volume @@ -0,0 +1,13 @@ +## assert-key-contains Service ExecStart " --opt o=uid=0,gid=11,rw,compress=zstd " +## assert-key-contains Service ExecStart " --opt type=btrfs " +## assert-key-contains Service ExecStart " --opt device=/dev/vda1 " +## assert-key-contains Service ExecStart " --opt nocopy " + +[Volume] +# Test usernames too +User=root +Group=11 +Device=/dev/vda1 +Type=btrfs +Options=rw,compress=zstd +Copy=no diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index a4a1b7f219..69324720c2 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -482,6 +482,7 @@ var _ = Describe("quadlet system generator", func() { Entry("basic.volume", "basic.volume"), Entry("label.volume", "label.volume"), Entry("uid.volume", "uid.volume"), + Entry("device.volume", "device-copy.volume"), Entry("Basic kube", "basic.kube"), Entry("Syslog Identifier", "syslog.identifier.kube"),