Cli change to pass driver specific options to docker run

The commit contains cli changes to support driver options for a network in
docker run and docker network connect cli's. The driver-opt, aliases is now
supported in the form of csv as per network option in service commands in
swarm mode since docker/cli#62 . This commit extends this support to docker
run command as well.

For docker connect command `--driver-opt` is added to pass driver specific
options for the network the container is connecting to.

Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Abhinandan Prativadi 2017-07-10 13:44:45 -07:00 committed by Sebastiaan van Stijn
parent 5bbb56bfee
commit c4844b1fdd
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
3 changed files with 61 additions and 7 deletions

View File

@ -97,7 +97,7 @@ type containerOptions struct {
ioMaxBandwidth opts.MemBytes ioMaxBandwidth opts.MemBytes
ioMaxIOps uint64 ioMaxIOps uint64
swappiness int64 swappiness int64
netMode string netMode opts.NetworkOpt
macAddress string macAddress string
ipv4Address string ipv4Address string
ipv6Address string ipv6Address string
@ -215,8 +215,8 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
flags.VarP(&copts.publish, "publish", "p", "Publish a container's port(s) to the host") flags.VarP(&copts.publish, "publish", "p", "Publish a container's port(s) to the host")
flags.BoolVarP(&copts.publishAll, "publish-all", "P", false, "Publish all exposed ports to random ports") flags.BoolVarP(&copts.publishAll, "publish-all", "P", false, "Publish all exposed ports to random ports")
// We allow for both "--net" and "--network", although the latter is the recommended way. // We allow for both "--net" and "--network", although the latter is the recommended way.
flags.StringVar(&copts.netMode, "net", "default", "Connect a container to a network") flags.Var(&copts.netMode, "net", "Connect a container to a network")
flags.StringVar(&copts.netMode, "network", "default", "Connect a container to a network") flags.Var(&copts.netMode, "network", "Connect a container to a network")
flags.MarkHidden("net") flags.MarkHidden("net")
// We allow for both "--net-alias" and "--network-alias", although the latter is the recommended way. // We allow for both "--net-alias" and "--network-alias", although the latter is the recommended way.
flags.Var(&copts.aliases, "net-alias", "Add network-scoped alias for the container") flags.Var(&copts.aliases, "net-alias", "Add network-scoped alias for the container")
@ -613,8 +613,8 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
DNSOptions: copts.dnsOptions.GetAllOrEmpty(), DNSOptions: copts.dnsOptions.GetAllOrEmpty(),
ExtraHosts: copts.extraHosts.GetAll(), ExtraHosts: copts.extraHosts.GetAll(),
VolumesFrom: copts.volumesFrom.GetAll(), VolumesFrom: copts.volumesFrom.GetAll(),
NetworkMode: container.NetworkMode(copts.netMode),
IpcMode: container.IpcMode(copts.ipcMode), IpcMode: container.IpcMode(copts.ipcMode),
NetworkMode: container.NetworkMode(copts.netMode.NetworkMode()),
PidMode: pidMode, PidMode: pidMode,
UTSMode: utsMode, UTSMode: utsMode,
UsernsMode: usernsMode, UsernsMode: usernsMode,
@ -678,6 +678,27 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
copy(epConfig.Links, hostConfig.Links) copy(epConfig.Links, hostConfig.Links)
networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = epConfig networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = epConfig
} }
value := copts.netMode.Value()
if value != nil && hostConfig.NetworkMode.IsUserDefined() {
epConfig := networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)]
if epConfig == nil {
epConfig = &networktypes.EndpointSettings{}
}
if len(value[0].Aliases) > 0 {
if copts.aliases.Len() > 0 {
return nil, fmt.Errorf("ambiguity in alias options provided")
}
epConfig.Aliases = append(epConfig.Aliases, value[0].Aliases...)
}
if len(value[0].DriverOpts) > 0 {
epConfig.DriverOpts = make(map[string]string)
epConfig.DriverOpts = value[0].DriverOpts
}
networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] = epConfig
}
if copts.aliases.Len() > 0 { if copts.aliases.Len() > 0 {
epConfig := networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)] epConfig := networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)]

View File

@ -3,6 +3,9 @@ package network
import ( import (
"context" "context"
"fmt"
"strings"
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
@ -18,6 +21,7 @@ type connectOptions struct {
links opts.ListOpts links opts.ListOpts
aliases []string aliases []string
linklocalips []string linklocalips []string
driverOpts []string
} }
func newConnectCommand(dockerCli command.Cli) *cobra.Command { func newConnectCommand(dockerCli command.Cli) *cobra.Command {
@ -42,13 +46,17 @@ func newConnectCommand(dockerCli command.Cli) *cobra.Command {
flags.Var(&options.links, "link", "Add link to another container") flags.Var(&options.links, "link", "Add link to another container")
flags.StringSliceVar(&options.aliases, "alias", []string{}, "Add network-scoped alias for the container") flags.StringSliceVar(&options.aliases, "alias", []string{}, "Add network-scoped alias for the container")
flags.StringSliceVar(&options.linklocalips, "link-local-ip", []string{}, "Add a link-local address for the container") flags.StringSliceVar(&options.linklocalips, "link-local-ip", []string{}, "Add a link-local address for the container")
flags.StringSliceVar(&options.driverOpts, "driver-opt", []string{}, "driver options for the network")
return cmd return cmd
} }
func runConnect(dockerCli command.Cli, options connectOptions) error { func runConnect(dockerCli command.Cli, options connectOptions) error {
client := dockerCli.Client() client := dockerCli.Client()
driverOpts, err := convertDriverOpt(options.driverOpts)
if err != nil {
return err
}
epConfig := &network.EndpointSettings{ epConfig := &network.EndpointSettings{
IPAMConfig: &network.EndpointIPAMConfig{ IPAMConfig: &network.EndpointIPAMConfig{
IPv4Address: options.ipaddress, IPv4Address: options.ipaddress,
@ -57,7 +65,22 @@ func runConnect(dockerCli command.Cli, options connectOptions) error {
}, },
Links: options.links.GetAll(), Links: options.links.GetAll(),
Aliases: options.aliases, Aliases: options.aliases,
DriverOpts: driverOpts,
} }
return client.NetworkConnect(context.Background(), options.network, options.container, epConfig) return client.NetworkConnect(context.Background(), options.network, options.container, epConfig)
} }
func convertDriverOpt(opts []string) (map[string]string, error) {
driverOpt := make(map[string]string)
for _, opt := range opts {
parts := strings.SplitN(opt, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid key/value pair format in driver options")
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
driverOpt[key] = value
}
return driverOpt, nil
}

View File

@ -95,6 +95,16 @@ func (n *NetworkOpt) String() string {
return "" return ""
} }
// NetworkMode return the network mode for the network option
func (n *NetworkOpt) NetworkMode() string {
networkIDOrName := "default"
netOptVal := n.Value()
if len(netOptVal) > 0 {
networkIDOrName = netOptVal[0].Target
}
return networkIDOrName
}
func parseDriverOpt(driverOpt string) (string, string, error) { func parseDriverOpt(driverOpt string) (string, string, error) {
parts := strings.SplitN(driverOpt, "=", 2) parts := strings.SplitN(driverOpt, "=", 2)
if len(parts) != 2 { if len(parts) != 2 {