Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support config default network name for nerdctl #1150

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 25 additions & 22 deletions cmd/nerdctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,34 +87,36 @@ func xmain() error {
// Config corresponds to nerdctl.toml .
// See docs/config.md .
type Config struct {
Debug bool `toml:"debug"`
DebugFull bool `toml:"debug_full"`
Address string `toml:"address"`
Namespace string `toml:"namespace"`
Snapshotter string `toml:"snapshotter"`
CNIPath string `toml:"cni_path"`
CNINetConfPath string `toml:"cni_netconfpath"`
DataRoot string `toml:"data_root"`
CgroupManager string `toml:"cgroup_manager"`
InsecureRegistry bool `toml:"insecure_registry"`
HostsDir []string `toml:"hosts_dir"`
Debug bool `toml:"debug"`
DebugFull bool `toml:"debug_full"`
Address string `toml:"address"`
Namespace string `toml:"namespace"`
Snapshotter string `toml:"snapshotter"`
CNIPath string `toml:"cni_path"`
CNINetConfPath string `toml:"cni_netconfpath"`
DataRoot string `toml:"data_root"`
CgroupManager string `toml:"cgroup_manager"`
InsecureRegistry bool `toml:"insecure_registry"`
HostsDir []string `toml:"hosts_dir"`
DefaultNetworkName string `toml:"default_network_name"`
}

// NewConfig creates a default Config object statically,
// without interpolating CLI flags, env vars, and toml.
func NewConfig() *Config {
return &Config{
Debug: false,
DebugFull: false,
Address: defaults.DefaultAddress,
Namespace: namespaces.Default,
Snapshotter: containerd.DefaultSnapshotter,
CNIPath: ncdefaults.CNIPath(),
CNINetConfPath: ncdefaults.CNINetConfPath(),
DataRoot: ncdefaults.DataRoot(),
CgroupManager: ncdefaults.CgroupManager(),
InsecureRegistry: false,
HostsDir: ncdefaults.HostsDirs(),
Debug: false,
DebugFull: false,
Address: defaults.DefaultAddress,
Namespace: namespaces.Default,
Snapshotter: containerd.DefaultSnapshotter,
CNIPath: ncdefaults.CNIPath(),
CNINetConfPath: ncdefaults.CNINetConfPath(),
DataRoot: ncdefaults.DataRoot(),
CgroupManager: ncdefaults.CgroupManager(),
InsecureRegistry: false,
HostsDir: ncdefaults.HostsDirs(),
DefaultNetworkName: ncdefaults.DefaultNetworkName,
}
}

Expand Down Expand Up @@ -152,6 +154,7 @@ func initRootCmdFlags(rootCmd *cobra.Command, tomlPath string) error {
rootCmd.PersistentFlags().Bool("insecure-registry", cfg.InsecureRegistry, "skips verifying HTTPS certs, and allows falling back to plain HTTP")
// hosts-dir is defined as StringSlice, not StringArray, to allow specifying "--hosts-dir=/etc/containerd/certs.d,/etc/docker/certs.d"
rootCmd.PersistentFlags().StringSlice("hosts-dir", cfg.HostsDir, "A directory that contains <HOST:PORT>/hosts.toml (containerd style) or <HOST:PORT>/{ca.cert, cert.pem, key.pem} (docker style)")
rootCmd.PersistentFlags().String("default-network-name", cfg.DefaultNetworkName, "Default network name")
return nil
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/nerdctl/network_rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"os"

"github.com/containerd/nerdctl/pkg/defaults"
"github.com/containerd/nerdctl/pkg/lockutil"
"github.com/containerd/nerdctl/pkg/netutil"

Expand Down Expand Up @@ -88,6 +89,6 @@ func networkRmAction(cmd *cobra.Command, args []string) error {

func networkRmShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// show network names, including "bridge"
exclude := []string{netutil.DefaultNetworkName, "host", "none"}
exclude := []string{defaults.DefaultNetworkName, "host", "none"}
return shellCompleteNetworkNames(cmd, exclude)
}
6 changes: 2 additions & 4 deletions cmd/nerdctl/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import (
"github.com/containerd/nerdctl/pkg/logging"
"github.com/containerd/nerdctl/pkg/mountutil"
"github.com/containerd/nerdctl/pkg/namestore"
"github.com/containerd/nerdctl/pkg/netutil"
"github.com/containerd/nerdctl/pkg/platformutil"
"github.com/containerd/nerdctl/pkg/referenceutil"
"github.com/containerd/nerdctl/pkg/strutil"
Expand Down Expand Up @@ -93,7 +92,6 @@ func newRunCommand() *cobra.Command {
}

func setCreateFlags(cmd *cobra.Command) {

// No "-h" alias for "--help", because "-h" for "--hostname".
cmd.Flags().Bool("help", false, "show help")

Expand Down Expand Up @@ -121,11 +119,11 @@ func setCreateFlags(cmd *cobra.Command) {

// #region network flags
// network (net) is defined as StringSlice, not StringArray, to allow specifying "--network=cni1,cni2"
cmd.Flags().StringSlice("network", []string{netutil.DefaultNetworkName}, `Connect a container to a network ("bridge"|"host"|"none"|<CNI>)`)
cmd.Flags().StringSlice("network", []string{defaults.DefaultNetworkName}, `Connect a container to a network ("bridge"|"host"|"none"|<CNI>)`)
cmd.RegisterFlagCompletionFunc("network", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return shellCompleteNetworkNames(cmd, []string{})
})
cmd.Flags().StringSlice("net", []string{netutil.DefaultNetworkName}, `Connect a container to a network ("bridge"|"host"|"none"|<CNI>)`)
cmd.Flags().StringSlice("net", []string{defaults.DefaultNetworkName}, `Connect a container to a network ("bridge"|"host"|"none"|<CNI>)`)
cmd.RegisterFlagCompletionFunc("net", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return shellCompleteNetworkNames(cmd, []string{})
})
Expand Down
10 changes: 9 additions & 1 deletion cmd/nerdctl/run_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,19 @@ func getNetworkSlice(cmd *cobra.Command) ([]string, error) {
}

if !networkSet {
globalDefaultNetworkName, err := cmd.Flags().GetString("default-network-name")
if err != nil {
return nil, err
}
network, err := cmd.Flags().GetStringSlice("network")
if err != nil {
return nil, err
}
netSlice = append(netSlice, network...)
if globalDefaultNetworkName != "" {
netSlice = append(netSlice, globalDefaultNetworkName)
} else {
netSlice = append(netSlice, network...)
}
}
return netSlice, nil
}
Expand Down
82 changes: 82 additions & 0 deletions cmd/nerdctl/run_network_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
package main

import (
"bufio"
"fmt"
"io"
"net"
"os"
"path/filepath"
"regexp"
"strings"
"testing"

ncdefaults "github.com/containerd/nerdctl/pkg/defaults"
"github.com/containerd/nerdctl/pkg/rootlessutil"
"github.com/containerd/nerdctl/pkg/testutil"
"github.com/containerd/nerdctl/pkg/testutil/nettestutil"
Expand Down Expand Up @@ -467,3 +471,81 @@ func TestRunContainerWithStaticIP(t *testing.T) {
})
}
}
func TestRunWithDefaultNetworkInConfig(t *testing.T) {
testutil.DockerIncompatible(t)
tomlPath := ncdefaults.NerdctlTOML()
defer func(name string) {
_ = os.Remove(name)
}(tomlPath)
networkName := "test-network"
networkSubnet := "172.0.0.0/16"
base := testutil.NewBase(t)
cmd := base.Cmd("network", "create", networkName, "--subnet", networkSubnet)
cmd.AssertOK()
defer base.Cmd("network", "rm", networkName).Run()
directory := filepath.Dir(tomlPath)
if _, err := os.Stat(directory); os.IsNotExist(err) {
_ = os.MkdirAll(directory, 0755)
}
fp, err := os.OpenFile(tomlPath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0777)
if err != nil {
t.Fatal(err)
}
w := bufio.NewWriter(fp)
if _, err := w.Write([]byte(fmt.Sprintf("default_network_name = \"%s\"", networkName))); err != nil {
t.Fatal(err)
}
_ = w.Flush()
testContainerName := "test-default-container"
defer base.Cmd("rm", "-f", testContainerName).Run()
args := []string{
"run", "-d", "--name", testContainerName,
}
args = append(args, []string{testutil.NginxAlpineImage}...)
cmd = base.Cmd(args...)
cmd.AssertOK()
inspectCmd := base.Cmd("inspect", testContainerName, "--format", "\"{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\"")
result := inspectCmd.Run()
stdoutContent := result.Stdout() + result.Stderr()
assert.Assert(inspectCmd.Base.T, result.ExitCode == 0, stdoutContent)
_, ipNet, err := net.ParseCIDR(networkSubnet)
if err != nil {
t.Fatal(err)
}
stdoutContent = strings.Replace(strings.Replace(stdoutContent, "\n", "", -1), `"`, "", -1)
ip := net.ParseIP(stdoutContent)
assert.Equal(t, ipNet.Contains(ip), true)
}

