summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/helloimage/podman_hello_world.bash24
-rw-r--r--go.mod2
-rw-r--r--go.sum3
-rw-r--r--libpod/container_internal_linux.go134
-rw-r--r--libpod/networking_linux.go48
-rw-r--r--pkg/api/handlers/libpod/networks.go66
-rw-r--r--pkg/bindings/test/networks_test.go4
-rw-r--r--test/apiv2/35-networks.at5
-rwxr-xr-xtest/apiv2/test-apiv210
-rw-r--r--test/e2e/network_connect_disconnect_test.go31
-rw-r--r--vendor/github.com/containers/common/libimage/copier.go7
-rw-r--r--vendor/github.com/containers/common/libimage/manifests/manifests.go12
-rw-r--r--vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go29
-rw-r--r--vendor/github.com/containers/common/libnetwork/cni/config.go2
-rw-r--r--vendor/github.com/containers/common/libnetwork/internal/util/validate.go6
-rw-r--r--vendor/github.com/containers/common/libnetwork/netavark/config.go9
-rw-r--r--vendor/github.com/containers/common/libnetwork/netavark/network.go4
-rw-r--r--vendor/github.com/containers/common/pkg/auth/auth.go2
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/modules.txt2
20 files changed, 319 insertions, 83 deletions
diff --git a/contrib/helloimage/podman_hello_world.bash b/contrib/helloimage/podman_hello_world.bash
index c28141174..a8919c92b 100755
--- a/contrib/helloimage/podman_hello_world.bash
+++ b/contrib/helloimage/podman_hello_world.bash
@@ -4,18 +4,18 @@
# duffy@redhat.com, Twitter: @mairin
# January 2022
###
-echo " "
-echo "! ... Hello Podman World ...!"
-echo " "
-echo " .--\"--. "
-echo " / - - \\ "
-echo " / (O) (O) \\ "
-echo " ~~~| -=(,Y,)=- | "
-echo " .---. /\` \\ |~~ "
-echo " ~/ o o \\~~~~.----. ~~ "
-echo " | =(X)= |~ / (O (O) \\ "
-echo " ~~~~~~~ ~| =(Y_)=- | "
-echo " ~~~~ ~~~| U |~~ "
+echo " "
+echo "! ... Hello Podman World ... !"
+echo " "
+echo " .--\"--. "
+echo " / - - \\ "
+echo " / (O) (O) \\ "
+echo " ~~~| -=(,Y,)=- | "
+echo " .---. /\` \\ |~~ "
+echo " ~/ o o \\~~~~.----. ~~ "
+echo " | =(X)= |~ / (O (O) \\ "
+echo " ~~~~~~~ ~| =(Y_)=- | "
+echo " ~~~~ ~~~| U |~~ "
echo ""
echo "Project: https://github.com/containers/podman"
echo "Website: https://podman.io"
diff --git a/go.mod b/go.mod
index 789c53f15..79880469b 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.0.1
github.com/containers/buildah v1.24.1
- github.com/containers/common v0.47.3
+ github.com/containers/common v0.47.4
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.19.1
github.com/containers/ocicrypt v1.1.2
diff --git a/go.sum b/go.sum
index 15565d743..b291e068e 100644
--- a/go.sum
+++ b/go.sum
@@ -325,8 +325,9 @@ github.com/containernetworking/plugins v1.0.1 h1:wwCfYbTCj5FC0EJgyzyjTXmqysOiJE9
github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE=
github.com/containers/buildah v1.24.1 h1:PlvU0hbUsm1x4H9kPcsmqjViqDGnBpSZT3QtZ00RtgI=
github.com/containers/buildah v1.24.1/go.mod h1:sE7AaoPQYwAB7dleOOKOpzOO3bA8lRUvZRiZcn/RYi0=
-github.com/containers/common v0.47.3 h1:pRT7gkLrBSQe3075j5hoHYeeKpGTWBJHws+tS5xxfak=
github.com/containers/common v0.47.3/go.mod h1:/VAV4ibC27Lfyb9cxXM4uTYrJFa/7s+utNB052MJdzY=
+github.com/containers/common v0.47.4 h1:kS202Z/bTQIM/pwyuJ+lF8143Uli6AB9Q9OVR0xa9CM=
+github.com/containers/common v0.47.4/go.mod h1:HgX0mFXyB0Tbe2REEIp9x9CxET6iSzmHfwR6S/t2LZc=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.19.1 h1:g4/+XIuh1kRoRn2MfLDhfHhkNOIO9JtqhSyo55tjpfE=
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 95f1634a8..afa351c17 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2045,19 +2045,8 @@ func (c *Container) generateResolvConf() (string, error) {
}
}
- ipv6 := false
- // If network status is set check for ipv6 and dns namesevers
netStatus := c.getNetworkStatus()
for _, status := range netStatus {
- for _, netInt := range status.Interfaces {
- for _, netAddress := range netInt.Subnets {
- // Note: only using To16() does not work since it also returns a valid ip for ipv4
- if netAddress.IPNet.IP.To4() == nil && netAddress.IPNet.IP.To16() != nil {
- ipv6 = true
- }
- }
- }
-
if status.DNSServerIPs != nil {
for _, nsIP := range status.DNSServerIPs {
networkNameServers = append(networkNameServers, nsIP.String())
@@ -2070,16 +2059,9 @@ 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
+ ipv6, err := c.checkForIPv6(netStatus)
+ if err != nil {
+ return "", err
}
// Ensure that the container's /etc/resolv.conf is compatible with its
@@ -2160,6 +2142,116 @@ func (c *Container) generateResolvConf() (string, error) {
return destPath, nil
}
+// Check if a container uses IPv6.
+func (c *Container) checkForIPv6(netStatus map[string]types.StatusBlock) (bool, error) {
+ for _, status := range netStatus {
+ for _, netInt := range status.Interfaces {
+ for _, netAddress := range netInt.Subnets {
+ // Note: only using To16() does not work since it also returns a valid ip for ipv4
+ if netAddress.IPNet.IP.To4() == nil && netAddress.IPNet.IP.To16() != nil {
+ return true, nil
+ }
+ }
+ }
+ }
+
+ 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 false, err
+ }
+ return slirpOpts.enableIPv6, nil
+ }
+
+ return false, nil
+}
+
+// Add a new nameserver to the container's resolv.conf, ensuring that it is the
+// first nameserver present.
+// Usable only with running containers.
+func (c *Container) addNameserver(ips []string) error {
+ // Take no action if container is not running.
+ if !c.ensureState(define.ContainerStateRunning, define.ContainerStateCreated) {
+ return nil
+ }
+
+ // Do we have a resolv.conf at all?
+ path, ok := c.state.BindMounts["/etc/resolv.conf"]
+ if !ok {
+ return nil
+ }
+
+ // Read in full contents, parse out existing nameservers
+ contents, err := ioutil.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ ns := resolvconf.GetNameservers(contents)
+ options := resolvconf.GetOptions(contents)
+ search := resolvconf.GetSearchDomains(contents)
+
+ // We could verify that it doesn't already exist
+ // but extra nameservers shouldn't harm anything.
+ // Ensure we are the first entry in resolv.conf though, otherwise we
+ // might be after user-added servers.
+ ns = append(ips, ns...)
+
+ // We're rewriting the container's resolv.conf as part of this, but we
+ // hold the container lock, so there should be no risk of parallel
+ // modification.
+ if _, err := resolvconf.Build(path, ns, search, options); err != nil {
+ return errors.Wrapf(err, "error adding new nameserver to container %s resolv.conf", c.ID())
+ }
+
+ return nil
+}
+
+// Remove an entry from the existing resolv.conf of the container.
+// Usable only with running containers.
+func (c *Container) removeNameserver(ips []string) error {
+ // Take no action if container is not running.
+ if !c.ensureState(define.ContainerStateRunning, define.ContainerStateCreated) {
+ return nil
+ }
+
+ // Do we have a resolv.conf at all?
+ path, ok := c.state.BindMounts["/etc/resolv.conf"]
+ if !ok {
+ return nil
+ }
+
+ // Read in full contents, parse out existing nameservers
+ contents, err := ioutil.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ ns := resolvconf.GetNameservers(contents)
+ options := resolvconf.GetOptions(contents)
+ search := resolvconf.GetSearchDomains(contents)
+
+ toRemove := make(map[string]bool)
+ for _, ip := range ips {
+ toRemove[ip] = true
+ }
+
+ newNS := make([]string, 0, len(ns))
+ for _, server := range ns {
+ if !toRemove[server] {
+ newNS = append(newNS, server)
+ }
+ }
+
+ if _, err := resolvconf.Build(path, newNS, search, options); err != nil {
+ return errors.Wrapf(err, "error removing nameservers from container %s resolv.conf", c.ID())
+ }
+
+ return nil
+}
+
// updateHosts updates the container's hosts file
func (c *Container) updateHosts(path string) error {
var hosts string
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index e55e9d114..19d5c7f76 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -1170,6 +1170,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
}
// update network status if container is running
+ oldStatus, statusExist := networkStatus[netName]
delete(networkStatus, netName)
c.state.NetworkStatus = networkStatus
err = c.save()
@@ -1180,8 +1181,26 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
// Reload ports when there are still connected networks, maybe we removed the network interface with the child ip.
// Reloading without connected networks does not make sense, so we can skip this step.
if rootless.IsRootless() && len(networkStatus) > 0 {
- return c.reloadRootlessRLKPortMapping()
+ if err := c.reloadRootlessRLKPortMapping(); err != nil {
+ return err
+ }
+ }
+
+ // Update resolv.conf if required
+ if statusExist {
+ stringIPs := make([]string, 0, len(oldStatus.DNSServerIPs))
+ for _, ip := range oldStatus.DNSServerIPs {
+ stringIPs = append(stringIPs, ip.String())
+ }
+ if len(stringIPs) == 0 {
+ return nil
+ }
+ logrus.Debugf("Removing DNS Servers %v from resolv.conf", stringIPs)
+ if err := c.removeNameserver(stringIPs); err != nil {
+ return err
+ }
}
+
return nil
}
@@ -1263,11 +1282,36 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
if err != nil {
return err
}
+
// The first network needs a port reload to set the correct child ip for the rootlessport process.
// Adding a second network does not require a port reload because the child ip is still valid.
if rootless.IsRootless() && len(networks) == 0 {
- return c.reloadRootlessRLKPortMapping()
+ if err := c.reloadRootlessRLKPortMapping(); err != nil {
+ return err
+ }
}
+
+ ipv6, err := c.checkForIPv6(networkStatus)
+ if err != nil {
+ return err
+ }
+
+ // Update resolv.conf if required
+ stringIPs := make([]string, 0, len(results[netName].DNSServerIPs))
+ for _, ip := range results[netName].DNSServerIPs {
+ if (ip.To4() == nil) && !ipv6 {
+ continue
+ }
+ stringIPs = append(stringIPs, ip.String())
+ }
+ if len(stringIPs) == 0 {
+ return nil
+ }
+ logrus.Debugf("Adding DNS Servers %v to resolv.conf", stringIPs)
+ if err := c.addNameserver(stringIPs); err != nil {
+ return err
+ }
+
return nil
}
diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go
index 71d46ce70..16f499d4c 100644
--- a/pkg/api/handlers/libpod/networks.go
+++ b/pkg/api/handlers/libpod/networks.go
@@ -17,22 +17,37 @@ import (
)
func CreateNetwork(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
network := types.Network{}
if err := json.NewDecoder(r.Body).Decode(&network); err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "decode body"))
+ utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "failed to decode request JSON payload"))
return
}
ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.NetworkCreate(r.Context(), network)
if err != nil {
- utils.InternalServerError(w, err)
+ if errors.Is(err, types.ErrNetworkExists) {
+ utils.Error(w, http.StatusConflict, err)
+ } else {
+ utils.InternalServerError(w, err)
+ }
return
}
utils.WriteResponse(w, http.StatusOK, report)
}
+
func ListNetworks(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
filterMap, err := util.PrepareFilters(r)
if err != nil {
@@ -54,6 +69,11 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
}
func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
@@ -87,21 +107,18 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, reports)
}
+// InspectNetwork reports on given network's details
func InspectNetwork(w http.ResponseWriter, r *http.Request) {
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
- query := struct {
- }{
- // override any golang type defaults
- }
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, http.StatusInternalServerError,
- errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
return
}
+
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ ic := abi.ContainerEngine{Libpod: runtime}
+
name := utils.GetName(r)
options := entities.InspectOptions{}
- ic := abi.ContainerEngine{Libpod: runtime}
reports, errs, err := ic.NetworkInspect(r.Context(), []string{name}, options)
// If the network cannot be found, we return a 404.
if len(errs) > 0 {
@@ -117,14 +134,19 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
// Connect adds a container to a network
func Connect(w http.ResponseWriter, r *http.Request) {
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
var netConnect entities.NetworkConnectOptions
if err := json.NewDecoder(r.Body).Decode(&netConnect); err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
+ utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "failed to decode request JSON payload"))
return
}
name := utils.GetName(r)
+
err := runtime.ConnectContainerToNetwork(netConnect.Container, name, netConnect.PerNetworkOptions)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
@@ -143,10 +165,15 @@ func Connect(w http.ResponseWriter, r *http.Request) {
// ExistsNetwork check if a network exists
func ExistsNetwork(w http.ResponseWriter, r *http.Request) {
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- name := utils.GetName(r)
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
ic := abi.ContainerEngine{Libpod: runtime}
+
+ name := utils.GetName(r)
report, err := ic.NetworkExists(r.Context(), name)
if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
@@ -161,7 +188,13 @@ func ExistsNetwork(w http.ResponseWriter, r *http.Request) {
// Prune removes unused networks
func Prune(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ ic := abi.ContainerEngine{Libpod: runtime}
filterMap, err := util.PrepareFilters(r)
if err != nil {
@@ -172,7 +205,6 @@ func Prune(w http.ResponseWriter, r *http.Request) {
pruneOptions := entities.NetworkPruneOptions{
Filters: *filterMap,
}
- ic := abi.ContainerEngine{Libpod: runtime}
pruneReports, err := ic.NetworkPrune(r.Context(), pruneOptions)
if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
diff --git a/pkg/bindings/test/networks_test.go b/pkg/bindings/test/networks_test.go
index ee2d6f472..137db71a3 100644
--- a/pkg/bindings/test/networks_test.go
+++ b/pkg/bindings/test/networks_test.go
@@ -80,7 +80,7 @@ var _ = Describe("Podman networks", func() {
// Valid filter params => network should be pruned now.
filters = map[string][]string{
- "until": {"5000000000"}, //June 11, 2128
+ "until": {"5000000000"}, // June 11, 2128
}
pruneResponse, err = network.Prune(connText, new(network.PruneOptions).WithFilters(filters))
Expect(err).To(BeNil())
@@ -105,7 +105,7 @@ var _ = Describe("Podman networks", func() {
_, err = network.Create(connText, &net)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
+ Expect(code).To(BeNumerically("==", http.StatusConflict))
})
It("inspect network", func() {
diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at
index 0e2389bd5..3502b89e0 100644
--- a/test/apiv2/35-networks.at
+++ b/test/apiv2/35-networks.at
@@ -8,7 +8,10 @@ t GET networks/non-existing-network 404 \
t POST libpod/networks/create name='"network1"' 200 \
.name=network1 \
- .created~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
+ .created~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.*
+
+t POST /v3.4.0/libpod/networks/create name='"bad_version"' 400 \
+ .cause='given version is not supported'
# --data '{"name":"network2","subnets":[{"subnet":"10.10.254.0/24"}],"Labels":{"abc":"val"}}'
t POST libpod/networks/create name='"network2"' \
diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2
index 56280f04e..bd728e130 100755
--- a/test/apiv2/test-apiv2
+++ b/test/apiv2/test-apiv2
@@ -256,11 +256,11 @@ function t() {
# If given path begins with /, use it as-is; otherwise prepend /version/
local url=http://$HOST:$PORT
- if expr "$path" : "/" >/dev/null; then
- url="$url$path"
- else
- url="$url/v1.40/$path"
- fi
+ case "$path" in
+ /*) url="$url$path" ;;
+ libpod/*) url="$url/v4.0.0/$path" ;;
+ *) url="$url/v1.41/$path" ;;
+ esac
# Log every action we do
echo "-------------------------------------------------------------" >>$LOG
diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go
index baef142ba..a0716c84d 100644
--- a/test/e2e/network_connect_disconnect_test.go
+++ b/test/e2e/network_connect_disconnect_test.go
@@ -2,6 +2,7 @@ package integration
import (
"os"
+ "strings"
. "github.com/containers/podman/v4/test/utils"
"github.com/containers/storage/pkg/stringid"
@@ -77,6 +78,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
Expect(session).Should(Exit(0))
defer podmanTest.removeNetwork(netName)
+ gw := podmanTest.Podman([]string{"network", "inspect", netName, "--format", "{{(index .Subnets 0).Gateway}}"})
+ gw.WaitWithDefaultTimeout()
+ Expect(gw).Should(Exit(0))
+ ns := gw.OutputToString()
+
ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, ALPINE, "top"})
ctr.WaitWithDefaultTimeout()
Expect(ctr).Should(Exit(0))
@@ -85,6 +91,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
exec.WaitWithDefaultTimeout()
Expect(exec).Should(Exit(0))
+ exec2 := podmanTest.Podman([]string{"exec", "-it", "test", "cat", "/etc/resolv.conf"})
+ exec2.WaitWithDefaultTimeout()
+ Expect(exec2).Should(Exit(0))
+ Expect(strings.Contains(exec2.OutputToString(), ns)).To(BeTrue())
+
dis := podmanTest.Podman([]string{"network", "disconnect", netName, "test"})
dis.WaitWithDefaultTimeout()
Expect(dis).Should(Exit(0))
@@ -98,6 +109,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
exec.WaitWithDefaultTimeout()
Expect(exec).Should(ExitWithError())
+
+ exec3 := podmanTest.Podman([]string{"exec", "-it", "test", "cat", "/etc/resolv.conf"})
+ exec3.WaitWithDefaultTimeout()
+ Expect(exec3).Should(Exit(0))
+ Expect(strings.Contains(exec3.OutputToString(), ns)).To(BeFalse())
})
It("bad network name in connect should result in error", func() {
@@ -182,6 +198,16 @@ var _ = Describe("Podman network connect and disconnect", func() {
Expect(session).Should(Exit(0))
defer podmanTest.removeNetwork(newNetName)
+ gw := podmanTest.Podman([]string{"network", "inspect", newNetName, "--format", "{{(index .Subnets 0).Gateway}}"})
+ gw.WaitWithDefaultTimeout()
+ Expect(gw).Should(Exit(0))
+ ns := gw.OutputToString()
+
+ exec2 := podmanTest.Podman([]string{"exec", "-it", "test", "cat", "/etc/resolv.conf"})
+ exec2.WaitWithDefaultTimeout()
+ Expect(exec2).Should(Exit(0))
+ Expect(strings.Contains(exec2.OutputToString(), ns)).To(BeFalse())
+
ip := "10.11.100.99"
mac := "44:11:44:11:44:11"
connect := podmanTest.Podman([]string{"network", "connect", "--ip", ip, "--mac-address", mac, newNetName, "test"})
@@ -206,6 +232,11 @@ var _ = Describe("Podman network connect and disconnect", func() {
Expect(exec.OutputToString()).Should(ContainSubstring(ip))
Expect(exec.OutputToString()).Should(ContainSubstring(mac))
+ exec3 := podmanTest.Podman([]string{"exec", "-it", "test", "cat", "/etc/resolv.conf"})
+ exec3.WaitWithDefaultTimeout()
+ Expect(exec3).Should(Exit(0))
+ Expect(strings.Contains(exec3.OutputToString(), ns)).To(BeTrue())
+
// make sure no logrus errors are shown https://github.com/containers/podman/issues/9602
rm := podmanTest.Podman([]string{"rm", "--time=0", "-f", "test"})
rm.WaitWithDefaultTimeout()
diff --git a/vendor/github.com/containers/common/libimage/copier.go b/vendor/github.com/containers/common/libimage/copier.go
index 459989579..2a8f47f7f 100644
--- a/vendor/github.com/containers/common/libimage/copier.go
+++ b/vendor/github.com/containers/common/libimage/copier.go
@@ -7,6 +7,7 @@ import (
"strings"
"time"
+ "github.com/containers/common/libimage/manifests"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/retry"
"github.com/containers/image/v5/copy"
@@ -26,8 +27,10 @@ const (
)
// LookupReferenceFunc return an image reference based on the specified one.
-// This can be used to pass custom blob caches to the copy operation.
-type LookupReferenceFunc func(ref types.ImageReference) (types.ImageReference, error)
+// The returned reference can return custom ImageSource or ImageDestination
+// objects which intercept or filter blobs, manifests, and signatures as
+// they are read and written.
+type LookupReferenceFunc = manifests.LookupReferenceFunc
// CopyOptions allow for customizing image-copy operations.
type CopyOptions struct {
diff --git a/vendor/github.com/containers/common/libimage/manifests/manifests.go b/vendor/github.com/containers/common/libimage/manifests/manifests.go
index 45223cc2f..ccff908c9 100644
--- a/vendor/github.com/containers/common/libimage/manifests/manifests.go
+++ b/vendor/github.com/containers/common/libimage/manifests/manifests.go
@@ -27,6 +27,12 @@ import (
const instancesData = "instances.json"
+// LookupReferenceFunc return an image reference based on the specified one.
+// The returned reference can return custom ImageSource or ImageDestination
+// objects which intercept or filter blobs, manifests, and signatures as
+// they are read and written.
+type LookupReferenceFunc func(ref types.ImageReference) (types.ImageReference, error)
+
// ErrListImageUnknown is returned when we attempt to create an image reference
// for a List that has not yet been saved to an image.
var ErrListImageUnknown = stderrors.New("unable to determine which image holds the manifest list")
@@ -57,6 +63,7 @@ type PushOptions struct {
SignBy string // fingerprint of GPG key to use to sign images
RemoveSignatures bool // true to discard signatures in images
ManifestType string // the format to use when saving the list - possible options are oci, v2s1, and v2s2
+ SourceFilter LookupReferenceFunc // filter the list source
}
// Create creates a new list containing information about the specified image,
@@ -221,6 +228,11 @@ func (l *list) Push(ctx context.Context, dest types.ImageReference, options Push
if err != nil {
return nil, "", err
}
+ if options.SourceFilter != nil {
+ if src, err = options.SourceFilter(src); err != nil {
+ return nil, "", err
+ }
+ }
copyOptions := &cp.Options{
ImageListSelection: options.ImageListSelection,
Instances: options.Instances,
diff --git a/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go b/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go
index dedb40ad3..5574b2b1c 100644
--- a/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go
+++ b/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go
@@ -222,14 +222,33 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ
err error
)
if len(network.Subnets) > 0 {
+ defIpv4Route := false
+ defIpv6Route := false
for _, subnet := range network.Subnets {
- route, err := newIPAMDefaultRoute(util.IsIPv6(subnet.Subnet.IP))
- if err != nil {
- return nil, "", err
- }
- routes = append(routes, route)
ipam := newIPAMLocalHostRange(subnet.Subnet, subnet.LeaseRange, subnet.Gateway)
ipamRanges = append(ipamRanges, []ipamLocalHostRangeConf{*ipam})
+
+ // only add default route for not internal networks
+ if !network.Internal {
+ ipv6 := util.IsIPv6(subnet.Subnet.IP)
+ if !ipv6 && defIpv4Route {
+ continue
+ }
+ if ipv6 && defIpv6Route {
+ continue
+ }
+
+ if ipv6 {
+ defIpv6Route = true
+ } else {
+ defIpv4Route = true
+ }
+ route, err := newIPAMDefaultRoute(ipv6)
+ if err != nil {
+ return nil, "", err
+ }
+ routes = append(routes, route)
+ }
}
ipamConf = newIPAMHostLocalConf(routes, ipamRanges)
} else {
diff --git a/vendor/github.com/containers/common/libnetwork/cni/config.go b/vendor/github.com/containers/common/libnetwork/cni/config.go
index b0aa19d94..b1f89400c 100644
--- a/vendor/github.com/containers/common/libnetwork/cni/config.go
+++ b/vendor/github.com/containers/common/libnetwork/cni/config.go
@@ -82,7 +82,7 @@ func (n *cniNetwork) networkCreate(newNetwork *types.Network, defaultNet bool) (
return nil, errors.Wrapf(types.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver)
}
- err = internalutil.ValidateSubnets(newNetwork, usedNetworks)
+ err = internalutil.ValidateSubnets(newNetwork, !newNetwork.Internal, usedNetworks)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/common/libnetwork/internal/util/validate.go b/vendor/github.com/containers/common/libnetwork/internal/util/validate.go
index bfc5e2247..ac3934f8d 100644
--- a/vendor/github.com/containers/common/libnetwork/internal/util/validate.go
+++ b/vendor/github.com/containers/common/libnetwork/internal/util/validate.go
@@ -65,11 +65,11 @@ func ValidateSubnet(s *types.Subnet, addGateway bool, usedNetworks []*net.IPNet)
}
// ValidateSubnets will validate the subnets for this network.
-// It also sets the gateway if the gateway is empty and it sets
+// It also sets the gateway if the gateway is empty and addGateway is set to true
// IPv6Enabled to true if at least one subnet is ipv6.
-func ValidateSubnets(network *types.Network, usedNetworks []*net.IPNet) error {
+func ValidateSubnets(network *types.Network, addGateway bool, usedNetworks []*net.IPNet) error {
for i := range network.Subnets {
- err := ValidateSubnet(&network.Subnets[i], !network.Internal, usedNetworks)
+ err := ValidateSubnet(&network.Subnets[i], addGateway, usedNetworks)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/common/libnetwork/netavark/config.go b/vendor/github.com/containers/common/libnetwork/netavark/config.go
index 7de59f807..16b4e5c53 100644
--- a/vendor/github.com/containers/common/libnetwork/netavark/config.go
+++ b/vendor/github.com/containers/common/libnetwork/netavark/config.go
@@ -115,16 +115,13 @@ func (n *netavarkNetwork) networkCreate(newNetwork *types.Network, defaultNet bo
return nil, errors.Wrapf(types.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver)
}
- err = internalutil.ValidateSubnets(newNetwork, usedNetworks)
+ // add gatway when not internal or dns enabled
+ addGateway := !newNetwork.Internal || newNetwork.DNSEnabled
+ err = internalutil.ValidateSubnets(newNetwork, addGateway, usedNetworks)
if err != nil {
return nil, err
}
- // FIXME: If we have a working solution for internal networks with dns this check should be removed.
- if newNetwork.DNSEnabled && newNetwork.Internal {
- return nil, errors.New("cannot set internal and dns enabled")
- }
-
newNetwork.Created = time.Now()
if !defaultNet {
diff --git a/vendor/github.com/containers/common/libnetwork/netavark/network.go b/vendor/github.com/containers/common/libnetwork/netavark/network.go
index 7122acf98..efea36fec 100644
--- a/vendor/github.com/containers/common/libnetwork/netavark/network.go
+++ b/vendor/github.com/containers/common/libnetwork/netavark/network.go
@@ -231,7 +231,9 @@ func parseNetwork(network *types.Network) error {
return errors.Errorf("invalid network ID %q", network.ID)
}
- return util.ValidateSubnets(network, nil)
+ // add gatway when not internal or dns enabled
+ addGateway := !network.Internal || network.DNSEnabled
+ return util.ValidateSubnets(network, addGateway, nil)
}
func (n *netavarkNetwork) createDefaultNetwork() (*types.Network, error) {
diff --git a/vendor/github.com/containers/common/pkg/auth/auth.go b/vendor/github.com/containers/common/pkg/auth/auth.go
index ff52b028e..af3c8f803 100644
--- a/vendor/github.com/containers/common/pkg/auth/auth.go
+++ b/vendor/github.com/containers/common/pkg/auth/auth.go
@@ -248,7 +248,7 @@ func getUserAndPass(opts *LoginOptions, password, userFromAuthFile string) (user
}
if password == "" {
fmt.Fprint(opts.Stdout, "Password: ")
- pass, err := terminal.ReadPassword(0)
+ pass, err := terminal.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
return "", "", errors.Wrap(err, "reading password")
}
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index 5ab8cd7f2..eac64b077 100644
--- a/vendor/github.com/containers/common/version/version.go
+++ b/vendor/github.com/containers/common/version/version.go
@@ -1,4 +1,4 @@
package version
// Version is the version of the build.
-const Version = "0.47.3"
+const Version = "0.47.4"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 909c2707e..9260511f5 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -109,7 +109,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
-# github.com/containers/common v0.47.3
+# github.com/containers/common v0.47.4
## explicit
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests