summaryrefslogtreecommitdiffstats
path: root/func/minion/modules
diff options
context:
space:
mode:
Diffstat (limited to 'func/minion/modules')
-rwxr-xr-xfunc/minion/modules/Makefile18
-rw-r--r--func/minion/modules/__init__.py0
-rw-r--r--func/minion/modules/command.py38
-rw-r--r--func/minion/modules/copyfile.py115
-rwxr-xr-xfunc/minion/modules/func_module.py67
-rwxr-xr-xfunc/minion/modules/hardware.py130
-rwxr-xr-xfunc/minion/modules/process.py76
-rwxr-xr-xfunc/minion/modules/reboot.py29
-rwxr-xr-xfunc/minion/modules/service.py59
-rwxr-xr-xfunc/minion/modules/smart.py53
-rwxr-xr-xfunc/minion/modules/test.py19
-rwxr-xr-xfunc/minion/modules/virt.py272
-rw-r--r--func/minion/modules/yum.py48
13 files changed, 924 insertions, 0 deletions
diff --git a/func/minion/modules/Makefile b/func/minion/modules/Makefile
new file mode 100755
index 0000000..f2bc6c4
--- /dev/null
+++ b/func/minion/modules/Makefile
@@ -0,0 +1,18 @@
+
+
+PYFILES = $(wildcard *.py)
+
+PYCHECKER = /usr/bin/pychecker
+PYFLAKES = /usr/bin/pyflakes
+
+clean::
+ @rm -fv *.pyc *~ .*~ *.pyo
+ @find . -name .\#\* -exec rm -fv {} \;
+ @rm -fv *.rpm
+
+
+pychecker::
+ @$(PYCHECKER) $(PYFILES) || exit 0
+
+pyflakes::
+ @$(PYFLAKES) $(PYFILES) || exit 0
diff --git a/func/minion/modules/__init__.py b/func/minion/modules/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/func/minion/modules/__init__.py
diff --git a/func/minion/modules/command.py b/func/minion/modules/command.py
new file mode 100644
index 0000000..06adaaa
--- /dev/null
+++ b/func/minion/modules/command.py
@@ -0,0 +1,38 @@
+# Copyright 2007, Red Hat, Inc
+# James Bowes <jbowes@redhat.com>
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+"""
+Abitrary command execution module for func.
+"""
+
+from modules import func_module
+
+import sub_process
+
+class Command(func_module.FuncModule):
+
+ def __init__(self):
+ self.methods = {
+ "run" : self.run
+ }
+ func_module.FuncModule.__init__(self)
+
+ def run(self, command):
+ """
+ Runs a command, returning the return code, stdout, and stderr as a tuple.
+ NOT FOR USE WITH INTERACTIVE COMMANDS.
+ """
+
+ cmdref = sub_process.Popen(command.split(),stdout=sub_process.PIPE,stderr=sub_process.PIPE, shell=False)
+ data = cmdref.communicate()
+ return (cmdref.returncode, data[0], data[1])
+
+methods = Command()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/copyfile.py b/func/minion/modules/copyfile.py
new file mode 100644
index 0000000..a4f91f0
--- /dev/null
+++ b/func/minion/modules/copyfile.py
@@ -0,0 +1,115 @@
+# Copyright 2007, Red Hat, Inc
+# seth vidal
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+import sha
+import os
+import time
+import shutil
+
+from modules import func_module
+
+
+
+
+class CopyFile(func_module.FuncModule):
+
+ def __init__(self):
+ self.methods = {
+ "copyfile" : self.copyfile,
+ "checksum" : self.checksum
+ }
+ func_module.FuncModule.__init__(self)
+
+ def checksum(self, thing):
+
+ CHUNK=2**16
+ thissum = sha.new()
+ if os.path.exists(thing):
+ fo = open(thing, 'r', CHUNK)
+ chunk = fo.read
+ while chunk:
+ chunk = fo.read(CHUNK)
+ thissum.update(chunk)
+ fo.close()
+ del fo
+ else:
+ # assuming it's a string of some kind
+ thissum.update(thing)
+
+ return thissum.hexdigest()
+
+
+ def copyfile(self, filepath, filebuf, mode=0644, uid=0, gid=0, force=None):
+ # -1 = problem file was not copied
+ # 1 = file was copied
+ # 0 = file was not copied b/c file is unchanged
+
+
+ # we should probably verify mode,uid,gid are valid as well
+
+ dirpath = os.path.dirname(filepath)
+ basepath = os.path.basename(filepath)
+ if not os.path.exists(dirpath):
+ os.makedirs(dirpath)
+
+ remote_sum = self.checksum(filebuf)
+ local_sum = 0
+ if os.path.exists(filepath):
+ local_sum = self.checksum(filepath)
+
+ if remote_sum != local_sum or force is not None:
+ # back up the localone
+ if os.path.exists(filepath):
+ if not self._backuplocal(filepath):
+ return -1
+
+ # do the new write
+ try:
+ fo = open(filepath, 'w')
+ fo.write(filebuf)
+ fo.close()
+ del fo
+ except (IOError, OSError), e:
+ # XXX logger output here
+ return -1
+ else:
+ return 0
+
+ # hmm, need to figure out proper exceptions -akl
+ try:
+ # we could intify the mode here if it's a string
+ os.chmod(filepath, mode)
+ os.chown(filepath, uid, gid)
+ except (IOError, OSError), e:
+ return -1
+
+ return 1
+
+ def _backuplocal(self, fn):
+ """
+ make a date-marked backup of the specified file,
+ return True or False on success or failure
+ """
+ # backups named basename-YYYY-MM-DD@HH:MM~
+ ext = time.strftime("%Y-%m-%d@%H:%M~", time.localtime(time.time()))
+ backupdest = '%s.%s' % (fn, ext)
+
+ try:
+ shutil.copy2(fn, backupdest)
+ except shutil.Error, e:
+ #XXX logger output here
+ return False
+ return True
+
+
+
+methods = CopyFile()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/func_module.py b/func/minion/modules/func_module.py
new file mode 100755
index 0000000..aa3c132
--- /dev/null
+++ b/func/minion/modules/func_module.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+
+##
+## Copyright 2007, Red Hat, Inc
+## see AUTHORS
+##
+## This software may be freely redistributed under the terms of the GNU
+## general public license.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+##
+
+
+from func import logger
+from func.config import read_config
+from func.commonconfig import FuncdConfig
+
+
+class FuncModule(object):
+
+ # the version is meant to
+ version = "0.0.0"
+ api_version = "0.0.0"
+ description = "No Description provided"
+
+ def __init__(self):
+
+ config_file = '/etc/func/minion.conf'
+ self.config = read_config(config_file, FuncdConfig)
+ self.__init_log()
+ self.__base_methods = {
+ # __'s so we don't clobber useful names
+ "module_version" : self.__module_version,
+ "module_api_version" : self.__module_api_version,
+ "module_description" : self.__module_description,
+ "list_methods" : self.__list_methods
+ }
+
+ def __init_log(self):
+ log = logger.Logger()
+ self.logger = log.logger
+
+ def register_rpc(self, handlers, module_name):
+ # add the internal methods, note that this means they
+ # can get clobbbered by subclass versions
+ for meth in self.__base_methods:
+ handlers["%s.%s" % (module_name, meth)] = self.__base_methods[meth]
+ for meth in self.methods:
+ handlers["%s.%s" % (module_name,meth)] = self.methods[meth]
+
+ def __list_methods(self):
+ return self.methods.keys() + self.__base_methods.keys()
+
+ def __module_version(self):
+ return self.version
+
+ def __module_api_version(self):
+ return self.api_version
+
+ def __module_description(self):
+ return self.description
+
+
+methods = FuncModule()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/hardware.py b/func/minion/modules/hardware.py
new file mode 100755
index 0000000..79faf4c
--- /dev/null
+++ b/func/minion/modules/hardware.py
@@ -0,0 +1,130 @@
+#!/usr/bin/python
+
+##
+## Hardware profiler plugin
+## requires the "smolt" client package be installed
+## but also relies on lspci for some things
+##
+## Copyright 2007, Red Hat, Inc
+## Michael DeHaan <mdehaan@redhat.com>
+##
+## This software may be freely redistributed under the terms of the GNU
+## general public license.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+##
+
+
+# other modules
+import sys
+
+# our modules
+import sub_process
+from modules import func_module
+
+# =================================
+
+class HardwareModule(func_module.FuncModule):
+ def __init__(self):
+ self.methods = {
+ "info" : self.info,
+ "hal_info" : self.hal_info
+ }
+ func_module.FuncModule.__init__(self)
+
+ def hal_info(self):
+ """
+ Returns the output of lshal, but split up into seperate devices
+ for easier parsing. Each device is a entry in the return hash.
+ """
+
+ cmd = sub_process.Popen(["/usr/bin/lshal"],shell=False,stdout=sub_process.PIPE)
+ data = cmd.communicate()[0]
+
+ data = data.split("\n")
+
+ results = {}
+ current = ""
+ label = data[0]
+ for d in data:
+ if d == '':
+ results[label] = current
+ current = ""
+ label = ""
+ else:
+ if label == "":
+ label = d
+ current = current + d
+
+ return results
+
+
+ def info(self,with_devices=True):
+ """
+ Returns a struct of hardware information. By default, this pulls down
+ all of the devices. If you don't care about them, set with_devices to
+ False.
+ """
+ return hw_info(with_devices)
+
+# =================================
+
+def hw_info(with_devices=True):
+
+ # this may fail if smolt is not installed. That's ok. hal_info will
+ # still work.
+
+ # hack: smolt is not installed in site-packages
+ sys.path.append("/usr/share/smolt/client")
+ import smolt
+
+ hardware = smolt.Hardware()
+ host = hardware.host
+
+ # NOTE: casting is needed because these are DBusStrings, not real strings
+ data = {
+ 'os' : str(host.os),
+ 'defaultRunlevel' : str(host.defaultRunlevel),
+ 'bogomips' : str(host.bogomips),
+ 'cpuVendor' : str(host.cpuVendor),
+ 'cpuModel' : str(host.cpuModel),
+ 'numCpus' : str(host.numCpus),
+ 'cpuSpeed' : str(host.cpuSpeed),
+ 'systemMemory' : str(host.systemMemory),
+ 'systemSwap' : str(host.systemSwap),
+ 'kernelVersion' : str(host.kernelVersion),
+ 'language' : str(host.language),
+ 'platform' : str(host.platform),
+ 'systemVendor' : str(host.systemVendor),
+ 'systemModel' : str(host.systemModel),
+ 'formfactor' : str(host.formfactor),
+ 'selinux_enabled' : str(host.selinux_enabled),
+ 'selinux_enforce' : str(host.selinux_enforce)
+ }
+
+ # if no hardware info requested, just return the above bits
+ if not with_devices:
+ return data
+
+ collection = data["devices"] = []
+
+ for item in hardware.deviceIter():
+
+ (VendorID,DeviceID,SubsysVendorID,SubsysDeviceID,Bus,Driver,Type,Description) = item
+
+ collection.append({
+ "VendorID" : str(VendorID),
+ "DeviceID" : str(DeviceID),
+ "SubsysVendorID" : str(SubsysVendorID),
+ "Bus" : str(Bus),
+ "Driver" : str(Driver),
+ "Type" : str(Type),
+ "Description" : str(Description)
+ })
+
+ return data
+
+methods = HardwareModule()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/process.py b/func/minion/modules/process.py
new file mode 100755
index 0000000..b48b910
--- /dev/null
+++ b/func/minion/modules/process.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python
+
+##
+## Process lister (control TBA)
+##
+## Copyright 2007, Red Hat, Inc
+## Michael DeHaan <mdehaan@redhat.com>
+##
+## This software may be freely redistributed under the terms of the GNU
+## general public license.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+##
+
+# other modules
+import sub_process
+import codes
+
+# our modules
+from modules import func_module
+
+# =================================
+
+class ProcessModule(func_module.FuncModule):
+ def __init__(self):
+ self.methods = {
+ "info" : self.info,
+ "kill" : self.kill,
+ "pkill" : self.pkill
+ }
+ func_module.FuncModule.__init__(self)
+
+ def info(self,flags="-auxh"):
+ """
+ Returns a struct of hardware information. By default, this pulls down
+ all of the devices. If you don't care about them, set with_devices to
+ False.
+ """
+
+ flags.replace(";","") # prevent stupidity
+
+
+ #FIXME: we need to swallow stdout/stderr as well, right now it spews to the console
+ cmd = sub_process.Popen(["/bin/ps", flags] ,executable="/bin/ps", stdout=sub_process.PIPE,shell=False)
+ data = cmd.communicate()[0]
+
+ results = []
+
+ for x in data.split("\n"):
+ tokens = x.split()
+ results.append(tokens)
+
+ return results
+
+
+ def kill(self,pid,signal="TERM"):
+ if pid == "0":
+ raise codes.FuncException("Killing pid group 0 not permitted")
+ if signal == "":
+ # this is default /bin/kill behaviour, it claims, but enfore it anyway
+ signal = "-TERM"
+ if signal[0] != "-":
+ signal = "-%s" % signal
+ rc = sub_process.call(["/bin/kill",signal, pid], executable="/bin/kill", shell=False)
+ print rc
+ return rc
+
+ def pkill(self,name,level=""):
+ # example killall("thunderbird","-9")
+ rc = sub_process.call(["/usr/bin/pkill", name, level], executable="/usr/bin/pkill", shell=False)
+ return rc
+
+methods = ProcessModule()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/reboot.py b/func/minion/modules/reboot.py
new file mode 100755
index 0000000..8772b8f
--- /dev/null
+++ b/func/minion/modules/reboot.py
@@ -0,0 +1,29 @@
+# Copyright 2007, Red Hat, Inc
+# James Bowes <jbowes@redhat.com>
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+from modules import func_module
+
+import sub_process
+
+class Reboot(func_module.FuncModule):
+
+ def __init__(self):
+ self.methods = {
+ "reboot" : self.reboot
+ }
+ func_module.FuncModule.__init__(self)
+
+ def reboot(self, when='now', message=''):
+ return sub_process.call(["/sbin/shutdown", '-r', when, message])
+
+
+methods = Reboot()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/service.py b/func/minion/modules/service.py
new file mode 100755
index 0000000..433d70b
--- /dev/null
+++ b/func/minion/modules/service.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+## func
+##
+## Copyright 2007, Red Hat, Inc
+## Michael DeHaan <mdehaan@redhat.com>
+##
+## This software may be freely redistributed under the terms of the GNU
+## general public license.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+##
+##
+
+import codes
+from modules import func_module
+
+import sub_process
+import os
+
+class Service(func_module.FuncModule):
+
+ def __init__(self):
+ self.methods = {
+ "start" : self.start,
+ "stop" : self.stop,
+ "restart" : self.restart,
+ "reload" : self.reload,
+ "status" : self.status
+ }
+ func_module.FuncModule.__init__(self)
+
+ def __command(self, service_name, command):
+
+ filename = os.path.join("/etc/rc.d/init.d/",service_name)
+ if os.path.exists(filename):
+ return sub_process.call(["/sbin/service", service_name, command])
+ else:
+ raise codes.FuncException("Service not installed: %s" % service_name)
+
+ def start(self, service_name):
+ return self.__command(service_name, "start")
+
+ def stop(self, service_name):
+ return self.__command(service_name, "stop")
+
+ def restart(self, service_name):
+ return self.__command(service_name, "restart")
+
+ def reload(self, service_name):
+ return self.__command(service_name, "reload")
+
+ def status(self, service_name):
+ return self.__command(service_name, "status")
+
+methods = Service()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/smart.py b/func/minion/modules/smart.py
new file mode 100755
index 0000000..c65dfb1
--- /dev/null
+++ b/func/minion/modules/smart.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+
+##
+## Grabs status from SMART to see if your hard drives are ok
+## Returns in the format of (return code, [line1, line2, line3,...])
+##
+## Copyright 2007, Red Hat, Inc
+## Michael DeHaan <mdehaan@redhat.com>
+##
+## This software may be freely redistributed under the terms of the GNU
+## general public license.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+##
+
+# other modules
+import sub_process
+
+# our modules
+from modules import func_module
+
+# =================================
+
+class SmartModule(func_module.FuncModule):
+ def __init__(self):
+ self.methods = {
+ "info" : self.info,
+ }
+ func_module.FuncModule.__init__(self)
+
+ def info(self,flags="-q onecheck"):
+ """
+ Returns a struct of hardware information. By default, this pulls down
+ all of the devices. If you don't care about them, set with_devices to
+ False.
+ """
+
+ flags.replace(";","") # prevent stupidity
+
+ cmd = sub_process.Popen("/usr/sbin/smartd %s" % flags,stdout=sub_process.PIPE,shell=True)
+ data = cmd.communicate()[0]
+
+ results = []
+
+ for x in data.split("\n"):
+ results.append(x)
+
+ return (cmd.returncode, results)
+
+methods = SmartModule()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/test.py b/func/minion/modules/test.py
new file mode 100755
index 0000000..55265a3
--- /dev/null
+++ b/func/minion/modules/test.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+from modules import func_module
+
+class Test(func_module.FuncModule):
+ version = "11.11.11"
+ api_version = "0.0.1"
+ description = "Just a very simple example module"
+ def __init__(self):
+ self.methods = {
+ "add": self.add
+ }
+ func_module.FuncModule.__init__(self)
+
+ def add(self, numb1, numb2):
+ return numb1 + numb2
+
+methods = Test()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/virt.py b/func/minion/modules/virt.py
new file mode 100755
index 0000000..07a9a87
--- /dev/null
+++ b/func/minion/modules/virt.py
@@ -0,0 +1,272 @@
+#!/usr/bin/python
+
+"""
+Virt management features
+
+Copyright 2007, Red Hat, Inc
+Michael DeHaan <mdehaan@redhat.com>
+
+This software may be freely redistributed under the terms of the GNU
+general public license.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+"""
+
+# warning: virt management is rather complicated
+# to see a simple example of func, look at the
+# service control module. API docs on how
+# to use this to come.
+
+# other modules
+import os
+import sub_process
+import libvirt
+
+# our modules
+import codes
+import func_module
+
+VIRT_STATE_NAME_MAP = {
+ 0 : "running",
+ 1 : "running",
+ 2 : "running",
+ 3 : "paused",
+ 4 : "shutdown",
+ 5 : "shutdown",
+ 6 : "crashed"
+}
+
+class FuncLibvirtConnection(object):
+
+ def __init__(self):
+
+
+ cmd = sub_process.Popen("uname -r", shell=True, stdout=sub_process.PIPE)
+ output = cmd.communicate()[0]
+
+ if output.find("xen") != -1:
+ conn = libvirt.open(None)
+ else:
+ conn = libvirt.open("qemu:///system")
+
+ if not conn:
+ raise codes.FuncException("hypervisor connection failure")
+
+ self.conn = conn
+
+ def find_vm(self, vmid):
+ """
+ Extra bonus feature: vmid = -1 returns a list of everything
+ """
+ conn = self.conn
+
+ vms = []
+
+ # this block of code borrowed from virt-manager:
+ # get working domain's name
+ ids = conn.listDomainsID();
+ for id in ids:
+ vm = conn.lookupByID(id)
+ vms.append(vm)
+ # get defined domain
+ names = conn.listDefinedDomains()
+ for name in names:
+ vm = conn.lookupByName(name)
+ vms.append(vm)
+
+ if vmid == -1:
+ return vms
+
+ for vm in vms:
+ if vm.name() == vmid:
+ return vm
+
+ raise codes.FuncException("virtual machine %s not found" % needle)
+
+ def shutdown(self, vmid):
+ return self.find_vm(vmid).shutdown()
+
+ def pause(self, vmid):
+ return suspend(self.conn,vmid)
+
+ def unpause(self, vmid):
+ return resume(self.conn,vmid)
+
+ def suspend(self, vmid):
+ return self.find_vm(vmid).suspend()
+
+ def resume(self, vmid):
+ return self.find_vm(vmid).resume()
+
+ def create(self, vmid):
+ return self.find_vm(vmid).create()
+
+ def destroy(self, vmid):
+ return self.find_vm(vmid).destroy()
+
+ def undefine(self, vmid):
+ return self.find_vm(vmid).undefine()
+
+ def get_status2(self, vm):
+ state = vm.info()[0]
+ # print "DEBUG: state: %s" % state
+ return VIRT_STATE_NAME_MAP.get(state,"unknown")
+
+ def get_status(self, vmid):
+ state = self.find_vm(vmid).info()[0]
+ return VIRT_STATE_NAME_MAP.get(state,"unknown")
+
+
+
+class Virt(func_module.FuncModule):
+
+
+ def __init__(self):
+
+ """
+ Constructor. Register methods and make them available.
+ """
+
+ self.methods = {
+ "install" : self.install,
+ "shutdown" : self.shutdown,
+ "destroy" : self.destroy,
+ "start" : self.create,
+ "pause" : self.pause,
+ "unpause" : self.unpause,
+ "delete" : self.undefine,
+ "status" : self.get_status,
+ "list_vms" : self.list_vms,
+ }
+
+ func_module.FuncModule.__init__(self)
+
+ def get_conn(self):
+ self.conn = FuncLibvirtConnection()
+ return self.conn
+
+ def list_vms(self):
+ self.conn = self.get_conn()
+ vms = self.conn.find_vm(-1)
+ results = []
+ for x in vms:
+ try:
+ results.append(x.name())
+ except:
+ pass
+ return results
+
+ def install(self, server_name, target_name, system=False):
+
+ """
+ Install a new virt system by way of a named cobbler profile.
+ """
+
+ # Example:
+ # install("bootserver.example.org", "fc7webserver", True)
+
+ conn = self.get_conn()
+
+ if conn is None:
+ raise codes.FuncException("no connection")
+
+ if not os.path.exists("/usr/bin/koan"):
+ raise codes.FuncException("no /usr/bin/koan")
+ target = "profile"
+ if system:
+ target = "system"
+
+ # TODO: FUTURE: set --virt-path in cobbler or here
+ koan_args = [
+ "/usr/bin/koan",
+ "--virt",
+ "--virt-graphics", # enable VNC
+ "--%s=%s" % (target, target_name),
+ "--server=%s" % server_name
+ ]
+
+ rc = sub_process.call(koan_args,shell=False)
+ if rc == 0:
+ return 0
+ else:
+ raise codes.FuncException("koan returned %d" % rc)
+
+
+ def shutdown(self, vmid):
+ """
+ Make the machine with the given vmid stop running.
+ Whatever that takes.
+ """
+ self.get_conn()
+ self.conn.shutdown(vmid)
+ return 0
+
+
+ def pause(self, vmid):
+
+ """
+ Pause the machine with the given vmid.
+ """
+ self.get_conn()
+ self.conn.suspend(vmid)
+ return 0
+
+
+ def unpause(self, vmid):
+
+ """
+ Unpause the machine with the given vmid.
+ """
+
+ self.get_conn()
+ self.conn.resume(vmid)
+ return 0
+
+
+ def create(self, vmid):
+
+ """
+ Start the machine via the given mac address.
+ """
+ self.get_conn()
+ self.conn.create(vmid)
+ return 0
+
+
+ def destroy(self, vmid):
+
+ """
+ Pull the virtual power from the virtual domain, giving it virtually no
+ time to virtually shut down.
+ """
+ self.get_conn()
+ self.conn.destroy(vmid)
+ return 0
+
+
+ def undefine(self, vmid):
+
+ """
+ Stop a domain, and then wipe it from the face of the earth.
+ by deleting the disk image and it's configuration file.
+ """
+
+ self.get_conn()
+ self.conn.undefine(vmid)
+ return 0
+
+
+ def get_status(self, vmid):
+
+ """
+ Return a state suitable for server consumption. Aka, codes.py values, not XM output.
+ """
+
+ self.get_conn()
+ return self.conn.get_status(vmid)
+
+
+methods = Virt()
+register_rpc = methods.register_rpc
diff --git a/func/minion/modules/yum.py b/func/minion/modules/yum.py
new file mode 100644
index 0000000..6600d47
--- /dev/null
+++ b/func/minion/modules/yum.py
@@ -0,0 +1,48 @@
+# Copyright 2007, Red Hat, Inc
+# James Bowes <jbowes@redhat.com>
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+from modules import func_module
+
+import yum
+
+# XXX Use internal yum callback or write a useful one.
+class DummyCallback(object):
+
+ def event(self, state, data=None):
+ pass
+
+class Yum(func_module.FuncModule):
+
+ def __init__(self):
+ self.methods = {
+ "update" : self.update
+ }
+ func_module.FuncModule.__init__(self)
+
+ def update(self):
+ # XXX support updating specific rpms
+ ayum = yum.YumBase()
+ ayum.doGenericSetup()
+ ayum.doRepoSetup()
+ try:
+ ayum.doLock()
+ ayum.update()
+ ayum.buildTransaction()
+ ayum.processTransaction(
+ callback=DummyCallback())
+ finally:
+ ayum.closeRpmDB()
+ ayum.doUnlock()
+ return True
+
+
+methods = Yum()
+register_rpc = methods.register_rpc