Skip to content

Commit 57965d2

Browse files
authored
Merge pull request #16 from bcdevtools/imp/command-gen-config-auto-backup
imp: command gen config auto backup
2 parents 2fd0a6d + 78680ff commit 57965d2

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ nmngd node zip-snapshot ~/.node_home
2626
### For validator node
2727
```bash
2828
nmngd node auto-backup-priv-validator-state-json ~/.node_home --binary xxxd
29+
# generate setup for auto-backup-pvs
30+
nmngd node auto-backup-priv-validator-state-json ~/.node_home --binary xxxd --gen-setup
2931
```
3032

3133
## Run web server

cmd/node/auto_backup_priv_validator_state.go

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
const (
1919
flagKeep = "keep"
2020
flagBinaryKillByAutoBackup = "binary"
21+
flagGenSetup = "gen-setup"
2122
)
2223

2324
const (
@@ -31,14 +32,19 @@ const (
3132

3233
func GetAutoBackupPrivValidatorStateCmd() *cobra.Command {
3334
var cmd = &cobra.Command{
34-
Use: commandAutoBackupPrivValidatorState + " [node_home]",
35-
Short: "Designed to be run as a service, it will automatically backup the `priv_validator_state.json`, and kill the node process if the content of the file is decreased",
36-
Args: cobra.ExactArgs(1),
35+
Use: commandAutoBackupPrivValidatorState + " [node_home]",
36+
Aliases: []string{"auto-backup-pvs", "auto-backup-priv-validator-state"},
37+
Short: "Designed to be run as a service, it will automatically backup the `priv_validator_state.json`, and kill the node process if the content of the file is decreased",
38+
Args: cobra.ExactArgs(1),
3739
Run: func(cmd *cobra.Command, args []string) {
3840
utils.MustNotUserRoot()
3941

40-
nodeHomeDirectory := strings.TrimSpace(args[0])
42+
nodeHomeDirectory := strings.TrimSuffix(strings.TrimSpace(args[0]), "/")
4143
validateNodeHomeDirectory(nodeHomeDirectory)
44+
if !strings.Contains(nodeHomeDirectory, "/") {
45+
utils.ExitWithErrorMsg("ERR: node home directory must be absolute path, eg: /home/user/.nodeHome")
46+
return
47+
}
4248

4349
currentUser, err := user.Current()
4450
if err != nil {
@@ -47,6 +53,11 @@ func GetAutoBackupPrivValidatorStateCmd() *cobra.Command {
4753
}
4854
userHomeDir := currentUser.HomeDir
4955

56+
if !strings.HasPrefix(nodeHomeDirectory, userHomeDir) {
57+
utils.ExitWithErrorMsg("ERR: node home directory must be under user home directory:", userHomeDir)
58+
return
59+
}
60+
5061
backupDstPath := path.Join(userHomeDir, fmt.Sprintf(".backup_priv_validator_state_%s", constants.BINARY_NAME))
5162
createBackupDirIfNotExists(backupDstPath)
5263
fmt.Println("INF: backup directory:", backupDstPath)
@@ -82,6 +93,11 @@ func GetAutoBackupPrivValidatorStateCmd() *cobra.Command {
8293
_, binaryNameToKill := path.Split(binaryPathToKill)
8394
fmt.Println("INF: binary to kill:", binaryNameToKill, "at", binaryPathToKill)
8495

96+
if cmd.Flags().Changed(flagGenSetup) {
97+
genSetupThenExit(nodeHomeDirectory, binaryPathToKill, keepRecent, currentUser)
98+
return
99+
}
100+
85101
privValStateJsonFilePath := path.Join(nodeHomeDirectory, "data", "priv_validator_state.json")
86102
fmt.Println("INF: priv_validator_state.json file path:", privValStateJsonFilePath)
87103

@@ -279,6 +295,7 @@ How to recover:
279295

280296
cmd.Flags().Int(flagKeep, 3, "Keep the last N backups")
281297
cmd.Flags().String(flagBinaryKillByAutoBackup, "", "Absolute path of the chain binary to be killed by process when priv_validator_state.json has problem")
298+
cmd.Flags().Bool(flagGenSetup, false, "Display guide to setup instead of running business logic")
282299

283300
return cmd
284301
}
@@ -453,3 +470,40 @@ func loadLatestBackupPrivValidatorStateOrExitWithErr(backupDstPath string) types
453470

454471
return *pvs
455472
}
473+
474+
func genSetupThenExit(nodeHomeDirectory, binaryPathToKill string, keepRecent int, currentUser *user.User) {
475+
const serviceFileName = "auto-backup-pvs"
476+
fmt.Println("Input chain name (eg: Cosmos Hub):")
477+
chainName := utils.ReadText(false)
478+
fmt.Println("Mainnet or Testnet?")
479+
networkType := utils.ReadText(false)
480+
fmt.Println("INF: setup guide:")
481+
fmt.Println("1. Create service file")
482+
fmt.Println("> sudo vi /etc/systemd/system/" + serviceFileName + ".service")
483+
fmt.Printf(`[Unit]
484+
Description=Auto backup priv_validator_state.json for Validator on %s %s
485+
After=network.target
486+
#
487+
[Service]
488+
User=%s
489+
ExecStart=%s/go/bin/%s start %s --%s %s --%s %d
490+
RestartSec=1
491+
Restart=on-failure
492+
LimitNOFILE=1024
493+
#
494+
[Install]
495+
WantedBy=multi-user.target
496+
`, chainName, networkType, currentUser.Username, currentUser.HomeDir, constants.BINARY_NAME, nodeHomeDirectory, flagBinaryKillByAutoBackup, binaryPathToKill, flagKeep, keepRecent)
497+
fmt.Println("2. Setup visudo")
498+
fmt.Println("> sudo visudo")
499+
fmt.Printf(strings.ReplaceAll(strings.ReplaceAll(`# Allow user @USER@ to manage @SVC@ service
500+
@USER@ ALL= NOPASSWD: /usr/bin/systemctl start @SVC@
501+
@USER@ ALL= NOPASSWD: /usr/bin/systemctl stop @SVC@
502+
@USER@ ALL= NOPASSWD: /usr/bin/systemctl restart @SVC@
503+
@USER@ ALL= NOPASSWD: /usr/bin/systemctl enable @SVC@ # Do not allow disable
504+
@USER@ ALL= NOPASSWD: /usr/bin/systemctl status @SVC@
505+
`, "@USER@", currentUser.Username), "@SVC@", serviceFileName))
506+
fmt.Println("3. Enable service to automatically run at startup")
507+
fmt.Println("> sudo systemctl daemon-reload && sudo systemctl enable " + serviceFileName + ".service")
508+
os.Exit(0)
509+
}

0 commit comments

Comments
 (0)