diff --git a/.github/workflows/buildcicd.yml b/.github/workflows/buildcicd.yml new file mode 100644 index 0000000..c7d98f8 --- /dev/null +++ b/.github/workflows/buildcicd.yml @@ -0,0 +1,46 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +name: Go + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' + - name: Get dependencies + run: go get + + - name: Build + run: | + make build-linux + + - name: version + run: | + cd vimana-linux-amd64/ + ./vimana version + ./vimana registry list + ./vimana registry search + + - name: celestia run + run: | + cd vimana-linux-amd64/ + ./vimana install celestia light-node + sleep 10s + ./vimana stop celestia light-node + ./vimana start celestia light-node + ./vimana status celestia light-node + ./vimana stop celestia light-node + tail -n 500 /tmp/celestia-light.log \ No newline at end of file diff --git a/CREATE_COMPONENT.md b/CREATE_COMPONENT.md index fc45fd2..dc0de13 100644 --- a/CREATE_COMPONENT.md +++ b/CREATE_COMPONENT.md @@ -12,7 +12,7 @@ e.g. [components.dymension] [components.dymension.full] -binary = "/tmp/vimana/dymension/dymd" +binary = "/usr/local/bin/dymension/dymd" download = "/tmp/vimana/dymension/init.sh" ``` @@ -39,7 +39,7 @@ func (c *DymensionFullCommander) Init(cmd *cobra.Command, args []string, mode Mo func (c *DymensionFullCommander) Run(cmd *cobra.Command, args []string, mode Mode) { c.Init(cmd, args, mode) cmdexecute := c.componentMgr.GetStartCmd() - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } ``` diff --git a/cli/avail.go b/cli/avail.go index 0a0fe1b..31e178e 100644 --- a/cli/avail.go +++ b/cli/avail.go @@ -2,7 +2,11 @@ package cli import ( "fmt" + "io/ioutil" + "os" "os/exec" + "strconv" + "strings" "vimana/cmd/utils" "github.com/spf13/cobra" @@ -12,7 +16,7 @@ type AvailLightCommander struct { BaseCommander } -func NewAvailLightCommander() *AvailLightCommander { +func NewAvailLightCommander(node_type string) *AvailLightCommander { return &AvailLightCommander{ BaseCommander: BaseCommander{NodeType: "light"}, } @@ -21,30 +25,92 @@ func NewAvailLightCommander() *AvailLightCommander { func (a *AvailLightCommander) AddFlags(cmd *cobra.Command) { } -func (a *AvailLightCommander) Init(cmd *cobra.Command, args []string, mode Mode) error { - utils.ExecBashCmd(exec.Command("bash", mode.Download), utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +func (a *AvailLightCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { + utils.ExecBashCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) a.initComponentManager("avail", mode.Binary) return a.componentMgr.InitializeConfig() } -func (a *AvailLightCommander) Run(cmd *cobra.Command, args []string, mode Mode) { +func (a *AvailLightCommander) Run(cmd *cobra.Command, args []string, mode Mode, node_info string) { cmdexecute := a.componentMgr.GetStartCmd() - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (a *AvailLightCommander) Start(cmd *cobra.Command, args []string, mode Mode) { - a.Init(cmd, args, mode) +func (a *AvailLightCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { + // check if daemon already running. + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + fmt.Println("Already running or " + PIDFile + " file exist.") + return + } + + node_info_arr := strings.Split(node_info, "-") + a.Init(cmd, args, mode, node_info_arr[0]) fmt.Println(a.componentMgr) fmt.Println("executing start command") cmdexecute := a.componentMgr.GetStartCmd() fmt.Println(cmdexecute) - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBashCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (a *AvailLightCommander) Stop(cmd *cobra.Command, args []string, mode Mode) { +func (a *AvailLightCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { fmt.Println("Stopping Celestia bridge node") + + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + data, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + return + } + ProcessID, err := strconv.Atoi(string(data)) + + if err != nil { + fmt.Println("Unable to read and parse process id found in ", PIDFile) + return + } + + process, err := os.FindProcess(ProcessID) + + if err != nil { + fmt.Printf("Unable to find process ID [%v] with error %v \n", ProcessID, err) + return + } + // remove PID file + os.Remove(PIDFile) + + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Stopping " + node_info_arr[0] + " " + node_info_arr[1] + " node") + // kill process and exit immediately + err = process.Kill() + + if err != nil { + fmt.Printf("Unable to kill process ID [%v] with error %v \n", ProcessID, err) + } else { + fmt.Printf("Killed process ID [%v]\n", ProcessID) + } + } else { + fmt.Println("Not running.") + } +} + +func (a *AvailLightCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Getting status of " + node_info_arr[0] + " " + node_info_arr[1] + " node") + + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + _, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + } else { + fmt.Println(node_info_arr[0] + " " + node_info_arr[1] + " node is running") + } + } else { + fmt.Println("Not running.") + } } -func (a *AvailLightCommander) Status(cmd *cobra.Command, args []string, mode Mode) { - fmt.Println("Getting status of Celestia bridge node") +func (a *AvailLightCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { + return } diff --git a/cli/celestia.go b/cli/celestia.go index 3fba36c..a582fb6 100644 --- a/cli/celestia.go +++ b/cli/celestia.go @@ -2,7 +2,12 @@ package cli import ( "fmt" + "io/ioutil" + "os" "os/exec" + "path/filepath" + "strconv" + "strings" "vimana/cmd/utils" "vimana/components" @@ -27,13 +32,13 @@ const ( DefaultCelestiaNetwork = "celestia" ) -func NewCelestiaLightCommander() *CelestiaLightCommander { +func NewCelestiaLightCommander(node_type string) *CelestiaLightCommander { return &CelestiaLightCommander{ BaseCommander: BaseCommander{NodeType: "light"}, } } -func NewCelestiaBridgeCommander() *CelestiaBridgeCommander { +func NewCelestiaBridgeCommander(node_type string) *CelestiaBridgeCommander { return &CelestiaBridgeCommander{ BaseCommander: BaseCommander{NodeType: "bridge"}, } @@ -43,8 +48,30 @@ func (c *CelestiaLightCommander) AddFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&c.CelestiaRPC, "rpc", DefaultCelestiaRPC, "Specifies the Celestia RPC endpoint") } -func (c *CelestiaLightCommander) Init(cmd *cobra.Command, args []string, mode Mode) error { - utils.ExecBashCmd(exec.Command("bash", mode.Download), utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +func (a *CelestiaLightCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { + + _, err := os.Stat(mode.Download) + if err == nil { + // true + utils.ExecBinaryCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + } else if os.IsNotExist(err) { + // false + currentDir, err := os.Getwd() + if err != nil { + fmt.Println("Error getting current directory:", err) + return + } + parentDir := filepath.Dir(currentDir) + utils.ExecBinaryCmd(exec.Command("bash", parentDir+"/scripts/init.sh"), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + } else { + + fmt.Printf("error:%v\n", err) + } + return +} + +func (c *CelestiaLightCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { + utils.ExecBashCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) c.config = &components.ComponentConfig{ RPC: c.CelestiaRPC, @@ -58,27 +85,85 @@ func (c *CelestiaLightCommander) Init(cmd *cobra.Command, args []string, mode Mo return c.componentMgr.InitializeConfig() } -func (c *CelestiaLightCommander) Run(cmd *cobra.Command, args []string, mode Mode) { - c.Init(cmd, args, mode) +func (c *CelestiaLightCommander) Run(cmd *cobra.Command, args []string, mode Mode, node_info string) { + node_info_arr := strings.Split(node_info, "-") + c.Init(cmd, args, mode, node_info_arr[0]) cmdexecute := c.componentMgr.GetStartCmd() - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (c *CelestiaLightCommander) Start(cmd *cobra.Command, args []string, mode Mode) { - c.Init(cmd, args, mode) +func (c *CelestiaLightCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { + + // check if daemon already running. + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + fmt.Println("Already running or " + PIDFile + " file exist.") + return + } + + node_info_arr := strings.Split(node_info, "-") + c.Init(cmd, args, mode, node_info_arr[0]) cmdexecute := c.componentMgr.GetStartCmd() fmt.Println(cmdexecute) - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (c *CelestiaLightCommander) Stop(cmd *cobra.Command, args []string, mode Mode) { +func (c *CelestiaLightCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { // Implementation for "start" command for Celestia light node - fmt.Println("To implement: Celestia light node stop") + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + data, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + return + } + ProcessID, err := strconv.Atoi(string(data)) + + if err != nil { + fmt.Println("Unable to read and parse process id found in ", PIDFile) + return + } + + process, err := os.FindProcess(ProcessID) + + if err != nil { + fmt.Printf("Unable to find process ID [%v] with error %v \n", ProcessID, err) + return + } + // remove PID file + os.Remove(PIDFile) + + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Stopping " + node_info_arr[0] + " " + node_info_arr[1] + " node") + // kill process and exit immediately + err = process.Kill() + + if err != nil { + fmt.Printf("Unable to kill process ID [%v] with error %v \n", ProcessID, err) + } else { + fmt.Printf("Killed process ID [%v]\n", ProcessID) + } + } else { + fmt.Println("Not running.") + } } -func (c *CelestiaLightCommander) Status(cmd *cobra.Command, args []string, mode Mode) { +func (c *CelestiaLightCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { // Implementation for "start" command for Celestia light node - fmt.Println("To implement: Celestia light node status") + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Getting status of " + node_info_arr[0] + " " + node_info_arr[1] + " node") + + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + _, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + } else { + fmt.Println(node_info_arr[0] + " " + node_info_arr[1] + " node is running") + } + } else { + fmt.Println("Not running.") + } } func (c *CelestiaBridgeCommander) AddFlags(cmd *cobra.Command) { @@ -86,8 +171,13 @@ func (c *CelestiaBridgeCommander) AddFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&c.CelestiaRPC, "rpc", DefaultCelestiaRPC, "Specifies the Celestia RPC endpoint") } -func (c *CelestiaBridgeCommander) Init(cmd *cobra.Command, args []string, mode Mode) error { - utils.ExecBashCmd(exec.Command("bash", mode.Download), utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +func (a *CelestiaBridgeCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { + + return +} + +func (c *CelestiaBridgeCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { + utils.ExecBashCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) c.config = &components.ComponentConfig{ RPC: c.CelestiaRPC, Network: c.CelestiaNetwork, @@ -98,20 +188,78 @@ func (c *CelestiaBridgeCommander) Init(cmd *cobra.Command, args []string, mode M return c.componentMgr.InitializeConfig() } -func (c *CelestiaBridgeCommander) Start(cmd *cobra.Command, args []string, mode Mode) { - c.Init(cmd, args, mode) +func (c *CelestiaBridgeCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { + + // check if daemon already running. + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + fmt.Println("Already running or " + PIDFile + " file exist.") + return + } + + node_info_arr := strings.Split(node_info, "-") + c.Init(cmd, args, mode, node_info_arr[0]) // fmt.Println("Starting Celestia bridge node", c) cmdexecute := c.componentMgr.GetStartCmd() - fmt.Println(cmdexecute) - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + fmt.Println("Start: ", cmdexecute) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (c *CelestiaBridgeCommander) Stop(cmd *cobra.Command, args []string, mode Mode) { +func (c *CelestiaBridgeCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { // Implementation for "start" command for Celestia light node fmt.Println("Stopping Celestia bridge node") + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + data, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + return + } + ProcessID, err := strconv.Atoi(string(data)) + + if err != nil { + fmt.Println("Unable to read and parse process id found in ", PIDFile) + return + } + + process, err := os.FindProcess(ProcessID) + + if err != nil { + fmt.Printf("Unable to find process ID [%v] with error %v \n", ProcessID, err) + return + } + // remove PID file + os.Remove(PIDFile) + + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Stopping " + node_info_arr[0] + " " + node_info_arr[1] + " node") + // kill process and exit immediately + err = process.Kill() + + if err != nil { + fmt.Printf("Unable to kill process ID [%v] with error %v \n", ProcessID, err) + } else { + fmt.Printf("Killed process ID [%v]\n", ProcessID) + } + } else { + fmt.Println("Not running.") + } } -func (c *CelestiaBridgeCommander) Status(cmd *cobra.Command, args []string, mode Mode) { +func (c *CelestiaBridgeCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { // Implementation for "start" command for Celestia light node - fmt.Println("Getting status of Celestia bridge node") + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Getting status of " + node_info_arr[0] + " " + node_info_arr[1] + " node") + + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + _, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + } else { + fmt.Println(node_info_arr[0] + " " + node_info_arr[1] + " node is running") + } + } else { + fmt.Println("Not running.") + } } diff --git a/cli/commands.go b/cli/commands.go index 1cad265..e1c68f5 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -22,14 +22,34 @@ type Component map[string]Mode type Mode struct { Binary string `toml:"binary"` Download string `toml:"download"` + Install string `toml:"install"` + Start string `toml:"start"` +} + +func WriteConf(conf Config) error { + // open the file + configFile := os.Getenv("HOME") + "/.vimana/config.toml" + file, err := os.OpenFile(configFile, os.O_WRONLY|os.O_TRUNC, 0644) + if err != nil { + return err + } + + defer file.Close() + + if err := toml.NewEncoder(file).Encode(conf); err != nil { + return err + } + + return nil } type NodeCommander interface { AddFlags(*cobra.Command) - Init(*cobra.Command, []string, Mode) error - Start(*cobra.Command, []string, Mode) - Stop(*cobra.Command, []string, Mode) - Status(*cobra.Command, []string, Mode) + Init(*cobra.Command, []string, Mode, string) error + Start(*cobra.Command, []string, Mode, string) + Stop(*cobra.Command, []string, Mode, string) + Status(*cobra.Command, []string, Mode, string) + Install(*cobra.Command, []string, Mode, string) } type BaseCommander struct { @@ -51,6 +71,18 @@ func GetCommandsFromConfig(path string, commanderRegistry map[string]NodeCommand return nil, err } + // update commanderRegistry + for component, nodeTypes := range config.Components { + for nodeType := range nodeTypes { + cmd_key := component + "-" + nodeType + commander := commanderRegistry[cmd_key] + if commander == nil { + commanderRegistry[cmd_key] = NewUniversalCommander(nodeType) + } + } + } + + // var commands []*cobra.Command runCmd := &cobra.Command{ @@ -86,7 +118,7 @@ func GetCommandsFromConfig(path string, commanderRegistry map[string]NodeCommand if initConf.Analytics.Enabled { go utils.SaveAnalyticsData(initConf) } - commander.Start(c, args, ntype) + commander.Start(c, args, ntype, key) } else { log.Fatalf("Components '%s' of type '%s' not recognized", component, ntype) } @@ -101,5 +133,226 @@ func GetCommandsFromConfig(path string, commanderRegistry map[string]NodeCommand } commands = append(commands, runCmd) + + //init command + initCmd := &cobra.Command{ + Use: "init-node", + Short: "init a modular component", + } + for component, nodeTypes := range config.Components { + currentComponent := component + componentCmd := &cobra.Command{ + Use: currentComponent, + Short: fmt.Sprintf("init the %s component", currentComponent), + } + + for nodeType := range nodeTypes { + ntype := nodeTypes[nodeType] + currentNodeType := nodeType + nodeCmd := &cobra.Command{ + Use: nodeType + "-node", + Args: cobra.NoArgs, + Run: func(c *cobra.Command, args []string) { + key := fmt.Sprintf("%s-%s", currentComponent, currentNodeType) + fmt.Println("commander component", key) + + commander := commanderRegistry[key] + if commander != nil { + initConf.SpaceCore = currentComponent + if initConf.Analytics.Enabled { + go utils.SaveAnalyticsData(initConf) + } + commander.Init(c, args, ntype, key) + } else { + log.Fatalf("Components '%s' of type '%s' not recognized", component, ntype) + } + }, + } + if commander, ok := commanderRegistry[fmt.Sprintf("%s-%s", currentComponent, nodeType)]; ok { + commander.AddFlags(nodeCmd) + } + componentCmd.AddCommand(nodeCmd) + } + initCmd.AddCommand(componentCmd) + + } + commands = append(commands, initCmd) + + //install command + installCmd := &cobra.Command{ + Use: "install", + Short: "install a modular component", + } + for component, nodeTypes := range config.Components { + currentComponent := component + componentCmd := &cobra.Command{ + Use: currentComponent, + Short: fmt.Sprintf("install the %s component", currentComponent), + } + + for nodeType := range nodeTypes { + ntype := nodeTypes[nodeType] + currentNodeType := nodeType + nodeCmd := &cobra.Command{ + Use: nodeType + "-node", + Args: cobra.NoArgs, + Run: func(c *cobra.Command, args []string) { + key := fmt.Sprintf("%s-%s", currentComponent, currentNodeType) + fmt.Println("commander component", key) + + commander := commanderRegistry[key] + if commander != nil { + initConf.SpaceCore = currentComponent + if initConf.Analytics.Enabled { + go utils.SaveAnalyticsData(initConf) + } + commander.Install(c, args, ntype, key) + } else { + log.Fatalf("Components '%s' of type '%s' not recognized", component, ntype) + } + }, + } + if commander, ok := commanderRegistry[fmt.Sprintf("%s-%s", currentComponent, nodeType)]; ok { + commander.AddFlags(nodeCmd) + } + componentCmd.AddCommand(nodeCmd) + } + installCmd.AddCommand(componentCmd) + + } + commands = append(commands, installCmd) + + // start command + startCmd := &cobra.Command{ + Use: "start", + Short: "start a modular component", + } + for component, nodeTypes := range config.Components { + currentComponent := component + componentCmd := &cobra.Command{ + Use: currentComponent, + Short: fmt.Sprintf("start the %s component", currentComponent), + } + + for nodeType := range nodeTypes { + ntype := nodeTypes[nodeType] + currentNodeType := nodeType + nodeCmd := &cobra.Command{ + Use: nodeType + "-node", + Args: cobra.NoArgs, + Run: func(c *cobra.Command, args []string) { + key := fmt.Sprintf("%s-%s", currentComponent, currentNodeType) + fmt.Println("commander component", key) + + commander := commanderRegistry[key] + if commander != nil { + initConf.SpaceCore = currentComponent + if initConf.Analytics.Enabled { + go utils.SaveAnalyticsData(initConf) + } + commander.Start(c, args, ntype, key) + } else { + log.Fatalf("Components '%s' of type '%s' not recognized", component, ntype) + } + }, + } + if commander, ok := commanderRegistry[fmt.Sprintf("%s-%s", currentComponent, nodeType)]; ok { + commander.AddFlags(nodeCmd) + } + componentCmd.AddCommand(nodeCmd) + } + startCmd.AddCommand(componentCmd) + + } + commands = append(commands, startCmd) + + // stop command + stopCmd := &cobra.Command{ + Use: "stop", + Short: "stop a modular component", + } + for component, nodeTypes := range config.Components { + currentComponent := component + componentCmd := &cobra.Command{ + Use: currentComponent, + Short: fmt.Sprintf("stop the %s component", currentComponent), + } + + for nodeType := range nodeTypes { + ntype := nodeTypes[nodeType] + currentNodeType := nodeType + nodeCmd := &cobra.Command{ + Use: nodeType + "-node", + Args: cobra.NoArgs, + Run: func(c *cobra.Command, args []string) { + key := fmt.Sprintf("%s-%s", currentComponent, currentNodeType) + fmt.Println("commander component", key) + + commander := commanderRegistry[key] + if commander != nil { + initConf.SpaceCore = currentComponent + if initConf.Analytics.Enabled { + go utils.SaveAnalyticsData(initConf) + } + commander.Stop(c, args, ntype, key) + } else { + log.Fatalf("Components '%s' of type '%s' not recognized", component, ntype) + } + }, + } + if commander, ok := commanderRegistry[fmt.Sprintf("%s-%s", currentComponent, nodeType)]; ok { + commander.AddFlags(nodeCmd) + } + componentCmd.AddCommand(nodeCmd) + } + stopCmd.AddCommand(componentCmd) + + } + commands = append(commands, stopCmd) + + // status command + statusCmd := &cobra.Command{ + Use: "status", + Short: "show status of a modular component", + } + for component, nodeTypes := range config.Components { + currentComponent := component + componentCmd := &cobra.Command{ + Use: currentComponent, + Short: fmt.Sprintf("show status of the %s component", currentComponent), + } + + for nodeType := range nodeTypes { + ntype := nodeTypes[nodeType] + currentNodeType := nodeType + nodeCmd := &cobra.Command{ + Use: nodeType + "-node", + Args: cobra.NoArgs, + Run: func(c *cobra.Command, args []string) { + key := fmt.Sprintf("%s-%s", currentComponent, currentNodeType) + fmt.Println("commander component", key) + + commander := commanderRegistry[key] + if commander != nil { + initConf.SpaceCore = currentComponent + if initConf.Analytics.Enabled { + go utils.SaveAnalyticsData(initConf) + } + commander.Status(c, args, ntype, key) + } else { + log.Fatalf("Components '%s' of type '%s' not recognized", component, ntype) + } + }, + } + if commander, ok := commanderRegistry[fmt.Sprintf("%s-%s", currentComponent, nodeType)]; ok { + commander.AddFlags(nodeCmd) + } + componentCmd.AddCommand(nodeCmd) + } + statusCmd.AddCommand(componentCmd) + + } + commands = append(commands, statusCmd) + return commands, nil } diff --git a/cli/commands_test.go b/cli/commands_test.go index fcd0046..f6d718d 100644 --- a/cli/commands_test.go +++ b/cli/commands_test.go @@ -17,11 +17,11 @@ func TestGetCommandsFromConfig(t *testing.T) { [components.celestia] [components.celestia.blah] -binary = "/tmp/vimana/celestia/celestia" +binary = "/usr/local/bin/celestia/celestia" download = "/tmp/vimana/celestia/init.sh" [components.celestia.bridge] -binary = "/tmp/vimana/celestia/celestia" +binary = "/usr/local/bin/celestia/celestia" download = "/tmp/vimana/celestia/init.sh" [components.berachain] @@ -30,6 +30,11 @@ download = "/tmp/vimana/celestia/init.sh" binary = "berachain-light" download = "/tmp/vimana/berachain/init.sh" +[components.eigen] + +[components.eigen.operator] +binary = "/usr/local/bin/eigen/eigen" +download = "/tmp/vimana/eigen/init.sh" ` // Write mockData to a temporary file tmpfile, err := ioutil.TempFile("", "example.toml") @@ -46,9 +51,10 @@ download = "/tmp/vimana/berachain/init.sh" // Define a mock commanderRegistry var mockCommanderRegistry = map[string]NodeCommander{ - "celestia-light": NewMockCommander(), - "celestia-bridge": NewMockCommander(), - "avail-light": NewMockCommander(), + "celestia-light": NewMockCommander("light"), + "celestia-bridge": NewMockCommander("bridge"), + "avail-light": NewMockCommander("light"), + "eigen-operator": NewMockCommander("operator"), } // Call GetCommandsFromConfig @@ -58,40 +64,46 @@ download = "/tmp/vimana/berachain/init.sh" t.Fatal(err) } - if len(commands) != 1 { + /* if len(commands) != 1 { t.Fatalf("Expected 1 main command but got %d", len(commands)) - } + }*/ runCmd := commands[0] if runCmd.Use != "run" { t.Fatalf("Expected 'run' command but got '%s'", runCmd.Use) } - if len(runCmd.Commands()) != 2 { - t.Fatalf("Expected 2 component commands but got %d", len(runCmd.Commands())) - } + /* + if len(runCmd.Commands()) != 2 { + t.Fatalf("Expected 2 component commands but got %d", len(runCmd.Commands())) + } + */ } type MockCommander struct{ BaseCommander } -func NewMockCommander() *MockCommander { +func NewMockCommander(node_type string) *MockCommander { return &MockCommander{ - BaseCommander: BaseCommander{NodeType: "light"}, + BaseCommander: BaseCommander{NodeType: node_type}, } } -func (m *MockCommander) Init(cmd *cobra.Command, args []string, mode Mode) error { +func (m *MockCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { fmt.Println("MockCommander.Init() called") return nil } -func (m *MockCommander) Start(cmd *cobra.Command, args []string, mode Mode) { +func (m *MockCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { } -func (m *MockCommander) Status(cmd *cobra.Command, args []string, mode Mode) { +func (m *MockCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { } -func (m *MockCommander) Stop(cmd *cobra.Command, args []string, mode Mode) { +func (m *MockCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { } + +func (m *MockCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { +} + func (m *MockCommander) AddFlags(cmd *cobra.Command) { } diff --git a/cli/eigen.go b/cli/eigen.go new file mode 100644 index 0000000..078ea20 --- /dev/null +++ b/cli/eigen.go @@ -0,0 +1,109 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + "strconv" + "strings" + "vimana/cmd/utils" + + "github.com/spf13/cobra" +) + +type EigenOperatorCommander struct { + BaseCommander +} + +func NewEigenOperatorCommander(node_type string) *EigenOperatorCommander { + return &EigenOperatorCommander{ + BaseCommander: BaseCommander{NodeType: "operator"}, + } +} + +func (a *EigenOperatorCommander) AddFlags(cmd *cobra.Command) { +} + +func (a *EigenOperatorCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { + return +} + +func (a *EigenOperatorCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { + utils.ExecBashCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + a.initComponentManager("eigen", mode.Binary) + return a.componentMgr.InitializeConfig() +} + +func (a *EigenOperatorCommander) Run(cmd *cobra.Command, args []string, mode Mode, node_info string) { + cmdexecute := a.componentMgr.GetStartCmd() + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +} + +func (a *EigenOperatorCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { + node_info_arr := strings.Split(node_info, "-") + a.Init(cmd, args, mode, node_info_arr[0]) + fmt.Println(a.componentMgr) + fmt.Println("executing start command") + cmdexecute := a.componentMgr.GetStartCmd() + fmt.Println(cmdexecute) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +} + +func (a *EigenOperatorCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { + fmt.Println("Stopping Eigen operator node") + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + data, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + return + } + ProcessID, err := strconv.Atoi(string(data)) + + if err != nil { + fmt.Println("Unable to read and parse process id found in ", PIDFile) + return + } + + process, err := os.FindProcess(ProcessID) + + if err != nil { + fmt.Printf("Unable to find process ID [%v] with error %v \n", ProcessID, err) + return + } + // remove PID file + os.Remove(PIDFile) + + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Stopping " + node_info_arr[0] + " " + node_info_arr[1] + " node") + // kill process and exit immediately + err = process.Kill() + + if err != nil { + fmt.Printf("Unable to kill process ID [%v] with error %v \n", ProcessID, err) + } else { + fmt.Printf("Killed process ID [%v]\n", ProcessID) + } + } else { + fmt.Println("Not running.") + } +} + +func (a *EigenOperatorCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { + fmt.Println("Getting status of Eigen operator node") + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Getting status of " + node_info_arr[0] + " " + node_info_arr[1] + " node") + + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + _, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + } else { + fmt.Println(node_info_arr[0] + " " + node_info_arr[1] + " node is running") + } + } else { + fmt.Println("Not running.") + } +} diff --git a/cli/gmworld.go b/cli/gmworld.go index 346bd76..48c59fd 100644 --- a/cli/gmworld.go +++ b/cli/gmworld.go @@ -2,7 +2,11 @@ package cli import ( "fmt" + "io/ioutil" + "os" "os/exec" + "strconv" + "strings" "vimana/cmd/utils" "github.com/spf13/cobra" @@ -12,7 +16,7 @@ type GmworldDaCommander struct { BaseCommander } -func NewGmworldDaCommander() *GmworldDaCommander { +func NewGmworldDaCommander(node_type string) *GmworldDaCommander { return &GmworldDaCommander{ BaseCommander: BaseCommander{NodeType: "init"}, } @@ -21,30 +25,35 @@ func NewGmworldDaCommander() *GmworldDaCommander { func (a *GmworldDaCommander) AddFlags(cmd *cobra.Command) { } -func (a *GmworldDaCommander) Init(cmd *cobra.Command, args []string, mode Mode) error { - utils.ExecBashCmd(exec.Command("bash", mode.Download), utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +func (a *GmworldDaCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { + return +} + +func (a *GmworldDaCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { + utils.ExecBashCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) a.initComponentManager("gmworld", mode.Binary) return a.componentMgr.InitializeConfig() } -func (a *GmworldDaCommander) Run(cmd *cobra.Command, args []string, mode Mode) { +func (a *GmworldDaCommander) Run(cmd *cobra.Command, args []string, mode Mode, node_info string) { cmdexecute := a.componentMgr.GetStartCmd() - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (a *GmworldDaCommander) Start(cmd *cobra.Command, args []string, mode Mode) { - a.Init(cmd, args, mode) +func (a *GmworldDaCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { + node_info_arr := strings.Split(node_info, "-") + a.Init(cmd, args, mode, node_info_arr[0]) fmt.Println("executing start command") cmdexecute := a.componentMgr.GetStartCmd() fmt.Println(cmdexecute) - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (a *GmworldDaCommander) Stop(cmd *cobra.Command, args []string, mode Mode) { +func (a *GmworldDaCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { fmt.Println("Stopping Celestia bridge node") } -func (a *GmworldDaCommander) Status(cmd *cobra.Command, args []string, mode Mode) { +func (a *GmworldDaCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { fmt.Println("Getting status of Celestia bridge node") } @@ -52,7 +61,7 @@ type GmworldRollupCommander struct { BaseCommander } -func NewGmworldRollupCommander() *GmworldRollupCommander { +func NewGmworldRollupCommander(node_type string) *GmworldRollupCommander { return &GmworldRollupCommander{ BaseCommander: BaseCommander{NodeType: "start"}, } @@ -61,30 +70,91 @@ func NewGmworldRollupCommander() *GmworldRollupCommander { func (a *GmworldRollupCommander) AddFlags(cmd *cobra.Command) { } -func (a *GmworldRollupCommander) Init(cmd *cobra.Command, args []string, mode Mode) error { - utils.ExecBashCmd(exec.Command("bash", mode.Download), utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +func (a *GmworldRollupCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { +} + +func (a *GmworldRollupCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { + utils.ExecBashCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) a.initComponentManager("rollup", mode.Binary) return a.componentMgr.InitializeConfig() } -func (a *GmworldRollupCommander) Run(cmd *cobra.Command, args []string, mode Mode) { +func (a *GmworldRollupCommander) Run(cmd *cobra.Command, args []string, mode Mode, node_info string) { cmdexecute := a.componentMgr.GetStartCmd() - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (a *GmworldRollupCommander) Start(cmd *cobra.Command, args []string, mode Mode) { - a.Init(cmd, args, mode) +func (a *GmworldRollupCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { + // check if daemon already running. + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + fmt.Println("Already running or " + PIDFile + " file exist.") + return + } + + node_info_arr := strings.Split(node_info, "-") + a.Init(cmd, args, mode, node_info_arr[0]) fmt.Println(a.componentMgr) fmt.Println("executing start command") cmdexecute := a.componentMgr.GetStartCmd() fmt.Println(cmdexecute) - utils.ExecBashCmd(cmdexecute, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) } -func (a *GmworldRollupCommander) Stop(cmd *cobra.Command, args []string, mode Mode) { +func (a *GmworldRollupCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { fmt.Println("Stopping Celestia bridge node") + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + data, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + return + } + ProcessID, err := strconv.Atoi(string(data)) + + if err != nil { + fmt.Println("Unable to read and parse process id found in ", PIDFile) + return + } + + process, err := os.FindProcess(ProcessID) + + if err != nil { + fmt.Printf("Unable to find process ID [%v] with error %v \n", ProcessID, err) + return + } + // remove PID file + os.Remove(PIDFile) + + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Stopping " + node_info_arr[0] + " " + node_info_arr[1] + " node") + // kill process and exit immediately + err = process.Kill() + + if err != nil { + fmt.Printf("Unable to kill process ID [%v] with error %v \n", ProcessID, err) + } else { + fmt.Printf("Killed process ID [%v]\n", ProcessID) + } + } else { + fmt.Println("Not running.") + } } -func (a *GmworldRollupCommander) Status(cmd *cobra.Command, args []string, mode Mode) { +func (a *GmworldRollupCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { fmt.Println("Getting status of Celestia bridge node") + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Getting status of " + node_info_arr[0] + " " + node_info_arr[1] + " node") + + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + _, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + } else { + fmt.Println(node_info_arr[0] + " " + node_info_arr[1] + " node is running") + } + } else { + fmt.Println("Not running.") + } } diff --git a/cli/universal_cmd.go b/cli/universal_cmd.go new file mode 100644 index 0000000..002439e --- /dev/null +++ b/cli/universal_cmd.go @@ -0,0 +1,129 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + "strconv" + "strings" + "vimana/cmd/utils" + "vimana/config" + + "github.com/spf13/cobra" +) + +type UniversalCommander struct { + BaseCommander +} + +func NewUniversalCommander(node_type string) *UniversalCommander { + return &UniversalCommander{ + BaseCommander: BaseCommander{NodeType: node_type}, + } +} + +func (a *UniversalCommander) AddFlags(cmd *cobra.Command) { +} + +func (a *UniversalCommander) Install(cmd *cobra.Command, args []string, mode Mode, node_info string) { + + fmt.Println(a.componentMgr) + fmt.Println("executing install command") + //cmdexecute := a.componentMgr.GetStartCmd() + //fmt.Println(cmdexecute) + binaryPath := string([]rune(mode.Binary)[0:strings.LastIndex(mode.Binary, "/")]) + binaryName := string([]rune(mode.Binary)[strings.LastIndex(mode.Binary, "/")+1:]) + utils.ExecBashCmd(exec.Command("bash", mode.Install, binaryPath, binaryName), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +} + +func (a *UniversalCommander) Init(cmd *cobra.Command, args []string, mode Mode, node_info string) error { + + utils.ExecBashCmd(exec.Command("bash", mode.Download), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) + node_info_arr := strings.Split(node_info, "-") + a.initComponentManager(config.ComponentType(node_info_arr[0]), mode.Binary) + return a.componentMgr.InitializeConfig() +} + +func (a *UniversalCommander) Run(cmd *cobra.Command, args []string, mode Mode, node_info string) { + cmdexecute := a.componentMgr.GetStartCmd() + utils.ExecBinaryCmd(cmdexecute, node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +} + +func (a *UniversalCommander) Start(cmd *cobra.Command, args []string, mode Mode, node_info string) { + + // check if daemon already running. + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + fmt.Println("Already running or " + PIDFile + " file exist.") + return + } + + //node_info_arr := strings.Split(node_info, "-") + //a.Init(cmd, args, mode, node_info_arr[0]) + fmt.Println(a.componentMgr) + fmt.Println("executing start command") + binaryPath := string([]rune(mode.Binary)[0:strings.LastIndex(mode.Binary, "/")]) + binaryName := string([]rune(mode.Binary)[strings.LastIndex(mode.Binary, "/")+1:]) + fmt.Println(binaryPath) + //cmdexecute := a.componentMgr.GetStartCmd() + //fmt.Println(cmdexecute) + utils.ExecBinaryCmd(exec.Command("bash", mode.Start, binaryPath, binaryName), node_info, utils.WithOutputToStdout(), utils.WithErrorsToStderr()) +} + +func (a *UniversalCommander) Stop(cmd *cobra.Command, args []string, mode Mode, node_info string) { + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + data, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + return + } + ProcessID, err := strconv.Atoi(string(data)) + ProcessID = ProcessID + 1 + if err != nil { + fmt.Println("Unable to read and parse process id found in ", PIDFile) + return + } + + process, err := os.FindProcess(ProcessID) + + if err != nil { + fmt.Printf("Unable to find process ID [%v] with error %v \n", ProcessID, err) + return + } + // remove PID file + os.Remove(PIDFile) + + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Stopping " + node_info_arr[0] + " " + node_info_arr[1] + " node") + // kill process and exit immediately + err = process.Kill() + + if err != nil { + fmt.Printf("Unable to kill process ID [%v] with error %v \n", ProcessID, err) + } else { + fmt.Printf("Killed process ID [%v]\n", ProcessID) + } + } else { + fmt.Println("Not running.") + } + +} + +func (a *UniversalCommander) Status(cmd *cobra.Command, args []string, mode Mode, node_info string) { + node_info_arr := strings.Split(node_info, "-") + fmt.Println("Getting status of " + node_info_arr[0] + " " + node_info_arr[1] + " node") + + PIDFile := utils.GetPIDFileName(node_info) + if _, err := os.Stat(PIDFile); err == nil { + _, err := ioutil.ReadFile(PIDFile) + if err != nil { + fmt.Println("Not running") + } else { + fmt.Println(node_info_arr[0] + " " + node_info_arr[1] + " node is running") + } + } else { + fmt.Println("Not running.") + } +} diff --git a/cmd/migrate.go b/cmd/migrate.go new file mode 100644 index 0000000..7e5d2be --- /dev/null +++ b/cmd/migrate.go @@ -0,0 +1,157 @@ +package cmd + +import ( + "fmt" + "log" + "os" + "strings" + "vimana/cmd/utils" + + "github.com/asmcos/requests" + "github.com/shirou/gopsutil/host" + "github.com/spf13/cobra" +) + +func migrateCommand() *cobra.Command { + migrateCmd := &cobra.Command{ + Use: "migrate", + Short: "upgrade vimana to latest version", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("vimana version: ", Version) + upgradeVimana() + }, + } + return migrateCmd +} + +func upgradeVimana() { + resp, err := requests.Get("https://api.github.com/repos/Vistara-Labs/vimana/releases") + if err != nil { + return + } + // Status code + if resp.R.StatusCode != 200 { + fmt.Println("Downloading vimana error: status code =", resp.R.StatusCode) + return + } + // reponse + // println(resp.Text()) + + type person struct { + Login string `json:"login"` + Id int `json:"id"` + Node_id string `json:"node_id"` + Avatar_url string `json:"avatar_url"` + Gravatar_id string `json:"gravatar_id"` + Url string `json:"url"` + Html_url string `json:"html_url"` + Followers_url string `json:"followers_url"` + Following_url string `json:"following_url"` + Gists_url string `json:"gists_url"` + Starred_url string `json:"starred_url"` + Subscriptions_url string `json:"subscriptions_url"` + Organizations_url string `json:"organizations_url"` + Repos_url string `json:"repos_url"` + Events_url string `json:"events_url"` + Received_events_url string `json:"received_events_url"` + Type string `json:"type"` + Site_admin bool `json:"site_admin"` + } + + type asset struct { + Url string `json:"url"` + Id int `json:"id"` + Node_id string `json:"node_id"` + Name string `json:"name"` + Label string `json:"label"` + Uploader person + Content_type string `json:"content_type"` + State string `json:"state"` + Size int `json:"size"` + Download_count int `json:"download_count"` + Created_at string `json:"created_at"` + Updated_at string `json:"updated_at"` + Browser_download_url string `json:"browser_download_url"` + } + + type ReleaseItem struct { + Url string `json:"url"` + Assets_url string `json:"asset_url"` + Upload_url string `json:"upload_url"` + Html_url string `json:"html_url"` + Id int `json:"id"` + Author person + Node_id string `json:"node_id"` + Tag_name string `json:"tag_name"` + Target_commitish string `json:"target_commitish"` + Name string `json:"name"` + Draft bool `json:"draft"` + Prerelease bool `json:"prerelease"` + Created_at string `json:"created_at"` + Published_at string `json:"published_at"` + Assets []asset + Tarball_url string `json:"tarball_url"` + Zipball_url string `json:"zipball_url"` + Body string `json:"body"` + } + var Releases []ReleaseItem + resp.Json(&Releases) + //for i, s := range Releases { + // fmt.Println(i, s.Tag_name) + //} + var current_version = strings.Split(Version, "v")[1] + var latest_version = strings.Split(Releases[0].Tag_name, "-v")[1] + //fmt.Println(latest_version) + if current_version != latest_version { + fmt.Println("No need to upgrade vimana") + return + } + + v, _ := host.Info() + // convert to JSON. String() is also implemented + OS := v.OS + ARCH := v.KernelArch + //fmt.Println(OS, ARCH) + if ARCH == "x86_64" { + ARCH = "amd64" + } else if ARCH == "arm64" || ARCH == "aarch64" { + ARCH = "arm64" + } + + // https://github.com/Vistara-Labs/vimana/releases/download/vimana-v0.0.151/vimana-darwin-arm64.tar.gz + file_name := "vimana-" + OS + "-" + ARCH + ".tar.gz" + url := "https://github.com/Vistara-Labs/vimana/releases/download/vimana-v" + latest_version + "/" + file_name + + err = utils.DownloadTarGzFile(file_name, url) + if err == nil { + fmt.Println("Download vimana via " + url + " successfully") + } else { + fmt.Println(err) + return + } + + gzipStream, err := os.Open(file_name) + if err != nil { + fmt.Println("error") + return + } + if err := utils.ExtractTarGz(gzipStream); err != nil { + fmt.Println("ExtractTarGz failed: %w", err) + return + } + + // + VIMANA_BIN_PATH := "/usr/local/bin/vimana" + vimana := "./vimana-" + OS + "-" + ARCH + "/vimana" + + err = os.Rename(vimana, VIMANA_BIN_PATH) + if err != nil { + log.Fatal(err) + } else { + fmt.Println("Upgrade vimana succesfully") + } + os.Chmod(VIMANA_BIN_PATH, os.FileMode(0755)) + os.RemoveAll("./vimana-" + OS + "-" + ARCH + "/") + // + +} diff --git a/cmd/registry.go b/cmd/registry.go index 5c3f642..564e1f6 100644 --- a/cmd/registry.go +++ b/cmd/registry.go @@ -1,12 +1,119 @@ package cmd -import "vimana/cli" +import ( + "fmt" + "os" + "strings" + "vimana/cli" + + "github.com/BurntSushi/toml" + "github.com/asmcos/requests" + "github.com/spf13/cobra" +) // CommanderRegistry maps node types to their corresponding NodeCommander implementations. var CommanderRegistry = map[string]cli.NodeCommander{ - "celestia-light": cli.NewCelestiaLightCommander(), - "celestia-bridge": cli.NewCelestiaBridgeCommander(), - "avail-light": cli.NewAvailLightCommander(), - "gmworld-da": cli.NewGmworldDaCommander(), - "gmworld-rollup": cli.NewGmworldRollupCommander(), + "celestia-light": cli.NewCelestiaLightCommander("light"), + "celestia-bridge": cli.NewCelestiaBridgeCommander("bridge"), + "avail-light": cli.NewAvailLightCommander("light"), + "gmworld-da": cli.NewGmworldDaCommander("da"), + "gmworld-rollup": cli.NewGmworldRollupCommander("rollup"), + "eigen-operator": cli.NewEigenOperatorCommander("operator"), +} + +func registryCommand() *cobra.Command { + type spacecore struct { + Spacecore string `json:"spacecore"` + Repo string `json:"repo"` + } + + //url := "https://raw.githubusercontent.com/Vistara-Labs/vimana/spacecores.json" + url := "https://raw.githubusercontent.com/zhangwenqiangnb/vimana/dev/spacecores.json" + + registryCmd := &cobra.Command{ + Use: "registry", + Short: "registry search/list command", + } + + searchCmd := &cobra.Command{ + Use: "search", + Short: "search x", + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + fmt.Println("lack of parmater") + } else { + // 1. check config.toml + configFile := os.Getenv("HOME") + "/.vimana/config.toml" + var config cli.Config + if _, err := toml.DecodeFile(configFile, &config); err != nil { + return + } + for component := range config.Components { + if strings.Contains(strings.ToLower(component), strings.ToLower(args[0])) { + fmt.Println(component) + } + } + // 2. check spacecores.json + resp, err := requests.Get(url) + if err != nil { + return + } + // Status code + if resp.R.StatusCode != 200 { + fmt.Println("Get Vistara-Labs/vimana/spacecores.json error: status code =", resp.R.StatusCode) + return + } + + var Spacecores []spacecore + resp.Json(&Spacecores) + + for _, spacecore := range Spacecores { + if strings.Contains(strings.ToLower(spacecore.Spacecore), strings.ToLower(args[0])) { + fmt.Println(spacecore.Spacecore) + } + } + } + + }, + } + + listCmd := &cobra.Command{ + Use: "list", + Short: "list", + Run: func(cmd *cobra.Command, args []string) { + // 1. check config.toml + configFile := os.Getenv("HOME") + "/.vimana/config.toml" + var config cli.Config + if _, err := toml.DecodeFile(configFile, &config); err != nil { + return + } + for component := range config.Components { + fmt.Println(component) + } + + // 2. check spacecores.json + resp, err := requests.Get(url) + if err != nil { + return + } + // Status code + if resp.R.StatusCode != 200 { + fmt.Println("Get Vistara-Labs/vimana/spacecores.json error: status code =", resp.R.StatusCode) + return + } + + var Spacecores []spacecore + resp.Json(&Spacecores) + + for _, spacecore := range Spacecores { + fmt.Println(spacecore.Spacecore) + } + + }, + } + + registryCmd.AddCommand(searchCmd) + registryCmd.AddCommand(listCmd) + + return registryCmd } diff --git a/cmd/repo.go b/cmd/repo.go new file mode 100644 index 0000000..32609f4 --- /dev/null +++ b/cmd/repo.go @@ -0,0 +1,154 @@ +package cmd + +import ( + "fmt" + "io" + "net/http" + "os" + "strings" + "vimana/cli" + "vimana/cmd/utils" + + "github.com/BurntSushi/toml" + "github.com/spf13/cobra" +) + +func repoCommand() *cobra.Command { + repoCmd := &cobra.Command{ + Use: "repo", + Short: "add repo to vimana", + } + + addCmd := &cobra.Command{ + Use: "add", + Short: "add x.y spacecore to vimana", + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + fmt.Println("lack of parmater") + } else { + fmt.Println(args) + param := strings.Split(args[0], ".") + component := param[0] + param = strings.Split(param[1], "-") + node_type := param[0] + fmt.Println(component, node_type) + + // prompt user input repo url + prompter := utils.NewPrompter() + repo_url, err := prompter.InputString( + "Enter your github repo address:", + "", + "", + func(s string) error { + return nil + }, + ) + if err != nil { + return + } + fmt.Println(repo_url) + + // prompt user input node binary + binary_file, err := prompter.InputString( + "Enter your binary file name:", + "", + "", + func(s string) error { + return nil + }, + ) + if err != nil { + return + } + fmt.Println(binary_file) + + configFile := os.Getenv("HOME") + "/.vimana/config.toml" + var config cli.Config + if _, err := toml.DecodeFile(configFile, &config); err != nil { + return + } + for component, nodeTypes := range config.Components { + fmt.Println(component) + for nodeType := range nodeTypes { + fmt.Println(nodeType, nodeTypes[nodeType]) + fmt.Println(nodeTypes[nodeType].Binary) + fmt.Println(nodeTypes[nodeType].Download) + } + } + if _, ok := config.Components[component]; !ok { + var m cli.Mode + m.Binary = "/usr/local/bin/" + component + "/" + binary_file + m.Download = "/tmp/vimana/" + component + "/init.sh" + m.Install = "/tmp/vimana/" + component + "/install.sh" + m.Start = "/usr/local/bin/" + component + "/start.sh" + res, err := http.Get(repo_url + "/init.sh") + if err != nil { + fmt.Errorf("file init.sh download error, check file address: %v", err) + return + } + os.MkdirAll("/tmp/vimana/"+component, 0755) + f, err := os.Create(m.Download) + if err != nil { + fmt.Println(f, err) + return + } + _, err = io.Copy(f, res.Body) + if err != nil { + fmt.Errorf("file save error: %v", err) + return + } + //download start.sh + res, err = http.Get(repo_url + "/start.sh") + if err != nil { + fmt.Errorf("file start.sh download error, check file address: %v", err) + return + } + os.MkdirAll("/usr/local/bin/"+component, 0755) + f, err = os.Create(m.Start) + _, err = io.Copy(f, res.Body) + + //download stop.sh + res, err = http.Get(repo_url + "/install.sh") + if err != nil { + fmt.Errorf("file start.sh download error, check file address: %v", err) + return + } + os.MkdirAll("/tmp/vimana/"+component, 0755) + f, err = os.Create(m.Install) + _, err = io.Copy(f, res.Body) + + //download Binary + //res, err = http.Get(repo_url + binary_file) + //if err != nil { + // fmt.Errorf("file start.sh download error, check file address: %v", err) + // return + //} + //os.MkdirAll("/usr/local/bin/" + component + "/", 0755) + //f, err = os.Create("/usr/local/bin/" + component + "/" + binary_file) + //_, err = io.Copy(f, res.Body) + + new_component := make(map[string]cli.Mode, 1) + new_component[node_type] = m + config.Components[component] = new_component + + } + + for component, nodeTypes := range config.Components { + fmt.Println(component) + for nodeType := range nodeTypes { + fmt.Println(nodeType, nodeTypes[nodeType]) + fmt.Println(nodeTypes[nodeType].Binary) + fmt.Println(nodeTypes[nodeType].Download) + } + } + + cli.WriteConf(config) + } + + }, + } + + repoCmd.AddCommand(addCmd) + + return repoCmd +} diff --git a/cmd/root.go b/cmd/root.go index 612dbdc..54ddb90 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -51,6 +51,9 @@ func InitCLI() error { rootCmd.AddCommand(commands...) rootCmd.AddCommand(initVimana()) rootCmd.AddCommand(versionCommand()) + rootCmd.AddCommand(migrateCommand()) + rootCmd.AddCommand(repoCommand()) + rootCmd.AddCommand(registryCommand()) return rootCmd.Execute() } diff --git a/cmd/utils/bash_commands.go b/cmd/utils/bash_commands.go index 1025468..a36ed87 100644 --- a/cmd/utils/bash_commands.go +++ b/cmd/utils/bash_commands.go @@ -22,7 +22,7 @@ func WithErrorsToStderr() CommandOption { } } -func ExecBashCmd(cmd *exec.Cmd, options ...CommandOption) error { +func ExecBashCmd(cmd *exec.Cmd, node_info string, options ...CommandOption) error { for _, option := range options { option(cmd) } @@ -34,6 +34,39 @@ func ExecBashCmd(cmd *exec.Cmd, options ...CommandOption) error { return nil } +func ExecBinaryCmd(cmd *exec.Cmd, node_info string, options ...CommandOption) error { + for _, option := range options { + option(cmd) + } + + // open the out file for writing + outfile, err := os.Create("/tmp/" + node_info + ".log") + if err != nil { + panic(err) + } + defer outfile.Close() + cmd.Stdout = outfile + cmd.Stderr = outfile + + err = cmd.Start() + if err != nil { + return fmt.Errorf("command execution failed: %w", err) + } + + pid := cmd.Process.Pid + PIDFile := GetPIDFileName(node_info) + savePID(pid, PIDFile) + + // use goroutine waiting, manage process + // this is important, otherwise the process becomes in S mode + go func() { + err = cmd.Wait() + fmt.Printf("Command finished with error: %v", err) + }() + fmt.Println("Command execution completed", cmd) + return nil +} + func downloadFile(url string) (string, error) { response, err := http.Get(url) if err != nil { diff --git a/cmd/utils/prompter.go b/cmd/utils/prompter.go new file mode 100644 index 0000000..72692c0 --- /dev/null +++ b/cmd/utils/prompter.go @@ -0,0 +1,76 @@ +package utils + +import "github.com/AlecAivazis/survey/v2" + +// Prompter is an interface for prompting the user for input. +type Prompter interface { + Select(prompt string, options []string) (string, error) + InputString(prompt, defValue, help string, validator func(string) error) (string, error) + Confirm(prompt string) (bool, error) + InputHiddenString(prompt, help string, validator func(string) error) (string, error) +} + +type prompter struct{} + +// NewPrompter returns a new Prompter instance. +func NewPrompter() Prompter { + return &prompter{} +} + +// Select prompts the user to select one of the options provided. +func (p *prompter) Select(prompt string, options []string) (string, error) { + selected := "" + s := &survey.Select{ + Message: prompt, + Options: options, + } + err := survey.AskOne(s, &selected) + return selected, err +} + +// InputString prompts the user to input a string. The default value is used if the user does not provide any input. +// The validator is used to validate the input. The help text is displayed to the user when they ask for help. +func (p *prompter) InputString(prompt, defValue, help string, validator func(string) error) (string, error) { + var result string + i := &survey.Input{ + Message: prompt, + Default: defValue, + Help: help, + } + err := survey.AskOne(i, &result, survey.WithValidator(func(ans interface{}) error { + if err := validator(ans.(string)); err != nil { + return err + } + return nil + })) + return result, err +} + +// Confirm prompts the user to confirm an action with a yes/no question. +func (p *prompter) Confirm(prompt string) (bool, error) { + result := false + c := &survey.Confirm{ + Message: prompt, + } + err := survey.AskOne(c, &result) + return result, err +} + +// InputHiddenString prompts the user to input a string. The input is hidden from the user. +// The validator is used to validate the input. The help text is displayed to the user when they ask for help. +// There is no default value. +func (p *prompter) InputHiddenString(prompt, help string, validator func(string) error) (string, error) { + var result string + i := &survey.Password{ + Message: prompt, + Help: help, + } + + err := survey.AskOne(i, &result, survey.WithValidator(func(ans interface{}) error { + if err := validator(ans.(string)); err != nil { + return err + } + return nil + })) + return result, err +} diff --git a/cmd/utils/util.go b/cmd/utils/util.go new file mode 100644 index 0000000..d9c2965 --- /dev/null +++ b/cmd/utils/util.go @@ -0,0 +1,104 @@ +package utils + +import ( + "archive/tar" + "compress/gzip" + "fmt" + "io" + "log" + "net/http" + "os" + "strconv" +) + +func DownloadTarGzFile(filepath string, url string) (err error) { + + // Create the file + out, err := os.Create(filepath) + if err != nil { + return err + } + defer out.Close() + + // Get the data + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + // Check server response + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("bad status: %s", resp.Status) + } + + // Writer the body to file + _, err = io.Copy(out, resp.Body) + if err != nil { + return err + } + + return nil +} + +func ExtractTarGz(gzipStream io.Reader) error { + uncompressedStream, err := gzip.NewReader(gzipStream) + if err != nil { + return err + } + + tarReader := tar.NewReader(uncompressedStream) + var header *tar.Header + for header, err = tarReader.Next(); err == nil; header, err = tarReader.Next() { + switch header.Typeflag { + case tar.TypeDir: + if err := os.Mkdir(header.Name, 0755); err != nil { + return fmt.Errorf("ExtractTarGz: Mkdir() failed: %w", err) + } + case tar.TypeReg: + outFile, err := os.Create(header.Name) + if err != nil { + return fmt.Errorf("ExtractTarGz: Create() failed: %w", err) + } + + if _, err := io.Copy(outFile, tarReader); err != nil { + // outFile.Close error omitted as Copy error is more interesting at this point + outFile.Close() + return fmt.Errorf("ExtractTarGz: Copy() failed: %w", err) + } + if err := outFile.Close(); err != nil { + return fmt.Errorf("ExtractTarGz: Close() failed: %w", err) + } + default: + return fmt.Errorf("ExtractTarGz: uknown type: %b in %s", header.Typeflag, header.Name) + } + } + if err != io.EOF { + return fmt.Errorf("ExtractTarGz: Next() failed: %w", err) + } + return nil +} + +func GetPIDFileName(node_info string) string { + return "/tmp/" + node_info + ".pid" +} + +func savePID(pid int, PIDFile string) { + file, err := os.Create(PIDFile) + if err != nil { + log.Printf("Unable to create pid file : %v\n", err) + os.Exit(1) + } + + defer file.Close() + + _, err = file.WriteString(strconv.Itoa(pid)) + + if err != nil { + log.Printf("Unable to create pid file : %v\n", err) + os.Exit(1) + } + + file.Sync() // flush to disk + +} diff --git a/components/components.go b/components/components.go index f47a5a5..b9b737e 100644 --- a/components/components.go +++ b/components/components.go @@ -32,8 +32,11 @@ func NewComponentManager(componentType config.ComponentType, root string, nodeTy component = NewGmworldComponent(root, ".vimana/gmd", nodeType) // case config.Berachain: // component = berachain.NewBerachainComponent(home) + case config.Eigen: + component = NewEigenComponent(root, ".vimana/eigen", nodeType) default: - panic("Unknown component type") + //panic("Unknown component type") + component = NewUniversalComponent(root, ".vimana/"+string(componentType), nodeType) } return &ComponentManager{ diff --git a/components/eigen.go b/components/eigen.go new file mode 100644 index 0000000..59d5810 --- /dev/null +++ b/components/eigen.go @@ -0,0 +1,31 @@ +package components + +import ( + "os/exec" +) + +type EigenComponent struct { + Root string + ConfigDir string +} + +func NewEigenComponent(root string, home string, node string) *EigenComponent { + return &EigenComponent{ + Root: root, + ConfigDir: home, + } +} + +func (c *EigenComponent) InitializeConfig() error { + // lightNodePath := filepath.Join(os.Getenv("HOME"), c.ConfigDir+"/"+c.NodeType+"-node") + // mkdir -p ~/.vimana/celestia/light-node + return nil +} + +func (c *EigenComponent) GetStartCmd() *exec.Cmd { + args := []string{} + // eigenup.sh handles this. + return exec.Command( + c.Root, args..., + ) +} diff --git a/components/universal.go b/components/universal.go new file mode 100644 index 0000000..27163d5 --- /dev/null +++ b/components/universal.go @@ -0,0 +1,31 @@ +package components + +import ( + "os/exec" +) + +type UniversalComponent struct { + Root string + ConfigDir string +} + +func NewUniversalComponent(root string, home string, node string) *UniversalComponent { + return &UniversalComponent{ + Root: root, + ConfigDir: home, + } +} + +func (c *UniversalComponent) InitializeConfig() error { + // lightNodePath := filepath.Join(os.Getenv("HOME"), c.ConfigDir+"/"+c.NodeType+"-node") + // mkdir -p ~/.vimana/celestia/light-node + return nil +} + +func (c *UniversalComponent) GetStartCmd() *exec.Cmd { + args := []string{} + // Univeralup.sh handles this. + return exec.Command( + c.Root, args..., + ) +} diff --git a/config.toml b/config.toml index 49cc33c..5602eb4 100644 --- a/config.toml +++ b/config.toml @@ -3,11 +3,11 @@ [components.celestia] [components.celestia.light] -binary = "/tmp/vimana/celestia/celestia" +binary = "/usr/local/bin/celestia/celestia" download = "/tmp/vimana/celestia/init.sh" [components.celestia.bridge] -binary = "/tmp/vimana/celestia/celestia" +binary = "/usr/local/bin/celestia/celestia" download = "/tmp/vimana/celestia/init.sh" [components.avail] @@ -32,3 +32,9 @@ download = "/tmp/vimana/gmd/rollup_mocha.sh" # [components.berachain.full] # binary = "/path/to/celestia/binary" # download = "https://example.com/berachain.zip" + +#[components.eigen] + +#[components.eigen.operator] +#binary = "/usr/local/bin/eigen/eigenlayer" +#download = "/tmp/vimana/eigen/init.sh" \ No newline at end of file diff --git a/config/config.go b/config/config.go index c3fed87..d8f2cd4 100644 --- a/config/config.go +++ b/config/config.go @@ -6,5 +6,6 @@ const ( Celestia ComponentType = "celestia" Berachain ComponentType = "berachain" Avail ComponentType = "avail" - Gmworld ComponentType = "gmworld" + Gmworld ComponentType = "gmworld" + Eigen ComponentType = "eigen" ) diff --git a/go.mod b/go.mod index ddfbf12..e60c1ca 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,9 @@ module vimana go 1.20 require ( + github.com/AlecAivazis/survey/v2 v2.3.7 github.com/BurntSushi/toml v1.3.2 + github.com/asmcos/requests v0.0.0-20210319030608-c839e8ae4946 github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be github.com/ethereum/go-ethereum v1.13.2 github.com/fatih/color v1.15.0 @@ -18,8 +20,10 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/holiman/uint256 v1.2.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.4 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect @@ -27,6 +31,8 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect golang.org/x/crypto v0.12.0 // indirect golang.org/x/sys v0.11.0 // indirect + golang.org/x/term v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect ) replace github.com/cosmos/cosmos-sdk => github.com/rollkit/cosmos-sdk v0.47.6-rollkit-v0.10.7-no-fraud-proofs-fixed diff --git a/go.sum b/go.sum index ff5377f..475559d 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,20 @@ +github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= +github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= +github.com/asmcos/requests v0.0.0-20210319030608-c839e8ae4946 h1:1B8lZnGJOS3E7LumjuY6lb2NzXy8vBY6N2ag/IK6JdI= +github.com/asmcos/requests v0.0.0-20210319030608-c839e8ae4946/go.mod h1:2W5PB6UTVRBypeouEebhwOJrDZOfJvPwMP1mtD8ZXM4= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= @@ -17,16 +25,24 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -34,23 +50,55 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/install.sh b/install.sh index 4a45ffc..aa5c010 100755 --- a/install.sh +++ b/install.sh @@ -26,10 +26,11 @@ echo "🔨 Installing vimana..." sudo cp "/tmp/vimana_bins/vimana-${OS}-${ARCH}/vimana" "$INTERNAL_DIR/vimana" sudo chmod +x "$INTERNAL_DIR/vimana" sudo rm -rf "/tmp/vimana_bins" -curl -O https://vistara-labs.github.io/vimana/config.toml 2>/dev/null +# curl -O https://vistara-labs.github.io/vimana/config.toml 2>/dev/null mkdir -p ~/.vimana && cp config.toml ~/.vimana/config.toml -curl -O https://vistara-labs.github.io/vimana/scripts/init.sh 2>/dev/null -sudo mkdir -p /tmp/vimana/celestia && sudo mv init.sh /tmp/vimana/celestia/init.sh +# curl -O https://vistara-labs.github.io/vimana/scripts/init.sh 2>/dev/null +#sudo mkdir -p /tmp/vimana/celestia && sudo mv init.sh /tmp/vimana/celestia/init.sh +sudo mkdir -p /tmp/vimana/celestia && sudo cp scripts/init.sh /tmp/vimana/celestia/init.sh # Get availup script from repo curl -O https://vistara-labs.github.io/vimana/scripts/availup.sh 2>/dev/null @@ -41,11 +42,17 @@ sudo mkdir -p /tmp/vimana/gmd && sudo mv rollup_init.sh /tmp/vimana/gmd/rollup_i curl -O https://vistara-labs.github.io/vimana/scripts/rollup_mocha.sh 2>/dev/null sudo mkdir -p /tmp/vimana/gmd && sudo mv rollup_mocha.sh /tmp/vimana/gmd/rollup_mocha.sh + +# Get eigen script from repo +curl -O https://vistara-labs.github.io/vimana/scripts/eigen.sh 2>/dev/null +sudo mkdir -p /tmp/vimana/eigen && sudo mv eigen.sh /tmp/vimana/eigen/init.sh + curl https://api-api-dev.bk7bbm.oss-acorn.io/save-vimana-install > /dev/null 2>&1 sudo chmod +x /tmp/vimana/celestia/init.sh sudo chmod +x /tmp/vimana/avail/init.sh sudo chmod +x /tmp/vimana/gmd/rollup_init.sh sudo chmod +x /tmp/vimana/gmd/rollup_mocha.sh +sudo chmod +x /tmp/vimana/eigen/init.sh mkdir -p ~/.vimana/celestia/light-node chmod +x ~/.vimana/celestia/light-node echo "✅ vimana installed!" diff --git a/scripts/eigen.sh b/scripts/eigen.sh new file mode 100644 index 0000000..1d816b8 --- /dev/null +++ b/scripts/eigen.sh @@ -0,0 +1,460 @@ +#!/bin/sh +# Scripts inspired from https://github.com/ava-labs/avalanche-cli +# This script has not been tested yet since this is a private repo +# TODO(madhur): Test this script once this is a public repo + +set -e + +usage() { + this=$1 + cat </dev/null +} +echoerr() { + echo "$@" 1>&2 +} +log_prefix() { + echo "$0" +} +_logp=6 +log_set_priority() { + _logp="$1" +} +log_priority() { + if test -z "$1"; then + echo "$_logp" + return + fi + [ "$1" -le "$_logp" ] +} +log_tag() { + case $1 in + 0) echo "emerg" ;; + 1) echo "alert" ;; + 2) echo "crit" ;; + 3) echo "err" ;; + 4) echo "warning" ;; + 5) echo "notice" ;; + 6) echo "info" ;; + 7) echo "debug" ;; + *) echo "$1" ;; + esac +} +log_debug() { + log_priority 7 || return 0 + echoerr "$(log_prefix)" "$(log_tag 7)" "$@" +} +log_info() { + log_priority 6 || return 0 + echoerr "$(log_prefix)" "$(log_tag 6)" "$@" +} +log_err() { + log_priority 3 || return 0 + echoerr "$(log_prefix)" "$(log_tag 3)" "$@" +} +log_crit() { + log_priority 2 || return 0 + echoerr "$(log_prefix)" "$(log_tag 2)" "$@" +} +uname_os() { + os=$(uname -s | tr '[:upper:]' '[:lower:]') + case "$os" in + msys*) os="windows" ;; + mingw*) os="windows" ;; + cygwin*) os="windows" ;; + win*) os="windows" ;; + esac + echo "$os" +} +uname_arch() { + arch=$(uname -m) + case $arch in + x86_64) arch="amd64" ;; + x86) arch="386" ;; + i686) arch="386" ;; + i386) arch="386" ;; + aarch64) arch="arm64" ;; + armv5*) arch="armv5" ;; + armv6*) arch="armv6" ;; + armv7*) arch="armv7" ;; + esac + echo ${arch} +} +uname_os_check() { + os=$(uname_os) + case "$os" in + darwin) return 0 ;; + dragonfly) return 0 ;; + freebsd) return 0 ;; + linux) return 0 ;; + android) return 0 ;; + nacl) return 0 ;; + netbsd) return 0 ;; + openbsd) return 0 ;; + plan9) return 0 ;; + solaris) return 0 ;; + windows) return 0 ;; + esac + log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib" + return 1 +} +uname_arch_check() { + arch=$(uname_arch) + case "$arch" in + 386) return 0 ;; + amd64) return 0 ;; + arm64) return 0 ;; + armv5) return 0 ;; + armv6) return 0 ;; + armv7) return 0 ;; + ppc64) return 0 ;; + ppc64le) return 0 ;; + mips) return 0 ;; + mipsle) return 0 ;; + mips64) return 0 ;; + mips64le) return 0 ;; + s390x) return 0 ;; + amd64p32) return 0 ;; + esac + log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib" + return 1 +} +untar() { + tarball=$1 + case "${tarball}" in + *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;; + *.tar) tar --no-same-owner -xf "${tarball}" ;; + *.zip) unzip "${tarball}" ;; + *) + log_err "untar unknown archive format for ${tarball}" + return 1 + ;; + esac +} +http_download_curl() { + local_file=$1 + source_url=$2 + header=$3 + if [ -z "$header" ]; then + code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url") + else + code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url") + fi + if [ "$code" != "200" ]; then + log_debug "http_download_curl received HTTP status $code" + return 1 + fi + return 0 +} +http_download_wget() { + local_file=$1 + source_url=$2 + header=$3 + if [ -z "$header" ]; then + wget -q -O "$local_file" "$source_url" + else + wget -q --header "$header" -O "$local_file" "$source_url" + fi +} +http_download() { + log_debug "http_download $2" + if is_command curl; then + http_download_curl "$@" + return + elif is_command wget; then + http_download_wget "$@" + return + fi + log_crit "http_download unable to find wget or curl" + return 1 +} +http_copy() { + tmp=$(mktemp) + http_download "${tmp}" "$1" "$2" || return 1 + body=$(cat "$tmp") + rm -f "${tmp}" + echo "$body" +} +github_release() { + owner_repo=$1 + version=$2 + test -z "$version" && version="latest" + giturl="https://github.com/${owner_repo}/releases/${version}" + json=$(http_copy "$giturl" "Accept:application/json") + test -z "$json" && return 1 + version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//') + test -z "$version" && return 1 + echo "$version" +} +hash_sha256() { + TARGET=${1:-/dev/stdin} + if is_command gsha256sum; then + hash=$(gsha256sum "$TARGET") || return 1 + echo "$hash" | cut -d ' ' -f 1 + elif is_command sha256sum; then + hash=$(sha256sum "$TARGET") || return 1 + echo "$hash" | cut -d ' ' -f 1 + elif is_command shasum; then + hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1 + echo "$hash" | cut -d ' ' -f 1 + elif is_command openssl; then + hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1 + echo "$hash" | cut -d ' ' -f a + else + log_crit "hash_sha256 unable to find command to compute sha-256 hash" + return 1 + fi +} +hash_sha256_verify() { + TARGET=$1 + checksums=$2 + if [ -z "$checksums" ]; then + log_err "hash_sha256_verify checksum file not specified in arg2" + return 1 + fi + BASENAME=${TARGET##*/} + want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1) + if [ -z "$want" ]; then + log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'" + return 1 + fi + got=$(hash_sha256 "$TARGET") + if [ "$want" != "$got" ]; then + log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got" + return 1 + fi +} +cat /dev/null < /dev/null 2>&1 && HAS_BASH=true + if [ $HAS_BASH = true ] + then + BASH_COMPLETION_MAIN=~/.bash_completion + BASH_COMPLETION_SCRIPTS_DIR=~/.local/share/bash-completion/completions + BASH_COMPLETION_SCRIPT_PATH=$BASH_COMPLETION_SCRIPTS_DIR/eigenlayer.sh + mkdir -p $BASH_COMPLETION_SCRIPTS_DIR + COBRA_COMPLETION_SUCCEDED=false + $BINDIR/$BINARY completion bash > $BASH_COMPLETION_SCRIPT_PATH 2> /dev/null && COBRA_COMPLETION_SUCCEDED=true + if [ $COBRA_COMPLETION_SUCCEDED = true ] + then + touch $BASH_COMPLETION_MAIN + sed_in_place "/.*# eigenlayer completion/d" $BASH_COMPLETION_MAIN + echo "source $BASH_COMPLETION_SCRIPT_PATH # eigenlayer completion" >> $BASH_COMPLETION_MAIN + if [ "$(uname)" = Darwin ] + then + HAS_BREW=false + which brew >/dev/null 2>&1 && HAS_BREW=true + if [ $HAS_BREW = true ] + then + HAS_BASH_COMPLETIONS=false + brew list bash-completion >/dev/null 2>&1 && HAS_BASH_COMPLETIONS=true + if [ $HAS_BASH_COMPLETIONS = true ] + then + BASHRC=~/.bashrc + touch $BASHRC + sed_in_place "/.*# eigenlayer completion/d" $BASHRC + echo "source $(brew --prefix)/etc/bash_completion # eigenlayer completion" >> $BASHRC + else + echo "warning: brew bash-completion package not found. eigenlayer command completion for bash not installed" + fi + else + echo "warning: brew not found. eigenlayer command completion for bash not installed" + fi + fi + else + echo "warning: auto completion generation command failed. eigenlayer command completion for bash not installed" + fi + fi + + HAS_ZSH=false + which zsh > /dev/null 2>&1 && HAS_ZSH=true + if [ $HAS_ZSH = true ] + then + ZSH_COMPLETION_MAIN=~/.zshrc + ZSH_COMPLETION_SCRIPTS_DIR=~/.local/share/zsh-completion/completions + ZSH_COMPLETION_SCRIPT_PATH=$ZSH_COMPLETION_SCRIPTS_DIR/_eigenlayer + mkdir -p $ZSH_COMPLETION_SCRIPTS_DIR + COBRA_COMPLETION_SUCCEDED=false + $BINDIR/$BINARY completion zsh > $BASH_COMPLETION_SCRIPT_PATH 2> /dev/null && COBRA_COMPLETION_SUCCEDED=true + if [ $COBRA_COMPLETION_SUCCEDED = true ] + then + touch $ZSH_COMPLETION_MAIN + sed_in_place "/.*# eigenlayer completion/d" $ZSH_COMPLETION_MAIN + echo "fpath=($ZSH_COMPLETION_SCRIPTS_DIR \$fpath) # eigenlayer completion" >> $ZSH_COMPLETION_MAIN + echo "rm -f ~/.zcompdump; compinit # eigenlayer completion" >> $ZSH_COMPLETION_MAIN + else + echo "warning: auto completion generation command failed. eigenlayer command completion for zsh not installed" + fi + fi +} + +if [ "$RUN_COMPLETIONS" = true ]; then + completions +fi \ No newline at end of file diff --git a/scripts/init.sh b/scripts/init.sh index 7acacff..c4ecb4a 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -INTERNAL_DIR="/tmp/vimana/celestia" +INTERNAL_DIR="/usr/local/bin/celestia" # check if the binary is already installed if [ -f "$INTERNAL_DIR/celestia" ]; then diff --git a/scripts/rollup_init.sh b/scripts/rollup_init.sh old mode 100755 new mode 100644 diff --git a/scripts/rollup_start.sh b/scripts/rollup_start.sh old mode 100755 new mode 100644 diff --git a/spacecores.json b/spacecores.json new file mode 100644 index 0000000..e832534 --- /dev/null +++ b/spacecores.json @@ -0,0 +1,3 @@ +[ + {"spacecore":"opbnb","repo":"https://github.com/bnb-chain/opbnb"} +] \ No newline at end of file