Unregister stateless agents from server on termination (#2606)

Closes #2027

---------

Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
Thomas Anderson
2023-11-02 02:53:47 +03:00
committed by GitHub
parent ec62a1d0c6
commit 3620c84da4
14 changed files with 157 additions and 61 deletions

View File

@@ -118,9 +118,20 @@ func run(c *cli.Context) error {
context.Background(),
metadata.Pairs("hostname", hostname),
)
agentConfigPersisted := abool.New()
ctx = utils.WithContextSigtermCallback(ctx, func() {
println("ctrl+c received, terminating process")
log.Info().Msg("Termination signal is received, shutting down")
sigterm.Set()
// Remove stateless agents from server
if agentConfigPersisted.IsNotSet() {
log.Debug().Msg("Unregistering agent from server")
err := client.UnregisterAgent(ctx)
if err != nil {
log.Err(err).Msg("Failed to unregister agent from server")
}
}
})
// check if grpc server version is compatible with agent
@@ -165,7 +176,11 @@ func run(c *cli.Context) error {
return err
}
writeAgentConfig(agentConfig, agentConfigPath)
if agentConfigPath != "" {
if err := writeAgentConfig(agentConfig, agentConfigPath); err == nil {
agentConfigPersisted.Set()
}
}
labels := map[string]string{
"hostname": hostname,
@@ -187,6 +202,7 @@ func run(c *cli.Context) error {
go func() {
for {
if sigterm.IsSet() {
log.Debug().Msg("Terminating health reporting")
return
}
@@ -210,6 +226,7 @@ func run(c *cli.Context) error {
for {
if sigterm.IsSet() {
log.Debug().Msgf("terminating runner %d", i)
return
}

View File

@@ -35,6 +35,10 @@ func readAgentConfig(agentConfigPath string) AgentConfig {
AgentID: defaultAgentIDValue,
}
if agentConfigPath == "" {
return conf
}
rawAgentConf, err := os.ReadFile(agentConfigPath)
if err != nil {
if os.IsNotExist(err) {
@@ -54,11 +58,11 @@ func readAgentConfig(agentConfigPath string) AgentConfig {
return conf
}
func writeAgentConfig(conf AgentConfig, agentConfigPath string) {
func writeAgentConfig(conf AgentConfig, agentConfigPath string) error {
rawAgentConf, err := json.Marshal(conf)
if err != nil {
log.Error().Err(err).Msg("could not marshal agent config")
return
return err
}
// get old config
@@ -68,6 +72,9 @@ func writeAgentConfig(conf AgentConfig, agentConfigPath string) {
if !bytes.Equal(rawAgentConf, oldRawAgentConf) {
if err := os.WriteFile(agentConfigPath, rawAgentConf, 0o644); err != nil {
log.Error().Err(err).Msgf("could not persist agent config at '%s'", agentConfigPath)
return err
}
}
return nil
}

View File

@@ -44,7 +44,7 @@ func TestReadAgentIDFileExists(t *testing.T) {
// update existing config and check
actual.AgentID = 33
writeAgentConfig(actual, tmpF.Name())
_ = writeAgentConfig(actual, tmpF.Name())
actual = readAgentConfig(tmpF.Name())
assert.EqualValues(t, 33, actual.AgentID)
@@ -55,7 +55,7 @@ func TestReadAgentIDFileExists(t *testing.T) {
defer os.Remove(tmpF2.Name())
// write new config
writeAgentConfig(actual, tmpF2.Name())
_ = writeAgentConfig(actual, tmpF2.Name())
actual = readAgentConfig(tmpF2.Name())
assert.EqualValues(t, 33, actual.AgentID)
}

View File

@@ -54,7 +54,7 @@ var flags = []cli.Flag{
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_AGENT_CONFIG_FILE"},
Name: "agent-config",
Usage: "agent config file path",
Usage: "agent config file path, if set empty the agent will be stateless and unregister on termination",
Value: "/etc/woodpecker/agent.conf",
},
&cli.StringSliceFlag{