summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/common/create_opts.go79
-rw-r--r--cmd/podman/common/create_test.go2
-rw-r--r--cmd/podman/common/netflags.go133
-rw-r--r--cmd/podman/containers/create.go2
-rw-r--r--cmd/podman/containers/run.go2
-rw-r--r--cmd/podman/networks/connect.go33
-rw-r--r--cmd/podman/play/kube.go2
-rw-r--r--cmd/podman/pods/create.go4
8 files changed, 163 insertions, 94 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 7d6471fd4..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.
@@ -184,52 +177,56 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
// network names
switch {
case len(cc.NetworkingConfig.EndpointsConfig) > 0:
- var aliases []string
-
endpointsConfig := cc.NetworkingConfig.EndpointsConfig
- cniNetworks := make([]string, 0, len(endpointsConfig))
+ networks := make(map[string]types.PerNetworkOptions, len(endpointsConfig))
for netName, endpoint := range endpointsConfig {
- cniNetworks = append(cniNetworks, netName)
-
- if endpoint == nil {
- continue
- }
- if len(endpoint.Aliases) > 0 {
- aliases = append(aliases, endpoint.Aliases...)
- }
- }
+ netOpts := types.PerNetworkOptions{}
+ if endpoint != nil {
+ netOpts.Aliases = endpoint.Aliases
- // static IP and MAC
- if len(endpointsConfig) == 1 {
- for _, ep := range endpointsConfig {
- if ep == nil {
- continue
- }
// if IP address is provided
- if len(ep.IPAddress) > 0 {
- staticIP := net.ParseIP(ep.IPAddress)
- netInfo.StaticIP = &staticIP
+ if len(endpoint.IPAddress) > 0 {
+ staticIP := net.ParseIP(endpoint.IPAddress)
+ if staticIP == nil {
+ return nil, nil, errors.Errorf("failed to parse the ip address %q", endpoint.IPAddress)
+ }
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
}
- // if IPAMConfig.IPv4Address is provided
- if ep.IPAMConfig != nil && ep.IPAMConfig.IPv4Address != "" {
- staticIP := net.ParseIP(ep.IPAMConfig.IPv4Address)
- netInfo.StaticIP = &staticIP
+
+ if endpoint.IPAMConfig != nil {
+ // if IPAMConfig.IPv4Address is provided
+ if len(endpoint.IPAMConfig.IPv4Address) > 0 {
+ staticIP := net.ParseIP(endpoint.IPAMConfig.IPv4Address)
+ if staticIP == nil {
+ return nil, nil, errors.Errorf("failed to parse the ipv4 address %q", endpoint.IPAMConfig.IPv4Address)
+ }
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
+ }
+ // if IPAMConfig.IPv6Address is provided
+ if len(endpoint.IPAMConfig.IPv6Address) > 0 {
+ staticIP := net.ParseIP(endpoint.IPAMConfig.IPv6Address)
+ if staticIP == nil {
+ return nil, nil, errors.Errorf("failed to parse the ipv6 address %q", endpoint.IPAMConfig.IPv6Address)
+ }
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
+ }
}
// If MAC address is provided
- if len(ep.MacAddress) > 0 {
- staticMac, err := net.ParseMAC(ep.MacAddress)
+ if len(endpoint.MacAddress) > 0 {
+ staticMac, err := net.ParseMAC(endpoint.MacAddress)
if err != nil {
- return nil, nil, err
+ return nil, nil, errors.Errorf("failed to parse the mac address %q", endpoint.MacAddress)
}
- netInfo.StaticMAC = &staticMac
+ netOpts.StaticMAC = types.HardwareAddr(staticMac)
}
- break
}
+
+ networks[netName] = netOpts
}
- netInfo.Aliases = aliases
- netInfo.CNINetworks = cniNetworks
+
+ netInfo.Networks = networks
case len(cc.HostConfig.NetworkMode) > 0:
- netInfo.CNINetworks = networks
+ netInfo.Networks = networks
}
parsedTmp := make([]string, 0, len(cc.HostConfig.Tmpfs))
diff --git a/cmd/podman/common/create_test.go b/cmd/podman/common/create_test.go
index 17b47dd16..601078b61 100644
--- a/cmd/podman/common/create_test.go
+++ b/cmd/podman/common/create_test.go
@@ -12,7 +12,7 @@ import (
func TestPodOptions(t *testing.T) {
entry := "/test1"
- exampleOptions := entities.ContainerCreateOptions{CPUS: 5.5, CPUSetCPUs: "0-4", Entrypoint: &entry, Hostname: "foo", Name: "testing123", Volume: []string{"/fakeVol1", "/fakeVol2"}, Net: &entities.NetOptions{CNINetworks: []string{"FakeNetwork"}}, PID: "ns:/proc/self/ns"}
+ exampleOptions := entities.ContainerCreateOptions{CPUS: 5.5, CPUSetCPUs: "0-4", Entrypoint: &entry, Hostname: "foo", Name: "testing123", Volume: []string{"/fakeVol1", "/fakeVol2"}, Net: &entities.NetOptions{DNSSearch: []string{"search"}}, PID: "ns:/proc/self/ns"}
podOptions := entities.PodCreateOptions{}
err := common.ContainerToPodOptions(&exampleOptions, &podOptions)
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go
index d11f3c9d2..ba8ab7a8b 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"
@@ -60,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)
@@ -87,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
)
@@ -151,18 +150,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 +161,106 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsF
}
}
- ip, err := flags.GetString("ip")
+ opts.NoHosts, err = flags.GetBool("no-hosts")
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)
+
+ // 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
}
- if staticIP.To4() == nil {
- return nil, errors.Wrapf(define.ErrInvalidArg, "%s is not an IPv4 address", ip)
+
+ ns, networks, options, err := specgen.ParseNetworkFlag(network)
+ if err != nil {
+ return nil, err
}
- opts.StaticIP = &staticIP
- }
- opts.NoHosts, err = flags.GetBool("no-hosts")
- if err != nil {
- return nil, err
+ opts.NetworkOptions = options
+ opts.Network = ns
+ opts.Networks = networks
}
- // 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")
+ 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": {},
+ }
+ }
+
+ ip, err := flags.GetString("ip")
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.Wrap(define.ErrInvalidArg, "cannot set --ip without infra container")
+ }
- ns, cniNets, options, err := specgen.ParseNetworkString(network)
+ 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
+ }
+ }
+
+ m, err := flags.GetString("mac-address")
if err != nil {
return nil, err
}
-
- if len(options) > 0 {
- opts.NetworkOptions = options
+ 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
+ }
}
- opts.Network = ns
- opts.CNINetworks = cniNets
- }
- aliases, err := flags.GetStringSlice("network-alias")
- if err != nil {
- return nil, err
- }
- if len(aliases) > 0 {
- opts.Aliases = aliases
+ 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
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index a17fcaa1c..e004f4ab2 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -105,7 +105,7 @@ func create(cmd *cobra.Command, args []string) error {
err error
)
flags := cmd.Flags()
- cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags, cliVals.Pod == "" && cliVals.PodIDFile == "")
+ cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags)
if err != nil {
return err
}
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index 9d1b040cc..cfb89ce57 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -120,7 +120,7 @@ func run(cmd *cobra.Command, args []string) error {
}
flags := cmd.Flags()
- cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags, cliVals.Pod == "" && cliVals.PodIDFile == "")
+ cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags)
if err != nil {
return err
}
diff --git a/cmd/podman/networks/connect.go b/cmd/podman/networks/connect.go
index 0d62a45df..b0ffbfe6d 100644
--- a/cmd/podman/networks/connect.go
+++ b/cmd/podman/networks/connect.go
@@ -1,9 +1,12 @@
package network
import (
+ "net"
+
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/spf13/cobra"
)
@@ -23,13 +26,28 @@ var (
var (
networkConnectOptions entities.NetworkConnectOptions
+ ipv4 net.IP
+ ipv6 net.IP
+ macAddress string
)
func networkConnectFlags(cmd *cobra.Command) {
flags := cmd.Flags()
aliasFlagName := "alias"
- flags.StringSliceVar(&networkConnectOptions.Aliases, aliasFlagName, []string{}, "network scoped alias for container")
+ flags.StringSliceVar(&networkConnectOptions.Aliases, aliasFlagName, nil, "network scoped alias for container")
_ = cmd.RegisterFlagCompletionFunc(aliasFlagName, completion.AutocompleteNone)
+
+ ipAddressFlagName := "ip"
+ flags.IPVar(&ipv4, ipAddressFlagName, nil, "set a static ipv4 address for this container network")
+ _ = cmd.RegisterFlagCompletionFunc(ipAddressFlagName, completion.AutocompleteNone)
+
+ ipv6AddressFlagName := "ip6"
+ flags.IPVar(&ipv6, ipv6AddressFlagName, nil, "set a static ipv6 address for this container network")
+ _ = cmd.RegisterFlagCompletionFunc(ipv6AddressFlagName, completion.AutocompleteNone)
+
+ macAddressFlagName := "mac-address"
+ flags.StringVar(&macAddress, macAddressFlagName, "", "set a static mac address for this container network")
+ _ = cmd.RegisterFlagCompletionFunc(macAddressFlagName, completion.AutocompleteNone)
}
func init() {
@@ -42,5 +60,18 @@ func init() {
func networkConnect(cmd *cobra.Command, args []string) error {
networkConnectOptions.Container = args[1]
+ if macAddress != "" {
+ mac, err := net.ParseMAC(macAddress)
+ if err != nil {
+ return err
+ }
+ networkConnectOptions.StaticMAC = types.HardwareAddr(mac)
+ }
+ for _, ip := range []net.IP{ipv4, ipv6} {
+ if ip != nil {
+ networkConnectOptions.StaticIPs = append(networkConnectOptions.StaticIPs, ip)
+ }
+ }
+
return registry.ContainerEngine().NetworkConnect(registry.Context(), args[0], networkConnectOptions)
}
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go
index 11b5d7d34..ae4066a6f 100644
--- a/cmd/podman/play/kube.go
+++ b/cmd/podman/play/kube.go
@@ -69,7 +69,7 @@ func init() {
_ = kubeCmd.RegisterFlagCompletionFunc(staticMACFlagName, completion.AutocompleteNone)
networkFlagName := "network"
- flags.StringVar(&kubeOptions.Network, networkFlagName, "", "Connect pod to CNI network(s)")
+ flags.StringArrayVar(&kubeOptions.Networks, networkFlagName, nil, "Connect pod to network(s) or network mode")
_ = kubeCmd.RegisterFlagCompletionFunc(networkFlagName, common.AutocompleteNetworkFlag)
staticIPFlagName := "ip"
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 7399dd029..f844812c2 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -116,7 +116,7 @@ func create(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cannot specify no-hosts without an infra container")
}
flags := cmd.Flags()
- createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, createOptions.Infra)
+ createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags)
if err != nil {
return err
}
@@ -133,7 +133,7 @@ func create(cmd *cobra.Command, args []string) error {
} else {
// reassign certain options for lbpod api, these need to be populated in spec
flags := cmd.Flags()
- infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, createOptions.Infra)
+ infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags)
if err != nil {
return err
}