network db: add new strucutre to container create

Make sure we create new containers in the db with the correct structure.
Also remove some unneeded code for alias handling. We no longer need this
functions.

The specgen format has not been changed for now.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2021-12-07 23:04:47 +01:00
parent 4e8ad039ce
commit 9ce6b64133
12 changed files with 131 additions and 321 deletions

View File

@ -1063,7 +1063,7 @@ func (s *BoltState) GetNetworks(ctr *Container) (map[string]types.PerNetworkOpti
return errors.Wrapf(err, "error creating networks bucket for container %s", ctr.ID()) return errors.Wrapf(err, "error creating networks bucket for container %s", ctr.ID())
} }
// the container has no networks in the db lookup config and write to the db // the container has no networks in the db lookup config and write to the db
networkList = ctr.config.Networks networkList = ctr.config.NetworksDeprecated
// if there are no networks we have to add the default // if there are no networks we have to add the default
if len(networkList) == 0 { if len(networkList) == 0 {
networkList = []string{ctr.runtime.config.Network.DefaultNetwork} networkList = []string{ctr.runtime.config.Network.DefaultNetwork}
@ -1146,155 +1146,6 @@ func (s *BoltState) GetNetworks(ctr *Container) (map[string]types.PerNetworkOpti
return networks, nil return networks, nil
} }
// GetNetworkAliases retrieves the network aliases for the given container in
// the given CNI network.
func (s *BoltState) GetNetworkAliases(ctr *Container, network string) ([]string, error) {
if !s.valid {
return nil, define.ErrDBClosed
}
if !ctr.valid {
return nil, define.ErrCtrRemoved
}
if network == "" {
return nil, errors.Wrapf(define.ErrInvalidArg, "network names must not be empty")
}
if s.namespace != "" && s.namespace != ctr.config.Namespace {
return nil, errors.Wrapf(define.ErrNSMismatch, "container %s is in namespace %q, does not match our namespace %q", ctr.ID(), ctr.config.Namespace, s.namespace)
}
ctrID := []byte(ctr.ID())
db, err := s.getDBCon()
if err != nil {
return nil, err
}
defer s.deferredCloseDBCon(db)
aliases := []string{}
err = db.View(func(tx *bolt.Tx) error {
ctrBucket, err := getCtrBucket(tx)
if err != nil {
return err
}
dbCtr := ctrBucket.Bucket(ctrID)
if dbCtr == nil {
ctr.valid = false
return errors.Wrapf(define.ErrNoSuchCtr, "container %s does not exist in database", ctr.ID())
}
ctrNetworkBkt := dbCtr.Bucket(networksBkt)
if ctrNetworkBkt == nil {
// No networks joined, so no aliases
return nil
}
inNetwork := ctrNetworkBkt.Get([]byte(network))
if inNetwork == nil {
return errors.Wrapf(define.ErrNoAliases, "container %s is not part of network %s, no aliases found", ctr.ID(), network)
}
ctrAliasesBkt := dbCtr.Bucket(aliasesBkt)
if ctrAliasesBkt == nil {
// No aliases
return nil
}
netAliasesBkt := ctrAliasesBkt.Bucket([]byte(network))
if netAliasesBkt == nil {
// No aliases for this specific network.
return nil
}
return netAliasesBkt.ForEach(func(alias, v []byte) error {
aliases = append(aliases, string(alias))
return nil
})
})
if err != nil {
return nil, err
}
return aliases, nil
}
// GetAllNetworkAliases retrieves the network aliases for the given container in
// all CNI networks.
func (s *BoltState) GetAllNetworkAliases(ctr *Container) (map[string][]string, error) {
if !s.valid {
return nil, define.ErrDBClosed
}
if !ctr.valid {
return nil, define.ErrCtrRemoved
}
if s.namespace != "" && s.namespace != ctr.config.Namespace {
return nil, errors.Wrapf(define.ErrNSMismatch, "container %s is in namespace %q, does not match our namespace %q", ctr.ID(), ctr.config.Namespace, s.namespace)
}
ctrID := []byte(ctr.ID())
db, err := s.getDBCon()
if err != nil {
return nil, err
}
defer s.deferredCloseDBCon(db)
aliases := make(map[string][]string)
err = db.View(func(tx *bolt.Tx) error {
ctrBucket, err := getCtrBucket(tx)
if err != nil {
return err
}
dbCtr := ctrBucket.Bucket(ctrID)
if dbCtr == nil {
ctr.valid = false
return errors.Wrapf(define.ErrNoSuchCtr, "container %s does not exist in database", ctr.ID())
}
ctrAliasesBkt := dbCtr.Bucket(aliasesBkt)
if ctrAliasesBkt == nil {
// No aliases present
return nil
}
ctrNetworkBkt := dbCtr.Bucket(networksBkt)
if ctrNetworkBkt == nil {
// No networks joined, so no aliases
return nil
}
return ctrNetworkBkt.ForEach(func(network, v []byte) error {
netAliasesBkt := ctrAliasesBkt.Bucket(network)
if netAliasesBkt == nil {
return nil
}
netAliases := []string{}
_ = netAliasesBkt.ForEach(func(alias, v []byte) error {
netAliases = append(netAliases, string(alias))
return nil
})
aliases[string(network)] = netAliases
return nil
})
})
if err != nil {
return nil, err
}
return aliases, nil
}
// NetworkConnect adds the given container to the given network. If aliases are // NetworkConnect adds the given container to the given network. If aliases are
// specified, those will be added to the given network. // specified, those will be added to the given network.
func (s *BoltState) NetworkConnect(ctr *Container, network string, opts types.PerNetworkOptions) error { func (s *BoltState) NetworkConnect(ctr *Container, network string, opts types.PerNetworkOptions) error {

View File

@ -563,6 +563,28 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
ctrNamespace = []byte(ctr.config.Namespace) ctrNamespace = []byte(ctr.config.Namespace)
} }
// make sure to marshal the network options before we get the db lock
networks := make(map[string][]byte, len(ctr.config.Networks))
for net, opts := range ctr.config.Networks {
// Check that we don't have any empty network names
if net == "" {
return errors.Wrapf(define.ErrInvalidArg, "network names cannot be an empty string")
}
if opts.InterfaceName == "" {
return errors.Wrapf(define.ErrInvalidArg, "network interface name cannot be an empty string")
}
// always add the short id as alias for docker compat
opts.Aliases = append(opts.Aliases, ctr.config.ID[:12])
optBytes, err := json.Marshal(opts)
if err != nil {
return errors.Wrapf(err, "error marshalling network options JSON for container %s", ctr.ID())
}
networks[net] = optBytes
}
// Set the original value to nil. We can safe some space by not storing it in the config
// since we store it in a different mutable bucket anyway.
ctr.config.Networks = nil
db, err := s.getDBCon() db, err := s.getDBCon()
if err != nil { if err != nil {
return err return err
@ -646,23 +668,6 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
return errors.Wrapf(err, "name \"%s\" is in use", ctr.Name()) return errors.Wrapf(err, "name \"%s\" is in use", ctr.Name())
} }
allNets := make(map[string]bool)
// Check that we don't have any empty network names
for _, net := range ctr.config.Networks {
if net == "" {
return errors.Wrapf(define.ErrInvalidArg, "network names cannot be an empty string")
}
allNets[net] = true
}
// Each network we have aliases for, must exist in networks
for net := range ctr.config.NetworkAliases {
if !allNets[net] {
return errors.Wrapf(define.ErrNoSuchNetwork, "container %s has network aliases for network %q but is not part of that network", ctr.ID(), net)
}
}
// No overlapping containers // No overlapping containers
// Add the new container to the DB // Add the new container to the DB
if err := idsBucket.Put(ctrID, ctrName); err != nil { if err := idsBucket.Put(ctrID, ctrName); err != nil {
@ -706,34 +711,17 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
return errors.Wrapf(err, "error adding container %s netns path to DB", ctr.ID()) return errors.Wrapf(err, "error adding container %s netns path to DB", ctr.ID())
} }
} }
if ctr.config.Networks != nil { if len(networks) > 0 {
ctrNetworksBkt, err := newCtrBkt.CreateBucket(networksBkt) ctrNetworksBkt, err := newCtrBkt.CreateBucket(networksBkt)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating networks bucket for container %s", ctr.ID()) return errors.Wrapf(err, "error creating networks bucket for container %s", ctr.ID())
} }
for _, network := range ctr.config.Networks { for network, opts := range networks {
if err := ctrNetworksBkt.Put([]byte(network), ctrID); err != nil { if err := ctrNetworksBkt.Put([]byte(network), opts); err != nil {
return errors.Wrapf(err, "error adding network %q to networks bucket for container %s", network, ctr.ID()) return errors.Wrapf(err, "error adding network %q to networks bucket for container %s", network, ctr.ID())
} }
} }
} }
if ctr.config.NetworkAliases != nil {
ctrAliasesBkt, err := newCtrBkt.CreateBucket(aliasesBkt)
if err != nil {
return errors.Wrapf(err, "error creating network aliases bucket for container %s", ctr.ID())
}
for net, aliases := range ctr.config.NetworkAliases {
netAliasesBkt, err := ctrAliasesBkt.CreateBucket([]byte(net))
if err != nil {
return errors.Wrapf(err, "error creating network aliases bucket for network %q in container %s", net, ctr.ID())
}
for _, alias := range aliases {
if err := netAliasesBkt.Put([]byte(alias), ctrID); err != nil {
return errors.Wrapf(err, "error creating network alias %q in network %q for container %s", alias, net, ctr.ID())
}
}
}
}
if _, err := newCtrBkt.CreateBucket(dependenciesBkt); err != nil { if _, err := newCtrBkt.CreateBucket(dependenciesBkt); err != nil {
return errors.Wrapf(err, "error creating dependencies bucket for container %s", ctr.ID()) return errors.Wrapf(err, "error creating dependencies bucket for container %s", ctr.ID())

View File

@ -229,10 +229,12 @@ type ContainerNetworkConfig struct {
// StaticIP is a static IP to request for the container. // StaticIP is a static IP to request for the container.
// This cannot be set unless CreateNetNS is set. // This cannot be set unless CreateNetNS is set.
// If not set, the container will be dynamically assigned an IP by CNI. // If not set, the container will be dynamically assigned an IP by CNI.
// Deprecated: Do no use this anymore, this is only for DB backwards compat.
StaticIP net.IP `json:"staticIP"` StaticIP net.IP `json:"staticIP"`
// StaticMAC is a static MAC to request for the container. // StaticMAC is a static MAC to request for the container.
// This cannot be set unless CreateNetNS is set. // This cannot be set unless CreateNetNS is set.
// If not set, the container will be dynamically assigned a MAC by CNI. // If not set, the container will be dynamically assigned a MAC by CNI.
// Deprecated: Do no use this anymore, this is only for DB backwards compat.
StaticMAC types.HardwareAddr `json:"staticMAC"` StaticMAC types.HardwareAddr `json:"staticMAC"`
// PortMappings are the ports forwarded to the container's network // PortMappings are the ports forwarded to the container's network
// namespace // namespace
@ -269,24 +271,24 @@ type ContainerNetworkConfig struct {
// Hosts to add in container // Hosts to add in container
// Will be appended to host's host file // Will be appended to host's host file
HostAdd []string `json:"hostsAdd,omitempty"` HostAdd []string `json:"hostsAdd,omitempty"`
// Network names (CNI) to add container to. Empty to use default network. // Network names with the network specific options.
// Please note that these can be altered at runtime. The actual list is
// stored in the DB and should be retrieved from there via c.networks()
// this value is only used for container create.
// Added in podman 4.0, previously NetworksDeprecated was used. Make
// sure to not change the json tags.
Networks map[string]types.PerNetworkOptions `json:"newNetworks,omitempty"`
// Network names to add container to. Empty to use default network.
// Please note that these can be altered at runtime. The actual list is // Please note that these can be altered at runtime. The actual list is
// stored in the DB and should be retrieved from there; this is only the // stored in the DB and should be retrieved from there; this is only the
// set of networks the container was *created* with. // set of networks the container was *created* with.
Networks []string `json:"networks,omitempty"` // Deprecated: Do no use this anymore, this is only for DB backwards compat.
// Also note that we need to keep the old json tag to decode from DB correctly
NetworksDeprecated []string `json:"networks,omitempty"`
// Network mode specified for the default network. // Network mode specified for the default network.
NetMode namespaces.NetworkMode `json:"networkMode,omitempty"` NetMode namespaces.NetworkMode `json:"networkMode,omitempty"`
// NetworkOptions are additional options for each network // NetworkOptions are additional options for each network
NetworkOptions map[string][]string `json:"network_options,omitempty"` NetworkOptions map[string][]string `json:"network_options,omitempty"`
// NetworkAliases are aliases that will be added to each network.
// These are additional names that this container can be accessed as via
// DNS when the CNI dnsname plugin is in use.
// Please note that these can be altered at runtime. As such, the actual
// list is stored in the database and should be retrieved from there;
// this is only the set of aliases the container was *created with*.
// Formatted as map of network name to aliases. All network names must
// be present in the Networks list above.
NetworkAliases map[string][]string `json:"network_alises,omitempty"`
} }
// ContainerImageConfig is an embedded sub-config providing image configuration // ContainerImageConfig is an embedded sub-config providing image configuration

View File

@ -74,7 +74,7 @@ func (c *Container) validate() error {
// Cannot set static IP or MAC if joining >1 CNI network. // Cannot set static IP or MAC if joining >1 CNI network.
if len(c.config.Networks) > 1 && (c.config.StaticIP != nil || c.config.StaticMAC != nil) { if len(c.config.Networks) > 1 && (c.config.StaticIP != nil || c.config.StaticMAC != nil) {
return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP or MAC address if joining more than one CNI network") return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP or MAC address if joining more than one network")
} }
// Using image resolv.conf conflicts with various DNS settings. // Using image resolv.conf conflicts with various DNS settings.
@ -115,17 +115,6 @@ func (c *Container) validate() error {
destinations[vol.Dest] = true destinations[vol.Dest] = true
} }
// Check that networks and network aliases match up.
ctrNets := make(map[string]bool)
for _, net := range c.config.Networks {
ctrNets[net] = true
}
for net := range c.config.NetworkAliases {
if _, ok := ctrNets[net]; !ok {
return errors.Wrapf(define.ErrNoSuchNetwork, "container tried to set network aliases for network %s but is not connected to the network", net)
}
}
// If User in the OCI spec is set, require that c.config.User is set for // If User in the OCI spec is set, require that c.config.User is set for
// security reasons (a lot of our code relies on c.config.User). // security reasons (a lot of our code relies on c.config.User).
if c.config.User == "" && (c.config.Spec.Process.User.UID != 0 || c.config.Spec.Process.User.GID != 0) { if c.config.User == "" && (c.config.Spec.Process.User.UID != 0 || c.config.Spec.Process.User.GID != 0) {

View File

@ -204,7 +204,8 @@ type PerNetworkOptions struct {
Aliases []string `json:"aliases,omitempty"` Aliases []string `json:"aliases,omitempty"`
// StaticMac for this container. Optional. // StaticMac for this container. Optional.
StaticMAC HardwareAddr `json:"static_mac,omitempty"` StaticMAC HardwareAddr `json:"static_mac,omitempty"`
// InterfaceName for this container. Required. // InterfaceName for this container. Required in the backend.
// Optional in the frontend. Will be filled with ethX (where X is a integer) when empty.
InterfaceName string `json:"interface_name"` InterfaceName string `json:"interface_name"`
} }

View File

@ -1058,7 +1058,7 @@ func WithDependencyCtrs(ctrs []*Container) CtrCreateOption {
// namespace with a minimal configuration. // namespace with a minimal configuration.
// An optional array of port mappings can be provided. // An optional array of port mappings can be provided.
// Conflicts with WithNetNSFrom(). // Conflicts with WithNetNSFrom().
func WithNetNS(portMappings []nettypes.PortMapping, exposedPorts map[uint16][]string, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption { func WithNetNS(portMappings []nettypes.PortMapping, exposedPorts map[uint16][]string, postConfigureNetNS bool, netmode string, networks map[string]nettypes.PerNetworkOptions) CtrCreateOption {
return func(ctr *Container) error { return func(ctr *Container) error {
if ctr.valid { if ctr.valid {
return define.ErrCtrFinalized return define.ErrCtrFinalized
@ -1076,23 +1076,6 @@ func WithNetNS(portMappings []nettypes.PortMapping, exposedPorts map[uint16][]st
} }
} }
// WithStaticIP indicates that the container should request a static IP from
// the CNI plugins.
// It cannot be set unless WithNetNS has already been passed.
// Further, it cannot be set if additional CNI networks to join have been
// specified.
func WithStaticIP(ip net.IP) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}
ctr.config.StaticIP = ip
return nil
}
}
// WithNetworkOptions sets additional options for the networks. // WithNetworkOptions sets additional options for the networks.
func WithNetworkOptions(options map[string][]string) CtrCreateOption { func WithNetworkOptions(options map[string][]string) CtrCreateOption {
return func(ctr *Container) error { return func(ctr *Container) error {
@ -1106,23 +1089,6 @@ func WithNetworkOptions(options map[string][]string) CtrCreateOption {
} }
} }
// WithStaticMAC indicates that the container should request a static MAC from
// the CNI plugins.
// It cannot be set unless WithNetNS has already been passed.
// Further, it cannot be set if additional CNI networks to join have been
// specified.
func WithStaticMAC(mac nettypes.HardwareAddr) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}
ctr.config.StaticMAC = mac
return nil
}
}
// WithLogDriver sets the log driver for the container // WithLogDriver sets the log driver for the container
func WithLogDriver(driver string) CtrCreateOption { func WithLogDriver(driver string) CtrCreateOption {
return func(ctr *Container) error { return func(ctr *Container) error {
@ -1572,20 +1538,6 @@ func WithCreateWorkingDir() CtrCreateOption {
} }
} }
// WithNetworkAliases sets network aliases for the container.
// Accepts a map of network name to aliases.
func WithNetworkAliases(aliases map[string][]string) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}
ctr.config.NetworkAliases = aliases
return nil
}
}
// Volume Creation Options // Volume Creation Options
// WithVolumeName sets the name of the volume. // WithVolumeName sets the name of the volume.

