diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-08-16 16:11:26 +0200 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2021-09-15 20:00:20 +0200 |
commit | 85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de (patch) | |
tree | 82b0c29102d2779c18ea8a6f10df5dc1139e3817 /libpod/container.go | |
parent | 218f132fdf4939d9e0374ef860d534f19e71df54 (diff) | |
download | podman-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.go | 127 |
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 +} |