Skip to content

Commit

Permalink
Cli change to pass driver specific options to docker run
Browse files Browse the repository at this point in the history
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#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 <[email protected]>
Signed-off-by: Sebastiaan van Stijn <[email protected]>
  • Loading branch information
abhi authored and thaJeztah committed Apr 3, 2019
1 parent 5bbb56b commit c4844b1
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
29 changes: 25 additions & 4 deletions cli/command/container/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type containerOptions struct {
ioMaxBandwidth opts.MemBytes
ioMaxIOps uint64
swappiness int64
netMode string
netMode opts.NetworkOpt
macAddress string
ipv4Address string
ipv6Address string
Expand Down Expand Up @@ -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.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.
flags.StringVar(&copts.netMode, "net", "default", "Connect a container to a network")
flags.StringVar(&copts.netMode, "network", "default", "Connect a container to a network")
flags.Var(&copts.netMode, "net", "Connect a container to a network")
flags.Var(&copts.netMode, "network", "Connect a container to a network")
flags.MarkHidden("net")
// 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")
Expand Down Expand Up @@ -613,8 +613,8 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
DNSOptions: copts.dnsOptions.GetAllOrEmpty(),
ExtraHosts: copts.extraHosts.GetAll(),
VolumesFrom: copts.volumesFrom.GetAll(),
NetworkMode: container.NetworkMode(copts.netMode),
IpcMode: container.IpcMode(copts.ipcMode),
NetworkMode: container.NetworkMode(copts.netMode.NetworkMode()),
PidMode: pidMode,
UTSMode: utsMode,
UsernsMode: usernsMode,
Expand Down Expand Up @@ -678,6 +678,27 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
copy(epConfig.Links, hostConfig.Links)
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 {
epConfig := networkingConfig.EndpointsConfig[string(hostConfig.NetworkMode)]
Expand Down
29 changes: 26 additions & 3 deletions cli/command/network/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package network
import (
"context"

"fmt"
"strings"

"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/opts"
Expand All @@ -18,6 +21,7 @@ type connectOptions struct {
links opts.ListOpts
aliases []string
linklocalips []string
driverOpts []string
}

func newConnectCommand(dockerCli command.Cli) *cobra.Command {
Expand All @@ -42,22 +46,41 @@ func newConnectCommand(dockerCli command.Cli) *cobra.Command {
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.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
}

func runConnect(dockerCli command.Cli, options connectOptions) error {
client := dockerCli.Client()

driverOpts, err := convertDriverOpt(options.driverOpts)
if err != nil {
return err
}
epConfig := &network.EndpointSettings{
IPAMConfig: &network.EndpointIPAMConfig{
IPv4Address: options.ipaddress,
IPv6Address: options.ipv6address,
LinkLocalIPs: options.linklocalips,
},
Links: options.links.GetAll(),
Aliases: options.aliases,
Links: options.links.GetAll(),
Aliases: options.aliases,
DriverOpts: driverOpts,
}

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
}
10 changes: 10 additions & 0 deletions opts/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ func (n *NetworkOpt) String() string {
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) {
parts := strings.SplitN(driverOpt, "=", 2)
if len(parts) != 2 {
Expand Down

0 comments on commit c4844b1

Please sign in to comment.