Пример #1
0
func (p linux) partitionEphemeralDisk(realPath string) (string, string, error) {
	p.logger.Info(logTag, "Creating swap & ephemeral partitions on ephemeral disk...")
	p.logger.Debug(logTag, "Getting device size of `%s'", realPath)
	diskSizeInBytes, err := p.diskManager.GetPartitioner().GetDeviceSizeInBytes(realPath)
	if err != nil {
		return "", "", bosherr.WrapError(err, "Getting device size")
	}

	p.logger.Debug(logTag, "Calculating ephemeral disk partition sizes of `%s' with total disk size %dB", realPath, diskSizeInBytes)
	swapSizeInBytes, linuxSizeInBytes, err := p.calculateEphemeralDiskPartitionSizes(diskSizeInBytes)
	if err != nil {
		return "", "", bosherr.WrapError(err, "Calculating partition sizes")
	}

	partitions := []boshdisk.Partition{
		{SizeInBytes: swapSizeInBytes, Type: boshdisk.PartitionTypeSwap},
		{SizeInBytes: linuxSizeInBytes, Type: boshdisk.PartitionTypeLinux},
	}

	p.logger.Info(logTag, "Partitioning ephemeral disk `%s' with %s", realPath, partitions)
	err = p.diskManager.GetPartitioner().Partition(realPath, partitions)
	if err != nil {
		return "", "", bosherr.WrapErrorf(err, "Partitioning ephemeral disk `%s'", realPath)
	}

	swapPartitionPath := realPath + "1"
	dataPartitionPath := realPath + "2"
	return swapPartitionPath, dataPartitionPath, nil
}
Пример #2
0
func (fs *osFileSystem) Chown(path, username string) error {
	fs.logger.Debug(fs.logTag, "Chown %s to user %s", path, username)

	uid, err := fs.runCommand(fmt.Sprintf("id -u %s", username))
	if err != nil {
		return bosherr.WrapErrorf(err, "Getting user id for '%s'", username)
	}

	uidAsInt, err := strconv.Atoi(uid)
	if err != nil {
		return bosherr.WrapError(err, "Converting UID to integer")
	}

	gid, err := fs.runCommand(fmt.Sprintf("id -g %s", username))
	if err != nil {
		return bosherr.WrapErrorf(err, "Getting group id for '%s'", username)
	}

	gidAsInt, err := strconv.Atoi(gid)
	if err != nil {
		return bosherr.WrapError(err, "Converting GID to integer")
	}

	err = os.Chown(path, uidAsInt, gidAsInt)
	if err != nil {
		return bosherr.WrapError(err, "Doing Chown")
	}

	return nil
}
Пример #3
0
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")
}
Пример #4
0
func (net centosNetManager) detectMacAddresses() (map[string]string, error) {
	addresses := map[string]string{}

	filePaths, err := net.fs.Glob("/sys/class/net/*")
	if err != nil {
		return addresses, bosherr.WrapError(err, "Getting file list from /sys/class/net")
	}

	var macAddress string
	for _, filePath := range filePaths {
		isPhysicalDevice := net.fs.FileExists(filepath.Join(filePath, "device"))

		if isPhysicalDevice {
			macAddress, err = net.fs.ReadFileString(filepath.Join(filePath, "address"))
			if err != nil {
				return addresses, bosherr.WrapError(err, "Reading mac address from file")
			}

			macAddress = strings.Trim(macAddress, "\n")

			interfaceName := filepath.Base(filePath)
			addresses[macAddress] = interfaceName
		}
	}

	return addresses, nil
}
Пример #5
0
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
}
Пример #6
0
func (r releaseRepo) Update(releases []release.Release) error {
	newRecordIDs := []string{}
	newRecords := []ReleaseRecord{}

	deploymentState, err := r.deploymentStateService.Load()
	if err != nil {
		return bosherr.WrapError(err, "Loading existing config")
	}

	for _, release := range releases {
		newRecord := ReleaseRecord{
			Name:    release.Name(),
			Version: release.Version(),
		}
		newRecord.ID, err = r.uuidGenerator.Generate()
		if err != nil {
			return bosherr.WrapError(err, "Generating release id")
		}
		newRecords = append(newRecords, newRecord)
		newRecordIDs = append(newRecordIDs, newRecord.ID)
	}

	deploymentState.CurrentReleaseIDs = newRecordIDs
	deploymentState.Releases = newRecords
	err = r.deploymentStateService.Save(deploymentState)
	if err != nil {
		return bosherr.WrapError(err, "Updating current release record")
	}
	return nil
}
Пример #7
0
func (s *cloudStemcell) Delete() error {
	deleteErr := s.cloud.DeleteStemcell(s.cid)
	if deleteErr != nil {
		// allow StemcellNotFoundError for idempotency
		cloudErr, ok := deleteErr.(bicloud.Error)
		if !ok || cloudErr.Type() != bicloud.StemcellNotFoundError {
			return bosherr.WrapError(deleteErr, "Deleting stemcell from cloud")
		}
	}

	stemcellRecord, found, err := s.repo.Find(s.name, s.version)
	if err != nil {
		return bosherr.WrapErrorf(err, "Finding stemcell record (name=%s, version=%s)", s.name, s.version)
	}

	if !found {
		return nil
	}

	err = s.repo.Delete(stemcellRecord)
	if err != nil {
		return bosherr.WrapError(err, "Deleting stemcell record")
	}

	return deleteErr
}
Пример #8
0
func (net UbuntuNetManager) SetupNetworking(networks boshsettings.Networks, errCh chan error) error {
	staticConfigs, dhcpConfigs, dnsServers, err := net.ComputeNetworkConfig(networks)
	if err != nil {
		return bosherr.WrapError(err, "Computing network configuration")
	}

	interfacesChanged, err := net.writeNetworkInterfaces(dhcpConfigs, staticConfigs, dnsServers)
	if err != nil {
		return bosherr.WrapError(err, "Writing network configuration")
	}

	dhcpChanged := false
	if len(dhcpConfigs) > 0 {
		dhcpChanged, err = net.writeDHCPConfiguration(dnsServers)
		if err != nil {
			return err
		}
	}

	if interfacesChanged || dhcpChanged {
		err = net.removeDhcpDNSConfiguration()
		if err != nil {
			return err
		}
		net.restartNetworkingInterfaces()
	}

	net.broadcastIps(staticConfigs, dhcpConfigs, errCh)

	return nil
}
Пример #9
0
func (p *parser) Parse(path string) (Manifest, error) {
	contents, err := p.fs.ReadFile(path)
	if err != nil {
		return Manifest{}, bosherr.WrapErrorf(err, "Reading file %s", path)
	}

	comboManifest := manifest{}
	err = yaml.Unmarshal(contents, &comboManifest)
	if err != nil {
		return Manifest{}, bosherr.WrapError(err, "Unmarshalling release set manifest")
	}
	p.logger.Debug(p.logTag, "Parsed release set manifest: %#v", comboManifest)

	for i, releaseRef := range comboManifest.Releases {
		comboManifest.Releases[i].URL, err = biutil.AbsolutifyPath(path, releaseRef.URL, p.fs)
		if err != nil {
			return Manifest{}, bosherr.WrapErrorf(err, "Resolving release path '%s", releaseRef.URL)
		}
	}

	releaseSetManifest := Manifest{
		Releases: comboManifest.Releases,
	}

	err = p.validator.Validate(releaseSetManifest)
	if err != nil {
		return Manifest{}, bosherr.WrapError(err, "Validating release set manifest")
	}

	return releaseSetManifest, nil
}
Пример #10
0
func (p linux) SetupHostname(hostname string) (err error) {
	_, _, _, err = p.cmdRunner.RunCommand("hostname", hostname)
	if err != nil {
		err = bosherr.WrapError(err, "Shelling out to hostname")
		return
	}

	err = p.fs.WriteFileString("/etc/hostname", hostname)
	if err != nil {
		err = bosherr.WrapError(err, "Writing /etc/hostname")
		return
	}

	buffer := bytes.NewBuffer([]byte{})
	t := template.Must(template.New("etc-hosts").Parse(etcHostsTemplate))

	err = t.Execute(buffer, hostname)
	if err != nil {
		err = bosherr.WrapError(err, "Generating config from template")
		return
	}

	err = p.fs.WriteFile("/etc/hosts", buffer.Bytes())
	if err != nil {
		err = bosherr.WrapError(err, "Writing to /etc/hosts")
	}
	return
}
Пример #11
0
func (d *disk) Delete() error {
	deleteErr := d.cloud.DeleteDisk(d.cid)
	if deleteErr != nil {
		// allow DiskNotFoundError for idempotency
		cloudErr, ok := deleteErr.(bicloud.Error)
		if !ok || cloudErr.Type() != bicloud.DiskNotFoundError {
			return bosherr.WrapError(deleteErr, "Deleting disk in the cloud")
		}
	}

	diskRecord, found, err := d.repo.Find(d.cid)
	if err != nil {
		return bosherr.WrapErrorf(err, "Finding disk record (cid=%s)", d.cid)
	}

	if !found {
		return nil
	}

	err = d.repo.Delete(diskRecord)
	if err != nil {
		return bosherr.WrapError(err, "Deleting disk record")
	}

	// returns bicloud.Error only if it is a DiskNotFoundError
	return deleteErr
}
func (ms *configDriveMetadataService) loadFromDiskPath(diskPath string) error {
	contentPaths := []string{ms.metaDataFilePath, ms.userDataFilePath}

	contents, err := ms.platform.GetFilesContentsFromDisk(diskPath, contentPaths)
	if err != nil {
		return bosherr.WrapError(err, "Reading files on config drive")
	}

	var metadata MetadataContentsType

	err = json.Unmarshal(contents[0], &metadata)
	if err != nil {
		return bosherr.WrapError(err, "Parsing config drive metadata from meta_data.json")
	}

	ms.metaDataContents = metadata

	var userdata UserDataContentsType

	err = json.Unmarshal(contents[1], &userdata)
	if err != nil {
		return bosherr.WrapError(err, "Parsing config drive metadata from user_data")
	}

	ms.userDataContents = userdata

	return nil
}
Пример #13
0
func describeMultilineError() {
	var err error

	It("returns a simple single-line message string (depth=0)", func() {
		err = bosherr.Error("omg")
		Expect(MultilineError(err)).To(Equal("omg"))
	})

	Context("when given a composite error", func() {
		It("returns a multi-line, indented message string (depth=1)", func() {
			err = bosherr.WrapError(bosherr.Error("inner omg"), "omg")
			Expect(MultilineError(err)).To(Equal("omg:\n  inner omg"))
		})

		It("returns a multi-line, indented message string (depth=2)", func() {
			err = bosherr.WrapError(bosherr.WrapError(bosherr.Error("inner omg"), "omg"), "outer omg")
			Expect(MultilineError(err)).To(Equal("outer omg:\n  omg:\n    inner omg"))
		})

		It("returns a multi-line, indented message string (depth=3)", func() {
			err = bosherr.WrapError(bosherr.WrapError(bosherr.WrapError(bosherr.Error("inner omg"), "almost inner omg"), "almost outer omg"), "outer omg")
			Expect(MultilineError(err)).To(Equal("outer omg:\n  almost outer omg:\n    almost inner omg:\n      inner omg"))
		})
	})

	Context("when given an explainable error", func() {
		It("returns a multi-line message string with sibling errors at the same indentation", func() {
			err = bosherr.NewMultiError(bosherr.Error("a"), bosherr.Error("b"))
			Expect(MultilineError(err)).To(Equal("a\nb"))
		})

		It("returns a multi-line message string with sibling errors at the same indentation", func() {
			complex := bosherr.WrapError(bosherr.Error("inner a"), "outer a")
			err = bosherr.NewMultiError(complex, bosherr.Error("b"))
			Expect(MultilineError(err)).To(Equal("outer a:\n  inner a\nb"))
		})

		It("returns a multi-line message string with sibling errors at the same indentation", func() {
			complex := bosherr.WrapError(bosherr.Error("inner b"), "outer b")
			err = bosherr.NewMultiError(bosherr.Error("a"), complex)
			Expect(MultilineError(err)).To(Equal("a\nouter b:\n  inner b"))
		})
	})

	Context("when given a composite err with explainable errors", func() {
		It("returns a multi-line message string with sibling errors at the same indentation", func() {
			multi := bosherr.NewMultiError(bosherr.Error("inner a"), bosherr.Error("inner b"))
			err = bosherr.WrapError(multi, "outer omg")
			Expect(MultilineError(err)).To(Equal("outer omg:\n  inner a\n  inner b"))
		})
	})

	Context("when given an ExecError", func() {
		It("returns a multi-line message string with the command, stdout, & stderr at the same indentation", func() {
			execErr := boshsys.NewExecError("fake-cmd --flag with some args", "some\nmultiline\nstdout", "some\nmultiline\nstderr")
			err = bosherr.WrapError(execErr, "outer omg")
			Expect(MultilineError(err)).To(Equal("outer omg:\n  Error Executing Command:\n    fake-cmd --flag with some args\n  StdOut:\n    some\n    multiline\n    stdout\n  StdErr:\n    some\n    multiline\n    stderr"))
		})
	})
}
Пример #14
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)
}
Пример #15
0
func (r *reader) Read() (Release, error) {
	err := r.extractor.DecompressFileToDir(r.tarFilePath, r.extractedReleasePath, boshcmd.CompressorOptions{})
	if err != nil {
		return nil, bosherr.WrapError(err, "Extracting release")
	}

	releaseManifestPath := path.Join(r.extractedReleasePath, "release.MF")
	releaseManifestBytes, err := r.fs.ReadFile(releaseManifestPath)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Reading release manifest '%s'", releaseManifestPath)
	}

	var manifest birelmanifest.Manifest
	err = yaml.Unmarshal(releaseManifestBytes, &manifest)
	if err != nil {
		return nil, bosherr.WrapError(err, "Parsing release manifest")
	}

	release, err := r.newReleaseFromManifest(manifest)
	if err != nil {
		return nil, bosherr.WrapError(err, "Constructing release from manifest")
	}

	return release, nil
}
Пример #16
0
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
}
Пример #17
0
func (net UbuntuNetManager) writeNetworkInterfaces(dhcpConfigs DHCPInterfaceConfigurations, staticConfigs StaticInterfaceConfigurations, dnsServers []string) (bool, error) {
	sort.Stable(dhcpConfigs)
	sort.Stable(staticConfigs)

	networkInterfaceValues := networkInterfaceConfig{
		DHCPConfigs:       dhcpConfigs,
		StaticConfigs:     staticConfigs,
		HasDNSNameServers: true,
		DNSServers:        dnsServers,
	}

	buffer := bytes.NewBuffer([]byte{})

	t := template.Must(template.New("network-interfaces").Parse(networkInterfacesTemplate))

	err := t.Execute(buffer, networkInterfaceValues)
	if err != nil {
		return false, bosherr.WrapError(err, "Generating config from template")
	}

	changed, err := net.fs.ConvergeFileContents("/etc/network/interfaces", buffer.Bytes())
	if err != nil {
		return changed, bosherr.WrapError(err, "Writing to /etc/network/interfaces")
	}

	return changed, nil
}
Пример #18
0
func (ms httpMetadataService) getUserData() (UserDataContentsType, error) {
	var userData UserDataContentsType

	err := ms.ensureMinimalNetworkSetup()
	if err != nil {
		return userData, err
	}

	userDataURL := fmt.Sprintf("%s/latest/user-data", ms.metadataHost)
	userDataResp, err := http.Get(userDataURL)
	if err != nil {
		return userData, bosherr.WrapError(err, "Getting user data from url")
	}

	defer userDataResp.Body.Close()

	userDataBytes, err := ioutil.ReadAll(userDataResp.Body)
	if err != nil {
		return userData, bosherr.WrapError(err, "Reading user data response body")
	}

	err = json.Unmarshal(userDataBytes, &userData)
	if err != nil {
		return userData, bosherr.WrapError(err, "Unmarshalling user data")
	}

	return userData, nil
}
Пример #19
0
func (p linux) MigratePersistentDisk(fromMountPoint, toMountPoint string) (err error) {
	p.logger.Debug(logTag, "Migrating persistent disk %v to %v", fromMountPoint, toMountPoint)

	err = p.diskManager.GetMounter().RemountAsReadonly(fromMountPoint)
	if err != nil {
		err = bosherr.WrapError(err, "Remounting persistent disk as readonly")
		return
	}

	// Golang does not implement a file copy that would allow us to preserve dates...
	// So we have to shell out to tar to perform the copy instead of delegating to the FileSystem
	tarCopy := fmt.Sprintf("(tar -C %s -cf - .) | (tar -C %s -xpf -)", fromMountPoint, toMountPoint)
	_, _, _, err = p.cmdRunner.RunCommand("sh", "-c", tarCopy)
	if err != nil {
		err = bosherr.WrapError(err, "Copying files from old disk to new disk")
		return
	}

	_, err = p.diskManager.GetMounter().Unmount(fromMountPoint)
	if err != nil {
		err = bosherr.WrapError(err, "Unmounting old persistent disk")
		return
	}

	err = p.diskManager.GetMounter().Remount(toMountPoint, fromMountPoint)
	if err != nil {
		err = bosherr.WrapError(err, "Remounting new disk on original mountpoint")
	}
	return
}
Пример #20
0
func (r erbRenderer) Render(srcPath, dstPath string, context TemplateEvaluationContext) error {
	r.logger.Debug(r.logTag, "Rendering template %s", dstPath)

	tmpDir, err := r.fs.TempDir("erb-renderer")
	if err != nil {
		return bosherr.WrapError(err, "Creating temporary directory")
	}
	defer r.fs.RemoveAll(tmpDir)

	rendererScriptPath := filepath.Join(tmpDir, "erb-render.rb")
	err = r.writeRendererScript(rendererScriptPath)
	if err != nil {
		return err
	}

	contextPath := filepath.Join(tmpDir, "erb-context.json")
	err = r.writeContext(contextPath, context)
	if err != nil {
		return err
	}

	command := boshsys.Command{
		Name: "ruby",
		Args: []string{rendererScriptPath, contextPath, srcPath, dstPath},
	}

	_, _, _, err = r.runner.RunComplexCommand(command)
	if err != nil {
		return bosherr.WrapError(err, "Running ruby to render templates")
	}

	return nil
}
Пример #21
0
func (net centosNetManager) writeNetworkInterfaces(dhcpInterfaceConfigurations []DHCPInterfaceConfiguration, staticInterfaceConfigurations []StaticInterfaceConfiguration, dnsServers []string) (bool, error) {
	anyInterfaceChanged := false

	staticConfig := centosStaticIfcfg{}
	staticConfig.DNSServers = newDNSConfigs(dnsServers)
	staticTemplate := template.Must(template.New("ifcfg").Parse(centosStaticIfcfgTemplate))

	for i := range staticInterfaceConfigurations {
		staticConfig.StaticInterfaceConfiguration = &staticInterfaceConfigurations[i]

		changed, err := net.writeIfcfgFile(staticConfig.StaticInterfaceConfiguration.Name, staticTemplate, staticConfig)
		if err != nil {
			return false, bosherr.WrapError(err, "Writing static config")
		}

		anyInterfaceChanged = anyInterfaceChanged || changed
	}

	dhcpTemplate := template.Must(template.New("ifcfg").Parse(centosDHCPIfcfgTemplate))

	for i := range dhcpInterfaceConfigurations {
		config := &dhcpInterfaceConfigurations[i]

		changed, err := net.writeIfcfgFile(config.Name, dhcpTemplate, config)
		if err != nil {
			return false, bosherr.WrapError(err, "Writing dhcp config")
		}

		anyInterfaceChanged = anyInterfaceChanged || changed
	}

	return anyInterfaceChanged, nil
}
Пример #22
0
func (v *validator) Validate(release Release) error {
	errs := []error{}

	err := v.validateReleaseName(release)
	if err != nil {
		errs = append(errs, bosherr.WrapError(err, "Validating release name"))
	}

	err = v.validateReleaseVersion(release)
	if err != nil {
		errs = append(errs, bosherr.WrapError(err, "Validating release version"))
	}

	err = v.validateReleaseJobs(release)
	if err != nil {
		errs = append(errs, bosherr.WrapError(err, "Validating release jobs"))
	}

	err = v.validateReleasePackages(release)
	if err != nil {
		errs = append(errs, bosherr.WrapError(err, "Validating release packages"))
	}

	if len(errs) > 0 {
		return bosherr.NewMultiError(errs...)
	}

	return nil
}
Пример #23
0
func (v *deploymentRecord) IsDeployed(manifestPath string, releases []birel.Release, stemcell bistemcell.ExtractedStemcell) (bool, error) {
	manifestSHA1, found, err := v.deploymentRepo.FindCurrent()
	if err != nil {
		return false, bosherr.WrapError(err, "Finding sha1 of currently deployed manifest")
	}

	if !found {
		return false, nil
	}

	newSHA1, err := v.sha1Calculator.Calculate(manifestPath)
	if err != nil {
		return false, bosherr.WrapError(err, "Calculating sha1 of current deployment manifest")
	}

	if manifestSHA1 != newSHA1 {
		return false, nil
	}

	currentStemcell, found, err := v.stemcellRepo.FindCurrent()
	if err != nil {
		return false, bosherr.WrapError(err, "Finding currently deployed stemcell")
	}

	if !found {
		return false, nil
	}

	if currentStemcell.Name != stemcell.Manifest().Name || currentStemcell.Version != stemcell.Manifest().Version {
		return false, nil
	}

	currentReleaseRecords, err := v.releaseRepo.List()
	if err != nil {
		return false, bosherr.WrapError(err, "Finding currently deployed release")
	}

	if len(currentReleaseRecords) == 0 {
		return false, nil
	}

	if len(releases) != len(currentReleaseRecords) {
		return false, nil
	}

	for _, release := range releases {
		found := false
		for _, releaseRecord := range currentReleaseRecords {
			if releaseRecord.Name == release.Name() && releaseRecord.Version == release.Version() {
				found = true
				break
			}
		}
		if !found {
			return false, nil
		}
	}

	return true, nil
}
Пример #24
0
func (d *diskDeployer) Deploy(diskPool bideplmanifest.DiskPool, cloud bicloud.Cloud, vm VM, stage biui.Stage) ([]bidisk.Disk, error) {
	if diskPool.DiskSize == 0 {
		return []bidisk.Disk{}, nil
	}

	d.diskManager = d.diskManagerFactory.NewManager(cloud)
	disks, err := d.diskManager.FindCurrent()
	if err != nil {
		return disks, bosherr.WrapError(err, "Finding existing disk")
	}

	if len(disks) > 1 {
		return disks, bosherr.WrapError(err, "Multiple current disks not supported")

	} else if len(disks) == 1 {
		disks, err = d.deployExistingDisk(disks[0], diskPool, vm, stage)
		if err != nil {
			return disks, err
		}

	} else {
		disks, err = d.deployNewDisk(diskPool, vm, stage)
		if err != nil {
			return disks, err
		}
	}

	err = d.diskManager.DeleteUnused(stage)
	if err != nil {
		return disks, err
	}

	return disks, nil
}
Пример #25
0
func (r *reader) newReleaseFromManifest(releaseManifest birelmanifest.Manifest) (Release, error) {
	errors := []error{}
	packages, isCompiledRelease, err := r.newPackagesFromManifestPackages(releaseManifest)
	if err != nil {
		errors = append(errors, bosherr.WrapError(err, "Constructing packages from manifest"))
	}

	jobs, err := r.newJobsFromManifestJobs(packages, releaseManifest.Jobs)
	if err != nil {
		errors = append(errors, bosherr.WrapError(err, "Constructing jobs from manifest"))
	}

	if len(errors) > 0 {
		return nil, bosherr.NewMultiError(errors...)
	}

	release := &release{
		name:    releaseManifest.Name,
		version: releaseManifest.Version,

		jobs:     jobs,
		packages: packages,

		extractedPath: r.extractedReleasePath,
		fs:            r.fs,
		isCompiled:    isCompiledRelease,
	}

	return release, nil
}
Пример #26
0
func (s concreteService) Get() (vitals Vitals, err error) {
	var (
		loadStats boshstats.CPULoad
		cpuStats  boshstats.CPUStats
		memStats  boshstats.Usage
		swapStats boshstats.Usage
		diskStats DiskVitals
	)

	loadStats, err = s.statsCollector.GetCPULoad()
	if err != nil {
		err = bosherr.WrapError(err, "Getting CPU Load")
		return
	}

	cpuStats, err = s.statsCollector.GetCPUStats()
	if err != nil {
		err = bosherr.WrapError(err, "Getting CPU Stats")
		return
	}

	memStats, err = s.statsCollector.GetMemStats()
	if err != nil {
		err = bosherr.WrapError(err, "Getting Memory Stats")
		return
	}

	swapStats, err = s.statsCollector.GetSwapStats()
	if err != nil {
		err = bosherr.WrapError(err, "Getting Swap Stats")
		return
	}

	diskStats, err = s.getDiskStats()
	if err != nil {
		err = bosherr.WrapError(err, "Getting Disk Stats")
		return
	}

	vitals = Vitals{
		Load: []string{
			fmt.Sprintf("%.2f", loadStats.One),
			fmt.Sprintf("%.2f", loadStats.Five),
			fmt.Sprintf("%.2f", loadStats.Fifteen),
		},
		CPU: CPUVitals{
			User: cpuStats.UserPercent().FormatFractionOf100(1),
			Sys:  cpuStats.SysPercent().FormatFractionOf100(1),
			Wait: cpuStats.WaitPercent().FormatFractionOf100(1),
		},
		Mem:  createMemVitals(memStats),
		Swap: createMemVitals(swapStats),
		Disk: diskStats,
	}
	return
}
Пример #27
0
func (m *manager) Create(stemcell bistemcell.CloudStemcell, deploymentManifest bideplmanifest.Manifest) (VM, error) {
	jobName := deploymentManifest.JobName()
	networkInterfaces, err := deploymentManifest.NetworkInterfaces(jobName)
	m.logger.Debug(m.logTag, "Creating VM with network interfaces: %#v", networkInterfaces)
	if err != nil {
		return nil, bosherr.WrapError(err, "Getting network spec")
	}

	resourcePool, err := deploymentManifest.ResourcePool(jobName)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Getting resource pool for job '%s'", jobName)
	}

	agentID, err := m.uuidGenerator.Generate()
	if err != nil {
		return nil, bosherr.WrapError(err, "Generating agent ID")
	}

	cid, err := m.createAndRecordVm(agentID, stemcell, resourcePool, networkInterfaces)
	if err != nil {
		return nil, err
	}

	metadata := bicloud.VMMetadata{
		Deployment: deploymentManifest.Name,
		Job:        deploymentManifest.JobName(),
		Index:      "0",
		Director:   "bosh-init",
	}
	err = m.cloud.SetVMMetadata(cid, metadata)
	if err != nil {
		cloudErr, ok := err.(bicloud.Error)
		if ok && cloudErr.Type() == bicloud.NotImplementedError {
			//ignore it
		} else {
			return nil, bosherr.WrapErrorf(err, "Setting VM metadata to %s", metadata)
		}
	}

	vm := NewVM(
		cid,
		m.vmRepo,
		m.stemcellRepo,
		m.diskDeployer,
		m.agentClient,
		m.cloud,
		m.fs,
		m.logger,
	)

	return vm, nil
}
Пример #28
0
func (i *instance) UpdateDisks(deploymentManifest bideplmanifest.Manifest, stage biui.Stage) ([]bidisk.Disk, error) {
	diskPool, err := deploymentManifest.DiskPool(i.jobName)
	if err != nil {
		return []bidisk.Disk{}, bosherr.WrapError(err, "Getting disk pool")
	}

	disks, err := i.vm.UpdateDisks(diskPool, stage)
	if err != nil {
		return disks, bosherr.WrapError(err, "Updating disks")
	}

	return disks, nil
}
Пример #29
0
// Compile resolves and compiles all transitive dependencies of multiple release jobs
func (c *dependencyCompiler) Compile(releaseJobs []bireljob.Job, stage biui.Stage) ([]CompiledPackageRef, error) {
	compileOrderReleasePackages, err := c.resolveJobCompilationDependencies(releaseJobs)
	if err != nil {
		return nil, bosherr.WrapError(err, "Resolving job package dependencies")
	}

	compiledPackageRefs, err := c.compilePackages(compileOrderReleasePackages, stage)
	if err != nil {
		return nil, bosherr.WrapError(err, "Compiling job package dependencies")
	}

	return compiledPackageRefs, nil
}
Пример #30
0
func (r erbRenderer) writeContext(contextPath string, context TemplateEvaluationContext) error {
	contextBytes, err := json.Marshal(context)
	if err != nil {
		return bosherr.WrapError(err, "Marshalling context")
	}

	err = r.fs.WriteFileString(contextPath, string(contextBytes))
	if err != nil {
		return bosherr.WrapError(err, "Writing context")
	}

	return nil
}