// DeleteServerSafe tries to delete a server using multiple ways func (a *ScalewayAPI) DeleteServerSafe(serverID string) error { // FIXME: also delete attached volumes and ip address err := a.DeleteServer(serverID) if err == nil { logrus.Infof("Server '%s' successfuly deleted", serverID) return nil } err = a.PostServerAction(serverID, "terminate") if err == nil { logrus.Infof("Server '%s' successfuly terminated", serverID) return nil } logrus.Errorf("Failed to delete server %s", serverID) logrus.Errorf("Try to run 'scw rm %s' later", serverID) return err }
// DeleteServerSafe tries to delete a server using multiple ways func (a *ScalewayAPI) DeleteServerSafe(serverID string) error { // FIXME: also delete attached volumes and ip address // FIXME: call delete and stop -t in parallel to speed up process err := a.DeleteServer(serverID) if err == nil { logrus.Infof("Server '%s' successfuly deleted", serverID) return nil } err = a.PostServerAction(serverID, "terminate") if err == nil { logrus.Infof("Server '%s' successfuly terminated", serverID) return nil } // FIXME: retry in a loop until timeout or Control+C logrus.Errorf("Failed to delete server %s", serverID) logrus.Errorf("Try to run 'scw rm -f %s' later", serverID) return err }
// GeneratingAnSSHKey generates an SSH key func GeneratingAnSSHKey(cfg SpawnRedirection, path string, name string) (string, error) { args := []string{ "-t", "rsa", "-b", "4096", "-f", filepath.Join(path, name), "-N", "", "-C", "", } log.Infof("Executing commands %v", args) spawn := exec.Command("ssh-keygen", args...) spawn.Stdout = cfg.Stdout spawn.Stdin = cfg.Stdin spawn.Stderr = cfg.Stderr return args[5], spawn.Run() }
// WaitForServerState asks API in a loop until a server matches a wanted state func WaitForServerState(api *ScalewayAPI, serverID string, targetState string) (*ScalewayServer, error) { var server *ScalewayServer var err error var currentState string for { server, err = api.GetServer(serverID) if currentState != server.State { log.Infof("Server changed state to '%s'", server.State) currentState = server.State } if err != nil { return nil, err } if server.State == targetState { break } time.Sleep(1 * time.Second) } return server, nil }
// Run is the handler for 'scw run' func Run(ctx CommandContext, args RunArgs) error { if args.Gateway == "" { args.Gateway = ctx.Getenv("SCW_GATEWAY") } if args.TmpSSHKey { err := AddSSHKeyToTags(ctx, &args.Tags, args.Image) if err != nil { return err } } env := strings.Join(args.Tags, " ") volume := strings.Join(args.Volumes, " ") // create IMAGE logrus.Info("Server creation ...") dynamicIPRequired := args.Gateway == "" serverID, err := api.CreateServer(ctx.API, args.Image, args.Name, args.Bootscript, env, volume, dynamicIPRequired) if err != nil { return fmt.Errorf("failed to create server: %v", err) } logrus.Infof("Server created: %s", serverID) if args.AutoRemove { defer ctx.API.DeleteServerSafe(serverID) } // start SERVER logrus.Info("Server start requested ...") err = api.StartServer(ctx.API, serverID, false) if err != nil { return fmt.Errorf("failed to start server %s: %v", serverID, err) } logrus.Info("Server is starting, this may take up to a minute ...") if args.Detach { fmt.Fprintln(ctx.Stdout, serverID) return nil } else { // Sync cache on disk ctx.API.Sync() } if args.Attach { // Attach to server serial logrus.Info("Attaching to server console ...") err = utils.AttachToSerial(serverID, ctx.API.Token, true) if err != nil { return fmt.Errorf("cannot attach to server serial: %v", err) } } else { // Resolve gateway gateway, err := api.ResolveGateway(ctx.API, args.Gateway) if err != nil { return fmt.Errorf("cannot resolve Gateway '%s': %v", args.Gateway, err) } // waiting for server to be ready logrus.Debug("Waiting for server to be ready") // We wait for 30 seconds, which is the minimal amount of time needed by a server to boot server, err := api.WaitForServerReady(ctx.API, serverID, gateway) if err != nil { return fmt.Errorf("cannot get access to server %s: %v", serverID, err) } logrus.Debugf("SSH server is available: %s:22", server.PublicAddress.IP) logrus.Info("Server is ready !") // exec -w SERVER COMMAND ARGS... if len(args.Command) < 1 { logrus.Info("Connecting to server ...") err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, []string{}, false, gateway) } else { logrus.Infof("Executing command: %s ...", args.Command) err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args.Command, false, gateway) } if err != nil { return fmt.Errorf("command execution failed: %v", err) } logrus.Info("Command successfuly executed") } return nil }