diff --git a/lotuspond/api.go b/lotuspond/api.go index 1dc8aeab3..c3bee1ea8 100644 --- a/lotuspond/api.go +++ b/lotuspond/api.go @@ -2,17 +2,12 @@ package main import ( "crypto/rand" - "fmt" "github.com/filecoin-project/go-lotus/lib/jsonrpc" + "github.com/filecoin-project/go-lotus/node/repo" "io" "io/ioutil" "os" - "os/exec" "sync" - "sync/atomic" - "time" - - "github.com/filecoin-project/go-lotus/node/repo" "golang.org/x/xerrors" ) @@ -42,83 +37,6 @@ type nodeInfo struct { Storage bool } -func (api *api) Spawn() (nodeInfo, error) { - dir, err := ioutil.TempDir(os.TempDir(), "lotus-") - if err != nil { - return nodeInfo{}, err - } - - genParam := "--genesis=" + api.genesis - id := atomic.AddInt32(&api.cmds, 1) - if id == 1 { - // make genesis - genf, err := ioutil.TempFile(os.TempDir(), "lotus-genesis-") - if err != nil { - return nodeInfo{}, err - } - - api.genesis = genf.Name() - genParam = "--lotus-make-random-genesis=" + api.genesis - - if err := genf.Close(); err != nil { - return nodeInfo{}, err - } - - } - - errlogfile, err := os.OpenFile(dir+".err.log", os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return nodeInfo{}, err - } - logfile, err := os.OpenFile(dir+".out.log", os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return nodeInfo{}, err - } - - mux := newWsMux() - - cmd := exec.Command("./lotus", "daemon", genParam, "--api", fmt.Sprintf("%d", 2500+id)) - cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) - cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) - cmd.Env = []string{"LOTUS_PATH=" + dir} - if err := cmd.Start(); err != nil { - return nodeInfo{}, err - } - - info := nodeInfo{ - Repo: dir, - ID: id, - ApiPort: 2500 + id, - State: NodeRunning, - } - - api.runningLk.Lock() - api.running[id] = &runningNode{ - cmd: cmd, - meta: info, - - mux: mux, - stop: func() { - cmd.Process.Signal(os.Interrupt) - cmd.Process.Wait() - - api.runningLk.Lock() - api.running[id].meta.State = NodeStopped - api.runningLk.Unlock() - - logfile.Close() - errlogfile.Close() - - close(mux.stop) - }, - } - api.runningLk.Unlock() - - time.Sleep(time.Millisecond * 750) // TODO: Something less terrible - - return info, nil -} - func (api *api) Nodes() []nodeInfo { api.runningLk.Lock() out := make([]nodeInfo, 0, len(api.running)) @@ -153,84 +71,6 @@ func (api *api) TokenFor(id int32) (string, error) { return string(t), nil } -func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { - dir, err := ioutil.TempDir(os.TempDir(), "lotus-storage-") - if err != nil { - return nodeInfo{}, err - } - - errlogfile, err := os.OpenFile(dir+".err.log", os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return nodeInfo{}, err - } - logfile, err := os.OpenFile(dir+".out.log", os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return nodeInfo{}, err - } - - initArgs := []string{"init"} - if fullNodeRepo == api.running[1].meta.Repo { - initArgs = []string{"init", "--actor=t0101", "--genesis-miner"} - } - - id := atomic.AddInt32(&api.cmds, 1) - cmd := exec.Command("./lotus-storage-miner", initArgs...) - cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile) - cmd.Stdout = io.MultiWriter(os.Stdout, logfile) - cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo} - if err := cmd.Run(); err != nil { - return nodeInfo{}, err - } - - time.Sleep(time.Millisecond * 300) - - mux := newWsMux() - - cmd = exec.Command("./lotus-storage-miner", "run", "--api", fmt.Sprintf("%d", 2500+id)) - cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) - cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) - cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo} - if err := cmd.Start(); err != nil { - return nodeInfo{}, err - } - - info := nodeInfo{ - Repo: dir, - ID: id, - ApiPort: 2500 + id, - State: NodeRunning, - - FullNode: fullNodeRepo, - Storage: true, - } - - api.runningLk.Lock() - api.running[id] = &runningNode{ - cmd: cmd, - meta: info, - - mux: mux, - stop: func() { - cmd.Process.Signal(os.Interrupt) - cmd.Process.Wait() - - api.runningLk.Lock() - api.running[id].meta.State = NodeStopped - api.runningLk.Unlock() - - logfile.Close() - errlogfile.Close() - - close(mux.stop) - }, - } - api.runningLk.Unlock() - - time.Sleep(time.Millisecond * 750) // TODO: Something less terrible - - return info, nil -} - func (api *api) FullID(id int32) (int32, error) { api.runningLk.Lock() defer api.runningLk.Unlock() diff --git a/lotuspond/front/src/NodeList.js b/lotuspond/front/src/NodeList.js index 367fe1680..5db07bfa5 100644 --- a/lotuspond/front/src/NodeList.js +++ b/lotuspond/front/src/NodeList.js @@ -130,7 +130,8 @@ class NodeList extends React.Component { } startNode = (id) => async () => { - + let node = await this.props.client.call('Pond.RestartNode', [Number(id)]) + await this.mountNode(node) } connMgr() { diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go new file mode 100644 index 000000000..2676ae119 --- /dev/null +++ b/lotuspond/spawn.go @@ -0,0 +1,218 @@ +package main + +import ( + "fmt" + "golang.org/x/xerrors" + "io" + "io/ioutil" + "os" + "os/exec" + "sync/atomic" + "time" +) + +func (api *api) Spawn() (nodeInfo, error) { + dir, err := ioutil.TempDir(os.TempDir(), "lotus-") + if err != nil { + return nodeInfo{}, err + } + + genParam := "--genesis=" + api.genesis + id := atomic.AddInt32(&api.cmds, 1) + if id == 1 { + // make genesis + genf, err := ioutil.TempFile(os.TempDir(), "lotus-genesis-") + if err != nil { + return nodeInfo{}, err + } + + api.genesis = genf.Name() + genParam = "--lotus-make-random-genesis=" + api.genesis + + if err := genf.Close(); err != nil { + return nodeInfo{}, err + } + + } + + errlogfile, err := os.OpenFile(dir+".err.log", os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return nodeInfo{}, err + } + logfile, err := os.OpenFile(dir+".out.log", os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return nodeInfo{}, err + } + + mux := newWsMux() + + cmd := exec.Command("./lotus", "daemon", genParam, "--api", fmt.Sprintf("%d", 2500+id)) + cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) + cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) + cmd.Env = []string{"LOTUS_PATH=" + dir} + if err := cmd.Start(); err != nil { + return nodeInfo{}, err + } + + info := nodeInfo{ + Repo: dir, + ID: id, + ApiPort: 2500 + id, + State: NodeRunning, + } + + api.runningLk.Lock() + api.running[id] = &runningNode{ + cmd: cmd, + meta: info, + + mux: mux, + stop: func() { + cmd.Process.Signal(os.Interrupt) + cmd.Process.Wait() + + api.runningLk.Lock() + api.running[id].meta.State = NodeStopped + api.runningLk.Unlock() + + //logfile.Close() + //errlogfile.Close() + + //close(mux.stop) + }, + } + api.runningLk.Unlock() + + time.Sleep(time.Millisecond * 750) // TODO: Something less terrible + + return info, nil +} + +func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { + dir, err := ioutil.TempDir(os.TempDir(), "lotus-storage-") + if err != nil { + return nodeInfo{}, err + } + + errlogfile, err := os.OpenFile(dir+".err.log", os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return nodeInfo{}, err + } + logfile, err := os.OpenFile(dir+".out.log", os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return nodeInfo{}, err + } + + initArgs := []string{"init"} + if fullNodeRepo == api.running[1].meta.Repo { + initArgs = []string{"init", "--actor=t0101", "--genesis-miner"} + } + + id := atomic.AddInt32(&api.cmds, 1) + cmd := exec.Command("./lotus-storage-miner", initArgs...) + cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile) + cmd.Stdout = io.MultiWriter(os.Stdout, logfile) + cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo} + if err := cmd.Run(); err != nil { + return nodeInfo{}, err + } + + time.Sleep(time.Millisecond * 300) + + mux := newWsMux() + + cmd = exec.Command("./lotus-storage-miner", "run", "--api", fmt.Sprintf("%d", 2500+id)) + cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) + cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) + cmd.Env = []string{"LOTUS_STORAGE_PATH=" + dir, "LOTUS_PATH=" + fullNodeRepo} + if err := cmd.Start(); err != nil { + return nodeInfo{}, err + } + + info := nodeInfo{ + Repo: dir, + ID: id, + ApiPort: 2500 + id, + State: NodeRunning, + + FullNode: fullNodeRepo, + Storage: true, + } + + api.runningLk.Lock() + api.running[id] = &runningNode{ + cmd: cmd, + meta: info, + + mux: mux, + stop: func() { + cmd.Process.Signal(os.Interrupt) + cmd.Process.Wait() + + api.runningLk.Lock() + api.running[id].meta.State = NodeStopped + api.runningLk.Unlock() + + //logfile.Close() + //errlogfile.Close() + + //close(mux.stop) + }, + } + api.runningLk.Unlock() + + time.Sleep(time.Millisecond * 750) // TODO: Something less terrible + + return info, nil +} + +func (api *api) RestartNode(id int32) (nodeInfo, error) { + api.runningLk.Lock() + defer api.runningLk.Unlock() + nd, ok := api.running[id] + + if !ok { + return nodeInfo{}, xerrors.New("node not found") + } + + if nd.meta.State != NodeStopped { + return nodeInfo{}, xerrors.New("node not stopped") + } + + var cmd *exec.Cmd + if nd.meta.Storage { + cmd = exec.Command("./lotus-storage-miner", "run", "--api", fmt.Sprintf("%d", 2500+id)) + } else { + cmd = exec.Command("./lotus", "daemon", "--api", fmt.Sprintf("%d", 2500+id)) + } + + cmd.Stderr = nd.cmd.Stderr // recycle old vars + cmd.Stdout = nd.cmd.Stdout + cmd.Env = nd.cmd.Env + + if err := cmd.Start(); err != nil { + return nodeInfo{}, err + } + + nd.cmd = cmd + + nd.stop = func() { + cmd.Process.Signal(os.Interrupt) + cmd.Process.Wait() + + api.runningLk.Lock() + api.running[id].meta.State = NodeStopped + api.runningLk.Unlock() + + //logfile.Close() + //errlogfile.Close() + + //close(mux.stop) + } + + nd.meta.State = NodeRunning + + time.Sleep(time.Millisecond * 750) // TODO: Something less terrible + + return nd.meta, nil +}