/
update.go
125 lines (111 loc) · 3.16 KB
/
update.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
package main
import (
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"io/ioutil"
"path"
"github.com/republicprotocol/co-go"
"github.com/republicprotocol/republic-go/cmd/darknode/config"
"github.com/republicprotocol/republic-go/crypto"
"github.com/urfave/cli"
)
// updateNode updates the Darknode to the latest release. It can also be used
// to update the config file of the darknode.
func updateNode(ctx *cli.Context) error {
name := ctx.Args().First()
updateConfig := ctx.Bool("config")
tags := ctx.String("tags")
branch := ctx.String("branch")
if tags == "" && name == "" {
return ErrEmptyNodeName
} else if tags == "" && name != "" {
return updateSingleNode(name, branch, updateConfig)
} else if tags != "" && name == "" {
nodes, err := getNodesByTags(tags)
if err != nil {
return err
}
errs := make([]error, len(nodes))
co.ForAll(nodes, func(i int) {
errs[i] = updateSingleNode(nodes[i], branch, updateConfig)
})
return handleErrs(errs)
}
return ErrNameAndTags
}
func updateSingleNode(name, branch string, updateConfig bool) error {
nodePath := nodePath(name)
keyPairPath := path.Join(nodePath, "ssh_keypair")
configPath := path.Join(nodePath, "config.json")
ip, err := getIp(nodePath)
if err != nil {
return err
}
// Check if we need to update the node config
if updateConfig {
// Read the local config file
data, err := ioutil.ReadFile(configPath)
if err != nil {
return err
}
var cfg config.Config
err = json.Unmarshal(data, &cfg)
if err != nil {
return err
}
// Read ssh private key from `ssh_keypair` file and decode it into a rsa key
keyData, err := ioutil.ReadFile(keyPairPath)
if err != nil {
return err
}
block, _ := pem.Decode(keyData)
if block == nil {
return ErrInvalidSshKeyFile
}
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return err
}
// Replace the rsaKey with the one for SSHing.
cfg.Keystore.RsaKey = crypto.NewRsaKey(key)
data, err = json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
if err := ioutil.WriteFile(configPath, data, 0644); err != nil {
return err
}
updateConfigScript := fmt.Sprintf(`echo '%s' > $HOME/.darknode/config.json`, string(data))
if err := run("ssh", "-i", keyPairPath, "darknode@"+ip, "-oStrictHostKeyChecking=no", updateConfigScript); err != nil {
return err
}
fmt.Printf("%sConfig of [%s] has been updated to the local version.%s\n", GREEN, name, RESET)
}
udpate, err := ioutil.ReadFile(path.Join(Directory, "scripts", "update.sh"))
if err != nil {
return err
}
err = run("ssh", "-i", keyPairPath, "darknode@"+ip, "-oStrictHostKeyChecking=no", string(udpate))
if err != nil {
return err
}
fmt.Printf("%s[%s] has been updated to the latest version on %s branch.%s \n", GREEN, name, branch, RESET)
return nil
}
// sshNode will ssh into the Darknode
func sshNode(ctx *cli.Context) error {
name := ctx.Args().First()
if name == "" {
cli.ShowCommandHelp(ctx, "ssh")
return ErrEmptyNodeName
}
nodePath := nodePath(name)
ip, err := getIp(nodePath)
if err != nil {
return err
}
keyPairPath := nodePath + "/ssh_keypair"
return run("ssh", "-i", keyPairPath, "darknode@"+ip)
}