// newHostedService creates a hosted service. It will make up a unique name, // starting with the given prefix. func newHostedService(azure *gwacl.ManagementAPI, prefix, affinityGroupName, label string) (*gwacl.HostedService, error) { var err error var createdService *gwacl.CreateHostedService for tries := 10; tries > 0 && err == nil && createdService == nil; tries-- { createdService, err = attemptCreateService(azure, prefix, affinityGroupName, label) } if err != nil { return nil, errors.Annotate(err, "could not create hosted service") } if createdService == nil { return nil, fmt.Errorf("could not come up with a unique hosted service name - is your randomizer initialized?") } return azure.GetHostedServiceProperties(createdService.ServiceName, true) }
// createInstance creates all of the Azure entities necessary for a // new instance. This includes Cloud Service, Deployment and Role. // // If serviceName is non-empty, then createInstance will assign to // the Cloud Service with that name. Otherwise, a new Cloud Service // will be created. func (env *azureEnviron) createInstance(azure *gwacl.ManagementAPI, role *gwacl.Role, serviceName string, stateServer bool) (resultInst instance.Instance, resultErr error) { var inst instance.Instance defer func() { if inst != nil && resultErr != nil { if err := env.StopInstances(inst.Id()); err != nil { // Failure upon failure. Log it, but return the original error. logger.Errorf("error releasing failed instance: %v", err) } } }() var err error var service *gwacl.HostedService if serviceName != "" { logger.Debugf("creating instance in existing cloud service %q", serviceName) service, err = azure.GetHostedServiceProperties(serviceName, true) } else { logger.Debugf("creating instance in new cloud service") // If we're creating a cloud service for state servers, // we will want to open additional ports. We need to // record this against the cloud service, so we use a // special label for the purpose. var label string if stateServer { label = stateServerLabel } service, err = newHostedService(azure, env.getEnvPrefix(), env.getAffinityGroupName(), label) } if err != nil { return nil, err } if len(service.Deployments) == 0 { // This is a newly created cloud service, so we // should destroy it if anything below fails. defer func() { if resultErr != nil { azure.DeleteHostedService(service.ServiceName) // Destroying the hosted service destroys the instance, // so ensure StopInstances isn't called. inst = nil } }() // Create an initial deployment. deployment := gwacl.NewDeploymentForCreateVMDeployment( deploymentNameV2(service.ServiceName), deploymentSlot, deploymentNameV2(service.ServiceName), []gwacl.Role{*role}, env.getVirtualNetworkName(), ) if err := azure.AddDeployment(deployment, service.ServiceName); err != nil { return nil, errors.Annotate(err, "error creating VM deployment") } service.Deployments = append(service.Deployments, *deployment) } else { // Update the deployment. deployment := &service.Deployments[0] if err := azure.AddRole(&gwacl.AddRoleRequest{ ServiceName: service.ServiceName, DeploymentName: deployment.Name, PersistentVMRole: (*gwacl.PersistentVMRole)(role), }); err != nil { return nil, err } deployment.RoleList = append(deployment.RoleList, *role) } return env.getInstance(service, role.RoleName) }