Commits

Michael Ziegler committed 050e127

implement deleting processes, VMs and bridges

Comments (0)

Files changed (2)

 
 import uuid
 from os.path import dirname, abspath, join
-from django.db import models
+
+from django.db        import models
+from django.db.models import signals
+
 from supervisord.models import Supervisor, Process
 
 class Bridge(models.Model):
 
         return models.Model.save(self, *args, **kwargs)
 
+    # Deletion handler
+    def post_delete( self ):
+        """ Delete the according process. """
+        self.process.delete()
+
+    @staticmethod
+    def post_delete_listener( **kwargs ):
+        kwargs['instance'].post_delete()
+
     def start(self):
         return self.process.start()
 
 
         return models.Model.save(self, *args, **kwargs)
 
+    # Deletion handler
+    def post_delete( self ):
+        """ Delete the according process. """
+        self.process.delete()
+
+    @staticmethod
+    def post_delete_listener( **kwargs ):
+        kwargs['instance'].post_delete()
+
     def start(self):
         if self.bridge is not None and not self.bridge.process.is_running:
             self.bridge.start()
         if not self.id:
             raise SystemError("Cannot load a snapshot that has not yet been created")
         return self.vm.process.sendStdin("loadvm %s\n" % self.tag.encode("utf-8"))
+
+
+signals.post_delete.connect( Bridge.post_delete_listener,         sender=Bridge         )
+signals.post_delete.connect( VirtualMachine.post_delete_listener, sender=VirtualMachine )

supervisord/models.py

 # -*- coding: utf-8 -*-
 # kate: space-indent on; indent-width 4; replace-tabs on;
 
+import xmlrpclib
+import os
 from os.path import join
 from functools import partial
 from time import time, sleep
-import xmlrpclib
 from ConfigParser import ConfigParser
 
-from django.db import models
+from django.db        import models
+from django.db.models import signals
 
 
 def mk_config_property( field, doc="", get_coerce=None, get_none=None, set_coerce=unicode, set_none='' ):
     password    = models.CharField(max_length=250, blank=True)
     confdir     = models.CharField(max_length=250)
 
+    Fault       = xmlrpclib.Fault
+
     def __init__(self, *args, **kwargs):
         models.Model.__init__(self, *args, **kwargs)
 
     stdout_logfile_maxbytes = mk_config_property( "stdout_logfile_maxbytes", "The max size of the logfile" )
     stdout_logfile_backups  = mk_config_property( "stdout_logfile_backups", "How many backups to keep" )
 
+    Fault = xmlrpclib.Fault
+
     def __init__(self, *args, **kwargs):
         models.Model.__init__(self, *args, **kwargs)
 
-        self._confpath = ""
         self._conf = ConfigParser()
         if self.id is not None and self.name:
-            self._confpath = join(self.supervisor.confdir, self.name + ".conf")
-            self._conf.read(self._confpath)
+            self._conf.read(self.confpath)
+
+    @property
+    def confpath(self):
+        return join(self.supervisor.confdir, self.name + ".conf")
 
     def getconf(self, option):
         return self._conf.get( ("program:" + self.name), option )
         return "%s on Supervisor at %s" % (self.name, self.supervisor.address)
 
     def save(self, *args, **kwargs):
-        self._confpath = join(self.supervisor.confdir, self.name + ".conf")
         adding = (self.id is None)
         ret = models.Model.save(self, *args, **kwargs)
 
-        fd = open(self._confpath, "w")
+        fd = open(self.confpath, "w")
         try:
             self._conf.write(fd)
         finally:
 
         return ret
 
+    # Deletion handler
+    def pre_delete( self ):
+        """ Delete this process from Supervisord. """
+        if self.is_running:
+            self.stop()
+        self.supervisor.xmlrpc.supervisor.removeProcessGroup(self.name)
+        os.unlink(self.confpath)
+        self.supervisor.xmlrpc.supervisor.reloadConfig()
+
+    @staticmethod
+    def pre_delete_listener( **kwargs ):
+        kwargs['instance'].pre_delete()
+
     def start(self):
         return self.supervisor.xmlrpc.supervisor.startProcess(self.name)
 
     def getInfo(self):
         return self.supervisor.xmlrpc.supervisor.getProcessInfo(self.name)
 
+    info = property(getInfo)
+
     def waitState(self, state="RUNNING", interval=0.5, maxwait=10):
         start = int(time())
         while self.info["statename"] != state:
             sleep(interval)
         return True
 
-    info = property(getInfo)
-
     @property
     def is_running(self):
         return self.info['statename'] == 'RUNNING'
+
+
+signals.pre_delete.connect( Process.pre_delete_listener, sender=Process )