ceremonyclient/client/cmd/node/shared.go
Tyler Sturos 9cfbdef12c
Feat/2.1 qclient refactor and node install (#429)
* initial auto-update

* working link, update, and testing docker container and scripts

* refactor packages/folders

* move files to proper folders

* fix typos

Closes #421

* optimize rpm imports

* optimize channel imports

* Refactor split command to allow testing of split operations

Closes #338

* modify split and test for folder changes

* remove alias

* fix docker warning about FROM and AS being in different letter case

Closes #422

* QClient Account Command

* Display transaction details and confirmation prompts for transfer and merge commands

* build qclient docker improvements

* update build args for mpfr.so.6

* update install and node commands

* remove NodeConfig check for qclient node commands

* udpate

* working node commands

* update commands

* move utils and rename package

---------

Co-authored-by: Vasyl Tretiakov <vasyl.tretiakov@gmail.com>
Co-authored-by: littleblackcloud <163544315+littleblackcloud@users.noreply.github.com>
Co-authored-by: 0xOzgur <29779769+0xOzgur@users.noreply.github.com>
Co-authored-by: Cassandra Heart <7929478+CassOnMars@users.noreply.github.com>
2025-04-11 21:43:20 -05:00

153 lines
5.8 KiB
Go

package node
import (
"fmt"
"os"
"path/filepath"
"strings"
"source.quilibrium.com/quilibrium/monorepo/client/utils"
)
// determineVersion gets the version to install from args or defaults to "latest"
func determineVersion(args []string) string {
if len(args) > 0 {
return args[0]
}
return "latest"
}
// confirmPaths asks the user to confirm the installation and data paths
// func confirmPaths(installPath, dataPath string) bool {
// fmt.Print("Do you want to continue with these paths? [Y/n]: ")
// reader := bufio.NewReader(os.Stdin)
// response, _ := reader.ReadString('\n')
// response = strings.TrimSpace(strings.ToLower(response))
// return response == "" || response == "y" || response == "yes"
// }
// setOwnership sets the ownership of directories to the node user
func setOwnership() {
// Change ownership of installation directory
err := utils.ChownPath(utils.NodeDataPath, NodeUser, true)
if err != nil {
fmt.Fprintf(os.Stderr, "Warning: Failed to change ownership of %s: %v\n", utils.NodeDataPath, err)
}
}
// setupLogRotation creates a logrotate configuration file for the Quilibrium node
func setupLogRotation() error {
// Check if we need sudo privileges for creating logrotate config
if err := utils.CheckAndRequestSudo("Creating logrotate configuration requires root privileges"); err != nil {
return fmt.Errorf("failed to get sudo privileges: %w", err)
}
// Create logrotate configuration
configContent := fmt.Sprintf(`%s/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 %s %s
postrotate
systemctl reload quilibrium-node >/dev/null 2>&1 || true
endscript
}`, logPath, NodeUser.Username, NodeUser.Username)
// Write the configuration file
configPath := "/etc/logrotate.d/quilibrium-node"
if err := utils.WriteFile(configPath, configContent); err != nil {
return fmt.Errorf("failed to create logrotate configuration: %w", err)
}
// Create log directory with proper permissions
if err := utils.ValidateAndCreateDir(logPath, NodeUser); err != nil {
return fmt.Errorf("failed to create log directory: %w", err)
}
// Set ownership of log directory
err := utils.ChownPath(logPath, NodeUser, true)
if err != nil {
return fmt.Errorf("failed to set log directory ownership: %w", err)
}
fmt.Fprintf(os.Stdout, "Created log rotation configuration at %s\n", configPath)
return nil
}
// finishInstallation completes the installation process by making the binary executable and creating a symlink
func finishInstallation(version string) {
setOwnership()
normalizedBinaryName := "node-" + version + "-" + OsType + "-" + Arch
// Finish installation
nodeBinaryPath := filepath.Join(utils.NodeDataPath, version, normalizedBinaryName)
fmt.Printf("Making binary executable: %s\n", nodeBinaryPath)
// Make the binary executable
if err := utils.ChmodPath(nodeBinaryPath, 0755, "executable"); err != nil {
fmt.Fprintf(os.Stderr, "Warning: Failed to make binary executable: %v\n", err)
}
// Check if we need sudo privileges for creating symlink in system directory
if strings.HasPrefix(defaultSymlinkPath, "/usr/") || strings.HasPrefix(defaultSymlinkPath, "/bin/") || strings.HasPrefix(defaultSymlinkPath, "/sbin/") {
if err := utils.CheckAndRequestSudo(fmt.Sprintf("Creating symlink at %s requires root privileges", defaultSymlinkPath)); err != nil {
fmt.Fprintf(os.Stderr, "Warning: Failed to get sudo privileges: %v\n", err)
return
}
}
// Create symlink using the utils package
if err := utils.CreateSymlink(nodeBinaryPath, defaultSymlinkPath); err != nil {
fmt.Fprintf(os.Stderr, "Error creating symlink: %v\n", err)
}
// Set up log rotation
if err := setupLogRotation(); err != nil {
fmt.Fprintf(os.Stderr, "Warning: Failed to set up log rotation: %v\n", err)
}
// Print success message
printSuccessMessage(version)
}
// printSuccessMessage prints a success message after installation
func printSuccessMessage(version string) {
fmt.Fprintf(os.Stdout, "\nSuccessfully installed Quilibrium node %s\n", version)
fmt.Fprintf(os.Stdout, "Binary download directory: %s\n", filepath.Join(utils.NodeDataPath, version))
fmt.Fprintf(os.Stdout, "Binary symlinked to %s\n", defaultSymlinkPath)
fmt.Fprintf(os.Stdout, "Log directory: %s\n", logPath)
fmt.Fprintf(os.Stdout, "Environment file: /etc/default/quilibrium-node\n")
fmt.Fprintf(os.Stdout, "Service file: /etc/systemd/system/quilibrium-node.service\n")
fmt.Fprintf(os.Stdout, "\nConfiguration:\n")
fmt.Fprintf(os.Stdout, " To create a new configuration:\n")
fmt.Fprintf(os.Stdout, " qclient node config create [name] --default\n")
fmt.Fprintf(os.Stdout, " quilibrium-node --peer-id %s/default-config\n", ConfigDirs)
fmt.Fprintf(os.Stdout, "\n To use an existing configuration:\n")
fmt.Fprintf(os.Stdout, " cp -r /path/to/your/existing/config %s/default-config\n", ConfigDirs)
fmt.Fprintf(os.Stdout, " # Or modify the service file to point to your existing config:\n")
fmt.Fprintf(os.Stdout, " sudo nano /etc/systemd/system/quilibrium-node.service\n")
fmt.Fprintf(os.Stdout, " # Then reload systemd:\n")
fmt.Fprintf(os.Stdout, " sudo systemctl daemon-reload\n")
fmt.Fprintf(os.Stdout, "\nTo select a configuration:\n")
fmt.Fprintf(os.Stdout, " qclient node config switch <config-name>\n")
fmt.Fprintf(os.Stdout, " # Or use the --default flag when creating a config to automatically select it:\n")
fmt.Fprintf(os.Stdout, " qclient node config create --default\n")
fmt.Fprintf(os.Stdout, "\nTo manually start the node (must create a config first), you can run:\n")
fmt.Fprintf(os.Stdout, " %s --config %s/myconfig/\n",
ServiceName, ConfigDirs)
fmt.Fprintf(os.Stdout, " # Or use systemd service using the default config:\n")
fmt.Fprintf(os.Stdout, " sudo systemctl start quilibrium-node\n")
fmt.Fprintf(os.Stdout, "\nFor more options, run:\n")
fmt.Fprintf(os.Stdout, " quilibrium-node --help\n")
}