Exemple #1
0
func (a DrainAction) determineParams(drainType DrainType, currentSpec boshas.V1ApplySpec, newSpecs []boshas.V1ApplySpec) (boshdrain.ScriptParams, error) {
	var newSpec *boshas.V1ApplySpec
	var params boshdrain.ScriptParams

	if len(newSpecs) > 0 {
		newSpec = &newSpecs[0]
	}

	switch drainType {
	case DrainTypeStatus:
		// Status was used in the past when dynamic drain was implemented in the Director.
		// Now that we implement it in the agent, we should never get a call for this type.
		return params, bosherr.Error("Unexpected call with drain type 'status'")

	case DrainTypeUpdate:
		if newSpec == nil {
			return params, bosherr.Error("Drain update requires new spec")
		}

		params = boshdrain.NewUpdateParams(currentSpec, *newSpec)

	case DrainTypeShutdown:
		err := a.notifier.NotifyShutdown()
		if err != nil {
			return params, bosherr.WrapError(err, "Notifying shutdown")
		}

		params = boshdrain.NewShutdownParams(currentSpec, newSpec)
	}

	return params, nil
}
Exemple #2
0
func (r concreteRunner) Run(action Action, payloadBytes []byte) (value interface{}, err error) {
	payloadArgs, err := r.extractJSONArguments(payloadBytes)
	if err != nil {
		err = bosherr.WrapError(err, "Extracting json arguments")
		return
	}

	actionValue := reflect.ValueOf(action)
	runMethodValue := actionValue.MethodByName("Run")
	if runMethodValue.Kind() != reflect.Func {
		err = bosherr.Error("Run method not found")
		return
	}

	runMethodType := runMethodValue.Type()
	if r.invalidReturnTypes(runMethodType) {
		err = bosherr.Error("Run method should return a value and an error")
		return
	}

	methodArgs, err := r.extractMethodArgs(runMethodType, payloadArgs)
	if err != nil {
		err = bosherr.WrapError(err, "Extracting method arguments from payload")
		return
	}

	values := runMethodValue.Call(methodArgs)
	return r.extractReturns(values)
}
Exemple #3
0
func (p linux) findRootDevicePathAndNumber() (string, int, error) {
	mounts, err := p.diskManager.GetMountsSearcher().SearchMounts()
	if err != nil {
		return "", 0, bosherr.WrapError(err, "Searching mounts")
	}

	for _, mount := range mounts {
		if mount.MountPoint == "/" && strings.HasPrefix(mount.PartitionPath, "/dev/") {
			p.logger.Debug(logTag, "Found root partition: `%s'", mount.PartitionPath)

			stdout, _, _, err := p.cmdRunner.RunCommand("readlink", "-f", mount.PartitionPath)
			if err != nil {
				return "", 0, bosherr.WrapError(err, "Shelling out to readlink")
			}
			rootPartition := strings.Trim(stdout, "\n")
			p.logger.Debug(logTag, "Symlink is: `%s'", rootPartition)

			validRootPartition := regexp.MustCompile(`^/dev/[a-z]+\d$`)
			if !validRootPartition.MatchString(rootPartition) {
				return "", 0, bosherr.Error("Root partition has an invalid name" + rootPartition)
			}

			devNum, err := strconv.Atoi(rootPartition[len(rootPartition)-1:])
			if err != nil {
				return "", 0, bosherr.WrapError(err, "Parsing device number failed")
			}

			devPath := rootPartition[:len(rootPartition)-1]

			return devPath, devNum, nil
		}
	}
	return "", 0, bosherr.Error("Getting root partition device")
}
func (v SyntaxValidator) validateJob(job *Job) error {
	if job.Name == "" {
		return bosherr.Error("Missing job name")
	}

	if job.Template != nil {
		return bosherr.Error("'template' is deprecated in favor of 'templates'")
	}

	err := v.validateUpdate(&job.Update)
	if err != nil {
		return bosherr.WrapError(err, "Update")
	}

	props, err := bputil.NewStringKeyed().ConvertMap(job.PropertiesRaw)
	if err != nil {
		return bosherr.WrapError(err, "Properties")
	}

	job.Properties = props

	for i, na := range job.NetworkAssociations {
		err := v.validateNetworkAssociation(&job.NetworkAssociations[i])
		if err != nil {
			return bosherr.WrapErrorf(err, "Network association %s (%d)", na.NetworkName, i)
		}
	}

	return nil
}
func (p linux) findRootDevicePath() (string, error) {
	mounts, err := p.diskManager.GetMountsSearcher().SearchMounts()

	if err != nil {
		return "", bosherr.WrapError(err, "Searching mounts")
	}

	for _, mount := range mounts {
		if mount.MountPoint == "/" && strings.HasPrefix(mount.PartitionPath, "/dev/") {
			p.logger.Debug(logTag, "Found root partition: `%s'", mount.PartitionPath)

			stdout, _, _, err := p.cmdRunner.RunCommand("readlink", "-f", mount.PartitionPath)
			if err != nil {
				return "", bosherr.WrapError(err, "Shelling out to readlink")
			}
			rootPartition := strings.Trim(stdout, "\n")
			p.logger.Debug(logTag, "Symlink is: `%s'", rootPartition)

			validRootPartition := regexp.MustCompile(`^/dev/[a-z]+1$`)
			if !validRootPartition.MatchString(rootPartition) {
				return "", bosherr.Error("Root partition is not the first partition")
			}

			return strings.Trim(rootPartition, "1"), nil
		}
	}

	return "", bosherr.Error("Getting root partition device")
}
func (r defaultNetworkResolver) GetDefaultNetwork() (boshsettings.Network, error) {
	network := boshsettings.Network{}

	routes, err := r.routesSearcher.SearchRoutes()
	if err != nil {
		return network, bosherr.WrapError(err, "Searching routes")
	}

	if len(routes) == 0 {
		return network, bosherr.Error("No routes found")
	}

	for _, route := range routes {
		if !route.IsDefault() {
			continue
		}

		ip, err := r.ipResolver.GetPrimaryIPv4(route.InterfaceName)
		if err != nil {
			return network, bosherr.WrapErrorf(err, "Getting primary IPv4 for interface '%s'", route.InterfaceName)
		}

		return boshsettings.Network{
			IP:      ip.IP.String(),
			Netmask: gonet.IP(ip.Mask).String(),
			Gateway: route.Gateway,
		}, nil

	}

	return network, bosherr.Error("Failed to find default route")
}
func (v SyntaxValidator) Validate() error {
	if v.release.Name == "" {
		return bosherr.Error("Missing release name")
	}

	if v.release.Version == "" {
		return bosherr.Error("Missing release version")
	}

	if v.release.CommitHash == "" {
		return bosherr.Error("Missing release commit_hash")
	}

	for i, job := range v.release.Jobs {
		err := v.validateJob(&v.release.Jobs[i])
		if err != nil {
			return bosherr.WrapErrorf(err, "Job %s (%d)", job.Name, i)
		}
	}

	for i, pkg := range v.release.Packages {
		err := v.validatePkg(&v.release.Packages[i])
		if err != nil {
			return bosherr.WrapErrorf(err, "Package %s (%d)", pkg.Name, i)
		}
	}

	return nil
}
func (c Config) validate() error {
	if c.AssetsDir == "" {
		return bosherr.Error("Must provide non-empty assets_dir")
	}

	if c.ReposDir == "" {
		return bosherr.Error("Must provide non-empty repos_dir")
	}

	err := c.EventLog.Validate()
	if err != nil {
		return bosherr.WrapError(err, "Validating event_log configuration")
	}

	if c.Blobstore.Type != bpprov.BlobstoreConfigTypeLocal {
		return bosherr.Error("Blobstore type must be local")
	}

	err = c.Blobstore.Validate()
	if err != nil {
		return bosherr.WrapError(err, "Validating blobstore configuration")
	}

	return nil
}
func (f SettingsSourceFactory) buildWithoutRegistry() (boshsettings.Source, error) {
	var settingsSources []boshsettings.Source

	for _, opts := range f.options.Sources {
		var settingsSource boshsettings.Source

		switch typedOpts := opts.(type) {
		case HTTPSourceOptions:
			return nil, bosherr.Error("HTTP source is not supported without registry")

		case ConfigDriveSourceOptions:
			settingsSource = NewConfigDriveSettingsSource(
				typedOpts.DiskPaths,
				typedOpts.MetaDataPath,
				typedOpts.SettingsPath,
				f.platform,
				f.logger,
			)

		case FileSourceOptions:
			return nil, bosherr.Error("File source is not supported without registry")

		case CDROMSourceOptions:
			settingsSource = NewCDROMSettingsSource(
				typedOpts.FileName,
				f.platform,
				f.logger,
			)
		}

		settingsSources = append(settingsSources, settingsSource)
	}

	return NewMultiSettingsSource(settingsSources...)
}
func (c BaremetalCreator) validate_arguments(memory int, processor int, disksize int, host string, domain string, ostype string, datacenter string) error {

	if memory <= 0 {
		return bosherr.Errorf("memory can not be negative: %d", memory)
	}

	if processor <= 0 {
		return bosherr.Errorf("processor can not be negative: %d", processor)
	}

	if disksize <= 0 {
		return bosherr.Errorf("disk size can not be negative: %d", disksize)
	}

	if host == "" {
		return bosherr.Error("host can not be empty.")
	}

	if domain == "" {
		return bosherr.Error("domain can not be empty.")
	}

	if ostype == "" {
		return bosherr.Error("os type can not be empty.")
	}

	if datacenter == "" {
		return bosherr.Error("data center can not be empty.")
	}

	return nil
}
// Precompile prepares release jobs to be later combined with instance properties
func (tc ConcreteTemplatesCompiler) Precompile(release bprel.Release) error {
	var allPkgs []bprel.Package

	for _, pkg := range release.Packages {
		if pkg == nil {
			// todo panic or should not be here?
			return bosherr.Error("Expected release to not have nil package")
		}

		allPkgs = append(allPkgs, *pkg)
	}
	for _, pkg := range release.CompiledPackages {
		if pkg == nil {
			// todo panic or should not be here?
			return bosherr.Error("Expected release to not have nil package")
		}

		allPkgs = append(allPkgs, *pkg)
	}

	for _, job := range release.Jobs {
		jobRec, found, err := tc.jobsRepo.Find(job)
		if err != nil {
			return bosherr.WrapErrorf(err, "Finding job source blob %s", job.Name)
		}

		if !found {
			blobID, fingerprint, err := tc.blobstore.Create(job.TarPath)
			if err != nil {
				return bosherr.WrapErrorf(err, "Creating job source blob %s", job.Name)
			}

			jobRec = bpjobsrepo.JobRecord{
				BlobID: blobID,
				SHA1:   fingerprint,
			}

			err = tc.jobsRepo.Save(job, jobRec)
			if err != nil {
				return bosherr.WrapErrorf(err, "Saving job record %s", job.Name)
			}
		}

		releaseJobRec, err := tc.tplToJobRepo.SaveForJob(release, job)
		if err != nil {
			return bosherr.WrapErrorf(err, "Saving release job %s", job.Name)
		}

		// todo associate to release instead
		err = tc.runPkgsRepo.SaveAll(releaseJobRec, allPkgs)
		if err != nil {
			return bosherr.WrapErrorf(err, "Saving release job %s", job.Name)
		}
	}

	return nil
}
func (f SettingsSourceFactory) buildWithRegistry() (boshsettings.Source, error) {
	var metadataServices []MetadataService

	digDNSResolver := NewDigDNSResolver(f.platform.GetRunner(), f.logger)
	resolver := NewRegistryEndpointResolver(digDNSResolver)

	for _, opts := range f.options.Sources {
		var metadataService MetadataService

		switch typedOpts := opts.(type) {
		case HTTPSourceOptions:
			metadataService = NewHTTPMetadataService(
				typedOpts.URI,
				typedOpts.Headers,
				typedOpts.UserDataPath,
				typedOpts.InstanceIDPath,
				typedOpts.SSHKeysPath,
				resolver,
				f.platform,
				f.logger,
			)

		case ConfigDriveSourceOptions:
			metadataService = NewConfigDriveMetadataService(
				resolver,
				f.platform,
				typedOpts.DiskPaths,
				typedOpts.MetaDataPath,
				typedOpts.UserDataPath,
				f.logger,
			)

		case FileSourceOptions:
			metadataService = NewFileMetadataService(
				typedOpts.MetaDataPath,
				typedOpts.UserDataPath,
				typedOpts.SettingsPath,
				f.platform.GetFs(),
				f.logger,
			)

		case CDROMSourceOptions:
			return nil, bosherr.Error("CDROM source is not supported when registry is used")

		case InstanceMetadataSourceOptions:
			return nil, bosherr.Error("Instance Metadata source is not supported when registry is used")
		}
		metadataServices = append(metadataServices, metadataService)
	}

	metadataService := NewMultiSourceMetadataService(metadataServices...)
	registryProvider := NewRegistryProvider(metadataService, f.platform, f.options.UseServerName, f.platform.GetFs(), f.logger)
	settingsSource := NewComplexSettingsSource(metadataService, registryProvider, f.logger)

	return settingsSource, nil
}
func (vm SoftLayerVM) Delete(agentID string) error {
	if strings.ToUpper(common.GetOSEnvVariable("OS_RELOAD_ENABLED", "TRUE")) == "FALSE" {
		if strings.ToUpper(common.GetOSEnvVariable("DEL_NOT_ALLOWED", "FALSE")) == "FALSE" {
			return vm.DeleteVM()
		} else {
			return bosherr.Error("DEL_NOT_ALLOWED is set to TRUE, the VM deletion reqeust is refused.")
		}
	}

	err := bslcvmpool.InitVMPoolDB(bslcvmpool.DB_RETRY_TIMEOUT, bslcvmpool.DB_RETRY_INTERVAL, vm.logger)
	if err != nil {
		return bosherr.WrapError(err, "Failed to initialize VM pool DB")
	}

	db, err := bslcvmpool.OpenDB(bslcvmpool.SQLITE_DB_FILE_PATH)
	if err != nil {
		return bosherr.WrapError(err, "Opening DB")
	}

	vmInfoDB := bslcvmpool.NewVMInfoDB(vm.id, "", "", "", "", vm.logger, db)
	defer vmInfoDB.CloseDB()

	err = vmInfoDB.QueryVMInfobyID(bslcvmpool.DB_RETRY_TIMEOUT, bslcvmpool.DB_RETRY_INTERVAL)
	if err != nil {
		return bosherr.WrapError(err, fmt.Sprintf("Failed to query VM info by given ID %d", vm.id))
	}
	vm.logger.Info(SOFTLAYER_VM_LOG_TAG, fmt.Sprintf("vmInfoDB.vmProperties.id is %d", vmInfoDB.VmProperties.Id))

	if vmInfoDB.VmProperties.Id != 0 {
		if agentID != "" {
			vm.logger.Info(SOFTLAYER_VM_LOG_TAG, fmt.Sprintf("Release the VM with id %d back to the VM pool", vmInfoDB.VmProperties.Id))
			vmInfoDB.VmProperties.InUse = "f"
			err = vmInfoDB.UpdateVMInfoByID(bslcvmpool.DB_RETRY_TIMEOUT, bslcvmpool.DB_RETRY_INTERVAL)
			if err != nil {
				return bosherr.WrapError(err, fmt.Sprintf("Failed to update in_use to %s by given ID %d", vmInfoDB.VmProperties.InUse, vm.id))
			} else {
				return nil
			}
		} else {
			if strings.ToUpper(common.GetOSEnvVariable("DEL_NOT_ALLOWED", "FALSE")) == "FALSE" {
				return vm.DeleteVM()
			} else {
				return bosherr.Error("DEL_NOT_ALLOWED is set to TRUE, the VM deletion reqeust is refused.")
			}
		}
	} else {
		if strings.ToUpper(common.GetOSEnvVariable("DEL_NOT_ALLOWED", "FALSE")) == "FALSE" {
			return vm.DeleteVM()
		} else {
			return bosherr.Error("DEL_NOT_ALLOWED is set to TRUE, the VM deletion reqeust is refused.")
		}
	}

}
func (c SoftLayerConfig) Validate() error {
	if c.Username == "" {
		return bosherr.Error("Must provide non-empty Username")
	}

	if c.ApiKey == "" {
		return bosherr.Error("Must provide non-empty ApiKey")
	}

	return nil
}
func (v SemanticValidator) validateNetworkAssociation(na NetworkAssociation) error {
	if na.Network == nil {
		return bosherr.Error("Missing associated network")
	}

	if na.MustHaveStaticIP && na.StaticIP == nil {
		return bosherr.Error("Missing static IP assignment")
	}

	return nil
}
Exemple #16
0
func (b localBlobstore) Validate() error {
	path, found := b.options["blobstore_path"]
	if !found {
		return bosherr.Error("missing blobstore_path")
	}

	_, ok := path.(string)
	if !ok {
		return bosherr.Error("blobstore_path must be a string")
	}

	return nil
}
func (bc FileBundleCollection) Get(definition BundleDefinition) (Bundle, error) {
	if len(definition.BundleName()) == 0 {
		return nil, bosherr.Error("Missing bundle name")
	}

	if len(definition.BundleVersion()) == 0 {
		return nil, bosherr.Error("Missing bundle version")
	}

	installPath := path.Join(bc.installPath, bc.name, definition.BundleName(), definition.BundleVersion())
	enablePath := path.Join(bc.enablePath, bc.name, definition.BundleName())
	return NewFileBundle(installPath, enablePath, bc.fs, bc.logger), nil
}
func (v SyntaxValidator) validateRelease(release *Release) error {
	if release.Name == "" {
		return bosherr.Error("Missing release name")
	}

	if release.Version == "" {
		return bosherr.Error("Missing release version")
	}

	if release.URL == "" {
		return bosherr.Error("Missing release URL")
	}

	return nil
}
func (d *deployWrapper) RunWithDebug(args ...string) (string, error) {
	output, err := d.cliRunner.RunWithOutput(args...)
	taskId := ""

	if err != nil {
		re := regexp.MustCompile("bosh task ([0-9]+) --debug")
		matches := re.FindAllStringSubmatch(output, -1)

		if len(matches) > 0 && len(matches[0]) > 1 {
			taskId = matches[0][1]
			debugErr := d.cliRunner.RunWithArgs("task", taskId, "--debug")
			if debugErr != nil {
				return taskId, debugErr
			}
		}
	} else {
		re := regexp.MustCompile("Task ([0-9]+) done")
		matches := re.FindAllStringSubmatch(output, -1)

		if len(matches) > 0 && len(matches[0]) > 1 {
			taskId = matches[0][1]
		}
	}

	if taskId == "" {
		return "", bosherr.Error("Failed to get task id")
	}

	return taskId, err
}
func (udev ConcreteUdevDevice) readByte(filePath string) error {
	udev.logger.Debug(udev.logtag, "readBytes from file: %s", filePath)
	device, err := os.Open(filePath)
	if err != nil {
		return err
	}
	defer func() {
		if err = device.Close(); err != nil {
			udev.logger.Warn(udev.logtag, "Failed to close device: %s", err.Error())
		}
	}()
	udev.logger.Debug(udev.logtag, "Successfully open file: %s", filePath)

	bytes := make([]byte, 1, 1)
	read, err := device.Read(bytes)
	if err != nil {
		return err
	}
	udev.logger.Debug(udev.logtag, "Successfully read %d bytes from file: %s", read, filePath)

	if read != 1 {
		return bosherr.Error("Device readable but zero length")
	}

	return nil
}
func (o BlobstoreOptions) Validate() error {
	if o.Type == "" {
		return bosherr.Error("Must provide non-empty Type")
	}

	return nil
}
// 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, isAlreadyCompiled, 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)

			if isAlreadyCompiled {
				return biui.NewSkipStageError(bosherr.Error(fmt.Sprintf("Package '%s' is already compiled. Skipped compilation", pkg.Name)), "Package already compiled")
			}

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

	return packageRefs, nil
}
func (b retryableBlobstore) Validate() error {
	if b.maxTries < 1 {
		return bosherr.Error("Max tries must be > 0")
	}

	return b.blobstore.Validate()
}
func (v SemanticValidator) validateNetwork(network Network) error {
	if network.Type == NetworkTypeManual {
		return bosherr.Error("Manual networking is not supported")
	}

	return nil
}
func (v SemanticValidator) validateRelease(release Release) error {
	if release.Version == "latest" {
		return bosherr.Error("Version 'latest' is not supported")
	}

	return nil
}
func (v SemanticValidator) validateTemplate(template Template) error {
	if template.Release == nil {
		return bosherr.Error("Missing associated release")
	}

	return nil
}
func (r identityDevicePathResolver) GetRealDevicePath(diskSettings boshsettings.DiskSettings) (string, bool, error) {
	if len(diskSettings.Path) == 0 {
		return "", false, bosherr.Error("Getting real device path: path is missing")
	}

	return diskSettings.Path, false, nil
}
func (v SyntaxValidator) validateCompilation(compilation *Compilation) error {
	if compilation.NetworkName == "" {
		return bosherr.Error("Missing network name")
	}

	return nil
}
func (v SyntaxValidator) validateNetwork(network *Network) error {
	if network.Name == "" {
		return bosherr.Error("Missing network name")
	}

	return v.validateNetworkType(network.Type)
}
func (s windowsRoutesSearcher) SearchRoutes() ([]Route, error) {
	ifs, err := net.Interfaces()
	if err != nil {
		return nil, bosherr.WrapError(err, "Running route")
	}
	var routes []Route
	var first error
	for _, fs := range ifs {
		gateway, err := getGateway(fs.Index)
		if err != nil {
			if first == nil {
				first = err
			}
			continue
		}
		route := Route{
			InterfaceName: fs.Name,
			Gateway:       gateway,
			Destination:   "0.0.0.0",
		}
		routes = append(routes, route)
	}
	if len(routes) == 0 {
		if first != nil {
			return nil, first
		}
		return nil, bosherr.Error("no routes")
	}
	return routes, nil
}