Example #1
0
// 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
}
Example #3
0
func (fsvFileSystem) MakeDirs(path string) error           { return fileutil.MakeDirs(path) }
Example #4
0
// 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
}
Example #5
0
// 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
}