コード例 #1
0
ファイル: openstack.go プロジェクト: LunaNode/cloug
func (os *OpenStack) ReimageInstance(instanceID string, image *compute.Image) error {
	imageID, err := common.GetMatchingImageID(os, image)
	if err != nil {
		return err
	}
	opts := servers.RebuildOpts{
		ImageID: imageID,
	}
	_, err = servers.Rebuild(os.ComputeClient, instanceID, opts).Extract()
	return err
}
コード例 #2
0
ファイル: lunanode.go プロジェクト: LunaNode/cloug
func (ln *LunaNode) ReimageInstance(instanceID string, image *compute.Image) error {
	imageID, err := common.GetMatchingImageID(ln, image)
	if err != nil {
		return err
	}
	imageIDInt, err := strconv.Atoi(imageID)
	if err != nil {
		return fmt.Errorf("invalid image ID: %s", imageID)
	}

	return ln.instanceAction(instanceID, func(id int) error {
		return ln.api.VmReimage(id, imageIDInt)
	})
}
コード例 #3
0
ファイル: lobster.go プロジェクト: LunaNode/cloug
func (lobster *Lobster) ReimageInstance(instanceID string, image *compute.Image) error {
	imageID, err := common.GetMatchingImageID(lobster, image)
	if err != nil {
		return err
	}
	imageIDInt, err := strconv.Atoi(imageID)
	if err != nil {
		return fmt.Errorf("invalid image ID: %s", imageID)
	}

	return lobster.instanceAction(instanceID, func(id int) error {
		return lobster.client.VmReimage(id, imageIDInt)
	})
}
コード例 #4
0
ファイル: lobster.go プロジェクト: LunaNode/cloug
func (lobster *Lobster) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	if instance.PublicKey.ID == "" && len(instance.PublicKey.Key) > 0 {
		return common.KeypairServiceCreateWrapper(lobster, lobster, instance)
	}

	imageID, err := common.GetMatchingImageID(lobster, &instance.Image)
	if err != nil {
		return nil, err
	}
	flavorID, err := common.GetMatchingFlavorID(lobster, &instance.Flavor)
	if err != nil {
		return nil, err
	}

	imageIDInt, err := strconv.Atoi(imageID)
	if err != nil {
		return nil, fmt.Errorf("invalid image ID: %s", imageID)
	}
	flavorIDInt, err := strconv.Atoi(flavorID)
	if err != nil {
		return nil, fmt.Errorf("invalid flavor ID: %s", flavorID)
	}

	name := instance.Name
	if name == "" {
		name = DEFAULT_NAME
	}

	var clientOptions api.VmCreateOptions
	if instance.PublicKey.ID != "" {
		clientOptions.KeyId, err = strconv.Atoi(instance.PublicKey.ID)
		if err != nil {
			return nil, fmt.Errorf("invalid key ID: %s", instance.PublicKey.ID)
		}
	}

	vmID, err := lobster.client.VmCreate(name, flavorIDInt, imageIDInt, &clientOptions)
	if err != nil {
		return nil, err
	} else {
		return &compute.Instance{
			ID: strconv.Itoa(vmID),
		}, nil
	}
}
コード例 #5
0
ファイル: lunanode.go プロジェクト: LunaNode/cloug
func (ln *LunaNode) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	imageID, err := common.GetMatchingImageID(ln, &instance.Image)
	if err != nil {
		return nil, err
	}
	flavorID, err := common.GetMatchingFlavorID(ln, &instance.Flavor)
	if err != nil {
		return nil, err
	}

	imageIDInt, err := strconv.Atoi(imageID)
	if err != nil {
		return nil, fmt.Errorf("invalid image ID: %s", imageID)
	}
	flavorIDInt, err := strconv.Atoi(flavorID)
	if err != nil {
		return nil, fmt.Errorf("invalid flavor ID: %s", flavorID)
	}

	region := instance.Region
	if region == "" {
		region = DEFAULT_REGION
	}

	name := instance.Name
	if name == "" {
		name = DEFAULT_NAME
	}

	vmId, err := ln.api.VmCreateImage(region, name, flavorIDInt, imageIDInt)
	if err != nil {
		return nil, err
	} else {
		return &compute.Instance{
			ID: fmt.Sprintf("%d", vmId),
		}, nil
	}
}
コード例 #6
0
ファイル: vultr.go プロジェクト: LunaNode/cloug
func (vt *Vultr) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	if instance.PublicKey.ID == "" && len(instance.PublicKey.Key) > 0 {
		return common.KeypairServiceCreateWrapper(vt, vt, instance)
	}

	imageID, err := common.GetMatchingImageID(vt, &instance.Image)
	if err != nil {
		return nil, err
	}
	flavorID, err := common.GetMatchingFlavorID(vt, &instance.Flavor)
	if err != nil {
		return nil, err
	}

	flavorIDInt, err := strconv.Atoi(flavorID)
	if err != nil {
		return nil, fmt.Errorf("invalid flavor ID: %s", flavorID)
	}

	name := instance.Name
	if name == "" {
		name = DEFAULT_NAME
	}

	serverOptions := &vultr.ServerOptions{
		PrivateNetworking:    instance.Detail("private_networking", "yes") == "yes",
		IPV6:                 instance.Detail("ipv6", "yes") == "yes",
		AutoBackups:          instance.Detail("auto_backups", "no") == "yes",
		DontNotifyOnActivate: instance.Detail("dont_notify_on_activate", "no") == "yes",
	}

	imageParts := strings.SplitN(imageID, ":", 2)
	if len(imageParts) != 2 {
		return nil, fmt.Errorf("malformed image ID: missing colon")
	}
	if imageParts[0] == "iso" {
		customOSID, err := vt.findOSByName("Custom")
		if err != nil {
			return nil, fmt.Errorf("failed to get custom OS for creation from ISO: %v", err)
		}
		serverOptions.OS = customOSID
		serverOptions.ISO, _ = strconv.Atoi(imageParts[1])
	} else if imageParts[0] == "os" {
		serverOptions.OS, _ = strconv.Atoi(imageParts[1])
	} else if imageParts[0] == "snapshot" {
		snapshotOSID, err := vt.findOSByName("Snapshot")
		if err != nil {
			return nil, fmt.Errorf("failed to get snapshot OS for creation from snapshot: %v", err)
		}
		serverOptions.OS = snapshotOSID
		serverOptions.Snapshot = imageParts[1]
	} else if imageParts[0] == "app" {
		appOSID, err := vt.findOSByName("Application")
		if err != nil {
			return nil, fmt.Errorf("failed to get application OS for creation from application: %v", err)
		}
		serverOptions.OS = appOSID
		serverOptions.Application, _ = strconv.Atoi(imageParts[1])
	} else {
		return nil, fmt.Errorf("invalid image type " + imageParts[0])
	}

	if instance.PublicKey.ID != "" {
		serverOptions.SSHKey = instance.PublicKey.ID
	}

	region := DEFAULT_REGION
	if instance.Region != "" {
		region = instance.Region
	}
	regionID, err := vt.findRegion(region)
	if err != nil {
		return nil, fmt.Errorf("failed to identify region ID: %v", err)
	}

	server, err := vt.client.CreateServer(name, regionID, flavorIDInt, serverOptions)
	if err != nil {
		return nil, err
	} else {
		return &compute.Instance{
			ID: server.ID,
		}, nil
	}
}
コード例 #7
0
ファイル: openstack.go プロジェクト: LunaNode/cloug
func (os *OpenStack) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	imageID, err := common.GetMatchingImageID(os, &instance.Image)
	if err != nil {
		return nil, err
	}
	flavorID, err := common.GetMatchingFlavorID(os, &instance.Flavor)
	if err != nil {
		return nil, err
	}

	password := instance.Password
	if password == "" {
		password = utils.Uid(16)
	}

	opts := servers.CreateOpts{
		Name:             instance.Name,
		ImageRef:         imageID,
		FlavorRef:        flavorID,
		AdminPass:        password,
		UserData:         []byte("#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n"),
		AvailabilityZone: instance.Region,
	}

	if instance.NetworkID != "" {
		opts.Networks = []servers.Network{{UUID: instance.NetworkID}}
	}

	if opts.Name == "" {
		opts.Name = DEFAULT_NAME
	}

	createResult := servers.Create(os.ComputeClient, opts)
	server, err := createResult.Extract()
	if err != nil {
		return nil, err
	}

	// try to associate floating IP with this VM
	// do asynchronously since it might fail until network port is created
	go func() {
		for try := 0; try < 6; try++ {
			time.Sleep(4 * time.Second)

			// find a free floating IP, or find the IP matching requested IP
			var freeFloatingIP *floatingip.FloatingIP
			err := floatingip.List(os.ComputeClient).EachPage(func(page pagination.Page) (bool, error) {
				floatingIPs, err := floatingip.ExtractFloatingIPs(page)
				if err != nil {
					return false, err
				}

				for _, floatingIP := range floatingIPs {
					if floatingIP.InstanceID == "" && (instance.IP == "" || floatingIP.IP == instance.IP) {
						freeFloatingIP = &floatingIP
						return false, nil
					}
				}
				return true, nil
			})
			if err != nil {
				continue
			} else if freeFloatingIP == nil {
				continue
			}

			// associate it
			err = floatingip.Associate(os.ComputeClient, server.ID, freeFloatingIP.IP).ExtractErr()
			if err == nil {
				break
			}
		}
	}()

	return &compute.Instance{
		ID:       server.ID,
		Name:     server.Name,
		Status:   os.mapInstanceStatus(server.Status),
		Password: password,
	}, nil
}
コード例 #8
0
ファイル: ec2.go プロジェクト: LunaNode/cloug
func (e *EC2) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	imageID, err := common.GetMatchingImageID(e, &instance.Image)
	if err != nil {
		return nil, err
	}
	flavorID, err := common.GetMatchingFlavorID(e, &instance.Flavor)
	if err != nil {
		return nil, err
	}

	region := DEFAULT_REGION
	if instance.Region != "" {
		region = instance.Region
	}
	svc := e.getService(region)

	opts := ec2.RunInstancesInput{
		ImageId:      aws.String(imageID),
		InstanceType: aws.String(flavorID),
		MinCount:     aws.Int64(1),
		MaxCount:     aws.Int64(1),
	}

	password := instance.Password
	if password == "" {
		password = utils.Uid(16)
	}
	userData := "#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n"
	opts.UserData = aws.String(base64.StdEncoding.EncodeToString([]byte(userData)))

	if instance.Flavor.DiskGB > 0 {
		opts.BlockDeviceMappings = []*ec2.BlockDeviceMapping{
			{
				Ebs: &ec2.EbsBlockDevice{
					VolumeSize:          aws.Int64(int64(instance.Flavor.DiskGB)),
					DeleteOnTermination: aws.Bool(true),
					VolumeType:          aws.String("gp2"),
				},
			},
		}
	}

	if len(instance.PublicKey.Key) > 0 {
		keyName := utils.Uid(8)
		_, err := svc.ImportKeyPair(&ec2.ImportKeyPairInput{
			KeyName:           aws.String(keyName),
			PublicKeyMaterial: instance.PublicKey.Key,
		})
		if err != nil {
			return nil, fmt.Errorf("failed to import public key: %v", err)
		}
		defer svc.DeleteKeyPair(&ec2.DeleteKeyPairInput{
			KeyName: aws.String(keyName),
		})
		opts.KeyName = aws.String(keyName)
	}

	res, err := svc.RunInstances(&opts)
	if err != nil {
		return nil, err
	} else if len(res.Instances) != 1 {
		return nil, fmt.Errorf("attempted to provision a single instance, but reservation contains %d instances", len(res.Instances))
	}
	resInstance := res.Instances[0]

	return &compute.Instance{
		ID:       encodeID(String(resInstance.InstanceId), region),
		Status:   e.mapInstanceStatus(String(resInstance.State.Name)),
		Password: password,
	}, nil
}
コード例 #9
0
ファイル: googlecompute.go プロジェクト: LunaNode/cloug
func (gc *GoogleCompute) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	imageID, err := common.GetMatchingImageID(gc, &instance.Image)
	if err != nil {
		return nil, err
	}
	flavorID, err := common.GetMatchingFlavorID(gc, &instance.Flavor)
	if err != nil {
		return nil, err
	}

	name := utils.UidAlphabet(24, []rune("abcdefghijklmnopqrstuvwxyz"))

	region := instance.Region
	if region == "" {
		region = DEFAULT_REGION
	}

	apiInstance := gcompute.Instance{
		Name:        name,
		MachineType: fmt.Sprintf("zones/%s/machineTypes/%s", region, flavorID),
		Disks: []*gcompute.AttachedDisk{
			&gcompute.AttachedDisk{
				AutoDelete: true,
				Boot:       true,
				Type:       "PERSISTENT",
				InitializeParams: &gcompute.AttachedDiskInitializeParams{
					SourceImage: imageID,
					DiskSizeGb:  int64(instance.Flavor.DiskGB),
				},
			},
		},
		NetworkInterfaces: []*gcompute.NetworkInterface{
			&gcompute.NetworkInterface{
				Network: "global/networks/default",
				AccessConfigs: []*gcompute.AccessConfig{
					&gcompute.AccessConfig{
						Type: "ONE_TO_ONE_NAT",
						Name: "External NAT",
					},
				},
			},
		},
	}

	password := instance.Password
	if password == "" {
		password = utils.Uid(16)
	}
	userData := "#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n"
	apiInstance.Metadata = &gcompute.Metadata{
		Items: []*gcompute.MetadataItems{
			&gcompute.MetadataItems{
				Key:   "user-data",
				Value: &userData,
			},
		},
	}

	operation, err := gc.waitForOperation(gc.service.Instances.Insert(gc.project, region, &apiInstance))
	if err != nil {
		return nil, err
	} else {
		return &compute.Instance{
			ID:       fmt.Sprintf("%s:%s", basename(operation.Zone), name),
			Password: password,
		}, nil
	}
}
コード例 #10
0
ファイル: linode.go プロジェクト: LunaNode/cloug
func (ln *Linode) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	imageID, err := common.GetMatchingImageID(ln, &instance.Image)
	if err != nil {
		return nil, err
	}
	plan, err := ln.findMatchingPlan(&instance.Flavor)
	if err != nil {
		return nil, err
	}
	kernelID, err := ln.findKernel()
	if err != nil {
		return nil, err
	}
	password := instance.Password
	if password == "" {
		password = utils.Uid(16)
	}

	datacenterAbbrev := instance.Region
	if datacenterAbbrev == "" {
		datacenterAbbrev = DEFAULT_DATACENTER
	}
	datacenterID, err := ln.findDatacenter(datacenterAbbrev)
	if err != nil {
		return nil, err
	}

	// create linode
	linodeID, err := ln.client.CreateLinode(datacenterID, plan.ID)
	if err != nil {
		return nil, err
	}

	// create disks
	storage := instance.Flavor.DiskGB
	if storage == 0 {
		storage = DEFAULT_STORAGE
	}

	totalDiskMB := storage * 1024
	swapSize := plan.RAM / 2
	diskSize := totalDiskMB - swapSize

	var diskID int
	imageParts := strings.SplitN(imageID, ":", 2)
	if len(imageParts) != 2 {
		return nil, errors.New("malformed image ID: missing colon")
	}
	if imageParts[0] == "distribution" {
		distributionID, _ := strconv.Atoi(imageParts[1])
		diskID, _, err = ln.client.CreateDiskFromDistribution(linodeID, "cloug", distributionID, diskSize, password, "")
		if err != nil {
			ln.client.DeleteLinode(linodeID, false)
			return nil, err
		}
	} else if imageParts[0] == "image" {
		imageID, _ := strconv.Atoi(imageParts[1])
		diskID, _, err = ln.client.CreateDiskFromImage(linodeID, "cloug", imageID, diskSize, password, "")
		if err != nil {
			ln.client.DeleteLinode(linodeID, false)
			return nil, err
		}
	} else {
		return nil, errors.New("invalid image type " + imageParts[0])
	}

	swapID, _, err := ln.client.CreateDisk(linodeID, "cloug-swap", "swap", swapSize, linode.CreateDiskOptions{})
	if err != nil {
		ln.client.DeleteLinode(linodeID, false)
		return nil, err
	}

	_, err = ln.client.CreateConfig(linodeID, kernelID, "cloug", []int{diskID, swapID}, linode.CreateConfigOptions{})
	if err != nil {
		ln.client.DeleteLinode(linodeID, false)
		return nil, err
	} else {
		ln.client.BootLinode(linodeID)
		return &compute.Instance{
			ID:       strconv.Itoa(linodeID),
			Password: password,
		}, nil
	}
}