diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9d7ec0d346..61cfeb30d9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,6 +4,7 @@ on: branches: - master - 0.3.x + - 'renovate/**' pull_request: branches: - master diff --git a/core/runjob.go b/core/runjob.go index 36e391f0f6..6838ea950d 100644 --- a/core/runjob.go +++ b/core/runjob.go @@ -33,6 +33,7 @@ type RunJob struct { Network string Hostname string Container string + Entrypoint *string Volume []string VolumesFrom []string `gcfg:"volumes-from" mapstructure:"volumes-from,"` Environment []string @@ -173,12 +174,15 @@ func (j *RunJob) buildContainer() (*docker.Container, error) { Env: j.Environment, Hostname: j.Hostname, } - + // Only set User if it's explicitly specified, otherwise use container's default user if j.User != "" { config.User = j.User } + if j.Entrypoint != nil { + config.Entrypoint = args.GetArgs(*j.Entrypoint) + } c, err := j.Client.CreateContainer(docker.CreateContainerOptions{ Config: config, NetworkingConfig: &docker.NetworkingConfig{}, diff --git a/core/runjob_test.go b/core/runjob_test.go index da80ef50e6..683c47546d 100644 --- a/core/runjob_test.go +++ b/core/runjob_test.go @@ -33,56 +33,71 @@ func (s *SuiteRunJob) SetUpTest(c *C) { } func (s *SuiteRunJob) TestRun(c *C) { - job := &RunJob{Client: s.client} - job.Image = ImageFixture - job.Command = `echo -a "foo bar"` - job.User = "foo" - job.TTY = true - job.Delete = "true" - job.Network = "foo" - job.Hostname = "test-host" - job.Name = "test" - job.Environment = []string{"test_Key1=value1", "test_Key2=value2"} - job.Volume = []string{"/test/tmp:/test/tmp:ro", "/test/tmp:/test/tmp:rw"} - - ctx := &Context{} - ctx.Execution = NewExecution() - ctx.Logger = NewSlogLogger(io.Discard) - ctx.Job = job - - go func() { - // Docker Test Server doesn't actually start container - // so "job.Run" will hang until container is stopped - if err := job.Run(ctx); err != nil { - c.Fatal(err) - } - }() - - time.Sleep(200 * time.Millisecond) - container, err := job.getContainer() - c.Assert(err, IsNil) - c.Assert(container.Config.Cmd, DeepEquals, []string{"echo", "-a", "foo bar"}) - c.Assert(container.Config.User, Equals, job.User) - c.Assert(container.Config.Image, Equals, job.Image) - c.Assert(container.State.Running, Equals, true) - c.Assert(container.Config.Env, DeepEquals, job.Environment) - - // this doesn't seem to be working with DockerTestServer - // c.Assert(container.Config.Hostname, Equals, job.Hostname) - // c.Assert(container.HostConfig.Binds, DeepEquals, job.Volume) - - // stop container, we don't need it anymore - err = job.stopContainer(0) - c.Assert(err, IsNil) - - // wait and double check if container was deleted on "stop" - time.Sleep(watchDuration * 2) - container, _ = job.getContainer() - c.Assert(container, IsNil) - - containers, err := s.client.ListContainers(docker.ListContainersOptions{All: true}) - c.Assert(err, IsNil) - c.Assert(containers, HasLen, 0) + overridenEntrypoint := "/bin/bash -c" + emptyEntrypoint := "" + testCases := []struct { + entrypoint *string + expectedEntrypoint []string + }{ + {nil, nil}, + {&overridenEntrypoint, []string{"/bin/bash", "-c"}}, + {&emptyEntrypoint, []string{}}, + } + + for _, tc := range testCases { + job := &RunJob{Client: s.client} + job.Image = ImageFixture + job.Command = `echo -a "foo bar"` + job.User = "foo" + job.TTY = true + job.Delete = "true" + job.Network = "foo" + job.Hostname = "test-host" + job.Name = "test" + job.Environment = []string{"test_Key1=value1", "test_Key2=value2"} + job.Volume = []string{"/test/tmp:/test/tmp:ro", "/test/tmp:/test/tmp:rw"} + job.Entrypoint = tc.entrypoint + + ctx := &Context{} + ctx.Execution = NewExecution() + ctx.Logger = NewSlogLogger(io.Discard) + ctx.Job = job + + go func() { + // Docker Test Server doesn't actually start container + // so "job.Run" will hang until container is stopped + if err := job.Run(ctx); err != nil { + c.Fatal(err) + } + }() + + time.Sleep(200 * time.Millisecond) + container, err := job.getContainer() + c.Assert(err, IsNil) + c.Assert(container.Config.Entrypoint, DeepEquals, tc.expectedEntrypoint) + c.Assert(container.Config.Cmd, DeepEquals, []string{"echo", "-a", "foo bar"}) + c.Assert(container.Config.User, Equals, job.User) + c.Assert(container.Config.Image, Equals, job.Image) + c.Assert(container.State.Running, Equals, true) + c.Assert(container.Config.Env, DeepEquals, job.Environment) + + // this doesn't seem to be working with DockerTestServer + // c.Assert(container.Config.Hostname, Equals, job.Hostname) + // c.Assert(container.HostConfig.Binds, DeepEquals, job.Volume) + + // stop container, we don't need it anymore + err = job.stopContainer(0) + c.Assert(err, IsNil) + + // wait and double check if container was deleted on "stop" + time.Sleep(watchDuration * 2) + container, _ = job.getContainer() + c.Assert(container, IsNil) + + containers, err := s.client.ListContainers(docker.ListContainersOptions{All: true}) + c.Assert(err, IsNil) + c.Assert(containers, HasLen, 0) + } } func (s *SuiteRunJob) TestBuildPullImageOptionsBareImage(c *C) { diff --git a/docs/jobs.md b/docs/jobs.md index c34b1165aa..4dddfbe6b4 100644 --- a/docs/jobs.md +++ b/docs/jobs.md @@ -84,6 +84,10 @@ This job can be used in 2 situations: - *description*: Command you want to run inside the container. - *value*: String, e.g. `touch /tmp/example` - *default*: Default container command +- **Entrypoint** (1) + - *description*: Override container default entrypoint. + - *value*: String, e.g. `/bin/bash -c` + - *default*: Default container entrypoint - **Image** (1) - *description*: Image you want to use for the job. - *value*: String, e.g. `nginx:latest` diff --git a/go.mod b/go.mod index 71c05823f7..186ac73f52 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/mcuadros/ofelia go 1.25.0 -toolchain go1.26.1 +toolchain go1.26.2 require ( github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 @@ -14,7 +14,7 @@ require ( github.com/gohugoio/hashstructure v0.6.0 github.com/jessevdk/go-flags v1.6.1 github.com/lmittmann/tint v1.1.3 - github.com/magefile/mage v1.16.1 + github.com/magefile/mage v1.17.1 github.com/mcuadros/go-defaults v1.2.0 github.com/robfig/cron/v3 v3.0.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c diff --git a/go.sum b/go.sum index 455e09a496..aab7ec0c6b 100644 --- a/go.sum +++ b/go.sum @@ -50,6 +50,8 @@ github.com/lmittmann/tint v1.1.3 h1:Hv4EaHWXQr+GTFnOU4VKf8UvAtZgn0VuKT+G0wFlO3I= github.com/lmittmann/tint v1.1.3/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/magefile/mage v1.16.1 h1:j5UwkdA48xTlGs0Hcm1Q3sSAcxBorntQjiewDNMsqlo= github.com/magefile/mage v1.16.1/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/magefile/mage v1.17.1 h1:F1d2lnLSlbQDM0Plq6Ac4NtaHxkxTK8t5nrMY9SkoNA= +github.com/magefile/mage v1.17.1/go.mod h1:Yj51kqllmsgFpvvSzgrZPK9WtluG3kUhFaBUVLo4feA= github.com/mcuadros/go-defaults v1.2.0 h1:FODb8WSf0uGaY8elWJAkoLL0Ri6AlZ1bFlenk56oZtc= github.com/mcuadros/go-defaults v1.2.0/go.mod h1:WEZtHEVIGYVDqkKSWBdWKUVdRyKlMfulPaGDWIVeCWY= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=