fix: clear consumed ephemeral registration state (#1256)

Ephemeral registrations are single-use, but the daemon kept `.runner` after the task, so a restarted container failed `Declare` with `unregistered runner` forever.

An ephemeral runner now removes its registration file as soon as it fetches a task, so a container killed mid-job registers afresh on restart. It also removes the file when Gitea answers `unregistered runner` at startup or while polling. A proxy's 401 does not count. Persistent runners keep their file, because Gitea sends the same reply for a token mismatch.

Closes https://gitea.com/gitea/runner/issues/818

---------

Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1256
Reviewed-by: silverwind <[email protected]>
This commit is contained in:
bircniandsilverwind committed 2026-10-01 09:23:45 +00:00
1 parent 0cedd98051
commit d93b7d278a
6 files changed
+148 -15

No files matched your search

+19 -1
View File
@@ -191,6 +191,9 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu
return err
case err != nil:
log.WithError(err).Error("fail to invoke Declare")
if client.IsRegistrationRejected(err) {
removeEphemeralRegistration(reg, cfg.Runner.File)
}
return err
default:
log.Infof("runner: %s, with version: %s, with labels: %v, declare successfully",
@@ -215,7 +218,7 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu
done := make(chan struct{})
go func() {
defer close(done)
poller.PollOnce()
poller.PollOnce(func() { removeEphemeralRegistration(reg, cfg.Runner.File) })
}()
// shutdown when we complete a job or cancel is requested
@@ -244,6 +247,10 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu
log.Warnf("runner: %s cancelled in progress jobs during shutdown", resp.Msg.Runner.Name)
}
if poller.RegistrationRejected() {
removeEphemeralRegistration(reg, cfg.Runner.File)
}
if poller.Unregistered() {
return errors.New("runner is no longer registered with the server; please register it again")
}
@@ -252,6 +259,17 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu
}
}
func removeEphemeralRegistration(reg *config.Registration, file string) {
if !reg.Ephemeral {
return
}
if err := os.Remove(file); err == nil {
log.Infof("removed the spent ephemeral registration %q", file)
} else if !os.IsNotExist(err) {
log.WithError(err).Warn("failed to remove the spent ephemeral registration")
}
}
type daemonArgs struct {
Once bool
Labels string