Merge pull request #2 from Azure/dev/vivekl/fixGetSequenceNumber

Fix Get sequence number from config folder
This commit is contained in:
Viv Lingaiah 2022-10-21 02:52:48 +05:30 коммит произвёл GitHub
Родитель 2c5a3e80cb 2fb356f6d1
Коммит 63e98f8b38
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 28 добавлений и 78 удалений

Просмотреть файл

@ -73,49 +73,11 @@ func install(ctx *log.Context, h HandlerEnvironment, report *RunCommandInstanceV
return "", "", errors.Wrap(err, "failed to create data dir")
}
// If the file mrseq does not exists
// the extension has never been installed on this VMs before
// if _, err := os.Stat(mostRecentSequence); os.IsNotExist(err) {
// migrateToMostRecentSequence(ctx, h, seqNum)
// }
ctx.Log("event", "created data dir", "path", dataDir)
ctx.Log("event", "installed")
return "", "", nil
}
func migrateToMostRecentSequence(ctx *log.Context, h HandlerEnvironment, seqNum int) {
// The status folder is used instead of the settings because the settings file is written
// by the agent before install is called. As a result, the extension cannot determine if this
// is a new install or an upgrade.
//
// If this is an upgrade there will be a status file. The agent will re-write the last status
// file to indicate that the upgrade happened successfully. The extension uses the last status
// sequence number to determine the last settings file that was executed.
//
// The agent helpfully copies mrseq every time an extension is upgraded thereby preserving the
// most recent executed sequence. If extensions use mrseq they benefit from this mechanism, and
// do not have invent another method. The CustomScript extension should have been using this
// from the beginning, but it was not.
//
computedSeqNum, err := FindSeqNumStatus(h.HandlerEnvironment.StatusFolder)
if err != nil {
// If there was an error, the sequence number is zero.
ctx.Log("event", "migrate to mrseq", "error", err)
return
}
fout, err := os.Create(mostRecentSequence)
if err != nil {
ctx.Log("event", "migrate to mrseq", "error", err)
return
}
defer fout.Close()
ctx.Log("event", "migrate to mrseq", "message", fmt.Sprintf("migrated mrseq to %v", computedSeqNum))
fout.WriteString(fmt.Sprintf("%v", computedSeqNum))
}
func uninstall(ctx *log.Context, h HandlerEnvironment, report *RunCommandInstanceView, extName string, seqNum int) (string, string, error) {
{ // a new context scope with path
ctx = ctx.With("path", dataDir)

Просмотреть файл

@ -23,16 +23,6 @@ type handlerSettingsCommon struct {
SettingsCertThumbprint string `json:"protectedSettingsCertThumbprint"`
}
// settingsPath returns the full path to the .settings file with the
// highest sequence number found in configFolder.
func settingsPath(configFolder string) (string, error) {
seq, err := FindSeqNumConfig(configFolder)
if err != nil {
return "", fmt.Errorf("Cannot find seqnum: %v", err)
}
return filepath.Join(configFolder, fmt.Sprintf("%d%s", seq, ".settings")), nil
}
// ReadSettings locates the .settings file and returns public settings
// JSON, and protected settings JSON (by decrypting it with the keys in
// configFolder).

Просмотреть файл

@ -37,6 +37,8 @@ var (
// configExtensionName environment variable should be set by VMAgent to extension name
configExtensionName = "ConfigExtensionName"
configFileExtension = ".settings"
)
func main() {
@ -64,23 +66,26 @@ func main() {
os.Exit(cmd.failExitCode)
}
}
extensionName := os.Getenv(configExtensionName)
if extensionName != "" {
ctx = ctx.With("extensionName", extensionName)
downloadDir = downloadDir + "/" + extensionName
mostRecentSequence = extensionName + "." + mostRecentSequence
pidFilePath = extensionName + "." + pidFilePath
}
// Read the seqNum from latest config file in case VMAgent did not set it as env variable
if seqNum == -1 {
seqNum, err = FindSeqNumConfig(hEnv.HandlerEnvironment.ConfigFolder)
seqNum, err = FindSequenceNumberFromConfig(hEnv.HandlerEnvironment.ConfigFolder, configFileExtension, extensionName)
if err != nil {
ctx.Log("messsage", "failed to find sequence number", "error", err)
ctx.Log("FindSequenceNumberFromConfig", "failed to find sequence number from config folder.", "error", err)
} else {
ctx.Log("FindSequenceNumberFromConfig", fmt.Sprintf("Sequence number determined from config folder: %d", seqNum))
}
}
ctx = ctx.With("seq", seqNum)
extName := os.Getenv(configExtensionName)
if extName != "" {
ctx = ctx.With("extensionName", extName)
downloadDir = downloadDir + "/" + extName
mostRecentSequence = extName + "." + mostRecentSequence
pidFilePath = extName + "." + pidFilePath
}
// check sub-command preconditions, if any, before executing
ctx.Log("event", "start")
if cmd.pre != nil {
@ -100,15 +105,15 @@ func main() {
EndTime: "",
}
reportInstanceView(ctx, hEnv, extName, seqNum, StatusTransitioning, cmd, &instanceView)
reportInstanceView(ctx, hEnv, extensionName, seqNum, StatusTransitioning, cmd, &instanceView)
// execute the subcommand
stdout, stderr, err := cmd.invoke(ctx, hEnv, &instanceView, extName, seqNum)
stdout, stderr, err := cmd.invoke(ctx, hEnv, &instanceView, extensionName, seqNum)
if err != nil {
ctx.Log("event", "failed to handle", "error", err)
instanceView.ExecutionMessage = "Execution failed: " + err.Error()
instanceView.EndTime = time.Now().UTC().Format(time.RFC3339)
reportInstanceView(ctx, hEnv, extName, seqNum, StatusSuccess, cmd, &instanceView)
reportInstanceView(ctx, hEnv, extensionName, seqNum, StatusSuccess, cmd, &instanceView)
os.Exit(cmd.failExitCode)
}
instanceView.ExecutionMessage = "Execution completed"
@ -116,7 +121,7 @@ func main() {
instanceView.Output = stdout
instanceView.Error = stderr
instanceView.EndTime = time.Now().UTC().Format(time.RFC3339)
reportInstanceView(ctx, hEnv, extName, seqNum, StatusSuccess, cmd, &instanceView)
reportInstanceView(ctx, hEnv, extensionName, seqNum, StatusSuccess, cmd, &instanceView)
ctx.Log("event", "end")
}

Просмотреть файл

@ -17,29 +17,22 @@ const (
chmod = os.FileMode(0600)
)
// FindSeqNumConfig gets the laster seq no from config files
func FindSeqNumConfig(path string) (int, error) {
return FindSeqNum(path, ".settings")
}
// FindSeqNumStatus gets the laster seq no from status files
func FindSeqNumStatus(path string) (int, error) {
return FindSeqNum(path, ".status")
}
// FindSeqNum finds the file with the highest number under configFolder
// named like 0.settings, 1.settings so on.
func FindSeqNum(path, ext string) (int, error) {
g, err := filepath.Glob(filepath.Join(path, fmt.Sprintf("*%s", ext)))
// FindSequenceNumberFromConfig finds the file with the highest sequence number for an extension under configFolder
// named like <RunCommandName>.0.settings, <RunCommandName>.1.settings so on.
func FindSequenceNumberFromConfig(path, fileExtension string, extensionName string) (int, error) {
g, err := filepath.Glob(filepath.Join(path, fmt.Sprintf("%s.*%s", extensionName, fileExtension)))
if err != nil {
return 0, err
}
seqs := make([]int, len(g))
for _, v := range g {
f := filepath.Base(v)
i, err := strconv.Atoi(strings.TrimSuffix(f, filepath.Ext(f)))
fileNameWithoutExtension := strings.TrimSuffix(f, filepath.Ext(f))
dotAndSequenceNumberString := filepath.Ext(fileNameWithoutExtension) // returns something like ".<sequenceNumber>"
sequenceNumberString := dotAndSequenceNumberString[1:] // Remove '.' in the front
i, err := strconv.Atoi(sequenceNumberString)
if err != nil {
return 0, fmt.Errorf("Can't parse int from filename: %s", f)
continue // continue to the next filename if Atoi fails
}
seqs = append(seqs, i)
}