github.com/scaleway/scaleway-cli@v1.11.1/pkg/commands/exec.go (about) 1 // Copyright (C) 2015 Scaleway. All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE.md file. 4 5 package commands 6 7 import ( 8 "fmt" 9 "time" 10 11 "github.com/Sirupsen/logrus" 12 13 "github.com/scaleway/scaleway-cli/pkg/api" 14 "github.com/scaleway/scaleway-cli/pkg/utils" 15 ) 16 17 // ExecArgs are flags for the `RunExec` function 18 type ExecArgs struct { 19 Timeout float64 20 Wait bool 21 Gateway string 22 Server string 23 Command []string 24 SSHUser string 25 SSHPort int 26 } 27 28 // RunExec is the handler for 'scw exec' 29 func RunExec(ctx CommandContext, args ExecArgs) error { 30 var fingerprints []string 31 32 done := make(chan struct{}) 33 34 serverID, err := ctx.API.GetServerID(args.Server) 35 if err != nil { 36 return err 37 } 38 39 go func() { 40 fingerprints = ctx.API.GetSSHFingerprintFromServer(serverID) 41 close(done) 42 }() 43 // Resolve gateway 44 if args.Gateway == "" { 45 args.Gateway = ctx.Getenv("SCW_GATEWAY") 46 } 47 var gateway string 48 49 if args.Gateway == serverID || args.Gateway == args.Server { 50 logrus.Debugf("The server and the gateway are the same host, using direct access to the server") 51 gateway = "" 52 } else { 53 gateway, err = api.ResolveGateway(ctx.API, args.Gateway) 54 if err != nil { 55 return fmt.Errorf("Cannot resolve Gateway '%s': %v", args.Gateway, err) 56 } 57 if gateway != "" { 58 logrus.Debugf("The server will be accessed using the gateway '%s' as a SSH relay", gateway) 59 } 60 } 61 62 var server *api.ScalewayServer 63 if args.Wait { 64 // --wait 65 logrus.Debugf("Waiting for server to be ready") 66 server, err = api.WaitForServerReady(ctx.API, serverID, gateway) 67 if err != nil { 68 return fmt.Errorf("Failed to wait for server to be ready, %v", err) 69 } 70 } else { 71 // no --wait 72 logrus.Debugf("scw won't wait for the server to be ready, if it is not, the command will fail") 73 server, err = ctx.API.GetServer(serverID) 74 if err != nil { 75 rerr := fmt.Errorf("Failed to get server information for %s: %v", serverID, err) 76 if err.Error() == `"`+serverID+`" not found` { 77 return fmt.Errorf("%v\nmaybe try to flush the cache with : scw _flush-cache", rerr) 78 } 79 return rerr 80 } 81 } 82 83 if server.PublicAddress.IP == "" && gateway == "" { 84 logrus.Warn(`Your host has no public IP address, you should use '--gateway', see 'scw help exec'`) 85 } 86 87 // --timeout 88 if args.Timeout > 0 { 89 logrus.Debugf("Setting up a global timeout of %d seconds", args.Timeout) 90 // FIXME: avoid use of log.Fatalf here 91 go func() { 92 time.Sleep(time.Duration(args.Timeout*1000) * time.Millisecond) 93 logrus.Fatalf("Operation timed out") 94 }() 95 } 96 97 <-done 98 if len(fingerprints) > 0 { 99 for i := range fingerprints { 100 fmt.Fprintf(ctx.Stdout, "%s\n", fingerprints[i]) 101 } 102 } 103 logrus.Debugf("PublicDNS %s", serverID+api.URLPublicDNS) 104 logrus.Debugf("PrivateDNS %s", serverID+api.URLPrivateDNS) 105 if err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args.SSHUser, args.SSHPort, args.Command, !args.Wait, gateway); err != nil { 106 return fmt.Errorf("Failed to run the command: %v", err) 107 } 108 109 logrus.Debugf("Command successfully executed") 110 return nil 111 }