blob: ce8b26b165aba5a2dc8f77b28b9613b9c532918f [file] [log] [blame]
Lorenz Brun35fcf032023-06-29 04:15:58 +02001package mgmt
2
3import (
4 "context"
5 "time"
6
7 "golang.org/x/sys/unix"
8 "google.golang.org/grpc/codes"
9 "google.golang.org/grpc/status"
10
11 apb "source.monogon.dev/metropolis/proto/api"
12)
13
14func (s *Service) UpdateNode(ctx context.Context, req *apb.UpdateNodeRequest) (*apb.UpdateNodeResponse, error) {
Lorenz Brund14be0e2023-07-31 16:46:14 +020015 ok := s.updateMutex.TryLock()
16 if ok {
17 defer s.updateMutex.Unlock()
18 } else {
19 return nil, status.Error(codes.Aborted, "another UpdateNode RPC is in progress on this node")
20 }
21 if req.ActivationMode == apb.ActivationMode_ACTIVATION_INVALID {
22 return nil, status.Errorf(codes.InvalidArgument, "activation_mode needs to be explicitly specified")
23 }
24 if err := s.UpdateService.InstallBundle(ctx, req.BundleUrl, req.ActivationMode == apb.ActivationMode_ACTIVATION_KEXEC); err != nil {
Lorenz Brun35fcf032023-06-29 04:15:58 +020025 return nil, status.Errorf(codes.Unavailable, "error installing update: %v", err)
26 }
Lorenz Brund14be0e2023-07-31 16:46:14 +020027 if req.ActivationMode != apb.ActivationMode_ACTIVATION_NONE {
Lorenz Brun35fcf032023-06-29 04:15:58 +020028 // TODO(#253): Tell Supervisor to shut down gracefully and reboot
29 go func() {
30 time.Sleep(10 * time.Second)
31 unix.Sync()
Lorenz Brund14be0e2023-07-31 16:46:14 +020032 if req.ActivationMode == apb.ActivationMode_ACTIVATION_KEXEC {
33 unix.Reboot(unix.LINUX_REBOOT_CMD_KEXEC)
34 } else {
35 unix.Reboot(unix.LINUX_REBOOT_CMD_RESTART)
36 }
Lorenz Brun35fcf032023-06-29 04:15:58 +020037 }()
38 }
Lorenz Brund14be0e2023-07-31 16:46:14 +020039
Lorenz Brun35fcf032023-06-29 04:15:58 +020040 return &apb.UpdateNodeResponse{}, nil
41}