Skip to content

Commit 0107eba

Browse files
authored
Merge pull request #793 from jshufro/jms/fixpurge
Fix commands that require escalation
2 parents 14bda54 + 605b8b9 commit 0107eba

1 file changed

Lines changed: 39 additions & 45 deletions

File tree

shared/services/rocketpool/client.go

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,6 @@ func (c *Client) StopService(composeFiles []string) error {
504504

505505
// Stop the Rocket Pool service and remove the config folder
506506
func (c *Client) TerminateService(composeFiles []string, configPath string) error {
507-
// Get the command to run with root privileges
508-
rootCmd, err := c.getEscalationCommand()
509-
if err != nil {
510-
return fmt.Errorf("could not get privilege escalation command: %w", err)
511-
}
512507

513508
// Terminate the Docker containers
514509
cmd, err := c.compose(composeFiles, "down -v")
@@ -526,8 +521,9 @@ func (c *Client) TerminateService(composeFiles []string, configPath string) erro
526521
return fmt.Errorf("error loading Rocket Pool directory: %w", err)
527522
}
528523
fmt.Printf("Deleting Rocket Pool directory (%s)...\n", path)
529-
cmd = fmt.Sprintf("%s rm -rf %s", rootCmd, path)
530-
_, err = c.readOutput(cmd)
524+
cmd = fmt.Sprintf("rm -rf %s", path)
525+
// The directory contains root-owned paths, so delete it as root
526+
_, err = c.readOutputSudo(cmd)
531527
if err != nil {
532528
return fmt.Errorf("error deleting Rocket Pool directory: %w", err)
533529
}
@@ -882,11 +878,6 @@ func (c *Client) RunNethermindPruneStarter(executionContainerName string, pruneS
882878

883879
// Deletes the node wallet and all validator keys, and restarts the Docker containers
884880
func (c *Client) PurgeAllKeys(composeFiles []string) error {
885-
// Get the command to run with root privileges
886-
rootCmd, err := c.getEscalationCommand()
887-
if err != nil {
888-
return fmt.Errorf("could not get privilege escalation command: %w", err)
889-
}
890881

891882
// Get the config
892883
cfg, _, err := c.LoadConfig()
@@ -912,8 +903,9 @@ func (c *Client) PurgeAllKeys(composeFiles []string) error {
912903
return fmt.Errorf("error loading wallet path: %w", err)
913904
}
914905
fmt.Println("Deleting wallet...")
915-
cmd := fmt.Sprintf("%s rm -f %s", rootCmd, walletPath)
916-
_, err = c.readOutput(cmd)
906+
cmd := fmt.Sprintf("rm -f %s", walletPath)
907+
// The file is owned by root, so delete as root
908+
_, err = c.readOutputSudo(cmd)
917909
if err != nil {
918910
return fmt.Errorf("error deleting wallet: %w", err)
919911
}
@@ -924,8 +916,9 @@ func (c *Client) PurgeAllKeys(composeFiles []string) error {
924916
return fmt.Errorf("error loading password path: %w", err)
925917
}
926918
fmt.Println("Deleting password...")
927-
cmd = fmt.Sprintf("%s rm -f %s", rootCmd, passwordPath)
928-
_, err = c.readOutput(cmd)
919+
cmd = fmt.Sprintf("rm -f %s", passwordPath)
920+
// The file is owned by root, so delete as root
921+
_, err = c.readOutputSudo(cmd)
929922
if err != nil {
930923
return fmt.Errorf("error deleting password: %w", err)
931924
}
@@ -936,13 +929,19 @@ func (c *Client) PurgeAllKeys(composeFiles []string) error {
936929
return fmt.Errorf("error loading validators folder path: %w", err)
937930
}
938931
fmt.Println("Deleting validator keys...")
939-
cmd = fmt.Sprintf("%s rm -rf %s/*", rootCmd, validatorsPath)
940-
_, err = c.readOutput(cmd)
932+
cmd = fmt.Sprintf("rm -rf %s/*", validatorsPath)
933+
// The validators path can be created by the smartnode daemon (owned by root, 0600)
934+
// So delete its contents as root, otherwise the * won't expand.
935+
// NB: we delete the contents of the folder instead of recreating the folder
936+
// This way, if the drive is full, we don't release the directory inode and fail to recreate it.
937+
_, err = c.readOutputSudo(cmd)
941938
if err != nil {
942939
return fmt.Errorf("error deleting validator keys: %w", err)
943940
}
944-
cmd = fmt.Sprintf("%s rm -rf %s/.[a-zA-Z0-9]*", rootCmd, validatorsPath)
945-
_, err = c.readOutput(cmd)
941+
// Also delete hidden files
942+
cmd = fmt.Sprintf("rm -rf %s/.[a-zA-Z0-9]*", validatorsPath)
943+
// also as root, so bash can expand the regex
944+
_, err = c.readOutputSudo(cmd)
946945
if err != nil {
947946
return fmt.Errorf("error deleting hidden files in validator folder: %w", err)
948947
}
@@ -977,31 +976,6 @@ func (c *Client) SetClientStatusFlags(ignoreSyncCheck bool, forceFallbacks bool)
977976
c.forceFallbacks = forceFallbacks
978977
}
979978

980-
// Get the command used to escalate privileges on the system
981-
func (c *Client) getEscalationCommand() (string, error) {
982-
// Check for sudo first
983-
sudo := "sudo"
984-
exists, err := c.checkIfCommandExists(sudo)
985-
if err != nil {
986-
return "", fmt.Errorf("error checking if %s exists: %w", sudo, err)
987-
}
988-
if exists {
989-
return sudo, nil
990-
}
991-
992-
// Check for doas next
993-
doas := "doas"
994-
exists, err = c.checkIfCommandExists(doas)
995-
if err != nil {
996-
return "", fmt.Errorf("error checking if %s exists: %w", doas, err)
997-
}
998-
if exists {
999-
return doas, nil
1000-
}
1001-
1002-
return "", fmt.Errorf("no privilege escalation command found")
1003-
}
1004-
1005979
func (c *Client) checkIfCommandExists(command string) (bool, error) {
1006980
// Run `type` to check for existence
1007981
cmd := fmt.Sprintf("type %s", command)
@@ -1390,6 +1364,26 @@ func (c *Client) printOutput(cmdText string) error {
13901364

13911365
}
13921366

1367+
// Run a command as root and return its output
1368+
func (c *Client) readOutputSudo(rootCmdText string) ([]byte, error) {
1369+
var escCmd string
1370+
for _, escalationCommand := range []string{"sudo", "doas"} {
1371+
exists, err := c.checkIfCommandExists(escalationCommand)
1372+
if err != nil {
1373+
return nil, fmt.Errorf("error checking if %s exists: %w", escalationCommand, err)
1374+
}
1375+
if exists {
1376+
escCmd = escalationCommand
1377+
break
1378+
}
1379+
}
1380+
if escCmd == "" {
1381+
return nil, fmt.Errorf("no privilege escalation command found")
1382+
}
1383+
1384+
return c.readOutput(fmt.Sprintf("%s bash -c %s", escCmd, shellescape.Quote(rootCmdText)))
1385+
}
1386+
13931387
// Run a command and return its output
13941388
func (c *Client) readOutput(cmdText string) ([]byte, error) {
13951389

0 commit comments

Comments
 (0)