// initializeBookkeepingLocations - initializes all folder locations required for bookkeeping func initializeBookkeepingLocations(log logger.T, instanceID string) bool { //Create folders pending, current, completed, corrupt under the location DefaultLogDirPath/<instanceId> log.Info("Initializing bookkeeping folders") initStatus := true folders := []string{ appconfig.DefaultLocationOfPending, appconfig.DefaultLocationOfCurrent, appconfig.DefaultLocationOfCompleted, appconfig.DefaultLocationOfCorrupt} for _, folder := range folders { directoryName := path.Join(appconfig.DefaultDataStorePath, instanceID, appconfig.DefaultCommandRootDirName, appconfig.DefaultLocationOfState, folder) err := fileutil.MakeDirs(directoryName) if err != nil { log.Errorf("Encountered error while creating folders for internal state management. %v", err) initStatus = false break } } return initStatus }
func createFile(filePath string) error { dir, _ := filepath.Split(filePath) if err := fileutil.MakeDirs(dir); err != nil { return fmt.Errorf("error creating directories, %s. %v", dir, err) } if err := fileutil.HardenedWriteFile(filePath, []byte("")); err != nil { return fmt.Errorf("error creating file, %s. %v", filePath, err) } return nil }
func (fsvFileSystem) MakeDirs(path string) error { return fileutil.MakeDirs(path) }
// runCommands executes one set of commands and returns their output. func (p *Plugin) runCommands(log log.T, pluginInput ApplicationPluginInput, orchestrationDirectory string, cancelFlag task.CancelFlag, outputS3BucketName string, outputS3KeyPrefix string) (out ApplicationPluginOutput) { var err error // if no orchestration directory specified, create temp directory var useTempDirectory = (orchestrationDirectory == "") var tempDir string if useTempDirectory { if tempDir, err = ioutil.TempDir("", "Ec2RunCommand"); err != nil { out.Errors = append(out.Errors, err.Error()) log.Error(err) return } orchestrationDirectory = tempDir } orchestrationDir := fileutil.RemoveInvalidChars(filepath.Join(orchestrationDirectory, pluginInput.ID)) log.Debugf("OrchestrationDir %v ", orchestrationDir) // create orchestration dir if needed if err = fileutil.MakeDirs(orchestrationDir); err != nil { log.Debug("failed to create orchestrationDir directory", orchestrationDir, err) out.Errors = append(out.Errors, err.Error()) return } // Get application mode mode, err := getMsiApplicationMode(pluginInput) if err != nil { out.MarkAsFailed(log, err) return } log.Debugf("mode is %v", mode) // Download file from source if available downloadOutput, err := pluginutil.DownloadFileFromSource(log, pluginInput.Source, pluginInput.SourceHash, pluginInput.SourceHashType) if err != nil || downloadOutput.IsHashMatched == false || downloadOutput.LocalFilePath == "" { errorString := fmt.Errorf("failed to download file reliably %v", pluginInput.Source) out.MarkAsFailed(log, errorString) return } log.Debugf("local path to file is %v", downloadOutput.LocalFilePath) // Create msi related log file localSourceLogFilePath := downloadOutput.LocalFilePath + ".msiexec.log.txt" log.Debugf("log path is %v", localSourceLogFilePath) // TODO: This needs to be pulled out of this function as it runs multiple times getting initialized with the same values // Create output file paths stdoutFilePath := filepath.Join(orchestrationDir, p.StdoutFileName) stderrFilePath := filepath.Join(orchestrationDir, p.StderrFileName) log.Debugf("stdout file %v, stderr file %v", stdoutFilePath, stderrFilePath) // Construct Command Name and Arguments commandName := msiExecCommand commandArguments := []string{mode, downloadOutput.LocalFilePath, "/quiet", "/norestart", "/log", localSourceLogFilePath} if pluginInput.Parameters != "" { log.Debugf("Got Parameters \"%v\"", pluginInput.Parameters) params := processParams(log, pluginInput.Parameters) commandArguments = append(commandArguments, params...) } // Execute Command _, _, exitCode, errs := p.ExecuteCommand(log, defaultWorkingDirectory, stdoutFilePath, stderrFilePath, cancelFlag, defaultApplicationExecutionTimeoutInSeconds, commandName, commandArguments) // Set output status out.ExitCode = exitCode setMsiExecStatus(log, pluginInput, cancelFlag, &out) if len(errs) > 0 { for _, err := range errs { out.Errors = append(out.Errors, err.Error()) log.Error("failed to run commands: ", err) out.Status = contracts.ResultStatusFailed } return } // Upload output to S3 uploadOutputToS3BucketErrors := p.ExecuteUploadOutputToS3Bucket(log, pluginInput.ID, orchestrationDir, outputS3BucketName, outputS3KeyPrefix, useTempDirectory, tempDir, out.Stdout, out.Stderr) out.Errors = append(out.Errors, uploadOutputToS3BucketErrors...) // Return Json indented response responseContent, _ := jsonutil.Marshal(out) log.Debug("Returning response:\n", jsonutil.Indent(responseContent)) return }
// Download is a generic utility which attempts to download smartly. func Download(log log.T, input DownloadInput) (output DownloadOutput, err error) { // parse the url var fileURL *url.URL fileURL, err = url.Parse(input.SourceURL) if err != nil { err = fmt.Errorf("url parsing failed. %v", err) return } // create destination directory var destinationDir = input.DestinationDirectory if destinationDir == "" { destinationDir = appconfig.DownloadRoot } // create directory where artifacts are downloaded. err = fileutil.MakeDirs(destinationDir) if err != nil { err = fmt.Errorf("failed to create directory=%v, err=%v", destinationDir, err) return } // process if the url is local file or it has already been downloaded. var isLocalFile = false isLocalFile, err = fileutil.LocalFileExist(input.SourceURL) if err != nil { err = fmt.Errorf("check for local file exists returned %v", err) err = nil } if isLocalFile == true { err = fmt.Errorf("source is a local file, skipping download. %v", input.SourceURL) output.LocalFilePath = input.SourceURL output.IsUpdated = false output.IsHashMatched, err = VerifyHash(log, input, output) } else { err = fmt.Errorf("source file wasn't found locally, will attempt as web download. %v", input.SourceURL) // compute the local filename which is hash of url_filename // Generating a hash_filename will also help against attackers // from specifying a directory and filename to overwrite any ami/built-in files. urlHash := md5.Sum([]byte(fileURL.String())) fileName := filepath.Base(fileURL.String()) output.LocalFilePath = filepath.Join(destinationDir, fmt.Sprintf("%x_%v", urlHash, fileName)) amazonS3URL := s3util.ParseAmazonS3URL(log, fileURL) if amazonS3URL.IsBucketAndKeyPresent() { // source is s3 output, err = s3Download(log, amazonS3URL, output.LocalFilePath) } else { // simple httphttps download output, err = httpDownload(log, input.SourceURL, output.LocalFilePath) } if err != nil { return } isLocalFile, err = fileutil.LocalFileExist(output.LocalFilePath) if isLocalFile == true { output.IsHashMatched, err = VerifyHash(log, input, output) } } return }