From ba63ce9f6a3c3a8a0d1e415f1e85ed53161973b7 Mon Sep 17 00:00:00 2001 From: Andrea Luzzardi Date: Tue, 4 Dec 2018 17:38:14 -0800 Subject: [PATCH] Move cmd.utils into their own package Signed-off-by: Andrea Luzzardi --- cmd/cli.go | 3 +- cmd/init.go | 5 ++-- cmd/start.go | 9 +++--- cmd/utils.go | 72 ------------------------------------------------ util/run.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 79 deletions(-) create mode 100644 util/run.go diff --git a/cmd/cli.go b/cmd/cli.go index 298e096..9010eaf 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -5,6 +5,7 @@ import ( "github.com/blocklayerhq/chainkit/project" "github.com/blocklayerhq/chainkit/ui" + "github.com/blocklayerhq/chainkit/util" "github.com/spf13/cobra" ) @@ -36,7 +37,7 @@ func cli(p *project.Project, args []string) { p.Binaries.CLI, } cmd = append(cmd, args...) - if err := docker(ctx, p, cmd...); err != nil { + if err := util.Run(ctx, "docker", cmd...); err != nil { ui.Fatal("Failed to start the cli (is the application running?): %v", err) } } diff --git a/cmd/init.go b/cmd/init.go index f0a312e..6e1eddb 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -6,6 +6,7 @@ import ( "github.com/blocklayerhq/chainkit/project" "github.com/blocklayerhq/chainkit/ui" + "github.com/blocklayerhq/chainkit/util" "github.com/spf13/cobra" ) @@ -47,14 +48,14 @@ func initialize(ctx context.Context, p *project.Project) error { } ui.Info("Generating configuration and genesis files") - if err := dockerRun(ctx, p, "init"); err != nil { + if err := util.DockerRun(ctx, p, "init"); err != nil { //NOTE: some cosmos app (e.g. Gaia) take a --moniker option in the init command // if the normal init fail, rerun with `--moniker $(hostname)` hostname, err := os.Hostname() if err != nil { return err } - if err := dockerRun(ctx, p, "init", "--moniker", hostname); err != nil { + if err := util.DockerRun(ctx, p, "init", "--moniker", hostname); err != nil { return err } } diff --git a/cmd/start.go b/cmd/start.go index 4a2d6a5..b2938fe 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -17,6 +17,7 @@ import ( "github.com/blocklayerhq/chainkit/discovery" "github.com/blocklayerhq/chainkit/project" "github.com/blocklayerhq/chainkit/ui" + "github.com/blocklayerhq/chainkit/util" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/tendermint/tendermint/rpc/client" @@ -57,14 +58,14 @@ func startExplorer(ctx context.Context, p *project.Project) error { "-p", fmt.Sprintf("%d:8080", p.Ports.Explorer), ExplorerImage, } - if err := docker(ctx, p, cmd...); err != nil { + if err := util.Run(ctx, "docker", cmd...); err != nil { return errors.Wrap(err, "failed to start the explorer") } return nil } func startServer(ctx context.Context, p *project.Project) error { - if err := dockerRun(ctx, p, "start"); err != nil { + if err := util.DockerRun(ctx, p, "start"); err != nil { return errors.Wrap(err, "failed to start the application") } return nil @@ -99,7 +100,7 @@ func start(p *project.Project, chainID string) { if err != nil { ui.Fatal("Unable to create temporary file: %v", err) } - if err := runWithFD(ctx, p, os.Stdin, f, os.Stderr, "docker", "save", p.Image); err != nil { + if err := util.RunWithFD(ctx, os.Stdin, f, os.Stderr, "docker", "save", p.Image); err != nil { ui.Fatal("Unable to save image: %v", err) } f.Close() @@ -131,7 +132,7 @@ func start(p *project.Project, chainID string) { ui.Success("Retrieved genesis data") - if err := runWithFD(ctx, p, image, os.Stdout, os.Stderr, "docker", "load"); err != nil { + if err := util.RunWithFD(ctx, image, os.Stdout, os.Stderr, "docker", "load"); err != nil { ui.Fatal("unable to load image: %v", err) } } diff --git a/cmd/utils.go b/cmd/utils.go index 65c96cb..9a584e9 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -1,18 +1,10 @@ package cmd import ( - "context" - "fmt" - "io" "os" - "os/exec" "path" "path/filepath" - "strings" - "syscall" - "time" - "github.com/blocklayerhq/chainkit/project" "github.com/blocklayerhq/chainkit/ui" "github.com/spf13/cobra" ) @@ -48,67 +40,3 @@ func goPath() string { func goSrc() string { return path.Join(goPath(), "src") } - -func dockerRun(ctx context.Context, p *project.Project, args ...string) error { - var ( - daemonDirContainer = path.Join("/", "root", "."+p.Binaries.Daemon) - cliDirContainer = path.Join("/", "root", "."+p.Binaries.CLI) - ) - - cmd := []string{ - "run", "--rm", - "-p", fmt.Sprintf("%d:26656", p.Ports.TendermintP2P), - "-p", fmt.Sprintf("%d:26657", p.Ports.TendermintRPC), - "-v", p.StateDir() + ":" + daemonDirContainer, - "-v", p.CLIDir() + ":" + cliDirContainer, - "--name", p.Image, - p.Image + ":latest", - p.Binaries.Daemon, - } - cmd = append(cmd, args...) - - return docker(ctx, p, cmd...) -} - -func docker(ctx context.Context, p *project.Project, args ...string) error { - return run(ctx, p, "docker", args...) -} - -func run(ctx context.Context, p *project.Project, command string, args ...string) error { - return runWithFD(ctx, p, os.Stdin, os.Stdout, os.Stderr, command, args...) -} - -func runWithFD(ctx context.Context, p *project.Project, stdin io.Reader, stdout, stderr io.Writer, command string, args ...string) error { - ui.Verbose("$ %s %s", command, strings.Join(args, " ")) - cmd := exec.Command(command) - cmd.Args = append([]string{command}, args...) - cmd.Stdin = stdin - cmd.Stdout = stdout - cmd.Stderr = stderr - cmd.Dir = p.RootDir - - if err := cmd.Start(); err != nil { - return err - } - - // We don't use exec.CommandContext here because it will - // SIGKILL the process. Instead, we handle the context - // on our own and try to gracefully shutdown the command. - waitDone := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - cmd.Process.Signal(syscall.SIGTERM) - select { - case <-time.After(5 * time.Second): - cmd.Process.Kill() - case <-waitDone: - } - case <-waitDone: - } - }() - - err := cmd.Wait() - close(waitDone) - return err -} diff --git a/util/run.go b/util/run.go new file mode 100644 index 0000000..b29fc1e --- /dev/null +++ b/util/run.go @@ -0,0 +1,78 @@ +package util + +import ( + "context" + "fmt" + "io" + "os" + "os/exec" + "path" + "strings" + "syscall" + "time" + + "github.com/blocklayerhq/chainkit/project" + "github.com/blocklayerhq/chainkit/ui" +) + +// DockerRun runs a command within the project's container. +func DockerRun(ctx context.Context, p *project.Project, args ...string) error { + var ( + daemonDirContainer = path.Join("/", "root", "."+p.Binaries.Daemon) + cliDirContainer = path.Join("/", "root", "."+p.Binaries.CLI) + ) + + cmd := []string{ + "run", "--rm", + "-p", fmt.Sprintf("%d:26656", p.Ports.TendermintP2P), + "-p", fmt.Sprintf("%d:26657", p.Ports.TendermintRPC), + "-v", p.StateDir() + ":" + daemonDirContainer, + "-v", p.CLIDir() + ":" + cliDirContainer, + "--name", p.Image, + p.Image + ":latest", + p.Binaries.Daemon, + } + cmd = append(cmd, args...) + + return Run(ctx, "docker", cmd...) +} + +// Run runs a system command. +func Run(ctx context.Context, command string, args ...string) error { + return RunWithFD(ctx, os.Stdin, os.Stdout, os.Stderr, command, args...) +} + +// RunWithFD is like Run, but accepts custom stdin/stdout/stderr. +func RunWithFD(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer, command string, args ...string) error { + ui.Verbose("$ %s %s", command, strings.Join(args, " ")) + cmd := exec.Command(command) + cmd.Args = append([]string{command}, args...) + cmd.Stdin = stdin + cmd.Stdout = stdout + cmd.Stderr = stderr + + if err := cmd.Start(); err != nil { + return err + } + + // We don't use exec.CommandContext here because it will + // SIGKILL the process. Instead, we handle the context + // on our own and try to gracefully shutdown the command. + waitDone := make(chan struct{}) + go func() { + select { + case <-ctx.Done(): + cmd.Process.Signal(syscall.SIGTERM) + select { + case <-time.After(5 * time.Second): + cmd.Process.Kill() + case <-waitDone: + } + case <-waitDone: + } + }() + + err := cmd.Wait() + close(waitDone) + return err +}