From f89ef9a9ee968c778af3444c7f9d2a39489fcf2b Mon Sep 17 00:00:00 2001 From: Harry Huang Date: Thu, 11 Oct 2018 11:05:02 +0800 Subject: Manage host power from cobbler JIRA: COMPASS-616 1. Use fence_ipmilan to control power of baremetal servers. Add fence_libvirt to control power of virtual servers. 2. Use power_manage field instead of ipmi field 3. Add power_type to specify machine's power manage tool 4. Store power manage information in db and update to cobbler 5. Manage power from cobbler for both virtual and baremetal machines Change-Id: Ic36ae640dc0aa1703566b5b0b549880a71be36e4 Signed-off-by: Harry Huang --- compass-cobbler/fence_libvirt | 106 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100755 compass-cobbler/fence_libvirt (limited to 'compass-cobbler/fence_libvirt') diff --git a/compass-cobbler/fence_libvirt b/compass-cobbler/fence_libvirt new file mode 100755 index 0000000..a59373b --- /dev/null +++ b/compass-cobbler/fence_libvirt @@ -0,0 +1,106 @@ +#!/usr/bin/env python +import libvirt +import yaml +import multiprocessing +import click +import sys + + +SETTING = "/root/cobbler/settings" +power_action_map = { + "on": "create", + "off": "destroy", + "status": "state" + } + +def get_virt_host(setting_file): + with open(setting_file) as fd: + try: + settings = yaml.load(fd) + return settings['server'] + except Exception: + raise RuntimeError("Can't get server ip from %s" % SETTING) + + +def get_libvit_connection(user, passwd): + # def request_cred(credentials, user_data): + # for credential in credentials: + # if credential[0] == libvirt.VIR_CRED_AUTHNAME: + # credential[4] = user + # elif credential[0] == libvirt.VIR_CRED_PASSPHRASE: + # credential[4] = passwd + # return 0 + # auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE], + # request_cred, None] + server = get_virt_host(SETTING) + conn = libvirt.open('qemu+tcp://%s/system' % server) + return conn + + +def libvirt_function(domain, action, rc): + function = getattr(domain, power_action_map.get(action)) + state, reason = domain.state() + if function.__name__ == "create": + if state == libvirt.VIR_DOMAIN_RUNNING: + rc.value = 1 + else: + rc.value = function() + elif function.__name__ == "destroy": + if state == libvirt.VIR_DOMAIN_SHUTOFF: + rc.value = 1 + else: + rc.value = function() + elif function.__name__ == "state": + rc.value = state + + +def power_action(action, hostname, user, passwd): + conn = get_libvit_connection(user, passwd) + domain = conn.lookupByName(hostname) + rc = multiprocessing.Value('i') + p = multiprocessing.Process(target=libvirt_function, + args=(domain, action, rc,)) + p.start() + p.join() + print rc.value + return rc.value + + +@click.command() +@click.option("--action") +@click.option("--hostname") +@click.option("--user") +@click.option("--passwd") +def cli(action, hostname, user, passwd): + power_action(action, hostname, user, passwd) + + +def no_cli(): + opt = {} + for line in sys.stdin.readlines(): + try: + line = line.strip() + name, value = line.split("=") + opt.update({name: value}) + except Exception: + continue + try: + if opt["action"] and opt["hostname"]: + power_action(opt["action"], opt["hostname"], + opt["user"], opt["passwd"]) + else: + raise RuntimeError("Invalid argument, \ + action: {0}, hostname: {1}, user: {2}, passwd: {3}".format( + opt.get("action", None), opt.get("hostname", None), + opt.get("user", None), opt.get("action", None))) + + +def main(): + if len(sys.argv) > 1: + cli() + else: + no_cli() + + +if __name__ == '__main__': + main() -- cgit 1.2.3-korg