Beispiel #1
0
func bootMachine(m machine.Machine) error {
	id := uuid.NewV4().String()

	err := initMachine(cloudcfg.Ubuntu(m.SSHKeys, "xenial"), m.Size, id)
	if err == nil {
		err = up(id)
	}

	if err != nil {
		destroy(id)
	}

	return err
}
Beispiel #2
0
// Boot blocks while creating instances.
func (clst *Cluster) Boot(bootSet []machine.Machine) error {
	// XXX: should probably have a better clean up routine if an error is encountered
	var names []string
	for _, m := range bootSet {
		name := "quilt-" + uuid.NewV4().String()
		_, err := clst.instanceNew(name, m.Size, m.Region,
			cloudcfg.Ubuntu(m.SSHKeys, "xenial"))
		if err != nil {
			log.WithFields(log.Fields{
				"error": err,
				"id":    m.ID,
			}).Error("Failed to start instance.")
			continue
		}
		names = append(names, name)
	}
	if err := clst.wait(names, true); err != nil {
		return err
	}
	return nil
}
Beispiel #3
0
func TestBoot(t *testing.T) {
	t.Parallel()

	mc := new(mockClient)
	mc.On("DescribeSecurityGroups", mock.Anything).Return(
		&ec2.DescribeSecurityGroupsOutput{
			SecurityGroups: []*ec2.SecurityGroup{
				{
					GroupId: aws.String("groupId"),
				},
			},
		}, nil,
	)
	mc.On("RequestSpotInstances", mock.Anything).Return(
		&ec2.RequestSpotInstancesOutput{
			SpotInstanceRequests: []*ec2.SpotInstanceRequest{
				{
					SpotInstanceRequestId: aws.String("spot1"),
				},
				{
					SpotInstanceRequestId: aws.String("spot2"),
				},
			},
		}, nil,
	)
	mc.On("CreateTags", mock.Anything).Return(
		&ec2.CreateTagsOutput{}, nil,
	)
	mc.On("DescribeInstances", mock.Anything).Return(
		&ec2.DescribeInstancesOutput{}, nil,
	)
	mc.On("DescribeSpotInstanceRequests", mock.Anything).Return(
		&ec2.DescribeSpotInstanceRequestsOutput{
			SpotInstanceRequests: []*ec2.SpotInstanceRequest{
				{
					SpotInstanceRequestId: aws.String("spot1"),
					State: aws.String(ec2.SpotInstanceStateActive),
					Tags: []*ec2.Tag{
						{
							Key:   aws.String(testNamespace),
							Value: aws.String(""),
						},
					},
				},
				{
					SpotInstanceRequestId: aws.String("spot2"),
					State: aws.String(ec2.SpotInstanceStateActive),
					Tags: []*ec2.Tag{
						{
							Key:   aws.String(testNamespace),
							Value: aws.String(""),
						},
					},
				},
			},
		}, nil,
	)

	amazonCluster := newAmazon(testNamespace)
	amazonCluster.newClient = func(region string) client {
		return mc
	}

	err := amazonCluster.Boot([]machine.Machine{
		{
			Region:   "us-west-1",
			Size:     "m4.large",
			DiskSize: 32,
		},
		{
			Region:   "us-west-1",
			Size:     "m4.large",
			DiskSize: 32,
		},
	})
	assert.Nil(t, err)

	cfg := cloudcfg.Ubuntu(nil, "xenial")
	mc.AssertCalled(t, "RequestSpotInstances",
		&ec2.RequestSpotInstancesInput{
			SpotPrice: aws.String(spotPrice),
			LaunchSpecification: &ec2.RequestSpotLaunchSpecification{
				ImageId:      aws.String(amis["us-west-1"]),
				InstanceType: aws.String("m4.large"),
				UserData: aws.String(base64.StdEncoding.EncodeToString(
					[]byte(cfg))),
				SecurityGroupIds: aws.StringSlice([]string{"groupId"}),
				BlockDeviceMappings: []*ec2.BlockDeviceMapping{
					blockDevice(32)},
			},
			InstanceCount: aws.Int64(2),
		},
	)
	mc.AssertCalled(t, "CreateTags",
		&ec2.CreateTagsInput{
			Tags: []*ec2.Tag{
				{
					Key:   aws.String(testNamespace),
					Value: aws.String(""),
				},
			},
			Resources: aws.StringSlice([]string{"spot1", "spot2"}),
		},
	)
}
Beispiel #4
0
// Boot creates instances in the `clst` configured according to the `bootSet`.
func (clst Cluster) Boot(bootSet []machine.Machine) error {
	if len(bootSet) <= 0 {
		return nil
	}

	type bootReq struct {
		cfg      string
		size     string
		region   string
		diskSize int
	}

	bootReqMap := make(map[bootReq]int64) // From boot request to an instance count.
	for _, m := range bootSet {
		br := bootReq{
			cfg:      cloudcfg.Ubuntu(m.SSHKeys, "xenial"),
			size:     m.Size,
			region:   m.Region,
			diskSize: m.DiskSize,
		}
		bootReqMap[br] = bootReqMap[br] + 1
	}

	var awsIDs []awsID
	for br, count := range bootReqMap {
		client := clst.getClient(br.region)
		groupID, _, err := clst.getCreateSecurityGroup(client)
		if err != nil {
			return err
		}

		cloudConfig64 := base64.StdEncoding.EncodeToString([]byte(br.cfg))
		resp, err := client.RequestSpotInstances(&ec2.RequestSpotInstancesInput{
			SpotPrice: aws.String(spotPrice),
			LaunchSpecification: &ec2.RequestSpotLaunchSpecification{
				ImageId:          aws.String(amis[br.region]),
				InstanceType:     aws.String(br.size),
				UserData:         &cloudConfig64,
				SecurityGroupIds: []*string{aws.String(groupID)},
				BlockDeviceMappings: []*ec2.BlockDeviceMapping{
					blockDevice(br.diskSize),
				},
			},
			InstanceCount: &count,
		})

		if err != nil {
			return err
		}

		for _, request := range resp.SpotInstanceRequests {
			awsIDs = append(awsIDs, awsID{
				spotID: *request.SpotInstanceRequestId,
				region: br.region})
		}
	}

	if err := clst.tagSpotRequests(awsIDs); err != nil {
		return err
	}

	return clst.wait(awsIDs, true)
}