コード例 #1
0
ファイル: manifest.go プロジェクト: hanzhefeng/bosh-init
func (d Manifest) DiskPool(jobName string) (DiskPool, error) {
	job, found := d.FindJobByName(jobName)
	if !found {
		return DiskPool{}, bosherr.Errorf("Could not find job with name: %s", jobName)
	}

	if job.PersistentDiskPool != "" {
		for _, diskPool := range d.DiskPools {
			if diskPool.Name == job.PersistentDiskPool {
				return diskPool, nil
			}
		}
		err := bosherr.Errorf("Could not find persistent disk pool '%s' for job '%s'", job.PersistentDiskPool, jobName)
		return DiskPool{}, err
	}

	if job.PersistentDisk > 0 {
		diskPool := DiskPool{
			DiskSize:        job.PersistentDisk,
			CloudProperties: biproperty.Map{},
		}
		return diskPool, nil
	}

	return DiskPool{}, nil
}
コード例 #2
0
ファイル: deployer.go プロジェクト: vestel/bosh-init
func (d *deployer) createAllInstances(
	deploymentManifest bideplmanifest.Manifest,
	instanceManager biinstance.Manager,
	cloudStemcell bistemcell.CloudStemcell,
	registryConfig biinstallmanifest.Registry,
	deployStage biui.Stage,
) ([]biinstance.Instance, []bidisk.Disk, error) {
	instances := []biinstance.Instance{}
	disks := []bidisk.Disk{}

	if len(deploymentManifest.Jobs) != 1 {
		return instances, disks, bosherr.Errorf("There must only be one job, found %d", len(deploymentManifest.Jobs))
	}

	for _, jobSpec := range deploymentManifest.Jobs {
		if jobSpec.Instances != 1 {
			return instances, disks, bosherr.Errorf("Job '%s' must have only one instance, found %d", jobSpec.Name, jobSpec.Instances)
		}
		for instanceID := 0; instanceID < jobSpec.Instances; instanceID++ {
			instance, instanceDisks, err := instanceManager.Create(jobSpec.Name, instanceID, deploymentManifest, cloudStemcell, registryConfig, deployStage)
			if err != nil {
				return instances, disks, bosherr.WrapErrorf(err, "Creating instance '%s/%d'", jobSpec.Name, instanceID)
			}
			instances = append(instances, instance)
			disks = append(disks, instanceDisks...)

			err = instance.UpdateJobs(deploymentManifest, deployStage)
			if err != nil {
				return instances, disks, err
			}
		}
	}

	return instances, disks, nil
}
コード例 #3
0
ファイル: builders.go プロジェクト: vestel/bosh-init
// Build creates a generic property that may be a Map, List or primitive.
// If it is a Map or List it will be built using the appropriate builder and constraints.
func Build(val interface{}) (Property, error) {
	if val == nil {
		return nil, nil
	}

	switch reflect.TypeOf(val).Kind() {
	case reflect.Map:
		valMap, ok := val.(map[interface{}]interface{})
		if !ok {
			return nil, bosherr.Errorf("Converting map %#v", val)
		}

		return BuildMap(valMap)

	case reflect.Slice:
		valSlice, ok := val.([]interface{})
		if !ok {
			return nil, bosherr.Errorf("Converting slice %#v", val)
		}

		return BuildList(valSlice)

	default:
		return val, nil
	}
}
コード例 #4
0
ファイル: validator.go プロジェクト: vestel/bosh-init
func (v *validator) validateGateway(idx int, gateway string, ipNet maybeIPNet) []error {
	if v.isBlank(gateway) {
		return []error{bosherr.Errorf("networks[%d].subnets[0].gateway must be provided", idx)}
	} else {
		errors := []error{}
		ipNet.Try(func(ipNet *net.IPNet) error {
			gatewayIp := net.ParseIP(gateway)
			if gatewayIp == nil {
				errors = append(errors, bosherr.Errorf("networks[%d].subnets[0].gateway must be an ip", idx))
			}

			if !ipNet.Contains(gatewayIp) {
				errors = append(errors, bosherr.Errorf("subnet gateway '%s' must be within the specified range '%s'", gateway, ipNet))
			}

			if ipNet.IP.Equal(gatewayIp) {
				errors = append(errors, bosherr.Errorf("subnet gateway can't be the network address '%s'", gatewayIp))
			}

			if binet.LastAddress(ipNet).Equal(gatewayIp) {
				errors = append(errors, bosherr.Errorf("subnet gateway can't be the broadcast address '%s'", gatewayIp))
			}

			return nil
		})

		return errors
	}
}
コード例 #5
0
ファイル: validator.go プロジェクト: vestel/bosh-init
func (v *validator) validateNetwork(network Network, networkIdx int) []error {
	errs := []error{}

	if v.isBlank(network.Name) {
		errs = append(errs, bosherr.Errorf("networks[%d].name must be provided", networkIdx))
	}
	if network.Type != Dynamic && network.Type != Manual && network.Type != VIP {
		errs = append(errs, bosherr.Errorf("networks[%d].type must be 'manual', 'dynamic', or 'vip'", networkIdx))
	}
	if network.Type == Manual {
		if len(network.Subnets) != 1 {
			errs = append(errs, bosherr.Errorf("networks[%d].subnets must be of size 1", networkIdx))
		} else {
			ipRange := network.Subnets[0].Range
			rangeErrors, maybeIpNet := v.validateRange(networkIdx, ipRange)
			errs = append(errs, rangeErrors...)

			gateway := network.Subnets[0].Gateway
			gatewayErrors := v.validateGateway(networkIdx, gateway, maybeIpNet)
			errs = append(errs, gatewayErrors...)
		}
	}

	return errs
}
コード例 #6
0
ファイル: ip_resolver.go プロジェクト: vestel/bosh-init
func (r ipResolver) GetPrimaryIPv4(interfaceName string) (*gonet.IPNet, error) {
	addrs, err := r.ifaceToAddrsFunc(interfaceName)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Looking up addresses for interface '%s'", interfaceName)
	}

	if len(addrs) == 0 {
		return nil, bosherr.Errorf("No addresses found for interface '%s'", interfaceName)
	}

	for _, addr := range addrs {
		ip, ok := addr.(*gonet.IPNet)
		if !ok {
			continue
		}

		// ignore ipv6
		if ip.IP.To4() == nil {
			continue
		}

		return ip, nil
	}

	return nil, bosherr.Errorf("Failed to find primary IPv4 address for interface '%s'", interfaceName)
}
コード例 #7
0
func (p rootDevicePartitioner) Partition(devicePath string, partitions []Partition) error {
	existingPartitions, deviceFullSizeInBytes, err := p.getPartitions(devicePath)
	if err != nil {
		return bosherr.WrapErrorf(err, "Getting existing partitions of `%s'", devicePath)
	}
	p.logger.Debug(p.logTag, "Current partitions: %#v", existingPartitions)

	if len(existingPartitions) == 0 {
		return bosherr.Errorf("Missing first partition on `%s'", devicePath)
	}

	if p.partitionsMatch(existingPartitions[1:], partitions) {
		p.logger.Info(p.logTag, "Partitions already match, skipping partitioning")
		return nil
	}

	if len(existingPartitions) > 1 {
		p.logger.Error(p.logTag,
			"Failed to create ephemeral partitions on root device `%s'. Expected 1 partition, found %d: %s",
			devicePath,
			len(existingPartitions),
			existingPartitions,
		)
		return bosherr.Errorf("Found %d unexpected partitions on `%s'", len(existingPartitions)-1, devicePath)
	}

	// To support optimal reads on HDDs and optimal erasure on SSD: use 1MiB partition alignments.
	alignmentInBytes := uint64(1048576)

	partitionStart := p.roundUp(existingPartitions[0].EndInBytes+1, alignmentInBytes)

	for index, partition := range partitions {
		partitionEnd := partitionStart + partition.SizeInBytes - 1
		if partitionEnd >= deviceFullSizeInBytes {
			partitionEnd = deviceFullSizeInBytes - 1
			p.logger.Info(p.logTag, "Partition %d would be larger than remaining space. Reducing size to %dB", index, partitionEnd-partitionStart)
		}

		p.logger.Info(p.logTag, "Creating partition %d with start %dB and end %dB", index, partitionStart, partitionEnd)

		_, _, _, err := p.cmdRunner.RunCommand(
			"parted",
			"-s",
			devicePath,
			"unit",
			"B",
			"mkpart",
			"primary",
			fmt.Sprintf("%d", partitionStart),
			fmt.Sprintf("%d", partitionEnd),
		)

		if err != nil {
			return bosherr.WrapErrorf(err, "Partitioning disk `%s'", devicePath)
		}

		partitionStart = p.roundUp(partitionEnd+1, alignmentInBytes)
	}
	return nil
}
コード例 #8
0
ファイル: watch_time.go プロジェクト: vestel/bosh-init
func NewWatchTime(timeRange string) (WatchTime, error) {
	parts := strings.Split(timeRange, "-")
	if len(parts) != 2 {
		return WatchTime{}, bosherr.Errorf("Invalid watch time range '%s'", timeRange)
	}

	start, err := strconv.Atoi(strings.Trim(parts[0], " "))
	if err != nil {
		return WatchTime{}, bosherr.WrapErrorf(
			err, "Non-positive number as watch time minimum %s", parts[0])
	}

	end, err := strconv.Atoi(strings.Trim(parts[1], " "))
	if err != nil {
		return WatchTime{}, bosherr.WrapErrorf(
			err, "Non-positive number as watch time maximum %s", parts[1])
	}

	if end < start {
		return WatchTime{}, bosherr.Errorf(
			"Watch time must have maximum greater than or equal minimum %s", timeRange)
	}

	return WatchTime{
		Start: start,
		End:   end,
	}, nil
}
コード例 #9
0
ファイル: validator.go プロジェクト: vestel/bosh-init
func (v *validator) validateJobNetworks(jobNetworks []JobNetwork, networks []Network, jobIdx int) []error {
	errs := []error{}
	defaultCounts := make(map[NetworkDefault]int)

	for networkIdx, jobNetwork := range jobNetworks {

		if v.isBlank(jobNetwork.Name) {
			errs = append(errs, bosherr.Errorf("jobs[%d].networks[%d].name must be provided", jobIdx, networkIdx))
		}

		var matchingNetwork Network
		found := false
		for _, network := range networks {
			if network.Name == jobNetwork.Name {
				found = true
				matchingNetwork = network
			}
		}

		if !found {
			errs = append(errs, bosherr.Errorf("jobs[%d].networks[%d] not found in networks", jobIdx, networkIdx))
		}

		for ipIdx, ip := range jobNetwork.StaticIPs {
			staticIPErrors := v.validateStaticIP(ip, jobNetwork, matchingNetwork, jobIdx, networkIdx, ipIdx)
			errs = append(errs, staticIPErrors...)
		}

		for defaultIdx, value := range jobNetwork.Defaults {
			if value != NetworkDefaultDNS && value != NetworkDefaultGateway {
				errs = append(errs, bosherr.Errorf("jobs[%d].networks[%d].default[%d] must be 'dns' or 'gateway'", jobIdx, networkIdx, defaultIdx))
			}
		}

		for _, dflt := range jobNetwork.Defaults {
			count, present := defaultCounts[dflt]
			if present {
				defaultCounts[dflt] = count + 1
			} else {
				defaultCounts[dflt] = 1
			}
		}
	}
	for _, dflt := range []NetworkDefault{"dns", "gateway"} {
		count, found := defaultCounts[dflt]
		if len(jobNetworks) > 1 && !found {
			errs = append(errs, bosherr.Errorf("with multiple networks, a default for '%s' must be specified", dflt))
		} else if count > 1 {
			errs = append(errs, bosherr.Errorf("only one network can be the default for '%s'", dflt))
		}
	}

	return errs
}
コード例 #10
0
ファイル: validator.go プロジェクト: vestel/bosh-init
func (v *validator) validateRange(idx int, ipRange string) ([]error, maybeIPNet) {
	if v.isBlank(ipRange) {
		return []error{bosherr.Errorf("networks[%d].subnets[0].range must be provided", idx)}, &nothingIpNet{}
	} else {
		_, ipNet, err := net.ParseCIDR(ipRange)
		if err != nil {
			return []error{bosherr.Errorf("networks[%d].subnets[0].range must be an ip range", idx)}, &nothingIpNet{}
		}

		return []error{}, &somethingIpNet{ipNet: ipNet}
	}
}
コード例 #11
0
ファイル: validator.go プロジェクト: vestel/bosh-init
func (v Validator) Validate(release birel.Release, cpiReleaseJobName string) error {
	job, ok := release.FindJobByName(cpiReleaseJobName)
	if !ok {
		return bosherr.Errorf("CPI release must contain specified job '%s'", cpiReleaseJobName)
	}

	_, ok = job.FindTemplateByValue(ReleaseBinaryName)
	if !ok {
		return bosherr.Errorf("Specified CPI release job '%s' must contain a template that renders to target '%s'", cpiReleaseJobName, ReleaseBinaryName)
	}

	return nil
}
コード例 #12
0
ファイル: agent_response.go プロジェクト: vestel/bosh-init
func (r *TaskResponse) TaskID() (string, error) {
	complexResponse, ok := r.Value.(map[string]interface{})
	if !ok {
		return "", bosherr.Errorf("Failed to convert agent response to map %#v\n%s", r.Value, debug.Stack())
	}

	agentTaskID, ok := complexResponse["agent_task_id"]
	if !ok {
		return "", bosherr.Errorf("Failed to parse task id from agent response %#v", r.Value)
	}

	return agentTaskID.(string), nil
}
コード例 #13
0
ファイル: job_resolver.go プロジェクト: vestel/bosh-init
func (r *resolver) Resolve(jobName, releaseName string) (bireljob.Job, error) {
	release, found := r.releaseManager.Find(releaseName)
	if !found {
		return bireljob.Job{}, bosherr.Errorf("Finding release '%s'", releaseName)
	}

	releaseJob, found := release.FindJobByName(jobName)
	if !found {
		return bireljob.Job{}, bosherr.Errorf("Finding job '%s' in release '%s'", jobName, releaseName)
	}

	return releaseJob, nil
}
コード例 #14
0
ファイル: manifest.go プロジェクト: hanzhefeng/bosh-init
func (d Manifest) ResourcePool(jobName string) (ResourcePool, error) {
	job, found := d.FindJobByName(jobName)
	if !found {
		return ResourcePool{}, bosherr.Errorf("Could not find job with name: %s", jobName)
	}

	for _, resourcePool := range d.ResourcePools {
		if resourcePool.Name == job.ResourcePool {
			return resourcePool, nil
		}
	}
	err := bosherr.Errorf("Could not find resource pool '%s' for job '%s'", job.ResourcePool, jobName)
	return ResourcePool{}, err
}
コード例 #15
0
ファイル: agent_client.go プロジェクト: vestel/bosh-init
func (c *agentClient) CompilePackage(packageSource agentclient.BlobRef, compiledPackageDependencies []agentclient.BlobRef) (compiledPackageRef agentclient.BlobRef, err error) {
	dependencies := make(map[string]BlobRef, len(compiledPackageDependencies))
	for _, dependency := range compiledPackageDependencies {
		dependencies[dependency.Name] = BlobRef{
			Name:        dependency.Name,
			Version:     dependency.Version,
			SHA1:        dependency.SHA1,
			BlobstoreID: dependency.BlobstoreID,
		}
	}

	args := []interface{}{
		packageSource.BlobstoreID,
		packageSource.SHA1,
		packageSource.Name,
		packageSource.Version,
		dependencies,
	}

	responseValue, err := c.sendAsyncTaskMessage("compile_package", args)
	if err != nil {
		return agentclient.BlobRef{}, bosherr.WrapError(err, "Sending 'compile_package' to the agent")
	}

	result, ok := responseValue["result"].(map[string]interface{})
	if !ok {
		return agentclient.BlobRef{}, bosherr.Errorf("Unable to parse 'compile_package' response from the agent: %#v", responseValue)
	}

	sha1, ok := result["sha1"].(string)
	if !ok {
		return agentclient.BlobRef{}, bosherr.Errorf("Unable to parse 'compile_package' response from the agent: %#v", responseValue)
	}

	blobstoreID, ok := result["blobstore_id"].(string)
	if !ok {
		return agentclient.BlobRef{}, bosherr.Errorf("Unable to parse 'compile_package' response from the agent: %#v", responseValue)
	}

	compiledPackageRef = agentclient.BlobRef{
		Name:        packageSource.Name,
		Version:     packageSource.Version,
		SHA1:        sha1,
		BlobstoreID: blobstoreID,
	}

	return compiledPackageRef, nil
}
コード例 #16
0
func (b externalBlobstore) Validate() error {
	if !b.runner.CommandExists(b.executable()) {
		return bosherr.Errorf("executable %s not found in PATH", b.executable())
	}

	return b.writeConfigFile()
}
コード例 #17
0
ファイル: cloud.go プロジェクト: vestel/bosh-init
func (c cloud) CreateVM(
	agentID string,
	stemcellCID string,
	cloudProperties biproperty.Map,
	networksInterfaces map[string]biproperty.Map,
	env biproperty.Map,
) (string, error) {
	method := "create_vm"
	diskLocality := []interface{}{} // not used with bosh-init
	cmdOutput, err := c.cpiCmdRunner.Run(
		c.context,
		method,
		agentID,
		stemcellCID,
		cloudProperties,
		networksInterfaces,
		diskLocality,
		env,
	)
	if err != nil {
		return "", err
	}

	if cmdOutput.Error != nil {
		return "", NewCPIError(method, *cmdOutput.Error)
	}

	// for create_vm, the result is a string of the vm cid
	cidString, ok := cmdOutput.Result.(string)
	if !ok {
		return "", bosherr.Errorf("Unexpected external CPI command result: '%#v'", cmdOutput.Result)
	}
	return cidString, nil
}
コード例 #18
0
ファイル: factory.go プロジェクト: vestel/bosh-init
func (cl CommandList) Create(name string) (Cmd, error) {
	if cl[name] == nil {
		return nil, bosherr.Errorf("Command '%s' unknown. See 'bosh-init help'", name)
	}

	return cl[name]()
}
コード例 #19
0
ファイル: provider.go プロジェクト: vestel/bosh-init
func (p provider) Get(name string) (Platform, error) {
	plat, found := p.platforms[name]
	if !found {
		return nil, bosherror.Errorf("Platform %s could not be found", name)
	}
	return plat, nil
}
コード例 #20
0
ファイル: cloud.go プロジェクト: vestel/bosh-init
func (c cloud) CreateDisk(size int, cloudProperties biproperty.Map, vmCID string) (string, error) {
	c.logger.Debug(c.logTag,
		"Creating disk with size %d, cloudProperties %#v, instanceID %s",
		size,
		cloudProperties,
		vmCID,
	)
	method := "create_disk"
	cmdOutput, err := c.cpiCmdRunner.Run(
		c.context,
		method,
		size,
		cloudProperties,
		vmCID,
	)
	if err != nil {
		return "", err
	}

	if cmdOutput.Error != nil {
		return "", NewCPIError(method, *cmdOutput.Error)
	}

	cidString, ok := cmdOutput.Result.(string)
	if !ok {
		return "", bosherr.Errorf("Unexpected external CPI command result: '%#v'", cmdOutput.Result)
	}
	return cidString, nil
}
コード例 #21
0
ファイル: disk_repo.go プロジェクト: vestel/bosh-init
func (r diskRepo) Save(cid string, size int, cloudProperties biproperty.Map) (DiskRecord, error) {
	config, records, err := r.load()
	if err != nil {
		return DiskRecord{}, err
	}

	oldRecord, found := r.find(records, cid)
	if found {
		return DiskRecord{}, bosherr.Errorf("Failed to save disk cid '%s', existing record found '%#v'", cid, oldRecord)
	}

	newRecord := DiskRecord{
		CID:             cid,
		Size:            size,
		CloudProperties: cloudProperties,
	}
	newRecord.ID, err = r.uuidGenerator.Generate()
	if err != nil {
		return newRecord, bosherr.WrapError(err, "Generating disk id")
	}

	records = append(records, newRecord)
	config.Disks = records

	err = r.deploymentStateService.Save(config)
	if err != nil {
		return newRecord, bosherr.WrapError(err, "Saving new config")
	}
	return newRecord, nil
}
コード例 #22
0
ファイル: manager.go プロジェクト: vestel/bosh-init
// 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
}
コード例 #23
0
ファイル: deploy_cmd.go プロジェクト: vestel/bosh-init
func (c *deployCmd) Run(stage biui.Stage, args []string) error {
	deploymentManifestPath, err := c.parseCmdInputs(args)
	if err != nil {
		return err
	}

	manifestAbsFilePath, err := filepath.Abs(deploymentManifestPath)
	if err != nil {
		c.ui.ErrorLinef("Failed getting absolute path to deployment file '%s'", deploymentManifestPath)
		return bosherr.WrapErrorf(err, "Getting absolute path to deployment file '%s'", deploymentManifestPath)
	}

	if !c.fs.FileExists(manifestAbsFilePath) {
		c.ui.ErrorLinef("Deployment '%s' does not exist", manifestAbsFilePath)
		return bosherr.Errorf("Deployment manifest does not exist at '%s'", manifestAbsFilePath)
	}

	c.ui.PrintLinef("Deployment manifest: '%s'", manifestAbsFilePath)

	deploymentPreparer, err := c.deploymentPreparerProvider(manifestAbsFilePath)
	if err != nil {
		return err
	}

	return deploymentPreparer.PrepareDeployment(stage)
}
コード例 #24
0
func (p rootDevicePartitioner) GetDeviceSizeInBytes(devicePath string) (uint64, error) {
	p.logger.Debug(p.logTag, "Getting size of disk remaining after first partition")

	stdout, _, _, err := p.cmdRunner.RunCommand("parted", "-m", devicePath, "unit", "B", "print")
	if err != nil {
		return 0, bosherr.WrapErrorf(err, "Getting remaining size of `%s'", devicePath)
	}

	allLines := strings.Split(stdout, "\n")
	if len(allLines) < 3 {
		return 0, bosherr.Errorf("Getting remaining size of `%s'", devicePath)
	}

	partitionInfoLines := allLines[1:3]
	deviceInfo := strings.Split(partitionInfoLines[0], ":")
	deviceFullSizeInBytes, err := strconv.ParseUint(strings.TrimRight(deviceInfo[1], "B"), 10, 64)
	if err != nil {
		return 0, bosherr.WrapErrorf(err, "Getting remaining size of `%s'", devicePath)
	}

	firstPartitionInfo := strings.Split(partitionInfoLines[1], ":")
	firstPartitionEndInBytes, err := strconv.ParseUint(strings.TrimRight(firstPartitionInfo[2], "B"), 10, 64)
	if err != nil {
		return 0, bosherr.WrapErrorf(err, "Getting remaining size of `%s'", devicePath)
	}

	remainingSizeInBytes := deviceFullSizeInBytes - firstPartitionEndInBytes - 1

	return remainingSizeInBytes, nil
}
コード例 #25
0
func (idpr idDevicePathResolver) GetRealDevicePath(diskSettings boshsettings.DiskSettings) (string, bool, error) {
	if diskSettings.ID == "" {
		return "", false, bosherr.Errorf("Disk ID is not set")
	}

	if len(diskSettings.ID) < 20 {
		return "", false, bosherr.Errorf("Disk ID is not the correct format")
	}

	err := idpr.udev.Trigger()
	if err != nil {
		return "", false, bosherr.WrapError(err, "Running udevadm trigger")
	}

	err = idpr.udev.Settle()
	if err != nil {
		return "", false, bosherr.WrapError(err, "Running udevadm settle")
	}

	stopAfter := time.Now().Add(idpr.diskWaitTimeout)
	found := false

	var realPath string

	diskID := diskSettings.ID[0:20]

	for !found {
		if time.Now().After(stopAfter) {
			return "", true, bosherr.Errorf("Timed out getting real device path for '%s'", diskID)
		}

		time.Sleep(100 * time.Millisecond)

		deviceIDPath := filepath.Join(string(os.PathSeparator), "dev", "disk", "by-id", fmt.Sprintf("virtio-%s", diskID))

		realPath, err = idpr.fs.ReadLink(deviceIDPath)
		if err != nil {
			continue
		}

		if idpr.fs.FileExists(realPath) {
			found = true
		}
	}

	return realPath, false, nil
}
コード例 #26
0
ファイル: manager.go プロジェクト: vestel/bosh-init
func (m *manager) DeleteAll() error {
	for _, release := range m.releases {
		deleteErr := release.Delete()
		if deleteErr != nil {
			return bosherr.Errorf("Failed to delete extracted release '%s': %s", release.Name(), deleteErr.Error())
		}
	}
	m.releases = []Release{}
	return nil
}
コード例 #27
0
ファイル: builder.go プロジェクト: vestel/bosh-init
// FIXME: why do i exist here and in installation/state/builder.go??
func (b *builder) resolveJobs(jobRefs []bideplmanifest.ReleaseJobRef) ([]bireljob.Job, error) {
	releaseJobs := make([]bireljob.Job, len(jobRefs), len(jobRefs))
	for i, jobRef := range jobRefs {
		release, err := b.releaseJobResolver.Resolve(jobRef.Name, jobRef.Release)
		if err != nil {
			return releaseJobs, bosherr.Errorf("Resolving job '%s' in release '%s'", jobRef.Name, jobRef.Release)
		}
		releaseJobs[i] = release
	}
	return releaseJobs, nil
}
コード例 #28
0
ファイル: fake_validator.go プロジェクト: vestel/bosh-init
func (v *FakeValidator) Validate(manifest birelsetmanifest.Manifest) error {
	v.ValidateInputs = append(v.ValidateInputs, ValidateInput{
		Manifest: manifest,
	})

	if len(v.validateOutputs) == 0 {
		return bosherr.Errorf("Unexpected FakeValidator.Validate(manifest) called with manifest: %#v", manifest)
	}
	validateOutput := v.validateOutputs[0]
	v.validateOutputs = v.validateOutputs[1:]
	return validateOutput.Err
}
コード例 #29
0
func (r *getStateRetryable) Attempt() (bool, error) {
	stateResponse, err := r.agentClient.GetState()
	if err != nil {
		return false, err
	}

	if stateResponse.JobState == "running" {
		return true, nil
	}

	return true, bosherr.Errorf("Received non-running job state: '%s'", stateResponse.JobState)
}
コード例 #30
0
ファイル: stemcell_creator.go プロジェクト: vestel/bosh-init
func CreateStemcell(stemcellSrcDir string, stemcellPath string) error {
	session, err := RunCommand("tar", "-zcf", stemcellPath, "-C", stemcellSrcDir, ".")
	if err != nil {
		return err
	}

	if session.ExitCode() != 0 {
		return bosherr.Errorf("Failed to create stemcell src:'%s' dest:'%s'", stemcellSrcDir, stemcellPath)
	}

	return nil
}