diff --git a/housekeeper/daemon/server/server.go b/housekeeper/daemon/server/server.go index 42a5b854a3e84605d460dd7e07e84f00b14b9099..1cd4637840b2f27c5786db3f8f5c6e8af18e12a3 100644 --- a/housekeeper/daemon/server/server.go +++ b/housekeeper/daemon/server/server.go @@ -17,17 +17,63 @@ limitations under the License. package server import ( + "bytes" "context" + "fmt" + "os" + "os/exec" + "strings" + "sync" + "github.com/sirupsen/logrus" pb "housekeeper.io/pkg/connection/proto" ) +const ostreeImage = "ostree-unverified-image:docker://" + type Server struct { pb.UnimplementedUpgradeClusterServer + mu sync.Mutex } // Implements the Upgrade func (s *Server) Upgrade(_ context.Context, req *pb.UpgradeRequest) (*pb.UpgradeResponse, error) { - //todo + s.mu.Lock() + defer s.mu.Unlock() + + if len(req.OsVersion) > 0 { + if err := upgradeOSVersion(req); err != nil { + logrus.Errorf("upgrade os version error: %v", err) + return &pb.UpgradeResponse{}, err + } + } return &pb.UpgradeResponse{}, nil } + +func upgradeOSVersion(req *pb.UpgradeRequest) error { + //upgrade os + customImageURL := fmt.Sprintf("%s%s", ostreeImage, req.OsImageUrl) + args := []string{"rebase", "--experimental", customImageURL, "--bypass-driver"} + if err := runCmd("rpm-ostree", args...); err != nil { + logrus.Errorf("failed to upgrade os to %s : %w", req.OsVersion, err) + return err + } + // todo:skipping reboot + rebootArgs := []string{"-c", "systemctl reboot"} + if err := runCmd("/bin/sh", rebootArgs...); err != nil { + logrus.Errorf("failed to run reboot: %v", err) + return err + } + return nil +} + +func runCmd(name string, args ...string) error { + cmd := exec.Command(name, args...) + var stderr bytes.Buffer + cmd.Stdout = os.Stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + return fmt.Errorf("error running %s %s: %s: %w", name, strings.Join(args, " "), string(stderr.Bytes()), err) + } + return nil +}