func (d *Driver) Create() error { if err := d.checkPrereqs(); err != nil { return err } log.Infof("Creating key pair for instances...") if err := d.createKeyPair(); err != nil { return fmt.Errorf("unable to create key pair: %s", err) } log.Infof("Configuring security groups...") if err := d.configureSecurityGroup(d.SecurityGroupName); err != nil { return err } // TODO Support data disk if d.SSHPassword == "" { d.SSHPassword = randomPassword() log.Info("Launching instance with generated password, please update password in console or log in with ssh key.") } imageID := d.GetImageID(d.ImageID) log.Infof("Launching instance with image %s ...", imageID) args := ecs.CreateInstanceArgs{ RegionId: d.Region, ImageId: imageID, InstanceType: d.InstanceType, SecurityGroupId: d.SecurityGroupId, Password: d.SSHPassword, VSwitchId: d.VSwitchId, ClientToken: d.getClient().GenerateClientToken(), } // Set InternetMaxBandwidthOut only for classic network if d.VSwitchId == "" { args.InternetMaxBandwidthOut = d.InternetMaxBandwidthOut } //log.Debugf("CreateInstanceArgs: %++v", args) // Create instance instanceId, err := d.getClient().CreateInstance(&args) if err != nil { err = fmt.Errorf("Error create instance: %s", err) log.Error(err) return err } d.InstanceId = instanceId // Wait for creation successfully err = d.getClient().WaitForInstance(instanceId, ecs.Stopped, 300) if err != nil { err = fmt.Errorf("Error wait instance to Stopped: %s", err) log.Error(err) } // Assign public IP if not private IP only if err == nil && !d.PrivateIPOnly { if d.VSwitchId == "" { // Allocate public IP address for classic network _, err = d.getClient().AllocatePublicIpAddress(instanceId) if err != nil { err = fmt.Errorf("Error allocate public IP address for instance %s: %v", instanceId, err) } } else { err = d.configNetwork(instanceId) } } if err == nil { // Start instance err = d.getClient().StartInstance(instanceId) if err == nil { // Wait for running err = d.getClient().WaitForInstance(instanceId, ecs.Running, 300) if err == nil { instance, err := d.getInstance() if err == nil { if len(instance.InnerIpAddress.IpAddress) > 0 { d.PrivateIPAddress = instance.InnerIpAddress.IpAddress[0] } d.IPAddress = d.getIP(instance) ssh.SetDefaultClient(ssh.Native) d.uploadKeyPair() log.Debugf("created instance ID %s, IP address %s, Private IP address %s", d.InstanceId, d.IPAddress, d.PrivateIPAddress, ) } } else { err = fmt.Errorf("Failed to wait instance to running state: %s", err) } } else { err = fmt.Errorf("Failed to start instance %s: %v", instanceId, err) } } if err != nil { log.Warn(err) d.Remove() } return err }
func (d *Driver) Create() error { var ( err error ) VpcId := d.VpcId VSwitchId := d.VSwitchId if err := d.checkPrereqs(); err != nil { return err } log.Infof("%s | Creating key pair for instance ...", d.MachineName) if err := d.createKeyPair(); err != nil { return fmt.Errorf("%s | Failed to create key pair: %v", d.MachineName, err) } log.Infof("%s | Configuring security groups instance ...", d.MachineName) if err := d.configureSecurityGroup(VpcId, d.SecurityGroupName); err != nil { return err } // TODO Support data disk if d.SSHPassword == "" { d.SSHPassword = randomPassword() log.Infof("%s | Launching instance with generated password, please update password in console or log in with ssh key.", d.MachineName) } imageID := d.GetImageID(d.ImageID) log.Infof("%s | Creating instance with image %s ...", d.MachineName, imageID) args := ecs.CreateInstanceArgs{ RegionId: d.Region, InstanceName: d.GetMachineName(), ImageId: imageID, InstanceType: d.InstanceType, SecurityGroupId: d.SecurityGroupId, InternetChargeType: internetChargeType, Password: d.SSHPassword, VSwitchId: VSwitchId, ZoneId: d.Zone, ClientToken: d.getClient().GenerateClientToken(), } if d.DiskSize > 0 { // Allocate Data Disk disk := ecs.DataDiskType{ DiskName: d.MachineName + "_data", Description: "Data volume for Docker", Size: d.DiskSize, Category: d.DiskCategory, Device: "/dev/xvdb", DeleteWithInstance: true, } args.DataDisk = []ecs.DataDiskType{disk} } // Set InternetMaxBandwidthOut only for classic network if VSwitchId == "" { args.InternetMaxBandwidthOut = d.InternetMaxBandwidthOut } // Create instance instanceId, err := d.getClient().CreateInstance(&args) if err != nil { err = fmt.Errorf("%s | Failed to create instance: %s", d.MachineName, err) log.Error(err) return err } log.Infof("%s | Create instance %s successfully", d.MachineName, instanceId) d.InstanceId = instanceId // Wait for creation successfully err = d.getClient().WaitForInstance(instanceId, ecs.Stopped, timeout) if err != nil { err = fmt.Errorf("%s | Failed to wait instance to 'stopped': %s", d.MachineName, err) log.Error(err) } if err == nil { err = d.configNetwork(VpcId, instanceId) } if err == nil { // Start instance log.Infof("%s | Starting instance %s ...", d.MachineName, instanceId) err = d.getClient().StartInstance(instanceId) if err == nil { // Wait for running err = d.getClient().WaitForInstance(instanceId, ecs.Running, timeout) if err == nil { log.Infof("%s | Start instance %s successfully", d.MachineName, instanceId) instance, err := d.getInstance() if err == nil { d.Zone = instance.ZoneId d.PrivateIPAddress = d.GetPrivateIP(instance) d.IPAddress = d.getIP(instance) ssh.SetDefaultClient(ssh.Native) d.uploadKeyPair() log.Infof("%s | Created instance %s successfully with public IP address %s and private IP address %s", d.MachineName, d.InstanceId, d.IPAddress, d.PrivateIPAddress, ) } } else { err = fmt.Errorf("%s | Failed to wait instance to running state: %s", d.MachineName, err) } } else { err = fmt.Errorf("%s | Failed to start instance %s: %v", d.MachineName, instanceId, err) } } // Add instance tags if len(d.Tags) > 0 { log.Infof("%s | Adding tags %v to instance %s ...", d.MachineName, d.Tags, instanceId) args := ecs.AddTagsArgs{ RegionId: d.Region, ResourceId: instanceId, ResourceType: ecs.TagResourceInstance, Tag: d.Tags, } err2 := d.getClient().AddTags(&args) if err2 != nil { log.Warnf("%s | Failed to add tags %v to instance %s: %v", d.MachineName, d.Tags, instanceId, err) } } if err != nil { log.Warn(err) d.Remove() } return err }