Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3154084
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/agents/kubevirt/fence_kubevirt.py b/agents/kubevirt/fence_kubevirt.py
index 8392b75a..8c27a033 100755
--- a/agents/kubevirt/fence_kubevirt.py
+++ b/agents/kubevirt/fence_kubevirt.py
@@ -1,152 +1,154 @@
#!@PYTHON@ -tt
import sys
import logging
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, fail_usage, run_delay, EC_STATUS, EC_FETCH_VM_UUID
try:
from kubernetes.client.exceptions import ApiException
except ImportError:
logging.error("Couldn\'t import kubernetes.client.exceptions.ApiException - not found or not accessible")
+def _get_namespace(options):
+ from kubernetes import config
+
+ ns = options.get("--namespace")
+ if ns is None:
+ ns = config.kube_config.list_kube_config_contexts()[1]['context']['namespace']
+
+ return ns
+
def get_nodes_list(conn, options):
logging.debug("Starting list/monitor operation")
result = {}
try:
apiversion = options.get("--apiversion")
- namespace = options.get("--namespace")
+ namespace = _get_namespace(options)
include_uninitialized = True
vm_api = conn.resources.get(api_version=apiversion, kind='VirtualMachine')
vm_list = vm_api.get(namespace=namespace)
for vm in vm_list.items:
result[vm.metadata.name] = ("", None)
except Exception as e:
logging.error("Exception when calling VirtualMachine list: %s", e)
return result
def get_power_status(conn, options):
logging.debug("Starting get status operation")
try:
apiversion = options.get("--apiversion")
- namespace = options.get("--namespace")
+ namespace = _get_namespace(options)
name = options.get("--plug")
vmi_api = conn.resources.get(api_version=apiversion,
kind='VirtualMachineInstance')
vmi = vmi_api.get(name=name, namespace=namespace)
return translate_status(vmi.status.phase)
except ApiException as e:
if e.status == 404:
try:
vm_api = conn.resources.get(api_version=apiversion, kind='VirtualMachine')
vm = vm_api.get(name=name, namespace=namespace)
except ApiException as e:
logging.error("VM %s doesn't exist", name)
fail(EC_FETCH_VM_UUID)
return "off"
logging.error("Failed to get power status, with API Exception: %s", e)
fail(EC_STATUS)
except Exception as e:
logging.error("Failed to get power status, with Exception: %s", e)
fail(EC_STATUS)
def translate_status(instance_status):
if instance_status == "Running":
return "on"
return "unknown"
def set_power_status(conn, options):
logging.debug("Starting set status operation")
try:
apiversion= options.get("--apiversion")
- namespace = options.get("--namespace")
+ namespace = _get_namespace(options)
name = options.get("--plug")
action = 'start' if options["--action"] == "on" else 'stop'
virtctl_vm_action(conn, action, namespace, name, apiversion)
except Exception as e:
logging.error("Failed to set power status, with Exception: %s", e)
fail(EC_STATUS)
def define_new_opts():
all_opt["namespace"] = {
"getopt" : ":",
"longopt" : "namespace",
"help" : "--namespace=[namespace] Namespace of the KubeVirt machine",
"shortdesc" : "Namespace of the KubeVirt machine.",
- "required" : "1",
+ "required" : "0",
"order" : 2
}
all_opt["kubeconfig"] = {
"getopt" : ":",
"longopt" : "kubeconfig",
"help" : "--kubeconfig=[kubeconfig] Kubeconfig file path",
"shortdesc": "Kubeconfig file path",
"required": "0",
"order": 4
}
all_opt["apiversion"] = {
"getopt" : ":",
"longopt" : "apiversion",
"help" : "--apiversion=[apiversion] Version of the KubeVirt API",
"shortdesc" : "Version of the KubeVirt API.",
"required" : "0",
"default" : "kubevirt.io/v1",
"order" : 5
}
def virtctl_vm_action(conn, action, namespace, name, apiversion):
path = '/apis/subresources.{api_version}/namespaces/{namespace}/virtualmachines/{name}/{action}'
path = path.format(api_version=apiversion, namespace=namespace, name=name, action=action)
return conn.request('put', path, header_params={'accept': '*/*'})
-def validate_options(required_options_list, options):
- for required_option in required_options_list:
- if required_option not in options:
- fail_usage("Failed: %s option must be provided" % required_option)
-
# Main agent method
def main():
conn = None
device_opt = ["port", "namespace", "kubeconfig", "ssl_insecure", "no_password", "apiversion"]
atexit.register(atexit_handler)
define_new_opts()
all_opt["power_timeout"]["default"] = "40"
options = check_input(device_opt, process_input(device_opt))
docs = {}
docs["shortdesc"] = "Fence agent for KubeVirt"
docs["longdesc"] = "fence_kubevirt is an I/O Fencing agent for KubeVirt."
docs["vendorurl"] = "https://kubevirt.io/"
show_docs(options, docs)
run_delay(options)
- validate_options(['--namespace'], options)
-
# Disable insecure-certificate-warning message
if "--ssl-insecure" in options:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
try:
from kubernetes import config
from openshift.dynamic import DynamicClient
kubeconfig = options.get('--kubeconfig')
k8s_client = config.new_client_from_config(config_file=kubeconfig)
conn = DynamicClient(k8s_client)
except ImportError:
logging.error("Couldn\'t import kubernetes.config or "
"openshift.dynamic.DynamicClient - not found or not accessible")
# Operate the fencing device
result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/tests/data/metadata/fence_kubevirt.xml b/tests/data/metadata/fence_kubevirt.xml
index 24e97558..ccb20c22 100644
--- a/tests/data/metadata/fence_kubevirt.xml
+++ b/tests/data/metadata/fence_kubevirt.xml
@@ -1,134 +1,134 @@
<?xml version="1.0" ?>
<resource-agent name="fence_kubevirt" shortdesc="Fence agent for KubeVirt" >
<longdesc>fence_kubevirt is an I/O Fencing agent for KubeVirt.</longdesc>
<vendor-url>https://kubevirt.io/</vendor-url>
<parameters>
<parameter name="action" unique="0" required="1">
<getopt mixed="-o, --action=[action]" />
<content type="string" default="reboot" />
<shortdesc lang="en">Fencing action</shortdesc>
</parameter>
<parameter name="plug" unique="0" required="1" obsoletes="port">
<getopt mixed="-n, --plug=[id]" />
<content type="string" />
<shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
</parameter>
<parameter name="port" unique="0" required="1" deprecated="1">
<getopt mixed="-n, --plug=[id]" />
<content type="string" />
<shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
</parameter>
<parameter name="ssl_insecure" unique="0" required="0">
<getopt mixed="--ssl-insecure" />
<content type="boolean" />
<shortdesc lang="en">Use SSL connection without verifying certificate</shortdesc>
</parameter>
- <parameter name="namespace" unique="0" required="1">
+ <parameter name="namespace" unique="0" required="0">
<getopt mixed="--namespace=[namespace]" />
<content type="string" />
<shortdesc lang="en">Namespace of the KubeVirt machine.</shortdesc>
</parameter>
<parameter name="kubeconfig" unique="0" required="0">
<getopt mixed="--kubeconfig=[kubeconfig]" />
<content type="string" />
<shortdesc lang="en">Kubeconfig file path</shortdesc>
</parameter>
<parameter name="apiversion" unique="0" required="0">
<getopt mixed="--apiversion=[apiversion]" />
<content type="string" default="kubevirt.io/v1" />
<shortdesc lang="en">Version of the KubeVirt API.</shortdesc>
</parameter>
<parameter name="quiet" unique="0" required="0">
<getopt mixed="-q, --quiet" />
<content type="boolean" />
<shortdesc lang="en">Disable logging to stderr. Does not affect --verbose or --debug-file or logging to syslog.</shortdesc>
</parameter>
<parameter name="verbose" unique="0" required="0">
<getopt mixed="-v, --verbose" />
<content type="boolean" />
<shortdesc lang="en">Verbose mode. Multiple -v flags can be stacked on the command line (e.g., -vvv) to increase verbosity.</shortdesc>
</parameter>
<parameter name="verbose_level" unique="0" required="0">
<getopt mixed="--verbose-level" />
<content type="integer" />
<shortdesc lang="en">Level of debugging detail in output. Defaults to the number of --verbose flags specified on the command line, or to 1 if verbose=1 in a stonith device configuration (i.e., on stdin).</shortdesc>
</parameter>
<parameter name="debug" unique="0" required="0" deprecated="1">
<getopt mixed="-D, --debug-file=[debugfile]" />
<content type="string" />
<shortdesc lang="en">Write debug information to given file</shortdesc>
</parameter>
<parameter name="debug_file" unique="0" required="0" obsoletes="debug">
<getopt mixed="-D, --debug-file=[debugfile]" />
<content type="string" />
<shortdesc lang="en">Write debug information to given file</shortdesc>
</parameter>
<parameter name="version" unique="0" required="0">
<getopt mixed="-V, --version" />
<content type="boolean" />
<shortdesc lang="en">Display version information and exit</shortdesc>
</parameter>
<parameter name="help" unique="0" required="0">
<getopt mixed="-h, --help" />
<content type="boolean" />
<shortdesc lang="en">Display help and exit</shortdesc>
</parameter>
<parameter name="separator" unique="0" required="0">
<getopt mixed="-C, --separator=[char]" />
<content type="string" default="," />
<shortdesc lang="en">Separator for CSV created by 'list' operation</shortdesc>
</parameter>
<parameter name="delay" unique="0" required="0">
<getopt mixed="--delay=[seconds]" />
<content type="second" default="0" />
<shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
</parameter>
<parameter name="disable_timeout" unique="0" required="0">
<getopt mixed="--disable-timeout=[true/false]" />
<content type="string" />
<shortdesc lang="en">Disable timeout (true/false) (default: true when run from Pacemaker 2.0+)</shortdesc>
</parameter>
<parameter name="login_timeout" unique="0" required="0">
<getopt mixed="--login-timeout=[seconds]" />
<content type="second" default="5" />
<shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc>
</parameter>
<parameter name="power_timeout" unique="0" required="0">
<getopt mixed="--power-timeout=[seconds]" />
<content type="second" default="40" />
<shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc>
</parameter>
<parameter name="power_wait" unique="0" required="0">
<getopt mixed="--power-wait=[seconds]" />
<content type="second" default="0" />
<shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
</parameter>
<parameter name="shell_timeout" unique="0" required="0">
<getopt mixed="--shell-timeout=[seconds]" />
<content type="second" default="3" />
<shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
</parameter>
<parameter name="stonith_status_sleep" unique="0" required="0">
<getopt mixed="--stonith-status-sleep=[seconds]" />
<content type="second" default="1" />
<shortdesc lang="en">Sleep X seconds between status calls during a STONITH action</shortdesc>
</parameter>
<parameter name="retry_on" unique="0" required="0">
<getopt mixed="--retry-on=[attempts]" />
<content type="integer" default="1" />
<shortdesc lang="en">Count of attempts to retry power on</shortdesc>
</parameter>
</parameters>
<actions>
<action name="on" automatic="0"/>
<action name="off" />
<action name="reboot" />
<action name="status" />
<action name="list" />
<action name="list-status" />
<action name="monitor" />
<action name="metadata" />
<action name="manpage" />
<action name="validate-all" />
</actions>
</resource-agent>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Feb 26, 7:38 AM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1463478
Default Alt Text
(12 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment