Skip to content

Commit

Permalink
Move cmd.utils into their own package
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Luzzardi <[email protected]>
  • Loading branch information
aluzzardi committed Dec 5, 2018
1 parent 8cd2e20 commit ba63ce9
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 79 deletions.
3 changes: 2 additions & 1 deletion cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/blocklayerhq/chainkit/project"
"github.com/blocklayerhq/chainkit/ui"
"github.com/blocklayerhq/chainkit/util"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -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)
}
}
5 changes: 3 additions & 2 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/blocklayerhq/chainkit/project"
"github.com/blocklayerhq/chainkit/ui"
"github.com/blocklayerhq/chainkit/util"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -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
}
}
Expand Down
9 changes: 5 additions & 4 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
}
}
Expand Down
72 changes: 0 additions & 72 deletions cmd/utils.go
Original file line number Diff line number Diff line change
@@ -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"
)
Expand Down Expand Up @@ -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
}
78 changes: 78 additions & 0 deletions util/run.go
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit ba63ce9

Please sign in to comment.