diff --git a/slapos/grid/SlapObject.py b/slapos/grid/SlapObject.py index 6dfb9dd35064408212ef4c75c65c25fa21a1f1fa..39ba232e0419b99aee3b970142b109212d27cc4d 100644 --- a/slapos/grid/SlapObject.py +++ b/slapos/grid/SlapObject.py @@ -30,6 +30,7 @@ import os import pkg_resources +import psutil import pwd import shutil import stat @@ -444,6 +445,10 @@ class Partition(object): gid = stat_info.st_gid return (uid, gid) + def getUserName(self): + """Returns the name of the owner of partition""" + return pwd.getpwuid(self.getUserGroupId()[0]).pw_name + def addServiceToGroup(self, partition_id, runner_list, path, extension=''): uid, gid = self.getUserGroupId() for runner in runner_list: @@ -673,11 +678,12 @@ class Partition(object): if not self.checkRetentionIsAuthorized(): return False + uid, gid = self.getUserGroupId() + # Launches "destroy" binary if exists destroy_executable_location = os.path.join(self.instance_path, 'sbin', 'destroy') if os.path.exists(destroy_executable_location): - uid, gid = self.getUserGroupId() self.logger.debug('Invoking %r' % destroy_executable_location) process_handler = SlapPopen([destroy_executable_location], preexec_fn=lambda: dropPrivileges(uid, gid, logger=self.logger), @@ -726,6 +732,29 @@ class Partition(object): except IOError as exc: raise IOError("I/O error while freeing partition (%s): %s" % (self.instance_path, exc)) + # Kill remaining processes + try: + current_pid = os.getpid() + [x.terminate() for x in psutil.process_iter() if uid in x.uids() + and x.pid != current_pid] + except (psutil.NoSuchProcess, psutil.AccessDenied) as e: + self.logger.info("Process finished before being " + "killed when freeing partition %s" % self.instance_path) + except psutil.TimeoutExpired as e: + self.logger.error("Couldn't kill process %s of destroyed partition %s" + % self.instance_path) + + # Clean user crontab and at jobs + user_crontab_path = os.path.join('/', 'var', 'spool', 'cron', self.getUserName()) + if os.path.exists(user_crontab_path): + os.unlink(user_crontab_path) + + at_directory = os.path.join('/', 'var', 'spool', 'atjobs') + for at_file_name in os.listdir(at_directory): + at_file_path = os.path.join(at_directory, at_file_name) + if uid == os.stat(at_file_path).st_uid: + os.unlink(at_file_path) + return True def cleanupFolder(self, folder_path):