Пример #1
0
// updateAgent downloads the installation packages and update the agent
func runUpdateAgent(
	p *Plugin,
	config contracts.Configuration,
	log log.T,
	manager pluginHelper,
	util updateutil.T,
	rawPluginInput interface{},
	cancelFlag task.CancelFlag,
	outputS3BucketName string,
	outputS3KeyPrefix string,
	startTime time.Time) (out UpdatePluginOutput) {
	var pluginInput UpdatePluginInput
	var err error
	var context *updateutil.InstanceContext

	if isUpdateSupported, err := util.IsPlatformSupportedForUpdate(log); err == nil && !isUpdateSupported {
		out.Failed(log, fmt.Errorf("Unsupported platform for update"))
		return
	}

	if err = jsonutil.Remarshal(rawPluginInput, &pluginInput); err != nil {
		out.Failed(log,
			fmt.Errorf("invalid format in plugin properties %v;\nerror %v", rawPluginInput, err))
		return
	}

	if context, err = util.CreateInstanceContext(log); err != nil {
		out.Failed(log, err)
		return
	}

	//Use default manifest location is the override is not present
	if len(pluginInput.Source) == 0 {
		pluginInput.Source = p.ManifestLocation
	}
	//Calculate manifest location base on current instance's region
	pluginInput.Source = strings.Replace(pluginInput.Source, updateutil.RegionHolder, context.Region, -1)
	//Calculate updater package name base on agent name
	pluginInput.UpdaterName = pluginInput.AgentName + updateutil.UpdaterPackageNamePrefix
	//Generate update output
	targetVersion := pluginInput.TargetVersion
	if len(targetVersion) == 0 {
		targetVersion = "latest"
	}
	out.AppendInfo(log, "Updating %v from %v to %v",
		pluginInput.AgentName,
		version.Version,
		targetVersion)

	//Download manifest file
	manifest, downloadErr := manager.downloadManifest(log, util, &pluginInput, context, &out)
	if downloadErr != nil {
		out.Failed(log, downloadErr)
		return
	}

	//Validate update details
	noNeedToUpdate := false
	if noNeedToUpdate, err = manager.validateUpdate(log, &pluginInput, context, manifest, &out); noNeedToUpdate {
		if err != nil {
			out.Failed(log, err)
		}
		return
	}

	//Download updater and retrieve the version number
	updaterVersion := ""
	if updaterVersion, err = manager.downloadUpdater(
		log, util, pluginInput.UpdaterName, manifest, &out, context); err != nil {
		out.Failed(log, err)
		return
	}

	//Generate update command base on the update detail
	cmd := ""
	if cmd, err = manager.generateUpdateCmd(log,
		manifest,
		&pluginInput,
		context,
		updateutil.UpdaterFilePath(appconfig.UpdaterArtifactsRoot, pluginInput.UpdaterName, updaterVersion),
		config.MessageId,
		p.StdoutFileName,
		p.StderrFileName,
		outputS3KeyPrefix,
		outputS3BucketName); err != nil {
		out.Failed(log, err)
		return
	}
	log.Debugf("Update command %v", cmd)

	//Save update plugin result to local file, updater will read it during agent update
	updatePluginResult := &updateutil.UpdatePluginResult{
		StandOut:      out.Stdout,
		StartDateTime: startTime,
	}
	if err = util.SaveUpdatePluginResult(log, appconfig.UpdaterArtifactsRoot, updatePluginResult); err != nil {
		out.Failed(log, err)
		return
	}

	// If disk space is not sufficient, fail the update to prevent installation and notify user in output
	// If loading disk space fails, continue to update (agent update is backed by rollback handler)
	log.Infof("Checking available disk space ...")
	if isDiskSpaceSufficient, err := util.IsDiskSpaceSufficientForUpdate(log); err == nil && !isDiskSpaceSufficient {
		out.Failed(log, errors.New("Insufficient available disk space"))
		return
	}

	log.Infof("Start Installation")
	log.Infof("Hand over update process to %v", pluginInput.UpdaterName)
	//Execute updater, hand over the update process
	workDir := updateutil.UpdateArtifactFolder(
		appconfig.UpdaterArtifactsRoot, pluginInput.UpdaterName, updaterVersion)

	if err = util.ExeCommand(
		log,
		cmd,
		workDir,
		appconfig.UpdaterArtifactsRoot,
		p.StdoutFileName,
		p.StderrFileName,
		true); err != nil {
		out.Failed(log, err)
		return
	}

	out.Pending()
	return
}