Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/agents/amt/fence_amt.py b/agents/amt/fence_amt.py
index feec6e3e..80d3f74c 100644
--- a/agents/amt/fence_amt.py
+++ b/agents/amt/fence_amt.py
@@ -1,128 +1,132 @@
#!@PYTHON@ -tt
import sys, re, os
import atexit
-from pipes import quote
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage, is_executable, run_command, run_delay
+try:
+ from shlex import quote
+except ImportError:
+ from pipes import quote
+
def get_power_status(_, options):
output = amt_run_command(options, create_command(options, "status"))
match = re.search('Powerstate:[\\s]*(..)', str(output))
status = match.group(1) if match else None
if status == None:
return "fail"
elif status == "S0": # SO = on; S3 = sleep; S5 = off
return "on"
else:
return "off"
def set_power_status(_, options):
amt_run_command(options, create_command(options, options["--action"]))
return
def reboot_cycle(_, options):
(status, _, _) = run_command(options, create_command(options, "cycle"))
return not bool(status)
def amt_run_command(options, command, timeout=None):
env = os.environ.copy()
x = quote(options["--password"])
x = x[:-1] if x.endswith("'") else x
x = x[1:] if x.startswith("'") else x
env["AMT_PASSWORD"] = x
# This is needed because setting the AMT_PASSWORD env
# variable only works when no pipe is involved. E.g.:
# - Broken:
# $ AMT_PASSWORD='foobar' echo 'y' | /usr/bin/amttool nuc2 powerdown
# 401 Unauthorized at /usr/bin/amttool line 129.
# - Working:
# $ AMT_PASSWORD='foobar' sh -c "(echo 'y' | /usr/bin/amttool nuc2 powerdown)"
# execute: powerdown
# result: pt_status: success
newcommand = "sh -c \"(%s)\"" % command
return run_command(options, newcommand, timeout, env)
def create_command(options, action):
cmd = options["--amttool-path"]
# --ip / -a
cmd += " " + options["--ip"]
# --action / -o
if action == "status":
cmd += " info"
elif action == "on":
cmd = "echo \"y\"|" + cmd
cmd += " powerup"
elif action == "off":
cmd = "echo \"y\"|" + cmd
cmd += " powerdown"
elif action == "cycle":
cmd = "echo \"y\"|" + cmd
cmd += " powercycle"
if action in ["on", "off", "cycle"] and "--boot-option" in options:
cmd += options["--boot-option"]
# --use-sudo / -d
if "--use-sudo" in options:
cmd = options["--sudo-path"] + " " + cmd
return cmd
def define_new_opts():
all_opt["boot_option"] = {
"getopt" : "b:",
"longopt" : "boot-option",
"help" : "-b, --boot-option=[option] "
"Change the default boot behavior of the machine. (pxe|hd|hdsafe|cd|diag)",
"required" : "0",
"shortdesc" : "Change the default boot behavior of the machine.",
"choices" : ["pxe", "hd", "hdsafe", "cd", "diag"],
"order" : 1
}
all_opt["amttool_path"] = {
"getopt" : ":",
"longopt" : "amttool-path",
"help" : "--amttool-path=[path] Path to amttool binary",
"required" : "0",
"shortdesc" : "Path to amttool binary",
"default" : "@AMTTOOL_PATH@",
"order": 200
}
def main():
atexit.register(atexit_handler)
device_opt = ["ipaddr", "no_login", "passwd", "boot_option", "no_port",
"sudo", "amttool_path", "method"]
define_new_opts()
all_opt["ipport"]["default"] = "16994"
options = check_input(device_opt, process_input(device_opt))
docs = {}
docs["shortdesc"] = "Fence agent for AMT"
docs["longdesc"] = "fence_amt is an I/O Fencing agent \
which can be used with Intel AMT. This agent calls support software amttool\
(http://www.kraxel.org/cgit/amtterm/)."
docs["vendorurl"] = "http://www.intel.com/"
show_docs(options, docs)
run_delay(options)
if not is_executable(options["--amttool-path"]):
fail_usage("Amttool not found or not accessible")
result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/agents/ipmilan/fence_ipmilan.py b/agents/ipmilan/fence_ipmilan.py
index f751de69..0acf977d 100644
--- a/agents/ipmilan/fence_ipmilan.py
+++ b/agents/ipmilan/fence_ipmilan.py
@@ -1,233 +1,237 @@
#!@PYTHON@ -tt
import sys, re, os
import atexit
-from pipes import quote
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage, is_executable, run_command, run_delay
+try:
+ from shlex import quote
+except ImportError:
+ from pipes import quote
+
def get_power_status(_, options):
output = _run_command(options, "status")
match = re.search('[Cc]hassis [Pp]ower is [\\s]*([a-zA-Z]{2,3})', str(output))
status = match.group(1) if match else None
return status
def set_power_status(_, options):
_run_command(options, options["--action"])
return
def reboot_cycle(_, options):
output = _run_command(options, "cycle")
return bool(re.search('chassis power control: cycle', str(output).lower()))
def reboot_diag(_, options):
output = _run_command(options, "diag")
return bool(re.search('chassis power control: diag', str(output).lower()))
def _run_command(options, action):
cmd, log_cmd = create_command(options, action)
return run_command(options, cmd, log_command=log_cmd)
def create_command(options, action):
class Cmd:
cmd = ""
log = ""
@classmethod
def append(cls, cmd, log=None):
cls.cmd += cmd
cls.log += (cmd if log is None else log)
# --use-sudo / -d
if "--use-sudo" in options:
Cmd.append(options["--sudo-path"] + " ")
Cmd.append(options["--ipmitool-path"])
# --lanplus / -L
if "--lanplus" in options and options["--lanplus"] in ["", "1"]:
Cmd.append(" -I lanplus")
else:
Cmd.append(" -I lan")
# --ip / -a
Cmd.append(" -H " + options["--ip"])
# --port / -n
if "--ipport" in options:
Cmd.append(" -p " + options["--ipport"])
# --target
if "--target" in options:
Cmd.append(" -t " + options["--target"])
# --username / -l
if "--username" in options and len(options["--username"]) != 0:
Cmd.append(" -U " + quote(options["--username"]))
# --auth / -A
if "--auth" in options:
Cmd.append(" -A " + options["--auth"])
# --password / -p
if "--password" in options:
Cmd.append(" -P " + quote(options["--password"]), " -P [set]")
else:
Cmd.append(" -P ''", " -P [set]")
# --cipher / -C
if "--cipher" in options:
Cmd.append(" -C " + options["--cipher"])
if "--privlvl" in options:
Cmd.append(" -L " + options["--privlvl"])
if "--hexadecimal-kg" in options:
Cmd.append(" -y " + options["--hexadecimal-kg"])
if "--ipmitool-timeout" in options:
Cmd.append(" -N " + options["--ipmitool-timeout"])
# --action / -o
Cmd.append(" chassis power " + action)
# --verbose-level
if options["--verbose-level"] > 1:
Cmd.append(" -" + "v" * (options["--verbose-level"] - 1))
return (Cmd.cmd, Cmd.log)
def define_new_opts():
all_opt["lanplus"] = {
"getopt" : "P",
"longopt" : "lanplus",
"help" : "-P, --lanplus Use Lanplus to improve security of connection",
"required" : "0",
"default" : "0",
"shortdesc" : "Use Lanplus to improve security of connection",
"order": 1
}
all_opt["auth"] = {
"getopt" : "A:",
"longopt" : "auth",
"help" : "-A, --auth=[auth] IPMI Lan Auth type (md5|password|none)",
"required" : "0",
"shortdesc" : "IPMI Lan Auth type.",
"choices" : ["md5", "password", "none"],
"order": 1
}
all_opt["cipher"] = {
"getopt" : "C:",
"longopt" : "cipher",
"help" : "-C, --cipher=[cipher] Ciphersuite to use (same as ipmitool -C parameter)",
"required" : "0",
"shortdesc" : "Ciphersuite to use (same as ipmitool -C parameter)",
"order": 1
}
all_opt["privlvl"] = {
"getopt" : "L:",
"longopt" : "privlvl",
"help" : "-L, --privlvl=[level] "
"Privilege level on IPMI device (callback|user|operator|administrator)",
"required" : "0",
"shortdesc" : "Privilege level on IPMI device",
"default" : "administrator",
"choices" : ["callback", "user", "operator", "administrator"],
"order": 1
}
all_opt["ipmitool_path"] = {
"getopt" : ":",
"longopt" : "ipmitool-path",
"help" : "--ipmitool-path=[path] Path to ipmitool binary",
"required" : "0",
"shortdesc" : "Path to ipmitool binary",
"default" : "@IPMITOOL_PATH@",
"order": 200
}
all_opt["ipmitool_timeout"] = {
"getopt" : ":",
"longopt" : "ipmitool-timeout",
"help" : "--ipmitool-timeout=[timeout] Timeout (sec) for IPMI operation",
"required" : "0",
"shortdesc" : "Timeout (sec) for IPMI operation",
"default" : "2",
"order": 201
}
all_opt["target"] = {
"getopt" : ":",
"longopt" : "target",
"help" : "--target=[targetaddress] Bridge IPMI requests to the remote target address",
"required" : "0",
"shortdesc" : "Bridge IPMI requests to the remote target address",
"order": 1
}
all_opt["hexadecimal_kg"] = {
"getopt" : ":",
"longopt" : "hexadecimal-kg",
"help" : "--hexadecimal-kg=[key] Hexadecimal-encoded Kg key for IPMIv2 authentication",
"required" : "0",
"shortdesc" : "Hexadecimal-encoded Kg key for IPMIv2 authentication",
"order": 1
}
def main():
atexit.register(atexit_handler)
device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd",
"diag", "lanplus", "auth", "cipher", "privlvl", "sudo",
"ipmitool_path", "ipmitool_timeout", "method", "target", "hexadecimal_kg"]
define_new_opts()
all_opt["power_wait"]["default"] = 2
if os.path.basename(sys.argv[0]) == "fence_ilo3":
all_opt["power_wait"]["default"] = "4"
all_opt["lanplus"]["default"] = "1"
elif os.path.basename(sys.argv[0]) == "fence_ilo4":
all_opt["lanplus"]["default"] = "1"
elif os.path.basename(sys.argv[0]) == "fence_ilo5":
all_opt["lanplus"]["default"] = "1"
elif os.path.basename(sys.argv[0]) == "fence_ipmilanplus":
all_opt["lanplus"]["default"] = "1"
all_opt["ipport"]["default"] = "623"
all_opt["method"]["help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: onoff)\n" \
"WARNING! This fence agent might report success before the node is powered off. " \
"You should use -m/method onoff if your fence device works correctly with that option."
options = check_input(device_opt, process_input(device_opt))
docs = {}
docs["shortdesc"] = "Fence agent for IPMI"
docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\
which can be used with machines controlled by IPMI.\
This agent calls support software ipmitool (http://ipmitool.sf.net/). \
WARNING! This fence agent might report success before the node is powered off. \
You should use -m/method onoff if your fence device works correctly with that option."
docs["vendorurl"] = ""
docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"),
("fence_ilo4", "Fence agent for HP iLO4"),
("fence_ilo5", "Fence agent for HP iLO5"),
("fence_ipmilanplus", "Fence agent for IPMIv2 lanplus"),
("fence_imm", "Fence agent for IBM Integrated Management Module"),
("fence_idrac", "Fence agent for Dell iDRAC")]
show_docs(options, docs)
run_delay(options)
if not is_executable(options["--ipmitool-path"]):
fail_usage("Ipmitool not found or not accessible")
reboot_fn = reboot_cycle
if options["--action"] == "diag":
# Diag is a special action that can't be verified so we will reuse reboot functionality
# to minimize impact on generic library
options["--action"] = "reboot"
options["--method"] = "cycle"
reboot_fn = reboot_diag
result = fence_action(None, options, set_power_status, get_power_status, None, reboot_fn)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/agents/ironic/fence_ironic.py b/agents/ironic/fence_ironic.py
index 66d84fca..d0c9d9c1 100644
--- a/agents/ironic/fence_ironic.py
+++ b/agents/ironic/fence_ironic.py
@@ -1,130 +1,134 @@
#!@PYTHON@ -tt
import atexit
import logging
import os
import re
import sys
-from pipes import quote
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage, is_executable, run_command, run_delay
+try:
+ from shlex import quote
+except ImportError:
+ from pipes import quote
+
def get_name_or_uuid(options):
return options["--uuid"] if "--uuid" in options else options["--plug"]
def get_power_status(_, options):
output = ironic_run_command(options, "status")
stdout = output[1]
match = re.search('power[\\s]*([a-zA-Z]{2,3})', str(stdout))
status = match.group(1) if match else None
return status
def set_power_status(_, options):
ironic_run_command(options, options["--action"])
return
def get_devices_list(_, options):
nodes = {}
output = ironic_run_command(options, "list")
stdout = output[1]
for line in stdout.splitlines():
uuid = "UUID"
try:
(uuid, name, state) = line.split(',')
except ValueError:
pass
if "UUID" in uuid:
continue # skip line header
match = re.search('power[\\s]*([a-zA-Z]{2,3})', state)
status = match.group(1) if match else None
nodes[uuid] = (name, status)
return nodes
def ironic_run_command(options, action, timeout=None):
cmd = options["--openstack-path"] + " baremetal"
env = os.environ.copy()
# --username / -l
if "--username" in options and len(options["--username"]) != 0:
env["OS_USERNAME"] = options["--username"]
# --password / -p
if "--password" in options:
env["OS_PASSWORD"] = options["--password"]
# --tenant-name -t
if "--tenant-name" in options:
env["OS_TENANT_NAME"] = options["--tenant-name"]
# --auth-url
if "--auth-url" in options:
env["OS_AUTH_URL"] = options["--auth-url"]
# --action / -o
if action == "status":
cmd += " show %s -c power_state --format value" % (get_name_or_uuid(options))
elif action in ["on", "off"]:
cmd += " power %s %s" % (action, get_name_or_uuid(options))
elif action == "list":
cmd += " list -c 'Instance UUID' -c Name -c 'Power State' --format csv --quote minimal"
logging.debug("cmd -> %s" % cmd)
return run_command(options, cmd, timeout, env)
def define_new_opts():
all_opt["auth-url"] = {
"getopt" : ":",
"longopt" : "auth-url",
"help" : "--auth-url=[authurl] Auth URL",
"required" : "1",
"shortdesc" : "Keystone Admin Auth URL",
"order": 1
}
all_opt["tenant-name"] = {
"getopt" : "t:",
"longopt" : "tenant-name",
"help" : "-t, --tenant-name=[tenant] Tenantname",
"required" : "0",
"shortdesc" : "Keystone Admin Tenant",
"default": "admin",
"order": 1
}
all_opt["openstack-path"] = {
"getopt" : ":",
"longopt" : "openstack-path",
"help" : "--openstack-path=[path] Path to openstack binary",
"required" : "0",
"shortdesc" : "Path to the OpenStack binary",
"default" : "@OPENSTACK_PATH@",
"order": 200
}
def main():
atexit.register(atexit_handler)
device_opt = ["login", "passwd", "port", "auth-url", "tenant-name", "openstack-path"]
define_new_opts()
options = check_input(device_opt, process_input(device_opt))
docs = {}
docs["shortdesc"] = "Fence agent for OpenStack's Ironic (Bare Metal as a service) service"
docs["longdesc"] = "fence_ironic is a Fencing agent \
which can be used with machines controlled by the Ironic service. \
This agent calls the openstack CLI. \
WARNING! This fence agent is not intended for production use. Relying on a functional ironic service for fencing is not a good design choice."
docs["vendorurl"] = "https://wiki.openstack.org/wiki/Ironic"
show_docs(options, docs)
run_delay(options)
if not is_executable(options["--openstack-path"]):
fail_usage("openstack tool not found or not accessible")
result = fence_action(None, options, set_power_status, get_power_status, get_devices_list)
sys.exit(result)
if __name__ == "__main__":
main()

File Metadata

Mime Type
text/x-diff
Expires
Mon, Feb 24, 11:51 AM (14 h, 57 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1452440
Default Alt Text
(15 KB)

Event Timeline