func TestRunWithDefaultNetworkInCLI(t *testing.T) {
testutil.DockerIncompatible(t)
tomlPath := ncdefaults.NerdctlTOML()
defer func(name string) {
_ = os.Remove(name)
}(tomlPath)
networkName := "test-network"
networkSubnet := "172.0.0.0/16"
base := testutil.NewBase(t)
cmd := base.Cmd("network", "create", networkName, "--subnet", networkSubnet)
cmd.AssertOK()
defer base.Cmd("network", "rm", networkName).Run()
testContainerName := "test-default-container"
defer base.Cmd("rm", "-f", testContainerName).Run()
args := []string{
"--default-network-name", networkName, "run", "-d", "--name", testContainerName,
}
args = append(args, []string{testutil.NginxAlpineImage}...)
cmd = base.Cmd(args...)
cmd.AssertOK()
inspectCmd := base.Cmd("inspect", testContainerName, "--format", "\"{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\"")
result := inspectCmd.Run()
stdoutContent := result.Stdout() + result.Stderr()
assert.Assert(inspectCmd.Base.T, result.ExitCode == 0, stdoutContent)
_, ipNet, err := net.ParseCIDR(networkSubnet)
if err != nil {
t.Fatal(err)
}
stdoutContent = strings.Replace(strings.Replace(stdoutContent, "\n", "", -1), `"`, "", -1)
ip := net.ParseIP(stdoutContent)
assert.Equal(t, ipNet.Contains(ip), true)
}
27 changes: 14 additions & 13 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,20 @@ hosts_dir = ["/etc/containerd/certs.d", "/etc/docker/certs.d"]

