1
0
mirror of https://github.com/woodpecker-ci/woodpecker.git synced 2025-01-23 17:53:23 +02:00

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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 157 additions and 61 deletions

View File

@ -366,6 +366,11 @@ func (c *client) RegisterAgent(ctx context.Context, platform, backend, version s
return res.GetAgentId(), err
}
func (c *client) UnregisterAgent(ctx context.Context) error {
_, err := c.client.UnregisterAgent(ctx, &proto.Empty{})
return err
}
func (c *client) ReportHealth(ctx context.Context) (err error) {
retry := c.newBackOff()
req := new(proto.ReportHealthRequest)

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{

View File

@ -41,6 +41,10 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
)
const (
EngineName = "kubernetes"
)
var noContext = context.Background()
type kube struct {
@ -98,7 +102,7 @@ func New(ctx context.Context) types.Engine {
}
func (e *kube) Name() string {
return "kubernetes"
return EngineName
}
func (e *kube) IsAvailable(context.Context) bool {

View File

@ -79,6 +79,9 @@ type Peer interface {
// RegisterAgent register our agent to the server
RegisterAgent(ctx context.Context, platform, backend, version string, capacity int) (int64, error)
// UnregisterAgent unregister our agent from the server
UnregisterAgent(ctx context.Context) error
// ReportHealth reports health status of the agent to the server
ReportHealth(c context.Context) error
}

View File

@ -16,4 +16,4 @@ package proto
// Version is the version of the woodpecker.proto file,
// !IMPORTANT! increased by 1 each time it get changed !IMPORTANT!
const Version int32 = 4
const Version int32 = 5

View File

@ -16,7 +16,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v4.24.3
// protoc v4.24.4
// source: woodpecker.proto
package proto
@ -1181,7 +1181,7 @@ var file_woodpecker_proto_rawDesc = []byte{
0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21,
0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x32, 0x8a, 0x04, 0x0a, 0x0a, 0x57, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72,
0x6e, 0x32, 0xbb, 0x04, 0x0a, 0x0a, 0x57, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72,
0x12, 0x31, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0c, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
@ -1210,19 +1210,22 @@ var file_woodpecker_proto_rawDesc = []byte{
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73,
0x74, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x61, 0x6c,
0x74, 0x68, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72,
0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x32, 0x43,
0x0a, 0x0e, 0x57, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68,
0x12, 0x31, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x77, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2d, 0x63, 0x69, 0x2f,
0x77, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c,
0x69, 0x6e, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
0x22, 0x00, 0x12, 0x2f, 0x0a, 0x0f, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x65, 0x61,
0x6c, 0x74, 0x68, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x70, 0x6f,
0x72, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x32,
0x43, 0x0a, 0x0e, 0x57, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x41, 0x75, 0x74,
0x68, 0x12, 0x31, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x77, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2d, 0x63, 0x69,
0x2f, 0x77, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2f, 0x70, 0x69, 0x70, 0x65,
0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -1277,21 +1280,23 @@ var file_woodpecker_proto_depIdxs = []int32{
9, // 13: proto.Woodpecker.Update:input_type -> proto.UpdateRequest
10, // 14: proto.Woodpecker.Log:input_type -> proto.LogRequest
13, // 15: proto.Woodpecker.RegisterAgent:input_type -> proto.RegisterAgentRequest
12, // 16: proto.Woodpecker.ReportHealth:input_type -> proto.ReportHealthRequest
17, // 17: proto.WoodpeckerAuth.Auth:input_type -> proto.AuthRequest
14, // 18: proto.Woodpecker.Version:output_type -> proto.VersionResponse
15, // 19: proto.Woodpecker.Next:output_type -> proto.NextResponse
11, // 20: proto.Woodpecker.Init:output_type -> proto.Empty
11, // 21: proto.Woodpecker.Wait:output_type -> proto.Empty
11, // 22: proto.Woodpecker.Done:output_type -> proto.Empty
11, // 23: proto.Woodpecker.Extend:output_type -> proto.Empty
11, // 24: proto.Woodpecker.Update:output_type -> proto.Empty
11, // 25: proto.Woodpecker.Log:output_type -> proto.Empty
16, // 26: proto.Woodpecker.RegisterAgent:output_type -> proto.RegisterAgentResponse
11, // 27: proto.Woodpecker.ReportHealth:output_type -> proto.Empty
18, // 28: proto.WoodpeckerAuth.Auth:output_type -> proto.AuthResponse
18, // [18:29] is the sub-list for method output_type
7, // [7:18] is the sub-list for method input_type
11, // 16: proto.Woodpecker.UnregisterAgent:input_type -> proto.Empty
12, // 17: proto.Woodpecker.ReportHealth:input_type -> proto.ReportHealthRequest
17, // 18: proto.WoodpeckerAuth.Auth:input_type -> proto.AuthRequest
14, // 19: proto.Woodpecker.Version:output_type -> proto.VersionResponse
15, // 20: proto.Woodpecker.Next:output_type -> proto.NextResponse
11, // 21: proto.Woodpecker.Init:output_type -> proto.Empty
11, // 22: proto.Woodpecker.Wait:output_type -> proto.Empty
11, // 23: proto.Woodpecker.Done:output_type -> proto.Empty
11, // 24: proto.Woodpecker.Extend:output_type -> proto.Empty
11, // 25: proto.Woodpecker.Update:output_type -> proto.Empty
11, // 26: proto.Woodpecker.Log:output_type -> proto.Empty
16, // 27: proto.Woodpecker.RegisterAgent:output_type -> proto.RegisterAgentResponse
11, // 28: proto.Woodpecker.UnregisterAgent:output_type -> proto.Empty
11, // 29: proto.Woodpecker.ReportHealth:output_type -> proto.Empty
18, // 30: proto.WoodpeckerAuth.Auth:output_type -> proto.AuthResponse
19, // [19:31] is the sub-list for method output_type
7, // [7:19] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name

View File

@ -24,16 +24,17 @@ package proto;
// Woodpecker Server Service
service Woodpecker {
rpc Version (Empty) returns (VersionResponse) {}
rpc Next (NextRequest) returns (NextResponse) {}
rpc Init (InitRequest) returns (Empty) {}
rpc Wait (WaitRequest) returns (Empty) {}
rpc Done (DoneRequest) returns (Empty) {}
rpc Extend (ExtendRequest) returns (Empty) {}
rpc Update (UpdateRequest) returns (Empty) {}
rpc Log (LogRequest) returns (Empty) {}
rpc RegisterAgent (RegisterAgentRequest) returns (RegisterAgentResponse) {}
rpc ReportHealth (ReportHealthRequest) returns (Empty) {}
rpc Version (Empty) returns (VersionResponse) {}
rpc Next (NextRequest) returns (NextResponse) {}
rpc Init (InitRequest) returns (Empty) {}
rpc Wait (WaitRequest) returns (Empty) {}
rpc Done (DoneRequest) returns (Empty) {}
rpc Extend (ExtendRequest) returns (Empty) {}
rpc Update (UpdateRequest) returns (Empty) {}
rpc Log (LogRequest) returns (Empty) {}
rpc RegisterAgent (RegisterAgentRequest) returns (RegisterAgentResponse) {}
rpc UnregisterAgent (Empty) returns (Empty) {}
rpc ReportHealth (ReportHealthRequest) returns (Empty) {}
}
//

View File

@ -16,7 +16,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v4.24.3
// - protoc v4.24.4
// source: woodpecker.proto
package proto
@ -34,16 +34,17 @@ import (
const _ = grpc.SupportPackageIsVersion7
const (
Woodpecker_Version_FullMethodName = "/proto.Woodpecker/Version"
Woodpecker_Next_FullMethodName = "/proto.Woodpecker/Next"
Woodpecker_Init_FullMethodName = "/proto.Woodpecker/Init"
Woodpecker_Wait_FullMethodName = "/proto.Woodpecker/Wait"
Woodpecker_Done_FullMethodName = "/proto.Woodpecker/Done"
Woodpecker_Extend_FullMethodName = "/proto.Woodpecker/Extend"
Woodpecker_Update_FullMethodName = "/proto.Woodpecker/Update"
Woodpecker_Log_FullMethodName = "/proto.Woodpecker/Log"
Woodpecker_RegisterAgent_FullMethodName = "/proto.Woodpecker/RegisterAgent"
Woodpecker_ReportHealth_FullMethodName = "/proto.Woodpecker/ReportHealth"
Woodpecker_Version_FullMethodName = "/proto.Woodpecker/Version"
Woodpecker_Next_FullMethodName = "/proto.Woodpecker/Next"
Woodpecker_Init_FullMethodName = "/proto.Woodpecker/Init"
Woodpecker_Wait_FullMethodName = "/proto.Woodpecker/Wait"
Woodpecker_Done_FullMethodName = "/proto.Woodpecker/Done"
Woodpecker_Extend_FullMethodName = "/proto.Woodpecker/Extend"
Woodpecker_Update_FullMethodName = "/proto.Woodpecker/Update"
Woodpecker_Log_FullMethodName = "/proto.Woodpecker/Log"
Woodpecker_RegisterAgent_FullMethodName = "/proto.Woodpecker/RegisterAgent"
Woodpecker_UnregisterAgent_FullMethodName = "/proto.Woodpecker/UnregisterAgent"
Woodpecker_ReportHealth_FullMethodName = "/proto.Woodpecker/ReportHealth"
)
// WoodpeckerClient is the client API for Woodpecker service.
@ -59,6 +60,7 @@ type WoodpeckerClient interface {
Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*Empty, error)
Log(ctx context.Context, in *LogRequest, opts ...grpc.CallOption) (*Empty, error)
RegisterAgent(ctx context.Context, in *RegisterAgentRequest, opts ...grpc.CallOption) (*RegisterAgentResponse, error)
UnregisterAgent(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
ReportHealth(ctx context.Context, in *ReportHealthRequest, opts ...grpc.CallOption) (*Empty, error)
}
@ -151,6 +153,15 @@ func (c *woodpeckerClient) RegisterAgent(ctx context.Context, in *RegisterAgentR
return out, nil
}
func (c *woodpeckerClient) UnregisterAgent(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
out := new(Empty)
err := c.cc.Invoke(ctx, Woodpecker_UnregisterAgent_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *woodpeckerClient) ReportHealth(ctx context.Context, in *ReportHealthRequest, opts ...grpc.CallOption) (*Empty, error) {
out := new(Empty)
err := c.cc.Invoke(ctx, Woodpecker_ReportHealth_FullMethodName, in, out, opts...)
@ -173,6 +184,7 @@ type WoodpeckerServer interface {
Update(context.Context, *UpdateRequest) (*Empty, error)
Log(context.Context, *LogRequest) (*Empty, error)
RegisterAgent(context.Context, *RegisterAgentRequest) (*RegisterAgentResponse, error)
UnregisterAgent(context.Context, *Empty) (*Empty, error)
ReportHealth(context.Context, *ReportHealthRequest) (*Empty, error)
mustEmbedUnimplementedWoodpeckerServer()
}
@ -208,6 +220,9 @@ func (UnimplementedWoodpeckerServer) Log(context.Context, *LogRequest) (*Empty,
func (UnimplementedWoodpeckerServer) RegisterAgent(context.Context, *RegisterAgentRequest) (*RegisterAgentResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RegisterAgent not implemented")
}
func (UnimplementedWoodpeckerServer) UnregisterAgent(context.Context, *Empty) (*Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnregisterAgent not implemented")
}
func (UnimplementedWoodpeckerServer) ReportHealth(context.Context, *ReportHealthRequest) (*Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method ReportHealth not implemented")
}
@ -386,6 +401,24 @@ func _Woodpecker_RegisterAgent_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Woodpecker_UnregisterAgent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WoodpeckerServer).UnregisterAgent(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Woodpecker_UnregisterAgent_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WoodpeckerServer).UnregisterAgent(ctx, req.(*Empty))
}
return interceptor(ctx, in, info, handler)
}
func _Woodpecker_ReportHealth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ReportHealthRequest)
if err := dec(in); err != nil {
@ -447,6 +480,10 @@ var Woodpecker_ServiceDesc = grpc.ServiceDesc{
MethodName: "RegisterAgent",
Handler: _Woodpecker_RegisterAgent_Handler,
},
{
MethodName: "UnregisterAgent",
Handler: _Woodpecker_UnregisterAgent_Handler,
},
{
MethodName: "ReportHealth",
Handler: _Woodpecker_ReportHealth_Handler,

View File

@ -350,6 +350,18 @@ func (s *RPC) RegisterAgent(ctx context.Context, platform, backend, version stri
return agent.ID, nil
}
func (s *RPC) UnregisterAgent(ctx context.Context) error {
agent, err := s.getAgentFromContext(ctx)
log.Debug().Msgf("unregistering agent with ID %d", agent.ID)
if err != nil {
return err
}
err = s.store.AgentDelete(agent)
return err
}
func (s *RPC) ReportHealth(ctx context.Context, status string) error {
agent, err := s.getAgentFromContext(ctx)
if err != nil {

View File

@ -163,6 +163,11 @@ func (s *WoodpeckerServer) RegisterAgent(c context.Context, req *proto.RegisterA
return res, err
}
func (s *WoodpeckerServer) UnregisterAgent(ctx context.Context, _ *proto.Empty) (*proto.Empty, error) {
err := s.peer.UnregisterAgent(ctx)
return new(proto.Empty), err
}
func (s *WoodpeckerServer) ReportHealth(c context.Context, req *proto.ReportHealthRequest) (*proto.Empty, error) {
res := new(proto.Empty)
err := s.peer.ReportHealth(c, req.GetStatus())

View File

@ -34,10 +34,10 @@ func WithContextSigtermCallback(ctx context.Context, f func()) context.Context {
select {
case <-ctx.Done():
case <-receivedSignal:
cancel(fmt.Errorf("received signal: %v", receivedSignal))
if f != nil {
f()
}
cancel(fmt.Errorf("received signal: %v", receivedSignal))
}
}()