Skip to content

Commit 1a627e3

Browse files
enable host name and default resolv.conf and hosts file in none network
Signed-off-by: Shubharanshu Mahapatra <[email protected]>
1 parent b17673d commit 1a627e3

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

cmd/nerdctl/container/container_run_network_linux_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"time"
3030

3131
"github.com/containernetworking/plugins/pkg/ns"
32+
"github.com/stretchr/testify/require"
3233
"github.com/vishvananda/netlink"
3334
"gotest.tools/v3/assert"
3435
"gotest.tools/v3/icmd"
@@ -504,6 +505,37 @@ func TestSharedNetworkStack(t *testing.T) {
504505
AssertOutContains(testutil.NginxAlpineIndexHTMLSnippet)
505506
}
506507

508+
func TestSharedNetworkWithNone(t *testing.T) {
509+
if runtime.GOOS != "linux" {
510+
t.Skip("--network=container:<container name|id> only supports linux now")
511+
}
512+
base := testutil.NewBase(t)
513+
514+
containerName := testutil.Identifier(t)
515+
defer base.Cmd("rm", "-f", containerName).AssertOK()
516+
base.Cmd("run", "-d", "--name", containerName, "--network", "none",
517+
testutil.NginxAlpineImage).AssertOK()
518+
base.EnsureContainerStarted(containerName)
519+
520+
containerNameJoin := testutil.Identifier(t) + "-network"
521+
defer base.Cmd("rm", "-f", containerNameJoin).AssertOK()
522+
base.Cmd("run",
523+
"-d",
524+
"--name", containerNameJoin,
525+
"--network=container:"+containerName,
526+
testutil.CommonImage,
527+
"sleep", "infinity").AssertOK()
528+
529+
base.Cmd("exec", containerNameJoin, "wget", "-qO-", "http://127.0.0.1:80").
530+
AssertOutContains(testutil.NginxAlpineIndexHTMLSnippet)
531+
532+
base.Cmd("restart", containerName).AssertOK()
533+
base.Cmd("stop", "--time=1", containerNameJoin).AssertOK()
534+
base.Cmd("start", containerNameJoin).AssertOK()
535+
base.Cmd("exec", containerNameJoin, "wget", "-qO-", "http://127.0.0.1:80").
536+
AssertOutContains(testutil.NginxAlpineIndexHTMLSnippet)
537+
}
538+
507539
func TestRunContainerInExistingNetNS(t *testing.T) {
508540
if rootlessutil.IsRootless() {
509541
t.Skip("Can't create new netns in rootless mode")
@@ -629,6 +661,8 @@ func TestHostsFileMounts(t *testing.T) {
629661
"sh", "-euxc", "echo >> /etc/hosts").AssertOK()
630662
base.Cmd("run", "--rm", "-v", "/etc/hosts:/etc/hosts", "--network", "host", testutil.CommonImage,
631663
"sh", "-euxc", "head -n -1 /etc/hosts > temp && cat temp > /etc/hosts").AssertOK()
664+
base.Cmd("run", "--rm", "--network", "none", testutil.CommonImage,
665+
"sh", "-euxc", "echo >> /etc/hosts").AssertOK()
632666

633667
base.Cmd("run", "--rm", testutil.CommonImage,
634668
"sh", "-euxc", "echo >> /etc/resolv.conf").AssertOK()
@@ -641,6 +675,8 @@ func TestHostsFileMounts(t *testing.T) {
641675
"sh", "-euxc", "echo >> /etc/resolv.conf").AssertOK()
642676
base.Cmd("run", "--rm", "-v", "/etc/resolv.conf:/etc/resolv.conf", "--network", "host", testutil.CommonImage,
643677
"sh", "-euxc", "head -n -1 /etc/resolv.conf > temp && cat temp > /etc/resolv.conf").AssertOK()
678+
base.Cmd("run", "--rm", "--network", "host", testutil.CommonImage,
679+
"sh", "-euxc", "echo >> /etc/resolv.conf").AssertOK()
644680
}
645681

646682
func TestRunContainerWithStaticIP6(t *testing.T) {
@@ -712,3 +748,41 @@ func TestRunContainerWithStaticIP6(t *testing.T) {
712748
})
713749
}
714750
}
751+
752+
func TestNoneNetworkStaticConfigs(t *testing.T) {
753+
base := testutil.NewBase(t)
754+
755+
cmd := base.Cmd("run", "--rm", "--net", "none", testutil.CommonImage, "cat", "/etc/hosts")
756+
cmd.AssertOutContains("127.0.0.1 localhost")
757+
cmd.AssertOutContains("::1 localhost")
758+
759+
cmd = base.Cmd("run", "--rm", "--net", "none", testutil.CommonImage, "cat", "/etc/resolv.conf")
760+
cmd.AssertOutContains("nameserver 127.0.0.1")
761+
762+
// If running on Linux, verify /etc/hostname is correctly set
763+
if runtime.GOOS == "linux" {
764+
containerHostName := "testcontainer"
765+
cmd := base.Cmd("run", "--rm", "--net", "none", "--hostname", containerHostName, testutil.CommonImage, "cat", "/etc/hostname")
766+
output := cmd.Run().Combined()
767+
hostname := strings.TrimSpace(output)
768+
769+
if len(containerHostName) > 12 {
770+
require.Equal(t, containerHostName[:12], hostname)
771+
} else {
772+
require.Equal(t, containerHostName, hostname)
773+
}
774+
775+
containerName := "testNoneNetworkHostname"
776+
defer base.Cmd("rm", "-f", containerName).AssertOK()
777+
cmd = base.Cmd("run", "--d", "--net", "none", "--name", containerName, testutil.CommonImage, "sleep", "infinity")
778+
output = cmd.Run().Combined()
779+
containerIdShort := strings.TrimSpace(output)[:12]
780+
781+
cmd = base.Cmd("exec", containerName, "cat", "/etc/hostname")
782+
output = cmd.Run().Combined()
783+
containerHostName = strings.TrimSpace(output)
784+
785+
require.Equal(t, containerHostName, containerIdShort)
786+
787+
}
788+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ require (
6161
github.com/rootless-containers/rootlesskit/v2 v2.3.1
6262
github.com/spf13/cobra v1.8.1
6363
github.com/spf13/pflag v1.0.5
64+
github.com/stretchr/testify v1.9.0
6465
github.com/vishvananda/netlink v1.3.0
6566
github.com/vishvananda/netns v0.0.4
6667
github.com/yuchanns/srslog v1.1.0
@@ -87,6 +88,7 @@ require (
8788
github.com/containerd/plugin v0.1.0 // indirect
8889
github.com/containerd/ttrpc v1.2.6-0.20240827082320-b5cd6e4b3287 // indirect
8990
github.com/containers/ocicrypt v1.2.0 // indirect
91+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
9092
github.com/djherbis/times v1.6.0 // indirect
9193
github.com/docker/docker-credential-helpers v0.8.2 // indirect
9294
github.com/felixge/httpsnoop v1.0.4 // indirect
@@ -121,6 +123,7 @@ require (
121123
github.com/opencontainers/selinux v1.11.1 // indirect
122124
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect
123125
github.com/pkg/errors v0.9.1 // indirect
126+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
124127
github.com/sirupsen/logrus v1.9.3 // indirect
125128
github.com/spaolacci/murmur3 v1.1.0 // indirect
126129
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect

go.sum

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,9 @@ github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLy
289289
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M=
290290
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
291291
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
292-
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
293292
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
293+
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
294+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
294295
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
295296
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
296297
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=

pkg/containerutil/container_network_manager.go

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"github.com/containerd/nerdctl/v2/pkg/mountutil"
4343
"github.com/containerd/nerdctl/v2/pkg/netutil"
4444
"github.com/containerd/nerdctl/v2/pkg/netutil/nettype"
45+
"github.com/containerd/nerdctl/v2/pkg/resolvconf"
4546
"github.com/containerd/nerdctl/v2/pkg/rootlessutil"
4647
"github.com/containerd/nerdctl/v2/pkg/strutil"
4748
)
@@ -179,9 +180,68 @@ func (m *noneNetworkManager) InternalNetworkingOptionLabels(_ context.Context) (
179180

180181
// ContainerNetworkingOpts Returns a slice of `oci.SpecOpts` and `containerd.NewContainerOpts` which represent
181182
// the network specs which need to be applied to the container with the given ID.
182-
func (m *noneNetworkManager) ContainerNetworkingOpts(_ context.Context, _ string) ([]oci.SpecOpts, []containerd.NewContainerOpts, error) {
183+
func (m *noneNetworkManager) ContainerNetworkingOpts(_ context.Context, containerID string) ([]oci.SpecOpts, []containerd.NewContainerOpts, error) {
183184
// No options to return if no network settings are provided.
184-
return []oci.SpecOpts{}, []containerd.NewContainerOpts{}, nil
185+
dataStore, err := clientutil.DataStore(m.globalOptions.DataRoot, m.globalOptions.Address)
186+
if err != nil {
187+
return nil, nil, err
188+
}
189+
190+
stateDir, err := ContainerStateDirPath(m.globalOptions.Namespace, dataStore, containerID)
191+
if err != nil {
192+
return nil, nil, err
193+
}
194+
195+
resolvConfPath := filepath.Join(stateDir, "resolv.conf")
196+
dns := []string{"127.0.0.1"}
197+
dnsSearch := []string{}
198+
dnsOptions := []string{}
199+
200+
// Call the Build function
201+
_, err = resolvconf.Build(resolvConfPath, dns, dnsSearch, dnsOptions)
202+
if err != nil {
203+
return nil, nil, err
204+
}
205+
206+
hs, err := hostsstore.New(dataStore, m.globalOptions.Namespace)
207+
if err != nil {
208+
return nil, nil, err
209+
}
210+
211+
content := []byte(`127.0.0.1 localhost
212+
::1 localhost
213+
`)
214+
etcHostsPath, err := hs.AllocHostsFile(containerID, content)
215+
if err != nil {
216+
return nil, nil, err
217+
}
218+
219+
specs := []oci.SpecOpts{
220+
withDedupMounts("/etc/hosts", withCustomHosts(etcHostsPath)),
221+
withDedupMounts("/etc/resolv.conf", withCustomResolvConf(resolvConfPath)),
222+
}
223+
224+
// `/etc/hostname` does not exist on FreeBSD
225+
if runtime.GOOS == "linux" {
226+
// If no hostname is set, default to first 12 characters of the container ID.
227+
hostname := m.netOpts.Hostname
228+
if hostname == "" {
229+
hostname = containerID
230+
if len(hostname) > 12 {
231+
hostname = hostname[0:12]
232+
}
233+
}
234+
m.netOpts.Hostname = hostname
235+
236+
hostnameOpts, err := writeEtcHostnameForContainer(m.globalOptions, m.netOpts.Hostname, containerID)
237+
if err != nil {
238+
return nil, nil, err
239+
}
240+
if hostnameOpts != nil {
241+
specs = append(specs, hostnameOpts...)
242+
}
243+
}
244+
return specs, []containerd.NewContainerOpts{}, nil
185245
}
186246

187247
// types.NetworkOptionsManager implementation for container networking settings.

0 commit comments

Comments
 (0)