Skip to content

Commit fcb324f

Browse files
committed
Refactored 'exec' command (scaleway#80)
1 parent e07a1fb commit fcb324f

File tree

2 files changed

+61
-20
lines changed

2 files changed

+61
-20
lines changed

pkg/commands/exec.go

+55-20
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
package commands
66

77
import (
8-
"os"
8+
"fmt"
99
"time"
1010

1111
log "github.com/scaleway/scaleway-cli/vendor/github.com/Sirupsen/logrus"
@@ -16,7 +16,7 @@ import (
1616
)
1717

1818
var cmdExec = &types.Command{
19-
Exec: runExec,
19+
Exec: cmdExecExec,
2020
UsageLine: "exec [OPTIONS] SERVER [COMMAND] [ARGS...]",
2121
Description: "Run a command on a running server",
2222
Help: "Run a command on a running server.",
@@ -47,57 +47,92 @@ var execTimeout float64 // -T flag
4747
var execHelp bool // -h, --help flag
4848
var execGateway string // -g, --gateway flag
4949

50-
func runExec(cmd *types.Command, args []string) {
50+
// ExecArgs are flags for the `RunExec` function
51+
type ExecArgs struct {
52+
Timeout float64
53+
Wait bool
54+
Gateway string
55+
Server string
56+
Command []string
57+
}
58+
59+
func cmdExecExec(cmd *types.Command, rawArgs []string) {
5160
if execHelp {
5261
cmd.PrintUsage()
5362
}
54-
if len(args) < 1 {
63+
if len(rawArgs) < 1 {
5564
cmd.PrintShortUsage()
5665
}
5766

58-
serverID := cmd.API.GetServerID(args[0])
67+
args := ExecArgs{
68+
Timeout: execTimeout,
69+
Wait: execW,
70+
Gateway: execGateway,
71+
Server: rawArgs[0],
72+
Command: rawArgs[1:],
73+
}
74+
ctx := cmd.GetContext(rawArgs)
75+
err := RunExec(ctx, args)
76+
if err != nil {
77+
log.Fatalf("Cannot exec 'exec': %v", err)
78+
}
79+
}
80+
81+
// RunExec is the handler for 'scw exec'
82+
func RunExec(ctx types.CommandContext, args ExecArgs) error {
83+
serverID := ctx.API.GetServerID(args.Server)
5984

6085
// Resolve gateway
61-
if execGateway == "" {
62-
execGateway = os.Getenv("SCW_GATEWAY")
86+
if args.Gateway == "" {
87+
args.Gateway = ctx.Getenv("SCW_GATEWAY")
6388
}
6489
var gateway string
6590
var err error
66-
if execGateway == serverID || execGateway == args[0] {
91+
if args.Gateway == serverID || args.Gateway == args.Server {
92+
log.Debugf("The server and the gateway are the same host, using direct access to the server")
6793
gateway = ""
6894
} else {
69-
gateway, err = api.ResolveGateway(cmd.API, execGateway)
95+
gateway, err = api.ResolveGateway(ctx.API, args.Gateway)
7096
if err != nil {
71-
log.Fatalf("Cannot resolve Gateway '%s': %v", execGateway, err)
97+
return fmt.Errorf("Cannot resolve Gateway '%s': %v", args.Gateway, err)
98+
}
99+
if gateway != "" {
100+
log.Debugf("The server will be accessed using the gateway '%s' as a SSH relay", gateway)
72101
}
73102
}
74103

75104
var server *api.ScalewayServer
76-
if execW {
105+
if args.Wait {
77106
// --wait
78-
server, err = api.WaitForServerReady(cmd.API, serverID, gateway)
107+
log.Debugf("Waiting for server to be ready")
108+
server, err = api.WaitForServerReady(ctx.API, serverID, gateway)
79109
if err != nil {
80-
log.Fatalf("Failed to wait for server to be ready, %v", err)
110+
return fmt.Errorf("Failed to wait for server to be ready, %v", err)
81111
}
82112
} else {
83113
// no --wait
84-
server, err = cmd.API.GetServer(serverID)
114+
log.Debugf("scw won't wait for the server to be ready, if it is not, the command will fail")
115+
server, err = ctx.API.GetServer(serverID)
85116
if err != nil {
86-
log.Fatalf("Failed to get server information for %s: %v", serverID, err)
117+
return fmt.Errorf("Failed to get server information for %s: %v", serverID, err)
87118
}
88119
}
89120

90-
if execTimeout > 0 {
121+
// --timeout
122+
if args.Timeout > 0 {
123+
log.Debugf("Setting up a global timeout of %d seconds", args.Timeout)
124+
// FIXME: avoid use of log.Fatalf here
91125
go func() {
92-
time.Sleep(time.Duration(execTimeout*1000) * time.Millisecond)
126+
time.Sleep(time.Duration(args.Timeout*1000) * time.Millisecond)
93127
log.Fatalf("Operation timed out")
94128
}()
95129
}
96130

97-
err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args[1:], !execW, gateway)
131+
err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args.Command, !args.Wait, gateway)
98132
if err != nil {
99-
log.Fatalf("%v", err)
100-
os.Exit(1)
133+
return fmt.Errorf("Failed to run the command: %v", err)
101134
}
135+
102136
log.Debugf("Command successfuly executed")
137+
return nil
103138
}

pkg/commands/types/command.go

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ type CommandContext struct {
5656
API *api.ScalewayAPI
5757
}
5858

59+
// Getenv returns the equivalent of os.Getenv for the CommandContext.Env
60+
func (c *CommandContext) Getenv(key string) string {
61+
// FIXME: parse c.Env instead
62+
return os.Getenv(key)
63+
}
64+
5965
// GetContext returns a standard context, with real stdin, stdout, stderr, a configured API and raw arguments
6066
func (c *Command) GetContext(rawArgs []string) CommandContext {
6167
return CommandContext{

0 commit comments

Comments
 (0)