Exemplo n.º 1
0
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
}