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/Dockerfile | 8 ++- compass-cobbler/fence_libvirt | 106 +++++++++++++++++++++++++++++++++ compass-cobbler/fence_libvirt.template | 4 ++ 3 files changed, 116 insertions(+), 2 deletions(-) create mode 100755 compass-cobbler/fence_libvirt create mode 100644 compass-cobbler/fence_libvirt.template (limited to 'compass-cobbler') diff --git a/compass-cobbler/Dockerfile b/compass-cobbler/Dockerfile index e5c1459..9ee1e64 100644 --- a/compass-cobbler/Dockerfile +++ b/compass-cobbler/Dockerfile @@ -7,7 +7,7 @@ ARG BRANCH=master RUN yum -y update && \ yum -y install epel-release && \ yum -y install wget dhcp bind syslinux pykickstart file initscripts net-tools tcpdump xinetd vim \ - avahi avahi-tools ntp fence_agents && \ + avahi avahi-tools ntp fence-agents libvirt-devel python-devel gcc python-pip && \ wget http://artifacts.opnfv.org/compass4nfv/package/cobbler/cobbler-2.6.10-1.fc22.noarch.rpm && \ wget http://artifacts.opnfv.org/compass4nfv/package/cobbler/cobbler-web-2.6.10-1.fc22.noarch.rpm && \ yum -y localinstall cobbler-2.6.10-1.fc22.noarch.rpm cobbler-web-2.6.10-1.fc22.noarch.rpm && \ @@ -16,7 +16,11 @@ RUN yum -y update && \ systemctl enable httpd && \ systemctl enable dhcpd && \ systemctl enable xinetd && \ - systemctl enable ntpd + systemctl enable ntpd && \ + pip install libvirt-python click + +COPY fence_libvirt /usr/sbin/fence_libvirt +COPY fence_libvirt.template /etc/cobbler/power/fence_libvirt.template # some tweaks on services RUN sed -i -e 's/\(^.*disable.*=\) yes/\1 no/' /etc/xinetd.d/tftp && \ 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() diff --git a/compass-cobbler/fence_libvirt.template b/compass-cobbler/fence_libvirt.template new file mode 100644 index 0000000..2e38628 --- /dev/null +++ b/compass-cobbler/fence_libvirt.template @@ -0,0 +1,4 @@ +action=$power_mode +hostname=$hostname +user=$power_user +passwd=$power_pass -- cgit 1.2.3-korg