Skip to content

Commit

Permalink
chore(node): call sudo on demand
Browse files Browse the repository at this point in the history
  • Loading branch information
PhearZero committed Dec 12, 2024
1 parent 965404b commit 74e75ae
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 32 deletions.
10 changes: 10 additions & 0 deletions cmd/node/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ var installCmd = &cobra.Command{
log.Error(err)
os.Exit(1)
}

// If it's not running, start the daemon (can happen)
if !algod.IsRunning() {
err = algod.Start()
if err != nil {
log.Error(err)
os.Exit(1)
}
}

log.Info(style.Green.Render("Algorand installed successfully 🎉"))
},
}
Expand Down
11 changes: 0 additions & 11 deletions cmd/node/node.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package node

import (
"errors"
"github.com/algorandfoundation/algorun-tui/internal/algod"
"github.com/algorandfoundation/algorun-tui/ui/style"
"github.com/charmbracelet/log"
"github.com/spf13/cobra"
"os"
"runtime"
)

const SudoWarningMsg = "(You may be prompted for your password)"
Expand All @@ -23,14 +20,6 @@ var Cmd = &cobra.Command{
Use: "node",
Short: "Node Management",
Long: style.Purple(style.BANNER) + "\n" + style.LightBlue("Manage your Algorand node"),
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {

// Check that we are calling with sudo on linux
if os.Geteuid() != 0 && runtime.GOOS == "linux" {
return errors.New(PermissionErrorMsg)
}
return nil
},
}

func NeedsToBeRunning(cmd *cobra.Command, args []string) {
Expand Down
63 changes: 42 additions & 21 deletions internal/algod/linux/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"github.com/algorandfoundation/algorun-tui/internal/algod/fallback"
"github.com/algorandfoundation/algorun-tui/internal/system"
"github.com/charmbracelet/log"

"os"
"os/exec"
"runtime"
"strings"
"text/template"
)
Expand All @@ -21,25 +21,46 @@ type Algod struct {
DataDirectoryPath string
}

// InstallSudoCmds generates installation commands for "sudo" based on the detected package manager and system state.
func InstallSudoCmds() system.CmdsList {
var cmds system.CmdsList
if system.CmdExists("sudo") || os.Geteuid() != 0 {
return cmds
}
if system.CmdExists("apt-get") {
return system.CmdsList{
{"apt-get", "update"},
{"apt-get", "install", "-y", "sudo"},
}
}

if system.CmdExists("dnf") {
return system.CmdsList{
{"dnf", "install", "-y", "sudo"},
}
}
return cmds
}

