// Create an entire cluster func (vp *scalewayProvider) CreateCluster(log *logging.Logger, options providers.CreateClusterOptions, dnsProvider providers.DnsProvider) error { wg := sync.WaitGroup{} errors := make(chan error, options.InstanceCount) instanceDatas := make(chan instanceData, options.InstanceCount) for i := 1; i <= options.InstanceCount; i++ { wg.Add(1) go func(i int) { defer wg.Done() time.Sleep(time.Duration((i - 1)) * time.Second * 10) isCore := (i <= 3) isLB := (i <= 2) instanceOptions, err := options.NewCreateInstanceOptions(isCore, isLB, i) if err != nil { errors <- maskAny(err) return } instance, err := vp.createInstance(log, instanceOptions, dnsProvider, nil) if err != nil { errors <- maskAny(err) } else { instanceDatas <- instanceData{ CreateInstanceOptions: instanceOptions, ClusterInstance: instance, FleetMetadata: instanceOptions.CreateFleetMetadata(i), } } }(i) } wg.Wait() close(errors) close(instanceDatas) err := <-errors if err != nil { return maskAny(err) } instances := []instanceData{} instanceList := providers.ClusterInstanceList{} for data := range instanceDatas { instances = append(instances, data) instanceList = append(instanceList, data.ClusterInstance) } clusterMembers, err := instanceList.AsClusterMemberList(log, nil) if err != nil { return maskAny(err) } // Create tinc network config if instanceList.ReconfigureTincCluster(vp.Logger, instanceList); err != nil { return maskAny(err) } if err := vp.setupInstances(log, instances, clusterMembers); err != nil { return maskAny(err) } return nil }
func (dp *doProvider) CreateCluster(log *logging.Logger, options providers.CreateClusterOptions, dnsProvider providers.DnsProvider) error { wg := sync.WaitGroup{} errors := make(chan error, options.InstanceCount) instanceDatas := make(chan instanceData, options.InstanceCount) for i := 1; i <= options.InstanceCount; i++ { wg.Add(1) go func(i int) { defer wg.Done() isCore := true isLB := true instanceOptions, err := options.NewCreateInstanceOptions(isCore, isLB, i) if err != nil { errors <- maskAny(err) return } instance, err := dp.CreateInstance(log, instanceOptions, dnsProvider) if err != nil { errors <- maskAny(err) } else { instanceDatas <- instanceData{ CreateInstanceOptions: instanceOptions, ClusterInstance: instance, FleetMetadata: instanceOptions.CreateFleetMetadata(i), } } }(i) } wg.Wait() close(errors) close(instanceDatas) err := <-errors if err != nil { return maskAny(err) } instances := []instanceData{} instanceList := providers.ClusterInstanceList{} for data := range instanceDatas { instances = append(instances, data) instanceList = append(instanceList, data.ClusterInstance) } clusterMembers, err := instanceList.AsClusterMemberList(log, nil) if err != nil { return maskAny(err) } if err := dp.setupInstances(log, instances, clusterMembers); err != nil { return maskAny(err) } return nil }
// Create an entire cluster func (vp *vagrantProvider) CreateCluster(log *logging.Logger, options providers.CreateClusterOptions, dnsProvider providers.DnsProvider) error { // Ensure folder exists if err := os.MkdirAll(vp.folder, fileMode|os.ModeDir); err != nil { return maskAny(err) } if _, err := os.Stat(filepath.Join(vp.folder, ".vagrant")); err == nil { return maskAny(fmt.Errorf("Vagrant in %s already exists", vp.folder)) } parts := strings.Split(options.ImageID, "-") if len(parts) != 2 || parts[0] != "coreos" { return maskAny(fmt.Errorf("Invalid image ID, expected 'coreos-alpha|beta|stable', got '%s'", options.ImageID)) } updateChannel := parts[1] vopts := struct { InstanceCount int UpdateChannel string }{ InstanceCount: options.InstanceCount, UpdateChannel: updateChannel, } vp.instanceCount = options.InstanceCount // Vagrantfile content, err := templates.Render(vagrantFileTemplate, vopts) if err != nil { return maskAny(err) } if err := ioutil.WriteFile(filepath.Join(vp.folder, vagrantFileName), []byte(content), fileMode); err != nil { return maskAny(err) } // config.rb content, err = templates.Render(configTemplate, vopts) if err != nil { return maskAny(err) } if err := ioutil.WriteFile(filepath.Join(vp.folder, configFileName), []byte(content), fileMode); err != nil { return maskAny(err) } // Fetch SSH keys sshKeys, err := providers.FetchSSHKeys(options.SSHKeyGithubAccount) if err != nil { return maskAny(err) } // Fetch vagrant insecure private key insecureKey, err := fetchVagrantInsecureSSHKey() if err != nil { return maskAny(err) } sshKeys = append(sshKeys, insecureKey) // user-data isCore := true isLB := true instanceOptions, err := options.NewCreateInstanceOptions(isCore, isLB, 0) if err != nil { return maskAny(err) } opts := instanceOptions.NewCloudConfigOptions() opts.PrivateIPv4 = "$private_ipv4" opts.SshKeys = sshKeys content, err = templates.Render(cloudConfigTemplate, opts) if err != nil { return maskAny(err) } if err := ioutil.WriteFile(filepath.Join(vp.folder, userDataFileName), []byte(content), fileMode); err != nil { return maskAny(err) } // Start cmd := exec.Command("vagrant", "up") cmd.Dir = vp.folder cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin if err := cmd.Run(); err != nil { return maskAny(err) } // Run initial setup instances, err := vp.GetInstances(providers.ClusterInfo{}) if err != nil { return maskAny(err) } clusterMembers, err := instances.AsClusterMemberList(log, nil) if err != nil { return maskAny(err) } for index, instance := range instances { iso := providers.InitialSetupOptions{ ClusterMembers: clusterMembers, FleetMetadata: instanceOptions.CreateFleetMetadata(index), } if err := instance.InitialSetup(log, instanceOptions, iso, vp); err != nil { return maskAny(err) } } return nil }