## Properties

| TOML property | CLI flag | Env var | Description | Availability \*1 |
|---------------------|------------------------------------|---------------------------|-------------------------------|------------------|
| `debug` | `--debug` | | Debug mode | Since 0.16.0 |
| `debug_full` | `--debug-full` | | Debug mode (with full output) | Since 0.16.0 |
| `address` | `--address`,`--host`,`-a`,`-H` | `$CONTAINERD_ADDRESS` | containerd address | Since 0.16.0 |
| `namespace` | `--namespace`,`-n` | `$CONTAINERD_NAMESPACE` | containerd namespace | Since 0.16.0 |
| `snapshotter` | `--snapshotter`,`--storage-driver` | `$CONTAINERD_SNAPSHOTTER` | containerd snapshotter | Since 0.16.0 |
| `cni_path` | `--cni-path` | `$CNI_PATH` | CNI binary directory | Since 0.16.0 |
| `cni_netconfpath` | `--cni-netconfpath` | `$NETCONFPATH` | CNI config directory | Since 0.16.0 |
| `data_root` | `--data-root` | | Persistent state directory | Since 0.16.0 |
| `cgroup_manager` | `--cgroup-manager` | | cgroup manager | Since 0.16.0 |
| `insecure_registry` | `--insecure-registry` | | Allow insecure registry | Since 0.16.0 |
| `hosts_dir` | `--hosts-dir` | | `certs.d` directory | Since 0.16.0 |
| TOML property | CLI flag | Env var | Description | Availability \*1 |
|------------------------|------------------------------------|---------------------------|-------------------------------|------------------|
| `debug` | `--debug` | | Debug mode | Since 0.16.0 |
| `debug_full` | `--debug-full` | | Debug mode (with full output) | Since 0.16.0 |
| `address` | `--address`,`--host`,`-a`,`-H` | `$CONTAINERD_ADDRESS` | containerd address | Since 0.16.0 |
| `namespace` | `--namespace`,`-n` | `$CONTAINERD_NAMESPACE` | containerd namespace | Since 0.16.0 |
| `snapshotter` | `--snapshotter`,`--storage-driver` | `$CONTAINERD_SNAPSHOTTER` | containerd snapshotter | Since 0.16.0 |
| `cni_path` | `--cni-path` | `$CNI_PATH` | CNI binary directory | Since 0.16.0 |
| `cni_netconfpath` | `--cni-netconfpath` | `$NETCONFPATH` | CNI config directory | Since 0.16.0 |
| `data_root` | `--data-root` | | Persistent state directory | Since 0.16.0 |
| `cgroup_manager` | `--cgroup-manager` | | cgroup manager | Since 0.16.0 |
| `insecure_registry` | `--insecure-registry` | | Allow insecure registry | Since 0.16.0 |
| `hosts_dir` | `--hosts-dir` | | `certs.d` directory | Since 0.16.0 |
| `default_network_name` | `--default-network-name` | | Default network name | Since 0.21.1 |

The properties are parsed in the following precedence:
1. CLI flag
Expand Down
24 changes: 24 additions & 0 deletions pkg/defaults/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Copyright The containerd Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package defaults

