summaryrefslogtreecommitdiff
path: root/libpod/container.go
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-08-16 16:11:26 +0200
committerPaul Holzinger <pholzing@redhat.com>2021-09-15 20:00:20 +0200
commit85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de (patch)
tree82b0c29102d2779c18ea8a6f10df5dc1139e3817 /libpod/container.go
parent218f132fdf4939d9e0374ef860d534f19e71df54 (diff)
downloadpodman-85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de.tar.gz
podman-85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de.tar.bz2
podman-85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de.zip
Wire network interface into libpod
Make use of the new network interface in libpod. This commit contains several breaking changes: - podman network create only outputs the new network name and not file path. - podman network ls shows the network driver instead of the cni version and plugins. - podman network inspect outputs the new network struct and not the cni conflist. - The bindings and libpod api endpoints have been changed to use the new network structure. The container network status is stored in a new field in the state. The status should be received with the new `c.getNetworkStatus`. This will migrate the old status to the new format. Therefore old containers should contine to work correctly in all cases even when network connect/ disconnect is used. New features: - podman network reload keeps the ip and mac for more than one network. - podman container restore keeps the ip and mac for more than one network. - The network create compat endpoint can now use more than one ipam config. The man pages and the swagger doc are updated to reflect the latest changes. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'libpod/container.go')
-rw-r--r--libpod/container.go127
1 files changed, 54 insertions, 73 deletions
diff --git a/libpod/container.go b/libpod/container.go
index a4bbb5dd0..28bf3da07 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -8,12 +8,13 @@ import (
"os"
"time"
- "github.com/containernetworking/cni/pkg/types"
cnitypes "github.com/containernetworking/cni/pkg/types/current"
"github.com/containers/common/pkg/secrets"
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/lock"
+ "github.com/containers/podman/v3/libpod/network/cni"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/storage"
"github.com/cri-o/ocicni/pkg/ocicni"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -114,14 +115,11 @@ type Container struct {
rootlessPortSyncR *os.File
rootlessPortSyncW *os.File
- // A restored container should have the same IP address as before
- // being checkpointed. If requestedIP is set it will be used instead
- // of config.StaticIP.
- requestedIP net.IP
- // A restored container should have the same MAC address as before
- // being checkpointed. If requestedMAC is set it will be used instead
- // of config.StaticMAC.
- requestedMAC net.HardwareAddr
+ // perNetworkOpts should be set when you want to use special network
+ // options when calling network setup/teardown. This should be used for
+ // container restore or network reload for example. Leave this nil if
+ // the settings from the container config should be used.
+ perNetworkOpts map[string]types.PerNetworkOptions
// This is true if a container is restored from a checkpoint.
restoreFromCheckpoint bool
@@ -173,11 +171,20 @@ type ContainerState struct {
// Podman.
// These are DEPRECATED and will be removed in a future release.
LegacyExecSessions map[string]*legacyExecSession `json:"execSessions,omitempty"`
- // NetworkStatus contains the configuration results for all networks
+ // NetworkStatusOld contains the configuration results for all networks
// the pod is attached to. Only populated if we created a network
// namespace for the container, and the network namespace is currently
- // active
- NetworkStatus []*cnitypes.Result `json:"networkResults,omitempty"`
+ // active.
+ // These are DEPRECATED and will be removed in a future release.
+ // This field is only used for backwarts compatibility.
+ NetworkStatusOld []*cnitypes.Result `json:"networkResults,omitempty"`
+ // NetworkStatus contains the network Status for all networks
+ // the container is attached to. Only populated if we created a network
+ // namespace for the container, and the network namespace is currently
+ // active.
+ // To read this field use container.getNetworkStatus() instead, this will
+ // take care of migrating the old DEPRECATED network status to the new format.
+ NetworkStatus map[string]types.StatusBlock `json:"networkStatus,omitempty"`
// BindMounts contains files that will be bind-mounted into the
// container when it is mounted.
// These include /etc/hosts and /etc/resolv.conf
@@ -788,66 +795,6 @@ func (c *Container) ExecSession(id string) (*ExecSession, error) {
return returnSession, nil
}
-// IPs retrieves a container's IP address(es)
-// This will only be populated if the container is configured to created a new
-// network namespace, and that namespace is presently active
-func (c *Container) IPs() ([]net.IPNet, error) {
- if !c.batched {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- if err := c.syncContainer(); err != nil {
- return nil, err
- }
- }
-
- if !c.config.CreateNetNS {
- return nil, errors.Wrapf(define.ErrInvalidArg, "container %s network namespace is not managed by libpod", c.ID())
- }
-
- ips := make([]net.IPNet, 0)
-
- for _, r := range c.state.NetworkStatus {
- for _, ip := range r.IPs {
- ips = append(ips, ip.Address)
- }
- }
-
- return ips, nil
-}
-
-// Routes retrieves a container's routes
-// This will only be populated if the container is configured to created a new
-// network namespace, and that namespace is presently active
-func (c *Container) Routes() ([]types.Route, error) {
- if !c.batched {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- if err := c.syncContainer(); err != nil {
- return nil, err
- }
- }
-
- if !c.config.CreateNetNS {
- return nil, errors.Wrapf(define.ErrInvalidArg, "container %s network namespace is not managed by libpod", c.ID())
- }
-
- routes := make([]types.Route, 0)
-
- for _, r := range c.state.NetworkStatus {
- for _, route := range r.Routes {
- newRoute := types.Route{
- Dst: route.Dst,
- GW: route.GW,
- }
- routes = append(routes, newRoute)
- }
- }
-
- return routes, nil
-}
-
// BindMounts retrieves bind mounts that were created by libpod and will be
// added to the container
// All these mounts except /dev/shm are ignored if a mount in the given spec has
@@ -1230,7 +1177,7 @@ func (c *Container) networks() ([]string, bool, error) {
networks, err := c.runtime.state.GetNetworks(c)
if err != nil && errors.Cause(err) == define.ErrNoSuchNetwork {
if len(c.config.Networks) == 0 && c.config.NetMode.IsBridge() {
- return []string{c.runtime.netPlugin.GetDefaultNetworkName()}, true, nil
+ return []string{c.runtime.config.Network.DefaultNetwork}, true, nil
}
return c.config.Networks, false, nil
}
@@ -1267,3 +1214,37 @@ func (d ContainerNetworkDescriptions) getInterfaceByName(networkName string) (st
}
return fmt.Sprintf("eth%d", val), exists
}
+
+// getNetworkStatus get the current network status from the state. If the container
+// still uses the old network status it is converted to the new format. This function
+// should be used instead of reading c.state.NetworkStatus directly.
+func (c *Container) getNetworkStatus() map[string]types.StatusBlock {
+ if c.state.NetworkStatus != nil {
+ return c.state.NetworkStatus
+ }
+ if c.state.NetworkStatusOld != nil {
+ // Note: NetworkStatusOld does not contain the network names so we get them extra
+ // Generally the order should be the same
+ networks, _, err := c.networks()
+ if err != nil {
+ return nil
+ }
+ if len(networks) != len(c.state.NetworkStatusOld) {
+ return nil
+ }
+ result := make(map[string]types.StatusBlock, len(c.state.NetworkStatusOld))
+ for i := range c.state.NetworkStatusOld {
+ status, err := cni.CNIResultToStatus(c.state.NetworkStatusOld[i])
+ if err != nil {
+ return nil
+ }
+ result[networks[i]] = status
+ }
+ c.state.NetworkStatus = result
+ _ = c.save()
+ // TODO remove debug for final version
+ logrus.Debugf("converted old network result to new result %v", result)
+ return result
+ }
+ return nil
+}