Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ By following these guidelines, we can easily determine which changes should be i

## Edge

- [#224](https://github.com/circleci/runner-init/pull/224) Record and log timings in orchestrator init function.
- [#212](https://github.com/circleci/runner-init/pull/212) Fix child process cleanup on Windows using job objects. This ensures that child processes are destroyed when the parent process (task-agent) terminates.
- [#197](https://github.com/circleci/runner-init/pull/197) Fix `%PATH%` on Windows by using the OS-specific path list separator.
- [#133](https://github.com/circleci/runner-init/pull/133) Don't re-handle task errors. If GOAT handles a task error (either with an infra-fail or retry), don't exit with a nonzero status code. Doing so causes container agent to overwrite the original error message in the UI.
Expand Down
2 changes: 1 addition & 1 deletion cmd/orchestrator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func run(version, date string) (err error) {
c := cli.Init
sys.AddService(func(_ context.Context) error {
defer cancel()
return initialize.Run(c.Source, c.Destination)
return initialize.Run(ctx, c.Source, c.Destination)
})

case "run-task":
Expand Down
24 changes: 19 additions & 5 deletions init/init.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
package init

import (
"context"
"errors"
"io"
"os"
"path/filepath"
"runtime"

"github.com/circleci/ex/o11y"
)

// Run function performs the copying of the orchestrator and task-agent binaries
func Run(srcDir, destDir string) error {
func Run(ctx context.Context, srcDir, destDir string) (err error) {
ctx, span := o11y.StartSpan(ctx, "orchestrator: init")
defer o11y.End(span, &err)

span.RecordMetric(o11y.Timing("init.duration"))

// Copy the orchestrator binary
orchestratorSrc := filepath.Join(srcDir, binOrchestrator)
orchestratorDest := filepath.Join(destDir, binOrchestrator)
if err := copyFile(orchestratorSrc, orchestratorDest); err != nil {
if err := copyFile(ctx, orchestratorSrc, orchestratorDest); err != nil {
return err
}

// Copy the task agent binary
agentSrc := filepath.Join(srcDir, binCircleciAgent)
agentDest := filepath.Join(destDir, binCircleciAgent)
if err := copyFile(agentSrc, agentDest); err != nil {
if err := copyFile(ctx, agentSrc, agentDest); err != nil {
return err
}

Expand All @@ -33,15 +41,21 @@ func Run(srcDir, destDir string) error {
} else {
// We copy the binary instead of creating a symlink to `circleci` as we do on Linux,
// since we do not have the necessary privileges to create symlinks to the shared volume on Windows.
if err := copyFile(agentSrc, circleciDest); err != nil {
if err := copyFile(ctx, agentSrc, circleciDest); err != nil {
return err
}
}

return nil
}

func copyFile(srcPath, destPath string) (err error) {
func copyFile(ctx context.Context, srcPath, destPath string) (err error) {
_, span := o11y.StartSpan(ctx, "orchestrator: init: copy")
defer o11y.End(span, &err)

span.AddField("binary", filepath.Base(srcPath))
span.RecordMetric(o11y.Timing("init.copy.duration"))

closeFile := func(f *os.File) {
err = errors.Join(err, f.Close())
}
Expand Down
6 changes: 4 additions & 2 deletions init/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"runtime"
"testing"

"github.com/circleci/ex/testing/testcontext"
"gotest.tools/v3/assert"
"gotest.tools/v3/assert/cmp"
)
Expand All @@ -18,9 +19,10 @@ func TestRun(t *testing.T) {
agentSrc := filepath.Join(srcDir, binCircleciAgent)
agentDest := filepath.Join(destDir, binCircleciAgent)
circleciDest := filepath.Join(destDir, binCircleci)
ctx := testcontext.Background()

t.Run("Copy files and create symlink", func(t *testing.T) {
err := Run(srcDir, destDir)
err := Run(ctx, srcDir, destDir)
assert.NilError(t, err)

assertFileIsCopied(t, orchSrc, orchDest)
Expand All @@ -36,7 +38,7 @@ func TestRun(t *testing.T) {
})

t.Run("Fail when source files not present", func(t *testing.T) {
err := Run(srcDir, "non-existent-dir")
err := Run(ctx, srcDir, "non-existent-dir")
if runtime.GOOS == "windows" {
assert.Check(t, cmp.ErrorContains(err, "The system cannot find the path specified"))
} else {
Expand Down