View File

@ -637,9 +637,17 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
infraConfig.HostAdd = make([]string, 0, len(infra.config.HostAdd)) infraConfig.HostAdd = make([]string, 0, len(infra.config.HostAdd))
infraConfig.HostAdd = append(infraConfig.HostAdd, infra.config.HostAdd...) infraConfig.HostAdd = append(infraConfig.HostAdd, infra.config.HostAdd...)
} }
if len(infra.config.ContainerNetworkConfig.Networks) > 0 {
infraConfig.Networks = make([]string, 0, len(infra.config.ContainerNetworkConfig.Networks)) networks, err := infra.networks()
infraConfig.Networks = append(infraConfig.Networks, infra.config.ContainerNetworkConfig.Networks...) if err != nil {
return nil, err
}
netNames := make([]string, 0, len(networks))
for name := range networks {
netNames = append(netNames, name)
}
if len(netNames) > 0 {
infraConfig.Networks = netNames
} }
infraConfig.NetworkOptions = infra.config.ContainerNetworkConfig.NetworkOptions infraConfig.NetworkOptions = infra.config.ContainerNetworkConfig.NetworkOptions
infraConfig.PortBindings = makeInspectPortBindings(infra.config.ContainerNetworkConfig.PortMappings, nil) infraConfig.PortBindings = makeInspectPortBindings(infra.config.ContainerNetworkConfig.PortMappings, nil)

