Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-ocm-2.12] MGMT-19873: Fixing agents reuse problem in z/VM after reclaim #908

Open
wants to merge 3 commits into
base: release-ocm-2.12
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/commands/actions/download_boot_artifacts_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const (
bootLoaderConfigFileName string = "/00-assisted-discovery.conf"
bootLoaderConfigTemplateS390x string = `title Assisted Installer Discovery
version 999
options random.trust_cpu=on ignition.firstboot ignition.platform.id=metal coreos.live.rootfs_url=%s
options random.trust_cpu=on ai.ip_cfg_override=1 ignition.firstboot ignition.platform.id=metal coreos.live.rootfs_url=%s
linux %s
initrd %s`
bootLoaderConfigTemplate string = `title Assisted Installer Discovery
Expand Down
64 changes: 61 additions & 3 deletions src/commands/actions/reboot_for_reclaim.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package actions
import (
"encoding/json"
"fmt"
"regexp"
"runtime"
"strings"
"syscall"

"github.com/openshift/assisted-installer-agent/src/util"
Expand All @@ -29,25 +31,81 @@ func (a *rebootForReclaim) Run() (stdout, stderr string, exitCode int) {
}

if runtime.GOARCH == "s390x" {
var options string
var requiredCmdline string

stdout, stderr, exitCode = util.Execute("cat", "/boot/loader/entries/00-assisted-discovery.conf")
if exitCode != 0 {
return stdout, stderr, exitCode
}
lines := strings.Split(stdout, "\n")
for _, line := range lines {
if strings.HasPrefix(line, "options") {
options = strings.TrimSpace(strings.TrimPrefix(line, "options"))
break
}
}
stdout, stderr, exitCode := util.Execute("cat", "/proc/cmdline")
if exitCode != 0 {
return stdout, stderr, exitCode
}

// Parameters to extract from cmdline for agents
paramsToExtract := []string{
"ip",
"nameserver",
"rd.znet",
"zfcp.allow_lun_scan",
"rd.zfcp",
"rd.dasd",
}

requiredCmdline = extractCmdlineParams(stdout, paramsToExtract)

unshareCommand := "unshare"
unshareArgs := []string{
"--mount",
"bash",
"-c",
fmt.Sprintf("mount -o remount,rw /boot && zipl -V -t /boot -i %s/%s -r %s/%s -c /boot/loader/entries%s -p /boot/loader/entries%s",
fmt.Sprintf("mount -o remount,rw /boot && zipl -V -t /boot -i %s/%s -r %s/%s -P '%s %s'",
artifactsFolder, kernelFile,
artifactsFolder, initrdFile,
bootLoaderConfigFileName,
bootLoaderConfigFileName),
options,
requiredCmdline),
}
stdout, stderr, exitCode = util.Execute(unshareCommand, unshareArgs...)
if exitCode != 0 {
return stdout, stderr, exitCode
}

}
return util.Execute("systemctl", "reboot")
}

// Returns the paramsToExtract parameters which are present in cmdlineOutput, if no paramter matched then returns any empty string ''

func extractCmdlineParams(cmdlineOutput string, paramsToExtract []string) string {
cmdlineParams := make(map[string]string)
var requiredCmdline string

// Matches the exact param from paramsToExtract followed by an = sign, and then capture the non-whitespace value after the =
for _, param := range paramsToExtract {
regex := regexp.MustCompile(fmt.Sprintf(`\b%s=([^\s]+)`, param))
match := regex.FindStringSubmatch(cmdlineOutput)
if len(match) > 1 {
cmdlineParams[param] = match[1]
}
}

// Convert the key value pairs in map to string with predefined order which is in paramsToExtract
for _, key := range paramsToExtract {
if value, exists := cmdlineParams[key]; exists {
requiredCmdline += fmt.Sprintf("%s=%s ", key, value)
}
}
return requiredCmdline
}

// Unused, but required as part of ActionInterface
func (a *rebootForReclaim) Command() string {
return "systemctl"
Expand Down
21 changes: 21 additions & 0 deletions src/commands/actions/reboot_for_reclaim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,25 @@ var _ = Describe("reboot_for_reclaim", func() {
It("fails when given bad input", func() {
badParamsCommonTests(models.StepTypeRebootForReclaim, []string{})
})

Context("extractCmdlineParams", func() {
It("returns the expected parameters when valid cmdline output is given", func() {
cmdlineOutput := "ip=192.168.1.1 nameserver=8.8.8.8 rd.znet=enabled zfcp.allow_lun_scan=0 rd.zfcp=xyz rd.dasd=abc"
paramsToExtract := []string{"ip", "nameserver", "rd.znet", "zfcp.allow_lun_scan", "rd.zfcp", "rd.dasd"}

expectedCmdline := "ip=192.168.1.1 nameserver=8.8.8.8 rd.znet=enabled zfcp.allow_lun_scan=0 rd.zfcp=xyz rd.dasd=abc "
requiredCmdline := extractCmdlineParams(cmdlineOutput, paramsToExtract)

Expect(requiredCmdline).To(Equal(expectedCmdline))
})

It("returns an empty string when no parameters match", func() {
cmdlineOutput := "other_param=value"
paramsToExtract := []string{"ip", "nameserver"}

requiredCmdline := extractCmdlineParams(cmdlineOutput, paramsToExtract)

Expect(requiredCmdline).To(Equal(""))
})
})
})