diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index e3d30b3186a..8dee46c8329 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -95,3 +95,4 @@ ignore$ ^\Qpkg/rancher-desktop/utils/_demo_metadata.js\E$ (?:^|/)pkg/rancher-desktop/nuxt/ ^\Qsrc/disk-images/github-runner-linux/root/etc/sysconfig/network/ifcfg-\E +^\Q.github/workflows/.golangci.yaml\E$ \ No newline at end of file diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 89eef1bbcc3..dc750011090 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -270,6 +270,7 @@ Gluster gname gofmt goland +golangci gomod googlegke googleoauth diff --git a/.github/workflows/.golangci.yaml b/.github/workflows/.golangci.yaml index 22a815a9b86..6d05be7c252 100644 --- a/.github/workflows/.golangci.yaml +++ b/.github/workflows/.golangci.yaml @@ -56,7 +56,6 @@ linters: - dupl - errcheck - exportloopref - - gochecknoinits - goconst - gocritic - gocyclo @@ -88,6 +87,7 @@ linters: # - funlen # - scopelint # - gochecknoglobals + # - gochecknoinits # - gocognit # - godot # - godox diff --git a/.github/workflows/github-runner-monitor-build.yaml b/.github/workflows/github-runner-monitor-build.yaml index cc1167f5203..0ffea03837d 100644 --- a/.github/workflows/github-runner-monitor-build.yaml +++ b/.github/workflows/github-runner-monitor-build.yaml @@ -19,7 +19,9 @@ jobs: - uses: actions/checkout@v4 with: persist-credentials: false - sparse-checkout: src/go/github-runner-monitor + sparse-checkout: | + src/go/github-runner-monitor + .github # For .golangci.yaml - uses: actions/setup-go@v4 with: go-version-file: src/go/github-runner-monitor/go.mod @@ -36,6 +38,6 @@ jobs: - uses: golangci/golangci-lint-action@v3.7.0 # This is only safe because this workflow does not allow writing with: - args: --config=.golangci.yaml --verbose --timeout 3m + args: --config=${{ github.workspace }}/.github/workflows/.golangci.yaml --verbose --timeout 3m working-directory: src/go/github-runner-monitor only-new-issues: true diff --git a/src/go/github-runner-monitor/cmd/root.go b/src/go/github-runner-monitor/cmd/root.go index 717bd7970cd..f1b1efad0ef 100644 --- a/src/go/github-runner-monitor/cmd/root.go +++ b/src/go/github-runner-monitor/cmd/root.go @@ -32,6 +32,7 @@ import ( "golang.org/x/sys/unix" ) +var perRunnerMemory = 6 * 1024 var rootCmd = &cobra.Command{ Use: "github-runner-linux", Short: "Manage ephemeral GitHub runners for Rancher Desktop", @@ -82,7 +83,7 @@ var rootCmd = &cobra.Command{ } } - if err = monitor.Monitor(ctx, config); err != nil { + if err = monitor.Monitor(ctx, &config); err != nil { return fmt.Errorf("failed to monitor: %w", err) } @@ -105,7 +106,7 @@ func init() { flags.StringP("repo", "r", "rancher-desktop", "GitHub repository") flags.StringSliceP("labels", "l", []string{"self-hosted", "Linux", "X64", "ephemeral"}, "Labels to apply to the runners") flags.Int("cpus", 3, "Number of vCPUs per runner") - flags.Int("memory", 6*1024, "Memory amount per runner, in megabytes") + flags.Int("memory", perRunnerMemory, "Memory amount per runner, in megabytes") flags.String("disk", "", "Disk image to use for the VM") flags.SortFlags = false cobra.OnInitialize(initConfig) diff --git a/src/go/github-runner-monitor/pkg/machines/machine.go b/src/go/github-runner-monitor/pkg/machines/machine.go index 6806e09545b..0ce17e1ee5d 100644 --- a/src/go/github-runner-monitor/pkg/machines/machine.go +++ b/src/go/github-runner-monitor/pkg/machines/machine.go @@ -30,6 +30,8 @@ import ( "golang.org/x/sys/unix" ) +const timeout = 30 * time.Second + // getDefault returns the default value if the first value is empty. func getDefault(value, defaultValue string) string { if value != "" { @@ -40,7 +42,7 @@ func getDefault(value, defaultValue string) string { // Run a new machine with the given configuration. When the machine shuts down, // the returned channel will be closed. -func Run(ctx context.Context, c Config) (<-chan struct{}, error) { +func Run(ctx context.Context, c *Config) (<-chan struct{}, error) { log := logrus.WithField("machine", c.Name) // Set up a qemu QMP control channel, so that we can try to terminate the @@ -152,7 +154,7 @@ func Run(ctx context.Context, c Config) (<-chan struct{}, error) { // Set a custom function that will be called when procCtx is closed. cmd.Cancel = func() error { log.Info("Gracefully shutting down, this may take a while...") - timeoutCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + timeoutCtx, cancel := context.WithTimeout(context.Background(), timeout) if err := qmp.ExecuteSystemPowerdown(timeoutCtx); err != nil { log.WithError(err).Error("Failed to power down") } @@ -185,7 +187,7 @@ func killProcess(cmd *exec.Cmd, chProcessDone <-chan struct{}, log logrus.FieldL select { case <-chProcessDone: return - case <-time.After(30 * time.Second): + case <-time.After(timeout): log.Warn("Time out waiting for process exit, force killing") if err := proc.Kill(); err != nil { log.WithError(err).Error("Failed to kill process; orphaning.") diff --git a/src/go/github-runner-monitor/pkg/monitor/monitor.go b/src/go/github-runner-monitor/pkg/monitor/monitor.go index bc5a38328fe..9e7a8543074 100644 --- a/src/go/github-runner-monitor/pkg/monitor/monitor.go +++ b/src/go/github-runner-monitor/pkg/monitor/monitor.go @@ -42,7 +42,7 @@ type Config struct { // Monitor the GitHub repository and spawn new VMs when the number of active // runners is less than the configured amount. -func Monitor(ctx context.Context, c Config) error { +func Monitor(ctx context.Context, c *Config) error { client := github.NewClient(nil).WithAuthToken(c.AuthToken) wg := &sync.WaitGroup{} @@ -69,7 +69,7 @@ monitorLoop: // added to before creating the GitHub-side runner record, and removed once that // has been removed. This is used to ensure we do not end up exiting before we // clean up. -func monitorOnce(ctx context.Context, c Config, client *github.Client, wg *sync.WaitGroup) error { +func monitorOnce(ctx context.Context, c *Config, client *github.Client, wg *sync.WaitGroup) error { runners, _, err := client.Actions.ListRunners(ctx, c.Owner, c.Repo, nil) if err != nil { return fmt.Errorf("failed to retrieve list of runners: %w", err) @@ -118,7 +118,7 @@ runnerLoop: removeRunner := func() { runner := config.GetRunner() if runner != nil { - // Don't use the given context; that might have been cancelled (and + // Don't use the given context; that might have been canceled (and // lead to us removing the runner). Use a new background context // instead. logrus.Tracef("Unregistering runner %s", name) @@ -138,7 +138,7 @@ runnerLoop: if configString == "" { return fmt.Errorf("got invalid runner config") } - machineDone, err := machines.Run(ctx, machines.Config{ + machineDone, err := machines.Run(ctx, &machines.Config{ Name: name, Cpus: fmt.Sprintf("%d", c.Cpus), Memory: fmt.Sprintf("%dM", c.Memory),