Skip to content

Commit

Permalink
Merge pull request #12534 from Luap99/network-db
Browse files Browse the repository at this point in the history
network db rewrite
  • Loading branch information
openshift-merge-robot authored Dec 15, 2021
2 parents b01a421 + ef325bc commit 7dabcbd
Show file tree
Hide file tree
Showing 68 changed files with 1,352 additions and 962 deletions.
79 changes: 38 additions & 41 deletions cmd/podman/common/create_opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/common/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
133 changes: 87 additions & 46 deletions cmd/podman/common/netflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -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
)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/containers/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/containers/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
33 changes: 32 additions & 1 deletion cmd/podman/networks/connect.go
Original file line number Diff line number Diff line change
@@ -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"
)
Expand All @@ -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() {
Expand All @@ -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)
}
2 changes: 1 addition & 1 deletion cmd/podman/play/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading

0 comments on commit 7dabcbd

Please sign in to comment.