Skip to content

Commit 57b2e04

Browse files
authored
Merge pull request #926 from Zheaoli/manjusaka/support-852
Support assign static IP address in `compose up` by using ipv4_address field
2 parents 1aaf6a9 + 0c334bd commit 57b2e04

File tree

3 files changed

+70
-7
lines changed

3 files changed

+70
-7
lines changed

cmd/nerdctl/compose_up_linux_test.go

+43
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import (
2424
"testing"
2525
"time"
2626

27+
"github.com/containerd/nerdctl/pkg/rootlessutil"
2728
"github.com/docker/go-connections/nat"
29+
"github.com/sirupsen/logrus"
2830

2931
"github.com/containerd/nerdctl/pkg/testutil"
3032
"github.com/containerd/nerdctl/pkg/testutil/nettestutil"
@@ -154,6 +156,47 @@ COPY index.html /usr/share/nginx/html/index.html
154156
assert.Assert(t, strings.Contains(string(respBody), indexHTML))
155157
}
156158

159+
func TestComposeUpNetWithStaticIP(t *testing.T) {
160+
if rootlessutil.IsRootless() {
161+
t.Skip("Static IP assignment is not supported rootless mode yet.")
162+
}
163+
base := testutil.NewBase(t)
164+
staticIP := "172.20.0.12"
165+
var dockerComposeYAML = fmt.Sprintf(`
166+
version: '3.1'
167+
168+
services:
169+
svc0:
170+
image: %s
171+
networks:
172+
net0:
173+
ipv4_address: %s
174+
175+
networks:
176+
net0:
177+
ipam:
178+
config:
179+
- subnet: 172.20.0.0/24
180+
`, testutil.NginxAlpineImage, staticIP)
181+
comp := testutil.NewComposeDir(t, dockerComposeYAML)
182+
defer comp.CleanUp()
183+
projectName := comp.ProjectName()
184+
t.Logf("projectName=%q", projectName)
185+
base.ComposeCmd("-f", comp.YAMLFullPath(), "up", "-d").AssertOK()
186+
defer base.ComposeCmd("-f", comp.YAMLFullPath(), "down", "-v").Run()
187+
188+
svc0 := fmt.Sprintf("%s_svc0_1", projectName)
189+
inspectCmd := base.Cmd("inspect", svc0, "--format", "\"{{range .NetworkSettings.Networks}} {{.IPAddress}}{{end}}\"")
190+
result := inspectCmd.Run()
191+
stdoutContent := result.Stdout() + result.Stderr()
192+
assert.Assert(inspectCmd.Base.T, result.ExitCode == 0, stdoutContent)
193+
if !strings.Contains(stdoutContent, staticIP) {
194+
logrus.Errorf("test failed, the actual container ip is %s", stdoutContent)
195+
t.Fail()
196+
return
197+
}
198+
}
199+
157200
func TestComposeUpMultiNet(t *testing.T) {
158201
base := testutil.NewBase(t)
159202

cmd/nerdctl/run_network_linux_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ func TestRunContainerWithStaticIP(t *testing.T) {
458458
inspectCmd := base.Cmd("inspect", testContainerName, "--format", "\"{{range .NetworkSettings.Networks}} {{.IPAddress}}{{end}}\"")
459459
result := inspectCmd.Run()
460460
stdoutContent := result.Stdout() + result.Stderr()
461-
assert.Assert(cmd.Base.T, result.ExitCode == 0, stdoutContent)
461+
assert.Assert(inspectCmd.Base.T, result.ExitCode == 0, stdoutContent)
462462
if !strings.Contains(stdoutContent, tc.ip) {
463463
t.Fail()
464464
return

pkg/composer/serviceparser/serviceparser.go

+26-6
Original file line numberDiff line numberDiff line change
@@ -320,16 +320,25 @@ func getRestart(svc compose.ServiceConfig) (string, error) {
320320
return restartFlag, nil
321321
}
322322

323+
type networkNamePair struct {
324+
shortNetworkName string
325+
fullName string
326+
}
327+
323328
// getNetworks returns full network names, e.g., {"compose-wordpress_default"}, or {"host"}
324-
func getNetworks(project *compose.Project, svc compose.ServiceConfig) ([]string, error) {
325-
var fullNames []string // nolint: prealloc
329+
func getNetworks(project *compose.Project, svc compose.ServiceConfig) ([]networkNamePair, error) {
330+
var fullNames []networkNamePair // nolint: prealloc
326331

327332
if svc.Net != "" {
328333
logrus.Warn("net is deprecated, use network_mode or networks")
329334
if len(svc.Networks) > 0 {
330335
return nil, errors.New("networks and net must not be set together")
331336
}
332-
fullNames = append(fullNames, svc.Net)
337+
338+
fullNames = append(fullNames, networkNamePair{
339+
fullName: svc.Net,
340+
shortNetworkName: "",
341+
})
333342
}
334343

335344
if svc.NetworkMode != "" {
@@ -342,15 +351,21 @@ func getNetworks(project *compose.Project, svc compose.ServiceConfig) ([]string,
342351
if strings.Contains(svc.NetworkMode, ":") {
343352
return nil, fmt.Errorf("unsupported network_mode: %q", svc.NetworkMode)
344353
}
345-
fullNames = append(fullNames, svc.NetworkMode)
354+
fullNames = append(fullNames, networkNamePair{
355+
fullName: svc.NetworkMode,
356+
shortNetworkName: "",
357+
})
346358
}
347359

348360
for shortName := range svc.Networks {
349361
net, ok := project.Networks[shortName]
350362
if !ok {
351363
return nil, fmt.Errorf("invalid network %q", shortName)
352364
}
353-
fullNames = append(fullNames, net.Name)
365+
fullNames = append(fullNames, networkNamePair{
366+
fullName: net.Name,
367+
shortNetworkName: shortName,
368+
})
354369
}
355370

356371
return fullNames, nil
@@ -514,7 +529,12 @@ func newContainer(project *compose.Project, parsed *Service, i int) (*Container,
514529
return nil, err
515530
} else {
516531
for _, net := range networks {
517-
c.RunArgs = append(c.RunArgs, "--net="+net)
532+
c.RunArgs = append(c.RunArgs, "--net="+net.fullName)
533+
if value, ok := svc.Networks[net.shortNetworkName]; ok {
534+
if value != nil && value.Ipv4Address != "" {
535+
c.RunArgs = append(c.RunArgs, "--ip="+value.Ipv4Address)
536+
}
537+
}
518538
}
519539
}
520540

0 commit comments

Comments
 (0)