Esempio n. 1
0
func (p linux) setupRunDir(sysDir string) error {
	runDir := filepath.Join(sysDir, "run")

	runDirIsMounted, err := p.IsMountPoint(runDir)
	if err != nil {
		return bosherr.WrapErrorf(err, "Checking for mount point %s", runDir)
	}

	if !runDirIsMounted {
		err = p.fs.MkdirAll(runDir, runDirPermissions)
		if err != nil {
			return bosherr.WrapErrorf(err, "Making %s dir", runDir)
		}

		err = p.diskManager.GetMounter().Mount("tmpfs", runDir, "-t", "tmpfs", "-o", "size=1m")
		if err != nil {
			return bosherr.WrapErrorf(err, "Mounting tmpfs to %s", runDir)
		}

		_, _, _, err = p.cmdRunner.RunCommand("chown", "root:vcap", runDir)
		if err != nil {
			return bosherr.WrapErrorf(err, "chown %s", runDir)
		}
	}

	return nil
}
Esempio n. 2
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
}
Esempio n. 3
0
func (p *parser) parseResourcePoolManifests(rawResourcePools []resourcePool, path string) ([]ResourcePool, error) {
	resourcePools := make([]ResourcePool, len(rawResourcePools), len(rawResourcePools))
	for i, rawResourcePool := range rawResourcePools {
		resourcePool := ResourcePool{
			Name:     rawResourcePool.Name,
			Network:  rawResourcePool.Network,
			Stemcell: StemcellRef(rawResourcePool.Stemcell),
		}

		cloudProperties, err := biproperty.BuildMap(rawResourcePool.CloudProperties)
		if err != nil {
			return resourcePools, bosherr.WrapErrorf(err, "Parsing resource_pool '%s' cloud_properties: %#v", rawResourcePool.Name, rawResourcePool.CloudProperties)
		}
		resourcePool.CloudProperties = cloudProperties

		env, err := biproperty.BuildMap(rawResourcePool.Env)
		if err != nil {
			return resourcePools, bosherr.WrapErrorf(err, "Parsing resource_pool '%s' env: %#v", rawResourcePool.Name, rawResourcePool.Env)
		}
		resourcePool.Env = env

		resourcePool.Stemcell.URL, err = biutil.AbsolutifyPath(path, resourcePool.Stemcell.URL, p.fs)
		if err != nil {
			return resourcePools, bosherr.WrapErrorf(err, "Resolving stemcell path '%s", resourcePool.Stemcell.URL)
		}

		resourcePools[i] = resourcePool
	}

	return resourcePools, nil
}
Esempio n. 4
0
func (p *parser) parseNetworkManifests(rawNetworks []network) ([]Network, error) {
	networks := make([]Network, len(rawNetworks), len(rawNetworks))
	for i, rawNetwork := range rawNetworks {
		network := Network{
			Name: rawNetwork.Name,
			Type: NetworkType(rawNetwork.Type),
			DNS:  rawNetwork.DNS,
		}

		cloudProperties, err := biproperty.BuildMap(rawNetwork.CloudProperties)
		if err != nil {
			return networks, bosherr.WrapErrorf(err, "Parsing network '%s' cloud_properties: %#v", rawNetwork.Name, rawNetwork.CloudProperties)
		}
		network.CloudProperties = cloudProperties

		for _, subnet := range rawNetwork.Subnets {
			cloudProperties, err := biproperty.BuildMap(subnet.CloudProperties)
			if err != nil {
				return networks, bosherr.WrapErrorf(err, "Parsing network subnet '%s' cloud_properties: %#v", rawNetwork.Name, subnet.CloudProperties)
			}

			network.Subnets = append(network.Subnets, Subnet{
				Range:           subnet.Range,
				Gateway:         subnet.Gateway,
				DNS:             subnet.DNS,
				CloudProperties: cloudProperties,
			})
		}

		networks[i] = network
	}

	return networks, nil
}
Esempio n. 5
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
}
Esempio n. 6
0
func (fs *osFileSystem) Symlink(oldPath, newPath string) error {
	fs.logger.Debug(fs.logTag, "Symlinking oldPath %s with newPath %s", oldPath, newPath)

	actualOldPath, err := filepath.EvalSymlinks(oldPath)
	if err != nil {
		return bosherr.WrapErrorf(err, "Evaluating symlinks for %s", oldPath)
	}

	existingTargetedPath, err := filepath.EvalSymlinks(newPath)
	if err == nil {
		if existingTargetedPath == actualOldPath {
			return nil
		}

		err = os.Remove(newPath)
		if err != nil {
			return bosherr.WrapErrorf(err, "Failed to delete symlimk at %s", newPath)
		}
	}

	containingDir := filepath.Dir(newPath)
	if !fs.FileExists(containingDir) {
		fs.MkdirAll(containingDir, os.FileMode(0700))
	}

	return os.Symlink(oldPath, newPath)
}
Esempio n. 7
0
func (b *blobstore) Add(sourcePath string) (string, error) {
	blobID, err := b.uuidGenerator.Generate()
	if err != nil {
		return "", bosherr.WrapError(err, "Generating Blob ID")
	}

	b.logger.Debug(b.logTag, "Uploading blob %s from %s", blobID, sourcePath)

	file, err := b.fs.OpenFile(sourcePath, os.O_RDONLY, 0)
	if err != nil {
		return "", bosherr.WrapErrorf(err, "Opening file for reading %s", sourcePath)
	}
	defer func() {
		if err := file.Close(); err != nil {
			b.logger.Warn(b.logTag, "Couldn't close source file: %s", err.Error())
		}
	}()

	fileInfo, err := file.Stat()
	if err != nil {
		return "", bosherr.WrapErrorf(err, "Getting fileInfo from %s", sourcePath)
	}

	err = b.davClient.Put(blobID, file, fileInfo.Size())
	if err != nil {
		return "", bosherr.WrapErrorf(err, "Putting file '%s' into blobstore (via DAVClient) as blobID '%s'", sourcePath, blobID)
	}

	return blobID, nil
}
Esempio n. 8
0
func (p sfdiskPartitioner) diskMatchesPartitions(devicePath string, partitionsToMatch []Partition) (result bool) {
	existingPartitions, err := p.getPartitions(devicePath)
	if err != nil {
		err = bosherr.WrapErrorf(err, "Getting partitions for %s", devicePath)
		return
	}

	if len(existingPartitions) < len(partitionsToMatch) {
		return
	}

	remainingDiskSpace, err := p.GetDeviceSizeInBytes(devicePath)
	if err != nil {
		err = bosherr.WrapErrorf(err, "Getting device size for %s", devicePath)
		return
	}

	for index, partitionToMatch := range partitionsToMatch {
		if index == len(partitionsToMatch)-1 {
			partitionToMatch.SizeInBytes = remainingDiskSpace
		}

		existingPartition := existingPartitions[index]
		switch {
		case existingPartition.Type != partitionToMatch.Type:
			return
		case !withinDelta(existingPartition.SizeInBytes, partitionToMatch.SizeInBytes, p.convertFromMbToBytes(20)):
			return
		}

		remainingDiskSpace = remainingDiskSpace - partitionToMatch.SizeInBytes
	}

	return true
}
func (s *fileSystemDeploymentStateService) Load() (DeploymentState, error) {
	if s.configPath == "" {
		panic("configPath not yet set!")
	}

	s.logger.Debug(s.logTag, "Loading deployment state: %s", s.configPath)

	deploymentState := &DeploymentState{}

	if s.fs.FileExists(s.configPath) {
		deploymentStateFileContents, err := s.fs.ReadFile(s.configPath)
		if err != nil {
			return DeploymentState{}, bosherr.WrapErrorf(err, "Reading deployment state file '%s'", s.configPath)
		}
		s.logger.Debug(s.logTag, "Deployment File Contents %#s", deploymentStateFileContents)

		err = json.Unmarshal(deploymentStateFileContents, deploymentState)
		if err != nil {
			return DeploymentState{}, bosherr.WrapErrorf(err, "Unmarshalling deployment state file '%s'", s.configPath)
		}
	}

	err := s.initDefaults(deploymentState)
	if err != nil {
		return DeploymentState{}, bosherr.WrapErrorf(err, "Initializing deployment state defaults")
	}

	return *deploymentState, nil
}
Esempio n. 10
0
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
}
Esempio n. 11
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
}
Esempio n. 12
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
}
Esempio n. 13
0
// Extract decompresses a release tarball into a temp directory (release.extractedPath),
// parses the release manifest, decompresses the packages and jobs, and validates the release.
// Use release.Delete() to clean up the temp directory.
func (e *extractor) Extract(releaseTarballPath string) (Release, error) {
	extractedReleasePath, err := e.fs.TempDir("bosh-init-release")
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Creating temp directory to extract release '%s'", releaseTarballPath)
	}

	e.logger.Info(e.logTag, "Extracting release tarball '%s' to '%s'", releaseTarballPath, extractedReleasePath)

	releaseReader := NewReader(releaseTarballPath, extractedReleasePath, e.fs, e.compressor)
	release, err := releaseReader.Read()
	if err != nil {
		if removeErr := e.fs.RemoveAll(extractedReleasePath); removeErr != nil {
			e.logger.Warn(e.logTag, "Failed to remove extracted release: %s", removeErr.Error())
		}
		return nil, bosherr.WrapErrorf(err, "Reading release from '%s'", releaseTarballPath)
	}

	err = e.validator.Validate(release)
	if err != nil {
		if removeErr := e.fs.RemoveAll(extractedReleasePath); removeErr != nil {
			e.logger.Warn(e.logTag, "Failed to remove extracted release: %s", removeErr.Error())
		}
		return nil, bosherr.WrapErrorf(err, "Validating release '%s-%s'", release.Name(), release.Version())
	}

	e.logger.Info(e.logTag, "Extracted release %s version %s", release.Name(), release.Version())

	return release, nil
}
Esempio n. 14
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
}
Esempio n. 15
0
func (p linux) SetupDataDir() error {
	dataDir := p.dirProvider.DataDir()

	sysDataDir := filepath.Join(dataDir, "sys")

	logDir := filepath.Join(sysDataDir, "log")
	err := p.fs.MkdirAll(logDir, logDirPermissions)
	if err != nil {
		return bosherr.WrapErrorf(err, "Making %s dir", logDir)
	}

	_, _, _, err = p.cmdRunner.RunCommand("chown", "root:vcap", sysDataDir)
	if err != nil {
		return bosherr.WrapErrorf(err, "chown %s", sysDataDir)
	}

	_, _, _, err = p.cmdRunner.RunCommand("chown", "root:vcap", logDir)
	if err != nil {
		return bosherr.WrapErrorf(err, "chown %s", logDir)
	}

	err = p.setupRunDir(sysDataDir)
	if err != nil {
		return err
	}

	sysDir := filepath.Join(filepath.Dir(dataDir), "sys")
	err = p.fs.Symlink(sysDataDir, sysDir)
	if err != nil {
		return bosherr.WrapErrorf(err, "Symlinking '%s' to '%s'", sysDir, sysDataDir)
	}

	return nil
}
Esempio n. 16
0
func (fs *osFileSystem) ConvergeFileContents(path string, content []byte) (bool, error) {
	if fs.filesAreIdentical(content, path) {
		fs.logger.Debug(fs.logTag, "Skipping writing %s because contents are identical", path)
		return false, nil
	}

	fs.logger.Debug(fs.logTag, "File %s will be overwritten", path)

	err := fs.MkdirAll(filepath.Dir(path), os.ModePerm)
	if err != nil {
		return true, bosherr.WrapErrorf(err, "Making dir for file %s", path)
	}

	file, err := os.Create(path)
	if err != nil {
		return true, bosherr.WrapErrorf(err, "Creating file %s", path)
	}

	defer file.Close()

	_, err = file.Write(content)
	if err != nil {
		return true, bosherr.WrapErrorf(err, "Writing content to file %s", path)
	}

	return true, nil
}
Esempio n. 17
0
func (e *extractor) Extract(blobID string, blobSHA1 string, targetDir string) error {
	// Retrieve a temp copy of blob
	filePath, err := e.blobstore.Get(blobID, blobSHA1)
	if err != nil {
		return bosherr.WrapErrorf(err, "Getting object from blobstore: %s", blobID)
	}
	// Clean up temp copy of blob
	defer e.cleanUpBlob(filePath)

	existed := e.fs.FileExists(targetDir)
	if !existed {
		err = e.fs.MkdirAll(targetDir, os.ModePerm)
		if err != nil {
			return bosherr.WrapErrorf(err, "Creating target dir: %s", targetDir)
		}
	}

	err = e.compressor.DecompressFileToDir(filePath, targetDir, boshcmd.CompressorOptions{})
	if err != nil {
		if !existed {
			// Clean up extracted contents of blob
			e.cleanUpFile(targetDir)
		}
		return bosherr.WrapErrorf(err, "Decompressing compiled package: BlobID: '%s', BlobSHA1: '%s'", blobID, blobSHA1)
	}
	return nil
}
Esempio n. 18
0
func (c sha1Calculator) Calculate(filePath string) (string, error) {
	file, err := c.fs.OpenFile(filePath, os.O_RDONLY, 0)
	if err != nil {
		return "", bosherr.WrapErrorf(err, "Calculating sha1 of '%s'", filePath)
	}
	defer file.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		return "", bosherr.WrapErrorf(err, "Opening file '%s' for sha1 calculation", filePath)
	}

	h := sha1.New()

	if fileInfo.IsDir() {
		c.fs.Walk(filePath+"/", func(path string, info os.FileInfo, err error) error {
			if !info.IsDir() {
				err := c.populateSha1(path, h)
				if err != nil {
					return bosherr.WrapErrorf(err, "Calculating directory SHA1 for %s", path)
				}
			}
			return nil
		})
	} else {
		err = c.populateSha1(filePath, h)
		if err != nil {
			return "", bosherr.WrapErrorf(err, "Calculating file SHA1 for %s", filePath)
		}
	}

	return fmt.Sprintf("%x", h.Sum(nil)), nil
}
Esempio n. 19
0
func (b *blobstore) Get(blobID string) (LocalBlob, error) {
	file, err := b.fs.TempFile("bosh-init-local-blob")
	destinationPath := file.Name()
	err = file.Close()
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Closing new temp file '%s'", destinationPath)
	}

	b.logger.Debug(b.logTag, "Downloading blob %s to %s", blobID, destinationPath)

	readCloser, err := b.davClient.Get(blobID)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Getting blob %s from blobstore", blobID)
	}
	defer func() {
		if err = readCloser.Close(); err != nil {
			b.logger.Warn(b.logTag, "Couldn't close davClient.Get reader: %s", err.Error())
		}
	}()

	targetFile, err := b.fs.OpenFile(destinationPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Opening file for blob at %s", destinationPath)
	}

	_, err = io.Copy(targetFile, readCloser)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Saving blob to %s", destinationPath)
	}

	return NewLocalBlob(destinationPath, b.fs, b.logger), nil
}
Esempio n. 20
0
func (net centosNetManager) writeDHCPConfiguration(dnsServers []string, dhcpInterfaceConfigurations []DHCPInterfaceConfiguration) (bool, error) {
	buffer := bytes.NewBuffer([]byte{})
	t := template.Must(template.New("dhcp-config").Parse(centosDHCPConfigTemplate))

	// Keep DNS servers in the order specified by the network
	// because they are added by a *single* DHCP's prepend command
	dnsServersList := strings.Join(dnsServers, ", ")
	err := t.Execute(buffer, dnsServersList)
	if err != nil {
		return false, bosherr.WrapError(err, "Generating config from template")
	}
	dhclientConfigFile := "/etc/dhcp/dhclient.conf"
	changed, err := net.fs.ConvergeFileContents(dhclientConfigFile, buffer.Bytes())

	if err != nil {
		return changed, bosherr.WrapErrorf(err, "Writing to %s", dhclientConfigFile)
	}

	for i := range dhcpInterfaceConfigurations {
		name := dhcpInterfaceConfigurations[i].Name
		interfaceDhclientConfigFile := filepath.Join("/etc/dhcp/", "dhclient-"+name+".conf")
		err = net.fs.Symlink(dhclientConfigFile, interfaceDhclientConfigFile)
		if err != nil {
			return changed, bosherr.WrapErrorf(err, "Symlinking '%s' to '%s'", interfaceDhclientConfigFile, dhclientConfigFile)
		}
	}

	return changed, nil
}
func (y ReleaseSetAndInstallationManifestParser) ReleaseSetAndInstallationManifest(deploymentManifestPath string) (birelsetmanifest.Manifest, biinstallmanifest.Manifest, error) {
	releaseSetManifest, err := y.ReleaseSetParser.Parse(deploymentManifestPath)
	if err != nil {
		return birelsetmanifest.Manifest{}, biinstallmanifest.Manifest{}, bosherr.WrapErrorf(err, "Parsing release set manifest '%s'", deploymentManifestPath)
	}

	installationManifest, err := y.InstallationParser.Parse(deploymentManifestPath, releaseSetManifest)
	if err != nil {
		return birelsetmanifest.Manifest{}, biinstallmanifest.Manifest{}, bosherr.WrapErrorf(err, "Parsing installation manifest '%s'", deploymentManifestPath)
	}
	return releaseSetManifest, installationManifest, nil
}
Esempio n. 22
0
func (r *jobRenderer) renderFile(sourcePath, destinationPath string, context bierbrenderer.TemplateEvaluationContext) error {
	err := r.fs.MkdirAll(filepath.Dir(destinationPath), os.ModePerm)
	if err != nil {
		return bosherr.WrapErrorf(err, "Creating tempdir '%s'", filepath.Dir(destinationPath))
	}

	err = r.erbRenderer.Render(sourcePath, destinationPath, context)
	if err != nil {
		return bosherr.WrapErrorf(err, "Rendering template src: %s, dst: %s", sourcePath, destinationPath)
	}
	return nil
}
Esempio n. 23
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
}
Esempio n. 24
0
func (m linuxMounter) Remount(fromMountPoint, toMountPoint string, mountOptions ...string) error {
	partitionPath, found, err := m.findDeviceMatchingMountPoint(fromMountPoint)
	if err != nil || !found {
		return bosherr.WrapErrorf(err, "Error finding device for mount point %s", fromMountPoint)
	}

	_, err = m.Unmount(fromMountPoint)
	if err != nil {
		return bosherr.WrapErrorf(err, "Unmounting %s", fromMountPoint)
	}

	return m.Mount(partitionPath, toMountPoint, mountOptions...)
}
Esempio n. 25
0
func (p linux) changeTmpDirPermissions(path string) error {
	_, _, _, err := p.cmdRunner.RunCommand("chown", "root:vcap", path)
	if err != nil {
		return bosherr.WrapErrorf(err, "chown %s", path)
	}

	_, _, _, err = p.cmdRunner.RunCommand("chmod", "0770", path)
	if err != nil {
		return bosherr.WrapErrorf(err, "chmod %s", path)
	}

	return nil
}
Esempio n. 26
0
// TerminateNicely can be called multiple times simultaneously from different goroutines
func (p *execProcess) TerminateNicely(killGracePeriod time.Duration) error {
	// Make sure process is being waited on for process state reaping to occur
	// as to avoid forcibly killing the process after killGracePeriod
	if p.waitCh == nil {
		panic("TerminateNicely() must be called after Wait()")
	}

	err := p.signalGroup(syscall.SIGTERM)
	if err != nil {
		return bosherr.WrapErrorf(err, "Sending SIGTERM to process group %d", p.pid)
	}

	terminatedCh := make(chan struct{})
	stopCheckingTerminatedCh := make(chan struct{})

	go func() {
		for p.groupExists() {
			select {
			case <-time.After(500 * time.Millisecond):
				// nothing to do
			case <-stopCheckingTerminatedCh:
				return
			}
		}

		close(terminatedCh)
	}()

	select {
	case <-terminatedCh:
		// nothing to do

	case <-time.After(killGracePeriod):
		close(stopCheckingTerminatedCh)

		err = p.signalGroup(syscall.SIGKILL)
		if err != nil {
			return bosherr.WrapErrorf(err, "Sending SIGKILL to process group %d", p.pid)
		}
	}

	// It takes some time for the process to disappear
	for i := 0; i < 20; i++ {
		if !p.groupExists() {
			return nil
		}
		time.Sleep(500 * time.Millisecond)
	}

	return bosherr.Errorf("Failed to kill process after grace timeout (PID %d)", p.pid)
}
Esempio n. 27
0
func (c *cache) Save(sourcePath string, source Source) error {
	err := c.fs.MkdirAll(c.basePath, os.FileMode(0766))
	if err != nil {
		return bosherr.WrapErrorf(err, "Failed to create cache directory '%s'", c.basePath)
	}

	err = c.fs.Rename(sourcePath, c.Path(source))
	if err != nil {
		return bosherr.WrapErrorf(err, "Failed to save tarball path '%s' in cache", sourcePath)
	}

	c.logger.Debug(c.logTag, "Saving tarball in cache at: '%s'", c.Path(source))
	return nil
}
Esempio n. 28
0
func (fs *osFileSystem) listDirContents(dirPath string) ([]os.FileInfo, error) {
	directory, err := os.Open(dirPath)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Openning dir '%s' for reading", dirPath)
	}
	defer directory.Close()

	files, err := directory.Readdir(-1)
	if err != nil {
		return nil, bosherr.WrapErrorf(err, "Reading dir '%s' contents", dirPath)
	}

	return files, nil
}
Esempio n. 29
0
func (p *parser) Parse(path string, releaseSetManifest birelsetmanifest.Manifest) (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 installation manifest")
	}
	p.logger.Debug(p.logTag, "Parsed installation manifest: %#v", comboManifest)

	if comboManifest.CloudProvider.SSHTunnel.PrivateKey != "" {
		comboManifest.CloudProvider.SSHTunnel.PrivateKey, err = biutil.AbsolutifyPath(path, comboManifest.CloudProvider.SSHTunnel.PrivateKey, p.fs)
		if err != nil {
			return Manifest{}, bosherr.WrapErrorf(err, "Expanding private_key path")
		}
	}

	installationManifest := Manifest{
		Name: comboManifest.Name,
		Template: ReleaseJobRef{
			Name:    comboManifest.CloudProvider.Template.Name,
			Release: comboManifest.CloudProvider.Template.Release,
		},
		Mbus: comboManifest.CloudProvider.Mbus,
	}

	properties, err := biproperty.BuildMap(comboManifest.CloudProvider.Properties)
	if err != nil {
		return Manifest{}, bosherr.WrapErrorf(err, "Parsing cloud_provider manifest properties: %#v", comboManifest.CloudProvider.Properties)
	}
	installationManifest.Properties = properties

	if comboManifest.CloudProvider.HasSSHTunnel() {
		password, err := p.uuidGenerator.Generate()
		if err != nil {
			return Manifest{}, bosherr.WrapError(err, "Generating registry password")
		}
		installationManifest.PopulateRegistry("registry", password, "127.0.0.1", 6901, comboManifest.CloudProvider.SSHTunnel)
	}

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

	return installationManifest, nil
}
Esempio n. 30
0
func (e *extractor) ChmodExecutables(binGlob string) error {
	files, err := e.fs.Glob(binGlob)
	if err != nil {
		return bosherr.WrapErrorf(err, "Globbing %s", binGlob)
	}

	for _, file := range files {
		err = e.fs.Chmod(file, os.FileMode(0755))
		if err != nil {
			return bosherr.WrapErrorf(err, "Making '%s' executable in '%s'", file, binGlob)
		}
	}
	return nil
}