From 2150c5b72779c0e07bbf4831da4ace7529b220ef Mon Sep 17 00:00:00 2001 From: Stephen Soltesz Date: Wed, 18 Feb 2009 18:39:52 +0000 Subject: [PATCH] add a new rpm package for monitor-runlevelagent that packages RunlevelAgent.py in the root context, and with which the bootmanager build script can pull in the script to run at boot time. --- Monitor.spec | 34 +++++++++++-- RunlevelAgent.py | 108 ++++++++++++++++++++++++++++++++++++++++++ monitor-runlevel.init | 50 +++++++++++++++++++ 3 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 RunlevelAgent.py create mode 100644 monitor-runlevel.init diff --git a/Monitor.spec b/Monitor.spec index efca5fe..192c10b 100644 --- a/Monitor.spec +++ b/Monitor.spec @@ -77,15 +77,26 @@ as Zabbix DB. ######################################## PCU Control %package pcucontrol -Summary: PCU Controls for Monitor and PLCAPI -Group: Applications/System -Requires: python +summary: pcu controls for monitor and plcapi +group: applications/system +requires: python %description pcucontrol -Both Monitor and the PLCAPI use a set of common commands to reboot machines -using their external or internal PCUs. This package is a library of several +both monitor and the plcapi use a set of common commands to reboot machines +using their external or internal pcus. this package is a library of several supported models. +####################################### RunlevelAgent +%package runlevelagent +summary: the RunlevelAgent that reports node runlevels +group: applications/system +requires: python + +%description runlevelagent +The RunlevelAgent starts as early as possible during boot-up and production +mode to actively report the observed runlevel to PLC and update the +'last_contact' field. + %prep %setup -q @@ -141,6 +152,11 @@ chmod 777 $RPM_BUILD_ROOT/var/www/cgi-bin/monitor/monitorconfig.php #install -D -m 755 monitor-default.conf $RPM_BUILD_ROOT/etc/monitor.conf #cp $RPM_BUILD_ROOT/usr/share/%{name}/monitorconfig-default.py $RPM_BUILD_ROOT/usr/share/%{name}/monitorconfig.py +#################### RunlevelAgent +install -D -m 755 RunlevelAgent.py $RPM_BUILD_ROOT/usr/bin/RunlevelAgent.py +install -D -m 755 monitor-runlevelagent.init $RPM_BUILD_ROOT/%{_initrddir}/monitor-runlevelagent + + %clean rm -rf $RPM_BUILD_ROOT @@ -167,6 +183,10 @@ rm -rf $RPM_BUILD_ROOT %files pcucontrol %{python_sitearch}/pcucontrol +%files runlevelagent +/usr/bin/RunlevelAgent.py +/%{_initrddir}/monitor-runlevelagent + %post server # TODO: this will be nice when we have a web-based service running., such as # an API server or so on. @@ -189,6 +209,10 @@ patch -d /var/www/html/zabbix/ -p0 < /usr/share/%{name}/zabbix/zabbix-auto-login chkconfig --add monitor chkconfig monitor on +%post runlevelagent +chkconfig --add monitor-runlevelagent +chkconfig monitor-runlevelagent on + %changelog * Mon Jan 05 2009 Stephen Soltesz - Monitor-2.0-0 - new changes are significantly different, that I'm upping the number for clarity. diff --git a/RunlevelAgent.py b/RunlevelAgent.py new file mode 100644 index 0000000..49fa631 --- /dev/null +++ b/RunlevelAgent.py @@ -0,0 +1,108 @@ +#!/usr/bin/python + +import xml, xmlrpclib +import logging +import time +import traceback +import sys +import os +import string + +CONFIG_FILE="/tmp/source/configuration" +SESSION_FILE="/etc/planetlab/session" + +def read_config_file(filename): + ## NOTE: text copied from BootManager.py + # TODO: unify this code to make it common. i.e. use ConfigParser module + vars = {} + vars_file= file(filename,'r') + validConfFile = True + for line in vars_file: + # if its a comment or a whitespace line, ignore + if line[:1] == "#" or string.strip(line) == "": + continue + + parts= string.split(line,"=") + if len(parts) != 2: + print "Invalid line in vars file: %s" % line + validConfFile = False + break + + name= string.strip(parts[0]) + value= string.strip(parts[1]) + vars[name]= value + + vars_file.close() + if not validConfFile: + print "Unable to read configuration vars." + + return vars + +try: + sys.path = ['/etc/planetlab'] + sys.path + import plc_config + api_server_url = "https://" + plc_config.PLC_API_HOST + plc_config.PLC_API_PATH +except: + filename=CONFIG_FILE + vars = read_config_file(filename) + api_server_url = vars['BOOT_API_SERVER'] + + +class Auth: + def __init__(self, username=None, password=None, **kwargs): + if 'session' in kwargs: + self.auth= { 'AuthMethod' : 'session', + 'session' : kwargs['session'] } + else: + if username==None and password==None: + self.auth = {'AuthMethod': "anonymous"} + else: + self.auth = {'Username' : username, + 'AuthMethod' : 'password', + 'AuthString' : password} +class PLC: + def __init__(self, auth, url): + self.auth = auth + self.url = url + self.api = xmlrpclib.Server(self.url, verbose=False, allow_none=True) + + def __getattr__(self, name): + method = getattr(self.api, name) + if method is None: + raise AssertionError("method does not exist") + + return lambda *params : method(self.auth.auth, *params) + + def __repr__(self): + return self.api.__repr__() + +def main(): + + f=open(SESSION_FILE,'r') + session_str=f.read().strip() + api = PLC(Auth(session=session_str), api_server_url) + # NOTE: should we rely on bootmanager for this functionality? + api.AuthCheck() + + while True: + print "reporting status: ", os.popen("uptime").read().strip() + try: + # NOTE: alternately, check other stuff in the environment to infer + # run_level + # is BootManager running? + # what is the boot_state at PLC? + # does /vservers exist? + # what about /tmp/source? + # is BootManager in /tmp/source? + # is /tmp/mnt/sysimg mounted? + # how long have we been running? if we were in safeboot and + # still running, we're likely in failboot now. + # length of runtime increases the certainty of inferred state. + # + api.ReportRunlevel({'run_level' : 'safeboot'}) + except: + traceback.print_exc() + time.sleep(30) + +if __name__ == "__main__": + main() diff --git a/monitor-runlevel.init b/monitor-runlevel.init new file mode 100644 index 0000000..f22d587 --- /dev/null +++ b/monitor-runlevel.init @@ -0,0 +1,50 @@ +#!/bin/bash +# +# monitor-runlevelagent starts the RunlevelAgent in production mode. +# +# Load before nm, vcached, and vservers, vserver-reference +# chkconfig: 3 14 85 +# description: Start RunlevelAgent to report the current Runlevel to PLC at +# periodic intervals. +# +# Stephen Soltesz +# Copyright (C) 2008 The Trustees of Princeton University +# +# $Id$ +# + +case "$1" in + start|restart|reload) + ;; + stop|status) + exit 0 + ;; + *) + echo $"Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac + +# NOTE: If user already exists, this just exists with status 9. I think it's +# ok to simply let this command check and error out. +# Parse PLC configuration +if [ -r /etc/planetlab/plc_config ] ; then + . /etc/planetlab/plc_config +else + PLC_NAME="PlanetLab" + PLC_SLICE_PREFIX="pl" + PLC_BOOT_HOST="boot.planet-lab.org" +fi + +USER="${PLC_SLICE_PREFIX}_monitor" +/usr/sbin/useradd -p "" -m $USER &> /dev/null || : + +if [ ! -d /home/$USER/.ssh ] ; then + mkdir /home/$USER/.ssh + chmod 700 /home/$USER/.ssh + chown $USER.$USER /home/$USER/.ssh +fi + +URL="http://${PLC_BOOT_HOST}/PlanetLabConf/keys.php?$USER" +curl -s "$URL" > /home/$USER/.ssh/authorized_keys +chown $USER.$USER /home/$USER/.ssh/authorized_keys -- 2.43.0