blob: 25727644dae0a11b1f7bc7be292dbd9022c197c5 [file] [log] [blame]
Serge Bazanskib40c0082023-03-29 14:28:04 +02001// Package mgmt implements the node-local management service, a.k.a.
2// metropolis.proto.api.NodeManagement.
3package mgmt
4
5import (
6 "context"
7 "fmt"
8 "net"
9
10 "google.golang.org/grpc"
11
12 "source.monogon.dev/metropolis/node"
13 "source.monogon.dev/metropolis/node/core/identity"
14 "source.monogon.dev/metropolis/node/core/rpc"
Serge Bazanskie012b722023-03-29 17:49:04 +020015 "source.monogon.dev/metropolis/pkg/logtree"
Serge Bazanskib40c0082023-03-29 14:28:04 +020016 "source.monogon.dev/metropolis/pkg/supervisor"
17
18 apb "source.monogon.dev/metropolis/proto/api"
19)
20
Serge Bazanskie012b722023-03-29 17:49:04 +020021// Service implements metropolis.proto.api.NodeManagement.
Serge Bazanskib40c0082023-03-29 14:28:04 +020022type Service struct {
Serge Bazanskie012b722023-03-29 17:49:04 +020023 // NodeCredentials used to set up gRPC server.
Serge Bazanskib40c0082023-03-29 14:28:04 +020024 NodeCredentials *identity.NodeCredentials
Serge Bazanskie012b722023-03-29 17:49:04 +020025 // LogTree from which NodeManagement.Logs will be served.
26 LogTree *logtree.LogTree
27
28 // Automatically populated on Run.
29 LogService
Serge Bazanskib40c0082023-03-29 14:28:04 +020030}
31
Serge Bazanskie012b722023-03-29 17:49:04 +020032// Run the Servie as a supervisor runnable.
Serge Bazanskib40c0082023-03-29 14:28:04 +020033func (s *Service) Run(ctx context.Context) error {
Serge Bazanskie012b722023-03-29 17:49:04 +020034 if s.NodeCredentials == nil {
35 return fmt.Errorf("NodeCredentials missing")
36 }
37 if s.LogTree == nil {
38 return fmt.Errorf("LogTree missing")
39 }
40
41 s.LogService.LogTree = s.LogTree
42
Serge Bazanskib40c0082023-03-29 14:28:04 +020043 sec := rpc.ServerSecurity{
44 NodeCredentials: s.NodeCredentials,
45 }
46 logger := supervisor.MustSubLogger(ctx, "rpc")
47 opts := sec.GRPCOptions(logger)
48 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", node.NodeManagement))
49 if err != nil {
50 return fmt.Errorf("failed to listen on node management socket socket: %w", err)
51 }
52 defer lis.Close()
53
54 srv := grpc.NewServer(opts...)
55 apb.RegisterNodeManagementServer(srv, s)
56
57 runnable := supervisor.GRPCServer(srv, lis, false)
58 if err := supervisor.Run(ctx, "server", runnable); err != nil {
59 return fmt.Errorf("could not run server: %w", err)
60 }
61 supervisor.Signal(ctx, supervisor.SignalHealthy)
62 <-ctx.Done()
63 return ctx.Err()
64}