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") }
func (f SettingsSourceFactory) buildWithoutRegistry() (boshsettings.Source, error) { var settingsSources []boshsettings.Source for _, opts := range f.options.Sources { var settingsSource boshsettings.Source switch typedOpts := opts.(type) { case HTTPSourceOptions: return nil, bosherr.Error("HTTP source is not supported without registry") case ConfigDriveSourceOptions: settingsSource = NewConfigDriveSettingsSource( typedOpts.DiskPaths, typedOpts.MetaDataPath, typedOpts.SettingsPath, f.platform, f.logger, ) case FileSourceOptions: return nil, bosherr.Error("File source is not supported without registry") case CDROMSourceOptions: settingsSource = NewCDROMSettingsSource( typedOpts.FileName, f.platform, f.logger, ) } settingsSources = append(settingsSources, settingsSource) } return NewMultiSettingsSource(settingsSources...) }
func (r defaultNetworkResolver) GetDefaultNetwork() (boshsettings.Network, error) { network := boshsettings.Network{} routes, err := r.routesSearcher.SearchRoutes() if err != nil { return network, bosherr.WrapError(err, "Searching routes") } if len(routes) == 0 { return network, bosherr.Error("No routes found") } for _, route := range routes { if !route.IsDefault() { continue } ip, err := r.ipResolver.GetPrimaryIPv4(route.InterfaceName) if err != nil { return network, bosherr.WrapErrorf(err, "Getting primary IPv4 for interface '%s'", route.InterfaceName) } return boshsettings.Network{ IP: ip.IP.String(), Netmask: gonet.IP(ip.Mask).String(), Gateway: route.Gateway, }, nil } return network, bosherr.Error("Failed to find default route") }
func (b localBlobstore) Validate() error { path, found := b.options["blobstore_path"] if !found { return bosherr.Error("missing blobstore_path") } _, ok := path.(string) if !ok { return bosherr.Error("blobstore_path must be a string") } return nil }
func (b retryableBlobstore) Validate() error { if b.maxTries < 1 { return bosherr.Error("Max tries must be > 0") } return b.blobstore.Validate() }
// compilePackages compiles the specified packages, in the order specified, uploads them to the Blobstore, and returns the blob references func (c *dependencyCompiler) compilePackages(requiredPackages []*birelpkg.Package, stage biui.Stage) ([]CompiledPackageRef, error) { packageRefs := make([]CompiledPackageRef, 0, len(requiredPackages)) for _, pkg := range requiredPackages { stepName := fmt.Sprintf("Compiling package '%s/%s'", pkg.Name, pkg.Fingerprint) err := stage.Perform(stepName, func() error { compiledPackageRecord, isAlreadyCompiled, err := c.packageCompiler.Compile(pkg) if err != nil { return err } packageRef := CompiledPackageRef{ Name: pkg.Name, Version: pkg.Fingerprint, BlobstoreID: compiledPackageRecord.BlobID, SHA1: compiledPackageRecord.BlobSHA1, } packageRefs = append(packageRefs, packageRef) if isAlreadyCompiled { return biui.NewSkipStageError(bosherr.Error(fmt.Sprintf("Package '%s' is already compiled. Skipped compilation", pkg.Name)), "Package already compiled") } return nil }) if err != nil { return nil, err } } return packageRefs, nil }
func (ms *configDriveMetadataService) GetInstanceID() (string, error) { if ms.metaDataContents.InstanceID == "" { return "", bosherr.Error("Failed to load instance-id from config drive metadata service") } ms.logger.Debug(ms.logTag, "Getting instance id: %s", ms.metaDataContents.InstanceID) return ms.metaDataContents.InstanceID, nil }
func (ms *configDriveMetadataService) GetServerName() (string, error) { if ms.userDataContents.Server.Name == "" { return "", bosherr.Error("Failed to load server name from config drive metadata service") } ms.logger.Debug(ms.logTag, "Getting server name: %s", ms.userDataContents.Server.Name) return ms.userDataContents.Server.Name, nil }
func NewMultiSettingsSource(sources ...boshsettings.Source) (boshsettings.Source, error) { var err error if len(sources) == 0 { err = bosherr.Error("MultiSettingsSource requires to have at least one source") } return &MultiSettingsSource{sources: sources}, err }
func (ms *configDriveMetadataService) GetPublicKey() (string, error) { if firstPublicKey, ok := ms.metaDataContents.PublicKeys["0"]; ok { if openSSHKey, ok := firstPublicKey["openssh-key"]; ok { return openSSHKey, nil } } return "", bosherr.Error("Failed to load openssh-key from config drive metadata service") }
func (udev ConcreteUdevDevice) Trigger() (err error) { udev.logger.Debug(udev.logtag, "Triggering UdevDevice") switch { case udev.runner.CommandExists("udevadm"): _, _, _, err = udev.runner.RunCommand("udevadm", "trigger") case udev.runner.CommandExists("udevtrigger"): _, _, _, err = udev.runner.RunCommand("udevtrigger") default: err = bosherr.Error("can not find udevadm or udevtrigger commands") } return }
func (s *server) Stop() error { if s.listener == nil { return bosherr.Error("Stopping not-started registry server") } s.logger.Debug(s.logTag, "Stopping registry server") err := s.listener.Close() if err != nil { return bosherr.WrapError(err, "Stopping registry server") } return nil }
func (i *installation) StopRegistry() error { if !i.manifest.Registry.IsEmpty() { if i.registryServer == nil { return bosherr.Error("Registry must be started before it can be stopped") } err := i.registryServer.Stop() if err != nil { return bosherr.WrapError(err, "Stopping registry") } i.registryServer = nil } return nil }
func (i *installation) StartRegistry() error { if !i.manifest.Registry.IsEmpty() { if i.registryServer != nil { return bosherr.Error("Registry already started") } config := i.manifest.Registry registryServer, err := i.registryServerManager.Start(config.Username, config.Password, config.Host, config.Port) if err != nil { return bosherr.WrapError(err, "Starting registry") } i.registryServer = registryServer } return nil }
func (ms httpMetadataService) GetServerName() (string, error) { userData, err := ms.getUserData() if err != nil { return "", bosherr.WrapError(err, "Getting user data") } serverName := userData.Server.Name if len(serverName) == 0 { return "", bosherr.Error("Empty server name") } return serverName, nil }
func (v *validator) Validate(manifest Manifest, releaseSetManifest birelsetmanifest.Manifest) error { errs := []error{} cpiJobName := manifest.Template.Name if v.isBlank(cpiJobName) { errs = append(errs, bosherr.Error("cloud_provider.template.name must be provided")) } cpiReleaseName := manifest.Template.Release if v.isBlank(cpiReleaseName) { errs = append(errs, bosherr.Error("cloud_provider.template.release must be provided")) } _, found := releaseSetManifest.FindByName(cpiReleaseName) if !found { errs = append(errs, bosherr.Errorf("cloud_provider.template.release '%s' must refer to a release in releases", cpiReleaseName)) } if len(errs) > 0 { return bosherr.NewMultiError(errs...) } return nil }
func (b *jobRenderer) RenderAndUploadFrom(installationManifest biinstallmanifest.Manifest, jobs []bireljob.Job, stage biui.Stage) ([]RenderedJobRef, error) { // installation jobs do not get rendered with global deployment properties, only the cloud_provider properties globalProperties := biproperty.Map{} jobProperties := installationManifest.Properties renderedJobRefs, err := b.renderJobTemplates(jobs, jobProperties, globalProperties, installationManifest.Name, stage) if err != nil { return nil, bosherr.WrapError(err, "Rendering job templates for installation") } if len(renderedJobRefs) != 1 { return nil, bosherr.Error("Too many jobs rendered... oops?") } return renderedJobRefs, nil }
func (d *diskDeployer) updateCurrentDiskRecord(disk bidisk.Disk) error { savedDiskRecord, found, err := d.diskRepo.Find(disk.CID()) if err != nil { return bosherr.WrapError(err, "Finding disk record") } if !found { return bosherr.Error("Failed to find disk record for new disk") } err = d.diskRepo.UpdateCurrent(savedDiskRecord.ID) if err != nil { return bosherr.WrapError(err, "Updating current disk record") } return nil }
func (s *cloudStemcell) PromoteAsCurrent() error { stemcellRecord, found, err := s.repo.Find(s.name, s.version) if err != nil { return bosherr.WrapError(err, "Finding current stemcell") } if !found { return bosherr.Error("Stemcell does not exist in repo") } err = s.repo.UpdateCurrent(stemcellRecord.ID) if err != nil { return bosherr.WrapError(err, "Updating current stemcell") } return nil }
func (f SettingsSourceFactory) buildWithRegistry() (boshsettings.Source, error) { var metadataServices []MetadataService digDNSResolver := NewDigDNSResolver(f.platform.GetRunner(), f.logger) resolver := NewRegistryEndpointResolver(digDNSResolver) for _, opts := range f.options.Sources { var metadataService MetadataService switch typedOpts := opts.(type) { case HTTPSourceOptions: metadataService = NewHTTPMetadataService(typedOpts.URI, resolver, f.platform, f.logger) case ConfigDriveSourceOptions: metadataService = NewConfigDriveMetadataService( resolver, f.platform, typedOpts.DiskPaths, typedOpts.MetaDataPath, typedOpts.UserDataPath, f.logger, ) case FileSourceOptions: metadataService = NewFileMetadataService( typedOpts.MetaDataPath, typedOpts.UserDataPath, typedOpts.SettingsPath, f.platform.GetFs(), f.logger, ) case CDROMSourceOptions: return nil, bosherr.Error("CDROM source is not supported when registry is used") } metadataServices = append(metadataServices, metadataService) } metadataService := NewMultiSourceMetadataService(metadataServices...) registryProvider := NewRegistryProvider(metadataService, f.platform, f.options.UseServerName, f.platform.GetFs(), f.logger) settingsSource := NewComplexSettingsSource(metadataService, registryProvider, f.logger) return settingsSource, nil }
func (s *SourceOptionsSlice) UnmarshalJSON(data []byte) error { var maps []map[string]interface{} err := json.Unmarshal(data, &maps) if err != nil { return bosherr.WrapError(err, "Unmarshalling sources") } for _, m := range maps { if optType, ok := m["Type"]; ok { var err error var opts SourceOptions switch { case optType == "HTTP": var o HTTPSourceOptions err, opts = mapstruc.Decode(m, &o), o case optType == "ConfigDrive": var o ConfigDriveSourceOptions err, opts = mapstruc.Decode(m, &o), o case optType == "File": var o FileSourceOptions err, opts = mapstruc.Decode(m, &o), o case optType == "CDROM": var o CDROMSourceOptions err, opts = mapstruc.Decode(m, &o), o default: err = bosherr.Errorf("Unknown source type '%s'", optType) } if err != nil { return bosherr.WrapErrorf(err, "Unmarshalling source type '%s'", optType) } *s = append(*s, opts) } else { return bosherr.Error("Missing source type") } } return nil }
func (p linux) GetMonitCredentials() (username, password string, err error) { monitUserFilePath := filepath.Join(p.dirProvider.BaseDir(), "monit", "monit.user") credContent, err := p.fs.ReadFileString(monitUserFilePath) if err != nil { err = bosherr.WrapError(err, "Reading monit user file") return } credParts := strings.SplitN(credContent, ":", 2) if len(credParts) != 2 { err = bosherr.Error("Malformated monit user file, expecting username and password separated by ':'") return } username = credParts[0] password = credParts[1] return }
func (p *provider) Get(source Source, stage biui.Stage) (string, error) { if strings.HasPrefix(source.GetURL(), "file://") { filePath := strings.TrimPrefix(source.GetURL(), "file://") expandedPath, err := p.fs.ExpandPath(filePath) if err != nil { p.logger.Warn(p.logTag, "Failed to expand file path %s, using original URL", filePath) return filePath, nil } p.logger.Debug(p.logTag, "Using the tarball from file source: '%s'", filePath) return expandedPath, nil } if !strings.HasPrefix(source.GetURL(), "http") { return "", bosherr.Errorf("Invalid source URL: '%s', must be either file:// or http(s)://", source.GetURL()) } var cachedPath string err := stage.Perform(fmt.Sprintf("Downloading %s", source.Description()), func() error { var found bool cachedPath, found = p.cache.Get(source) if found { p.logger.Debug(p.logTag, "Using the tarball from cache: '%s'", cachedPath) return biui.NewSkipStageError(bosherr.Error("Already downloaded"), "Found in local cache") } retryStrategy := boshretry.NewAttemptRetryStrategy(p.downloadAttempts, p.delayTimeout, p.downloadRetryable(source), p.logger) err := retryStrategy.Try() if err != nil { return bosherr.WrapErrorf(err, "Failed to download from '%s'", source.GetURL()) } p.logger.Debug(p.logTag, "Using the downloaded tarball: '%s'", cachedPath) return nil }) if err != nil { return "", err } return p.cache.Path(source), nil }
func (ms *configDriveMetadataService) GetRegistryEndpoint() (string, error) { if ms.userDataContents.Registry.Endpoint == "" { return "", bosherr.Error("Failed to load registry endpoint from config drive metadata service") } endpoint := ms.userDataContents.Registry.Endpoint nameServers := ms.userDataContents.DNS.Nameserver if len(nameServers) == 0 { ms.logger.Debug(ms.logTag, "Getting registry endpoint %s", endpoint) return endpoint, nil } resolvedEndpoint, err := ms.resolver.LookupHost(nameServers, endpoint) if err != nil { return "", bosherr.WrapError(err, "Resolving registry endpoint") } ms.logger.Debug(ms.logTag, "Registry endpoint %s was resolved to %s", endpoint, resolvedEndpoint) return resolvedEndpoint, nil }
func (udev ConcreteUdevDevice) readByte(filePath string) error { udev.logger.Debug(udev.logtag, "readBytes from file: %s", filePath) device, err := os.Open(filePath) if err != nil { return err } defer device.Close() udev.logger.Debug(udev.logtag, "Successfully open file: %s", filePath) bytes := make([]byte, 1, 1) read, err := device.Read(bytes) if err != nil { return err } udev.logger.Debug(udev.logtag, "Successfully read %d bytes from file: %s", read, filePath) if read != 1 { return bosherr.Error("Device readable but zero length") } return nil }
target := biinstall.NewTarget(filepath.Join("fake-install-dir", "fake-installation-id")) mockInstallerFactory.EXPECT().NewInstaller(target).Return(mockCpiInstaller).AnyTimes() fakeInstallation := &fakecmd.FakeInstallation{} expectCPIInstall = mockCpiInstaller.EXPECT().Install(installationManifest, gomock.Any()).Do(func(_ biinstallmanifest.Manifest, stage biui.Stage) { Expect(fakeStage.SubStages).To(ContainElement(stage)) }).Return(fakeInstallation, nil).AnyTimes() mockCpiInstaller.EXPECT().Cleanup(fakeInstallation).AnyTimes() expectNewCloud = mockCloudFactory.EXPECT().NewCloud(fakeInstallation, directorID).Return(mockCloud, nil).AnyTimes() }) Context("when the call to delete the deployment returns an error", func() { It("returns the error", func() { mockDeploymentManagerFactory.EXPECT().NewManager(mockCloud, mockAgentClient, mockBlobstore).Return(mockDeploymentManager) mockDeploymentManager.EXPECT().FindCurrent().Return(mockDeployment, true, nil) deleteError := bosherr.Error("delete error") mockDeployment.EXPECT().Delete(gomock.Any()).Return(deleteError) err := newDeploymentDeleter().DeleteDeployment(fakeStage) Expect(err).To(HaveOccurred()) }) }) }) }) })
Expect(blobID).To(Equal("fake-blob-id")) Expect(sha1).To(Equal(fixtureSHA1)) Expect(innerBlobstore.CreateFileNames[0]).To(Equal(fixturePath)) }) It("returns error if inner blobstore blob creation fails", func() { innerBlobstore.CreateErr = errors.New("fake-create-error") _, _, err := sha1VerifiableBlobstore.Create(fixturePath) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-create-error")) }) }) Describe("Validate", func() { It("delegates to inner blobstore to validate", func() { err := sha1VerifiableBlobstore.Validate() Expect(err).ToNot(HaveOccurred()) }) It("returns error if inner blobstore validation fails", func() { innerBlobstore.ValidateError = bosherr.Error("fake-validate-error") err := sha1VerifiableBlobstore.Validate() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-validate-error")) }) }) })
Expect(err).ToNot(HaveOccurred()) Expect(fakeVM.UnmountDiskInputs).To(Equal([]fakebivm.UnmountDiskInput{ {Disk: firstDisk}, {Disk: secondDisk}, })) Expect(fakeStage.PerformCalls[2:4]).To(Equal([]*fakebiui.PerformCall{ {Name: "Unmounting disk 'fake-disk-1'"}, {Name: "Unmounting disk 'fake-disk-2'"}, })) }) Context("when stopping vm fails", func() { var ( stopError = bosherr.Error("fake-stop-error") ) BeforeEach(func() { fakeVM.StopErr = stopError }) It("returns an error", func() { err := instance.Delete(pingTimeout, pingDelay, fakeStage) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-stop-error")) Expect(fakeStage.PerformCalls).To(Equal([]*fakebiui.PerformCall{ {Name: "Waiting for the agent on VM 'fake-vm-cid'"}, { Name: "Stopping jobs on instance 'fake-job-name/0'",
Expect(packages).To(ConsistOf([]installation.CompiledPackageRef{ { Name: "fake-release-package-name-1", Version: "fake-release-package-fingerprint-1", BlobstoreID: "fake-compiled-package-blobstore-id-1", SHA1: "fake-compiled-package-sha1-1", }, { Name: "fake-release-package-name-2", Version: "fake-release-package-fingerprint-2", BlobstoreID: "fake-compiled-package-blobstore-id-2", SHA1: "fake-compiled-package-sha1-2", }, })) }) Context("when package compilation fails", func() { JustBeforeEach(func() { expectCompile.Return([]bistatejob.CompiledPackageRef{}, bosherr.Error("fake-compile-package-2-error")).Times(1) }) It("returns an error", func() { _, err := compiler.For(releaseJobs, fakeStage) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake-compile-package-2-error")) }) }) }) })
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")) }) }) }