Esempio n. 1
0
func waitSSHConnection(ctx CommandContext, args RunArgs, serverID string) (chan notifSSHConnection, string, error) {
	notif := make(chan notifSSHConnection)
	// Resolve gateway
	gateway, err := api.ResolveGateway(ctx.API, args.Gateway)
	if err != nil {
		return nil, "", 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
	go func() {
		server, err := api.WaitForServerReady(ctx.API, serverID, gateway)
		if err != nil {
			notif <- notifSSHConnection{
				err: fmt.Errorf("cannot get access to server %s: %v", serverID, err),
			}
			return
		}
		logrus.Debugf("SSH server is available: %s:22", server.PublicAddress.IP)
		logrus.Info("Server is ready !")
		notif <- notifSSHConnection{
			server: server,
		}
	}()
	return notif, gateway, nil
}
Esempio n. 2
0
// restartIdentifiers resolves server IDs, restarts, and waits for them to be ready (-w)
func restartIdentifiers(ctx CommandContext, wait bool, servers []string, cr chan string) {
	var wg sync.WaitGroup
	for _, needle := range servers {
		wg.Add(1)
		go func(needle string) {
			defer wg.Done()
			server := ctx.API.GetServerID(needle)
			res := server
			err := ctx.API.PostServerAction(server, "reboot")
			if err != nil {
				if err.Error() != "server is being stopped or rebooted" {
					logrus.Errorf("failed to restart server %s: %s", server, err)
				}
				res = ""
			} else {
				if wait {
					// FIXME: handle gateway
					api.WaitForServerReady(ctx.API, server, "")
				}
			}
			cr <- res
		}(needle)
	}
	wg.Wait()
	close(cr)
}
func resourceServerCreate(d *schema.ResourceData, m interface{}) error {
	scaleway := m.(*api.ScalewayAPI)

	image := d.Get("image").(string)

	volumes := make(map[string]string)

	/*for k, v := range d.Get("volumes").(map[string]interface{}) {
		volumes[k] = v.(string)
	}*/

	var def api.ScalewayServerDefinition

	def.Name = d.Get("name").(string)
	def.Image = &image
	def.Volumes = volumes

	if bootscriptI, ok := d.GetOk("bootscript"); ok {
		bootscript := bootscriptI.(string)
		def.Bootscript = &bootscript
	}

	if tags, ok := d.GetOk("tags"); ok {
		def.Tags = tags.([]string)
	}

	id, err := scaleway.PostServer(def)
	if err != nil {
		serr := err.(api.ScalewayAPIError)
		// _, _ := json.Marshal(def)
		return fmt.Errorf("Error Posting server with image %s. Reason: %s", image, serr.APIMessage)
	}

	err = scaleway.PostServerAction(id, "poweron")

	if err != nil {
		return err
	}

	d.SetId(id)

	_, err = api.WaitForServerReady(scaleway, id, "")

	if err != nil {
		return err
	}

	return resourceServerRead(d, m)
}
Esempio n. 4
0
// RunExec is the handler for 'scw exec'
func RunExec(ctx CommandContext, args ExecArgs) error {
	var fingerprints []string

	done := make(chan struct{})

	serverID, err := ctx.API.GetServerID(args.Server)
	if err != nil {
		return err
	}

	go func() {
		fingerprints = ctx.API.GetSSHFingerprintFromServer(serverID)
		close(done)
	}()
	// Resolve gateway
	if args.Gateway == "" {
		args.Gateway = ctx.Getenv("SCW_GATEWAY")
	}
	var gateway string

	if args.Gateway == serverID || args.Gateway == args.Server {
		logrus.Debugf("The server and the gateway are the same host, using direct access to the server")
		gateway = ""
	} else {
		gateway, err = api.ResolveGateway(ctx.API, args.Gateway)
		if err != nil {
			return fmt.Errorf("Cannot resolve Gateway '%s': %v", args.Gateway, err)
		}
		if gateway != "" {
			logrus.Debugf("The server will be accessed using the gateway '%s' as a SSH relay", gateway)
		}
	}

	var server *api.ScalewayServer
	if args.Wait {
		// --wait
		logrus.Debugf("Waiting for server to be ready")
		server, err = api.WaitForServerReady(ctx.API, serverID, gateway)
		if err != nil {
			return fmt.Errorf("Failed to wait for server to be ready, %v", err)
		}
	} else {
		// no --wait
		logrus.Debugf("scw won't wait for the server to be ready, if it is not, the command will fail")
		server, err = ctx.API.GetServer(serverID)
		if err != nil {
			rerr := fmt.Errorf("Failed to get server information for %s: %v", serverID, err)
			if err.Error() == `"`+serverID+`" not found` {
				return fmt.Errorf("%v\nmaybe try to flush the cache with : scw _flush-cache", rerr)
			}
			return rerr
		}
	}

	if server.PublicAddress.IP == "" && gateway == "" {
		logrus.Warn(`Your host has no public IP address, you should use '--gateway', see 'scw help exec'`)
	}

	// --timeout
	if args.Timeout > 0 {
		logrus.Debugf("Setting up a global timeout of %d seconds", args.Timeout)
		// FIXME: avoid use of log.Fatalf here
		go func() {
			time.Sleep(time.Duration(args.Timeout*1000) * time.Millisecond)
			logrus.Fatalf("Operation timed out")
		}()
	}

	<-done
	if len(fingerprints) > 0 {
		for i := range fingerprints {
			fmt.Fprintf(ctx.Stdout, "%s\n", fingerprints[i])
		}
	}
	logrus.Debugf("PublicDNS %s", serverID+api.URLPublicDNS)
	logrus.Debugf("PrivateDNS %s", serverID+api.URLPrivateDNS)
	if err = utils.SSHExec(server.PublicAddress.IP, server.PrivateIP, args.SSHUser, args.SSHPort, args.Command, !args.Wait, gateway); err != nil {
		return fmt.Errorf("Failed to run the command: %v", err)
	}

	logrus.Debugf("Command successfully executed")
	return nil
}
Esempio n. 5
0
// 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
}