diff options
-rw-r--r-- | .github/issue-labeler.yml | 13 | ||||
-rw-r--r-- | .github/workflows/issue-labeler.yml | 15 | ||||
-rw-r--r-- | cmd/podman/networks/create.go | 64 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-prune.1.md | 6 | ||||
-rw-r--r-- | docs/source/markdown/podman-image-prune.1.md | 5 | ||||
-rw-r--r-- | docs/source/markdown/podman-network-create.1.md | 18 | ||||
-rw-r--r-- | docs/source/markdown/podman-network-prune.1.md | 21 | ||||
-rw-r--r-- | docs/source/markdown/podman-system-prune.1.md | 12 | ||||
-rw-r--r-- | docs/source/markdown/podman-volume-prune.1.md | 18 | ||||
-rwxr-xr-x | hack/get_ci_vm.sh | 7 | ||||
-rw-r--r-- | pkg/domain/entities/network.go | 6 | ||||
-rw-r--r-- | test/e2e/network_create_test.go | 78 | ||||
-rw-r--r-- | test/system/520-checkpoint.bats | 4 | ||||
-rw-r--r-- | troubleshooting.md | 12 |
14 files changed, 226 insertions, 53 deletions
diff --git a/.github/issue-labeler.yml b/.github/issue-labeler.yml new file mode 100644 index 000000000..e285749a9 --- /dev/null +++ b/.github/issue-labeler.yml @@ -0,0 +1,13 @@ +# List of labels which should be assigned to issues based on a regex +windows: + # info prints OsArch: ... + # version prints OS/Arch: ... + - 'O[Ss]\/?Arch:\s*windows' +macos: + # info prints OsArch: ... + # version prints OS/Arch: ... + - 'O[Ss]\/?Arch:\s*darwin' + +remote: + # we cannot use multiline regex so we check for serviceIsRemote in podman info + - 'serviceIsRemote:\strue' diff --git a/.github/workflows/issue-labeler.yml b/.github/workflows/issue-labeler.yml new file mode 100644 index 000000000..ee9785d23 --- /dev/null +++ b/.github/workflows/issue-labeler.yml @@ -0,0 +1,15 @@ +name: "Issue Labeler" +on: + issues: + types: [opened, edited] + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: github/issue-labeler@v2.0 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: .github/issue-labeler.yml + not-before: 2022-01-27T00:00:00Z + enable-versioned-regex: 0 diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go index 9f6470858..3dd393c46 100644 --- a/cmd/podman/networks/create.go +++ b/cmd/podman/networks/create.go @@ -47,13 +47,13 @@ func networkCreateFlags(cmd *cobra.Command) { _ = cmd.RegisterFlagCompletionFunc(optFlagName, completion.AutocompleteNone) gatewayFlagName := "gateway" - flags.IPVar(&networkCreateOptions.Gateway, gatewayFlagName, nil, "IPv4 or IPv6 gateway for the subnet") + flags.IPSliceVar(&networkCreateOptions.Gateways, gatewayFlagName, nil, "IPv4 or IPv6 gateway for the subnet") _ = cmd.RegisterFlagCompletionFunc(gatewayFlagName, completion.AutocompleteNone) flags.BoolVar(&networkCreateOptions.Internal, "internal", false, "restrict external access from this network") ipRangeFlagName := "ip-range" - flags.IPNetVar(&networkCreateOptions.Range, ipRangeFlagName, net.IPNet{}, "allocate container IP from range") + flags.StringArrayVar(&networkCreateOptions.Ranges, ipRangeFlagName, nil, "allocate container IP from range") _ = cmd.RegisterFlagCompletionFunc(ipRangeFlagName, completion.AutocompleteNone) // TODO consider removing this for 4.0 @@ -72,7 +72,7 @@ func networkCreateFlags(cmd *cobra.Command) { flags.BoolVar(&networkCreateOptions.IPv6, "ipv6", false, "enable IPv6 networking") subnetFlagName := "subnet" - flags.IPNetVar(&networkCreateOptions.Subnet, subnetFlagName, net.IPNet{}, "subnet in CIDR format") + flags.StringArrayVar(&networkCreateOptions.Subnets, subnetFlagName, nil, "subnets in CIDR format") _ = cmd.RegisterFlagCompletionFunc(subnetFlagName, completion.AutocompleteNone) flags.BoolVar(&networkCreateOptions.DisableDNS, "disable-dns", false, "disable dns plugin") @@ -125,27 +125,35 @@ func networkCreate(cmd *cobra.Command, args []string) error { } } - if networkCreateOptions.Subnet.IP != nil { - s := types.Subnet{ - Subnet: types.IPNet{IPNet: networkCreateOptions.Subnet}, - Gateway: networkCreateOptions.Gateway, + if len(networkCreateOptions.Subnets) > 0 { + if len(networkCreateOptions.Gateways) > len(networkCreateOptions.Subnets) { + return errors.New("cannot set more gateways than subnets") } - if networkCreateOptions.Range.IP != nil { - startIP, err := util.FirstIPInSubnet(&networkCreateOptions.Range) + if len(networkCreateOptions.Ranges) > len(networkCreateOptions.Subnets) { + return errors.New("cannot set more ranges than subnets") + } + + for i := range networkCreateOptions.Subnets { + subnet, err := types.ParseCIDR(networkCreateOptions.Subnets[i]) if err != nil { - return errors.Wrap(err, "failed to get first ip in range") + return err } - lastIP, err := util.LastIPInSubnet(&networkCreateOptions.Range) - if err != nil { - return errors.Wrap(err, "failed to get last ip in range") + s := types.Subnet{ + Subnet: subnet, + } + if len(networkCreateOptions.Ranges) > i { + leaseRange, err := parseRange(networkCreateOptions.Ranges[i]) + if err != nil { + return err + } + s.LeaseRange = leaseRange } - s.LeaseRange = &types.LeaseRange{ - StartIP: startIP, - EndIP: lastIP, + if len(networkCreateOptions.Gateways) > i { + s.Gateway = networkCreateOptions.Gateways[i] } + network.Subnets = append(network.Subnets, s) } - network.Subnets = append(network.Subnets, s) - } else if networkCreateOptions.Range.IP != nil || networkCreateOptions.Gateway != nil { + } else if len(networkCreateOptions.Ranges) > 0 || len(networkCreateOptions.Gateways) > 0 { return errors.New("cannot set gateway or range without subnet") } @@ -156,3 +164,23 @@ func networkCreate(cmd *cobra.Command, args []string) error { fmt.Println(response.Name) return nil } + +func parseRange(iprange string) (*types.LeaseRange, error) { + _, subnet, err := net.ParseCIDR(iprange) + if err != nil { + return nil, err + } + + startIP, err := util.FirstIPInSubnet(subnet) + if err != nil { + return nil, errors.Wrap(err, "failed to get first ip in range") + } + lastIP, err := util.LastIPInSubnet(subnet) + if err != nil { + return nil, errors.Wrap(err, "failed to get last ip in range") + } + return &types.LeaseRange{ + StartIP: startIP, + EndIP: lastIP, + }, nil +} diff --git a/docs/source/markdown/podman-container-prune.1.md b/docs/source/markdown/podman-container-prune.1.md index 6e4aa35ff..b20936c15 100644 --- a/docs/source/markdown/podman-container-prune.1.md +++ b/docs/source/markdown/podman-container-prune.1.md @@ -20,13 +20,13 @@ Supported filters: | Filter | Description | | :----------------: | --------------------------------------------------------------------------- | -| *until* | Only remove containers created before given timestamp. | | *label* | Only remove containers, with (or without, in the case of label!=[...] is used) the specified labels. | - -The `until` *filter* can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. +| *until* | Only remove containers created before given timestamp. | The `label` *filter* accepts two formats. One is the `label`=*key* or `label`=*key*=*value*, which removes containers with the specified labels. The other format is the `label!`=*key* or `label!`=*key*=*value*, which removes containers without the specified labels. +The `until` *filter* can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. + #### **--force**, **-f** Do not provide an interactive prompt for container removal.\ diff --git a/docs/source/markdown/podman-image-prune.1.md b/docs/source/markdown/podman-image-prune.1.md index 66edad207..db17f97fb 100644 --- a/docs/source/markdown/podman-image-prune.1.md +++ b/docs/source/markdown/podman-image-prune.1.md @@ -31,13 +31,14 @@ Supported filters: | Filter | Description | | :----------------: | --------------------------------------------------------------------------- | -| *until* | Only remove images created before given timestamp. | | *label* | Only remove images, with (or without, in the case of label!=[...] is used) the specified labels. | +| *until* | Only remove images created before given timestamp. | -The `until` *filter* can be Unix timestamps, date formatted timestamps or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. The `label` *filter* accepts two formats. One is the `label`=*key* or `label`=*key*=*value*, which removes containers with the specified labels. The other format is the `label!`=*key* or `label!`=*key*=*value*, which removes containers without the specified labels. +The `until` *filter* can be Unix timestamps, date formatted timestamps or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. + #### **--force**, **-f** Do not provide an interactive prompt for container removal. diff --git a/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md index 8a9b2f3cf..5be0c2595 100644 --- a/docs/source/markdown/podman-network-create.1.md +++ b/docs/source/markdown/podman-network-create.1.md @@ -46,7 +46,8 @@ The `macvlan` and `ipvlan` driver support the following options: #### **--gateway** Define a gateway for the subnet. If you want to provide a gateway address, you must also provide a -*subnet* option. +*subnet* option. Can be specified multiple times. +The argument order of the **--subnet**, **--gateway** and **--ip-range** options must match. #### **--internal** @@ -56,7 +57,8 @@ automatically disabled. #### **--ip-range** 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. +must be used with a *subnet* option. Can be specified multiple times. +The argument order of the **--subnet**, **--gateway** and **--ip-range** options must match. #### **--label** @@ -64,11 +66,13 @@ Set metadata for a network (e.g., --label mykey=value). #### **--subnet** -The subnet in CIDR notation. +The subnet in CIDR notation. Can be specified multiple times to allocate more than one subnet for this network. +The argument order of the **--subnet**, **--gateway** and **--ip-range** options must match. +This is useful to set a static ipv4 and ipv6 subnet. #### **--ipv6** -Enable IPv6 (Dual Stack) networking. +Enable IPv6 (Dual Stack) networking. If not subnets are given it will allocate a ipv4 and ipv6 subnet. ## EXAMPLE @@ -102,6 +106,12 @@ $ podman network create --subnet 192.168.55.0/24 --ip-range 192.168.55.128/25 cni-podman5 ``` +Create a network with a static ipv4 and ipv6 subnet and set a gateway. +``` +$ podman network create --subnet 192.168.55.0/24 --gateway 192.168.55.3 --subnet fd52:2a5a:747e:3acd::/64 --gateway fd52:2a5a:747e:3acd::10 +podman4 +``` + Create a Macvlan based network using the host interface eth0. Macvlan networks can only be used as root. ``` # podman network create -d macvlan -o parent=eth0 newnet diff --git a/docs/source/markdown/podman-network-prune.1.md b/docs/source/markdown/podman-network-prune.1.md index d35decb1b..a1dc5d85c 100644 --- a/docs/source/markdown/podman-network-prune.1.md +++ b/docs/source/markdown/podman-network-prune.1.md @@ -18,17 +18,20 @@ Do not prompt for confirmation #### **--filter** -Filter output based on conditions given. -Multiple filters can be given with multiple uses of the --filter option. -Filters with the same key work inclusive with the only exception being -`label` which is exclusive. Filters with different keys always work exclusive. +Provide filter values. -Valid filters are listed below: +The *filters* argument format is of `key=value`. If there is more than one *filter*, then pass multiple OPTIONS: **--filter** *foo=bar* **--filter** *bif=baz*. -| **Filter** | **Description** | -| ---------- | ------------------------------------------------------------------------------------- | -| label | [Key] or [Key=Value] Label assigned to a network | -| until | only remove networks created before given timestamp | +Supported filters: + +| Filter | Description | +| :----------------: | --------------------------------------------------------------------------- | +| *label* | Only remove networks, with (or without, in the case of label!=[...] is used) the specified labels. | +| *until* | Only remove networks created before given timestamp. | + +The `label` *filter* accepts two formats. One is the `label`=*key* or `label`=*key*=*value*, which removes networks with the specified labels. The other format is the `label!`=*key* or `label!`=*key*=*value*, which removes networks without the specified labels. + +The `until` *filter* can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. ## EXAMPLE Prune networks diff --git a/docs/source/markdown/podman-system-prune.1.md b/docs/source/markdown/podman-system-prune.1.md index d8b218db2..fb9ed44d6 100644 --- a/docs/source/markdown/podman-system-prune.1.md +++ b/docs/source/markdown/podman-system-prune.1.md @@ -22,16 +22,18 @@ Recursively remove all unused pod, container, image and volume data (Maximum 50 Provide filter values. -The --filter flag format is of “key=value”. If there is more than one filter, then pass multiple flags (e.g., --filter "foo=bar" --filter "bif=baz") +The *filters* argument format is of `key=value`. If there is more than one *filter*, then pass multiple OPTIONS: **--filter** *foo=bar* **--filter** *bif=baz*. Supported filters: -- `until` (_timestamp_) - only remove containers and images created before given timestamp -- `label` (label=_key_, label=_key=value_, label!=_key_, or label!=_key=value_) - only remove containers and images, with (or without, in case label!=... is used) the specified labels. +| Filter | Description | +| :----------------: | --------------------------------------------------------------------------- | +| *label* | Only remove containers and images, with (or without, in the case of label!=[...] is used) the specified labels. | +| *until* | Only remove containers and images created before given timestamp. | -The until filter can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. +The `label` *filter* accepts two formats. One is the `label`=*key* or `label`=*key*=*value*, which removes containers and images with the specified labels. The other format is the `label!`=*key* or `label!`=*key*=*value*, which removes containers and images without the specified labels. -The label filter accepts two formats. One is the label=... (label=_key_ or label=_key=value_), which removes containers and images with the specified labels. The other format is the label!=... (label!=_key_ or label!=_key=value_), which removes containers and images without the specified labels. +The `until` *filter* can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. #### **--force**, **-f** diff --git a/docs/source/markdown/podman-volume-prune.1.md b/docs/source/markdown/podman-volume-prune.1.md index 012567957..2028e42f2 100644 --- a/docs/source/markdown/podman-volume-prune.1.md +++ b/docs/source/markdown/podman-volume-prune.1.md @@ -21,12 +21,20 @@ Do not prompt for confirmation. #### **--filter** -Filter volumes to be pruned. Volumes can be filtered by the following attributes: +Provide filter values. -| **Filter** | **Description** | -| ---------- | ------------------------------------------------------------------------------------- | -| label | [Key] or [Key=Value] Label assigned to a volume | -| until | Only remove volumes created before given timestamp | +The *filters* argument format is of `key=value`. If there is more than one *filter*, then pass multiple OPTIONS: **--filter** *foo=bar* **--filter** *bif=baz*. + +Supported filters: + +| Filter | Description | +| :----------------: | --------------------------------------------------------------------------- | +| *label* | Only remove volumes, with (or without, in the case of label!=[...] is used) the specified labels. | +| *until* | Only remove volumes created before given timestamp. | + +The `label` *filter* accepts two formats. One is the `label`=*key* or `label`=*key*=*value*, which removes volumes with the specified labels. The other format is the `label!`=*key* or `label!`=*key*=*value*, which removes volumes without the specified labels. + +The `until` *filter* can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine’s time. #### **--help** diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh index 1a4804857..ef7069a81 100755 --- a/hack/get_ci_vm.sh +++ b/hack/get_ci_vm.sh @@ -47,11 +47,10 @@ elif [[ "$1" == "--setup" ]]; then cd $REPO_DIRPATH echo "+ Loading ./contrib/cirrus/lib.sh" > /dev/stderr source ./contrib/cirrus/lib.sh - echo "+ Mimicking .cirrus.yml clone_script and build_task" > /dev/stderr + echo "+ Mimicking .cirrus.yml build_task" > /dev/stderr make install.tools - make vendor - make podman - make podman-remote + make binaries + make docs echo "+ Running environment setup" > /dev/stderr ./contrib/cirrus/setup_environment.sh else diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go index 79edc3227..a057640b3 100644 --- a/pkg/domain/entities/network.go +++ b/pkg/domain/entities/network.go @@ -43,12 +43,12 @@ type NetworkRmReport struct { type NetworkCreateOptions struct { DisableDNS bool Driver string - Gateway net.IP + Gateways []net.IP Internal bool Labels map[string]string MacVLAN string - Range net.IPNet - Subnet net.IPNet + Ranges []string + Subnets []string IPv6 bool // Mapping of driver options and values. Options map[string]string diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go index ade78a308..4a8a24ad7 100644 --- a/test/e2e/network_create_test.go +++ b/test/e2e/network_create_test.go @@ -356,4 +356,82 @@ var _ = Describe("Podman network create", func() { } }) + It("podman network create with multiple subnets", func() { + name := "subnets-" + stringid.GenerateNonCryptoID() + subnet1 := "10.10.0.0/24" + subnet2 := "10.10.1.0/24" + nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--subnet", subnet2, name}) + nc.WaitWithDefaultTimeout() + defer podmanTest.removeCNINetwork(name) + Expect(nc).To(Exit(0)) + Expect(nc.OutputToString()).To(Equal(name)) + + inspect := podmanTest.Podman([]string{"network", "inspect", name}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet1)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet2)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"ipv6_enabled": false`)) + }) + + It("podman network create with multiple subnets dual stack", func() { + name := "subnets-" + stringid.GenerateNonCryptoID() + subnet1 := "10.10.2.0/24" + subnet2 := "fd52:2a5a:747e:3acd::/64" + nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--subnet", subnet2, name}) + nc.WaitWithDefaultTimeout() + defer podmanTest.removeCNINetwork(name) + Expect(nc).To(Exit(0)) + Expect(nc.OutputToString()).To(Equal(name)) + + inspect := podmanTest.Podman([]string{"network", "inspect", name}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet1)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet2)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"ipv6_enabled": true`)) + }) + + It("podman network create with multiple subnets dual stack with gateway and range", func() { + name := "subnets-" + stringid.GenerateNonCryptoID() + subnet1 := "10.10.3.0/24" + gw1 := "10.10.3.10" + range1 := "10.10.3.0/26" + subnet2 := "fd52:2a5a:747e:3acd::/64" + gw2 := "fd52:2a5a:747e:3acd::10" + nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--gateway", gw1, "--ip-range", range1, "--subnet", subnet2, "--gateway", gw2, name}) + nc.WaitWithDefaultTimeout() + defer podmanTest.removeCNINetwork(name) + Expect(nc).To(Exit(0)) + Expect(nc.OutputToString()).To(Equal(name)) + + inspect := podmanTest.Podman([]string{"network", "inspect", name}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet1)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"gateway": "` + gw1)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"start_ip": "10.10.3.1",`)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"end_ip": "10.10.3.63"`)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet2)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"gateway": "` + gw2)) + Expect(inspect.OutputToString()).To(ContainSubstring(`"ipv6_enabled": true`)) + }) + + It("podman network create invalid options with multiple subnets", func() { + name := "subnets-" + stringid.GenerateNonCryptoID() + subnet1 := "10.10.3.0/24" + gw1 := "10.10.3.10" + gw2 := "fd52:2a5a:747e:3acd::10" + nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--gateway", gw1, "--gateway", gw2, name}) + nc.WaitWithDefaultTimeout() + Expect(nc).To(Exit(125)) + Expect(nc.ErrorToString()).To(Equal("Error: cannot set more gateways than subnets")) + + range1 := "10.10.3.0/26" + range2 := "10.10.3.0/28" + nc = podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--ip-range", range1, "--ip-range", range2, name}) + nc.WaitWithDefaultTimeout() + Expect(nc).To(Exit(125)) + Expect(nc.ErrorToString()).To(Equal("Error: cannot set more ranges than subnets")) + }) }) diff --git a/test/system/520-checkpoint.bats b/test/system/520-checkpoint.bats index 046dfd126..fcb7fbb84 100644 --- a/test/system/520-checkpoint.bats +++ b/test/system/520-checkpoint.bats @@ -15,6 +15,10 @@ function setup() { skip "FIXME: checkpointing broken in Ubuntu 2004, 2104, 2110, ..." fi + if [[ "$(uname -r)" =~ "5.17" ]]; then + skip "FIXME: checkpointing broken on kernel 5.17 (#12949)" + fi + # None of these tests work rootless.... if is_rootless; then # ...however, is that a genuine cast-in-stone limitation, or one diff --git a/troubleshooting.md b/troubleshooting.md index 114a96d41..82ca64305 100644 --- a/troubleshooting.md +++ b/troubleshooting.md @@ -907,3 +907,15 @@ Resolution steps * Before invoking Podman command create a valid login session for your rootless user using `loginctl enable-linger <username>` * If `loginctl` is unavailable you can also try logging in via `ssh` i.e `ssh <username>@localhost`. + +### 31) 127.0.0.1:7777 port already bound + +After deleting a VM on macOS, the initialization of subsequent VMs fails. + +#### Symptom + +After deleting a client VM on macOS via `podman machine stop` && `podman machine rm`, attempting to `podman machine init` a new client VM leads to an error with the 127.0.0.1:7777 port already bound. + +### Solution + +You will need to remove the hanging gv-proxy process bound to the port in question. For example, if the port mentioned in the error message is 127.0.0.1:7777, you can use the command `kill -9 $(lsof -i:7777)` in order to identify and remove the hanging process which prevents you from starting a new VM on that default port. |