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
17 changes: 17 additions & 0 deletions cmd/benchmarkoor/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ func runBuild(_ *cobra.Command, _ []string) error {

installSignalHandler(cancel)

// Clean up any benchmarkoor resources left by a previous build or run
// before starting, if configured. Uses all available runtimes so
// containers left under a different runtime (e.g. Docker vs Podman) are
// also removed. Mirrors runner.cleanup_on_start.
if cfg.Builder.CleanupOnStart {
log.Info("Performing cleanup before start")

cleanupManagers := buildCleanupManagers(ctx)
if err := performCleanup(ctx, cleanupManagers, true); err != nil {
log.WithError(err).Warn("Cleanup failed")
}

for _, mgr := range cleanupManagers {
_ = mgr.Stop()
}
}

builders, stop, err := buildBuilders(ctx, cfg)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Configuration values can also be overridden via environment variables with the `
|-------------|---------------------|
| `global.log_level` | `BENCHMARKOOR_GLOBAL_LOG_LEVEL` |
| `builder.run_timeout` | `BENCHMARKOOR_BUILDER_RUN_TIMEOUT` |
| `builder.cleanup_on_start` | `BENCHMARKOOR_BUILDER_CLEANUP_ON_START` |
| `runner.run_timeout` | `BENCHMARKOOR_RUNNER_RUN_TIMEOUT` |
| `runner.benchmark.results_dir` | `BENCHMARKOOR_RUNNER_BENCHMARK_RESULTS_DIR` |
| `runner.client.config.jwt` | `BENCHMARKOOR_RUNNER_CLIENT_CONFIG_JWT` |
Expand Down Expand Up @@ -1472,6 +1473,7 @@ Builds are **decoupled from `benchmarkoor run`**: invoke `benchmarkoor build` to
| Option | Type | Default | Description |
|---|---|---|---|
| `run_timeout` | string | – | Global timeout capping the entire `benchmarkoor build` (all builders and targets), as a Go duration (e.g. `2h`, `90m`). Empty means no timeout. Overridable via `BENCHMARKOOR_BUILDER_RUN_TIMEOUT`. The analogue of [`runner.run_timeout`](#runner-run-timeout) for builds. |
| `cleanup_on_start` | bool | `false` | Remove leftover benchmarkoor resources (containers, volumes, the build network, ZFS clones, overlay mounts, CPU-freq state) before the build starts — the same sweep as the `benchmarkoor cleanup` command. Overridable via `BENCHMARKOOR_BUILDER_CLEANUP_ON_START`. The analogue of `runner.cleanup_on_start` for builds. |

### `builder.state_actor` options

Expand Down
11 changes: 8 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,13 @@ type BuilderConfig struct {
// RunTimeout caps the entire build (all builders and targets) as a Go
// duration string (e.g. "2h"). Empty means no timeout. Overridable via
// BENCHMARKOOR_BUILDER_RUN_TIMEOUT.
RunTimeout string `yaml:"run_timeout,omitempty" mapstructure:"run_timeout"`
StateActor *StateActorConfig `yaml:"state_actor,omitempty" mapstructure:"state_actor"`
EESTPayloads *EESTPayloadsConfig `yaml:"eest_payloads,omitempty" mapstructure:"eest_payloads"`
RunTimeout string `yaml:"run_timeout,omitempty" mapstructure:"run_timeout"`
// CleanupOnStart removes any leftover benchmarkoor resources (containers,
// volumes, the build network, ZFS clones, overlay mounts, CPU-freq state)
// before the build starts. The analogue of runner.cleanup_on_start.
CleanupOnStart bool `yaml:"cleanup_on_start" mapstructure:"cleanup_on_start"`
StateActor *StateActorConfig `yaml:"state_actor,omitempty" mapstructure:"state_actor"`
EESTPayloads *EESTPayloadsConfig `yaml:"eest_payloads,omitempty" mapstructure:"eest_payloads"`
}

// StateActorConfig configures how the state-actor binary is invoked via
Expand Down Expand Up @@ -1556,6 +1560,7 @@ func bindEnvKeys(v *viper.Viper) {
"global.directories.cachedir",
// Builder settings
"builder.run_timeout",
"builder.cleanup_on_start",
// Runner settings
"runner.container_runtime",
"runner.client_logs_to_stdout",
Expand Down
38 changes: 38 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,44 @@ func TestLoad_BuilderRunTimeoutEnv(t *testing.T) {
assert.Equal(t, 3*time.Hour, c.GetBuilderRunTimeout())
}

func TestLoad_BuilderCleanupOnStart(t *testing.T) {
base := "builder:\n%s state_actor:\n images: {geth: img}\n" +
" targets:\n - client: geth\n output_dir: /tmp/x\n"

t.Run("from file", func(t *testing.T) {
f := filepath.Join(t.TempDir(), "config.yaml")
require.NoError(t, os.WriteFile(f, []byte(
fmt.Sprintf(base, " cleanup_on_start: true\n")), 0o600))

c, err := Load(f)
require.NoError(t, err)
require.NotNil(t, c.Builder)
assert.True(t, c.Builder.CleanupOnStart)
})

t.Run("defaults to false", func(t *testing.T) {
f := filepath.Join(t.TempDir(), "config.yaml")
require.NoError(t, os.WriteFile(f, []byte(fmt.Sprintf(base, "")), 0o600))

c, err := Load(f)
require.NoError(t, err)
require.NotNil(t, c.Builder)
assert.False(t, c.Builder.CleanupOnStart)
})

t.Run("from env when absent in file", func(t *testing.T) {
f := filepath.Join(t.TempDir(), "config.yaml")
require.NoError(t, os.WriteFile(f, []byte(fmt.Sprintf(base, "")), 0o600))

t.Setenv("BENCHMARKOOR_BUILDER_CLEANUP_ON_START", "true")

c, err := Load(f)
require.NoError(t, err)
require.NotNil(t, c.Builder)
assert.True(t, c.Builder.CleanupOnStart)
})
}

func TestLoad_InlineAddressStubsKeyCasing(t *testing.T) {
// Viper is case-insensitive and lowercases all map keys; EEST resolves stub
// names by exact match, so Load must restore the original casing.
Expand Down
Loading