cmd/storagenode-updater: restart storagenode after update on BSD unix derivatives

On BSD, the storagenode-updater falls back to renaming the storagenode without
doing anything to restart the service.
Like the approach we have for linux, this change finds the process ID of the
storagenode using pgrep and sends an interrupt signal to the process.

Closes https://github.com/storj/storj/issues/5333

Change-Id: Icced90ea3e831528804784c2170a3b8b14952e8c
This commit is contained in:
Clement Sam 2022-12-13 10:12:24 +00:00 committed by Storj Robot
parent 282aaf8945
commit b5d0021fb6
2 changed files with 82 additions and 2 deletions

View File

@ -1,8 +1,8 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
//go:build !service || (!windows && !linux && service)
// +build !service !windows,!linux,service
//go:build !service || (!windows && !linux && !freebsd && !dragonfly && !netbsd && !openbsd && !solaris && !darwin && service)
// +build !service !windows,!linux,!freebsd,!dragonfly,!netbsd,!openbsd,!solaris,!darwin,service
package main

View File

@ -0,0 +1,80 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
//go:build service && (darwin || freebsd || dragonfly || netbsd || openbsd || solaris)
// +build service
// +build darwin freebsd dragonfly netbsd openbsd solaris
package main
import (
"context"
"os"
"os/exec"
"strconv"
"strings"
"github.com/spf13/cobra"
"github.com/zeebo/errs"
)
func cmdRestart(cmd *cobra.Command, args []string) error {
return nil
}
func restartService(ctx context.Context, service, binaryLocation, newVersionPath, backupPath string) error {
if err := os.Rename(binaryLocation, backupPath); err != nil {
return errs.Wrap(err)
}
if err := os.Rename(newVersionPath, binaryLocation); err != nil {
return errs.Combine(err, os.Rename(backupPath, binaryLocation), os.Remove(newVersionPath))
}
if service == updaterServiceName {
os.Exit(1)
}
if err := stopProcess(service); err != nil {
err = errs.New("error stopping %s service: %v", service, err)
return errs.Combine(err, os.Rename(backupPath, binaryLocation))
}
return nil
}
func stopProcess(service string) (err error) {
pid, err := getServicePID(service)
if err != nil {
return err
}
p, err := os.FindProcess(pid)
if err != nil {
return err
}
return p.Signal(os.Interrupt)
}
func getServicePID(service string) (int, error) {
args := []string{
"-n", // only return the newest process (though we expect only one to be running)
"-x", // match the whole name
service,
}
cmd := exec.Command("pgrep", args...)
out, err := cmd.CombinedOutput()
if err != nil {
return 0, errs.New("Error retrieving service pid: pgrep: %s %v", string(out), err)
}
trimmed := strings.TrimSuffix(string(out), "\n")
pid, err := strconv.Atoi(trimmed)
if err != nil {
return 0, err
}
return pid, nil
}