func (res digDnsResolver) runCommand(cmdName string, args ...string) (stdout, stderr string, err error) { res.logger.Debug("Dig Dns Resolver", "Running command: %s %s", cmdName, strings.Join(args, " ")) cmd := exec.Command(cmdName, args...) stdoutWriter := bytes.NewBufferString("") stderrWriter := bytes.NewBufferString("") cmd.Stdout = stdoutWriter cmd.Stderr = stderrWriter err = cmd.Start() if err != nil { err = bosherr.WrapError(err, "Starting dig command") return } err = cmd.Wait() stdout = string(stdoutWriter.Bytes()) stderr = string(stderrWriter.Bytes()) res.logger.Debug("Cmd Runner", "Stdout: %s", stdout) res.logger.Debug("Cmd Runner", "Stderr: %s", stderr) res.logger.Debug("Cmd Runner", "Successful: %t", err == nil) if err != nil { err = bosherr.WrapError(err, "Waiting for dig command") } return }
func (inf awsInfrastructure) MountPersistentDisk(volumeId string, mountPoint string) (err error) { inf.platform.GetFs().MkdirAll(mountPoint, os.FileMode(0700)) realPath, err := inf.devicePathResolver.GetRealDevicePath(volumeId) if err != nil { err = bosherr.WrapError(err, "Getting real device path") return } partitions := []boshdisk.Partition{ {Type: boshdisk.PartitionTypeLinux}, } err = inf.platform.GetDiskManager().GetPartitioner().Partition(realPath, partitions) if err != nil { err = bosherr.WrapError(err, "Partitioning disk") return } partitionPath := realPath + "1" err = inf.platform.GetDiskManager().GetFormatter().Format(partitionPath, boshdisk.FileSystemExt4) if err != nil { err = bosherr.WrapError(err, "Formatting partition with ext4") return } err = inf.platform.GetDiskManager().GetMounter().Mount(partitionPath, mountPoint) if err != nil { err = bosherr.WrapError(err, "Mounting partition") return } return }
func (h natsHandler) Start(handlerFunc boshhandler.HandlerFunc) (err error) { connProvider, err := h.getConnectionInfo() if err != nil { err = bosherr.WrapError(err, "Getting connection info") return } err = h.client.Connect(connProvider) if err != nil { err = bosherr.WrapError(err, "Connecting") return } subject := fmt.Sprintf("agent.%s", h.settings.GetAgentId()) h.client.Subscribe(subject, func(natsMsg *yagnats.Message) { respBytes, req, err := boshhandler.PerformHandlerWithJSON(natsMsg.Payload, handlerFunc, h.logger) if err != nil { err = bosherr.WrapError(err, "Running handler in a nice JSON sandwhich") return } h.client.Publish(req.ReplyTo, respBytes) }) return }
func (s *concretePackageApplier) downloadAndInstall(pkg models.Package, pkgBundle bc.Bundle) error { tmpDir, err := s.fs.TempDir("bosh-agent-applier-packageapplier-ConcretePackageApplier-Apply") if err != nil { return bosherr.WrapError(err, "Getting temp dir") } defer s.fs.RemoveAll(tmpDir) file, err := s.blobstore.Get(pkg.Source.BlobstoreID, pkg.Source.Sha1) if err != nil { return bosherr.WrapError(err, "Fetching package blob") } defer s.blobstore.CleanUp(file) err = s.compressor.DecompressFileToDir(file, tmpDir) if err != nil { return bosherr.WrapError(err, "Decompressing package files") } _, _, err = pkgBundle.Install(tmpDir) if err != nil { return bosherr.WrapError(err, "Installling package directory") } return nil }
func (c httpClient) status() (status status, err error) { url := c.monitUrl("/_status2") url.RawQuery = "format=xml" response, err := c.makeRequest(url, "GET", "") if err != nil { err = bosherr.WrapError(err, "Sending status request to monit") return } defer response.Body.Close() err = c.validateResponse(response) if err != nil { err = bosherr.WrapError(err, "Getting monit status") return } decoder := xml.NewDecoder(response.Body) decoder.CharsetReader = charset.NewReader err = decoder.Decode(&status) if err != nil { err = bosherr.WrapError(err, "Unmarshalling Monit status") } return }
func (fs osFileSystem) ConvergeFileContents(path string, content []byte) (written bool, err error) { if fs.filesAreIdentical(content, path) { return } err = fs.MkdirAll(filepath.Dir(path), os.ModePerm) if err != nil { err = bosherr.WrapError(err, "Making dir for file %s", path) return } file, err := os.Create(path) if err != nil { err = bosherr.WrapError(err, "Creating file %s", path) return } defer file.Close() _, err = file.Write(content) if err != nil { err = bosherr.WrapError(err, "Writing content to file %s", path) return } written = true return }
func (fs osFileSystem) Chown(path, username string) (err error) { fs.logger.Debug(fs.logTag, "Chown %s to user %s", path, username) user, err := osuser.Lookup(username) if err != nil { err = bosherr.WrapError(err, "Looking up user %s", username) return } uid, err := strconv.Atoi(user.Uid) if err != nil { err = bosherr.WrapError(err, "Converting UID to integer") return } gid, err := strconv.Atoi(user.Gid) if err != nil { err = bosherr.WrapError(err, "Converting GID to integer") return } err = os.Chown(path, uid, gid) if err != nil { err = bosherr.WrapError(err, "Doing Chown") return } return }
func (r concreteRunner) Run(action Action, payloadBytes []byte) (value interface{}, err error) { payloadArgs, err := r.extractJsonArguments(payloadBytes) if err != nil { err = bosherr.WrapError(err, "Extracting json arguments") return } actionValue := reflect.ValueOf(action) runMethodValue := actionValue.MethodByName("Run") if runMethodValue.Kind() != reflect.Func { err = bosherr.New("Run method not found") return } runMethodType := runMethodValue.Type() if r.invalidReturnTypes(runMethodType) { err = bosherr.New("Run method should return a value and an error") return } methodArgs, err := r.extractMethodArgs(runMethodType, payloadArgs) if err != nil { err = bosherr.WrapError(err, "Extracting method arguments from payload") return } values := runMethodValue.Call(methodArgs) return r.extractReturns(values) }
func (s *concretePackageApplier) Apply(pkg models.Package) (err error) { _, packageDir, err := s.packagesBc.Install(pkg) if err != nil { err = bosherr.WrapError(err, "Installling package directory") return } file, err := s.blobstore.Get(pkg.Source.BlobstoreId, pkg.Source.Sha1) if err != nil { err = bosherr.WrapError(err, "Fetching package blob") return } defer s.blobstore.CleanUp(file) err = s.compressor.DecompressFileToDir(file, packageDir) if err != nil { err = bosherr.WrapError(err, "Decompressing package files") return } err = s.packagesBc.Enable(pkg) if err != nil { err = bosherr.WrapError(err, "Enabling package") } return }
func (fs osFileSystem) WriteToFile(path, content string) (written bool, err error) { fs.logger.DebugWithDetails(fs.logTag, "Writing to file %s", path, content) if fs.filesAreIdentical(content, path) { return } err = fs.MkdirAll(filepath.Dir(path), os.ModePerm) if err != nil { err = bosherr.WrapError(err, "Making dir for file %s", path) return } file, err := os.Create(path) if err != nil { err = bosherr.WrapError(err, "Creating file %s", path) return } defer file.Close() _, err = file.WriteString(content) if err != nil { err = bosherr.WrapError(err, "Writing content to file %s", path) return } written = true return }
func (run execCmdRunner) runCmd(cmd *exec.Cmd) (stdout, stderr string, err error) { cmdString := strings.Join(cmd.Args, " ") run.logger.Debug("Cmd Runner", "Running command: %s", cmdString) stdoutWriter := bytes.NewBufferString("") stderrWriter := bytes.NewBufferString("") cmd.Stdout = stdoutWriter cmd.Stderr = stderrWriter err = cmd.Start() if err != nil { err = bosherr.WrapError(err, "Starting command %s", cmdString) return } err = cmd.Wait() stdout = string(stdoutWriter.Bytes()) stderr = string(stderrWriter.Bytes()) run.logger.Debug("Cmd Runner", "Stdout: %s", stdout) run.logger.Debug("Cmd Runner", "Stderr: %s", stderr) run.logger.Debug("Cmd Runner", "Successful: %t", err == nil) if err != nil { err = bosherr.WrapError(err, "Running command: '%s', stdout: '%s', stderr: '%s'", cmdString, stdout, stderr) } return }
func (a SshAction) setupSsh(params SshParams) (value interface{}, err error) { boshSshPath := filepath.Join(a.dirProvider.BaseDir(), "bosh_ssh") err = a.platform.CreateUser(params.User, params.Password, boshSshPath) if err != nil { err = bosherr.WrapError(err, "Creating user") return } err = a.platform.AddUserToGroups(params.User, []string{boshsettings.VCAPUsername, boshsettings.AdminGroup}) if err != nil { err = bosherr.WrapError(err, "Adding user to groups") return } err = a.platform.SetupSsh(params.PublicKey, params.User) if err != nil { err = bosherr.WrapError(err, "Setting ssh public key") return } defaultIP, found := a.settings.GetDefaultIP() if !found { err = errors.New("No default ip could be found") return } value = map[string]string{ "command": "setup", "status": "success", "ip": defaultIP, } return }
func (m monitJobSupervisor) Reload() (err error) { oldIncarnation, err := m.getIncarnation() if err != nil { err = bosherr.WrapError(err, "Getting monit incarnation") return err } // Exit code or output cannot be trusted m.runner.RunCommand("monit", "reload") for attempt := 1; attempt < 60; attempt++ { err = nil currentIncarnation, err := m.getIncarnation() if err != nil { err = bosherr.WrapError(err, "Getting monit incarnation") return err } if oldIncarnation < currentIncarnation { return nil } time.Sleep(m.delayBetweenReloadCheckRetries) } err = bosherr.New("Failed to reload monit") return }
func (action logsAction) Run(payloadBytes []byte) (value interface{}, err error) { filters, err := extractFilters(payloadBytes) if err != nil { err = bosherr.WrapError(err, "Extracting filters from payload") return } if len(filters) == 0 { filters = []string{"**/*"} } logsDir := filepath.Join(boshsettings.VCAP_BASE_DIR, "bosh", "log") tarball, err := action.compressor.CompressFilesInDir(logsDir, filters) if err != nil { err = bosherr.WrapError(err, "Making logs tarball") return } blobId, err := action.blobstore.Create(tarball) if err != nil { err = bosherr.WrapError(err, "Create file on blobstore") return } value = map[string]string{"blobstore_id": blobId} return }
func (v SyntaxValidator) validateJob(job *Job) error { if job.Name == "" { return bosherr.New("Missing job name") } if job.Template != nil { return bosherr.New("'template' is deprecated in favor of 'templates'") } err := v.validateUpdate(&job.Update) if err != nil { return bosherr.WrapError(err, "Update") } props, err := bputil.NewStringKeyed().ConvertMap(job.PropertiesRaw) if err != nil { return bosherr.WrapError(err, "Properties") } job.Properties = props for i, na := range job.NetworkAssociations { err := v.validateNetworkAssociation(&job.NetworkAssociations[i]) if err != nil { return bosherr.WrapError(err, "Network association %s (%d)", na.NetworkName, i) } } return nil }
func (net ubuntu) detectMacAddresses() (addresses map[string]string, err error) { addresses = map[string]string{} filePaths, err := net.fs.Glob("/sys/class/net/*") if err != nil { err = bosherr.WrapError(err, "Getting file list from /sys/class/net") return } var macAddress string for _, filePath := range filePaths { macAddress, err = net.fs.ReadFileString(filepath.Join(filePath, "address")) if err != nil { err = bosherr.WrapError(err, "Reading mac address from file") return } macAddress = strings.Trim(macAddress, "\n") interfaceName := filepath.Base(filePath) addresses[macAddress] = interfaceName } return }
func (script ConcreteDrainScript) Run(params DrainScriptParams) (int, error) { jobChange := params.JobChange() hashChange := params.HashChange() updatedPkgs := params.UpdatedPackages() command := boshsys.Command{ Name: script.drainScriptPath, Env: map[string]string{ "PATH": "/usr/sbin:/usr/bin:/sbin:/bin", }, } command.Args = append(command.Args, jobChange, hashChange) command.Args = append(command.Args, updatedPkgs...) stdout, _, err := script.runner.RunComplexCommand(command) if err != nil { return 0, bosherr.WrapError(err, "Running drain script") } value, err := strconv.Atoi(strings.TrimSpace(stdout)) if err != nil { return 0, bosherr.WrapError(err, "Script did not return a signed integer") } return value, nil }
func (net ubuntu) SetupDhcp(networks boshsettings.Networks) (err error) { dnsServers := net.getDnsServers(networks) buffer := bytes.NewBuffer([]byte{}) t := template.Must(template.New("dhcp-config").Parse(UBUNTU_DHCP_CONFIG_TEMPLATE)) err = t.Execute(buffer, dnsConfigArg{dnsServers}) if err != nil { err = bosherr.WrapError(err, "Generating config from template") return } written, err := net.fs.ConvergeFileContents("/etc/dhcp3/dhclient.conf", buffer.Bytes()) if err != nil { err = bosherr.WrapError(err, "Writing to /etc/dhcp3/dhclient.conf") return } if written { // Ignore errors here, just run the commands net.cmdRunner.RunCommand("pkill", "dhclient3") net.cmdRunner.RunCommand("/etc/init.d/networking", "restart") } return }
func (fs osFileSystem) Symlink(oldPath, newPath string) (err error) { fs.logger.Debug(fs.logTag, "Symlinking oldPath %s with newPath %s", oldPath, newPath) actualOldPath, err := filepath.EvalSymlinks(oldPath) if err != nil { err = bosherr.WrapError(err, "Evaluating symlinks for %s", oldPath) return } existingTargetedPath, err := filepath.EvalSymlinks(newPath) if err == nil { if existingTargetedPath == actualOldPath { return } err = os.Remove(newPath) if err != nil { err = bosherr.WrapError(err, "Failed to delete symlimk at %s", newPath) return } } containingDir := filepath.Dir(newPath) if !fs.FileExists(containingDir) { fs.MkdirAll(containingDir, os.FileMode(0700)) } return os.Symlink(oldPath, newPath) }
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.WrapError(err, "Making dir for file %s", path) } file, err := os.Create(path) if err != nil { return true, bosherr.WrapError(err, "Creating file %s", path) } defer file.Close() _, err = file.Write(content) if err != nil { return true, bosherr.WrapError(err, "Writing content to file %s", path) } return true, nil }
func (s *concretePackageApplier) Apply(pkg models.Package) error { s.logger.Debug(logTag, "Applying package %v", pkg) pkgBundle, err := s.packagesBc.Get(pkg) if err != nil { return bosherr.WrapError(err, "Getting package bundle") } pkgInstalled, err := pkgBundle.IsInstalled() if err != nil { return bosherr.WrapError(err, "Checking if package is installed") } if !pkgInstalled { err := s.downloadAndInstall(pkg, pkgBundle) if err != nil { return err } } _, _, err = pkgBundle.Enable() if err != nil { return bosherr.WrapError(err, "Enabling package") } return nil }
func (p ubuntu) SetupHostname(hostname string) (err error) { _, _, err = p.cmdRunner.RunCommand("hostname", hostname) if err != nil { err = bosherr.WrapError(err, "Shelling out to hostname") return } _, err = p.fs.WriteToFile("/etc/hostname", hostname) if err != nil { err = bosherr.WrapError(err, "Writing /etc/hostname") return } buffer := bytes.NewBuffer([]byte{}) t := template.Must(template.New("etc-hosts").Parse(ETC_HOSTS_TEMPLATE)) err = t.Execute(buffer, hostname) if err != nil { err = bosherr.WrapError(err, "Generating config from template") return } _, err = p.fs.WriteToFile("/etc/hosts", buffer.String()) if err != nil { err = bosherr.WrapError(err, "Writing to /etc/hosts") } return }
func (net ubuntuNetManager) SetupManualNetworking(networks boshsettings.Networks, errCh chan error) error { modifiedNetworks, written, err := net.writeNetworkInterfaces(networks) if err != nil { return bosherr.WrapError(err, "Writing network interfaces") } if written { net.restartNetworkingInterfaces(modifiedNetworks) } err = net.writeResolvConf(networks) if err != nil { return bosherr.WrapError(err, "Writing resolv.conf") } addresses := toInterfaceAddresses(modifiedNetworks) go func() { net.addressBroadcaster.BroadcastMACAddresses(addresses) if errCh != nil { errCh <- nil } }() return nil }
func (p ubuntu) MountPersistentDisk(devicePath, mountPoint string) (err error) { p.fs.MkdirAll(mountPoint, os.FileMode(0700)) realPath, err := p.getRealDevicePath(devicePath) if err != nil { err = bosherr.WrapError(err, "Getting real device path") return } partitions := []boshdisk.Partition{ {Type: boshdisk.PartitionTypeLinux}, } err = p.partitioner.Partition(realPath, partitions) if err != nil { err = bosherr.WrapError(err, "Partitioning disk") return } partitionPath := realPath + "1" err = p.formatter.Format(partitionPath, boshdisk.FileSystemExt4) if err != nil { err = bosherr.WrapError(err, "Formatting partition with ext4") return } err = p.mounter.Mount(partitionPath, mountPoint) if err != nil { err = bosherr.WrapError(err, "Mounting partition") return } return }
func (inf awsInfrastructure) getSettingsAtUrl(settingsUrl string) (settings boshsettings.Settings, err error) { wrapperResponse, err := http.Get(settingsUrl) if err != nil { err = bosherr.WrapError(err, "Getting settings from url") return } defer wrapperResponse.Body.Close() wrapperBytes, err := ioutil.ReadAll(wrapperResponse.Body) if err != nil { err = bosherr.WrapError(err, "Reading settings response body") return } wrapper := new(settingsWrapperType) err = json.Unmarshal(wrapperBytes, wrapper) if err != nil { err = bosherr.WrapError(err, "Unmarshalling settings wrapper") return } err = json.Unmarshal([]byte(wrapper.Settings), &settings) if err != nil { err = bosherr.WrapError(err, "Unmarshalling wrapped settings") } return }
func (p ubuntu) MigratePersistentDisk(fromMountPoint, toMountPoint string) (err error) { err = p.mounter.RemountAsReadonly(fromMountPoint) if err != nil { err = bosherr.WrapError(err, "Remounting persistent disk as readonly") return } // Golang does not implement a file copy that would allow us to preserve dates... // So we have to shell out to tar to perform the copy instead of delegating to the FileSystem tarCopy := fmt.Sprintf("(tar -C %s -cf - .) | (tar -C %s -xpf -)", fromMountPoint, toMountPoint) _, _, err = p.cmdRunner.RunCommand("sh", "-c", tarCopy) if err != nil { err = bosherr.WrapError(err, "Copying files from old disk to new disk") return } _, err = p.mounter.Unmount(fromMountPoint) if err != nil { err = bosherr.WrapError(err, "Unmounting old persistent disk") return } err = p.mounter.Remount(toMountPoint, fromMountPoint) if err != nil { err = bosherr.WrapError(err, "Remounting new disk on original mountpoint") } return }
func (a SshAction) setupSsh(params SshParams) (SshResult, error) { var result SshResult boshSshPath := filepath.Join(a.dirProvider.BaseDir(), "bosh_ssh") err := a.platform.CreateUser(params.User, params.Password, boshSshPath) if err != nil { return result, bosherr.WrapError(err, "Creating user") } err = a.platform.AddUserToGroups(params.User, []string{boshsettings.VCAPUsername, boshsettings.AdminGroup}) if err != nil { return result, bosherr.WrapError(err, "Adding user to groups") } err = a.platform.SetupSsh(params.PublicKey, params.User) if err != nil { return result, bosherr.WrapError(err, "Setting ssh public key") } settings := a.settingsService.GetSettings() defaultIP, found := settings.Networks.DefaultIP() if !found { return result, errors.New("No default ip could be found") } result = SshResult{ Command: "setup", Status: "success", IP: defaultIP, } return result, nil }
func (p RunitProvisioner) setUpService(name string, stopTimeout time.Duration) error { p.logger.Info(runitProvisionerLogTag, "Setting up %s service", name) servicePath := fmt.Sprintf("/etc/sv/%s", name) enableServicePath := fmt.Sprintf("/etc/service/%s", name) err := p.stopRunAndLog(servicePath, enableServicePath, name, stopTimeout) if err != nil { return bosherr.WrapError(err, "Stopping run and log") } err = p.setUpRun(servicePath, name) if err != nil { return bosherr.WrapError(err, "Setting up run") } err = p.setUpLog(servicePath, name) if err != nil { return bosherr.WrapError(err, "Setting up log") } err = p.startRunAndLog(servicePath, enableServicePath, name) if err != nil { return bosherr.WrapError(err, "Starting run and log") } return nil }
func (a mountDiskAction) Run(volumeId string) (value interface{}, err error) { err = a.settings.Refresh() if err != nil { err = bosherr.WrapError(err, "Refreshing the settings") return } disksSettings := a.settings.GetDisks() devicePath, found := disksSettings.Persistent[volumeId] if !found { err = bosherr.New("Persistent disk with volume id '%s' could not be found", volumeId) return } mountPoint := a.dirProvider.StoreDir() isMountPoint, err := a.platform.IsMountPoint(mountPoint) if err != nil { err = bosherr.WrapError(err, "Checking mount point") return } if isMountPoint { mountPoint = a.dirProvider.StoreMigrationDir() } err = a.platform.MountPersistentDisk(devicePath, mountPoint) if err != nil { err = bosherr.WrapError(err, "Mounting persistent disk") return } value = make(map[string]string) return }
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.New("No routes found") } for _, route := range routes { if !route.IsDefault() { continue } ip, err := r.ipResolver.GetPrimaryIPv4(route.InterfaceName) if err != nil { return network, bosherr.WrapError( 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.New("Failed to find default route") }