示例#1
0
// Upload stemcell to an IAAS. It does the following steps:
// 1) uploads the stemcell to the cloud (if needed),
// 2) saves a record of the uploaded stemcell in the repo
func (m *manager) Upload(extractedStemcell ExtractedStemcell, uploadStage biui.Stage) (cloudStemcell CloudStemcell, err error) {
	manifest := extractedStemcell.Manifest()
	stageName := fmt.Sprintf("Uploading stemcell '%s/%s'", manifest.Name, manifest.Version)
	err = uploadStage.Perform(stageName, func() error {
		foundStemcellRecord, found, err := m.repo.Find(manifest.Name, manifest.Version)
		if err != nil {
			return bosherr.WrapError(err, "Finding existing stemcell record in repo")
		}

		if found {
			cloudStemcell = NewCloudStemcell(foundStemcellRecord, m.repo, m.cloud)
			return biui.NewSkipStageError(bosherr.Errorf("Found stemcell: %#v", foundStemcellRecord), "Stemcell already uploaded")
		}

		cid, err := m.cloud.CreateStemcell(manifest.ImagePath, manifest.CloudProperties)
		if err != nil {
			return bosherr.WrapErrorf(err, "creating stemcell (%s %s)", manifest.Name, manifest.Version)
		}

		stemcellRecord, err := m.repo.Save(manifest.Name, manifest.Version, cid)
		if err != nil {
			//TODO: delete stemcell from cloud when saving fails
			return bosherr.WrapErrorf(err, "saving stemcell record in repo (cid=%s, stemcell=%s)", cid, extractedStemcell)
		}

		cloudStemcell = NewCloudStemcell(stemcellRecord, m.repo, m.cloud)
		return nil
	})
	if err != nil {
		return cloudStemcell, err
	}

	return cloudStemcell, nil
}
示例#2
0
func (i *instance) UpdateJobs(
	deploymentManifest bideplmanifest.Manifest,
	stage biui.Stage,
) error {
	newState, err := i.stateBuilder.Build(i.jobName, i.id, deploymentManifest, stage)
	if err != nil {
		return bosherr.WrapErrorf(err, "Building state for instance '%s/%d'", i.jobName, i.id)
	}

	stepName := fmt.Sprintf("Updating instance '%s/%d'", i.jobName, i.id)
	err = stage.Perform(stepName, func() error {
		err := i.vm.Stop()
		if err != nil {
			return bosherr.WrapError(err, "Stopping the agent")
		}

		err = i.vm.Apply(newState.ToApplySpec())
		if err != nil {
			return bosherr.WrapError(err, "Applying the agent state")
		}

		err = i.vm.Start()
		if err != nil {
			return bosherr.WrapError(err, "Starting the agent")
		}

		return nil
	})
	if err != nil {
		return err
	}

	return i.waitUntilJobsAreRunning(deploymentManifest.Update.UpdateWatchTime, stage)
}
示例#3
0
func (i *instance) shutdown(
	pingTimeout time.Duration,
	pingDelay time.Duration,
	stage biui.Stage,
) error {
	stepName := fmt.Sprintf("Waiting for the agent on VM '%s'", i.vm.CID())
	waitingForAgentErr := stage.Perform(stepName, func() error {
		if err := i.vm.WaitUntilReady(pingTimeout, pingDelay); err != nil {
			return bosherr.WrapError(err, "Agent unreachable")
		}
		return nil
	})
	if waitingForAgentErr != nil {
		i.logger.Warn(i.logTag, "Gave up waiting for agent: %s", waitingForAgentErr.Error())
		return nil
	}

	if err := i.stopJobs(stage); err != nil {
		return err
	}
	if err := i.unmountDisks(stage); err != nil {
		return err
	}
	return nil
}
示例#4
0
func (i *instance) Delete(
	pingTimeout time.Duration,
	pingDelay time.Duration,
	stage biui.Stage,
) error {
	vmExists, err := i.vm.Exists()
	if err != nil {
		return bosherr.WrapErrorf(err, "Checking existance of vm for instance '%s/%d'", i.jobName, i.id)
	}

	if vmExists {
		if err = i.shutdown(pingTimeout, pingDelay, stage); err != nil {
			return err
		}
	}

	// non-existent VMs still need to be 'deleted' to clean up related resources owned by the CPI
	stepName := fmt.Sprintf("Deleting VM '%s'", i.vm.CID())
	return stage.Perform(stepName, func() error {
		err := i.vm.Delete()
		cloudErr, ok := err.(bicloud.Error)
		if ok && cloudErr.Type() == bicloud.VMNotFoundError {
			return biui.NewSkipStageError(cloudErr, "VM not found")
		}
		return err
	})
}
示例#5
0
func (s Fetcher) GetStemcell(deploymentManifest bideplmanifest.Manifest, stage biui.Stage) (ExtractedStemcell, error) {
	stemcell, err := deploymentManifest.Stemcell(deploymentManifest.JobName())
	if err != nil {
		return nil, err
	}

	stemcellTarballPath, err := s.TarballProvider.Get(stemcell, stage)
	if err != nil {
		return nil, err
	}

	var extractedStemcell ExtractedStemcell
	err = stage.Perform("Validating stemcell", func() error {
		extractedStemcell, err = s.StemcellExtractor.Extract(stemcellTarballPath)
		if err != nil {
			return bosherr.WrapErrorf(err, "Extracting stemcell from '%s'", stemcellTarballPath)
		}

		return nil
	})
	if err != nil {
		return nil, err
	}

	return extractedStemcell, nil
}
示例#6
0
// renderJobTemplates renders all the release job templates for multiple release jobs specified
// by a deployment job and randomly uploads them to blobstore
func (b *jobRenderer) renderJobTemplates(
	releaseJobs []bireljob.Job,
	releaseJobProperties map[string]*biproperty.Map,
	jobProperties biproperty.Map,
	globalProperties biproperty.Map,
	deploymentName string,
	stage biui.Stage,
) ([]RenderedJobRef, error) {
	renderedJobRefs := make([]RenderedJobRef, 0, len(releaseJobs))
	err := stage.Perform("Rendering job templates", func() error {
		renderedJobList, err := b.jobListRenderer.Render(releaseJobs, releaseJobProperties, jobProperties, globalProperties, deploymentName, "")
		if err != nil {
			return err
		}
		defer renderedJobList.DeleteSilently()

		for _, renderedJob := range renderedJobList.All() {
			renderedJobRef, err := b.compressAndUpload(renderedJob)
			if err != nil {
				return err
			}

			renderedJobRefs = append(renderedJobRefs, renderedJobRef)
		}

		return nil
	})

	return renderedJobRefs, err
}
func (y DeploymentManifestParser) GetDeploymentManifest(deploymentManifestPath string, releaseSetManifest birelsetmanifest.Manifest, stage biui.Stage) (bideplmanifest.Manifest, error) {
	var deploymentManifest bideplmanifest.Manifest
	err := stage.Perform("Validating deployment manifest", func() error {
		var err error
		deploymentManifest, err = y.DeploymentParser.Parse(deploymentManifestPath)
		if err != nil {
			return bosherr.WrapErrorf(err, "Parsing deployment manifest '%s'", deploymentManifestPath)
		}

		err = y.DeploymentValidator.Validate(deploymentManifest, releaseSetManifest)
		if err != nil {
			return bosherr.WrapError(err, "Validating deployment manifest")
		}

		err = y.DeploymentValidator.ValidateReleaseJobs(deploymentManifest, y.ReleaseManager)
		if err != nil {
			return bosherr.WrapError(err, "Validating deployment jobs refer to jobs in release")
		}

		return nil
	})
	if err != nil {
		return bideplmanifest.Manifest{}, err
	}

	return deploymentManifest, nil
}
示例#8
0
// compilePackages compiles the specified packages, in the order specified, uploads them to the Blobstore, and returns the blob references
func (c *dependencyCompiler) compilePackages(requiredPackages []*birelpkg.Package, stage biui.Stage) ([]CompiledPackageRef, error) {
	packageRefs := make([]CompiledPackageRef, 0, len(requiredPackages))

	for _, pkg := range requiredPackages {
		stepName := fmt.Sprintf("Compiling package '%s/%s'", pkg.Name, pkg.Fingerprint)
		err := stage.Perform(stepName, func() error {
			compiledPackageRecord, err := c.packageCompiler.Compile(pkg)
			if err != nil {
				return err
			}

			packageRef := CompiledPackageRef{
				Name:        pkg.Name,
				Version:     pkg.Fingerprint,
				BlobstoreID: compiledPackageRecord.BlobID,
				SHA1:        compiledPackageRecord.BlobSHA1,
			}
			packageRefs = append(packageRefs, packageRef)

			return nil
		})
		if err != nil {
			return nil, err
		}
	}

	return packageRefs, nil
}
示例#9
0
func (i *installation) stopRegistryNice(logger boshlog.Logger, stage biui.Stage) {
	err := stage.Perform("Stopping registry", func() error {
		return i.StopRegistry()
	})
	if err != nil {
		logger.Warn("installation", "Registry failed to stop: %s", err)
	}
}
示例#10
0
func (d *diskDeployer) attachDisk(disk bidisk.Disk, vm VM, stage biui.Stage) error {
	stageName := fmt.Sprintf("Attaching disk '%s' to VM '%s'", disk.CID(), vm.CID())
	err := stage.Perform(stageName, func() error {
		return vm.AttachDisk(disk)
	})

	return err
}
示例#11
0
func (d *diskDeployer) createDisk(diskPool bideplmanifest.DiskPool, vm VM, stage biui.Stage) (disk bidisk.Disk, err error) {
	err = stage.Perform("Creating disk", func() error {
		disk, err = d.diskManager.Create(diskPool, vm.CID())
		return err
	})

	return disk, err
}
示例#12
0
func (i *installation) WithRunningRegistry(logger boshlog.Logger, stage biui.Stage, fn func() error) error {
	err := stage.Perform("Starting registry", func() error {
		return i.StartRegistry()
	})
	if err != nil {
		return err
	}
	defer i.stopRegistryNice(logger, stage)
	return fn()
}
示例#13
0
func (d *diskDeployer) migrateDisk(
	originalDisk bidisk.Disk,
	diskPool bideplmanifest.DiskPool,
	vm VM,
	stage biui.Stage,
) (newDisk bidisk.Disk, err error) {
	d.logger.Debug(d.logTag, "Migrating disk '%s'", originalDisk.CID())

	err = stage.Perform("Creating disk", func() error {
		newDisk, err = d.diskManager.Create(diskPool, vm.CID())
		return err
	})
	if err != nil {
		return newDisk, err
	}

	stageName := fmt.Sprintf("Attaching disk '%s' to VM '%s'", newDisk.CID(), vm.CID())
	err = stage.Perform(stageName, func() error {
		return vm.AttachDisk(newDisk)
	})
	if err != nil {
		return newDisk, err
	}

	stageName = fmt.Sprintf("Migrating disk content from '%s' to '%s'", originalDisk.CID(), newDisk.CID())
	err = stage.Perform(stageName, func() error {
		return vm.MigrateDisk()
	})
	if err != nil {
		return newDisk, err
	}

	err = d.updateCurrentDiskRecord(newDisk)
	if err != nil {
		return newDisk, err
	}

	stageName = fmt.Sprintf("Detaching disk '%s'", originalDisk.CID())
	err = stage.Perform(stageName, func() error {
		return vm.DetachDisk(originalDisk)
	})
	if err != nil {
		return newDisk, err
	}

	stageName = fmt.Sprintf("Deleting disk '%s'", originalDisk.CID())
	err = stage.Perform(stageName, func() error {
		return originalDisk.Delete()
	})
	if err != nil {
		return newDisk, err
	}

	return newDisk, nil
}
示例#14
0
func (d *deployment) deleteDisk(deleteStage biui.Stage, disk bidisk.Disk) error {
	stepName := fmt.Sprintf("Deleting disk '%s'", disk.CID())
	return deleteStage.Perform(stepName, func() error {
		err := disk.Delete()
		cloudErr, ok := err.(bicloud.Error)
		if ok && cloudErr.Type() == bicloud.DiskNotFoundError {
			return biui.NewSkipStageError(cloudErr, "Disk not found")
		}
		return err
	})
}
示例#15
0
func (d *deployment) deleteStemcell(deleteStage biui.Stage, stemcell bistemcell.CloudStemcell) error {
	stepName := fmt.Sprintf("Deleting stemcell '%s'", stemcell.CID())
	return deleteStage.Perform(stepName, func() error {
		err := stemcell.Delete()
		cloudErr, ok := err.(bicloud.Error)
		if ok && cloudErr.Type() == bicloud.StemcellNotFoundError {
			return biui.NewSkipStageError(cloudErr, "Stemcell not found")
		}
		return err
	})
}
示例#16
0
func (i *instance) waitUntilJobsAreRunning(updateWatchTime bideplmanifest.WatchTime, stage biui.Stage) error {
	start := time.Duration(updateWatchTime.Start) * time.Millisecond
	end := time.Duration(updateWatchTime.End) * time.Millisecond
	delayBetweenAttempts := 1 * time.Second
	maxAttempts := int((end - start) / delayBetweenAttempts)

	stepName := fmt.Sprintf("Waiting for instance '%s/%d' to be running", i.jobName, i.id)
	return stage.Perform(stepName, func() error {
		time.Sleep(start)
		return i.vm.WaitToBeRunning(maxAttempts, delayBetweenAttempts)
	})
}
示例#17
0
func (i CpiInstaller) installCpiRelease(installer biinstall.Installer, installationManifest biinstallmanifest.Manifest, target biinstall.Target, stage biui.Stage) (biinstall.Installation, error) {
	var installation biinstall.Installation
	var err error
	err = stage.PerformComplex("installing CPI", func(installStage biui.Stage) error {
		installation, err = installer.Install(installationManifest, installStage)
		return err
	})
	if err != nil {
		return installation, bosherr.WrapError(err, "Installing CPI")
	}

	return installation, nil
}
示例#18
0
func (i CpiInstaller) ValidateCpiRelease(installationManifest biinstallmanifest.Manifest, stage biui.Stage) error {
	return stage.Perform("Validating cpi release", func() error {
		cpiReleaseName := installationManifest.Template.Release
		cpiRelease, found := i.ReleaseManager.Find(cpiReleaseName)
		if !found {
			return bosherr.Errorf("installation release '%s' must refer to a provided release", cpiReleaseName)
		}

		err := i.Validator.Validate(cpiRelease, installationManifest.Template.Name)
		if err != nil {
			return bosherr.WrapErrorf(err, "Invalid CPI release '%s'", cpiReleaseName)
		}
		return nil
	})
}
示例#19
0
func (c *deploymentDeleter) findCurrentDeploymentAndDelete(stage biui.Stage, deploymentManager bidepl.Manager) error {
	c.logger.Debug(c.logTag, "Finding current deployment...")
	deployment, found, err := deploymentManager.FindCurrent()
	if err != nil {
		return bosherr.WrapError(err, "Finding current deployment")
	}

	return stage.PerformComplex("deleting deployment", func(deleteStage biui.Stage) error {
		if !found {
			//TODO: skip? would require adding skip support to PerformComplex
			c.logger.Debug(c.logTag, "No current deployment found...")
			return nil
		}

		return deployment.Delete(deleteStage)
	})
}
示例#20
0
func (p *provider) Get(source Source, stage biui.Stage) (string, error) {
	if strings.HasPrefix(source.GetURL(), "file://") {
		filePath := strings.TrimPrefix(source.GetURL(), "file://")

		expandedPath, err := p.fs.ExpandPath(filePath)
		if err != nil {
			p.logger.Warn(p.logTag, "Failed to expand file path %s, using original URL", filePath)
			return filePath, nil
		}

		p.logger.Debug(p.logTag, "Using the tarball from file source: '%s'", filePath)
		return expandedPath, nil
	}

	if !strings.HasPrefix(source.GetURL(), "http") {
		return "", bosherr.Errorf("Invalid source URL: '%s', must be either file:// or http(s)://", source.GetURL())
	}

	var cachedPath string
	err := stage.Perform(fmt.Sprintf("Downloading %s", source.Description()), func() error {
		var found bool
		cachedPath, found = p.cache.Get(source)
		if found {
			p.logger.Debug(p.logTag, "Using the tarball from cache: '%s'", cachedPath)
			return biui.NewSkipStageError(bosherr.Error("Already downloaded"), "Found in local cache")
		}

		retryStrategy := boshretry.NewAttemptRetryStrategy(p.downloadAttempts, p.delayTimeout, p.downloadRetryable(source), p.logger)
		err := retryStrategy.Try()
		if err != nil {
			return bosherr.WrapErrorf(err, "Failed to download from '%s'", source.GetURL())
		}

		p.logger.Debug(p.logTag, "Using the downloaded tarball: '%s'", cachedPath)
		return nil
	})

	if err != nil {
		return "", err
	}

	return p.cache.Path(source), nil
}
示例#21
0
// renderJobTemplates renders all the release job templates for multiple release jobs specified by a deployment job
func (b *builder) renderJobTemplates(
	releaseJobs []bireljob.Job,
	releaseJobProperties map[string]*biproperty.Map,
	jobProperties biproperty.Map,
	globalProperties biproperty.Map,
	deploymentName string,
	address string,
	stage biui.Stage,
) (renderedJobs, error) {
	var (
		renderedJobListArchive bitemplate.RenderedJobListArchive
		blobID                 string
	)
	err := stage.Perform("Rendering job templates", func() error {
		renderedJobList, err := b.jobListRenderer.Render(releaseJobs, releaseJobProperties, jobProperties, globalProperties, deploymentName, address)
		if err != nil {
			return err
		}
		defer renderedJobList.DeleteSilently()

		renderedJobListArchive, err = b.renderedJobListCompressor.Compress(renderedJobList)
		if err != nil {
			return bosherr.WrapError(err, "Compressing rendered job templates")
		}
		defer renderedJobListArchive.DeleteSilently()

		blobID, err = b.blobstore.Add(renderedJobListArchive.Path())
		if err != nil {
			return bosherr.WrapErrorf(err, "Uploading rendered job template archive '%s' to the blobstore", renderedJobListArchive.Path())
		}

		return nil
	})
	if err != nil {
		return renderedJobs{}, err
	}

	return renderedJobs{
		BlobstoreID: blobID,
		Archive:     renderedJobListArchive,
	}, nil
}
示例#22
0
func (i *installer) installJob(renderedJobRef RenderedJobRef, stage biui.Stage) (installedJob InstalledJob, err error) {
	err = stage.Perform(fmt.Sprintf("Installing job '%s'", renderedJobRef.Name), func() error {
		var stageErr error
		jobDir := filepath.Join(i.target.JobsPath(), renderedJobRef.Name)

		stageErr = i.blobExtractor.Extract(renderedJobRef.BlobstoreID, renderedJobRef.SHA1, jobDir)
		if stageErr != nil {
			return bosherr.WrapErrorf(stageErr, "Extracting blob with ID '%s'", renderedJobRef.BlobstoreID)
		}

		stageErr = i.blobExtractor.ChmodExecutables(path.Join(jobDir, "bin", "*"))
		if stageErr != nil {
			return bosherr.WrapErrorf(stageErr, "Chmoding binaries for '%s'", jobDir)
		}

		installedJob = NewInstalledJob(renderedJobRef, jobDir)
		return nil
	})
	return installedJob, err
}
示例#23
0
func (i *instance) unmountDisks(stage biui.Stage) error {
	disks, err := i.vm.Disks()
	if err != nil {
		return bosherr.WrapErrorf(err, "Getting VM '%s' disks", i.vm.CID())
	}

	for _, disk := range disks {
		stepName := fmt.Sprintf("Unmounting disk '%s'", disk.CID())
		err = stage.Perform(stepName, func() error {
			if err := i.vm.UnmountDisk(disk); err != nil {
				return bosherr.WrapErrorf(err, "Unmounting disk '%s' from VM '%s'", disk.CID(), i.vm.CID())
			}
			return nil
		})
		if err != nil {
			return err
		}
	}
	return nil
}
示例#24
0
func (f Fetcher) DownloadAndExtract(releaseRef manifest.ReleaseRef, stage ui.Stage) error {
	releasePath, err := f.tarballProvider.Get(releaseRef, stage)
	if err != nil {
		return err
	}

	err = stage.Perform(fmt.Sprintf("Validating release '%s'", releaseRef.Name), func() error {
		release, err := f.releaseExtractor.Extract(releasePath)
		if err != nil {
			return bosherr.WrapErrorf(err, "Extracting release '%s'", releasePath)
		}

		if release.Name() != releaseRef.Name {
			return bosherr.Errorf("Release name '%s' does not match the name in release tarball '%s'", releaseRef.Name, release.Name())
		}
		f.releaseManager.Add(release)

		return nil
	})
	return err
}
示例#25
0
func (m *manager) Create(
	jobName string,
	id int,
	deploymentManifest bideplmanifest.Manifest,
	cloudStemcell bistemcell.CloudStemcell,
	registryConfig biinstallmanifest.Registry,
	eventLoggerStage biui.Stage,
) (Instance, []bidisk.Disk, error) {
	var vm bivm.VM
	stepName := fmt.Sprintf("Creating VM for instance '%s/%d' from stemcell '%s'", jobName, id, cloudStemcell.CID())
	err := eventLoggerStage.Perform(stepName, func() error {
		var err error
		vm, err = m.vmManager.Create(cloudStemcell, deploymentManifest)
		if err != nil {
			return bosherr.WrapError(err, "Creating VM")
		}

		if err = cloudStemcell.PromoteAsCurrent(); err != nil {
			return bosherr.WrapErrorf(err, "Promoting stemcell as current '%s'", cloudStemcell.CID())
		}

		return nil
	})
	if err != nil {
		return nil, []bidisk.Disk{}, err
	}

	instance := m.instanceFactory.NewInstance(jobName, id, vm, m.vmManager, m.sshTunnelFactory, m.blobstore, m.logger)

	if err := instance.WaitUntilReady(registryConfig, eventLoggerStage); err != nil {
		return instance, []bidisk.Disk{}, bosherr.WrapError(err, "Waiting until instance is ready")
	}

	disks, err := instance.UpdateDisks(deploymentManifest, eventLoggerStage)
	if err != nil {
		return instance, disks, bosherr.WrapError(err, "Updating instance disks")
	}

	return instance, disks, err
}
示例#26
0
func (i *installer) Install(manifest biinstallmanifest.Manifest, stage biui.Stage) (Installation, error) {
	i.logger.Info(i.logTag, "Installing CPI deployment '%s'", manifest.Name)
	i.logger.Debug(i.logTag, "Installing CPI deployment '%s' with manifest: %#v", manifest.Name, manifest)

	jobs, err := i.jobResolver.From(manifest)
	if err != nil {
		return nil, bosherr.WrapError(err, "Resolving jobs from manifest")
	}

	compiledPackages, err := i.packageCompiler.For(jobs, stage)
	if err != nil {
		return nil, err
	}

	err = stage.Perform("Installing packages", func() error {
		return i.installPackages(compiledPackages)
	})
	if err != nil {
		return nil, err
	}

	renderedJobRefs, err := i.jobRenderer.RenderAndUploadFrom(manifest, jobs, stage)
	if err != nil {
		return nil, bosherr.WrapError(err, "Rendering and uploading Jobs")
	}

	renderedCPIJob := renderedJobRefs[0]
	installedJob, err := i.installJob(renderedCPIJob, stage)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Installing job '%s' for CPI release", renderedCPIJob.Name)
	}

	return NewInstallation(
		i.target,
		installedJob,
		manifest,
		i.registryServerManager,
	), nil
}
示例#27
0
func (m *manager) DeleteUnused(eventLoggerStage biui.Stage) error {
	disks, err := m.FindUnused()
	if err != nil {
		return bosherr.WrapError(err, "Finding unused disks")
	}

	for _, disk := range disks {
		stepName := fmt.Sprintf("Deleting unused disk '%s'", disk.CID())
		err = eventLoggerStage.Perform(stepName, func() error {
			err := disk.Delete()
			cloudErr, ok := err.(bicloud.Error)
			if ok && cloudErr.Type() == bicloud.DiskNotFoundError {
				return biui.NewSkipStageError(cloudErr, "Disk Not Found")
			}
			return err
		})
		if err != nil {
			return err
		}
	}

	return nil
}
示例#28
0
func (m *manager) DeleteUnused(deleteStage biui.Stage) error {
	stemcells, err := m.FindUnused()
	if err != nil {
		return bosherr.WrapError(err, "Finding unused stemcells")
	}

	for _, stemcell := range stemcells {
		stepName := fmt.Sprintf("Deleting unused stemcell '%s'", stemcell.CID())
		err = deleteStage.Perform(stepName, func() error {
			err := stemcell.Delete()
			cloudErr, ok := err.(bicloud.Error)
			if ok && cloudErr.Type() == bicloud.StemcellNotFoundError {
				return biui.NewSkipStageError(cloudErr, "Stemcell not found")
			}
			return err
		})
		if err != nil {
			return err
		}
	}

	return nil
}
示例#29
0
func (i *instance) WaitUntilReady(
	registryConfig biinstallmanifest.Registry,
	stage biui.Stage,
) error {
	stepName := fmt.Sprintf("Waiting for the agent on VM '%s' to be ready", i.vm.CID())
	err := stage.Perform(stepName, func() error {
		if !registryConfig.IsEmpty() {
			sshTunnelOptions := bisshtunnel.Options{
				Host:              registryConfig.SSHTunnel.Host,
				Port:              registryConfig.SSHTunnel.Port,
				User:              registryConfig.SSHTunnel.User,
				Password:          registryConfig.SSHTunnel.Password,
				PrivateKey:        registryConfig.SSHTunnel.PrivateKey,
				LocalForwardPort:  registryConfig.Port,
				RemoteForwardPort: registryConfig.Port,
			}
			sshTunnel := i.sshTunnelFactory.NewSSHTunnel(sshTunnelOptions)
			sshReadyErrCh := make(chan error)
			sshErrCh := make(chan error)
			go sshTunnel.Start(sshReadyErrCh, sshErrCh)
			defer func() {
				if err := sshTunnel.Stop(); err != nil {
					i.logger.Warn(i.logTag, "Failed to stop ssh tunnel: %s", err.Error())
				}
			}()

			err := <-sshReadyErrCh
			if err != nil {
				return bosherr.WrapError(err, "Starting SSH tunnel")
			}
		}

		return i.vm.WaitUntilReady(10*time.Minute, 500*time.Millisecond)
	})

	return err
}
示例#30
0
func (i *instance) stopJobs(stage biui.Stage) error {
	stepName := fmt.Sprintf("Stopping jobs on instance '%s/%d'", i.jobName, i.id)
	return stage.Perform(stepName, func() error {
		return i.vm.Stop()
	})
}