// 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 }
func (vm SoftLayerVM) getAllowedHostCredential(virtualGuest datatypes.SoftLayer_Virtual_Guest) (AllowedHostCredential, error) { virtualGuestService, err := vm.softLayerClient.GetSoftLayer_Virtual_Guest_Service() if err != nil { return AllowedHostCredential{}, bosherr.WrapError(err, "Cannot get softlayer virtual guest service.") } allowedHost, err := virtualGuestService.GetAllowedHost(virtualGuest.Id) if err != nil { return AllowedHostCredential{}, bosherr.WrapErrorf(err, "Cannot get allowed host with instance id: %d", virtualGuest.Id) } if allowedHost.Id == 0 { return AllowedHostCredential{}, bosherr.Errorf("Cannot get allowed host with instance id: %d", virtualGuest.Id) } allowedHostService, err := vm.softLayerClient.GetSoftLayer_Network_Storage_Allowed_Host_Service() if err != nil { return AllowedHostCredential{}, bosherr.WrapError(err, "Cannot get network storage allowed host service.") } credential, err := allowedHostService.GetCredential(allowedHost.Id) if err != nil { return AllowedHostCredential{}, bosherr.WrapErrorf(err, "Cannot get credential with allowed host id: %d", allowedHost.Id) } return AllowedHostCredential{ Iqn: allowedHost.Name, Username: credential.Username, Password: credential.Password, }, nil }
func (p partedPartitioner) 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 }
func (s *systemInterfaceAddrs) Get() ([]InterfaceAddress, error) { ifaces, err := net.Interfaces() if err != nil { return []InterfaceAddress{}, bosherr.WrapError(err, "Getting network interfaces") } interfaceAddrs := []InterfaceAddress{} for _, iface := range ifaces { addrs, err := iface.Addrs() if err != nil { return []InterfaceAddress{}, bosherr.WrapErrorf(err, "Getting addresses of interface '%s'", iface.Name) } for _, addr := range addrs { ip, _, err := net.ParseCIDR(addr.String()) if err != nil { return []InterfaceAddress{}, bosherr.WrapErrorf(err, "Parsing addresses of interface '%s'", iface.Name) } if ipv4 := ip.To4(); ipv4 != nil { interfaceAddrs = append(interfaceAddrs, NewSimpleInterfaceAddress(iface.Name, ipv4.String())) } } } return interfaceAddrs, nil }
func (fs *osFileSystem) Symlink(oldPath, newPath string) error { fs.logger.Debug(fs.logTag, "Symlinking oldPath %s with newPath %s", oldPath, newPath) if fi, err := os.Lstat(newPath); err == nil { if fi.Mode()&os.ModeSymlink != 0 { // Symlink new, err := os.Readlink(newPath) if err != nil { return bosherr.WrapErrorf(err, "Reading link for %s", newPath) } if filepath.Clean(oldPath) == filepath.Clean(new) { return nil } } if err := os.Remove(newPath); err != nil { return bosherr.WrapErrorf(err, "Removing new path at %s", newPath) } } containingDir := filepath.Dir(newPath) if !fs.FileExists(containingDir) { fs.MkdirAll(containingDir, os.FileMode(0700)) } return symlink(oldPath, newPath) }
func (tc ConcreteTemplatesCompiler) buildJobReaders(job bpdep.Job) ([]jobReader, error) { var readers []jobReader for _, template := range job.Templates { rec, found, err := tc.tplToJobRepo.FindByTemplate(template) if err != nil { return readers, bosherr.WrapErrorf(err, "Finding dep-template -> release-job record %s", template.Name) } else if !found { return readers, bosherr.Errorf("Expected to find dep-template -> release-job record %s", template.Name) } jobRec, found, err := tc.jobsRepo.FindByReleaseJob(rec) if err != nil { return readers, bosherr.WrapErrorf(err, "Finding job source blob %s", template.Name) } else if !found { return readers, bosherr.Errorf("Expected to find job source blob %s -- %s", template.Name, rec) } jobURL := fmt.Sprintf("blobstore:///%s?fingerprint=%s", jobRec.BlobID, jobRec.SHA1) reader := jobReader{ rec: rec, tarReader: tc.jobReaderFactory.NewReader(jobURL), } readers = append(readers, reader) } return readers, nil }
func (p linux) setupRunDir(sysDir string) error { runDir := path.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 (s registryAgentEnvService) Update(agentEnv AgentEnv) error { settingsJSON, err := json.Marshal(agentEnv) if err != nil { return bosherr.WrapError(err, "Marshalling agent env") } s.logger.Debug(s.logTag, "Updating registry endpoint '%s' with agent env: '%s'", s.endpoint, settingsJSON) putPayload := bytes.NewReader(settingsJSON) request, err := http.NewRequest("PUT", s.endpoint, putPayload) if err != nil { return bosherr.WrapErrorf(err, "Creating PUT request to update registry at '%s' with settings '%s'", s.endpoint, settingsJSON) } httpClient := http.Client{} httpResponse, err := httpClient.Do(request) if err != nil { return bosherr.WrapErrorf(err, "Updating registry endpoint '%s' with settings: '%s'", s.endpoint, settingsJSON) } defer httpResponse.Body.Close() if httpResponse.StatusCode != http.StatusOK && httpResponse.StatusCode != http.StatusCreated { return bosherr.Errorf("Received non-2xx status code when contacting registry: '%d'", httpResponse.StatusCode) } return nil }
func (a SyncDNS) Run(blobID, sha1 string) (string, error) { fileName, err := a.blobstore.Get(blobID, sha1) if err != nil { return "", bosherr.WrapErrorf(err, "Getting %s from blobstore", blobID) } fs := a.platform.GetFs() contents, err := fs.ReadFile(fileName) if err != nil { return "", bosherr.WrapErrorf(err, "Reading fileName %s from blobstore", fileName) } err = fs.RemoveAll(fileName) if err != nil { a.logger.Info(a.logTag, fmt.Sprintf("Failed to remove dns blob file at path '%s'", fileName)) } dnsRecords := boshsettings.DNSRecords{} err = json.Unmarshal(contents, &dnsRecords) if err != nil { return "", bosherr.WrapError(err, "Unmarshalling DNS records") } err = a.platform.SaveDNSRecords(dnsRecords, a.settingsService.GetSettings().AgentID) if err != nil { return "", bosherr.WrapError(err, "Saving DNS records in platform") } return "synced", nil }
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 (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 (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 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 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 (ms httpMetadataService) getUserData() (UserDataContentsType, error) { var userData UserDataContentsType err := ms.ensureMinimalNetworkSetup() if err != nil { return userData, err } userDataURL := fmt.Sprintf("%s%s", ms.metadataHost, ms.userdataPath) userDataResp, err := ms.doGet(userDataURL) if err != nil { return userData, bosherr.WrapErrorf(err, "Getting user data from url %s", userDataURL) } defer func() { if err := userDataResp.Body.Close(); err != nil { ms.logger.Warn(ms.logTag, "Failed to close response body when getting user data: %s", err.Error()) } }() 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.WrapErrorf(err, "Unmarshalling user data '%s'", string(userDataBytes)) } return userData, 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 (fs *osFileSystem) Symlink(oldPath, newPath string) error { fs.logger.Debug(fs.logTag, "Symlinking oldPath %s with newPath %s", oldPath, newPath) source, target, err := fs.symlinkPaths(oldPath, newPath) if err != nil { bosherr.WrapErrorf(err, "Getting absolute paths for target and path links: %s %s", oldPath, newPath) } if fi, err := fs.Lstat(target); err == nil { if fi.Mode()&os.ModeSymlink != 0 { // Symlink new, err := fs.Readlink(target) if err != nil { return bosherr.WrapErrorf(err, "Reading link for %s", target) } if filepath.Clean(source) == filepath.Clean(new) { return nil } } if err := fs.RemoveAll(target); err != nil { return bosherr.WrapErrorf(err, "Removing new path at %s", target) } } containingDir := filepath.Dir(target) if !fs.FileExists(containingDir) { fs.MkdirAll(containingDir, os.FileMode(0700)) } return fsWrapper.Symlink(source, target) }
func (p linux) SetupDataDir() error { dataDir := p.dirProvider.DataDir() sysDataDir := path.Join(dataDir, "sys") logDir := path.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 := path.Join(path.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 NewWatchTimeFromString(str string) (WatchTime, error) { var watchTime WatchTime parts := strings.Split(str, "-") if len(parts) != 2 { return watchTime, bosherr.Errorf("Invalid watch time range %s", str) } min, 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]) } max, 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 max < min { return watchTime, bosherr.Errorf( "Watch time must have maximum greater than or equal minimum %s", str) } watchTime[0], watchTime[1] = min, max return watchTime, nil }
func (v SyntaxValidator) Validate() error { if v.release.Name == "" { return bosherr.Error("Missing release name") } if v.release.Version == "" { return bosherr.Error("Missing release version") } if v.release.CommitHash == "" { return bosherr.Error("Missing release commit_hash") } for i, job := range v.release.Jobs { err := v.validateJob(&v.release.Jobs[i]) if err != nil { return bosherr.WrapErrorf(err, "Job %s (%d)", job.Name, i) } } for i, pkg := range v.release.Packages { err := v.validatePkg(&v.release.Packages[i]) if err != nil { return bosherr.WrapErrorf(err, "Package %s (%d)", pkg.Name, i) } } return nil }
func (g *renderer) Render(input bftinput.Input, manifestPath string, cloudConfigPath string) error { deploymentTemplate := template.Must(template.New("deployment").Parse(DeploymentTemplate)) buffer := bytes.NewBuffer([]byte{}) err := deploymentTemplate.Execute(buffer, input) if err != nil { return bosherr.WrapErrorf(err, "Generating deployment manifest") } err = g.fs.WriteFile(manifestPath, buffer.Bytes()) if err != nil { return bosherr.WrapErrorf(err, "Saving generated manifest") } cloudTemplate := template.Must(template.New("cloud-config").Parse(CloudTemplate)) buffer = bytes.NewBuffer([]byte{}) err = cloudTemplate.Execute(buffer, input) if err != nil { return bosherr.WrapErrorf(err, "Generating cloud config") } err = g.fs.WriteFile(cloudConfigPath, buffer.Bytes()) if err != nil { return bosherr.WrapErrorf(err, "Saving generated cloud config") } 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 (a AttachDisk) Run(vmCID VMCID, diskCID DiskCID) (interface{}, error) { vm, found, err := a.vmFinder.Find(vmCID.Int()) if err != nil { return nil, bosherr.WrapErrorf(err, "Finding VM '%s'", vmCID) } if !found { return nil, bosherr.Errorf("Expected to find VM '%s'", vmCID) } disk, found, err := a.diskFinder.Find(diskCID.Int()) if err != nil { return nil, bosherr.WrapErrorf(err, "Finding disk '%s'", diskCID) } if !found { return nil, bosherr.Errorf("Expected to find disk '%s'", diskCID) } err = vm.AttachDisk(disk) if err != nil { return nil, bosherr.WrapErrorf(err, "Attaching disk '%s' to VM '%s'", diskCID, vmCID) } return nil, 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 }
// 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 (vm SoftLayerVM) SetMetadata(vmMetadata VMMetadata) error { tags, err := vm.extractTagsFromVMMetadata(vmMetadata) if err != nil { return err } if len(tags) == 0 { return nil } //Check below needed since Golang strings.Split return [""] on strings.Split("", ",") if len(tags) == 1 && tags[0] == "" { return nil } virtualGuestService, err := vm.softLayerClient.GetSoftLayer_Virtual_Guest_Service() if err != nil { return bosherr.WrapError(err, "Creating SoftLayer VirtualGuestService from client") } success, err := virtualGuestService.SetTags(vm.ID(), tags) if !success { return bosherr.WrapErrorf(err, "Settings tags on SoftLayer VirtualGuest `%d`", vm.ID()) } if err != nil { return bosherr.WrapErrorf(err, "Settings tags on SoftLayer VirtualGuest `%d`", vm.ID()) } return 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 (s JobState) buildPackageSpecs() (map[string]boshas.PackageSpec, error) { specs := map[string]boshas.PackageSpec{} for _, template := range s.depJob.Templates { pkgs, err := s.templatesCompiler.FindPackages(template) if err != nil { return specs, bosherr.WrapErrorf(err, "Finding packages for template %s", template.Name) } for _, pkg := range pkgs { rec, err := s.packagesCompiler.FindCompiledPackage(pkg) if err != nil { return specs, bosherr.WrapErrorf(err, "Finding compiled package %s", pkg.Name) } specs[pkg.Name] = boshas.PackageSpec{ Name: pkg.Name, Version: pkg.Version, Sha1: rec.SHA1, BlobstoreID: rec.BlobID, } } } return specs, 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 }