-
Notifications
You must be signed in to change notification settings - Fork 107
/
fee-recipient.go
195 lines (163 loc) · 5.56 KB
/
fee-recipient.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package validator
import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/rocket-pool/smartnode/shared/services/beacon"
"github.com/rocket-pool/smartnode/shared/services/config"
"github.com/rocket-pool/smartnode/shared/utils/log"
)
// Settings
const ValidatorContainerSuffix = "_validator"
const BeaconContainerSuffix = "_eth2"
var validatorRestartTimeout, _ = time.ParseDuration("5s")
// Restart validator process
func RestartValidator(cfg *config.RocketPoolConfig, bc beacon.Client, log *log.ColorLogger, d *client.Client) error {
// Restart validator container
if !cfg.IsNativeMode {
// Get validator container name & client type label
var containerName string
var clientTypeLabel string
if cfg.Smartnode.ProjectName.Value == "" {
return errors.New("Rocket Pool docker project name not set")
}
clientType, _ := bc.GetClientType()
switch clientType {
case beacon.SplitProcess:
containerName = cfg.Smartnode.ProjectName.Value.(string) + ValidatorContainerSuffix
clientTypeLabel = "validator"
case beacon.SingleProcess:
containerName = cfg.Smartnode.ProjectName.Value.(string) + BeaconContainerSuffix
clientTypeLabel = "beacon"
default:
return fmt.Errorf("Can't restart the validator, unknown client type '%d'", clientType)
}
// Log
if log != nil {
log.Printlnf("Restarting %s container (%s)...", clientTypeLabel, containerName)
}
// Get all containers
containers, err := d.ContainerList(context.Background(), types.ContainerListOptions{All: true})
if err != nil {
return fmt.Errorf("Could not get docker containers: %w", err)
}
// Get validator container ID
var validatorContainerId string
for _, container := range containers {
if container.Names[0] == "/"+containerName {
validatorContainerId = container.ID
break
}
}
if validatorContainerId == "" {
return errors.New("Validator container not found")
}
// Restart validator container
timeout := int(validatorRestartTimeout.Seconds())
if err := d.ContainerRestart(context.Background(), validatorContainerId, container.StopOptions{Timeout: &timeout}); err != nil {
return fmt.Errorf("Could not restart validator container: %w", err)
}
// Restart external validator process
} else {
// Get validator restart command
restartCommand := os.ExpandEnv(cfg.Native.ValidatorRestartCommand.Value.(string))
// Log
if log != nil {
log.Printlnf("Restarting validator process with command '%s'...", restartCommand)
}
// Run validator restart command bound to os stdout/stderr
cmd := exec.Command(restartCommand)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("Could not restart validator process: %w", err)
}
}
// Log & return
if log != nil {
log.Println("Successfully restarted validator")
}
return nil
}
// Stops the validator process
func StopValidator(cfg *config.RocketPoolConfig, bc beacon.Client, log *log.ColorLogger, d *client.Client) error {
// Stop validator container
if !cfg.IsNativeMode {
// Get validator container name & client type label
var containerName string
var clientTypeLabel string
if cfg.Smartnode.ProjectName.Value == "" {
return errors.New("Rocket Pool docker project name not set")
}
clientType, _ := bc.GetClientType()
switch clientType {
case beacon.SplitProcess:
containerName = cfg.Smartnode.ProjectName.Value.(string) + ValidatorContainerSuffix
clientTypeLabel = "validator"
case beacon.SingleProcess:
containerName = cfg.Smartnode.ProjectName.Value.(string) + BeaconContainerSuffix
clientTypeLabel = "beacon"
default:
return fmt.Errorf("Can't stop the validator, unknown client type '%d'", clientType)
}
// Log
if log != nil {
log.Printlnf("Stopping %s container (%s)...", clientTypeLabel, containerName)
}
// Get all containers
containers, err := d.ContainerList(context.Background(), types.ContainerListOptions{All: true})
if err != nil {
return fmt.Errorf("Could not get docker containers: %w", err)
}
// Get validator container ID
var validatorContainerId string
for _, container := range containers {
if container.Names[0] == "/"+containerName {
validatorContainerId = container.ID
break
}
}
if validatorContainerId == "" {
// TODO: return here if the container doesn't exist? Is erroring out necessary?
return fmt.Errorf("Validator container %s not found", containerName)
}
// Stop validator container
if err := d.ContainerPause(context.Background(), validatorContainerId); err != nil {
if strings.Contains(err.Error(), "is not running") {
// Handle situations where the container is already stopped
if log != nil {
log.Printlnf("Validator container %s was not running.", containerName)
}
return nil
}
return fmt.Errorf("Could not stop validator container %s: %w", containerName, err)
}
} else {
// Stop external validator process
// Get validator stop command
stopCommand := os.ExpandEnv(cfg.Native.ValidatorStopCommand.Value.(string))
// Log
if log != nil {
log.Printlnf("Stopping validator process with command '%s'...", stopCommand)
}
// Run validator stop command bound to os stdout/stderr
cmd := exec.Command(stopCommand)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("Could not stop validator process: %w", err)
}
}
// Log & return
if log != nil {
log.Println("Successfully stopped validator")
}
return nil
}