summaryrefslogtreecommitdiff
path: root/cmd/podman/common
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-12-10 15:22:09 +0100
committerPaul Holzinger <pholzing@redhat.com>2021-12-14 15:23:39 +0100
commit535818414c2a6bdcf6434e36c33775ea1a43f1cf (patch)
treebc7130eb922b7d2918527f13c3155506af4444f1 /cmd/podman/common
parentd072167fe2f75db9648bf1be4181b42e9b7db9a4 (diff)
downloadpodman-535818414c2a6bdcf6434e36c33775ea1a43f1cf.tar.gz
podman-535818414c2a6bdcf6434e36c33775ea1a43f1cf.tar.bz2
podman-535818414c2a6bdcf6434e36c33775ea1a43f1cf.zip
support advanced network configuration via cli
Rework the --network parse logic to support multiple networks with specific network configuration settings. --network can now be set multiple times. For bridge network mode the following options have been added: - **alias=name**: Add network-scoped alias for the container. - **ip=IPv4**: Specify a static ipv4 address for this container. - **ip=IPv6**: Specify a static ipv6 address for this container. - **mac=MAC**: Specify a static mac address address for this container. - **interface_name**: Specify a name for the created network interface inside the container. So now you can set --network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99 for the default bridge network as well as for network names. This is better than using --ip because we can set the ip per network without any confusion which network the ip address should be assigned to. The --ip, --mac-address and --network-alias options are still supported but --ip or --mac-address can only be set when only one network is set. This limitation already existed previously. The ability to specify a custom network interface name is new Fixes #11534 Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'cmd/podman/common')
-rw-r--r--cmd/podman/common/create_opts.go9
-rw-r--r--cmd/podman/common/netflags.go131
2 files changed, 76 insertions, 64 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 8f0cd1be6..990c1c063 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -156,18 +156,11 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
}
// netMode
- nsmode, networks, err := specgen.ParseNetworkNamespace(string(cc.HostConfig.NetworkMode), true)
+ nsmode, networks, netOpts, err := specgen.ParseNetworkFlag([]string{string(cc.HostConfig.NetworkMode)})
if err != nil {
return nil, nil, err
}
- var netOpts map[string][]string
- parts := strings.SplitN(string(cc.HostConfig.NetworkMode), ":", 2)
- if len(parts) > 1 {
- netOpts = make(map[string][]string)
- netOpts[parts[0]] = strings.Split(parts[1], ",")
- }
-
// network
// Note: we cannot emulate compat exactly here. we only allow specifics of networks to be
// defined when there is only one network.
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go
index f79a9fd88..ba8ab7a8b 100644
--- a/cmd/podman/common/netflags.go
+++ b/cmd/podman/common/netflags.go
@@ -61,8 +61,8 @@ func DefineNetFlags(cmd *cobra.Command) {
_ = cmd.RegisterFlagCompletionFunc(macAddressFlagName, completion.AutocompleteNone)
networkFlagName := "network"
- netFlags.String(
- networkFlagName, containerConfig.NetNS(),
+ netFlags.StringArray(
+ networkFlagName, nil,
"Connect a container to a network",
)
_ = cmd.RegisterFlagCompletionFunc(networkFlagName, AutocompleteNetworkFlag)
@@ -88,9 +88,7 @@ func DefineNetFlags(cmd *cobra.Command) {
}
// NetFlagsToNetOptions parses the network flags for the given cmd.
-// The netnsFromConfig bool is used to indicate if the --network flag
-// should always be parsed regardless if it was set on the cli.
-func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsFromConfig bool) (*entities.NetOptions, error) {
+func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet) (*entities.NetOptions, error) {
var (
err error
)
@@ -168,79 +166,100 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsF
return nil, err
}
- // parse the --network value only when the flag is set or we need to use
- // the netns config value, e.g. when --pod is not used
- if netnsFromConfig || flags.Changed("network") {
- network, err := flags.GetString("network")
+ // parse the network only when network was changed
+ // otherwise we send default to server so that the server
+ // can pick the correct default instead of the client
+ if flags.Changed("network") {
+ network, err := flags.GetStringArray("network")
if err != nil {
return nil, err
}
- ns, networks, options, err := specgen.ParseNetworkString(network)
+ ns, networks, options, err := specgen.ParseNetworkFlag(network)
if err != nil {
return nil, err
}
- if len(options) > 0 {
- opts.NetworkOptions = options
- }
+ opts.NetworkOptions = options
opts.Network = ns
opts.Networks = networks
}
- ip, err := flags.GetString("ip")
- if err != nil {
- return nil, err
- }
- if ip != "" {
- staticIP := net.ParseIP(ip)
- if staticIP == nil {
- return nil, errors.Errorf("%s is not an ip address", ip)
- }
- if !opts.Network.IsBridge() {
- return nil, errors.Wrap(define.ErrInvalidArg, "--ip can only be set when the network mode is bridge")
- }
- if len(opts.Networks) != 1 {
- return nil, errors.Wrap(define.ErrInvalidArg, "--ip can only be set for a single network")
- }
- for name, netOpts := range opts.Networks {
- netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
- opts.Networks[name] = netOpts
+ if flags.Changed("ip") || flags.Changed("mac-address") || flags.Changed("network-alias") {
+ // if there is no network we add the default
+ if len(opts.Networks) == 0 {
+ opts.Networks = map[string]types.PerNetworkOptions{
+ "default": {},
+ }
}
- }
- m, err := flags.GetString("mac-address")
- if err != nil {
- return nil, err
- }
- if len(m) > 0 {
- mac, err := net.ParseMAC(m)
+ ip, err := flags.GetString("ip")
if err != nil {
return nil, err
}
- if !opts.Network.IsBridge() {
- return nil, errors.Wrap(define.ErrInvalidArg, "--mac-address can only be set when the network mode is bridge")
+ if ip != "" {
+ // if pod create --infra=false
+ if infra, err := flags.GetBool("infra"); err == nil && !infra {
+ return nil, errors.Wrap(define.ErrInvalidArg, "cannot set --ip without infra container")
+ }
+
+ staticIP := net.ParseIP(ip)
+ if staticIP == nil {
+ return nil, errors.Errorf("%s is not an ip address", ip)
+ }
+ if !opts.Network.IsBridge() && !opts.Network.IsDefault() {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--ip can only be set when the network mode is bridge")
+ }
+ if len(opts.Networks) != 1 {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--ip can only be set for a single network")
+ }
+ for name, netOpts := range opts.Networks {
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
+ opts.Networks[name] = netOpts
+ }
}
- if len(opts.Networks) != 1 {
- return nil, errors.Wrap(define.ErrInvalidArg, "--mac-address can only be set for a single network")
+
+ m, err := flags.GetString("mac-address")
+ if err != nil {
+ return nil, err
}
- for name, netOpts := range opts.Networks {
- netOpts.StaticMAC = types.HardwareAddr(mac)
- opts.Networks[name] = netOpts
+ if len(m) > 0 {
+ // if pod create --infra=false
+ if infra, err := flags.GetBool("infra"); err == nil && !infra {
+ return nil, errors.Wrap(define.ErrInvalidArg, "cannot set --mac without infra container")
+ }
+ mac, err := net.ParseMAC(m)
+ if err != nil {
+ return nil, err
+ }
+ if !opts.Network.IsBridge() && !opts.Network.IsDefault() {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--mac-address can only be set when the network mode is bridge")
+ }
+ if len(opts.Networks) != 1 {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--mac-address can only be set for a single network")
+ }
+ for name, netOpts := range opts.Networks {
+ netOpts.StaticMAC = types.HardwareAddr(mac)
+ opts.Networks[name] = netOpts
+ }
}
- }
- aliases, err := flags.GetStringSlice("network-alias")
- if err != nil {
- return nil, err
- }
- if len(aliases) > 0 {
- if !opts.Network.IsBridge() {
- return nil, errors.Wrap(define.ErrInvalidArg, "--network-alias can only be set when the network mode is bridge")
+ aliases, err := flags.GetStringSlice("network-alias")
+ if err != nil {
+ return nil, err
}
- for name, netOpts := range opts.Networks {
- netOpts.Aliases = aliases
- opts.Networks[name] = netOpts
+ if len(aliases) > 0 {
+ // if pod create --infra=false
+ if infra, err := flags.GetBool("infra"); err == nil && !infra {
+ return nil, errors.Wrap(define.ErrInvalidArg, "cannot set --network-alias without infra container")
+ }
+ if !opts.Network.IsBridge() && !opts.Network.IsDefault() {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--network-alias can only be set when the network mode is bridge")
+ }
+ for name, netOpts := range opts.Networks {
+ netOpts.Aliases = aliases
+ opts.Networks[name] = netOpts
+ }
}
}