/
prepare.go
152 lines (133 loc) · 5.07 KB
/
prepare.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
package nodecmd
import (
"bytes"
"fmt"
"html/template"
"os"
"path/filepath"
"reflect"
"github.com/lasthyphen/dijetsnode/ids"
"github.com/lasthyphen/ecctools/pkg/configs"
"github.com/lasthyphen/ecctools/pkg/constants"
"github.com/lasthyphen/ecctools/pkg/utils"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tidwall/sjson"
)
func newPrepareCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "prepare work-dir",
Short: "Create a new self-contained directory in [work-dir] for a node",
Long: `TODO Notes: You are not allowed to replace genesis for 'local' network,
so we use the ANR 'custom' genesis that can be freely tweaked.`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
_ = viper.BindPFlags(cmd.Flags())
if viper.GetString("ava-bin") == "" {
return fmt.Errorf("must supply --ava-bin flag or AVA_BIN env")
}
if exists := utils.FileExists(viper.GetString("ava-bin")); !exists {
return fmt.Errorf("ava-bin file does not exist: %s", viper.GetString("ava-bin"))
}
if viper.GetString("vm-bin") == "" {
app.Log.Warnln("WARNING: --vm-bin or VM_BIN not supplied, creating dijetsnode node without any subnet vms")
} else {
if exists := utils.FileExists(viper.GetString("vm-bin")); !exists {
return fmt.Errorf("vm-bin file does not exist: %s", viper.GetString("vm-bin"))
}
}
if err := prepareWorkDir(args[0], viper.GetString("ava-bin"), viper.GetString("vm-bin"), viper.GetString("vm-name")); err != nil {
return err
}
app.Log.Infof("Success! run 'ggt node run %s' to start the node", args[0])
return nil
},
}
cmd.Flags().String("ava-bin", "", "Location of dijetsnode binary (also AVA_BIN)")
cmd.Flags().String("vm-bin", "", "(optional) Location of subnetevm binary (also VM_BIN)")
cmd.Flags().String("vm-name", "subnetevm", "(optional) Name of vm (also VM_NAME)")
return cmd
}
func prepareWorkDir(workDir string, avaBin string, vmBin string, vmName string) error {
if _, err := os.Stat(workDir); err == nil {
return fmt.Errorf("%s exists, aborting", workDir)
}
err := mkDirs(workDir)
cobra.CheckErr(err)
dirStruct := utils.NewDirectoryLayout(workDir)
fileLocations := utils.NewFileLocations(workDir)
bash, err := prepareBashScript(workDir)
cobra.CheckErr(err)
app.Log.Infof("Creating %s", filepath.Join(workDir, configs.BashScriptFilename))
err = os.WriteFile(filepath.Join(workDir, configs.BashScriptFilename), []byte(bash), constants.DefaultPerms755)
cobra.CheckErr(err)
app.Log.Infof("Linking %s to %s", avaBin, fileLocations.AvaBinFile)
if err := utils.LinkFile(avaBin, fileLocations.AvaBinFile); err != nil {
return fmt.Errorf("failed linking file: %w", err)
}
// Copy configs from cur dir where `ggt init` put some defaults.
app.Log.Infof("Copying %s to %s", configs.NodeConfigFilename, fileLocations.ConfigFile)
err = utils.CopyFile(configs.NodeConfigFilename, fileLocations.ConfigFile)
cobra.CheckErr(err)
app.Log.Infof("Copying %s to %s", configs.CChainConfigFilename, fileLocations.CChainConfigFile)
err = utils.CopyFile(configs.CChainConfigFilename, fileLocations.CChainConfigFile)
cobra.CheckErr(err)
app.Log.Infof("Copying %s to %s", configs.XChainConfigFilename, fileLocations.XChainConfigFile)
err = utils.CopyFile(configs.XChainConfigFilename, fileLocations.XChainConfigFile)
cobra.CheckErr(err)
app.Log.Infof("Copying %s to %s", configs.AvaGenesisFilename, fileLocations.AvaGenesisFile)
err = utils.CopyFile(configs.AvaGenesisFilename, fileLocations.AvaGenesisFile)
cobra.CheckErr(err)
// Always write a vm aliases file even if empty to make avalanchego happy
vmAliases := "{}"
if vmBin != "" {
// TODO make this a fn
paddedBytes := [32]byte{}
copy(paddedBytes[:], []byte(vmName))
vmID, err := ids.ToID(paddedBytes[:])
if err != nil {
return err
}
fn := filepath.Join(dirStruct.PluginDir, vmID.String())
app.Log.Infof("Linking %s to %s", vmBin, fn)
if err := utils.LinkFile(vmBin, fn); err != nil {
return fmt.Errorf("failed linking file %w", err)
}
vmAliases, _ = sjson.Set("{}", vmID.String(), []string{vmName})
}
app.Log.Infof("Creating %s", fileLocations.VMAliasesFile)
err = os.WriteFile(fileLocations.VMAliasesFile, []byte(vmAliases), 0644)
cobra.CheckErr(err)
app.Log.Infof("Creating %s", fileLocations.ChainAliasesFile)
err = os.WriteFile(fileLocations.ChainAliasesFile, []byte("{}"), 0644)
cobra.CheckErr(err)
return err
}
type bashCmdParams struct {
utils.DirectoryLayout
utils.FileLocations
}
func prepareBashScript(workDir string) (string, error) {
layout := utils.NewDirectoryLayout("")
files := utils.NewFileLocations("")
params := bashCmdParams{layout, files}
bash := configs.StartBash
buf := &bytes.Buffer{}
t, err := template.New("").Parse(bash)
if err != nil {
return "", nil
}
err = t.Execute(buf, params)
return buf.String(), err
}
func mkDirs(workDir string) error {
dirStruct := utils.NewDirectoryLayout(workDir)
values := reflect.ValueOf(dirStruct)
for i := 0; i < values.NumField(); i++ {
err := os.MkdirAll(values.Field(i).String(), os.ModePerm)
if err != nil {
return err
}
}
return nil
}