From d974a79e27ea1f4620aaa24d056ae5263d504185 Mon Sep 17 00:00:00 2001 From: Ygal Blum Date: Tue, 29 Nov 2022 14:31:48 +0200 Subject: [PATCH] Quadlet: add network support Support .network file to create a systemd service that runs podman network create Support networks with .network suffix in Container and Kube to link with Quadlet created networks Add E2E Tests Add man doc Signed-off-by: Ygal Blum --- cmd/quadlet/main.go | 3 + docs/source/markdown/podman-systemd.unit.5.md | 90 +++++++- pkg/systemd/quadlet/quadlet.go | 209 +++++++++++++++--- test/e2e/quadlet/basic.network | 7 + test/e2e/quadlet/disable-dns.network | 5 + test/e2e/quadlet/driver.network | 5 + test/e2e/quadlet/gateway.less-subnet.network | 7 + test/e2e/quadlet/gateway.network | 6 + test/e2e/quadlet/gateway.no-subnet.network | 5 + test/e2e/quadlet/internal.network | 5 + test/e2e/quadlet/ipam-driver.network | 5 + test/e2e/quadlet/ipv6.network | 5 + test/e2e/quadlet/label.network | 11 + test/e2e/quadlet/network.kube | 5 + test/e2e/quadlet/network.quadlet.container | 7 + test/e2e/quadlet/network.quadlet.kube | 8 + test/e2e/quadlet/options.multiple.network | 7 + test/e2e/quadlet/options.network | 5 + test/e2e/quadlet/range.less-subnet.network | 7 + test/e2e/quadlet/range.network | 6 + test/e2e/quadlet/range.no-subnet.network | 5 + test/e2e/quadlet/subnet-trio.multiple.network | 11 + test/e2e/quadlet/subnet-trio.network | 7 + test/e2e/quadlet/subnets.network | 7 + test/e2e/quadlet_test.go | 27 ++- 25 files changed, 427 insertions(+), 38 deletions(-) create mode 100644 test/e2e/quadlet/basic.network create mode 100644 test/e2e/quadlet/disable-dns.network create mode 100644 test/e2e/quadlet/driver.network create mode 100644 test/e2e/quadlet/gateway.less-subnet.network create mode 100644 test/e2e/quadlet/gateway.network create mode 100644 test/e2e/quadlet/gateway.no-subnet.network create mode 100644 test/e2e/quadlet/internal.network create mode 100644 test/e2e/quadlet/ipam-driver.network create mode 100644 test/e2e/quadlet/ipv6.network create mode 100644 test/e2e/quadlet/label.network create mode 100644 test/e2e/quadlet/network.kube create mode 100644 test/e2e/quadlet/network.quadlet.container create mode 100644 test/e2e/quadlet/network.quadlet.kube create mode 100644 test/e2e/quadlet/options.multiple.network create mode 100644 test/e2e/quadlet/options.network create mode 100644 test/e2e/quadlet/range.less-subnet.network create mode 100644 test/e2e/quadlet/range.network create mode 100644 test/e2e/quadlet/range.no-subnet.network create mode 100644 test/e2e/quadlet/subnet-trio.multiple.network create mode 100644 test/e2e/quadlet/subnet-trio.network create mode 100644 test/e2e/quadlet/subnets.network diff --git a/cmd/quadlet/main.go b/cmd/quadlet/main.go index 7adeeb1500..62374a145e 100644 --- a/cmd/quadlet/main.go +++ b/cmd/quadlet/main.go @@ -40,6 +40,7 @@ var ( ".container": void, ".volume": void, ".kube": void, + ".network": void, } ) @@ -337,6 +338,8 @@ func main() { service, err = quadlet.ConvertVolume(unit, name) case strings.HasSuffix(name, ".kube"): service, err = quadlet.ConvertKube(unit, isUser) + case strings.HasSuffix(name, ".network"): + service, err = quadlet.ConvertNetwork(unit, name) default: Logf("Unsupported file type '%s'", name) continue diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index f6ca0e22e2..9ca76e2797 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -310,9 +310,85 @@ Set one or more OCI labels on the volume. The format is a list of This key can be listed multiple times. +### Network units -Set one or more OCI labels on the volume. The format is a list of `key=value` items, -similar to `Environment`. +Network files are named with a `.network` extension and contain a section `[Network]` describing the +named Podman network. The generated service is a one-time command that ensures that the network +exists on the host, creating it if needed. + +For a network file named `$NAME.network`, the generated Podman network will be called `systemd-$NAME`, +and the generated service file `$NAME-network.service`. + +Using network units allows containers to depend on networks being automatically pre-created. This is +particularly interesting when using special options to control network creation, as Podman will +otherwise create networks with the default options. + +Supported keys in `Network` section are: + +#### `DisableDNS=` (defaults to `no`) + +If enabled, disables the DNS plugin for this network. + +This is equivalent to the Podman `--disable-dns` option + +#### `Driver=` (defaults to `bridge`) + +Driver to manage the network. Currently `bridge`, `macvlan` and `ipvlan` are supported. + +This is equivalent to the Podman `--driver` option + +#### `Gateway=` + +Define a gateway for the subnet. If you want to provide a gateway address, you must also provide a subnet option. + +This is equivalent to the Podman `--gateway` option + +This key can be listed multiple times. + +#### `Internal=` (defaults to `no`) + +Restrict external access of this network. + +This is equivalent to the Podman `--internal` option + +#### `IPRange=` + +Allocate container IP from a range. The range must be a complete subnet and in CIDR notation. The ip-range option must be used with a subnet option. + +This is equivalent to the Podman `--ip-range` option + +This key can be listed multiple times. + +#### `IPAMDriver=` + +Set the ipam driver (IP Address Management Driver) for the network. Currently `host-local`, `dhcp` and `none` are supported. + +This is equivalent to the Podman `--ipam-driver` option + +#### `IPv6=` + +Enable IPv6 (Dual Stack) networking. + +This is equivalent to the Podman `--ipv6` option + +#### `Options=` + +Set driver specific options. + +This is equivalent to the Podman `--opt` option + +#### `Subnet=` + +The subnet in CIDR notation. + +This is equivalent to the Podman `--subnet` option + +This key can be listed multiple times. + +#### `Label=` + +Set one or more OCI labels on the network. The format is a list of +`key=value` items, similar to `Environment`. This key can be listed multiple times. @@ -351,7 +427,17 @@ Group=projectname Label=org.test.Key=value ``` +Example `test.network`: +``` +[Network] +Subnet=172.16.0.0/24 +Gateway=172.16.0.1 +IPRange=172.16.0.0/28 +Label=org.test.Key=value +``` + ## SEE ALSO **[systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html)**, **[systemd.service(5)](https://www.freedesktop.org/software/systemd/man/systemd.service.html)**, **[podman-run(1)](podman-run.1.md)** +**[podman-network-create(1)](podman-network-create.1.md)** diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 8ad12fa3b1..6c473df253 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -25,40 +25,51 @@ const ( XVolumeGroup = "X-Volume" KubeGroup = "Kube" XKubeGroup = "X-Kube" + NetworkGroup = "Network" + XNetworkGroup = "X-Network" ) var validPortRange = regexp.MustCompile(`\d+(-\d+)?(/udp|/tcp)?$`) // All the supported quadlet keys const ( - KeyContainerName = "ContainerName" - KeyImage = "Image" - KeyEnvironment = "Environment" - KeyExec = "Exec" - KeyNoNewPrivileges = "NoNewPrivileges" - KeyDropCapability = "DropCapability" - KeyAddCapability = "AddCapability" - KeyReadOnly = "ReadOnly" - KeyRemapUsers = "RemapUsers" - KeyRemapUID = "RemapUid" - KeyRemapGID = "RemapGid" - KeyRemapUIDSize = "RemapUidSize" - KeyNotify = "Notify" - KeyExposeHostPort = "ExposeHostPort" - KeyPublishPort = "PublishPort" - KeyUser = "User" - KeyGroup = "Group" - KeyVolume = "Volume" - KeyPodmanArgs = "PodmanArgs" - KeyLabel = "Label" - KeyAnnotation = "Annotation" - KeyRunInit = "RunInit" - KeyVolatileTmp = "VolatileTmp" - KeyTimezone = "Timezone" - KeySeccompProfile = "SeccompProfile" - KeyAddDevice = "AddDevice" - KeyNetwork = "Network" - KeyYaml = "Yaml" + KeyContainerName = "ContainerName" + KeyImage = "Image" + KeyEnvironment = "Environment" + KeyExec = "Exec" + KeyNoNewPrivileges = "NoNewPrivileges" + KeyDropCapability = "DropCapability" + KeyAddCapability = "AddCapability" + KeyReadOnly = "ReadOnly" + KeyRemapUsers = "RemapUsers" + KeyRemapUID = "RemapUid" + KeyRemapGID = "RemapGid" + KeyRemapUIDSize = "RemapUidSize" + KeyNotify = "Notify" + KeyExposeHostPort = "ExposeHostPort" + KeyPublishPort = "PublishPort" + KeyUser = "User" + KeyGroup = "Group" + KeyVolume = "Volume" + KeyPodmanArgs = "PodmanArgs" + KeyLabel = "Label" + KeyAnnotation = "Annotation" + KeyRunInit = "RunInit" + KeyVolatileTmp = "VolatileTmp" + KeyTimezone = "Timezone" + KeySeccompProfile = "SeccompProfile" + KeyAddDevice = "AddDevice" + KeyNetwork = "Network" + KeyYaml = "Yaml" + KeyNetworkDisableDNS = "DisableDNS" + KeyNetworkDriver = "Driver" + KeyNetworkGateway = "Gateway" + KeyNetworkInternal = "Internal" + KeyNetworkIPRange = "IPRange" + KeyNetworkIPAMDriver = "IPAMDriver" + KeyNetworkIPv6 = "IPv6" + KeyNetworkOptions = "Options" + KeyNetworkSubnet = "Subnet" ) // Supported keys in "Container" group @@ -99,6 +110,20 @@ var supportedVolumeKeys = map[string]bool{ KeyLabel: true, } +// Supported keys in "Volume" group +var supportedNetworkKeys = map[string]bool{ + KeyNetworkDisableDNS: true, + KeyNetworkDriver: true, + KeyNetworkGateway: true, + KeyNetworkInternal: true, + KeyNetworkIPRange: true, + KeyNetworkIPAMDriver: true, + KeyNetworkIPv6: true, + KeyNetworkOptions: true, + KeyNetworkSubnet: true, + KeyLabel: true, +} + // Supported keys in "Kube" group var supportedKubeKeys = map[string]bool{ KeyYaml: true, @@ -106,6 +131,7 @@ var supportedKubeKeys = map[string]bool{ KeyRemapGID: true, KeyRemapUsers: true, KeyRemapUIDSize: true, + KeyNetwork: true, } func replaceExtension(name string, extension string, extraPrefix string, extraSuffix string) string { @@ -266,12 +292,7 @@ func ConvertContainer(container *parser.UnitFile, isUser bool) (*parser.UnitFile podman.addf("--tz=%s", timezone) } - networks := container.LookupAll(ContainerGroup, KeyNetwork) - for _, network := range networks { - if len(network) > 0 { - podman.addf("--network=%s", network) - } - } + addNetworks(container, ContainerGroup, service, podman) // Run with a pid1 init to reap zombies by default (as most apps don't do that) runInit := container.LookupBoolean(ContainerGroup, KeyRunInit, false) @@ -494,10 +515,99 @@ func ConvertContainer(container *parser.UnitFile, isUser bool) (*parser.UnitFile return service, nil } +// Convert a quadlet network file (unit file with a Network group) to a systemd +// service file (unit file with Service group) based on the options in the +// Network group. +// The original Network group is kept around as X-Network. +func ConvertNetwork(network *parser.UnitFile, name string) (*parser.UnitFile, error) { + service := network.Dup() + service.Filename = replaceExtension(network.Filename, ".service", "", "-network") + + if err := checkForUnknownKeys(network, NetworkGroup, supportedNetworkKeys); err != nil { + return nil, err + } + + /* Rename old Network group to x-Network so that systemd ignores it */ + service.RenameGroup(NetworkGroup, XNetworkGroup) + + networkName := replaceExtension(name, "", "systemd-", "") + + // Need the containers filesystem mounted to start podman + service.Add(UnitGroup, "RequiresMountsFor", "%t/containers") + + podman := NewPodmanCmdline("network", "create", "--ignore") + + if disableDNS := network.LookupBoolean(NetworkGroup, KeyNetworkDisableDNS, false); disableDNS { + podman.add("--disable-dns") + } + + driver, ok := network.Lookup(NetworkGroup, KeyNetworkDriver) + if ok && len(driver) > 0 { + podman.addf("--driver=%s", driver) + } + + subnets := network.LookupAll(NetworkGroup, KeyNetworkSubnet) + gateways := network.LookupAll(NetworkGroup, KeyNetworkGateway) + ipRanges := network.LookupAll(NetworkGroup, KeyNetworkIPRange) + if len(subnets) > 0 { + if len(gateways) > len(subnets) { + return nil, fmt.Errorf("cannot set more gateways than subnets") + } + if len(ipRanges) > len(subnets) { + return nil, fmt.Errorf("cannot set more ranges than subnets") + } + for i := range subnets { + podman.addf("--subnet=%s", subnets[i]) + if len(gateways) > i { + podman.addf("--gateway=%s", gateways[i]) + } + if len(ipRanges) > i { + podman.addf("--ip-range=%s", ipRanges[i]) + } + } + } else if len(ipRanges) > 0 || len(gateways) > 0 { + return nil, fmt.Errorf("cannot set gateway or range without subnet") + } + + if internal := network.LookupBoolean(NetworkGroup, KeyNetworkInternal, false); internal { + podman.add("--internal") + } + + if ipamDriver, ok := network.Lookup(NetworkGroup, KeyNetworkIPAMDriver); ok && len(ipamDriver) > 0 { + podman.addf("--ipam-driver=%s", ipamDriver) + } + + if ipv6 := network.LookupBoolean(NetworkGroup, KeyNetworkIPv6, false); ipv6 { + podman.add("--ipv6") + } + + networkOptions := network.LookupAllKeyVal(NetworkGroup, KeyNetworkOptions) + if len(networkOptions) > 0 { + podman.addKeys("--opt", networkOptions) + } + + if labels := network.LookupAllKeyVal(NetworkGroup, KeyLabel); len(labels) > 0 { + podman.addLabels(labels) + } + + podman.add(networkName) + + service.AddCmdline(ServiceGroup, "ExecStart", podman.Args) + + service.Setv(ServiceGroup, + "Type", "oneshot", + "RemainAfterExit", "yes", + + // The default syslog identifier is the exec basename (podman) which isn't very useful here + "SyslogIdentifier", "%N") + + return service, nil +} + // Convert a quadlet volume file (unit file with a Volume group) to a systemd // service file (unit file with Service group) based on the options in the // Volume group. -// The original Container group is kept around as X-Container. +// The original Volume group is kept around as X-Volume. func ConvertVolume(volume *parser.UnitFile, name string) (*parser.UnitFile, error) { service := volume.Dup() service.Filename = replaceExtension(volume.Filename, ".service", "", "-volume") @@ -627,6 +737,8 @@ func ConvertKube(kube *parser.UnitFile, isUser bool) (*parser.UnitFile, error) { return nil, err } + addNetworks(kube, KubeGroup, service, execStart) + execStart.add(yamlPath) service.AddCmdline(ServiceGroup, "ExecStart", execStart.Args) @@ -686,3 +798,30 @@ func handleUserRemap(unitFile *parser.UnitFile, groupName string, podman *Podman return nil } + +func addNetworks(quadletUnitFile *parser.UnitFile, groupName string, serviceUnitFile *parser.UnitFile, podman *PodmanCmdline) { + networks := quadletUnitFile.LookupAll(groupName, KeyNetwork) + for _, network := range networks { + if len(network) > 0 { + networkName, options, found := strings.Cut(network, ":") + if strings.HasSuffix(networkName, ".network") { + // the podman network name is systemd-$name + networkName = replaceExtension(networkName, "", "systemd-", "") + + // the systemd unit name is $name-network.service + networkServiceName := replaceExtension(networkName, ".service", "", "-network") + + serviceUnitFile.Add(UnitGroup, "Requires", networkServiceName) + serviceUnitFile.Add(UnitGroup, "After", networkServiceName) + + if found { + network = fmt.Sprintf("%s:%s", networkName, options) + } else { + network = networkName + } + } + + podman.addf("--network=%s", network) + } + } +} diff --git a/test/e2e/quadlet/basic.network b/test/e2e/quadlet/basic.network new file mode 100644 index 0000000000..9cee893f68 --- /dev/null +++ b/test/e2e/quadlet/basic.network @@ -0,0 +1,7 @@ +## assert-key-is Unit RequiresMountsFor "%t/containers" +## assert-key-is Service Type oneshot +## assert-key-is Service RemainAfterExit yes +## assert-key-is-regex Service ExecStart ".*/podman network create --ignore systemd-basic" +## assert-key-is Service SyslogIdentifier "%N" + +[Network] diff --git a/test/e2e/quadlet/disable-dns.network b/test/e2e/quadlet/disable-dns.network new file mode 100644 index 0000000000..7d366e13e4 --- /dev/null +++ b/test/e2e/quadlet/disable-dns.network @@ -0,0 +1,5 @@ +## assert-podman-final-args systemd-disable-dns +## assert-podman-args "--disable-dns" + +[Network] +DisableDNS=yes diff --git a/test/e2e/quadlet/driver.network b/test/e2e/quadlet/driver.network new file mode 100644 index 0000000000..c49a596a8a --- /dev/null +++ b/test/e2e/quadlet/driver.network @@ -0,0 +1,5 @@ +## assert-podman-final-args systemd-driver +## assert-podman-args "--driver=macvlan" + +[Network] +Driver=macvlan diff --git a/test/e2e/quadlet/gateway.less-subnet.network b/test/e2e/quadlet/gateway.less-subnet.network new file mode 100644 index 0000000000..fa6da46c05 --- /dev/null +++ b/test/e2e/quadlet/gateway.less-subnet.network @@ -0,0 +1,7 @@ +## assert-failed +## assert-stderr-contains "cannot set more gateways than subnets" + +[Network] +Subnet=192.168.1.0/24 +Gateway=192.168.1.1 +Gateway=192.168.2.1 diff --git a/test/e2e/quadlet/gateway.network b/test/e2e/quadlet/gateway.network new file mode 100644 index 0000000000..e2f349f3d7 --- /dev/null +++ b/test/e2e/quadlet/gateway.network @@ -0,0 +1,6 @@ +## assert-podman-final-args systemd-gateway +## assert-podman-args "--subnet=192.168.1.0/24" "--gateway=192.168.1.1" + +[Network] +Subnet=192.168.1.0/24 +Gateway=192.168.1.1 diff --git a/test/e2e/quadlet/gateway.no-subnet.network b/test/e2e/quadlet/gateway.no-subnet.network new file mode 100644 index 0000000000..dea597c67c --- /dev/null +++ b/test/e2e/quadlet/gateway.no-subnet.network @@ -0,0 +1,5 @@ +## assert-failed +## assert-stderr-contains "cannot set gateway or range without subnet" + +[Network] +Gateway=192.168.1.1 diff --git a/test/e2e/quadlet/internal.network b/test/e2e/quadlet/internal.network new file mode 100644 index 0000000000..de06bc23f9 --- /dev/null +++ b/test/e2e/quadlet/internal.network @@ -0,0 +1,5 @@ +## assert-podman-final-args systemd-internal +## assert-podman-args "--internal" + +[Network] +Internal=yes diff --git a/test/e2e/quadlet/ipam-driver.network b/test/e2e/quadlet/ipam-driver.network new file mode 100644 index 0000000000..03fc842034 --- /dev/null +++ b/test/e2e/quadlet/ipam-driver.network @@ -0,0 +1,5 @@ +## assert-podman-final-args systemd-ipam-driver +## assert-podman-args "--ipam-driver=dhcp" + +[Network] +IPAMDriver=dhcp diff --git a/test/e2e/quadlet/ipv6.network b/test/e2e/quadlet/ipv6.network new file mode 100644 index 0000000000..b1662fb95c --- /dev/null +++ b/test/e2e/quadlet/ipv6.network @@ -0,0 +1,5 @@ +## assert-podman-final-args systemd-ipv6 +## assert-podman-args "--ipv6" + +[Network] +IPv6=yes diff --git a/test/e2e/quadlet/label.network b/test/e2e/quadlet/label.network new file mode 100644 index 0000000000..1050aa76ae --- /dev/null +++ b/test/e2e/quadlet/label.network @@ -0,0 +1,11 @@ +## assert-podman-final-args systemd-label +## assert-podman-args "--label" "org.foo.Arg0=arg0" +## assert-podman-args "--label" "org.foo.Arg1=arg1" +## assert-podman-args "--label" "org.foo.Arg2=arg 2" +## assert-podman-args "--label" "org.foo.Arg3=arg3" + +[Network] +Label=org.foo.Arg1=arg1 "org.foo.Arg2=arg 2" \ + org.foo.Arg3=arg3 + +Label=org.foo.Arg0=arg0 diff --git a/test/e2e/quadlet/network.kube b/test/e2e/quadlet/network.kube new file mode 100644 index 0000000000..3b64fc419f --- /dev/null +++ b/test/e2e/quadlet/network.kube @@ -0,0 +1,5 @@ +## assert-podman-args "--network=basic" + +[Kube] +Yaml=deployment.yml +Network=basic diff --git a/test/e2e/quadlet/network.quadlet.container b/test/e2e/quadlet/network.quadlet.container new file mode 100644 index 0000000000..5b15ca6810 --- /dev/null +++ b/test/e2e/quadlet/network.quadlet.container @@ -0,0 +1,7 @@ +## assert-podman-args "--network=systemd-basic" +## assert-key-is "Unit" "Requires" "systemd-basic-network.service" +## assert-key-is "Unit" "After" "systemd-basic-network.service" + +[Container] +Image=localhost/imagename +Network=basic.network diff --git a/test/e2e/quadlet/network.quadlet.kube b/test/e2e/quadlet/network.quadlet.kube new file mode 100644 index 0000000000..a24d5e3544 --- /dev/null +++ b/test/e2e/quadlet/network.quadlet.kube @@ -0,0 +1,8 @@ +## assert-podman-args "--network=systemd-basic" +## assert-key-is "Unit" "Requires" "systemd-basic-network.service" +## assert-key-is "Unit" "After" "systemd-basic-network.service" + + +[Kube] +Yaml=deployment.yml +Network=basic.network diff --git a/test/e2e/quadlet/options.multiple.network b/test/e2e/quadlet/options.multiple.network new file mode 100644 index 0000000000..ffb3a338d0 --- /dev/null +++ b/test/e2e/quadlet/options.multiple.network @@ -0,0 +1,7 @@ +## assert-podman-final-args systemd-options.multiple +## assert-podman-args "--opt" "mtu=1504" +## assert-podman-args "--opt" "isolate=true" + +[Network] +Options=mtu=1504 +Options=isolate=true diff --git a/test/e2e/quadlet/options.network b/test/e2e/quadlet/options.network new file mode 100644 index 0000000000..a59333c360 --- /dev/null +++ b/test/e2e/quadlet/options.network @@ -0,0 +1,5 @@ +## assert-podman-final-args systemd-options +## assert-podman-args "--opt" "mtu=1504" + +[Network] +Options=mtu=1504 diff --git a/test/e2e/quadlet/range.less-subnet.network b/test/e2e/quadlet/range.less-subnet.network new file mode 100644 index 0000000000..ade88eeb53 --- /dev/null +++ b/test/e2e/quadlet/range.less-subnet.network @@ -0,0 +1,7 @@ +## assert-failed +## assert-stderr-contains "cannot set more ranges than subnets" + +[Network] +Subnet=192.168.1.0/24 +IPRange=192.168.1.0/32 +IPRange=192.168.1.127/32 diff --git a/test/e2e/quadlet/range.network b/test/e2e/quadlet/range.network new file mode 100644 index 0000000000..26e40e3cc3 --- /dev/null +++ b/test/e2e/quadlet/range.network @@ -0,0 +1,6 @@ +## assert-podman-final-args systemd-range +## assert-podman-args "--subnet=192.168.1.0/24" "--ip-range=192.168.1.0/32" + +[Network] +Subnet=192.168.1.0/24 +IPRange=192.168.1.0/32 diff --git a/test/e2e/quadlet/range.no-subnet.network b/test/e2e/quadlet/range.no-subnet.network new file mode 100644 index 0000000000..7e9bec691d --- /dev/null +++ b/test/e2e/quadlet/range.no-subnet.network @@ -0,0 +1,5 @@ +## assert-failed +## assert-stderr-contains "cannot set gateway or range without subnet" + +[Network] +IPRange=192.168.1.0/32 diff --git a/test/e2e/quadlet/subnet-trio.multiple.network b/test/e2e/quadlet/subnet-trio.multiple.network new file mode 100644 index 0000000000..14097c9c48 --- /dev/null +++ b/test/e2e/quadlet/subnet-trio.multiple.network @@ -0,0 +1,11 @@ +## assert-podman-final-args systemd-subnet-trio.multiple +## assert-podman-args "--subnet=192.168.1.0/24" "--gateway=192.168.1.1" "--ip-range=192.168.1.0/32" +## assert-podman-args "--subnet=192.168.2.0/24" "--gateway=192.168.2.1" "--ip-range=192.168.2.0/32" + +[Network] +Subnet=192.168.1.0/24 +Subnet=192.168.2.0/24 +Gateway=192.168.1.1 +Gateway=192.168.2.1 +IPRange=192.168.1.0/32 +IPRange=192.168.2.0/32 diff --git a/test/e2e/quadlet/subnet-trio.network b/test/e2e/quadlet/subnet-trio.network new file mode 100644 index 0000000000..eec5ed0e44 --- /dev/null +++ b/test/e2e/quadlet/subnet-trio.network @@ -0,0 +1,7 @@ +## assert-podman-final-args systemd-subnet-trio +## assert-podman-args "--subnet=192.168.1.0/24" "--gateway=192.168.1.1" "--ip-range=192.168.1.0/32" + +[Network] +Subnet=192.168.1.0/24 +Gateway=192.168.1.1 +IPRange=192.168.1.0/32 diff --git a/test/e2e/quadlet/subnets.network b/test/e2e/quadlet/subnets.network new file mode 100644 index 0000000000..c6dec14d1c --- /dev/null +++ b/test/e2e/quadlet/subnets.network @@ -0,0 +1,7 @@ +## assert-podman-final-args systemd-subnets +## assert-podman-args "--subnet=192.168.0.0/24" +## assert-podman-args "--subnet=192.168.1.0/24" + +[Network] +Subnet=192.168.0.0/24 +Subnet=192.168.1.0/24 diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index 12e5c68878..c2a03fb094 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -30,8 +30,11 @@ func loadQuadletTestcase(path string) *quadletTestcase { base := filepath.Base(path) ext := filepath.Ext(base) service := base[:len(base)-len(ext)] - if ext == ".volume" { + switch ext { + case ".volume": service += "-volume" + case ".network": + service += "-network" } service += ".service" @@ -360,6 +363,7 @@ var _ = Describe("quadlet system generator", func() { Entry("label.container", "label.container"), Entry("name.container", "name.container"), Entry("network.container", "network.container"), + Entry("network.quadlet.container", "network.quadlet.container"), Entry("noimage.container", "noimage.container"), Entry("notify.container", "notify.container"), Entry("other-sections.container", "other-sections.container"), @@ -388,6 +392,27 @@ var _ = Describe("quadlet system generator", func() { 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"), + Entry("Kube - Network", "network.kube"), + Entry("Kube - Quadlet Network", "network.quadlet.kube"), + + Entry("Network - Basic", "basic.network"), + Entry("Network - Label", "label.network"), + Entry("Network - Disable DNS", "disable-dns.network"), + Entry("Network - Driver", "driver.network"), + Entry("Network - Subnets", "subnets.network"), + Entry("Network - Gateway", "gateway.network"), + Entry("Network - Gateway without Subnet", "gateway.no-subnet.network"), + Entry("Network - Gateway not enough Subnet", "gateway.less-subnet.network"), + Entry("Network - Range", "range.network"), + Entry("Network - Range without Subnet", "range.no-subnet.network"), + Entry("Network - Range not enough Subnet", "range.less-subnet.network"), + Entry("Network - subnet, gateway and range", "subnet-trio.network"), + Entry("Network - multiple subnet, gateway and range", "subnet-trio.multiple.network"), + Entry("Network - Internal network", "internal.network"), + Entry("Network - IPAM Driver", "ipam-driver.network"), + Entry("Network - IPv6", "ipv6.network"), + Entry("Network - Options", "options.network"), + Entry("Network - Multiple Options", "options.multiple.network"), ) })