Exemplo n.º 1
0
// Create a single server
func (vp *vultrProvider) createServer(options providers.CreateInstanceOptions) (string, error) {
	// Find SSH key ID
	var sshid string
	if len(options.SSHKeyNames) > 0 {
		var err error
		sshid, err = vp.findSSHKeyID(options.SSHKeyNames[0])
		if err != nil {
			return "", maskAny(err)
		}
	}
	// Fetch SSH keys
	sshKeys, err := providers.FetchSSHKeys(options.SSHKeyGithubAccount)
	if err != nil {
		return "", maskAny(err)
	}

	// Create cloud-config
	// user-data
	ccOpts := options.NewCloudConfigOptions()
	ccOpts.PrivateIPv4 = "$private_ipv4"
	ccOpts.SshKeys = sshKeys
	userData, err := templates.Render(cloudConfigTemplate, ccOpts)
	if err != nil {
		return "", maskAny(err)
	}

	name := options.InstanceName
	opts := &lib.ServerOptions{
		IPV6:              true,
		PrivateNetworking: true,
		SSHKey:            sshid,
		UserData:          userData,
	}
	regionID, err := strconv.Atoi(options.RegionID)
	if err != nil {
		return "", maskAny(err)
	}
	planID, err := strconv.Atoi(options.TypeID)
	if err != nil {
		return "", maskAny(err)
	}
	osID, err := strconv.Atoi(options.ImageID)
	if err != nil {
		return "", maskAny(err)
	}
	server, err := vp.client.CreateServer(name, regionID, planID, osID, opts)
	if err != nil {
		vp.Logger.Debugf("CreateServer failed: %#v", err)
		return "", maskAny(err)
	}
	vp.Logger.Infof("Created server %s %s\n", server.ID, server.Name)

	return server.ID, nil
}
Exemplo n.º 2
0
// createAndStartServer creates a new server and starts it.
// It then waits until the instance is active.
func (vp *scalewayProvider) createAndStartServer(options providers.CreateInstanceOptions) (providers.ClusterInstance, error) {
	zeroInstance := providers.ClusterInstance{}

	// Validate input
	if options.TincIpv4 == "" {
		return zeroInstance, maskAny(fmt.Errorf("TincIpv4 is empty"))
	}

	// Fetch SSH keys
	sshKeys, err := providers.FetchSSHKeys(options.SSHKeyGithubAccount)
	if err != nil {
		return zeroInstance, maskAny(err)
	}

	// Create cloud-config
	// user-data
	ccOpts := options.NewCloudConfigOptions()
	ccOpts.PrivateIPv4 = "$private_ipv4"
	ccOpts.SshKeys = sshKeys
	_ /*userData*/, err = templates.Render(cloudConfigTemplate, ccOpts)
	if err != nil {
		return zeroInstance, maskAny(err)
	}

	var arch string
	switch options.TypeID[:2] {
	case "C1":
		arch = "arm"
	case "C2", "VC":
		arch = "x86_64"
	}

	// Find image
	imageID, err := vp.getImageID(options.ImageID, arch)
	if err != nil {
		vp.Logger.Errorf("getImageID failed: %#v", err)
		return zeroInstance, maskAny(err)
	}

	name := options.InstanceName
	image := &imageID
	dynamicIPRequired := !vp.NoIPv4
	//bootscript := ""

	volID := ""
	/*if options.TypeID != commercialTypeVC1 {
		volDef := api.ScalewayVolumeDefinition{
			Name:         vp.volumeName(name),
			Size:         volumeSize,
			Type:         volumeType,
			Organization: vp.organization,
		}
		volID, err = vp.client.PostVolume(volDef)
		if err != nil {
			vp.Logger.Errorf("PostVolume failed: %#v", err)
			return zeroInstance, maskAny(err)
		}
	}*/

	publicIPIdentifier := ""
	if options.RoleLoadBalancer && vp.ReserveLoadBalancerIP {
		ip, err := vp.getFreeIP()
		if err != nil {
			return zeroInstance, maskAny(err)
		}
		publicIPIdentifier = ip.ID
	}

	opts := api.ScalewayServerDefinition{
		Name:              name,
		Image:             image,
		Volumes:           map[string]string{},
		DynamicIPRequired: &dynamicIPRequired,
		//Bootscript:        &bootscript,
		Tags: []string{
			options.ClusterInfo.ID,
			options.TincIpv4,
		},
		Organization:   vp.Organization,
		CommercialType: options.TypeID,
		PublicIP:       publicIPIdentifier,
		EnableIPV6:     vp.EnableIPV6,
	}
	if volID != "" {
		opts.Volumes["0"] = volID
	}
	vp.Logger.Debugf("Creating server %s: %#v\n", name, opts)
	id, err := vp.client.PostServer(opts)
	if err != nil {
		vp.Logger.Errorf("PostServer failed: %#v", err)
		// Delete volume
		if volID != "" {
			if err := vp.client.DeleteVolume(volID); err != nil {
				vp.Logger.Errorf("DeleteVolume failed: %#v", err)
			}
		}
		return zeroInstance, maskAny(err)
	}

	// Start server
	if err := vp.client.PostServerAction(id, "poweron"); err != nil {
		vp.Logger.Errorf("poweron failed: %#v", err)
		return zeroInstance, maskAny(err)
	}

	// Wait until server starts
	server, err := vp.waitUntilServerActive(id, true)
	if err != nil {
		return zeroInstance, maskAny(err)
	}

	// Download & copy fleet,etcd
	instance := vp.clusterInstance(server, true)
	return instance, nil
}
Exemplo n.º 3
0
// Create an entire cluster
func (vp *vagrantProvider) CreateCluster(log *logging.Logger, options providers.CreateClusterOptions, dnsProvider providers.DnsProvider) error {
	// Ensure folder exists
	if err := os.MkdirAll(vp.folder, fileMode|os.ModeDir); err != nil {
		return maskAny(err)
	}

	if _, err := os.Stat(filepath.Join(vp.folder, ".vagrant")); err == nil {
		return maskAny(fmt.Errorf("Vagrant in %s already exists", vp.folder))
	}

	parts := strings.Split(options.ImageID, "-")
	if len(parts) != 2 || parts[0] != "coreos" {
		return maskAny(fmt.Errorf("Invalid image ID, expected 'coreos-alpha|beta|stable', got '%s'", options.ImageID))
	}
	updateChannel := parts[1]

	vopts := struct {
		InstanceCount int
		UpdateChannel string
	}{
		InstanceCount: options.InstanceCount,
		UpdateChannel: updateChannel,
	}
	vp.instanceCount = options.InstanceCount

	// Vagrantfile
	content, err := templates.Render(vagrantFileTemplate, vopts)
	if err != nil {
		return maskAny(err)
	}
	if err := ioutil.WriteFile(filepath.Join(vp.folder, vagrantFileName), []byte(content), fileMode); err != nil {
		return maskAny(err)
	}

	// config.rb
	content, err = templates.Render(configTemplate, vopts)
	if err != nil {
		return maskAny(err)
	}
	if err := ioutil.WriteFile(filepath.Join(vp.folder, configFileName), []byte(content), fileMode); err != nil {
		return maskAny(err)
	}

	// Fetch SSH keys
	sshKeys, err := providers.FetchSSHKeys(options.SSHKeyGithubAccount)
	if err != nil {
		return maskAny(err)
	}
	// Fetch vagrant insecure private key
	insecureKey, err := fetchVagrantInsecureSSHKey()
	if err != nil {
		return maskAny(err)
	}
	sshKeys = append(sshKeys, insecureKey)

	// user-data
	isCore := true
	isLB := true
	instanceOptions, err := options.NewCreateInstanceOptions(isCore, isLB, 0)
	if err != nil {
		return maskAny(err)
	}
	opts := instanceOptions.NewCloudConfigOptions()
	opts.PrivateIPv4 = "$private_ipv4"
	opts.SshKeys = sshKeys

	content, err = templates.Render(cloudConfigTemplate, opts)
	if err != nil {
		return maskAny(err)
	}
	if err := ioutil.WriteFile(filepath.Join(vp.folder, userDataFileName), []byte(content), fileMode); err != nil {
		return maskAny(err)
	}

	// Start
	cmd := exec.Command("vagrant", "up")
	cmd.Dir = vp.folder
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	if err := cmd.Run(); err != nil {
		return maskAny(err)
	}

	// Run initial setup
	instances, err := vp.GetInstances(providers.ClusterInfo{})
	if err != nil {
		return maskAny(err)
	}
	clusterMembers, err := instances.AsClusterMemberList(log, nil)
	if err != nil {
		return maskAny(err)
	}
	for index, instance := range instances {
		iso := providers.InitialSetupOptions{
			ClusterMembers: clusterMembers,
			FleetMetadata:  instanceOptions.CreateFleetMetadata(index),
		}
		if err := instance.InitialSetup(log, instanceOptions, iso, vp); err != nil {
			return maskAny(err)
		}
	}

	return nil
}