diff options
Diffstat (limited to 'cmd/podman/common/netflags.go')
-rw-r--r-- | cmd/podman/common/netflags.go | 144 |
1 files changed, 97 insertions, 47 deletions
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go index d11f3c9d2..425d85c9d 100644 --- a/cmd/podman/common/netflags.go +++ b/cmd/podman/common/netflags.go @@ -6,6 +6,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/podman/v3/cmd/podman/parse" "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/specgenutil" @@ -52,6 +53,13 @@ func DefineNetFlags(cmd *cobra.Command) { ) _ = cmd.RegisterFlagCompletionFunc(ipFlagName, completion.AutocompleteNone) + ip6FlagName := "ip6" + netFlags.String( + ip6FlagName, "", + "Specify a static IPv6 address for the container", + ) + _ = cmd.RegisterFlagCompletionFunc(ip6FlagName, completion.AutocompleteNone) + macAddressFlagName := "mac-address" netFlags.String( macAddressFlagName, "", @@ -60,8 +68,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) @@ -87,9 +95,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 ) @@ -151,18 +157,6 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsF } opts.DNSSearch = dnsSearches - m, err := flags.GetString("mac-address") - if err != nil { - return nil, err - } - if len(m) > 0 { - mac, err := net.ParseMAC(m) - if err != nil { - return nil, err - } - opts.StaticMAC = &mac - } - inputPorts, err := flags.GetStringSlice("publish") if err != nil { return nil, err @@ -174,52 +168,108 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsF } } - 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 staticIP.To4() == nil { - return nil, errors.Wrapf(define.ErrInvalidArg, "%s is not an IPv4 address", ip) - } - opts.StaticIP = &staticIP - } - opts.NoHosts, err = flags.GetBool("no-hosts") if err != nil { 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, cniNets, 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.CNINetworks = cniNets + opts.Networks = networks } - aliases, err := flags.GetStringSlice("network-alias") - if err != nil { - return nil, err - } - if len(aliases) > 0 { - opts.Aliases = aliases + if flags.Changed("ip") || flags.Changed("ip6") || 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": {}, + } + } + + for _, ipFlagName := range []string{"ip", "ip6"} { + ip, err := flags.GetString(ipFlagName) + if err != nil { + return nil, err + } + if ip != "" { + // if pod create --infra=false + if infra, err := flags.GetBool("infra"); err == nil && !infra { + return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set --%s without infra container", ipFlagName) + } + + staticIP := net.ParseIP(ip) + if staticIP == nil { + return nil, errors.Errorf("%q is not an ip address", ip) + } + if !opts.Network.IsBridge() && !opts.Network.IsDefault() { + return nil, errors.Wrapf(define.ErrInvalidArg, "--%s can only be set when the network mode is bridge", ipFlagName) + } + if len(opts.Networks) != 1 { + return nil, errors.Wrapf(define.ErrInvalidArg, "--%s can only be set for a single network", ipFlagName) + } + for name, netOpts := range opts.Networks { + netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP) + opts.Networks[name] = netOpts + } + } + } + + m, err := flags.GetString("mac-address") + if err != nil { + return nil, err + } + 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 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 + } + } } return opts, err |