diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index dce47eb8dd..7f296376fa 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -466,6 +466,14 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn models.Q(ProjectUpdate___project=self) ) + def delete(self, *args, **kwargs): + path_to_delete = self.get_project_path(check_if_exists=False) + r = super(Project, self).delete(*args, **kwargs) + if self.scm_type and path_to_delete: # non-manual, concrete path + from awx.main.tasks import delete_project_files + delete_project_files.delay(path_to_delete) + return r + class ProjectUpdate(UnifiedJob, ProjectOptions, JobNotificationMixin, TaskManagerProjectUpdateMixin): ''' diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 0a021b9650..0fdbef8036 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -251,6 +251,24 @@ def handle_setting_changes(setting_keys): cache.delete_many(cache_keys) +@task(queue='tower_broadcast_all', exchange_type='fanout') +def delete_project_files(project_path): + # TODO: possibly implement some retry logic + lock_file = project_path + '.lock' + if os.path.exists(project_path): + try: + shutil.rmtree(project_path) + logger.info(six.text_type('Success removing project files {}').format(project_path)) + except Exception: + logger.exception(six.text_type('Could not remove project directory {}').format(project_path)) + if os.path.exists(lock_file): + try: + os.remove(lock_file) + logger.debug(six.text_type('Success removing {}').format(lock_file)) + except Exception: + logger.exception(six.text_type('Could not remove lock file {}').format(lock_file)) + + @task() def send_notifications(notification_list, job_id=None): if not isinstance(notification_list, list):