Commit 5d642e15 authored by Yusei Tahara's avatar Yusei Tahara

Add a fence agent for PiKVM.

parent c37434ae
#!/usr/bin/python3
# pcs -f stonith_cfg stonith create MyFence fence_pikvm pcmk_host_check=static-list pcmk_host_list=comp1,comp2 pcmk_host_map='comp1:192.168.0.1#password1;comp2:192.168.0.2#password2'
# pcs -f stonith_cfg property set stonith-enabled=true
# pcs -f stonith_cfg property set stonith-timeout=100s
import sys
import subprocess
import json
import time
import atexit
sys.path.append('/usr/share/fence')
from fencing import *
from fencing import fail_usage
def get_ipaddr_password(options):
plug = options['--plug']
return plug.split('#', 1)
def get_power_status(conn, options):
ip, password = get_ipaddr_password(options)
args = ('curl', '-k', '-u', 'admin:%s' % password, 'https://%s/api/atx' % ip)
completed_process = subprocess.run(args, capture_output=True)
try:
result_dict = json.loads(completed_process.stdout)
except:
fail_usage('Failed: PiKVM API is not working.')
return
if result_dict['result']['leds']['power']:
return 'on'
return 'off'
def set_power_off(conn, options):
ip, password = get_ipaddr_password(options)
args = ('curl', '-X', 'POST', '-k', '-u', 'admin:%s' % password, 'https://%s/api/atx/power?action=off' % ip)
subprocess.run(args, capture_output=True)
power_status = None
for i in range(20):
time.sleep(5)
power_status = get_power_status(conn, options)
if power_status == 'off':
break
if power_status != 'off':
fail_usage('Failed: PiKVM fence agent failed to power off. %r' % power_status)
return
def set_power_on(conn, options):
ip, password = get_ipaddr_password(options)
args = ('curl', '-X', 'POST', '-k', '-u', 'admin:%s' % password, 'https://%s/api/atx/power?action=on' % ip)
subprocess.run(args, capture_output=True)
power_status = None
for i in range(20):
time.sleep(5)
power_status = get_power_status(conn, options)
if power_status == 'on':
break
elif power_status == 'off':
subprocess.run(args, capture_output=True)
if power_status != 'on':
fail_usage('Failed: PiKVM fence agent failed to power on. %r' % power_status)
return
def set_power_status(conn, options):
action = options["--action"]
if action in ('off', 'reboot'):
result = set_power_off(conn, options)
if action == 'reboot':
result = set_power_on(conn, options)
elif action == 'on':
result = set_power_on(conn, options)
else:
fail_usage('Failed: PiKVM fence agent does not support %r.' % action)
return
return result
def main():
device_opt = ['no_password', 'port']
atexit.register(atexit_handler)
options = check_input(device_opt, process_input(device_opt))
docs = {}
docs['shortdesc'] = 'Fence agent for PiKVM'
docs['longdesc'] = 'Fence agent for PiKVM'
docs['vendorurl'] = 'https://www.pikvm.org/'
show_docs(options, docs)
result = fence_action(None, options, set_power_status, get_power_status)
sys.exit(result)
if __name__ == '__main__':
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment