parseNetworkOpts converts --network advanced options to endpoint-specs, and combines them with the old --network-alias and --links. If returns an error if conflicting options are found. this function may return _multiple_ endpoints, which is not currently supported by the daemon, but may be in futu
(copts *containerOptions)
| 755 | // by the daemon, but may be in future; it's up to the daemon to produce an error |
| 756 | // in case that is not supported. |
| 757 | func parseNetworkOpts(copts *containerOptions) (map[string]*network.EndpointSettings, error) { |
| 758 | var ( |
| 759 | endpoints = make(map[string]*network.EndpointSettings, len(copts.netMode.Value())) |
| 760 | hasUserDefined, hasNonUserDefined bool |
| 761 | ) |
| 762 | |
| 763 | if len(copts.netMode.Value()) == 0 { |
| 764 | n := opts.NetworkAttachmentOpts{ |
| 765 | Target: "default", |
| 766 | } |
| 767 | if err := applyContainerOptions(&n, copts); err != nil { |
| 768 | return nil, err |
| 769 | } |
| 770 | ep, err := parseNetworkAttachmentOpt(n) |
| 771 | if err != nil { |
| 772 | return nil, err |
| 773 | } |
| 774 | endpoints["default"] = ep |
| 775 | } |
| 776 | |
| 777 | for i, n := range copts.netMode.Value() { |
| 778 | if container.NetworkMode(n.Target).IsUserDefined() { |
| 779 | hasUserDefined = true |
| 780 | } else { |
| 781 | hasNonUserDefined = true |
| 782 | } |
| 783 | if i == 0 { |
| 784 | // The first network corresponds with what was previously the "only" |
| 785 | // network, and what would be used when using the non-advanced syntax |
| 786 | // `--network-alias`, `--link`, `--ip`, `--ip6`, and `--link-local-ip` |
| 787 | // are set on this network, to preserve backward compatibility with |
| 788 | // the non-advanced notation |
| 789 | if err := applyContainerOptions(&n, copts); err != nil { |
| 790 | return nil, err |
| 791 | } |
| 792 | } |
| 793 | ep, err := parseNetworkAttachmentOpt(n) |
| 794 | if err != nil { |
| 795 | return nil, err |
| 796 | } |
| 797 | if _, ok := endpoints[n.Target]; ok { |
| 798 | return nil, fmt.Errorf("network %q is specified multiple times", n.Target) |
| 799 | } |
| 800 | |
| 801 | // For backward compatibility: if no custom options are provided for the network, |
| 802 | // and only a single network is specified, omit the endpoint-configuration |
| 803 | // on the client (the daemon will still create it when creating the container) |
| 804 | if i == 0 && len(copts.netMode.Value()) == 1 { |
| 805 | if ep == nil || reflect.ValueOf(*ep).IsZero() { |
| 806 | continue |
| 807 | } |
| 808 | } |
| 809 | endpoints[n.Target] = ep |
| 810 | } |
| 811 | if hasUserDefined && hasNonUserDefined { |
| 812 | return nil, errors.New("conflicting options: cannot attach both user-defined and non-user-defined network-modes") |
| 813 | } |
| 814 | return endpoints, nil |
no test coverage detected
searching dependent graphs…