diff --git a/go.mod b/go.mod index 5a1156bc..06c621f7 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/go-git/go-git/v5 v5.2.0 github.com/go-ini/ini v1.62.0 github.com/golang/protobuf v1.4.3 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect github.com/imdario/mergo v0.3.11 // indirect github.com/joho/godotenv v1.3.0 @@ -29,6 +30,7 @@ require ( github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 github.com/sirupsen/logrus v1.7.0 github.com/spf13/cobra v1.1.1 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 github.com/xanzy/ssh-agent v0.3.0 // indirect golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect diff --git a/go.sum b/go.sum index ec6fb41b..d3d76739 100644 --- a/go.sum +++ b/go.sum @@ -461,6 +461,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/pkg/container/docker_run.go b/pkg/container/docker_run.go index 190ee052..8dde8589 100644 --- a/pkg/container/docker_run.go +++ b/pkg/container/docker_run.go @@ -52,6 +52,7 @@ type NewContainerInput struct { Privileged bool UsernsMode string Platform string + Hostname string } // FileEntry is a file to copy to a container @@ -302,6 +303,7 @@ func (cr *containerReference) create(capAdd []string, capDrop []string) common.E WorkingDir: input.WorkingDir, Env: input.Env, Tty: isTerminal, + Hostname: input.Hostname, } mounts := make([]mount.Mount, 0) diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index c736ed17..79e7d917 100755 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -11,6 +11,9 @@ import ( "runtime" "strings" + "github.com/google/shlex" + "github.com/spf13/pflag" + "github.com/mitchellh/go-homedir" log "github.com/sirupsen/logrus" @@ -96,6 +99,7 @@ func (rc *RunContext) GetBindsAndMounts() ([]string, map[string]string) { func (rc *RunContext) startJobContainer() common.Executor { image := rc.platformImage() + hostname := rc.hostname() return func(ctx context.Context) error { rawLogger := common.Logger(ctx).WithField("raw_output", true) @@ -136,6 +140,7 @@ func (rc *RunContext) startJobContainer() common.Executor { Privileged: rc.Config.Privileged, UsernsMode: rc.Config.UsernsMode, Platform: rc.Config.ContainerArchitecture, + Hostname: hostname, }) var copyWorkspace bool @@ -304,6 +309,28 @@ func (rc *RunContext) platformImage() string { return "" } +func (rc *RunContext) hostname() string { + job := rc.Run.Job() + c := job.Container() + if c == nil { + return "" + } + + optionsFlags := pflag.NewFlagSet("container_options", pflag.ContinueOnError) + hostname := optionsFlags.StringP("hostname", "h", "", "") + optionsArgs, err := shlex.Split(c.Options) + if err != nil { + log.Warnf("Cannot parse container options: %s", c.Options) + return "" + } + err = optionsFlags.Parse(optionsArgs) + if err != nil { + log.Warnf("Cannot parse container options: %s", c.Options) + return "" + } + return *hostname +} + func (rc *RunContext) isEnabled(ctx context.Context) bool { job := rc.Run.Job() l := common.Logger(ctx) diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 85245c99..d0e8fe50 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -103,6 +103,7 @@ func TestRunEvent(t *testing.T) { {"testdata", "shells/sh", "push", "", platforms, ""}, {"testdata", "job-container", "push", "", platforms, ""}, {"testdata", "job-container-non-root", "push", "", platforms, ""}, + {"testdata", "container-hostname", "push", "", platforms, ""}, {"testdata", "uses-docker-url", "push", "", platforms, ""}, {"testdata", "remote-action-docker", "push", "", platforms, ""}, {"testdata", "remote-action-js", "push", "", platforms, ""}, diff --git a/pkg/runner/testdata/container-hostname/push.yml b/pkg/runner/testdata/container-hostname/push.yml new file mode 100644 index 00000000..ab055cb2 --- /dev/null +++ b/pkg/runner/testdata/container-hostname/push.yml @@ -0,0 +1,20 @@ +name: container-hostname +on: push + +jobs: + with-hostname: + runs-on: ubuntu-latest + container: + image: node:12-buster-slim + options: "--hostname my.host.local" + steps: + - run: | + [[ $(uname -n) == "my.host.local" ]] + + default-hostname: + runs-on: ubuntu-latest + container: + image: node:12-buster-slim + steps: + - run: | + [[ $(uname -n) ]] && [[ $(uname -n) != "my.host.local" ]]