mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Windows: Refactor network modes
Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
parent
aa4f495cae
commit
c5e6a4b307
10 changed files with 250 additions and 131 deletions
|
@ -65,22 +65,17 @@ func populateCommand(c *Container, env []string) error {
|
||||||
Interface: nil,
|
Interface: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Windows. Appropriate network mode (will refactor as part of
|
|
||||||
// libnetwork. For now, even through bridge not used, let it succeed to
|
|
||||||
// allow the Windows daemon to limp during its bring-up
|
|
||||||
parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2)
|
parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2)
|
||||||
switch parts[0] {
|
switch parts[0] {
|
||||||
|
|
||||||
case "none":
|
case "none":
|
||||||
case "bridge", "": // empty string to support existing containers
|
case "default", "": // empty string to support existing containers
|
||||||
if !c.Config.NetworkDisabled {
|
if !c.Config.NetworkDisabled {
|
||||||
network := c.NetworkSettings
|
network := c.NetworkSettings
|
||||||
en.Interface = &execdriver.NetworkInterface{
|
en.Interface = &execdriver.NetworkInterface{
|
||||||
Bridge: network.Bridge,
|
|
||||||
MacAddress: network.MacAddress,
|
MacAddress: network.MacAddress,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "host", "container":
|
|
||||||
return fmt.Errorf("unsupported network mode: %s", c.hostConfig.NetworkMode)
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid network mode: %s", c.hostConfig.NetworkMode)
|
return fmt.Errorf("invalid network mode: %s", c.hostConfig.NetworkMode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import (
|
||||||
"github.com/docker/docker/pkg/graphdb"
|
"github.com/docker/docker/pkg/graphdb"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/namesgenerator"
|
"github.com/docker/docker/pkg/namesgenerator"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/docker/pkg/sysinfo"
|
"github.com/docker/docker/pkg/sysinfo"
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
|
@ -553,43 +552,6 @@ func (daemon *Daemon) RegisterLink(parent, child *Container, alias string) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
|
|
||||||
if hostConfig != nil && hostConfig.Links != nil {
|
|
||||||
for _, l := range hostConfig.Links {
|
|
||||||
name, alias, err := parsers.ParseLink(l)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
child, err := daemon.Get(name)
|
|
||||||
if err != nil {
|
|
||||||
//An error from daemon.Get() means this name could not be found
|
|
||||||
return fmt.Errorf("Could not get container for %s", name)
|
|
||||||
}
|
|
||||||
for child.hostConfig.NetworkMode.IsContainer() {
|
|
||||||
parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
|
|
||||||
child, err = daemon.Get(parts[1])
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not get container for %s", parts[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if child.hostConfig.NetworkMode.IsHost() {
|
|
||||||
return runconfig.ErrConflictHostNetworkAndLinks
|
|
||||||
}
|
|
||||||
if err := daemon.RegisterLink(container, child, alias); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// After we load all the links into the daemon
|
|
||||||
// set them to nil on the hostconfig
|
|
||||||
hostConfig.Links = nil
|
|
||||||
if err := container.WriteHostConfig(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemon, err error) {
|
func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemon, err error) {
|
||||||
setDefaultMtu(config)
|
setDefaultMtu(config)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/docker/docker/daemon/graphdriver"
|
"github.com/docker/docker/daemon/graphdriver"
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
"github.com/docker/docker/pkg/fileutils"
|
"github.com/docker/docker/pkg/fileutils"
|
||||||
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/docker/docker/pkg/parsers/kernel"
|
"github.com/docker/docker/pkg/parsers/kernel"
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
|
@ -460,3 +461,44 @@ func setupInitLayer(initLayer string) error {
|
||||||
func (daemon *Daemon) NetworkApiRouter() func(w http.ResponseWriter, req *http.Request) {
|
func (daemon *Daemon) NetworkApiRouter() func(w http.ResponseWriter, req *http.Request) {
|
||||||
return nwapi.NewHTTPHandler(daemon.netController)
|
return nwapi.NewHTTPHandler(daemon.netController)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
|
||||||
|
|
||||||
|
if hostConfig == nil || hostConfig.Links == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range hostConfig.Links {
|
||||||
|
name, alias, err := parsers.ParseLink(l)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
child, err := daemon.Get(name)
|
||||||
|
if err != nil {
|
||||||
|
//An error from daemon.Get() means this name could not be found
|
||||||
|
return fmt.Errorf("Could not get container for %s", name)
|
||||||
|
}
|
||||||
|
for child.hostConfig.NetworkMode.IsContainer() {
|
||||||
|
parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
|
||||||
|
child, err = daemon.Get(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Could not get container for %s", parts[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if child.hostConfig.NetworkMode.IsHost() {
|
||||||
|
return runconfig.ErrConflictHostNetworkAndLinks
|
||||||
|
}
|
||||||
|
if err := daemon.RegisterLink(container, child, alias); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After we load all the links into the daemon
|
||||||
|
// set them to nil on the hostconfig
|
||||||
|
hostConfig.Links = nil
|
||||||
|
if err := container.WriteHostConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/docker/daemon/graphdriver"
|
"github.com/docker/docker/daemon/graphdriver"
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/libnetwork"
|
"github.com/docker/libnetwork"
|
||||||
)
|
)
|
||||||
|
@ -103,3 +104,35 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error)
|
||||||
// TODO Windows
|
// TODO Windows
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
|
||||||
|
// TODO Windows. Factored out for network modes. There may be more
|
||||||
|
// refactoring required here.
|
||||||
|
|
||||||
|
if hostConfig == nil || hostConfig.Links == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range hostConfig.Links {
|
||||||
|
name, alias, err := parsers.ParseLink(l)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
child, err := daemon.Get(name)
|
||||||
|
if err != nil {
|
||||||
|
//An error from daemon.Get() means this name could not be found
|
||||||
|
return fmt.Errorf("Could not get container for %s", name)
|
||||||
|
}
|
||||||
|
if err := daemon.RegisterLink(container, child, alias); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After we load all the links into the daemon
|
||||||
|
// set them to nil on the hostconfig
|
||||||
|
hostConfig.Links = nil
|
||||||
|
if err := container.WriteHostConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -16,51 +16,6 @@ type KeyValuePair struct {
|
||||||
|
|
||||||
type NetworkMode string
|
type NetworkMode string
|
||||||
|
|
||||||
// IsPrivate indicates whether container use it's private network stack
|
|
||||||
func (n NetworkMode) IsPrivate() bool {
|
|
||||||
return !(n.IsHost() || n.IsContainer())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n NetworkMode) IsDefault() bool {
|
|
||||||
return n == "default"
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultDaemonNetworkMode() NetworkMode {
|
|
||||||
return NetworkMode("bridge")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n NetworkMode) NetworkName() string {
|
|
||||||
if n.IsBridge() {
|
|
||||||
return "bridge"
|
|
||||||
} else if n.IsHost() {
|
|
||||||
return "host"
|
|
||||||
} else if n.IsContainer() {
|
|
||||||
return "container"
|
|
||||||
} else if n.IsNone() {
|
|
||||||
return "none"
|
|
||||||
} else if n.IsDefault() {
|
|
||||||
return "default"
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n NetworkMode) IsBridge() bool {
|
|
||||||
return n == "bridge"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n NetworkMode) IsHost() bool {
|
|
||||||
return n == "host"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n NetworkMode) IsContainer() bool {
|
|
||||||
parts := strings.SplitN(string(n), ":", 2)
|
|
||||||
return len(parts) > 1 && parts[0] == "container"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n NetworkMode) IsNone() bool {
|
|
||||||
return n == "none"
|
|
||||||
}
|
|
||||||
|
|
||||||
type IpcMode string
|
type IpcMode string
|
||||||
|
|
||||||
// IsPrivate indicates whether container use it's private ipc stack
|
// IsPrivate indicates whether container use it's private ipc stack
|
||||||
|
|
52
runconfig/hostconfig_unix.go
Normal file
52
runconfig/hostconfig_unix.go
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package runconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsPrivate indicates whether container use it's private network stack
|
||||||
|
func (n NetworkMode) IsPrivate() bool {
|
||||||
|
return !(n.IsHost() || n.IsContainer())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkMode) IsDefault() bool {
|
||||||
|
return n == "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultDaemonNetworkMode() NetworkMode {
|
||||||
|
return NetworkMode("bridge")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkMode) NetworkName() string {
|
||||||
|
if n.IsBridge() {
|
||||||
|
return "bridge"
|
||||||
|
} else if n.IsHost() {
|
||||||
|
return "host"
|
||||||
|
} else if n.IsContainer() {
|
||||||
|
return "container"
|
||||||
|
} else if n.IsNone() {
|
||||||
|
return "none"
|
||||||
|
} else if n.IsDefault() {
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkMode) IsBridge() bool {
|
||||||
|
return n == "bridge"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkMode) IsHost() bool {
|
||||||
|
return n == "host"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkMode) IsContainer() bool {
|
||||||
|
parts := strings.SplitN(string(n), ":", 2)
|
||||||
|
return len(parts) > 1 && parts[0] == "container"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkMode) IsNone() bool {
|
||||||
|
return n == "none"
|
||||||
|
}
|
18
runconfig/hostconfig_windows.go
Normal file
18
runconfig/hostconfig_windows.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package runconfig
|
||||||
|
|
||||||
|
func (n NetworkMode) IsDefault() bool {
|
||||||
|
return n == "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultDaemonNetworkMode() NetworkMode {
|
||||||
|
return NetworkMode("default")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkMode) NetworkName() string {
|
||||||
|
if n.IsDefault() {
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
|
@ -24,6 +24,19 @@ var (
|
||||||
ErrConflictNetworkExposePorts = fmt.Errorf("Conflicting options: --expose and the network mode (--expose)")
|
ErrConflictNetworkExposePorts = fmt.Errorf("Conflicting options: --expose and the network mode (--expose)")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// validateNM is the set of fields passed to validateNetMode()
|
||||||
|
type validateNM struct {
|
||||||
|
netMode NetworkMode
|
||||||
|
flHostname *string
|
||||||
|
flLinks opts.ListOpts
|
||||||
|
flDns opts.ListOpts
|
||||||
|
flExtraHosts opts.ListOpts
|
||||||
|
flMacAddress *string
|
||||||
|
flPublish opts.ListOpts
|
||||||
|
flPublishAll *bool
|
||||||
|
flExpose opts.ListOpts
|
||||||
|
}
|
||||||
|
|
||||||
func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSet, error) {
|
func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSet, error) {
|
||||||
var (
|
var (
|
||||||
// FIXME: use utils.ListOpts for attach and volumes?
|
// FIXME: use utils.ListOpts for attach and volumes?
|
||||||
|
@ -121,37 +134,22 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||||
return nil, nil, cmd, fmt.Errorf("--net: invalid net mode: %v", err)
|
return nil, nil, cmd, fmt.Errorf("--net: invalid net mode: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netMode.IsHost() || netMode.IsContainer()) && *flHostname != "" {
|
vals := validateNM{
|
||||||
return nil, nil, cmd, ErrConflictNetworkHostname
|
netMode: netMode,
|
||||||
|
flHostname: flHostname,
|
||||||
|
flLinks: flLinks,
|
||||||
|
flDns: flDns,
|
||||||
|
flExtraHosts: flExtraHosts,
|
||||||
|
flMacAddress: flMacAddress,
|
||||||
|
flPublish: flPublish,
|
||||||
|
flPublishAll: flPublishAll,
|
||||||
|
flExpose: flExpose,
|
||||||
}
|
}
|
||||||
|
|
||||||
if netMode.IsHost() && flLinks.Len() > 0 {
|
if err := validateNetMode(&vals); err != nil {
|
||||||
return nil, nil, cmd, ErrConflictHostNetworkAndLinks
|
return nil, nil, cmd, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if netMode.IsContainer() && flLinks.Len() > 0 {
|
|
||||||
return nil, nil, cmd, ErrConflictContainerNetworkAndLinks
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netMode.IsHost() || netMode.IsContainer()) && flDns.Len() > 0 {
|
|
||||||
return nil, nil, cmd, ErrConflictNetworkAndDns
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netMode.IsContainer() || netMode.IsHost()) && flExtraHosts.Len() > 0 {
|
|
||||||
return nil, nil, cmd, ErrConflictNetworkHosts
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netMode.IsContainer() || netMode.IsHost()) && *flMacAddress != "" {
|
|
||||||
return nil, nil, cmd, ErrConflictContainerNetworkAndMac
|
|
||||||
}
|
|
||||||
|
|
||||||
if netMode.IsContainer() && (flPublish.Len() > 0 || *flPublishAll == true) {
|
|
||||||
return nil, nil, cmd, ErrConflictNetworkPublishPorts
|
|
||||||
}
|
|
||||||
|
|
||||||
if netMode.IsContainer() && flExpose.Len() > 0 {
|
|
||||||
return nil, nil, cmd, ErrConflictNetworkExposePorts
|
|
||||||
}
|
|
||||||
// Validate the input mac address
|
// Validate the input mac address
|
||||||
if *flMacAddress != "" {
|
if *flMacAddress != "" {
|
||||||
if _, err := opts.ValidateMACAddress(*flMacAddress); err != nil {
|
if _, err := opts.ValidateMACAddress(*flMacAddress); err != nil {
|
||||||
|
@ -463,20 +461,6 @@ func parseKeyValueOpts(opts opts.ListOpts) ([]KeyValuePair, error) {
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNetMode(netMode string) (NetworkMode, error) {
|
|
||||||
parts := strings.Split(netMode, ":")
|
|
||||||
switch mode := parts[0]; mode {
|
|
||||||
case "default", "bridge", "none", "host":
|
|
||||||
case "container":
|
|
||||||
if len(parts) < 2 || parts[1] == "" {
|
|
||||||
return "", fmt.Errorf("invalid container format container:<name|id>")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("invalid --net: %s", netMode)
|
|
||||||
}
|
|
||||||
return NetworkMode(netMode), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseDevice(device string) (DeviceMapping, error) {
|
func ParseDevice(device string) (DeviceMapping, error) {
|
||||||
src := ""
|
src := ""
|
||||||
dst := ""
|
dst := ""
|
||||||
|
|
58
runconfig/parse_unix.go
Normal file
58
runconfig/parse_unix.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package runconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseNetMode(netMode string) (NetworkMode, error) {
|
||||||
|
parts := strings.Split(netMode, ":")
|
||||||
|
switch mode := parts[0]; mode {
|
||||||
|
case "default", "bridge", "none", "host":
|
||||||
|
case "container":
|
||||||
|
if len(parts) < 2 || parts[1] == "" {
|
||||||
|
return "", fmt.Errorf("invalid container format container:<name|id>")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("invalid --net: %s", netMode)
|
||||||
|
}
|
||||||
|
return NetworkMode(netMode), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateNetMode(vals *validateNM) error {
|
||||||
|
|
||||||
|
if (vals.netMode.IsHost() || vals.netMode.IsContainer()) && *vals.flHostname != "" {
|
||||||
|
return ErrConflictNetworkHostname
|
||||||
|
}
|
||||||
|
|
||||||
|
if vals.netMode.IsHost() && vals.flLinks.Len() > 0 {
|
||||||
|
return ErrConflictHostNetworkAndLinks
|
||||||
|
}
|
||||||
|
|
||||||
|
if vals.netMode.IsContainer() && vals.flLinks.Len() > 0 {
|
||||||
|
return ErrConflictContainerNetworkAndLinks
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vals.netMode.IsHost() || vals.netMode.IsContainer()) && vals.flDns.Len() > 0 {
|
||||||
|
return ErrConflictNetworkAndDns
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vals.netMode.IsContainer() || vals.netMode.IsHost()) && vals.flExtraHosts.Len() > 0 {
|
||||||
|
return ErrConflictNetworkHosts
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vals.netMode.IsContainer() || vals.netMode.IsHost()) && *vals.flMacAddress != "" {
|
||||||
|
return ErrConflictContainerNetworkAndMac
|
||||||
|
}
|
||||||
|
|
||||||
|
if vals.netMode.IsContainer() && (vals.flPublish.Len() > 0 || *vals.flPublishAll == true) {
|
||||||
|
return ErrConflictNetworkPublishPorts
|
||||||
|
}
|
||||||
|
|
||||||
|
if vals.netMode.IsContainer() && vals.flExpose.Len() > 0 {
|
||||||
|
return ErrConflictNetworkExposePorts
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
20
runconfig/parse_windows.go
Normal file
20
runconfig/parse_windows.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package runconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseNetMode(netMode string) (NetworkMode, error) {
|
||||||
|
parts := strings.Split(netMode, ":")
|
||||||
|
switch mode := parts[0]; mode {
|
||||||
|
case "default":
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("invalid --net: %s", netMode)
|
||||||
|
}
|
||||||
|
return NetworkMode(netMode), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateNetMode(vals *validateNM) error {
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue