class PlcLxcInstance (PlcInstance):
# does lxc have a context id of any kind ?
- def __init__ (self, plcbox, lxcname):
+ def __init__ (self, plcbox, lxcname, pid):
PlcInstance.__init__(self, plcbox)
self.lxcname = lxcname
+ self.pid = pid
- def kill (self):
- print "TODO lxc PlcLxcInstance.kill ..."
+ def vplcname (self):
+ return self.lxcname.split('-')[-1]
+ def buildname (self):
+ return self.lxcname.rsplit('-',2)[0]
def line (self):
- return "TODO lxc PlcLxcInstance.line with lxcname=%s"%(self.lxcname)
+ msg="== %s =="%(self.vplcname())
+ msg += " [=%s]"%self.lxcname
+ if self.pid==-1: msg+=" not (yet?) running"
+ else: msg+=" (pid=%s)"%self.pid
+ if self.timestamp: msg += " @ %s"%self.pretty_timestamp()
+ else: msg += " *unknown timestamp*"
+ return msg
+
+ def kill (self):
+ command="rsync lxc-driver.sh %s:/root"%self.plc_box.hostname
+ commands.getstatusoutput(command)
+ msg="lxc container stopping %s on %s"%(self.lxcname,self.plc_box.hostname)
+ self.plc_box.run_ssh(['/root/lxc-driver.sh','-c','stop_lxc','-n',self.lxcname],msg)
+ self.plc_box.forget(self)
##########
class PlcBox (Box):
class PlcLxcBox (PlcBox):
+ def add_lxc (self,lxcname,pid):
+ for plc in self.plc_instances:
+ if plc.lxcname==lxcname:
+ header("WARNING, duplicate myplc %s running on %s"%\
+ (lxcname,self.hostname),banner=False)
+ return
+ self.plc_instances.append(PlcLxcInstance(self,lxcname,pid))
+
+
# a line describing the box
def line(self):
msg="%s [max=%d,%d free, LXC-based] (%s)"%(self.hostname, self.max_plcs,self.free_slots(),self.uname())
return msg
-
+
+ def plc_instance_by_lxcname (self, lxcname):
+ for p in self.plc_instances:
+ if p.lxcname==lxcname: return p
+ return None
+
# essentially shutdown all running containers
def soft_reboot (self, options):
- print "TODO lxc PlcLxcBox.soft_reboot"
+ command="rsync lxc-driver.sh %s:/root"%self.hostname
+ commands.getstatusoutput(command)
+ self.run_ssh(['/root/lxc-driver.sh','-c','stop_all'],"Stopping all running lxc containers",
+ dry_run=options.dry_run)
+
# sense is expected to fill self.plc_instances with PlcLxcInstance's
# to describe the currently running VM's
# as well as to call self.get_uname() once
def sense (self, options):
- print "xp (todo:PlcLxcBox.sense)",
+ print "xp",
self.get_uname()
-
+ command="rsync lxc-driver.sh %s:/root"%self.hostname
+ commands.getstatusoutput(command)
+ command=['/root/lxc-driver.sh','-c','sense_all']
+ lxc_stat = self.backquote_ssh (command)
+ for lxc_line in lxc_stat.split("\n"):
+ if not lxc_line: continue
+ lxcname=lxc_line.split(";")[0]
+ pid=lxc_line.split(";")[1]
+ timestamp=lxc_line.split(";")[2]
+ self.add_lxc(lxcname,pid)
+ timestamp=int(timestamp)
+ p=self.plc_instance_by_lxcname(lxcname)
+ if not p:
+ print 'WARNING zombie plc',self.hostname,lxcname
+ print '... was expecting',lxcname,'in',[i.lxcname for i in self.plc_instances]
+ continue
+ p.set_timestamp(timestamp)
############################################################
class QemuInstance:
--- /dev/null
+#!/bin/bash
+
+function sense_all () {
+
+ for i in $(lxc-ls -1|sort|uniq); do
+ [ "$(lxc-info -n $i | grep state| awk '{print $2;}' )" == "RUNNING" ] && echo "$i;$(lxc-info -n $i | grep pid | awk '{print $2;}');$(cat /var/lib/lxc/$i/$i.timestamp)" || :
+ done
+}
+
+function start_all () {
+
+ for i in $(lxc-ls -1|sort|uniq); do
+ [ "$(lxc-info -n $i | grep state| awk '{print $2;}' )" != "RUNNING" ] && lxc-start -d -n $i || :
+ lxc-wait -n $i -s RUNNING
+ done
+
+ #sense_all
+}
+
+function stop_all () {
+
+ for i in $(lxc-ls -1|sort|uniq); do
+ [ "$(lxc-info -n $i | grep state| awk '{print $2;}' )" != "STOPPED" ] && lxc-stop -n $i
+ lxc-wait -n $i -s STOPPED
+ done
+
+ sense_all
+}
+
+function sense_lxc () {
+
+ lxc=$1; shift
+ [ "$(lxc-info -n $lxc | grep state | awk '{print $2;}')" == "RUNNING" ] && echo "$lxc;$(lxc-info -n $lxc | grep pid | awk '{print $2;}');$(cat /var/lib/lxc/$lxc/$lxc.timestamp)" || :
+}
+
+function start_lxc () {
+
+ lxc=$1; shift
+ [ "$(lxc-info -n $lxc | grep state| awk '{print $2;}' )" != "RUNNING" ] && lxc-start -d -n $lxc ||:
+ lxc-wait -n $lxc -s RUNNING
+
+ sense_lxc $lxc
+}
+
+function stop_lxc () {
+
+ lxc=$1; shift
+ [ "$(lxc-info -n $lxc | grep state| awk '{print $2;}' )" != "STOPPED" ] && lxc-stop -n $lxc
+ lxc-wait -n $lxc -s STOPPED
+
+ sense_lxc $lxc
+}
+
+function restart_all () {
+
+ stop_all
+ start_all
+}
+
+function restart_lxc () {
+
+ lxc=$1; shift
+ stop_lxc $lxc
+ start_lxc $lxc
+}
+
+function destroy_all () {
+
+ stop_all
+ for i in $(lxc-ls -1|sort|uniq); do
+ lxc-destroy -n $i
+ done
+
+}
+
+function destroy_lxc () {
+
+ lxc=$1; shift
+ stop_lxc $lxc
+ lxc-destroy -n $lxc
+}
+
+function usage () {
+ echo "Usage: lxc-driver.sh [options]"
+ echo "Description:"
+ echo " This command is used to manage and retreive information on existing lxc containers "
+ echo "lxc-driver.sh -c <COMMAND>_all"
+ echo "lxc-driver.sh -c <COMMAND>_lxc -l <LXCNAME>"
+ echo "<COMMAND> in {sense,start,stop,restart,destroy}"
+
+}
+
+function main () {
+
+ #set -x
+
+ while getopts "c:n:" opt ; do
+ case $opt in
+ c) command=$OPTARG;;
+ n) lxc=$OPTARG;;
+ *) usage && exit 1;;
+ esac
+ done
+
+
+ case $command in
+ sense_all) sense_all ;;
+ start_all) start_all ;;
+ stop_all) stop_all ;;
+ restart_all) restart_all ;;
+ destroy_all) destroy_all ;;
+ sense_lxc) sense_lxc $lxc;;
+ start_lxc) start_lxc $lxc;;
+ stop_lxc) stop_lxc $lxc;;
+ restart_lxc) restart_lxc $lxc;;
+ destroy_lxc) destroy_lxc $lxc;;
+ *) usage
+ esac
+
+
+}
+
+main "$@"
+