From 4b8ca63039e411fb890df3a4b38b768499f3f012 Mon Sep 17 00:00:00 2001 From: Matej Vasek Date: Tue, 1 Jun 2021 15:05:13 +0200 Subject: [PATCH 1/7] Use request context instead of background This prevents goroutine leak: If background context were used then push operation would continue even if client aborted request by closing connection. [NO TESTS NEEDED] Signed-off-by: Matej Vasek --- pkg/api/handlers/compat/images_push.go | 112 ++++++++++++------------- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go index db02af4459..62f8cdc772 100644 --- a/pkg/api/handlers/compat/images_push.go +++ b/pkg/api/handlers/compat/images_push.go @@ -1,7 +1,6 @@ package compat import ( - "context" "encoding/json" "fmt" "io/ioutil" @@ -12,7 +11,6 @@ import ( "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/pkg/api/handlers/utils" "github.com/containers/podman/v3/pkg/auth" - "github.com/containers/podman/v3/pkg/channel" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/infra/abi" "github.com/containers/storage" @@ -101,46 +99,33 @@ func PushImage(w http.ResponseWriter, r *http.Request) { destination = imageName } - errorWriter := channel.NewWriter(make(chan []byte)) - defer errorWriter.Close() - - statusWriter := channel.NewWriter(make(chan []byte)) - defer statusWriter.Close() - - runCtx, cancel := context.WithCancel(context.Background()) - var failed bool - - go func() { - defer cancel() - - statusWriter.Write([]byte(fmt.Sprintf("The push refers to repository [%s]", imageName))) - - err := imageEngine.Push(runCtx, imageName, destination, options) - if err != nil { - if errors.Cause(err) != storage.ErrImageUnknown { - errorWriter.Write([]byte("An image does not exist locally with the tag: " + imageName)) - } else { - errorWriter.Write([]byte(err.Error())) - } - } - }() - - flush := func() { - if flusher, ok := w.(http.Flusher); ok { - flusher.Flush() - } + flush := func() {} + if flusher, ok := w.(http.Flusher); ok { + flush = flusher.Flush } w.WriteHeader(http.StatusOK) w.Header().Add("Content-Type", "application/json") flush() + var report jsonmessage.JSONMessage enc := json.NewEncoder(w) enc.SetEscapeHTML(true) + report.Status = fmt.Sprintf("The push refers to repository [%s]", imageName) + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to json encode error %q", err.Error()) + } + flush() + + pushErrChan := make(chan error) + go func() { + pushErrChan <- imageEngine.Push(r.Context(), imageName, destination, options) + }() + loop: // break out of for/select infinite loop for { - var report jsonmessage.JSONMessage + report = jsonmessage.JSONMessage{} select { case e := <-options.Progress: @@ -160,43 +145,50 @@ loop: // break out of for/select infinite loop } report.ID = e.Artifact.Digest.Encoded()[0:12] if err := enc.Encode(report); err != nil { - errorWriter.Write([]byte(err.Error())) + logrus.Warnf("Failed to json encode error %q", err.Error()) } flush() - case e := <-statusWriter.Chan(): - report.Status = string(e) - if err := enc.Encode(report); err != nil { - errorWriter.Write([]byte(err.Error())) + case err := <-pushErrChan: + if err != nil { + var msg string + if errors.Cause(err) != storage.ErrImageUnknown { + msg = "An image does not exist locally with the tag: " + imageName + } else { + msg = err.Error() + } + report.Error = &jsonmessage.JSONError{ + Message: msg, + } + report.ErrorMessage = msg + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to json encode error %q", err.Error()) + } + flush() + break loop } - flush() - case e := <-errorWriter.Chan(): - failed = true - report.Error = &jsonmessage.JSONError{ - Message: string(e), + + digestBytes, err := ioutil.ReadAll(digestFile) + if err != nil { + report.Error = &jsonmessage.JSONError{ + Message: err.Error(), + } + report.ErrorMessage = err.Error() + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to json encode error %q", err.Error()) + } + flush() + break loop } - report.ErrorMessage = string(e) + tag := query.Tag + if tag == "" { + tag = "latest" + } + report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes)) if err := enc.Encode(report); err != nil { logrus.Warnf("Failed to json encode error %q", err.Error()) } + flush() - case <-runCtx.Done(): - if !failed { - digestBytes, err := ioutil.ReadAll(digestFile) - if err == nil { - tag := query.Tag - if tag == "" { - tag = "latest" - } - report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes)) - if err := enc.Encode(report); err != nil { - logrus.Warnf("Failed to json encode error %q", err.Error()) - } - flush() - } - } - break loop // break out of for/select infinite loop - case <-r.Context().Done(): - // Client has closed connection break loop // break out of for/select infinite loop } } From f62c6bf6ecd1737afab66e2e79064bf14719d36f Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 2 Jun 2021 21:00:26 +0200 Subject: [PATCH 2/7] add ipv6 nameservers only when the container has ipv6 enabled The containers /etc/resolv.conf allways preserved the ipv6 nameserves from the host even when the container did not supported ipv6. Check if the cni result contains an ipv6 address or slirp4netns has ipv6 support enabled and only add the ipv6 nameservers when this is the case. The test needs to have an ipv6 nameserver in the hosts /etc/hosts but we should never mess with this file on the host. Therefore the test is skipped when no ipv6 is detected. Fixes #10158 Signed-off-by: Paul Holzinger --- libpod/container_internal_linux.go | 34 +++++++++++++----- test/system/500-networking.bats | 58 ++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 17b894ce0a..df9e03e78f 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -1666,17 +1666,16 @@ func (c *Container) generateResolvConf() (string, error) { return "", err } - // Ensure that the container's /etc/resolv.conf is compatible with its - // network configuration. - // TODO: set ipv6 enable bool more sanely - resolv, err := resolvconf.FilterResolvDNS(contents, true, c.config.CreateNetNS) - if err != nil { - return "", errors.Wrapf(err, "error parsing host resolv.conf") - } - + ipv6 := false // Check if CNI gave back and DNS servers for us to add in cniResponse := c.state.NetworkStatus for _, i := range cniResponse { + for _, ip := range i.IPs { + // Note: only using To16() does not work since it also returns a vaild ip for ipv4 + if ip.Address.IP.To4() == nil && ip.Address.IP.To16() != nil { + ipv6 = true + } + } if i.DNS.Nameservers != nil { cniNameServers = append(cniNameServers, i.DNS.Nameservers...) logrus.Debugf("adding nameserver(s) from cni response of '%q'", i.DNS.Nameservers) @@ -1687,6 +1686,25 @@ func (c *Container) generateResolvConf() (string, error) { } } + if c.config.NetMode.IsSlirp4netns() { + ctrNetworkSlipOpts := []string{} + if c.config.NetworkOptions != nil { + ctrNetworkSlipOpts = append(ctrNetworkSlipOpts, c.config.NetworkOptions["slirp4netns"]...) + } + slirpOpts, err := parseSlirp4netnsNetworkOptions(c.runtime, ctrNetworkSlipOpts) + if err != nil { + return "", err + } + ipv6 = slirpOpts.enableIPv6 + } + + // Ensure that the container's /etc/resolv.conf is compatible with its + // network configuration. + resolv, err := resolvconf.FilterResolvDNS(contents, ipv6, c.config.CreateNetNS) + if err != nil { + return "", errors.Wrapf(err, "error parsing host resolv.conf") + } + dns := make([]net.IP, 0, len(c.runtime.config.Containers.DNSServers)) for _, i := range c.runtime.config.Containers.DNSServers { result := net.ParseIP(i) diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 63b9a7c14b..55ec80bb26 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -329,4 +329,62 @@ load helpers run_podman network rm -f $mynetname } +@test "podman ipv6 in /etc/resolv.conf" { + ipv6_regex='([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})(%\w+)?' + + # Make sure to read the correct /etc/resolv.conf file in case of systemd-resolved. + resolve_file=$(readlink -f /etc/resolv.conf) + if [[ "$resolve_file" == "/run/systemd/resolve/stub-resolv.conf" ]]; then + resolve_file="/run/systemd/resolve/resolv.conf" + fi + + # If the host doesn't have an ipv6 in resolv.conf skip this test. + # We should never modify resolv.conf on the host. + if ! grep -E "$ipv6_regex" "$resolve_file"; then + skip "This test needs an ipv6 nameserver in $resolve_file" + fi + + # ipv4 slirp + run_podman run --rm --network slirp4netns:enable_ipv6=false $IMAGE cat /etc/resolv.conf + if grep -E "$ipv6_regex" <<< $output; then + die "resolv.conf contains a ipv6 nameserver" + fi + + # ipv6 slirp + run_podman run --rm --network slirp4netns:enable_ipv6=true $IMAGE cat /etc/resolv.conf + # "is" does not like the ipv6 regex + if ! grep -E "$ipv6_regex" <<< $output; then + die "resolv.conf does not contain a ipv6 nameserver" + fi + + # ipv4 cni + local mysubnet=$(random_rfc1918_subnet) + local netname=testnet-$(random_string 10) + + run_podman network create --subnet $mysubnet.0/24 $netname + is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" + + run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf + if grep -E "$ipv6_regex" <<< $output; then + die "resolv.conf contains a ipv6 nameserver" + fi + + run_podman network rm -f $netname + + # ipv6 cni + mysubnet=fd00:4:4:4:4::/64 + netname=testnet-$(random_string 10) + + run_podman network create --subnet $mysubnet $netname + is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" + + run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf + # "is" does not like the ipv6 regex + if ! grep -E "$ipv6_regex" <<< $output; then + die "resolv.conf does not contain a ipv6 nameserver" + fi + + run_podman network rm -f $netname +} + # vim: filetype=sh From 8688f54eacd7b4f18037fccd564d300142ad306e Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 3 Jun 2021 13:57:49 -0400 Subject: [PATCH 3/7] Final release notes updates for v3.2.0 Signed-off-by: Matthew Heon --- RELEASE_NOTES.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a08439b920..c6efff5ddd 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -44,6 +44,7 @@ - Fixed a bug where the remote Podman client's `podman build --iidfile` command could include extra output (in addition to just the image ID) in the image ID file written ([#10233](https://github.com/containers/podman/issues/10233)). - Fixed a bug where the remote Podman client's `podman build` command did not preserve hardlinks when moving files into the container via `COPY` instructions ([#9893](https://github.com/containers/podman/issues/9893)). - Fixed a bug where the `podman generate systemd --new` command could generate extra `--iidfile` arguments if the container was already created with one. +- Fixed a bug where the `podman generate systemd --new` command would generate unit files that did not include `RequiresMountsFor` lines ([#10493](https://github.com/containers/podman/issues/10493)). - Fixed a bug where the `podman generate kube` command produced incorrect YAML for containers which bind-mounted both `/` and `/root` from the host system into the container ([#9764](https://github.com/containers/podman/issues/9764)). - Fixed a bug where pods created by `podman play kube` from YAML that specified `ShareProcessNamespace` would only share the PID namespace (and not also the UTS, Network, and IPC namespaces) ([#9128](https://github.com/containers/podman/issues/9128)). - Fixed a bug where the `podman network reload` command could generate spurious error messages when `iptables-nft` was in use. @@ -58,6 +59,9 @@ - Fixed a bug where Podman could freeze when creating containers with a specific combination of volumes and working directory ([#10216](https://github.com/containers/podman/issues/10216)). - Fixed a bug where rootless Podman containers restarted by restart policy (e.g. containers created with `--restart=always`) would lose networking after being restarted ([#8047](https://github.com/containers/podman/issues/8047)). - Fixed a bug where the `podman cp` command could not copy files into containers created with the `--pid=host` flag ([#9985](https://github.com/containers/podman/issues/9985)). +- Fixed a bug where filters to the `podman events` command could not be specified twice (if a filter is specified more than once, it will match if any of the given values match - logical or) ([#10507](https://github.com/containers/podman/issues/10507)). +- Fixed a bug where Podman would include IPv6 nameservers in `resolv.conf` in containers without IPv6 connectivity ([#10158](https://github.com/containers/podman/issues/10158)). +- Fixed a bug where containers could not be created with static IP addresses when connecting to a network using the `macvlan` driver ([#10283](https://github.com/containers/podman/issues/10283)). ### API - Fixed a bug where the Compat Create endpoint for Containers did not allow advanced network options to be set ([#10110](https://github.com/containers/podman/issues/10110)). @@ -67,11 +71,12 @@ - Fixed a bug where the Compat Create endpoint for Volumes required that the user provide a name for the new volume ([#9803](https://github.com/containers/podman/issues/9803)). - Fixed a bug where the Libpod Info handler would sometimes not return the correct path to the Podman API socket. - Fixed a bug where the Compat Events handler used the wrong name for container exited events (`died` instead of `die`) ([#10168](https://github.com/containers/podman/issues/10168)). +- Fixed a bug where the Compat Push endpoint for Images could leak goroutines if the remote end closed the connection prematurely. ### Misc - Updated Buildah to v1.21.0 -- Updated the containers/common library to v0.38.4 -- Updated the containers/storage library to v1.31.1 +- Updated the containers/common library to v0.38.5 +- Updated the containers/storage library to v1.31.3 ## 3.1.2 ### Bugfixes From cff73766fc4421774ad3b9a3cefa12abde2c5c03 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 20 May 2021 11:23:03 +0200 Subject: [PATCH 4/7] Fix network create macvlan with subnet option Creating a macvlan network with the subnet or ipRange option should set the ipam plugin type to `host-local`. We also have to insert the default route. Fixes #10283 Signed-off-by: Paul Holzinger --- libpod/network/config.go | 43 +++++++++++++++-------------------- libpod/network/netconflist.go | 18 +++++++++++---- test/e2e/network_test.go | 26 ++++++++++++++++++--- 3 files changed, 54 insertions(+), 33 deletions(-) diff --git a/libpod/network/config.go b/libpod/network/config.go index ac44786023..9a3bc47638 100644 --- a/libpod/network/config.go +++ b/libpod/network/config.go @@ -44,17 +44,17 @@ type CNIPlugins interface { // HostLocalBridge describes a configuration for a bridge plugin // https://github.com/containernetworking/plugins/tree/master/plugins/main/bridge#network-configuration-reference type HostLocalBridge struct { - PluginType string `json:"type"` - BrName string `json:"bridge,omitempty"` - IsGW bool `json:"isGateway"` - IsDefaultGW bool `json:"isDefaultGateway,omitempty"` - ForceAddress bool `json:"forceAddress,omitempty"` - IPMasq bool `json:"ipMasq,omitempty"` - MTU int `json:"mtu,omitempty"` - HairpinMode bool `json:"hairpinMode,omitempty"` - PromiscMode bool `json:"promiscMode,omitempty"` - Vlan int `json:"vlan,omitempty"` - IPAM IPAMHostLocalConf `json:"ipam"` + PluginType string `json:"type"` + BrName string `json:"bridge,omitempty"` + IsGW bool `json:"isGateway"` + IsDefaultGW bool `json:"isDefaultGateway,omitempty"` + ForceAddress bool `json:"forceAddress,omitempty"` + IPMasq bool `json:"ipMasq,omitempty"` + MTU int `json:"mtu,omitempty"` + HairpinMode bool `json:"hairpinMode,omitempty"` + PromiscMode bool `json:"promiscMode,omitempty"` + Vlan int `json:"vlan,omitempty"` + IPAM IPAMConfig `json:"ipam"` } // Bytes outputs []byte @@ -62,9 +62,9 @@ func (h *HostLocalBridge) Bytes() ([]byte, error) { return json.MarshalIndent(h, "", "\t") } -// IPAMHostLocalConf describes an IPAM configuration +// IPAMConfig describes an IPAM configuration // https://github.com/containernetworking/plugins/tree/master/plugins/ipam/host-local#network-configuration-reference -type IPAMHostLocalConf struct { +type IPAMConfig struct { PluginType string `json:"type"` Routes []IPAMRoute `json:"routes,omitempty"` ResolveConf string `json:"resolveConf,omitempty"` @@ -81,7 +81,7 @@ type IPAMLocalHostRangeConf struct { } // Bytes outputs the configuration as []byte -func (i IPAMHostLocalConf) Bytes() ([]byte, error) { +func (i IPAMConfig) Bytes() ([]byte, error) { return json.MarshalIndent(i, "", "\t") } @@ -101,19 +101,12 @@ func (p PortMapConfig) Bytes() ([]byte, error) { return json.MarshalIndent(p, "", "\t") } -// IPAMDHCP describes the ipamdhcp config -type IPAMDHCP struct { - DHCP string `json:"type"` - Routes []IPAMRoute `json:"routes,omitempty"` - Ranges [][]IPAMLocalHostRangeConf `json:"ranges,omitempty"` -} - // MacVLANConfig describes the macvlan config type MacVLANConfig struct { - PluginType string `json:"type"` - Master string `json:"master"` - IPAM IPAMDHCP `json:"ipam"` - MTU int `json:"mtu,omitempty"` + PluginType string `json:"type"` + Master string `json:"master"` + IPAM IPAMConfig `json:"ipam"` + MTU int `json:"mtu,omitempty"` } // Bytes outputs the configuration as []byte diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go index d2031df6d1..d6c33740ea 100644 --- a/libpod/network/netconflist.go +++ b/libpod/network/netconflist.go @@ -45,7 +45,7 @@ func NewNcList(name, version string, labels NcLabels) NcList { } // NewHostLocalBridge creates a new LocalBridge for host-local -func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, mtu int, vlan int, ipamConf IPAMHostLocalConf) *HostLocalBridge { +func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, mtu int, vlan int, ipamConf IPAMConfig) *HostLocalBridge { hostLocalBridge := HostLocalBridge{ PluginType: "bridge", BrName: name, @@ -65,8 +65,8 @@ func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, mtu in } // NewIPAMHostLocalConf creates a new IPAMHostLocal configuration -func NewIPAMHostLocalConf(routes []IPAMRoute, ipamRanges [][]IPAMLocalHostRangeConf) (IPAMHostLocalConf, error) { - ipamConf := IPAMHostLocalConf{ +func NewIPAMHostLocalConf(routes []IPAMRoute, ipamRanges [][]IPAMLocalHostRangeConf) (IPAMConfig, error) { + ipamConf := IPAMConfig{ PluginType: "host-local", Routes: routes, // Possible future support ? Leaving for clues @@ -177,8 +177,10 @@ func HasDNSNamePlugin(paths []string) bool { // NewMacVLANPlugin creates a macvlanconfig with a given device name func NewMacVLANPlugin(device string, gateway net.IP, ipRange *net.IPNet, subnet *net.IPNet, mtu int) (MacVLANConfig, error) { - i := IPAMDHCP{DHCP: "dhcp"} - if gateway != nil || ipRange != nil || subnet != nil { + i := IPAMConfig{PluginType: "dhcp"} + if gateway != nil || + (ipRange != nil && ipRange.IP != nil && ipRange.Mask != nil) || + (subnet != nil && subnet.IP != nil && subnet.Mask != nil) { ipam, err := NewIPAMLocalHostRange(subnet, ipRange, gateway) if err != nil { return MacVLANConfig{}, err @@ -186,6 +188,12 @@ func NewMacVLANPlugin(device string, gateway net.IP, ipRange *net.IPNet, subnet ranges := make([][]IPAMLocalHostRangeConf, 0) ranges = append(ranges, ipam) i.Ranges = ranges + route, err := NewIPAMDefaultRoute(IsIPv6(subnet.IP)) + if err != nil { + return MacVLANConfig{}, err + } + i.Routes = []IPAMRoute{route} + i.PluginType = "host-local" } m := MacVLANConfig{ diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index 6f28d7e19f..a7e61932ed 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -533,7 +533,11 @@ var _ = Describe("Podman network", func() { out, err := inspect.jq(".[0].plugins[0].master") Expect(err).To(BeNil()) - Expect(out).To(Equal("\"lo\"")) + Expect(out).To(Equal(`"lo"`)) + + ipamType, err := inspect.jq(".[0].plugins[0].ipam.type") + Expect(err).To(BeNil()) + Expect(ipamType).To(Equal(`"dhcp"`)) nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() @@ -571,13 +575,29 @@ var _ = Describe("Podman network", func() { Expect(err).To(BeNil()) Expect(mtu).To(Equal("1500")) + name, err := inspect.jq(".[0].plugins[0].type") + Expect(err).To(BeNil()) + Expect(name).To(Equal(`"macvlan"`)) + + netInt, err := inspect.jq(".[0].plugins[0].master") + Expect(err).To(BeNil()) + Expect(netInt).To(Equal(`"lo"`)) + + ipamType, err := inspect.jq(".[0].plugins[0].ipam.type") + Expect(err).To(BeNil()) + Expect(ipamType).To(Equal(`"host-local"`)) + gw, err := inspect.jq(".[0].plugins[0].ipam.ranges[0][0].gateway") Expect(err).To(BeNil()) - Expect(gw).To(Equal("\"192.168.1.254\"")) + Expect(gw).To(Equal(`"192.168.1.254"`)) subnet, err := inspect.jq(".[0].plugins[0].ipam.ranges[0][0].subnet") Expect(err).To(BeNil()) - Expect(subnet).To(Equal("\"192.168.1.0/24\"")) + Expect(subnet).To(Equal(`"192.168.1.0/24"`)) + + routes, err := inspect.jq(".[0].plugins[0].ipam.routes[0].dst") + Expect(err).To(BeNil()) + Expect(routes).To(Equal(`"0.0.0.0/0"`)) nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() From 0281ef262dd0ffae28b5fa5e4bdf545f93c08dc7 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 3 Jun 2021 13:59:24 -0400 Subject: [PATCH 5/7] Bump to v3.2.0 Signed-off-by: Matthew Heon --- changelog.txt | 10 ++++++++++ version/version.go | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 2792868397..0441908e62 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,13 @@ +- Changelog for v3.2.0 (2021-06-03): + * Final release notes updates for v3.2.0 + * add ipv6 nameservers only when the container has ipv6 enabled + * Use request context instead of background + * [v.3.2] events: support disjunctive filters + * System tests: add :Z to volume mounts + * generate systemd: make mounts portable + * vendor containers/storage@v1.31.3 + * vendor containers/common@v0.38.5 + - Changelog for v3.2.0-RC3 (2021-05-26): * Update release notes for v3.2.0-RC3 * Fix race on podman start --all diff --git a/version/version.go b/version/version.go index 1cbd9e309a..e1d37432a8 100644 --- a/version/version.go +++ b/version/version.go @@ -27,7 +27,7 @@ const ( // NOTE: remember to bump the version at the top // of the top-level README.md file when this is // bumped. -var Version = semver.MustParse("3.2.0-dev") +var Version = semver.MustParse("3.2.0") // See https://docs.docker.com/engine/api/v1.40/ // libpod compat handlers are expected to honor docker API versions @@ -38,7 +38,7 @@ var Version = semver.MustParse("3.2.0-dev") var APIVersion = map[Tree]map[Level]semver.Version{ Libpod: { CurrentAPI: Version, - MinimalAPI: semver.MustParse("3.1.0"), + MinimalAPI: semver.MustParse("3.2.0"), }, Compat: { CurrentAPI: semver.MustParse("1.40.0"), From 72455ece420056634c76d79d4d88d366c8ee0815 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 3 Jun 2021 14:00:29 -0400 Subject: [PATCH 6/7] Bump to v3.2.1-dev Signed-off-by: Matthew Heon --- contrib/spec/podman.spec.in | 2 +- version/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index 02b73bdb8f..798dfb3d9f 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -36,7 +36,7 @@ Epoch: 99 %else Epoch: 0 %endif -Version: 3.2.0 +Version: 3.2.1 Release: #COMMITDATE#.git%{shortcommit0}%{?dist} Summary: Manage Pods, Containers and Container Images License: ASL 2.0 diff --git a/version/version.go b/version/version.go index e1d37432a8..606eed5af4 100644 --- a/version/version.go +++ b/version/version.go @@ -27,7 +27,7 @@ const ( // NOTE: remember to bump the version at the top // of the top-level README.md file when this is // bumped. -var Version = semver.MustParse("3.2.0") +var Version = semver.MustParse("3.2.1-dev") // See https://docs.docker.com/engine/api/v1.40/ // libpod compat handlers are expected to honor docker API versions From 9647d88449f44028c9b870af74e5e44cb819ff9d Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 3 Jun 2021 14:46:04 -0400 Subject: [PATCH 7/7] Ensure minimum API version is set correctly in tests Signed-off-by: Matthew Heon --- test/apiv2/01-basic.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/apiv2/01-basic.at b/test/apiv2/01-basic.at index 64aafa0137..ae078b9008 100644 --- a/test/apiv2/01-basic.at +++ b/test/apiv2/01-basic.at @@ -19,7 +19,7 @@ for i in /version version; do t GET $i 200 \ .Components[0].Name="Podman Engine" \ .Components[0].Details.APIVersion~3[0-9.-]\\+ \ - .Components[0].Details.MinAPIVersion=3.1.0 \ + .Components[0].Details.MinAPIVersion=3.2.0 \ .Components[0].Details.Os=linux \ .ApiVersion=1.40 \ .MinAPIVersion=1.24 \