// Install installs Algorand development tools or node software depending on the package manager.
func Install() error {
log.Info("Installing Algod on Linux")
// Based off of https://developer.algorand.org/docs/run-a-node/setup/install/#installation-with-a-package-manager
if system.CmdExists("apt-get") { // On some Debian systems we use apt-get
log.Info("Installing with apt-get")
return system.RunAll(system.CmdsList{
{"apt-get", "update"},
{"apt-get", "install", "-y", "gnupg2", "curl", "software-properties-common"},
{"sh", "-c", "curl -o - https://releases.algorand.com/key.pub | tee /etc/apt/trusted.gpg.d/algorand.asc"},
{"sh", "-c", `add-apt-repository -y "deb [arch=amd64] https://releases.algorand.com/deb/ stable main"`},
{"apt-get", "update"},
{"apt-get", "install", "-y", "algorand-devtools"},
})
return system.RunAll(append(InstallSudoCmds(), system.CmdsList{
{"sudo", "apt-get", "update"},
{"sudo", "apt-get", "install", "-y", "gnupg2", "curl", "software-properties-common"},
{"sh", "-c", "curl -o - https://releases.algorand.com/key.pub | sudo tee /etc/apt/trusted.gpg.d/algorand.asc"},
{"sudo", "add-apt-repository", "-y", fmt.Sprintf("deb [arch=%s] https://releases.algorand.com/deb/ stable main", runtime.GOARCH)},
{"sudo", "apt-get", "update"},
{"sudo", "apt-get", "install", "-y", "algorand-devtools"},
}...))
}

if system.CmdExists("dnf") { // On Fedora and CentOs8 there's the dnf package manager
log.Printf("Installing with dnf")
return system.RunAll(system.CmdsList{
return system.RunAll(append(InstallSudoCmds(), system.CmdsList{
{"curl", "-O", "https://releases.algorand.com/rpm/rpm_algorand.pub"},
{"rpmkeys", "--import", "rpm_algorand.pub"},
{"dnf", "install", "-y", "dnf-command(config-manager)"},
Expand All @@ -48,7 +69,7 @@ func Install() error {
{"systemctl", "enable", "algorand.service"},
{"systemctl", "start", "algorand.service"},
{"rm", "-f", "rpm_algorand.pub"},
})
}...))

}

Expand All @@ -65,14 +86,14 @@ func Uninstall() error {
if system.CmdExists("apt-get") {
log.Info("Using apt-get package manager")
unInstallCmds = [][]string{
{"apt-get", "autoremove", "algorand-devtools", "algorand", "-y"},
{"sudo", "apt-get", "autoremove", "algorand-devtools", "algorand", "-y"},
}
}
// On Fedora and CentOs8 there's the dnf package manager
if system.CmdExists("dnf") {
log.Info("Using dnf package manager")
unInstallCmds = [][]string{
{"dnf", "remove", "algorand-devtools", "algorand", "-y"},
{"sudo", "dnf", "remove", "algorand-devtools", "algorand", "-y"},
}
}
// Error on unsupported package managers
Expand All @@ -81,8 +102,8 @@ func Uninstall() error {
}

// Commands to clear systemd algorand.service and any other files, like the configuration override
unInstallCmds = append(unInstallCmds, []string{"bash", "-c", "rm -rf /etc/systemd/system/algorand*"})
unInstallCmds = append(unInstallCmds, []string{"systemctl", "daemon-reload"})
unInstallCmds = append(unInstallCmds, []string{"sudo", "bash", "-c", "rm -rf /etc/systemd/system/algorand*"})
unInstallCmds = append(unInstallCmds, []string{"sudo", "systemctl", "daemon-reload"})

return system.RunAll(unInstallCmds)
}
Expand All @@ -92,13 +113,13 @@ func Uninstall() error {
func Upgrade() error {
if system.CmdExists("apt-get") {
return system.RunAll(system.CmdsList{
{"apt-get", "update"},
{"apt-get", "install", "--only-upgrade", "-y", "algorand-devtools", "algorand"},
{"sudo", "apt-get", "update"},
{"sudo", "apt-get", "install", "--only-upgrade", "-y", "algorand-devtools", "algorand"},
})
}
if system.CmdExists("dnf") {
return system.RunAll(system.CmdsList{
{"dnf", "update", "-y", "--refresh", "algorand-devtools", "algorand"},
{"sudo", "dnf", "update", "-y", "--refresh", "algorand-devtools", "algorand"},
})
}
return fmt.Errorf("the *node upgrade* command is currently only available for installations done with an approved package manager. Please use a different method to upgrade")
Expand All @@ -109,21 +130,21 @@ func Upgrade() error {
// Returns an error if the command fails.
// TODO: Replace with D-Bus integration
func Start() error {
return exec.Command("systemctl", "start", "algorand").Run()
return exec.Command("sudo", "systemctl", "start", "algorand").Run()
}

// Stop shuts down the Algorand algod system process on Linux using the systemctl stop command.
// Returns an error if the operation fails.
// TODO: Replace with D-Bus integration
func Stop() error {
return exec.Command("systemctl", "stop", "algorand").Run()
return exec.Command("sudo", "systemctl", "stop", "algorand").Run()
}

// IsService checks if the "algorand.service" is listed as a systemd unit file on Linux.
// Returns true if it exists.
// TODO: Replace with D-Bus integration
func IsService() bool {
out, err := system.Run([]string{"systemctl", "list-unit-files", "algorand.service"})
out, err := system.Run([]string{"sudo", "systemctl", "list-unit-files", "algorand.service"})
if err != nil {
return false
}
Expand Down

0 comments on commit 74e75ae

Please sign in to comment.