View File

@ -2,6 +2,7 @@ package libpod
import ( import (
"context" "context"
"fmt"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -13,10 +14,12 @@ import (
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/libpod/shutdown" "github.com/containers/podman/v3/libpod/shutdown"
"github.com/containers/podman/v3/pkg/domain/entities/reports" "github.com/containers/podman/v3/pkg/domain/entities/reports"
"github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
"github.com/docker/go-units" "github.com/docker/go-units"
@ -230,39 +233,56 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Container, retErr error) { func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Container, retErr error) {
// normalize the networks to names // normalize the networks to names
// ocicni only knows about cni names so we have to make // the db backend only knows about network names so we have to make
// sure we do not use ids internally // sure we do not use ids internally
if len(ctr.config.Networks) > 0 { if len(ctr.config.Networks) > 0 {
netNames := make([]string, 0, len(ctr.config.Networks)) normalizeNetworks := make(map[string]types.PerNetworkOptions, len(ctr.config.Networks))
for _, nameOrID := range ctr.config.Networks { // first get the already used interface names so we do not conflict
usedIfNames := make([]string, 0, len(ctr.config.Networks))
for _, opts := range ctr.config.Networks {
if opts.InterfaceName != "" {
// check that no name is assigned to more than network
if util.StringInSlice(opts.InterfaceName, usedIfNames) {
return nil, errors.Errorf("network interface name %q is already assigned to another network", opts.InterfaceName)
}
usedIfNames = append(usedIfNames, opts.InterfaceName)
}
}
i := 0
for nameOrID, opts := range ctr.config.Networks {
netName, err := r.normalizeNetworkName(nameOrID) netName, err := r.normalizeNetworkName(nameOrID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
netNames = append(netNames, netName) if len(opts.Aliases) > 0 {
} network, err := r.network.NetworkInspect(netName)
ctr.config.Networks = netNames if err != nil {
} return nil, err
}
if !network.DNSEnabled {
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set network aliases for network %q because dns is disabled", netName)
}
}
// assign interface name if empty
if opts.InterfaceName == "" {
for i < 100000 {
ifName := fmt.Sprintf("eth%d", i)
if !util.StringInSlice(ifName, usedIfNames) {
opts.InterfaceName = ifName
usedIfNames = append(usedIfNames, ifName)
break
}
i++
}
// if still empty we did not find a free name
if opts.InterfaceName == "" {
return nil, errors.New("failed to find free network interface name")
}
}
// https://github.com/containers/podman/issues/11285 normalizeNetworks[netName] = opts
// normalize the networks aliases to use network names and never ids
if len(ctr.config.NetworkAliases) > 0 {
netAliases := make(map[string][]string, len(ctr.config.NetworkAliases))
for nameOrID, aliases := range ctr.config.NetworkAliases {
netName, err := r.normalizeNetworkName(nameOrID)
if err != nil {
return nil, err
}
network, err := r.network.NetworkInspect(netName)
if err != nil {
return nil, err
}
if !network.DNSEnabled {
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set network aliases for network %q because dns is disabled", netName)
}
netAliases[netName] = aliases
} }
ctr.config.NetworkAliases = netAliases ctr.config.Networks = normalizeNetworks
} }
// Validate the container // Validate the container

View File

@ -102,12 +102,7 @@ type State interface {
// Get networks the container is currently connected to. // Get networks the container is currently connected to.
GetNetworks(ctr *Container) (map[string]types.PerNetworkOptions, error) GetNetworks(ctr *Container) (map[string]types.PerNetworkOptions, error)
// Get network aliases for the given container in the given network. // Add the container to the given network with the given options
GetNetworkAliases(ctr *Container, network string) ([]string, error)
// Get all network aliases for the given container.
GetAllNetworkAliases(ctr *Container) (map[string][]string, error)
// Add the container to the given network, adding the given aliases
// (if present).
NetworkConnect(ctr *Container, network string, opts types.PerNetworkOptions) error NetworkConnect(ctr *Container, network string, opts types.PerNetworkOptions) error
// Remove the container from the given network, removing all aliases for // Remove the container from the given network, removing all aliases for
// the container in that network in the process. // the container in that network in the process.

View File

@ -1299,21 +1299,9 @@ func TestAddContainerEmptyNetworkNameErrors(t *testing.T) {
testCtr, err := getTestCtr1(manager) testCtr, err := getTestCtr1(manager)
assert.NoError(t, err) assert.NoError(t, err)
testCtr.config.Networks = []string{""} testCtr.config.Networks = map[string]types.PerNetworkOptions{
"": {},
err = state.AddContainer(testCtr) }
assert.Error(t, err)
})
}
func TestAddContainerNetworkAliasesButNoMatchingNetwork(t *testing.T) {
runForAllStates(t, func(t *testing.T, state State, manager lock.Manager) {
testCtr, err := getTestCtr1(manager)
assert.NoError(t, err)
testCtr.config.Networks = []string{"test1"}
testCtr.config.NetworkAliases = make(map[string][]string)
testCtr.config.NetworkAliases["test2"] = []string{"alias1"}
err = state.AddContainer(testCtr) err = state.AddContainer(testCtr)
assert.Error(t, err) assert.Error(t, err)

View File

@ -160,10 +160,6 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
} }
options = append(options, opts...) options = append(options, opts...)
if len(s.Aliases) > 0 {
options = append(options, libpod.WithNetworkAliases(s.Aliases))
}
if containerType := s.InitContainerType; len(containerType) > 0 { if containerType := s.InitContainerType; len(containerType) > 0 {
options = append(options, libpod.WithInitCtrType(containerType)) options = append(options, libpod.WithInitCtrType(containerType))
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util" "github.com/containers/podman/v3/pkg/util"
@ -250,7 +251,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
if s.NetNS.Value != "" { if s.NetNS.Value != "" {
val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value) val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value)
} }
toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, s.CNINetworks)) toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil))
case specgen.Private: case specgen.Private:
fallthrough fallthrough
case specgen.Bridge: case specgen.Bridge:
@ -258,7 +259,32 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
if err != nil { if err != nil {
return nil, err return nil, err
} }
toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", s.CNINetworks)) if len(s.CNINetworks) == 0 {
rtConfig, err := rt.GetConfigNoCopy()
if err != nil {
return nil, err
}
s.CNINetworks = append(s.CNINetworks, rtConfig.Network.DefaultNetwork)
}
networks := make(map[string]types.PerNetworkOptions, len(s.CNINetworks))
for i, netName := range s.CNINetworks {
opts := types.PerNetworkOptions{}
opts.Aliases = s.Aliases[netName]
if i == 0 {
if s.StaticIP != nil {
opts.StaticIPs = append(opts.StaticIPs, *s.StaticIP)
}
if s.StaticIPv6 != nil {
opts.StaticIPs = append(opts.StaticIPs, *s.StaticIPv6)
}
if s.StaticMAC != nil {
opts.StaticMAC = *s.StaticMAC
}
}
networks[netName] = opts
}
toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", networks))
} }
if s.UseImageHosts { if s.UseImageHosts {
@ -281,12 +307,6 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
if len(s.DNSOptions) > 0 { if len(s.DNSOptions) > 0 {
toReturn = append(toReturn, libpod.WithDNSOption(s.DNSOptions)) toReturn = append(toReturn, libpod.WithDNSOption(s.DNSOptions))
} }
if s.StaticIP != nil {
toReturn = append(toReturn, libpod.WithStaticIP(*s.StaticIP))
}
if s.StaticMAC != nil {
toReturn = append(toReturn, libpod.WithStaticMAC(*s.StaticMAC))
}
if s.NetworkOptions != nil { if s.NetworkOptions != nil {
toReturn = append(toReturn, libpod.WithNetworkOptions(s.NetworkOptions)) toReturn = append(toReturn, libpod.WithNetworkOptions(s.NetworkOptions))
} }