mirror of
https://gitea.com/gitea/runner.git
synced 2026-11-08 16:20:29 +00:00
Removes dead code and redundant logic and consolidates tests, so there is less to read and maintain. No behavior change. 1. **act/runner**: inline single-use wrappers, compile regexes once instead of per call, embed the trampoline as a string, drop the unused legacy result of `parseActionCommand` 2. **act/container**: `sanitizeConfig` and `mergeContainerConfigs` stop returning the configs they already mutate in place, drop never-set option fields and the unused `user` parameter of `ExecWithCmdLine` 3. **act/common and cache server**: drop the unused `Trace`/`Tracef` loggers and the short SHA of `FindGitRevision`, `RegisterJob` releases through `RevokeJob` 4. **daemon, poller and reporter**: one shutdown wait for both poll modes, drop an unreachable fetch timeout branch, guard the reporter's last report time with its existing lock instead of an atomic 5. **build**: drop unused Makefile and release workflow variables, collapse the goreleaser ignore list to the same build targets 6. **tests**: fold near-duplicate tests into tables with shared setup Throughout, hand-rolled logic gives way to `cmp.Or`, `strings.Cut`, `slices` and `min`/`max`. Reviewed-on: https://gitea.com/gitea/runner/pulls/1335 Reviewed-by: bircni <[email protected]> Co-authored-by: silverwind <[email protected]>
103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package run
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"maps"
|
|
"os"
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitea.com/gitea/runner/act/common"
|
|
"gitea.com/gitea/runner/internal/pkg/process"
|
|
)
|
|
|
|
func (r *Runner) checkConfiguredHealth(ctx context.Context) (bool, string) {
|
|
script := r.cfg.HealthCheck.Script
|
|
if script == "" {
|
|
return true, "ok"
|
|
}
|
|
|
|
now := time.Now()
|
|
if r.now != nil {
|
|
now = r.now()
|
|
}
|
|
if !r.healthCheckLast.IsZero() && now.Sub(r.healthCheckLast) < r.cfg.HealthCheck.Interval {
|
|
return r.healthCheckReady, r.healthCheckReason
|
|
}
|
|
|
|
env := processEnvironment()
|
|
maps.Copy(env, r.envs)
|
|
env["GITEA_RUNNER_HEALTH_CHECK"] = "true"
|
|
env["GITEA_RUNNER_NAME"] = r.name
|
|
if r.client != nil {
|
|
env["GITEA_INSTANCE_URL"] = r.client.Address()
|
|
}
|
|
env["GITEA_RUNNER_RUNNING_JOBS"] = strconv.FormatInt(r.RunningCount(), 10)
|
|
|
|
runner := r.runHealthCheck
|
|
if runner == nil {
|
|
runner = executeHealthCheck
|
|
}
|
|
err := runner(ctx, script, r.cfg.HealthCheck.Timeout, env)
|
|
r.healthCheckLast = now
|
|
r.healthCheckReady = err == nil
|
|
if err != nil {
|
|
r.healthCheckReason = "runner health check failed: " + err.Error()
|
|
} else {
|
|
r.healthCheckReason = "ok"
|
|
}
|
|
return r.healthCheckReady, r.healthCheckReason
|
|
}
|
|
|
|
func executeHealthCheck(ctx context.Context, script string, timeout time.Duration, env map[string]string) error {
|
|
checkCtx, cancel := context.WithTimeout(ctx, timeout)
|
|
defer cancel()
|
|
cmd := exec.CommandContext(checkCtx, script)
|
|
cmd.Env = envListFromMap(env)
|
|
cmd.SysProcAttr = process.SysProcAttr(script, false)
|
|
writer := common.NewLineWriter(func(line string) bool {
|
|
line = strings.TrimRight(line, "\r\n")
|
|
if line != "" {
|
|
common.Logger(ctx).Infof("health check: %s", line)
|
|
}
|
|
return true
|
|
})
|
|
cmd.Stdout = writer
|
|
cmd.Stderr = writer
|
|
|
|
treeKill := process.NewTreeKill(cmd)
|
|
if err := cmd.Start(); err != nil {
|
|
return fmt.Errorf("start: %w", err)
|
|
}
|
|
if killer, err := treeKill.Capture(cmd.Process); err == nil {
|
|
defer killer.Close()
|
|
}
|
|
err := cmd.Wait()
|
|
common.FlushWriter(writer)
|
|
if errors.Is(checkCtx.Err(), context.DeadlineExceeded) {
|
|
return fmt.Errorf("timed out after %s", timeout)
|
|
}
|
|
if exitErr, ok := errors.AsType[*exec.ExitError](err); ok {
|
|
return fmt.Errorf("exited with code %d", exitErr.ExitCode())
|
|
}
|
|
return err
|
|
}
|
|
|
|
func processEnvironment() map[string]string {
|
|
environ := os.Environ()
|
|
env := make(map[string]string, len(environ))
|
|
for _, value := range environ {
|
|
if key, item, ok := strings.Cut(value, "="); ok {
|
|
env[key] = item
|
|
}
|
|
}
|
|
return env
|
|
}
|