diff --git a/cmd/finch/nerdctl.go b/cmd/finch/nerdctl.go index 38ead302d..bf3abfc59 100644 --- a/cmd/finch/nerdctl.go +++ b/cmd/finch/nerdctl.go @@ -9,6 +9,9 @@ import ( "path/filepath" "strings" + dockerops "github.com/docker/docker/opts" + "github.com/lima-vm/lima/pkg/networks" + "github.com/spf13/afero" "github.com/spf13/cobra" @@ -102,7 +105,6 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { if addEnv != "" { envs = append(envs, addEnv) } - case strings.HasPrefix(arg, "--env-file"): shouldSkip, addEnvs, err := handleEnvFile(nc.fs, nc.systemDeps, arg, args[i+1]) if err != nil { @@ -110,6 +112,9 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { } skip = shouldSkip fileEnvs = append(fileEnvs, addEnvs...) + case arg == "--add-host": + args[i+1] = resolveIP(args[i+1], nc.logger) + nerdctlArgs = append(nerdctlArgs, arg) default: nerdctlArgs = append(nerdctlArgs, arg) } @@ -273,6 +278,19 @@ func handleEnvFile(fs afero.Fs, systemDeps NerdctlCommandSystemDeps, arg, arg2 s return skip, envs, nil } +func resolveIP(host string, logger flog.Logger) string { + parts := strings.SplitN(host, ":", 2) + // If the IP Address is a string called "host-gateway", replace this value with the IP address that can be used to + // access host from the containers. + // TODO: make the host gateway ip configurable. + if parts[1] == dockerops.HostGatewayName { + resolvedIP := networks.SlirpGateway + logger.Debugf(`Resolving special IP "host-gateway" to %q for host %q`, resolvedIP, parts[0]) + return fmt.Sprintf("%s:%s", parts[0], resolvedIP) + } + return host +} + var nerdctlCmds = map[string]string{ "build": "Build an image from Dockerfile", "builder": "Manage builds", diff --git a/cmd/finch/nerdctl_test.go b/cmd/finch/nerdctl_test.go index bd45c94e4..a4313dc80 100644 --- a/cmd/finch/nerdctl_test.go +++ b/cmd/finch/nerdctl_test.go @@ -336,6 +336,76 @@ func TestNerdctlCommand_run(t *testing.T) { logger.EXPECT().Debugf("Status of virtual machine: %s", "Running") }, }, + { + name: "with --add-host flag and special IP", + cmdName: "run", + args: []string{"--rm", "--add-host", "name:host-gateway", "alpine:latest"}, + wantErr: nil, + mockSvc: func( + t *testing.T, + lcc *mocks.LimaCmdCreator, + ncsd *mocks.NerdctlCommandSystemDeps, + logger *mocks.Logger, + ctrl *gomock.Controller, + fs afero.Fs, + ) { + getVMStatusC := mocks.NewCommand(ctrl) + lcc.EXPECT().CreateWithoutStdio("ls", "-f", "{{.Status}}", limaInstanceName).Return(getVMStatusC) + getVMStatusC.EXPECT().Output().Return([]byte("Running"), nil) + logger.EXPECT().Debugf("Status of virtual machine: %s", "Running") + logger.EXPECT().Debugf(`Resolving special IP "host-gateway" to %q for host %q`, "192.168.5.2", "name") + c := mocks.NewCommand(ctrl) + lcc.EXPECT().Create("shell", limaInstanceName, nerdctlCmdName, "run", + "--rm", "--add-host", "name:192.168.5.2", "alpine:latest").Return(c) + c.EXPECT().Run() + }, + }, + { + name: "with --add-host flag but without using special IP", + cmdName: "run", + args: []string{"--rm", "--add-host", "name:0.0.0.0", "alpine:latest"}, + wantErr: nil, + mockSvc: func( + t *testing.T, + lcc *mocks.LimaCmdCreator, + ncsd *mocks.NerdctlCommandSystemDeps, + logger *mocks.Logger, + ctrl *gomock.Controller, + fs afero.Fs, + ) { + getVMStatusC := mocks.NewCommand(ctrl) + lcc.EXPECT().CreateWithoutStdio("ls", "-f", "{{.Status}}", limaInstanceName).Return(getVMStatusC) + getVMStatusC.EXPECT().Output().Return([]byte("Running"), nil) + logger.EXPECT().Debugf("Status of virtual machine: %s", "Running") + c := mocks.NewCommand(ctrl) + lcc.EXPECT().Create("shell", limaInstanceName, nerdctlCmdName, "run", + "--rm", "--add-host", "name:0.0.0.0", "alpine:latest").Return(c) + c.EXPECT().Run() + }, + }, + { + name: "with --add-host flag but without subsequent arg", + cmdName: "run", + args: []string{"--rm", "--add-host", "alpine:latest"}, + wantErr: errors.New("run cmd error"), + mockSvc: func( + t *testing.T, + lcc *mocks.LimaCmdCreator, + ncsd *mocks.NerdctlCommandSystemDeps, + logger *mocks.Logger, + ctrl *gomock.Controller, + fs afero.Fs, + ) { + getVMStatusC := mocks.NewCommand(ctrl) + lcc.EXPECT().CreateWithoutStdio("ls", "-f", "{{.Status}}", limaInstanceName).Return(getVMStatusC) + getVMStatusC.EXPECT().Output().Return([]byte("Running"), nil) + logger.EXPECT().Debugf("Status of virtual machine: %s", "Running") + c := mocks.NewCommand(ctrl) + lcc.EXPECT().Create("shell", limaInstanceName, nerdctlCmdName, "run", + "--rm", "--add-host", "alpine:latest").Return(c) + c.EXPECT().Run().Return(errors.New("run cmd error")) + }, + }, { name: "with --help flag", cmdName: "pull", diff --git a/e2e/container/container_test.go b/e2e/container/container_test.go index b9931f260..db4f463ef 100644 --- a/e2e/container/container_test.go +++ b/e2e/container/container_test.go @@ -39,7 +39,7 @@ func TestContainer(t *testing.T) { tests.Pull(o) tests.Rm(o) tests.Rmi(o) - tests.Run(&tests.RunOption{BaseOpt: o, CGMode: tests.Unified}) + tests.Run(&tests.RunOption{BaseOpt: o, CGMode: tests.Unified, DefaultHostGatewayIP: "192.168.5.2"}) tests.Start(o) tests.Stop(o) tests.Cp(o) diff --git a/go.mod b/go.mod index 9371f4af7..795777f82 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/runfinch/finch go 1.18 require ( + github.com/docker/docker v23.0.1+incompatible github.com/golang/mock v1.6.0 github.com/google/go-licenses v1.6.0 github.com/lima-vm/lima v0.14.2 @@ -10,7 +11,7 @@ require ( github.com/onsi/gomega v1.26.0 github.com/pelletier/go-toml v1.9.5 github.com/pkg/sftp v1.13.5 - github.com/runfinch/common-tests v0.4.0 + github.com/runfinch/common-tests v0.5.0 github.com/sirupsen/logrus v1.9.0 github.com/spf13/afero v1.9.3 github.com/spf13/cobra v1.6.1 @@ -27,11 +28,14 @@ require ( github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/containerd/containerd v1.6.14 // indirect github.com/containers/gvisor-tap-vsock v0.4.1-0.20220920072955-5b1aff8ba743 // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f // indirect github.com/miekg/dns v1.1.50 // indirect + github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect golang.org/x/sync v0.1.0 // indirect diff --git a/go.sum b/go.sum index 164360a8c..1fa05ad75 100644 --- a/go.sum +++ b/go.sum @@ -155,6 +155,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY= +github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -220,6 +224,7 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -458,6 +463,8 @@ github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdM github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= +github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc90/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -502,8 +509,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/runfinch/common-tests v0.4.0 h1:MOtkY/Wcg3hEILDWcaA4cK/NXmk9vUS4y0yOdlIm2Cw= -github.com/runfinch/common-tests v0.4.0/go.mod h1:8Kjz5W85nbSzFCI0NEnwoPMDvTeCm/JutQAEVFMJP/I= +github.com/runfinch/common-tests v0.5.0 h1:ihYdYKLuXEZR0aYT2hbgfUffn5x2IgSRjItDUhyTj1I= +github.com/runfinch/common-tests v0.5.0/go.mod h1:8Kjz5W85nbSzFCI0NEnwoPMDvTeCm/JutQAEVFMJP/I= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=