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
}
Example #2
0
// MoveCommandState moves the CommandState object
func MoveCommandState(log log.T, commandID, instanceID, srcLocationFolder, dstLocationFolder string) {

	//get a lock for documentID specific lock
	lockDocument(commandID)

	absoluteSource := path.Join(appconfig.DefaultDataStorePath,
		instanceID,
		appconfig.DefaultCommandRootDirName,
		appconfig.DefaultLocationOfState,
		srcLocationFolder)

	absoluteDestination := path.Join(appconfig.DefaultDataStorePath,
		instanceID,
		appconfig.DefaultCommandRootDirName,
		appconfig.DefaultLocationOfState,
		dstLocationFolder)

	if s, err := fileutil.MoveFile(commandID, absoluteSource, absoluteDestination); s && err == nil {
		log.Debugf("moved file %v from %v to %v successfully", commandID, srcLocationFolder, dstLocationFolder)
	} else {
		log.Debugf("moving file %v from %v to %v failed with error %v", commandID, srcLocationFolder, dstLocationFolder, err)
	}

	//release documentID specific lock - before deleting the entry from the map
	unlockDocument(commandID)

	//delete documentID specific lock if document has finished executing. This is to avoid documentLock growing too much in memory.
	//This is done by ensuring that as soon as document finishes executing it is removed from documentLock
	//Its safe to assume that document has finished executing if it is being moved to appconfig.DefaultLocationOfCompleted
	if dstLocationFolder == appconfig.DefaultLocationOfCompleted {
		deleteLock(commandID)
	}
}
Example #3
0
// process launches one job in a separate go routine and waits
// for either the job to finish or for a cancel to be requested.
// If cancel is requested, this function waits for some time to allow the
// job to complete. If the job does not complete by the timeout, the go routine
// of the job is abandoned, and this function returns.
func process(log log.T, job Job, cancelFlag *ChanneledCancelFlag, cancelWait time.Duration, clock times.Clock) {
	// Make a buffered channel to avoid blocking on send. This helps
	// in case the job fails to cancel on time and we give up on it.
	// If the job finally ends, it will succeed to send a signal
	// on the channel and then it will terminate. This will allow
	// the garbage collector to collect the go routine's resources
	// and the channel.
	doneChan := make(chan struct{}, 1)

	go runJob(log, func() { job(cancelFlag) }, doneChan)

	done := waitEither(doneChan, cancelFlag.ch)
	if done {
		// task done, set the flag to wake up waiting routines
		cancelFlag.Set(Completed)
		return
	}

	log.Debugf("Execution has been canceled, waiting up to %v to finish", cancelWait)
	done = waitEither(doneChan, clock.After(cancelWait))
	if done {
		// job completed within cancel waiting window
		cancelFlag.Set(Completed)
		return
	}

	log.Debugf("Job failed to terminate within %v!", cancelWait)
}
Example #4
0
// LatestVersion returns latest version for specific package
func (m *Manifest) LatestVersion(log log.T, context *updateutil.InstanceContext, packageName string) (result string, err error) {
	var version = minimumVersion
	var compareResult = 0
	for _, p := range m.Packages {
		if p.Name == packageName {
			for _, f := range p.Files {
				if f.Name == context.FileName(packageName) {
					for _, v := range f.AvailableVersions {
						if compareResult, err = updateutil.VersionCompare(v.Version, version); err != nil {
							return version, err
						}
						if compareResult > 0 {
							version = v.Version
						}
					}
				}
			}
		}
	}
	if version == minimumVersion {
		log.Debugf("Filename: %v", context.FileName(packageName))
		log.Debugf("Package Name: %v", packageName)
		log.Debugf("Manifest: %v", m)
		return version, fmt.Errorf("cannot find the latest version for package %v", packageName)
	}

	return version, nil
}
Example #5
0
// validateManifest makes sure all the fields are provided.
func validateManifest(log log.T, parsedManifest *Manifest, context *updateutil.InstanceContext, packageName string) error {
	if len(parsedManifest.URIFormat) == 0 {
		return fmt.Errorf("folder format cannot be null in the Manifest file")
	}
	fileName := context.FileName(packageName)
	foundPackage := false
	foundFile := false
	for _, p := range parsedManifest.Packages {
		if p.Name == packageName {
			log.Infof("found package %v", packageName)
			foundPackage = true
			for _, f := range p.Files {
				if f.Name == fileName {
					foundFile = true
					if len(f.AvailableVersions) == 0 {
						return fmt.Errorf("at least one available version is required for the %v", fileName)
					}

					log.Infof("found file %v", fileName)
					break
				}
			}
		}
	}

	if !foundPackage {
		return fmt.Errorf("cannot find the %v information in the Manifest file", packageName)
	}
	if !foundFile {
		return fmt.Errorf("cannot find the %v information in the Manifest file", fileName)
	}

	return nil
}
Example #6
0
// HandleAwsError logs an AWS error.
func HandleAwsError(log log.T, err error, stopPolicy *StopPolicy) {
	if err != nil {
		// notice that we're using 1, so it will actually log the where
		// the error happened, 0 = this function, we don't want that.
		pc, fn, line, _ := runtime.Caller(1)
		log.Debugf("error in %s[%s:%d] %v", runtime.FuncForPC(pc).Name(), fn, line, err)

		// In case this is aws error, update the stop policy as well.
		if aErr, ok := err.(awserr.Error); ok {
			// Generic AWS Error with Code, Message, and original error (if any)
			log.Debugf("AWS error. Code: %v, Message: %v, origerror: %v ", aErr.Code(), aErr.Message(), aErr.OrigErr())

			// special treatment for Timeout exception - as this is expected
			if aErr.Code() == "RequestError" && aErr.OrigErr() != nil && strings.Contains(aErr.OrigErr().Error(), "Client.Timeout") {
				// resetting the error count to 0 - as these exceptions are all expected
				if stopPolicy != nil {
					resetStopPolicy(stopPolicy)
				}
				return
			}
		}

		log.Errorf("error when calling AWS APIs. error details - %v", err)
		if stopPolicy != nil {
			log.Infof("increasing error count by 1")
			stopPolicy.AddErrorCount(1)
		}

	} else {
		// there is no error,
		resetStopPolicy(stopPolicy)
	}
}
Example #7
0
// install executes the install script for the specific version of agent
func installAgent(mgr *updateManager, log log.T, version string, context *UpdateContext) (err error) {
	log.Infof("Initiating %v %v installation", context.Current.PackageName, version)

	// find the path for the install script
	installerPath := updateutil.InstallerFilePath(
		context.Current.UpdateRoot,
		context.Current.PackageName,
		version)
	// calculate work directory
	workDir := updateutil.UpdateArtifactFolder(
		context.Current.UpdateRoot,
		context.Current.PackageName,
		version)

	// Install version
	if err = mgr.util.ExeCommand(
		log,
		installerPath,
		workDir,
		context.Current.UpdateRoot,
		context.Current.StdoutFileName,
		context.Current.StderrFileName,
		false); err != nil {

		return err
	}

	log.Infof("%v %v installed successfully", context.Current.PackageName, version)
	return nil
}
Example #8
0
func (svc *sdkService) SendCommand(log log.T,
	documentName string,
	instanceIDs []string,
	parameters map[string][]*string,
	timeoutSeconds *int64,
	outputS3BucketName *string,
	outputS3KeyPrefix *string) (response *ssm.SendCommandOutput, err error) {
	params := ssm.SendCommandInput{
		DocumentName:       aws.String(documentName),
		InstanceIds:        makeAwsStrings(instanceIDs),
		Comment:            aws.String("Comment"),
		OutputS3BucketName: outputS3BucketName,
		OutputS3KeyPrefix:  outputS3KeyPrefix,
		Parameters:         parameters,
		TimeoutSeconds:     timeoutSeconds,
	}

	log.Debug("SendCommand params:", params)
	response, err = svc.sdk.SendCommand(&params)
	if err != nil {
		sdkutil.HandleAwsError(log, err, ssmStopPolicy)
		return
	}
	log.Debug("SendCommand Response", response)
	return
}
Example #9
0
// processFingerprint handles flags related to the fingerprint category
func processFingerprint(log logger.T) (exitCode int) {
	if err := fingerprint.SetSimilarityThreshold(similarityThreshold); err != nil {
		log.Errorf("Error setting the SimilarityThreshold. %v", err)
		return 1
	}
	log.Infof("Fingerprint SimilarityTHreshold set to %v", similarityThreshold)
	return 0
}
Example #10
0
// clearRegistration clears any existing registration data
func clearRegistration(log logger.T) (exitCode int) {
	err := registration.UpdateServerInfo("", "", "", "")
	if err == nil {
		log.Info("Registration information has been removed from the instance.")
		return 0
	}
	log.Errorf("error clearing the instance registration information. %v\nTry running as sudo/administrator.", err)
	return 1
}
Example #11
0
// Run as a single process. Used by Unix systems and when running agent from console.
func run(log logger.T) {
	// run core manager
	cpm, err := start(log, instanceIDPtr, regionPtr)
	if err != nil {
		log.Errorf("error occured when starting amazon-ssm-agent: %v", err)
		return
	}
	blockUntilSignaled(log)
	stop(log, cpm)
}
Example #12
0
// RemoveData deletes the fileName from locationFolder under defaultLogDir/instanceID
func RemoveData(log log.T, commandID, instanceID, locationFolder string) {

	absoluteFileName := getCmdStateFileName(commandID, instanceID, locationFolder)

	err := fileutil.DeleteFile(absoluteFileName)
	if err != nil {
		log.Errorf("encountered error %v while deleting file %v", err, absoluteFileName)
	} else {
		log.Debugf("successfully deleted file %v", absoluteFileName)
	}
}
Example #13
0
func killProcessOnTimeout(log log.T, command *exec.Cmd, timer *time.Timer) {
	<-timer.C
	log.Debug("Process exceeded timeout. Attempting to kill process!")

	// task has been exceeded the allowed execution timeout, kill process
	if err := command.Process.Kill(); err != nil {
		log.Error(err)
		return
	}

	log.Debug("Done kill process!")
}
Example #14
0
func processSendReply(log log.T, messageID string, mdsService service.Service, payloadDoc messageContracts.SendReplyPayload, processorStopPolicy *sdkutil.StopPolicy) {
	payloadB, err := json.Marshal(payloadDoc)
	if err != nil {
		log.Error("could not marshal reply payload!", err)
	}
	payload := string(payloadB)
	log.Info("Sending reply ", jsonutil.Indent(payload))
	err = mdsService.SendReply(log, messageID, payload)
	if err != nil {
		sdkutil.HandleAwsError(log, err, processorStopPolicy)
	}
}
Example #15
0
// killProcessOnTimeout waits for a timeout.
// When the timeout is reached, this method kills the underlying
// process of the command. This will unblock the command.Wait() call.
// If the task completed successfully this method returns with no action.
func killProcessOnTimeout(log log.T, command *exec.Cmd, timer *time.Timer) {
	<-timer.C
	log.Debug("Process exceeded timeout. Attempting to stop process.")

	// task has been exceeded the allowed execution timeout, kill process
	if err := killProcess(command.Process); err != nil {
		log.Error(err)
		return
	}

	log.Debug("Process stopped successfully")
}
Example #16
0
func getPlatformDetail(log log.T, param string) (value string, err error) {
	var contentsBytes []byte
	value = notAvailableMessage

	log.Debugf(gettingPlatformDetailsMessage)
	if contentsBytes, err = exec.Command(platformDetailsCommand, param).Output(); err != nil {
		log.Debugf(errorOccurredMessage, platformDetailsCommand, err)
		return
	}
	value = strings.TrimSpace(string(contentsBytes))
	log.Debugf(commandOutputMessage, value)
	return
}
Example #17
0
// LoadUpdateContext loads update context info from local storage, set current update with new update detail
func LoadUpdateContext(log log.T, source string) (context *UpdateContext, err error) {
	log.Debugf("file %v", source)
	if _, err := os.Stat(source); os.IsNotExist(err) {
		log.Debugf("UpdateContext file doesn't exist, creating new one")
		context = &UpdateContext{}
	} else {
		log.Debugf("UpdateContext file exists")
		if context, err = parseContext(log, source); err != nil {
			return context, err
		}
	}
	return context, nil
}
Example #18
0
// ReplaceParameters traverses an arbitrarily complex input object (maps/slices/strings/etc.)
// and tries to replace parameters given as {{parameter}} with their values from the parameters map.
//
// Strings like "{{ parameter }}" are replaced directly with the value associated with
// the parameter. That value need not be a string.
//
// Strings like "a {{ parameter1 }} within a string" are replaced with strings where the parameters
// are replaced by a marshaled version of their values. In this case, the resulting object is always a string.
//
// Note: this only works on composite types []interface{} and map[string]interface{} which are what json.Unmarshal
// produces by default. If your object contains []string, for example, the object will be returned as is.
//
// Returns a new object with replaced parameters.
func ReplaceParameters(input interface{}, parameters map[string]interface{}, logger log.T) interface{} {
	switch input := input.(type) {
	case string:
		// handle single parameter case first
		for parameterName, parameterValue := range parameters {
			if isSingleParameterString(input, parameterName) {
				return parameterValue
			}
		}

		// look for multiple parameter strings
		for parameterName, parameterValue := range parameters {
			var parameterValueString string
			var err error
			if parameterValueString, err = convertToString(parameterValue); err != nil {
				logger.Error(err)
			}
			input = ReplaceParameter(input, parameterName, parameterValueString)
		}
		return input

	case []interface{}:
		// for slices, recursively replace parameters on each element of the slice
		out := make([]interface{}, len(input))
		for i, v := range input {
			out[i] = ReplaceParameters(v, parameters, logger)
		}
		return out

	case []map[string]interface{}:
		// this case is not caught by the one above because map cannot be converted to interface{}
		out := make([]map[string]interface{}, len(input))
		for i, v := range input {
			out[i] = ReplaceParameters(v, parameters, logger).(map[string]interface{})
		}
		return out

	case map[string]interface{}:
		// for maps, recursively replace parameters on each value in the map
		out := make(map[string]interface{})
		for k, v := range input {
			out[k] = ReplaceParameters(v, parameters, logger)
		}
		return out

	default:
		// any other type, return as is
		return input
	}
}
Example #19
0
// DeleteMessage calls the DeleteMessage MDS API.
func (mds *sdkService) DeleteMessage(log log.T, messageID string) (err error) {
	params := &ssmmds.DeleteMessageInput{
		MessageId: aws.String(messageID), // Required
	}
	log.Debug("Calling DeleteMessage with params", params)
	req, resp := mds.sdk.DeleteMessageRequest(params)
	if err = mds.sendRequest(req); err != nil {
		err = fmt.Errorf("DeleteMessage Error: %v", err)
		log.Debug(err)
	} else {
		log.Debug("DeleteMessage Response", resp)
	}
	return
}
Example #20
0
// RebootMachine reboots the machine
func RebootMachine(log log.T) {
	log.Info("Executing reboot request...")
	if RebootInitiated() {
		return
	}

	syncObject.Lock()
	defer syncObject.Unlock()
	if err := reboot(log); err != nil {
		log.Error("error in rebooting the machine", err)
		return
	}
	rebootInitiated = true
}
Example #21
0
// processRegistration handles flags related to the registration category
func processRegistration(log logger.T) (exitCode int) {
	if activationCode == "" || activationID == "" || region == "" {
		// clear registration
		if clear {
			return clearRegistration(log)
		}
		flagUsage()
		return 1
	}

	// check if previously registered
	if !force && registration.InstanceID() != "" {
		confirmation, err := askForConfirmation()
		if err != nil {
			log.Errorf("Registration failed due to %v", err)
			return 1
		}

		if !confirmation {
			log.Info("Registration canceled by user")
			return 1
		}
	}

	managedInstanceID, err := registerManagedInstance()
	if err != nil {
		log.Errorf("Registration failed due to %v", err)
		return 1
	}

	log.Infof("Successfully registered the instance with AWS SSM using Managed instance-id: %s", managedInstanceID)
	return 0
}
Example #22
0
// reboot is performed by running the following command
// shutdown -r -t 60
// The above command will cause the machine to reboot after 60 seconds
func reboot(log log.T) (err error) {
	log.Infof("rebooting the machine in %v seconds..", timeOutInSecondsBeforeReboot)
	command := exec.Command("shutdown", "-r", "-t", timeOutInSecondsBeforeReboot)
	var stdout, stderr bytes.Buffer
	command.Stderr = &stderr
	command.Stdout = &stdout
	err = command.Start()
	log.Infof("shutdown output: %v\n", stdout.String())

	if stderr.Len() != 0 {
		log.Errorf("shutdown error: %v\n", stderr.String())
	}
	return
}
Example #23
0
// FileCopy copies the content from reader to destinationPath file
func FileCopy(log log.T, destinationPath string, src io.Reader) (written int64, err error) {

	var file *os.File
	file, err = os.Create(destinationPath)
	if err != nil {
		log.Errorf("failed to create file. %v", err)
		return
	}
	defer file.Close()
	var size int64
	size, err = io.Copy(file, src)
	log.Infof("%s with %v bytes downloaded", destinationPath, size)
	return
}
Example #24
0
// killProcessOnCancel waits for a cancel request.
// If a cancel request is received, this method kills the underlying
// process of the command. This will unblock the command.Wait() call.
// If the task completed successfully this method returns with no action.
func killProcessOnCancel(log log.T, command *exec.Cmd, cancelFlag task.CancelFlag) {
	cancelFlag.Wait()
	if cancelFlag.Canceled() {
		log.Debug("Process cancelled. Attempting to stop process.")

		// task has been asked to cancel, kill process
		if err := killProcess(command.Process); err != nil {
			log.Error(err)
			return
		}

		log.Debug("Process stopped successfully.")
	}
}
Example #25
0
// uploadOutput uploads the stdout and stderr file to S3
func (c *contextManager) uploadOutput(log log.T, context *UpdateContext) (err error) {

	awsConfig := sdkutil.AwsConfig()
	var config appconfig.SsmagentConfig
	config, err = appconfig.Config(false)

	if err != nil {
		return fmt.Errorf("could not load config file: %v", err)
	}
	// If customers have provided override in app config, honor that.
	if config.S3.Region != "" {
		awsConfig.Region = &config.S3.Region
	}
	log.Infof("Uploading output files to region: %v", *awsConfig.Region)

	s3 := s3.New(session.New(awsConfig))

	// upload outputs (if any) to s3
	uploader := s3util.NewManager(s3)
	uploadOutputsToS3 := func() {
		// delete temp outputDir once we're done
		defer pluginutil.DeleteDirectory(log, updateutil.UpdateOutputDirectory(context.Current.UpdateRoot))

		// get stdout file path
		stdoutPath := updateutil.UpdateStandOutPath(context.Current.UpdateRoot, context.Current.StdoutFileName)
		s3Key := path.Join(context.Current.OutputS3KeyPrefix, context.Current.StdoutFileName)
		log.Debugf("Uploading %v to s3://%v/%v", stdoutPath, context.Current.OutputS3BucketName, s3Key)
		err = uploader.S3Upload(context.Current.OutputS3BucketName, s3Key, stdoutPath)
		if err != nil {
			log.Errorf("failed uploading %v to s3://%v/%v \n err:%v",
				stdoutPath,
				context.Current.OutputS3BucketName,
				s3Key,
				err)
		}

		// get stderr file path
		stderrPath := updateutil.UpdateStandOutPath(context.Current.UpdateRoot, context.Current.StderrFileName)
		s3Key = path.Join(context.Current.OutputS3KeyPrefix, context.Current.StderrFileName)
		log.Debugf("Uploading %v to s3://%v/%v", stderrPath, context.Current.OutputS3BucketName, s3Key)
		err = uploader.S3Upload(context.Current.OutputS3BucketName, s3Key, stderrPath)
		if err != nil {
			log.Errorf("failed uploading %v to s3://%v/%v \n err:%v", stderrPath, context.Current.StderrFileName, s3Key, err)
		}
	}

	uploadOutputsToS3()

	return nil
}
Example #26
0
func stop(log logger.T, cpm *coremanager.CoreManager) {
	log.Info("Stopping agent")
	log.Flush()
	cpm.Stop()
	log.Info("Bye.")
	log.Flush()
}
Example #27
0
// verifyInstallation checks installation result, verifies if agent is running
func verifyInstallation(mgr *updateManager, log log.T, context *UpdateContext, isRollback bool) (err error) {
	// Check if agent is running
	var isRunning = false
	var instanceContext *updateutil.InstanceContext

	if instanceContext, err = mgr.util.CreateInstanceContext(log); err != nil {
		return mgr.failed(context, log, updateutil.ErrorEnvironmentIssue, err.Error(), false)
	}

	log.Infof("Initiating update health check")
	isRunning, err = mgr.util.IsServiceRunning(log, instanceContext)
	if err != nil || !isRunning {
		if !isRollback {
			message := updateutil.BuildMessage(err,
				"failed to update %v to %v, %v",
				context.Current.PackageName,
				context.Current.TargetVersion,
				"failed to start the agent")

			context.Current.AppendError(log, message)
			context.Current.AppendInfo(
				log,
				"Initiating rollback %v to %v",
				context.Current.PackageName,
				context.Current.SourceVersion)
			// Update state to rollback
			if err = mgr.inProgress(context, log, Rollback); err != nil {
				return err
			}
			return mgr.rollback(mgr, log, context)
		}

		message := updateutil.BuildMessage(err,
			"failed to rollback %v to %v, %v",
			context.Current.PackageName,
			context.Current.SourceVersion,
			"failed to start the agent")
		// Rolled back, but service cannot start, Update failed.
		return mgr.failed(context, log, updateutil.ErrorCannotStartService, message, false)
	}

	log.Infof("%v is running", context.Current.PackageName)
	if !isRollback {
		return mgr.succeeded(context, log)
	}

	message := fmt.Sprintf("rolledback %v to %v", context.Current.PackageName, context.Current.SourceVersion)
	log.Infof("message is %v", message)
	return mgr.failed(context, log, updateutil.ErrorCannotStartService, message, false)
}
Example #28
0
// processParams smartly divides the input parameter string into valid string blocks
func processParams(log log.T, str string) []string {

	// Sample transformation:
	// str = "/v value "some path" myproperty=value"
	// result: []string{"/v", "value", "some path", "myproperty=value"}

	// contains the last split location of the string
	lastbit := 0

	params := []string{}

	// true if first quote was encountered else false
	quoteInit := false

	// Iterate through each character in str
	for i, c := range str {

		// Look for quotes or spaces
		// By default we split a string using space as a delimiter
		// If a quote(") is encountered then wait for the next quote irrespective of any spaces in between
		if c == '"' {
			if quoteInit {
				quoteInit = false
				params = append(params, str[lastbit:i+1])
				lastbit = i + 1
			} else {
				quoteInit = true
				lastbit = i
			}
		} else if c == ' ' && !quoteInit {
			if lastbit != i {
				params = append(params, str[lastbit:i])
			}
			lastbit = i + 1
		}
	}

	// This handles the last word in str
	if lastbit < len(str) {
		params = append(params, str[lastbit:len(str)])
	}

	log.Debug("Parameters after processing...")
	for _, param := range params {
		log.Debug(param)
	}

	return params
}
Example #29
0
// FailMessage calls the FailMessage MDS API.
func (mds *sdkService) FailMessage(log log.T, messageID string, failureType FailureType) (err error) {
	params := &ssmmds.FailMessageInput{
		FailureType: aws.String(string(failureType)), // Required
		MessageId:   aws.String(messageID),           // Required
	}
	log.Debug("Calling FailMessage with params", params)
	req, resp := mds.sdk.FailMessageRequest(params)
	if err = mds.sendRequest(req); err != nil {
		err = fmt.Errorf("FailMessage Error: %v", err)
		log.Debug(err)
	} else {
		log.Debug("FailMessage Response", resp)
	}
	return
}
Example #30
0
// reboot is performed by running the following command
// /sbin/shutdown -r +1
// The above command will cause the machine to reboot after 1 minute
func reboot(log log.T) (err error) {
	log.Infof("Rebooting the machine in %v Minutes..", timeOutInMinutesBeforeReboot)
	command := exec.Command("/sbin/shutdown", "-r", timeOutInMinutesBeforeReboot)
	command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	var stdout, stderr bytes.Buffer
	command.Stderr = &stderr
	command.Stdout = &stdout
	err = command.Start()
	log.Infof("shutdown output: %v\n", stdout.String())

	if stderr.Len() != 0 {
		log.Errorf("shutdown error: %v\n", stderr.String())
	}
	return
}