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 }
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 }
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 }
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 }
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 }
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) }
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 }
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 }
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 }
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 }
// 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 }
// 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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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...) }
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 }
// 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) }
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 }
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 }
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 }
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 }