|
5 | 5 | package commands
|
6 | 6 |
|
7 | 7 | import (
|
8 |
| - "os" |
| 8 | + "fmt" |
9 | 9 | "time"
|
10 | 10 |
|
11 | 11 | log "github.com/scaleway/scaleway-cli/vendor/github.com/Sirupsen/logrus"
|
12 | 12 |
|
13 | 13 | "github.com/scaleway/scaleway-cli/pkg/api"
|
14 |
| - types "github.com/scaleway/scaleway-cli/pkg/commands/types" |
| 14 | + "github.com/scaleway/scaleway-cli/pkg/commands/types" |
15 | 15 | "github.com/scaleway/scaleway-cli/pkg/utils"
|
16 | 16 | )
|
17 | 17 |
|
18 | 18 | var cmdExec = &types.Command{
|
19 |
| - Exec: runExec, |
| 19 | + Exec: cmdExecExec, |
20 | 20 | UsageLine: "exec [OPTIONS] SERVER [COMMAND] [ARGS...]",
|
21 | 21 | Description: "Run a command on a running server",
|
22 | 22 | Help: "Run a command on a running server.",
|
@@ -47,57 +47,92 @@ var execTimeout float64 // -T flag
|
47 | 47 | var execHelp bool // -h, --help flag
|
48 | 48 | var execGateway string // -g, --gateway flag
|
49 | 49 |
|
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) { |
51 | 60 | if execHelp {
|
52 | 61 | cmd.PrintUsage()
|
53 | 62 | }
|
54 |
| - if len(args) < 1 { |
| 63 | + if len(rawArgs) < 1 { |
55 | 64 | cmd.PrintShortUsage()
|
56 | 65 | }
|
57 | 66 |
|
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) |
59 | 84 |
|
60 | 85 | // Resolve gateway
|
61 |
| - if execGateway == "" { |
62 |
| - execGateway = os.Getenv("SCW_GATEWAY") |
| 86 | + if args.Gateway == "" { |
| 87 | + args.Gateway = ctx.Getenv("SCW_GATEWAY") |
63 | 88 | }
|
64 | 89 | var gateway string
|
65 | 90 | 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") |
67 | 93 | gateway = ""
|
68 | 94 | } else {
|
69 |
| - gateway, err = api.ResolveGateway(cmd.API, execGateway) |
| 95 | + gateway, err = api.ResolveGateway(ctx.API, args.Gateway) |
70 | 96 | 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) |
72 | 101 | }
|
73 | 102 | }
|
74 | 103 |
|
75 | 104 | var server *api.ScalewayServer
|
76 |
| - if execW { |
| 105 | + if args.Wait { |
77 | 106 | // --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) |
79 | 109 | 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) |
81 | 111 | }
|
82 | 112 | } else {
|
83 | 113 | // 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) |
85 | 116 | 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) |
87 | 118 | }
|
88 | 119 | }
|
89 | 120 |
|
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 |
91 | 125 | go func() {
|
92 |
| - time.Sleep(time.Duration(execTimeout*1000) * time.Millisecond) |
| 126 | + time.Sleep(time.Duration(args.Timeout*1000) * time.Millisecond) |
93 | 127 | log.Fatalf("Operation timed out")
|
94 | 128 | }()
|
95 | 129 | }
|
96 | 130 |
|
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) |
98 | 132 | if err != nil {
|
99 |
| - log.Fatalf("%v", err) |
100 |
| - os.Exit(1) |
| 133 | + return fmt.Errorf("Failed to run the command: %v", err) |
101 | 134 | }
|
| 135 | + |
102 | 136 | log.Debugf("Command successfuly executed")
|
| 137 | + return nil |
103 | 138 | }
|
0 commit comments