|
|
d00b21 |
From 3424464d3e447308f171399302cf76eb573a618f Mon Sep 17 00:00:00 2001
|
|
|
d00b21 |
From: Reid wahl <nrwahl@protonmail.com>
|
|
|
d00b21 |
Date: Fri, 24 Jul 2020 18:22:24 -0700
|
|
|
d00b21 |
Subject: [PATCH] fence_lpar: Fix parse error from long command line
|
|
|
d00b21 |
|
|
|
d00b21 |
When Pacemaker executes `fence_lpar` and the HMC command line is greater
|
|
|
d00b21 |
than 80 characters, a parse error causes agent failure. This can happen
|
|
|
d00b21 |
with a long user name and/or long managed system name. It happens only
|
|
|
d00b21 |
when Pacemaker spawns the `fence_lpar` process; it does not happen when
|
|
|
d00b21 |
`fence_lpar` is run from the CLI.
|
|
|
d00b21 |
|
|
|
d00b21 |
A long command line gets a carriage return ('\r') added at the 80
|
|
|
d00b21 |
character mark and wraps back to the beginning of the line with no line
|
|
|
d00b21 |
feed ('\n'), overwriting the displayed characters. `fence_lpar`'s regex
|
|
|
d00b21 |
matches handle this fine when it's run from the command line.
|
|
|
d00b21 |
|
|
|
d00b21 |
The problem is that when Pacemaker spawns fence_lpar, **for some
|
|
|
d00b21 |
reason** there are backspace characters in the buffer when we hit the
|
|
|
d00b21 |
'\r' character. This seems to overwrite some of the `conn.before`
|
|
|
d00b21 |
string. As a result, the regex doesn't match `conn.before`, and the
|
|
|
d00b21 |
agent fails.
|
|
|
d00b21 |
|
|
|
d00b21 |
This patch works around the `conn.before` weirdness by reading and
|
|
|
d00b21 |
discarding the first received line **before** any regex processing.
|
|
|
d00b21 |
|
|
|
d00b21 |
Resolves: RHBZ#1860544
|
|
|
d00b21 |
Resolves: RHBZ#1860545
|
|
|
d00b21 |
|
|
|
d00b21 |
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
|
|
d00b21 |
---
|
|
|
d00b21 |
agents/lpar/fence_lpar.py | 33 +++++++++++++++++++++++++++------
|
|
|
d00b21 |
1 file changed, 27 insertions(+), 6 deletions(-)
|
|
|
d00b21 |
|
|
|
d00b21 |
diff --git a/agents/lpar/fence_lpar.py b/agents/lpar/fence_lpar.py
|
|
|
d00b21 |
index 270bbe3b..9dfabc43 100644
|
|
|
d00b21 |
--- a/agents/lpar/fence_lpar.py
|
|
|
d00b21 |
+++ b/agents/lpar/fence_lpar.py
|
|
|
d00b21 |
@@ -19,6 +19,9 @@
|
|
|
d00b21 |
def get_power_status(conn, options):
|
|
|
d00b21 |
if options["--hmc-version"] == "3":
|
|
|
d00b21 |
conn.send("lssyscfg -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + " -F name,state\n")
|
|
|
d00b21 |
+
|
|
|
d00b21 |
+ # First line (command) may cause parsing issues if long
|
|
|
d00b21 |
+ conn.readline()
|
|
|
d00b21 |
conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
|
|
|
d00b21 |
|
|
|
d00b21 |
try:
|
|
|
d00b21 |
@@ -29,6 +32,9 @@ def get_power_status(conn, options):
|
|
|
d00b21 |
elif options["--hmc-version"] in ["4", "IVM"]:
|
|
|
d00b21 |
conn.send("lssyscfg -r lpar -m "+ options["--managed"] +
|
|
|
d00b21 |
" --filter 'lpar_names=" + options["--plug"] + "'\n")
|
|
|
d00b21 |
+
|
|
|
d00b21 |
+ # First line (command) may cause parsing issues if long
|
|
|
d00b21 |
+ conn.readline()
|
|
|
d00b21 |
conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
|
|
|
d00b21 |
|
|
|
d00b21 |
try:
|
|
|
d00b21 |
@@ -49,6 +55,9 @@ def set_power_status(conn, options):
|
|
|
d00b21 |
if options["--hmc-version"] == "3":
|
|
|
d00b21 |
conn.send("chsysstate -o " + options["--action"] + " -r lpar -m " + options["--managed"]
|
|
|
d00b21 |
+ " -n " + options["--plug"] + "\n")
|
|
|
d00b21 |
+
|
|
|
d00b21 |
+ # First line (command) may cause parsing issues if long
|
|
|
d00b21 |
+ conn.readline()
|
|
|
d00b21 |
conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
|
|
|
d00b21 |
elif options["--hmc-version"] in ["4", "IVM"]:
|
|
|
d00b21 |
if options["--action"] == "on":
|
|
|
d00b21 |
@@ -60,17 +69,23 @@ def set_power_status(conn, options):
|
|
|
d00b21 |
else:
|
|
|
d00b21 |
conn.send("chsysstate -o shutdown -r lpar --immed" +
|
|
|
d00b21 |
" -m " + options["--managed"] + " -n " + options["--plug"] + "\n")
|
|
|
d00b21 |
+
|
|
|
d00b21 |
+ # First line (command) may cause parsing issues if long
|
|
|
d00b21 |
+ conn.readline()
|
|
|
d00b21 |
conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
|
|
|
d00b21 |
|
|
|
d00b21 |
def get_lpar_list(conn, options):
|
|
|
d00b21 |
outlets = {}
|
|
|
d00b21 |
if options["--hmc-version"] == "3":
|
|
|
d00b21 |
conn.send("query_partition_names -m " + options["--managed"] + "\n")
|
|
|
d00b21 |
+
|
|
|
d00b21 |
+ ## We have to remove first line (command)
|
|
|
d00b21 |
+ conn.readline()
|
|
|
d00b21 |
conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
|
|
|
d00b21 |
|
|
|
d00b21 |
- ## We have to remove first 3 lines (command + header) and last line (part of new prompt)
|
|
|
d00b21 |
+ ## We have to remove next 2 lines (header) and last line (part of new prompt)
|
|
|
d00b21 |
####
|
|
|
d00b21 |
- res = re.search("^.+?\n(.+?\n){2}(.*)\n.*$", conn.before, re.S)
|
|
|
d00b21 |
+ res = re.search("^(.+?\n){2}(.*)\n.*$", conn.before, re.S)
|
|
|
d00b21 |
|
|
|
d00b21 |
if res == None:
|
|
|
d00b21 |
fail_usage("Unable to parse output of list command")
|
|
|
d00b21 |
@@ -81,11 +96,14 @@ def get_lpar_list(conn, options):
|
|
|
d00b21 |
elif options["--hmc-version"] == "4":
|
|
|
d00b21 |
conn.send("lssyscfg -r lpar -m " + options["--managed"] +
|
|
|
d00b21 |
" -F name:state\n")
|
|
|
d00b21 |
+
|
|
|
d00b21 |
+ ## We have to remove first line (command)
|
|
|
d00b21 |
+ conn.readline()
|
|
|
d00b21 |
conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
|
|
|
d00b21 |
|
|
|
d00b21 |
- ## We have to remove first line (command) and last line (part of new prompt)
|
|
|
d00b21 |
+ ## We have to remove last line (part of new prompt)
|
|
|
d00b21 |
####
|
|
|
d00b21 |
- res = re.search("^.+?\n(.*)\n.*$", conn.before, re.S)
|
|
|
d00b21 |
+ res = re.search("^(.*)\n.*$", conn.before, re.S)
|
|
|
d00b21 |
|
|
|
d00b21 |
if res == None:
|
|
|
d00b21 |
fail_usage("Unable to parse output of list command")
|
|
|
d00b21 |
@@ -100,11 +118,14 @@ def get_lpar_list(conn, options):
|
|
|
d00b21 |
elif options["--hmc-version"] == "IVM":
|
|
|
d00b21 |
conn.send("lssyscfg -r lpar -m " + options["--managed"] +
|
|
|
d00b21 |
" -F name,state\n")
|
|
|
d00b21 |
+
|
|
|
d00b21 |
+ ## We have to remove first line (command)
|
|
|
d00b21 |
+ conn.readline()
|
|
|
d00b21 |
conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
|
|
|
d00b21 |
|
|
|
d00b21 |
- ## We have to remove first line (command) and last line (part of new prompt)
|
|
|
d00b21 |
+ ## We have to remove last line (part of new prompt)
|
|
|
d00b21 |
####
|
|
|
d00b21 |
- res = re.search("^.+?\n(.*)\n.*$", conn.before, re.S)
|
|
|
d00b21 |
+ res = re.search("^(.*)\n.*$", conn.before, re.S)
|
|
|
d00b21 |
|
|
|
d00b21 |
if res == None:
|
|
|
d00b21 |
fail_usage("Unable to parse output of list command")
|