const (
DefaultNetworkName = "bridge"
DefaultID = 0
DefaultCIDR = "10.4.0.0/24"
DefaultIPAMDriver = "host-local"
)
4 changes: 2 additions & 2 deletions pkg/dnsutil/hostsstore/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"strings"

"github.com/containerd/containerd/errdefs"
"github.com/containerd/nerdctl/pkg/netutil"
"github.com/containerd/nerdctl/pkg/defaults"
"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -190,7 +190,7 @@ func createLine(thatNetwork string, meta *Meta, myNetworks map[string]struct{})

for _, baseHostname := range baseHostnames {
line = append(line, baseHostname)
if thatNetwork != netutil.DefaultNetworkName {
if thatNetwork != defaults.DefaultNetworkName {
// Do not add a entry like "foo.bridge"
line = append(line, baseHostname+"."+thatNetwork)
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/netutil/netutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"strings"

"github.com/containerd/containerd/errdefs"
"github.com/containerd/nerdctl/pkg/defaults"
"github.com/containerd/nerdctl/pkg/strutil"
"github.com/containernetworking/cni/libcni"
)
Expand Down Expand Up @@ -133,9 +134,9 @@ func (e *CNIEnv) WriteNetworkConfig(net *networkConfig) error {
}

func (e *CNIEnv) ensureDefaultNetworkConfig() error {
ipam, _ := GenerateIPAM("default", DefaultCIDR, "", "", nil)
plugins, _ := e.GenerateCNIPlugins(DefaultNetworkName, DefaultID, DefaultNetworkName, ipam, nil)
conf, err := e.GenerateNetworkConfig(nil, DefaultID, DefaultNetworkName, plugins)
ipam, _ := GenerateIPAM("default", defaults.DefaultCIDR, "", "", nil)
plugins, _ := e.GenerateCNIPlugins(defaults.DefaultNetworkName, defaults.DefaultID, defaults.DefaultNetworkName, ipam, nil)
conf, err := e.GenerateNetworkConfig(nil, defaults.DefaultID, defaults.DefaultNetworkName, plugins)
if err != nil {
return err
}
Expand Down Expand Up @@ -183,7 +184,7 @@ func (e *CNIEnv) networkConfigList() ([]*networkConfig, error) {

// AcquireNextID suggests the next ID.
func (e *CNIEnv) AcquireNextID() (int, error) {
maxID := DefaultID
maxID := defaults.DefaultID
for _, n := range e.Networks {
if n.NerdctlID != nil && *n.NerdctlID > maxID {
maxID = *n.NerdctlID
Expand Down
13 changes: 3 additions & 10 deletions pkg/netutil/netutil_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ import (
"github.com/sirupsen/logrus"
)

const (
DefaultNetworkName = "bridge"
DefaultID = 0
DefaultCIDR = "10.4.0.0/24"
DefaultIPAMDriver = "host-local"
)

func (e *CNIEnv) GenerateCNIPlugins(driver string, id int, name string, ipam map[string]interface{}, opts map[string]string) ([]CNIPlugin, error) {
var (
plugins []CNIPlugin
Expand Down Expand Up @@ -147,21 +140,21 @@ func fixUpIsolation(e *CNIEnv, name string, plugins []CNIPlugin) []CNIPlugin {
isolationPath := filepath.Join(e.Path, "isolation")
if _, err := exec.LookPath(isolationPath); err == nil {
// the warning is suppressed for DefaultNetworkName (because multi-bridge networking is not involved)
if name != DefaultNetworkName {
if name != defaults.DefaultNetworkName {
logrus.Warnf(`network %q: Using the deprecated CNI "isolation" plugin instead of CNI "firewall" plugin (>= 1.1.0) ingressPolicy.
To dismiss this warning, uninstall %q and install CNI "firewall" plugin (>= 1.1.0) from https://github.com/containernetworking/plugins`,
name, isolationPath)
}
plugins = append(plugins, newIsolationPlugin())
for _, f := range plugins {
if x, ok := f.(*firewallConfig); ok {
if name != DefaultNetworkName {
if name != defaults.DefaultNetworkName {
logrus.Warnf("network %q: Unsetting firewall ingressPolicy %q (because using the deprecated \"isolation\" plugin)", name, x.IngressPolicy)
}
x.IngressPolicy = ""
}
}
} else if name != DefaultNetworkName {
} else if name != defaults.DefaultNetworkName {
firewallPath := filepath.Join(e.Path, "firewall")
ok, err := firewallPluginGEQ110(firewallPath)
if err != nil {
Expand Down