From 8bc55a5676f7efce0051d4ba3570176518789c5d Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 23 Feb 2018 16:45:16 -0500 Subject: [PATCH] Make namespace deletion asynchronous Instead of deleting a namespace synchronously as before, we now mark the namespace for deletion, disable it, and rename it. A worker then comes along and deletes the namespace in the background. This results in a *significantly* better user experience, as the namespace deletion operation now "completes" in under a second, where before it could take 10s of minutes at the worse. Fixes https://jira.coreos.com/browse/QUAY-838 --- app.py | 7 +- .../service/batch/namespacegcworker/log/run | 4 + conf/init/service/batch/namespacegcworker/run | 9 +++ config.py | 1 + data/database.py | 10 ++- ...4c2d45bc132_add_deleted_namespace_table.py | 39 ++++++++++ data/model/test/test_user.py | 47 +++++++++++- data/model/user.py | 70 ++++++++++++++++-- endpoints/api/organization.py | 4 +- endpoints/api/superuser.py | 4 +- endpoints/api/superuser_models_interface.py | 4 +- endpoints/api/superuser_models_pre_oci.py | 10 +-- endpoints/api/user.py | 4 +- initdb.py | 11 ++- static/js/services/user-service.js | 64 ++++------------ test/data/test.db | Bin 1699840 -> 1724416 bytes test/test_api_usage.py | 2 +- test/test_suconfig_api.py | 2 +- tools/deleteaccount.py | 52 ------------- util/config/schema.py | 1 + workers/namespacegcworker.py | 28 +++++++ 21 files changed, 244 insertions(+), 129 deletions(-) create mode 100755 conf/init/service/batch/namespacegcworker/log/run create mode 100755 conf/init/service/batch/namespacegcworker/run create mode 100644 data/migrations/versions/b4c2d45bc132_add_deleted_namespace_table.py delete mode 100644 tools/deleteaccount.py create mode 100644 workers/namespacegcworker.py diff --git a/app.py b/app.py index 9db5c8819..fdf908b9f 100644 --- a/app.py +++ b/app.py @@ -228,8 +228,13 @@ secscan_notification_queue = WorkQueue(app.config['SECSCAN_NOTIFICATION_QUEUE_NA has_namespace=False, metric_queue=metric_queue) +# Note: We set `has_namespace` to `False` here, as we explicitly want this queue to not be emptied +# when a namespace is marked for deletion. +namespace_gc_queue = WorkQueue(app.config['NAMESPACE_GC_QUEUE_NAME'], tf, has_namespace=False, + metric_queue=metric_queue) + all_queues = [image_replication_queue, dockerfile_build_queue, notification_queue, - secscan_notification_queue, chunk_cleanup_queue] + secscan_notification_queue, chunk_cleanup_queue, namespace_gc_queue] secscan_api = SecurityScannerAPI(app, app.config, storage) tuf_metadata_api = TUFMetadataAPI(app, app.config) diff --git a/conf/init/service/batch/namespacegcworker/log/run b/conf/init/service/batch/namespacegcworker/log/run new file mode 100755 index 000000000..6e43109a9 --- /dev/null +++ b/conf/init/service/batch/namespacegcworker/log/run @@ -0,0 +1,4 @@ +#!/bin/sh + +# Start the logger +exec logger -i -t namespacegcworker diff --git a/conf/init/service/batch/namespacegcworker/run b/conf/init/service/batch/namespacegcworker/run new file mode 100755 index 000000000..04b41a0fb --- /dev/null +++ b/conf/init/service/batch/namespacegcworker/run @@ -0,0 +1,9 @@ +#! /bin/bash + +echo 'Starting Namespace GC worker' + +QUAYPATH=${QUAYPATH:-"."} +cd ${QUAYDIR:-"/"} +PYTHONPATH=$QUAYPATH venv/bin/python -m workers.namespacegcworker 2>&1 + +echo 'Namespace GC exited' diff --git a/config.py b/config.py index aa77413b4..e912b8ab1 100644 --- a/config.py +++ b/config.py @@ -171,6 +171,7 @@ class DefaultConfig(ImmutableConfig): REPLICATION_QUEUE_NAME = 'imagestoragereplication' SECSCAN_NOTIFICATION_QUEUE_NAME = 'security_notification' CHUNK_CLEANUP_QUEUE_NAME = 'chunk_cleanup' + NAMESPACE_GC_QUEUE_NAME = 'namespacegc' # Super user config. Note: This MUST BE an empty list for the default config. SUPER_USERS = [] diff --git a/data/database.py b/data/database.py index fd19aa9db..fa8fa88f8 100644 --- a/data/database.py +++ b/data/database.py @@ -470,13 +470,21 @@ class User(BaseModel): RepositoryNotification, OAuthAuthorizationCode, RepositoryActionCount, TagManifestLabel, Tag, ManifestLabel, BlobUploading, TeamSync, - RepositorySearchScore} | beta_classes + RepositorySearchScore, DeletedNamespace} | beta_classes delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes) Namespace = User.alias() +class DeletedNamespace(BaseModel): + namespace = QuayUserField(index=True, allows_robots=False, unique=True) + marked = DateTimeField(default=datetime.now) + original_username = CharField(index=True) + original_email = CharField(index=True) + queue_id = CharField(null=True, index=True) + + class UserPromptTypes(object): CONFIRM_USERNAME = 'confirm_username' ENTER_NAME = 'enter_name' diff --git a/data/migrations/versions/b4c2d45bc132_add_deleted_namespace_table.py b/data/migrations/versions/b4c2d45bc132_add_deleted_namespace_table.py new file mode 100644 index 000000000..e5f137877 --- /dev/null +++ b/data/migrations/versions/b4c2d45bc132_add_deleted_namespace_table.py @@ -0,0 +1,39 @@ +"""Add deleted namespace table + +Revision ID: b4c2d45bc132 +Revises: 152edccba18c +Create Date: 2018-02-27 11:43:02.329941 + +""" + +# revision identifiers, used by Alembic. +revision = 'b4c2d45bc132' +down_revision = '152edccba18c' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(tables): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('deletednamespace', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('namespace_id', sa.Integer(), nullable=False), + sa.Column('marked', sa.DateTime(), nullable=False), + sa.Column('original_username', sa.String(length=255), nullable=False), + sa.Column('original_email', sa.String(length=255), nullable=False), + sa.Column('queue_id', sa.String(length=255), nullable=True), + sa.ForeignKeyConstraint(['namespace_id'], ['user.id'], name=op.f('fk_deletednamespace_namespace_id_user')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_deletednamespace')) + ) + op.create_index('deletednamespace_namespace_id', 'deletednamespace', ['namespace_id'], unique=True) + op.create_index('deletednamespace_original_email', 'deletednamespace', ['original_email'], unique=False) + op.create_index('deletednamespace_original_username', 'deletednamespace', ['original_username'], unique=False) + op.create_index('deletednamespace_queue_id', 'deletednamespace', ['queue_id'], unique=False) + # ### end Alembic commands ### + + +def downgrade(tables): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('deletednamespace') + # ### end Alembic commands ### diff --git a/data/model/test/test_user.py b/data/model/test/test_user.py index 2f4f82995..ce0649322 100644 --- a/data/model/test/test_user.py +++ b/data/model/test/test_user.py @@ -4,9 +4,11 @@ import pytest from mock import patch -from data.database import EmailConfirmation +from data.database import EmailConfirmation, User, DeletedNamespace from data.model.user import create_user_noverify, validate_reset_code, get_active_users +from data.model.user import mark_namespace_for_deletion, delete_namespace_via_marker from util.timedeltastring import convert_to_timedelta +from data.queue import WorkQueue from test.fixtures import * def test_create_user_with_expiration(initialized_db): @@ -38,3 +40,46 @@ def test_get_active_users(disabled, initialized_db): for user in users: if not disabled: assert user.enabled + +def test_mark_namespace_for_deletion(initialized_db): + def create_transaction(db): + return db.transaction() + + # Create a user and then mark it for deletion. + user = create_user_noverify('foobar', 'foo@example.com', email_required=False) + + # Mark the user for deletion. + queue = WorkQueue('testgcnamespace', create_transaction) + mark_namespace_for_deletion(user, [], queue) + + # Ensure the older user is still in the DB. + assert User.get(id=user.id).username != 'foobar' + + # Ensure we can create a user with the same namespace again. + new_user = create_user_noverify('foobar', 'foo@example.com', email_required=False) + assert new_user.id != user.id + + # Ensure the older user is still in the DB. + assert User.get(id=user.id).username != 'foobar' + + +def test_delete_namespace_via_marker(initialized_db): + def create_transaction(db): + return db.transaction() + + # Create a user and then mark it for deletion. + user = create_user_noverify('foobar', 'foo@example.com', email_required=False) + + # Mark the user for deletion. + queue = WorkQueue('testgcnamespace', create_transaction) + marker_id = mark_namespace_for_deletion(user, [], queue) + + # Delete the user. + delete_namespace_via_marker(marker_id, []) + + # Ensure the user was actually deleted. + with pytest.raises(User.DoesNotExist): + User.get(id=user.id) + + with pytest.raises(DeletedNamespace.DoesNotExist): + DeletedNamespace.get(id=marker_id) diff --git a/data/model/user.py b/data/model/user.py index 763e7305e..0c86b5a7b 100644 --- a/data/model/user.py +++ b/data/model/user.py @@ -14,7 +14,7 @@ from data.database import (User, LoginService, FederatedLogin, RepositoryPermiss EmailConfirmation, Role, db_for_update, random_string_generator, UserRegion, ImageStorageLocation, ServiceKeyApproval, OAuthApplication, RepositoryBuildTrigger, - UserPromptKind, UserPrompt, UserPromptTypes) + UserPromptKind, UserPrompt, UserPromptTypes, DeletedNamespace) from data.model import (DataModelException, InvalidPasswordException, InvalidRobotException, InvalidUsernameException, InvalidEmailAddressException, TooManyLoginAttemptsException, db_transaction, @@ -835,7 +835,14 @@ def get_solely_admined_organizations(user_obj): return solely_admined -def delete_user(user, queues, force=False): +def mark_namespace_for_deletion(user, queues, namespace_gc_queue, force=False): + """ Marks a namespace (as referenced by the given user) for deletion. A queue item will be added + to delete the namespace's repositories and storage, while the namespace itself will be + renamed, disabled, and delinked from other tables. + """ + if not user.enabled: + return None + if not force and not user.organization: # Ensure that the user is not the sole admin for any organizations. If so, then the user # cannot be deleted before those organizations are deleted or reassigned. @@ -854,10 +861,66 @@ def delete_user(user, queues, force=False): for queue in queues: queue.delete_namespaced_items(user.username) + # Delete non-repository related items. This operation is very quick, so we can do so here. + _delete_user_linked_data(user) + + with db_transaction(): + original_username = user.username + user = db_for_update(User.select().where(User.id == user.id)).get() + + # Mark the namespace as deleted and ready for GC. + try: + marker = DeletedNamespace.create(namespace=user, + original_username=original_username, + original_email=user.email) + except IntegrityError: + return + + # Disable the namespace itself, and replace its various unique fields with UUIDs. + user.enabled = False + user.username = str(uuid4()) + user.email = str(uuid4()) + user.save() + + # Add a queueitem to delete the namespace. + marker.queue_id = namespace_gc_queue.put([str(user.id)], json.dumps({ + 'marker_id': marker.id, + 'original_username': original_username, + })) + marker.save() + return marker.id + + +def delete_namespace_via_marker(marker_id, queues): + """ Deletes a namespace referenced by the given DeletedNamespace marker ID. """ + try: + marker = DeletedNamespace.get(id=marker_id) + except DeletedNamespace.DoesNotExist: + return + + delete_user(marker.namespace, queues) + + +def delete_user(user, queues): + """ Deletes a user/organization/robot. Should *not* be called by any user-facing API. Instead, + mark_namespace_for_deletion should be used, and the queue should call this method. + """ + # Delete all queue items for the user. + for queue in queues: + queue.delete_namespaced_items(user.username) + # Delete any repositories under the user's namespace. for repo in list(Repository.select().where(Repository.namespace_user == user)): repository.purge_repository(user.username, repo.name) + # Delete non-repository related items. + _delete_user_linked_data(user) + + # Delete the user itself. + user.delete_instance(recursive=True, delete_nullable=True) + + +def _delete_user_linked_data(user): if user.organization: # Delete the organization's teams. for team in Team.select().where(Team.organization == user): @@ -879,9 +942,6 @@ def delete_user(user, queues, force=False): # falling and only occurs if a superuser is being deleted. ServiceKeyApproval.update(approver=None).where(ServiceKeyApproval.approver == user).execute() - # Delete the user itself. - user.delete_instance(recursive=True, delete_nullable=True) - def get_pull_credentials(robotname): try: diff --git a/endpoints/api/organization.py b/endpoints/api/organization.py index 93cf5ed85..c449bd843 100644 --- a/endpoints/api/organization.py +++ b/endpoints/api/organization.py @@ -6,7 +6,7 @@ from flask import request import features -from app import billing as stripe, avatar, all_queues, authentication +from app import billing as stripe, avatar, all_queues, authentication, namespace_gc_queue from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error, related_user_resource, internal_only, require_user_admin, log_action, show_if, path_param, require_scope, require_fresh_login) @@ -217,7 +217,7 @@ class Organization(ApiResource): except model.InvalidOrganizationException: raise NotFound() - model.user.delete_user(org, all_queues) + model.user.mark_namespace_for_deletion(org, all_queues, namespace_gc_queue) return '', 204 raise Unauthorized() diff --git a/endpoints/api/superuser.py b/endpoints/api/superuser.py index f5d0a9e81..151ffb961 100644 --- a/endpoints/api/superuser.py +++ b/endpoints/api/superuser.py @@ -412,7 +412,7 @@ class SuperUserManagement(ApiResource): if superusers.is_superuser(username): raise InvalidRequest('Cannot delete a superuser') - pre_oci_model.delete_user(username) + pre_oci_model.mark_user_for_deletion(username) return '', 204 raise Unauthorized() @@ -540,7 +540,7 @@ class SuperUserOrganizationManagement(ApiResource): def delete(self, name): """ Deletes the specified organization. """ if SuperUserPermission().can(): - pre_oci_model.delete_organization(name) + pre_oci_model.mark_organization_for_deletion(name) return '', 204 raise Unauthorized() diff --git a/endpoints/api/superuser_models_interface.py b/endpoints/api/superuser_models_interface.py index ec83c7c48..48bd9f716 100644 --- a/endpoints/api/superuser_models_interface.py +++ b/endpoints/api/superuser_models_interface.py @@ -353,7 +353,7 @@ class SuperuserDataInterface(object): """ @abstractmethod - def delete_user(self, username): + def mark_user_for_deletion(self, username): """ Returns None """ @@ -383,7 +383,7 @@ class SuperuserDataInterface(object): """ @abstractmethod - def delete_organization(self, name): + def mark_organization_for_deletion(self, name): """ Returns None """ diff --git a/endpoints/api/superuser_models_pre_oci.py b/endpoints/api/superuser_models_pre_oci.py index 4e44aea78..daa97f83f 100644 --- a/endpoints/api/superuser_models_pre_oci.py +++ b/endpoints/api/superuser_models_pre_oci.py @@ -2,7 +2,7 @@ import features from flask import request -from app import all_queues, userfiles +from app import all_queues, userfiles, namespace_gc_queue from auth.permissions import ReadRepositoryPermission, ModifyRepositoryPermission, AdministerRepositoryPermission from data import model, database from endpoints.api.build import get_job_config, _get_build_status @@ -141,9 +141,9 @@ class PreOCIModel(SuperuserDataInterface): return Organization(org.username, org.email) - def delete_organization(self, name): + def mark_organization_for_deletion(self, name): org = model.organization.get_organization(name) - model.user.delete_user(org, all_queues) + model.user.mark_namespace_for_deletion(org, all_queues, namespace_gc_queue, force=True) def take_ownership(self, namespace, authed_user): entity = model.user.get_user_or_org(namespace) @@ -172,9 +172,9 @@ class PreOCIModel(SuperuserDataInterface): user = model.user.get_nonrobot_user(username) model.user.change_password(user, password) - def delete_user(self, username): + def mark_user_for_deletion(self, username): user = model.user.get_nonrobot_user(username) - model.user.delete_user(user, all_queues, force=True) + model.user.mark_namespace_for_deletion(user, all_queues, namespace_gc_queue, force=True) def create_reset_password_email_code(self, email): code = model.user.create_reset_password_email_code(email) diff --git a/endpoints/api/user.py b/endpoints/api/user.py index 6b900a387..7f86df918 100644 --- a/endpoints/api/user.py +++ b/endpoints/api/user.py @@ -12,7 +12,7 @@ from peewee import IntegrityError import features from app import (app, billing as stripe, authentication, avatar, user_analytics, all_queues, - oauth_login) + oauth_login, namespace_gc_queue) from auth import scopes from auth.auth_context import get_authenticated_user @@ -485,7 +485,7 @@ class User(ApiResource): if app.config['AUTHENTICATION_TYPE'] != 'Database': abort(404) - model.user.delete_user(get_authenticated_user(), all_queues) + model.user.mark_namespace_for_deletion(get_authenticated_user(), all_queues, namespace_gc_queue) return '', 204 diff --git a/initdb.py b/initdb.py index 18317e25e..aecdddfb7 100644 --- a/initdb.py +++ b/initdb.py @@ -20,7 +20,8 @@ from data.database import (db, all_models, beta_classes, Role, TeamRole, Visibil ExternalNotificationEvent, ExternalNotificationMethod, NotificationKind, QuayRegion, QuayService, UserRegion, OAuthAuthorizationCode, ServiceKeyApprovalType, MediaType, LabelSourceType, UserPromptKind, - RepositoryKind, TagKind, BlobPlacementLocation, User) + RepositoryKind, TagKind, BlobPlacementLocation, User, + DeletedNamespace) from data import model from data.queue import WorkQueue from app import app, storage as store, tf @@ -893,8 +894,11 @@ def populate_database(minimal=False, with_storage=False): model.repositoryactioncount.update_repository_score(to_count) +WHITELISTED_EMPTY_MODELS = ['DeletedNamespace'] + def find_models_missing_data(): - # As a sanity check we are going to make sure that all db tables have some data + # As a sanity check we are going to make sure that all db tables have some data, unless explicitly + # whitelisted. models_missing_data = set() for one_model in all_models: if one_model in beta_classes: @@ -903,7 +907,8 @@ def find_models_missing_data(): try: one_model.select().get() except one_model.DoesNotExist: - models_missing_data.add(one_model.__name__) + if one_model.__name__ not in WHITELISTED_EMPTY_MODELS: + models_missing_data.add(one_model.__name__) return models_missing_data diff --git a/static/js/services/user-service.js b/static/js/services/user-service.js index 1196bf030..af59217be 100644 --- a/static/js/services/user-service.js +++ b/static/js/services/user-service.js @@ -189,59 +189,21 @@ function(ApiService, CookieService, $rootScope, Config, $location, $timeout) { } var errorDisplay = ApiService.errorDisplay('Could not delete namespace', callback); - var deleteNamespaceItself = function() { - info.progress = 1; - info.progressMessage = 'Deleting namespace...'; - var cb = function(resp) { - userService.load(function(currentUser) { - callback(true); - $location.path('/'); - }); - } + var cb = function(resp) { + userService.load(function(currentUser) { + callback(true); + $location.path('/'); + }); + } - if (info.user) { - ApiService.deleteCurrentUser().then(cb, errorDisplay) - } else { - var delParams = { - 'orgname': info.organization.name - }; - ApiService.deleteAdminedOrganization(null, delParams).then(cb, errorDisplay); - } - }; - - var repoIndex = 0; - var repositories = null; - var deleteAllRepos = function() { - if (repoIndex >= repositories.length) { - deleteNamespaceItself(); - return; - } - - var repoParams = { - 'repository': namespace + '/' + repositories[repoIndex]['name'] + if (info.user) { + ApiService.deleteCurrentUser().then(cb, errorDisplay) + } else { + var delParams = { + 'orgname': info.organization.name }; - - info.progress = repoIndex / repositories.length; - info.progressMessage = 'Deleting repository ' + repoParams['repository'] + '...'; - - ApiService.deleteRepository(null, repoParams).then(function() { - repoIndex++; - deleteAllRepos(); - }, errorDisplay); - }; - - // First delete each repo for the namespace, updating the info so it can show a progress bar. - // This is not strictly necessary (as the namespace delete call will do it as well), but it is - // a better user experience. - var params = { - 'namespace': namespace, - 'public': false - }; - - ApiService.listRepos(null, params).then(function(resp) { - repositories = resp['repositories']; - deleteAllRepos(); - }, errorDisplay); + ApiService.deleteAdminedOrganization(null, delParams).then(cb, errorDisplay); + } }; userService.currentUser = function() { diff --git a/test/data/test.db b/test/data/test.db index f3806a8766c90c81db71e38ef8425f18a75cf0da..286e2d0fc1163590e8bb4cf91ae54af614106912 100644 GIT binary patch delta 82428 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 delta 73932 zcmeFacYIveaVU(tSO5!P7rW@BNQxi{Hc=P6y-=(Dhw&chrTq8Mtj$^q(~E z)krD9-hyu4f7S8R0KNTqzfZzO>7)=PcsxpSDV*U_aXgxe$8aIZQA8|G0+{Z5s>7>) z?B6@QeoOfQrDN>hf!lY+B-mY#J^J;@$HrdKVkPwMgR_&5rC!lt#SZY<=Uy3lH?$1P z0BHhSUpR}=V{+gigWta4!+o(w)q5n^;5hW& z1Cr0r3n?xZjip#T5u*s4p`r{POK=1pk3|`tVu>i16wreQCA%>ez3-sJc^N)0&r7aC zUpXk5M9d+{?#mF|IWIYe?l~kmaTy#ud^P&!A;}Gw!NGIKQD9!O>+-nM^@A)cuov0?_y6=0w;zXh?3^S}`{hA_ zWiD{O@r_B2p~(}Hnagx^w|U} zU$N`96TjLazHA@tL;Ql|?Casavmklf1sr>dWfpjjWf*b&_LGvjZEgp@t7iLYj3P(@ zCn%g^k@BsQ+0`9XyRPn6Z&K|*&t4flb7l1OrRde|x?yS?eutP%ZbR=7w}~sG$G4$- z0<*eBF{v(t--1?N89jDowBqvU)r(qDetG;w^yrn*BiqnB25tCt(W_mREZc_P(XT^S zMh|X7?@&YoS3*ZPPPz@hqwf7zMoaeftA{rxb?@mdvT*)R$qVv>JD6UzTZ++`bmKV| z{mX-r-Io!DIVq;blzx_h5=#G_dfLchDNbLx8waiLvsa!o}gTTpeHC@f-4%D zO%^*vr7O;x1UrVQCn{GUxL{~DDRxXX5SFbfWd|OF<%)Qal`G;EfM4CBvv#}y%*+)T zfSI`>9%N-Je#b}-@0YG#kpP5cD}F~OgPFM^9%N-Jen$fbz|dZi0L;u*{EilYnYkif zvL9AW!;(uT^VU__Gm_ts&+p(nd)1x+Se9X1#pN@fk?h%NkcM|19Ds!xwmFY>FjLIF zA<6K}8V>F&hFmaxZG9oJo=(KWhewAjD(Ks6uagHNsoFTylC{RQa7h@dwCKEzJ zOmfjuxt>W@3(;7zKvFc*Pf3RQe3O&Im`Ej)3_~SwnvJnI!z5X7ZGtP2BjX8?<2i<9 z+cZ0nWjjN_WOqCw>RMO^*=v1c<)W~G)2eA zlt|!FA|>JsO)$IKVjRJ80!i{o^r6V$wewM)<6_`(g<)VwoMFiXE|Po-Ct%n} zctwgK66-&U46Z9}Z-!~NqHl)h`O4s{7d^x5DMnlXk1u$JKQ{F0$qjeb2J}2J^y>c0 zfSp4xC^--z5Dxf9E{MFy(e!}G#0U}Uj>iNx*=ZAp3o(|&q*;*UrqAA}KhW9xUuhHk;<-^}yp9~t`BZcVqp8w79Y>&i}5FM)si#i1WPyDD-~ zAs&sAILoA>I3tpAJeDM)I2+|Df#FkeIxfbRTctv@nogdGSCi3txf(0iT{ed1ojOt@ zcr1QGtFt<7R)eeK(X%V#~Ya|0^tM-B&p6sq_ zyEP;E1zO-JmO{C^WP4XRnEWKk@HichbG5+_4A|2y6JWdLo?iQoCKnqDc zE(%mK!HFq~q&uubt~45wp^ z2zo?d2#zZ+*K65C66V)D6`d!kdEU5aFD_SB>UFnX?RIFb&5|v)Ogfh-n{ERm@Nnt@5ebt-dg1g6xUwSnWqebB_sHiEJi z=mZ~wIg|ns;0O*PeJqQ|qAUlhE*Yhn)CKi%p=RNf(X&!;wnQdqCPbIV7OIJ zPnIakq>i>1TJdN}<61Js^^IbCCChm#sd$!fcoWuK3MPB0OkT07McZ2Th^(g1$Lz!WU_HD)QjC&uMJHMeMrK1Q#3?HM;?&v z&5@Kq69O!RVq`P{CPH9wkq5<0MM)vfBt;=cbJb`mQ7$gmHabj`D$|QLTdeB$#{*g> zz>+J;ftlL0Y z^#R82^ZNaZAckR1bbCF9P>2d>p=4N_&EyxoZktulx;#!D9}sL_v!Of5raSSeo_O}E z1~!4CQRYF}-Ym(1Trvp;r$CT#_yFdeCV8+`ToTrj6cvrp8&$h7azWn;AFT=OVlz}o z*E}Z|oIydKT+r$grITdd8@Ks`G`(Dj8QO~pOJmWrOt+{2`rd=GgIha@B`Aomp}B{k zgW_zQg*hbRU^bzHI8YA)5hHM#0m~GJ5slGgWjR*J#xGPsCm0BWMq{%PUXLf%7W8?S zuk0Y2=|p%Xk+H_xV#d!K+l{<~AsO!EvctWYbmXG(a%`bku4R&?eED>`7|j;ClDK*? zh_|JaNEVbr*AgA=2T{a#S|VN$m{=?Uvx(tha*?2LJF6ia) z4lp8RqjeV3POU*KkPwAsX>`ZiW&6@plz;(+j_gC(#Q} z%l4uD56gx(hP1Q55B+Ic;JW0ko_N-GAnx%12^jxY#7UyCYd*{NS zmeM*hpEf0Z94jsd<0l=93kfEv%jI&;m3Sjj%BLDed!wFfs;!20s8I^G+LZmr&zfF8`UO&D7=AHi-R*>_y$Ls%r-K_1}bb#C$i3JuN$Q`to!A%}@39 zFFY-~o?u5N`zEmQK1E=7eKhoa3eZ#(e)9SuHDlQUn0k+00%&v}&6LFE?U_P@v zALZk)jG?$%xtN@bRx0&mt-e)IdqH`ynJmE*%=y#9-`GF@X84_VV)rPqw?b8x(2t*% zkF5_@hWV?1&(Gx5?fVYkCcVIIy#H67(7>$!0y9&)xb zH@#*DZs6nSHgvH6SDoI#44fapOsg30@Bfu2_b(nE9+{Jm{igDh%Hw0Mv2Q7to*h4P z!`P}}0LBID|5er0-~~Sa+2LKibXz%afzhuzveFBDUT07*j_K+fZp8X8F#1);Q=;$m z^zbDkNnNzbZ(dKGe}4E2`>)dleI`HUB)v8v;I{b<^;V^P`l5lmbiEG>q35T8HKIVA z|K{*(O4X$d&c8M+Rjo_UjQso9v4Gk^5uDd;(FaAn*}^Wm=^#NG7(2CSby{^ki(TWO z+$4>jD~}vT#`1{cn8;}?Ca2NI>(s;|n*s|^M`0WYry4~Mt&h?-M? z%A3MceM;lldlW|b=jGRrtPFo|*ez2Hof-Vvz&i%a(r-#1mX1pPK(dIv41{U<&2smn z>RnQ~PVyc2i~SO`)KB{}Ye&&r_|aq7Gw8kis2V$hzQd1RgFTHVgi#%K7zKsV!`MgA z=iY%$qsN5N6VkJ{tj(jpKQ+1!`|x^YZe$2Ub6=7UqwjrtU^hDbzhu+WwZ64O=*H`T z$%lH6-EsZs>3;j#LDW7lvKRXU^!)=Plj!#kjLcyN(5oHxzuy6=_vzN=250wAOXAs5 zBH64bqs2%mT1<96^nI}R)IH+puB*-pYx{?0r>7-%xw=cW4nddb1MAj-|oBlFU; zH?HkP()ke)d++*<^CMDBx;DGE2Mrw^xdHpV&J$DUUyqKAq67eBR}IaoaS8O_*wK+0 z^xV;rtFZsJL32H}8=W{df@AMq4;>qMC$|1Bd?YDBA3i+tex&}EZ2f#?CUpt2G z;6@K%A4N}bqkk>EYu6eNTLU?ceQw?UkoC=9a&?Lg&fslf7C(6`j4#9o$trdzg<7N2m5RXcmkce zVU!z%A*6<8L$qWqfL^|SbT=A3H9CQoAC^yHpXsp$fL=zz-~i3h9?jFIMh8*z)aVrU z=^hOLPDt;%ZjC@+xM7sWKDGXn8%BpD(ly!IN%TWtX__0_%0UJe#2_&VGlM-1U<{JiU zD5r%em5k98P6{2j6U#GrG{%FMNMM*4DF_sJuLk>1V%-O@K1`khR~h(@<9Jd`b~eM{ zE{`T?2y(;-AvTmGU{}Df>%Vw)^rK~0l8Pqy6bJDLuH!ahA)#3yY4E?tU>6@t#*!&6 zT1{5Ur=p2sw$xd6)yw&0iQ2NC6HigpDVATLI0oV(=kFZ)hI0PRu>IK3;N1G)Q}SQz zACioHq)*u#LkG_6dg$4?Gc#l4nn5zs=fj524y$E-F+Rp~aoF7pR08&aG#3N+5l!F} z9i>QyjzJG`=#{U@iB(&hM-li5R(ojpDcPDYUyX&n62 zjM(WyQsB@BUzF=Du>ZZthy$-O%P2wVN3;3^sr|;aNlrDS(Xb#Y+{@R)eUGv8Z z9Qz+==`Q&$RQY4YNz90z`eVg$?9VQM*5pSq0~-0f;xP90-n_o*Zutmud|t6n`nI_> zJ$mS@`~ddy`qO9SYZ#_OHaL*KR=Xx>tS} z`{MfN?v<}%6JwS><(3Xgui4N$z6!1XEA*MKDsGUjO|6MY`JnuI?DIX9dFDa6MtXK& z&5C~hRmB19FVVYSRO~|h*A!pHEXZ`Hd;$B5&Xc>)BX`OV4<0Gw<*l9Q+?$bVNgdBX+JhR28Qk@N{DPq`um56dxW3wQ+`|dd8o^} z@`lT#z;>kYg7Caf3M>UK&yGmE@ARnZ{G8$s6&sFt2$n&ljAbbFd0Y|Q3WijEj;9d2 zpwO!>`p1Eq2J_3K2No2Dt;8fjb2Nqi=Yqnt2?j?Z5B_@=-EdN&-wI|S)GLbU@k_uo z5Ag!={og&Q*bEeO>PNB!INN^aR`^#n{upjBvc7WL47Jv)6PaSlV~ZO?t(-mJ0jDS| z3@P5aYz_K6)vU7=b7oW3vd-(%>#IR7!v-3SNG`pIhjC3SlGTTNwH&T?w}>36rJFf- zt75F+i#DqcFVT2uH_1|@(RMh( zfkFXq)&otOy?_gqfYqnh(Y0pDM>m%9HX&{Bv)QVL)L48=HitHA^lQqjPv>-UQIjs_ z@(QKK!MEPNO(S27S+bp(0nzx*IRO%Mck?XHu{ohX*I(KLkPdUwuFxqXXPUCvB+f_XPdtVRm_a?Z{9 zoDF)#qREDei9pF>BJz%euUHjJA-%2;5Q2eF#;PrZ$!OFW_L&6}y<&B^3jRbgV{&+t zYHLN%q$-+VE)ob9t$B}6{kp>ffl&y)ZJ5w;cE_+h=T{_GD{NL>TBzpn5ahR zM#V=hsS9bk><4ef`=WF@5RAA84Xdqdb?TNco@&!8*_2gJ8oAYKCD{na)Qpfy zC1WcQex>N;igmX&sAu!Muk2bDEbbMPB_FgjvRO+hUc`NtR4A6`ZF-l!yzJD3IUkvC zgtE@XrD!DNir|4z5`6MPdns(ht>u-BqvCbwse*@02L1LWHy-nO(|cg;Bous9(4nvEF?I05koT(_jwv&Mo^sJeuL)}08& zTdjysNc)?Hia+C}b!~?cB2@0z9Tq|mND7YCb)<#H$;%uK`@^8ZyXr6JBcid*)fU+(yz zjkRFLMaH?5)?Hu-zPMa&=QJ@_JZJUh{fl$B7r8!P36 z&EZ(#NrP6MGUT-}OFd239HAw(V5w3e7zV*?B`xK+!LAE0IkGFBLaat>JVvXHDT}q$ z6%S73Jf3{T!BdSkz3eo3n}u9Dvr^LXhEO7F#W@Y@(Fz5JtF86gJ<(9K9`)mDf0<%K zdQ+^bD_f~Tb*U5&SxRNU(01!05wGj=It*+O3l@Rd5SGj6u*bqMD%Ex+7!PJwBJss` zu5QUi^=2w$z{|R#&D>l}>dfZ2k+VcHVwR^WOw3(q)=d!Db+Z|#-s{%!F@JV34}R8+ zI=Jiz8DmaYvf)sZ`l?$KQ0HBiCauKtah@+>O`V zj&z-0_Jl$_lk>!NOF4@@>#?=Wi41FNMeRBtnPOT^v!%wx3udC_B^zD#1#G0nkQ1v;4dYIw0{L2@>ZoX& z?m*3>B^=Rkl3r*J`Mjdp#QCP0I!j+{;m=t~H zV4HL2GI@P2Xmq#oOvdgpwKCjmHodOOqFD(2lbyA{O!?tH<@)d$#lJ_+ zzog(Fn2)k4ND5(NcoHJb;8h?5Tm*Ll9)lzma5!)Y$X`J>-#m8XJa`#6pou{^9P%3( z1`>K=uz$vBa6Q0*aEcV++~;R+9y>WtCR2hyqy(HM5*<$k2@!1A`Qs1-CKGXRU%+Yu zscsqL=S3n#L1s@92Tup=#$mM%NrEDYCrBp6l7v7}@b>&IWBPeEDUxs&n8Cqg0wE^> zvJXWT{C2QvVTD+fgQP?j{rN3p*U!h3f=IBC5CZQ37X-mWo`XQZCng2+l3^2Uj7IFO zWApQHcs)r{kS_;r7-$jCfV+kh5|Hi%i6?P3l}u6udh4ywb}~h=DS}ABI}?z~A*3ic zQJ#c+q6AArwGuHpo2?}zGM97Q;S0s~wY?e59CK(EX*pS`|z6un-ZESHq z3T~zpWNSc50NF{xjB=34LBoqUB1P~}SMal-FWokFd_EaxX%WukL)WIDg>(WuSdh(t zlW;(u5>nBm5KE$&$k?^>G{nfo6y$6HOUSQ{L9alC>HV!NtS~o67XNq4Eji9Y~c)~zCuzWWC8He&f8N7NcsRj5abe3 zke~y3C*VI*$d5uu^YOm1A7YOy?p0hp`q5Ex0Oq!FsgiBA)@bpQL!6YKc|qdf9>;% z*Dx%Ep8JAAK;Qn7Vg@~RLOFtF|3qQLg6PbjfFt66by(~|@A(tOQ7nL7_!DsX{Lda} z;)@Cf^CQC-6*Ttk9ta+sK&_}sg@`XIr0A1hRLo#L^wJl>_wh~id`h(o-EhzN5cq*`rwVDqwDrRRTMGIi$3!u#S!e4Ug!MyONtYi2hG0#&;LErzo57k zbEDsT0X$HDhra%TLf1d`WY?GNm#$s4b}Os z_M)$xR1TwuPbz1zf9`NU+yMv>>lynq$8k1Al1Yk;fIQDlUNj ziN+9Nm_y)wos9|F(GR}`!Jv4Or}nR;U-c#$bhEr72> z;DtHKKp!SkUwT*tHp4&x`H3tsH`b*XyBrTjph2h34R$F8cT!wKEkKr|AaZjW%gQ4j;MVI0-=U}J>ih>MZer}{o zF><*#li(oY$+`Y6ML$ri_U;DQ@){Bh0m;ruyCj=uAh%Eu0?D)V+-R3#^m4BuAb(jD zlrQ&5=agM4<>ja#jgj<_^xSZl8;6Du>>HoasDE3EK3`jrN$9Jmt zbr7+y9rUl&2WL-AN^b83_M+)X9e(rhEs{;ZM+`&KvP#5i==7X&Kh}qCE32-MbQ4Rz}K z`8uCaSs)~I<60S!hmeXJW zPMlCGA3KU2LLWM;JcxetT4m|{ol3~6c{9`U{8P#;2Ou`4<@x885E^NMK}DGXNSsu;s{~YPw6bsq|RYR2Q!AI1=<(GJ5^jMZ7?Krt=+6xbc7b3h7AkV7BHy5(!RO9FlJySNxj_M;0yxaU zv2(Ic52$5uqHm)IE?8LtEESk4a)+h5$b=BVQjt)T9p-L>f&`-q`T67yrQD+coeDfi zk>yv#9TsJS1Ue1!)I@%ZS-LQy7lVDw0@y9E7CUVB1`m1xtQNHAQuBY2z}5+#KopUu zIvcL5m5x5;&y+XAEnH`muR#LAKP!J*`M;D7<=-m{5D;p@OVbX?Q|^=Y4`X{fA0>M_<=9o75>gPL z9NyI_hh{saY^GDnr#q!$s#A_kcFO*VPAMJll%wnKe^vQ$#VULCSpR{|laTDb?O*q9 z|GH=U*Q>UF-M#(muI*oEw||}Ke%%z=>FwyL?O!Lif1TL=b$t8R?N{#fMu$7KA$wb| z+<{vGF5)*NZ~L7)8|aH-xBbqY4fI8k+kWNF2Ku7BZNGAdUA?#*y(n$l@7&pV{GzCB zzjJ2;eNoJ|U%7J;y&+@UuiWXNS3Aeth>H@o{mz}<Wq+XVTP7x(nE1srD(Q zuu0!kW_!B?TkO=HE?|q9x~dD0b7jJt}dXnQopboW@o#QEhcKF3)o_zrn`VG z25PDc*kYe1yMQg`X`&0*Vx7jjfXxLot6J?|x3HzT7pCB*d~^x6wC>^@y=a=oF1fIw zH&)y!ILpdjBNta+tQ!f&12uhb=OAlWp*btR2 z!Iu8LK(I<~NK2PubN6(y9h>sfCD<~o7g%fxOqXEGT#%Xra4%SX+{BBZoY3*(YoTCW`ovh2Lu^GaGUQN(Jzm29%Y|ual z?Ha@8cwgMd!6v)2mnCRPrw%IYOrP>8<-*v1Q~XjsKl+JLVdRC8TZWz*{Mn#m;0fvO zf0T+q@!h^~XOlB>2lfx0zpxBG2K${k2{s7QE5W39`_4+y9S@G5z$QA2;C)DS@3?gR z%MXq}Ai?@Oj+{dX?uVR5&!to{Bs(`ggU&?Z6TlSc^Ji3Zla=K{A<{jD0(%z74Y~HL z1QBP)jhG5y=f?N-$ba|j_)R11Sum)#g1;hy*3OMjbuf^B7*)+;$_-Kn?5yCW25f8t zBt!dRsv9M1tLWC4N{cDBAnuH*M$kL&9iQ&-8baTTsZ`Rtg|$1-Jt^3#$=9Jls}jlD zTah}eI)RNMM^1GWI+s-)k*vL?1KWkZm{m<;koc2R?Lj}vst!xmZb$oaDiRy+z-(9> z{Z3AG43l;D43FIeyPki{sSaT+G?IrugXpP;A&2tk8P(9bJ+FEKlQoBCJ(H5PBzmN% z+Kb*kG$ltj&%p-dPu~G8S}3Z*SOeWxRN~gm{cTaj%T|VFMR;;w=gB?j zmAGoYhkQ~tHHZR5)jsL*Ti2G+-6holOoHBDQeAicdDZjE)4%F8JO7d@d()e`>2v)d z<@n02TU|a7p%5u@eX2Nq2HOTF;5etaes}2-IQTJmf?fYnd3;25{*m#I-sIRawR_CA zo3*XzF3;^&Z40```h72r&*>D>m%$ZquCM=k$sb5hDXU}uXRM(3TSZv@o1=d<5*hxB zVW;dbhkiNmmjiL>_xe97IgXth{hN+#Z2U-H?yrD!EJ7aA)n|93!urH1^va#%vfe1d z9(N4Aus*Sf?LvxAOwicT&fe78uQ)r1K6CH*Ui8g#ARD)_(<1}1N$kejTJZcOUrq{o_hxeqj8Xj+byRa-#9iZ3AT_OSEG;W`)AhgxO@B*EWJ_t9Q534_kr8>8~1>^8M=S`NaxcOI(2UR zCJ=hS8_)yyj~_t4ac+D!`sumx8!oz{A=S+>_4?-O7PYvj#@9F;s34yI+3w=+H9+%HNs@~g~#5g)LJjG%+bQ~~~kWzhi z0lh4n;vtW5Nj9|?eOET6M9lEi3CK*oKnU>TozTEB$VdLC;VA;UzDLTAOkE2J$gz>B zqmVV&b0Iomog6yA~I0~}1@~MeAjOl^? z;8PQa!K3tY=MUWjjedFp2T2n@4a8Ijr0plp9zZXBc48JI*Z=9W6T85pr#U-^-u{OZ z2hc}8HZg=={piFYbnC|_E~uccckipug0Jnv9|IU*$9jPkfQ_NbA5QE8`Gcn|*vVeY zHy=3NVKVycgb4(2?&H9J<=Kh7kUHKCpLAJ%{MiW#+lT(?*$EAd#wOhUv56b8y}gH^ zQhQ-sHj&@^7(BG6gS-KTWfOkq$0sNS9714O$vvZ8*CmQR3!V38AD@_pobm36b}GHD zJU@c9KsPM|91zSS)4A=LLE(U$%r<1d}$N2|$oxGHU>3e&JX0N$~g73SlLvbI90>vtPm_2q01>1LL zhvMGZqwrdAZ)~=cx}%3Uaw&p*O9ydo<}k3@`UG=(4?cehoNjgC_spywx&%Qrx`@ex z!(hO>udYC0b zer5!~cTDfS1bp)_fZsa3=Mu1A2H>|$UbU?v)*%44r*~gM+XGMT>e9juZ!*~mw?G&N zfw(m}yTM@v_HBj^usJ!i31k)sT@N_D38WW@(;Z-Aa%uzE>9rFbU~PKxk_z;|GZUSj zzrNeW5NAk(fx4zkKRLd^WQAHFj&*?5N!13h!};I<0GH6yznGkc8C01Z+rV}n+26rd zb}M@Cm0pyRtE2!pK2C!2JnFMN< zo9-XJar>0)!6zgg;^EHVc8EKz%T7VOX?G9S(;8jqdDYbCPWD6N*Z=!XQ@_2x^9jWx zQy;*dT$i7j+BMiY7c#tx{Z2=pz3U_tzllTf#0e~gV`9?lYA$uTGru$)_fw@| zOe6ns-=f?zddH*cDd`$}_9pZsH*JIHc-OGp#!aixG(UZlbnW=r>(H4~(+13nUVL6U zjXry7+JT)yitDCLaCG4!2;%(LO)F6an^7b32?O^Z!?#Ag;a9#wy?cZ4G4kCO1)M2pv<(sCj!}LAm z=2G|XZkj$MeH(U`LBrB19FCAYJUF#`-6@^A9)oqjLjzOSz(EpVxEsAZFm(jh0YC15 z7B?y}iZp|;=pj*laOw~o9f8MR#t0N0nli(Ik?v8)u2KKU@YHy3qxjGetXyDOHH&02 zc;iXL$)--hNfKCF-O|}4%)%{kqie3S>Y>^6O%m8nU>r2Z!cOCmuCU3l+q(dr?5!xi z%uX-B3;%2bi)YH!>b4`X1~uvAjf}});|Q(Y6Fl#n{@eYBFJ&Q_ z?8k?9kXEK2-Mdw69W|@XQ6h{-Ee&%zH>wdd(lyiMoku%&Suj1 zsbVCTa>PxIwA7}%`<_+o`nshNAN>^7ZEsD^kEtPuQAuj3d$tAKL z(u7>WN_)B4Y~fyx@ytxw0P|axCS4)<(F+($3^wha* z&|fbXo69(#H-yU0P$jHOP`br@&g`&c7t12yspMR2Gf#Qcnpll9m(vbyiq9{i-&xt6 zLH5$roPzReb(AA#BON(k8?AkHcK@n=amAXA`ABX_yQIz64UH8#<}%bR#$?IJH60}} z?2CnCBwhB}d}e$}-_jImV?5t-XEU*+36ic27C){nX|-g^E9yc{Z93q^T@g4!VTJ5? zwjB)8m6*O#^!cMDr_Ow$~F0dgKy+lOjXtqSt2-nr40FZ4NW;_3i&GL zvZE9+H1g}OK0N&%`LCz+f9aI|-Ra9tX}>!ejU>{(m0Bhs#0(m>opzcG9G-9)gQi8h zzDh^Jc2=FSXoO}cO9v>YrO_nPktAhUsia~pqg9*pH7v`dZJBrFBZWL}#N+OkkZR%9 zfY+3^CG;zvM97|lG-ryA=X3U!P;@X}%5QIbA#puwZ>vK&Q$sA<;Otb~Rj0#n^OB>m zEG&C0)tFbaA{ zWMXSRU#wiHSC;*PEm(I(=#)Aiw>Ygtrlbqh^EH>?&Q~p|V9S&6rjz9e)hKd&hAB3) zp4M^*^jFc8Ehn_KeA3KYs(yV=*YHrZR=Zp>wQZz75p_Eg22&s#(b;)NR!zl2dc2+# zZG4W87llk?{k12j-~H=3{a>r5KXS>OCVFZ*V}T3B>TXxU%9_&6SOCEi20 z>XjCm^0f5%Y|iSoS~wj}HQ|^=F&Houbq1@pWzsWg!QHNh^(*zIvd3j#uF|POIBYID z!a35>%2KW+!Q^bUU2yElS2jj$kO@V3Y(BNNkd9bmt=wwKT5cN~$+l3i3TmU5DOTE$8^tbrS?+Fnjmj|y6^*^`8$XJN6~(9gXL#3L{l~5On z=Ay=y^%pJvnvS9KkPTgO2O!_8nggC&*}f_rNo8l5F3^&c z%d7XZg`hv1h#Leeo3Ge)EBY0&ptXg3@kMVtgZn(*RXXo7C-V5R5D3yHv)dMH6PAcE z)p83tOFNlt=&IgCQD13VQ)I60C({ujlgjAqaMfXA$yLsX;XplT1s=j~$7SM!%# zR%eU}gd65u#8#xzC9dG~=_o4gEqOwIr$xJ@<1C9@v>2vWT(zKeC2#YkMN61>=*spL zIGtqo*VR6&ooeLtf-9kOFS4z$+7&K^YC63mYBC0^bWUd>m)*sPt5MbZ>I@#J*>iR_ zRCL%9Wl^`>WQ{PVpZoQk{;!_XU%O;ZlRZ6Mw1h(ueJctF)!2+D?AK6jEAFE*OJcla zgVl%7$kxefJ)E!>34N`gZWZn2m?N3j7fq&YG6^?y@J>^bN>=c4tmzjDYBJI!s$45s zZsnIkrgYxDTn;5@ZP9LMvc(m_0(T^q9VxuN>}*&m&#JfO_28PAy=hvkMs;v1gz{?J zaldoP>=m^i7yy0Uc9RJK@wNDYT6-%yVPgH`@T9dM*s;!nbz%<~%yv}P|O8FzC zmkXxS3?6J-tA#w%%DZZoq?Qug9$O&itR*Z4VL3tB@aS^6&U(`Ih#gL17xd8(yX^Mx z$x3?twO4+vrvJa5(^OAQgMKNs8CSvVw6?8BvW;C&w*3Hw_gkEf>gM85*jFnoNbT+<(x7y2& zY>ZUXCf5qF9MVOid7nMm(1=mDrM?QT2shk4Z#Fce4$-Q|jY} zRy1*zE9X2u6Q8P?+VM~hJTKuG>#>`2l~|*yr(G*ijn-hvTg|+KcBdnurU~wauHiz_ zV=f!pI7LLA78{?hy3}zdXm>TMQ97LR2t-*QB=iljno8AZLd(XR>U^Q)bdhC^3eG2JMZndVZ- zgrkeM(C4k~}whY-I1SZ0H{bZy!iYuaUffJ=1sBW8-IH=MfI}*YCKsQyIhKAOGh1Z{9Y!3+~b?-nY0x z@_c#rH2V23r>h%>%ij5gnRiIv`<9ex{bp=tFD8BP3y*zd{dUPr29rNGY|3vu8U0;& z@}zX;=h9~^|3k7)49w&(>Dj@bzqbCngEI+CX8pT=@^^^QYlAa7y7_^?Z*G=neEQ33z{lrNt-+=Yuv$m3>HmT$UAYpSD@6z zu(}pmY8Sn&220_zJ{uPUP6qA};hKKVv`E_Rl}IThgd$X^TF9jY#-%TB(-u-c+4mF*2>yC8AV{ro-hxGf>hO@`jkF zQjBsbb2_56SNv9?N)-YrrzKS~EfNW{Gw)n%@=Y8MtY}z5w~{lI=upXp?b3x%I7JJsk@) z%ZtTiA-kw?>gjq=trJ$X24ii-p|-J0WZdY~2EA2H#vU;Ss@la?I8h2je1y0{E;;kH zdc0JDivg;+vVez|^by!3?VtIzGwZ)N=I}amx)uf>xq%KB0%0Lo@^HaGw%AU(jp=a0 zRf{Il9<}ZNVeieu;obCy0AhM=NRd?40vh-5DRCiY|)zwwq3QeuO zRIk;0D+~bNp(iP<1ToB}Zf|$z;nc)#5@ah=RyiB7^rU=pf*4 z*Og2=t!IWL5|8G9vI+=a)mTrdSiN+zPr!_>u~sl;3`QNdS+5ClN~0p47ZN ztR$k%vfiP3wa5@pn~gjp4%(%bREPlQetKMYGi80yM%~Ry9t|_Ptg}6T*h)%5ql;Fu zSrd-^@m9T+5+fZN8~M!AxRWSq440Jls^#4y5WmY!bRd>Co=3)(A(u+wXkpnRaIz9r1qDtNh zii1X?RJYg`je4_|((Uzp?UDsARZ`?!H>%=Zp-3f|PAHp}Yx!QuN@s|I2|?CwzG29L zs;{Nu?s%$an6*MZ7RzR`9U51A12sM(c4M)Tk3EHc=+(%Q@YrbGXEZm|~y^oMjcV z9L950uThHxkVXX2I!MXTvN#_Oni)5TwuqoAaR#4}`F^lcE>;ALO0)-HOm^uE7Y`R( zooY3h%7!Q|>GNQ{T24tdD@AL_lMtFK_6b%t$%s;75~c@YDS@Oltk5a5<>_RazSZZ> zIXI^e^ql7Y&i3%Uc1lu|Bp1mS^Wpe_!t-doD4HUJ>Cr|!B$*jlMyr7^P?pz zSL9%Z47&zlkW^=&CI!^pt(zivH(TvUhwu9$L0>;p50XBsA+gmiDe`ERv@CC~AI=hS zy2@%|F6j4iIG7ssW`Om{)Q&P!rO#V_^_16g{JHfUJ=|PEQDgnl$-N$gFBTT;Vl$ z#}lrzEtt6#UuzT()5+XW12R2)Fy0`9dy0DND4m8v95C|*^Qy-wE@N8rjz zHn>VZ5NZ%`E-Sd3DK1Kc*hZ(2QNq2tpDb3|3CmPPBIRj>IXL+z56&IMvkcl*VBB=LM$RhMumF=N6$;2$BL^{| z(r?GK!o3XSF%2)iQ5aD&t$CA6O! zF?l97q!Q6uGcm4|K&~g(98}U$2uxk3m@?~X)Xeu1LV?amR$mQLl$K8iYY}B6Md(Do zfD}+*rcG~AScIrVm`QPDK<5hv=qs4d52O`YW+7a{6k2o3oWqI+Nn~r$;yqVX}rS_rU zarzEB{=!!;QBOE*;vLuyNAcZ9&)LVSi>q)Jzxrmgy!sP$k#Q{i^qprH_MK+m@xhR-d|9N(C=Bk;E)9-Y=;&{ZtPJIKOzh!@|wTRBU?)||H$A9R3=h)|c*u||xK8?zi@=&)G$8W&X41JbucXu4ikjKeBK6Ae3AQB};m6*9q_Y z=1*77`B!e`h|i((?&UMT8v4v}9s7bDRJk5XCJqb7d8d8d#y;rc=65>)3oOjctepJ$ zlh?gTSUCErf!)5|#l3Ckk@Hi+6c8~?fiNFP^C<*y&jF>A7XvOS;DiEgI)ea;U)&Aq zjLOb!du!7QNHt9upLCsody^;Xs33cX05z3ifOZ`QB1@HPCPcEiPrJb8l@NRSX&!FcCrn(seHeyk8)8 z=muV@HSQ?LP^74pUra9c?u)j)`OO!K_Lf~vZl$`4&TqZv=y$#8#rNO068kB)^4#ji zWe-qLk?2HbOowQU7oSjO$sq5D(gaZGfL@KJVmlAtdu1Kd43hBR2F zLW3NkGLgf>40-2aduyu%sd&90ETsXZ6;Nl%=tR*>2F^~%dDOk24X8NemGKwQ`Lmwe zEavVV9d3UbX3ht`h|W8&raH&Ha>*Gh)E6(BcU*txmg%#f``OAK_{-5VZ@=o~n??`X z*aL6kRzC10Y(2Q_w%_3VqJ8m6POiLjVei#}8jQphP=3TF&t~nF&=jGYEp+YCwq%?hF*qP#{0kQ35pCXnFSxV3&niz(DUl#lCvcwPW7- zssDCtKk@F;%ANOJG>^Y)>OJiLeDBJYd!FJ}F8(q)e`0F)jrd3Y<97R*t6@E?`wBWg zaRlys{vDjX{XW|#qg_NJ;ffCkKnGocyXPhWv{<@G302$ z(msA+w2Ec`Q-w|tgAVfzF2p`VAM@op$O z>^l3VZS#)@?C)LY;;y{}N{;!%L;rr7klA3rI;r%oNztxP{Nf7#mp*=;z2}m}i{`gK z7dT_rrB|oz-`)!qK5!{iz_!2BAN=-ZFWTR^6e_$WcJ`iZMSQ|ey%YX+)U%fyb@C;b zJZ~@E;EJE`_Ut@o?^8l)QloTW;Ddyz$-F}ikOrU?n6w}XV0blBmeHMO@2#yWpx=mN zAnfP?Dn2g|(E%|X5Ou&D1;#c^fzYF2Uwj#i#yP7>$I;?5D_1?row4&Rdpn>=1Ji(c z4rD8-$1bd*7kU=h60kFE4SY?{x3IU)VBaP|l@5 z?!gNWj6mUjfyx*GVO12PRn-dumG)QP1N{;I{iTn@e}2<1?1#R&2tB|q{Mz2C0`DRX z%!ml3Qm{0EHUvoWfZLA(N;A-vAZUU@?e2S_hhqmH-MDk}FK@H&d@qdX$m<^4bK4>|kdE8r=iDD2V-u=lBM&@Omw-_>AeL}?0G7j*+fL}mM~E1;+Kp=%u*cir@` z{m{qYcD?U|q74n>qno{_#8-X`-F<0Na@K8EZqKD&I(^0W1iXeTq2%=QzWDBQ|MN!4 z#%_aV-y`bsD(*C=JxGy#@`Oj@U%^O9ruDprD5TQIK8@ z?VJw(TaWX;xNNsib8`1ywRrVG*Y|;Sec$wVraJzbsa})K^q7rMokp#RWxCOBiEPy~ z{i1*brM??8hJfYCRJ)~qffJF;uoZUqnr*fp&C|K?pp3=YQZ^fk$-bc182UX-wAU#E z#j}#nda-6lVlyRx5~YQ9Br{Bl<&aO#cS?bpXc{2D+3k%w%T>^cu2nFh84VxJ%# zMw1!Rh|fwf5Gf1^{cbA6Mbc$=u2U{%xojH`blgZSn#{;tx6X*Nf5@Xv7Sp1cY&hBr z8bR3`u++AS7i(0hDS8x%PvbdeB(ro?63hMyjT?bLh!!dwA!~tVTrLIDoW@7%xiTJ@ zfSC}h+g^S4!;1%@$p_f;eb?e~3wzP_fVlVB7k|%r+_FC!9acJCJ{BwIy+Q>zrN`+A z=(Y@#lu{^?pjcfBa9FR-rma>wP-_(_Qx2I84us6xQn_B|Ybx8%jeGgxD4sJyO)n81 zyK~;Mww>BpDz%2BP)$snMB(KB+)Q3Szp30^dhMk zNJ}?YwGFK0&TuW2xy1-Kkmmn*q7Q`cQP`c%_ zLxgm@u}mR0Xqz7w0YT~75iI?zL-tS1!8V8K8qNxQ3s5{l-H zPSMCHvJr{~6Ez~oBv2)i?{Z9?(R2^sLt2%73k?KS+@};}=LJ->%n+qhT~*4wYolDCj$I-r&@wv~E(+)nsYAxLk+vn0;|e|)^2 z9*>Kpp{LWs7}kR0N>7SXq8O`_2$M(oP^L5xX{O5}tZYSk4WgTf6wLN8R10RsY>_UM z$!r&?(h-r%#S3_c!AJ;kQL2^pddjh`97wB~e6cTp?tS7i`|+aFF@MoJw|{%B@v;93;1}#C zi$?%@=7I0KSEE0j_#3Zz=o>fg8{E?aKo9-o$;IOwvu|f2{?%8Wn!so3_b`{N^^p3v z34G@1gYcOHy_EkJk3Ct+qt}+Q746h984q_oIWa;Ps@_(jor_74RJT&%J*ip>)Mg6J zEJvmM;k+jY$%Ou)H&O;bXs{p7x9O7C7Z0*6u`Kt@nvW|IAUjW~q}eI*!k`nvdm}c{ zV>-385=91pL-DpoVUpvreIe0sN8`&~zsgh9aWGm*3}dZkOcAvP<0Gr?^mwFnOHp6T zKk94Ac(rDk{=vB8PsWQSLJ6h_O!UVpT#CUlNLuK5K{0BO3+Zu8sv#h4GKdwFP`_9y zsfErkk{;%Y1y8L}&PBDhFzB|x$$?iyBP|6G5PMID$6SFKCkl8j-;IaxLc9`+){{}l zjO@9+K9%!E02)IUy4loF$oaZf3sVQxx{$*%w$f#p0btm_b0fvKcPl5{MXzWyvgnJ)X1SUyk+Rx5daxu%F28PQNCFN`^#u z>ors_2oZ0y_=dq;mQ9Wl4Y?R-GzJZg@r)r=fE#LbJ!CS? zWPOYe{n=gu8~4<1vP2d6dQ1w83ne;G@x}UuZgPy|f=V(%=u$?>CWeVdC{!9!aV3!xr6e75>%I0MltzrC)UgyWxn4aurw{a;-r{_t z$@Ti2Rzm(zBAY7I1gqf@66Qb&#E4YNJ03+q0wmNN4GjrZRkkDsk{HA%;YC-?7F*4! z^<)r<2SdRwljmy5R*fA<>8P1(Q(~?i5hT_`lw4W~^vOabo5uqEJm5?usp{!y;T$EC zRjpFSnPnp58<-KC7^lM-tb&3p7*?XCR3XpCB1$WRl6j(Lbwos|w8E%t34;c%#!BI) z%)#!-b&9F1Ptt;^vf#67Iuj?bez&5IC@m93>26C))a-;M zH!IR&3mrBF-Tuhr@}nG2G+Jt{RBy9>cP9pOdaLt)W*z<2r;l)cX8pl@^aGlY{`WS> z>vOvr%oNf@(IAit>FE(ff_c0JcavSYo-b|P6K z#bAnraiLsFAbJ2U;M-CV^1SdAt5^+4B@1O@bX9CJi3X&-1lvlK>u`9EOZ0?BE)i^c zl1z|Wj@3O;4*~*U&3uT3?Ai$E>8Q9L(rognL1n_+;PzytV!T2iq8K8L;g~uIkBqD0X?`if~oi){l%J}6j=M6XcB*VrV ze!Wk+b7H5-jOsBx9!}=_0PW<`Ub0{`_%ekA!e}%)(#!(K^D;6HRrB~js`U`7l?sVi zH>VjnW?Zo{y(%BnD@-6*Xq1f1kSLWgVzm0~vCiuc0X+T8hd+Dh1vfeD)*qJ+Up?FH zd}PbQ9cTXg)_o@Wqc)i61)tLgEw`OfMhxtEDv?{dayRvziIQ@8_na z;p!o)*D=m_f%t6TndkOq3D~Xsoj%(PJO8wKdW-9h-~F}kFq}>9i8%jr_OUNs_~q3b zqt1b2{*%>kf34?dqtLS)b8d3XHsAZ6Cstc==Lmj0>yiIm{cXb8b!>2We)_@CTGewn z072ZHbc&!yygudhZ}{#M2jnqRQy0RqXtaL!bY&9UvmZ@4Pg!5dePn87#M-+&5Hw1q zo#_1hv%k4%;ZoNj_OTQcJuxYA3A-LV{*Wh^?JXInlyOriNkWJkg7^>u@hS=gK0x6b z!lu9s3X)c;+vDD;?~D8B7)6861d(ZaqCiDJkjxDl(>MwW-XQmF7#`aGLI$par5#r? zo2C)_xr`GcQRI5{(4`;kus59z!}tad6;7Cau#2tx?5+08JXARDi;sUDdE~`A?0>_Y zz&(?7ZrVY3D6g(*5X^&cIKfQD&Lq_)pX2$B|EvJ-u!jPpJg>{^9(1% z_0HcrT7aX2delV4iH7*N7jOUwC4&?e4&fa|)h2;HZ1)ThCcPdKUODbxcFdo#Z zeES#e{}Nza>!i>8c>dp4{%p5$PHBhNOH&Z7*Aa*-La>Si4R9I<`5qP2#4udLAzDt@ zzsbRn4l_>JvGg^}ZNKF)xM53#BK+|8e2(R=eAzx4qDS_hCPhnEMXDz}_{vN6?rU6} zeUSu3M_n2J@kuY4AGB|I9BR$xq3HD1)f;>>ubg8aawF7wPu{t4hvCK)h`ON=^anvM zFK7rMG6_hGi3S)BPmKf#FZ&CV#z&?;^yGak#xcnn;g$jp#?(hevafs_v^nvkyEYI@TRv_-@@c4`oCg(-xb|D0IO?&*V^==?G-vBr(P z{n$S4d}wk;5y8`6ur9Pe{pu1#JkN&;Cnt#z)%fK#_Rb4Wd^7)OV`T3HOu)4l zINvu}&bPyI)*SZx9yxryegB7@zSXl7=c_I#eBQB&Ug-SLEc}>v%!OumZ=SYWfo!9o{ua(W#4-c*0c%5@)2Ff0Ot?UQ| z%Az+qzcRh;o~bRL*t}^|Wy5a(yVO|cn|*jjoL-!|XQ}|z&w3rZ^qHHT-=4kn?hih@ zdeJS;vmCS0oB#OZ)%$OCb{q@Ork76Gw=?WohF#~Pk2+6s%s%;FFTA??iH|u?am?TL zBQv(P-v9hDSntQ)=FDu~=KmXlC3(-n#sG6|kvw>vZNRbtGP@|DriwxlD5ZCAO%s>lpQ7alO;(f#uA2&M9VyZf> zLh_5)M2o00D3L`fZ-_ywlVo#Q3kmQ67O>kP(<%=cSF+^aHGe%usT@P;%*#?$smF@(!fs2UJ(fF*U{ z!XOka21ng$H2@;GG*78oCQJ^rR77eJIUcQZU1jJmrigGPSBGGw+wJ*m@%E(vg`rEjH=x%?p z-YFzAy>cr^=aVI`fKyx@*veSLVK~sN@R?Mp7UHUXcdpqiXT*f3TQWgNJt6T)DiIV@fxc1G z`CMe6q7dQjYrqH*Ptm~3W)f0F45gbMUk>uui?qk#oZ%ck2(ie_SiuqUq?05D-B$S&(p8Wu=3sKPMm z83=rPC_++p#`K5rQL0T+err?>SBMIQkHYvc5$G%jkN}l*XWE+N#R!qj5k!gBc$A1_ zv|hF>)WMA>Sr(`j(n2IO$@>l_u_`C^ae)YT{kRUx1vXR@&qqeXVZ4TOq(Zs{jPGN? z=ui&U+vP&QOtPAh7V#P|HVixwPD$5WRaC<~0Y>s`!;-t~YXBeLs8whL{X_v0?}nbf zR0{N>dZ8B>MlBM~1-(=f^HJ1jz(v{+)Az=daN@^+&PQiI@t!M? z)j$5u8F4J!^3-x~pHXyd8;qj&{=xZX$Lv3!dsE#0-1E*Gwv}d$!s1JS(|*;NTaM4%JGJ#kAd+?2*0*hSZ`}a8oS)xv#q7Jcs9Vn1a>(XiZ~n^W zYc|(52R3h8cy8f=g&P+-3+%%7O@G?-{Y@X+^o~s#$gO{M;}aY2+<586{6=)+`q}e0 zJhkC-8{RwX-5_tEHf){$)%=&|SLQ48=gu##|IPZZ&D^{GL+e}X!|RV(_rkh|)(N++ z8_jN9mjXWdzsx;8_sO|S=A^k@Ge4V~n|*TjGc#AulxNPKdDHZ7roTRY{d9XeGJTBW z1;;~Hyo%;GI zGs3h7M?ogpjUgnU&;goG1I|(6$^b4^yfAuzO5!R3z-if| zP2FnWG3UCN+aGMV^W+)9u|JS;mz`Ya;#bc44r2fBI@g=+@Oszo9s6+zed|i|n{f1A z?;6@y&$~`tUVB6;1$xJTM+Mk499}iho>de$R4ar^P&nrCcocQ&uF1&u2f0eW)+Iq; z1Ux-lhgaj(;fcyByh}|7p=gg61#l=m^|_O0rUl2fMc0lwbJED(^qr+0%Tr%oyV8C@ zycgCg?gz^Kh}SFrLu{-2lo?yu;5ywtrr{^;W&W!M+MtG;nI_)Ap^KT)V&||A(0NO>2F6R4+*b>K`L9c(=5wf!a6) zxP5}uRNX^+G!31)er=c_kgKT#ICy06JAwxXW&uiq=fIfAr4yhc?$!pcRYa+kYrgj8 zQ}zcRd(xzZ-8j#+!#;Y!b=umK1bJgvv5@fWgMJWJ zfBUsHhH0R5?gh*@BwB!L$?Dm!~eZ+Y7GSZ2xB0cUP|a<|+15 zTU=TDty^7EVn0y$>n4NTA87eG_FY?Dr!VgZG8x%8^V=zQ>amTEwBzKdSEt$O?bE-T z{`L$rbN%eKv-R2F?2$9SpSy3o1)@Y13m1C#`>F>M_TQYg^}d zvfr=AraSB2xAn5Qv$no%-Muqk-@5GCx^c@h>u8XAd;b<=%UN5Fn7(n-CpQ20`XA0T zH-ByOhi3nC?w6ZeGe@q!bN2rA^P9t)k6CzO;i2_~g^$dq<_=#NFQnH!z2RSGKD6Pw z4NXUC)|`5I?&{fVHiR}DJ^%dtcjs@Nj?UdTf6}aPe)NXTdTMI&m?)H3`NO^2XBVfB zowC1osOyvuJcQVf@Xj4`%H-GA7M(j*lHXXjV?U7dZ?O+qbe(G7yXZRQwCM*Xt@p>X zcfralUq8iu@laRRF|+c_cTTZWhq~tMo?Y8Se)~Ju4sq&^$}oZ-IJO!fqMuKB(Q+!JxqBN5@smK5`r`X-DBvo3@JhM z)a^6&(h)A?G#Y~v@P2~3P=!y5+hc%_jU=G0M!^C?X_RtLeGH!7+>{-ib|LnMr(uWw zpJ~_IUmM{ue{$`Zp1Q%l_6XNS)9bdbv>rt4mmIF-uCek%AEb#gLlO_}%~DOlk&yeR}g>Zpe@;A5$) zQ>&9lY+og~cAUOE`4K+0Zs-w5Pz|)~y)tA}KpG9CMWK{p7??`BRpY|7HW$BlaR<

q|Qv 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 VZ7PiS`lHug`?>e<`#neZ{x92?J-q+` diff --git a/test/test_api_usage.py b/test/test_api_usage.py index b1f8b7476..54071de6c 100644 --- a/test/test_api_usage.py +++ b/test/test_api_usage.py @@ -4013,7 +4013,7 @@ class TestSuperUserCreateInitialSuperUser(ApiTestCase): # Delete all users in the DB. for user in list(database.User.select()): - model.user.delete_user(user, all_queues, force=True) + model.user.delete_user(user, all_queues) # Create the superuser. self.postJsonResponse(SuperUserCreateInitialSuperUser, data=data) diff --git a/test/test_suconfig_api.py b/test/test_suconfig_api.py index f24b28f19..ad49b59d5 100644 --- a/test/test_suconfig_api.py +++ b/test/test_suconfig_api.py @@ -95,7 +95,7 @@ class TestSuperUserCreateInitialSuperUser(ApiTestCase): # Delete all the users in the DB. for user in list(User.select()): - model.user.delete_user(user, all_queues, force=True) + model.user.delete_user(user, all_queues) # This method should now succeed. data = dict(username='cooluser', password='password', email='fake@example.com') diff --git a/tools/deleteaccount.py b/tools/deleteaccount.py deleted file mode 100644 index 5dda48ec1..000000000 --- a/tools/deleteaccount.py +++ /dev/null @@ -1,52 +0,0 @@ -import logging -import sys - -from app import app -from data import model -from data.database import Repository, User - -logger = logging.getLogger(__name__) - - -def delete_summary(username): - found = User.get(User.username == username) - dependencies = found.dependencies(search_nullable=False) - counts = {} - for expression, field in dependencies: - use_count = field.model_class.select().where(expression).count() - if use_count > 0: - counts[field.model_class.__name__] = use_count - - return counts - - -def delete_username(username): - # First delete the repositories owned by this user - found = User.get(User.username == username) - for repository in list(Repository.select().where(Repository.namespace_user == found)): - print 'Deleting repository: {0}/{1}'.format(found.username, repository.name) - model.repository.purge_repository(found.username, repository.name) - - # Now recursively delete user, which will clean up all non-nullable referencing fields - print 'Deleting user: {0}'.format(username) - found.delete_instance(recursive=True) - - -if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) - - summary = delete_summary(sys.argv[1]).items() - - if summary: - print 'Will delete:' - for model_name, count in summary: - print '{0}: {1}'.format(model_name, count) - else: - print 'Nothing references user.' - - print 'Delete? [y/n]' - delete_yn = raw_input().lower().strip() - if delete_yn == 'y': - delete_username(sys.argv[1]) - else: - print 'Aborted!' diff --git a/util/config/schema.py b/util/config/schema.py index ab4da0932..5bf7320ab 100644 --- a/util/config/schema.py +++ b/util/config/schema.py @@ -15,6 +15,7 @@ INTERNAL_ONLY_PROPERTIES = { 'SECSCAN_NOTIFICATION_QUEUE_NAME', 'SECURITY_SCANNER_ISSUER_NAME', 'NOTIFICATION_QUEUE_NAME', + 'NAMESPACE_GC_QUEUE_NAME', 'FEATURE_BILLING', 'FEATURE_SUPPORT_CHAT', diff --git a/workers/namespacegcworker.py b/workers/namespacegcworker.py new file mode 100644 index 000000000..863f2d649 --- /dev/null +++ b/workers/namespacegcworker.py @@ -0,0 +1,28 @@ +import logging +import time + +from app import app, namespace_gc_queue, all_queues +from data import model +from workers.queueworker import QueueWorker, JobException +from util.log import logfile_path + +logger = logging.getLogger(__name__) + + +POLL_PERIOD_SECONDS = 60 + + +class NamespaceGCWorker(QueueWorker): + """ Worker which cleans up namespaces enqueued to be GCed. + """ + def process_queue_item(self, job_details): + logger.debug('Got namespace GC queue item: %s', job_details) + marker_id = job_details['marker_id'] + model.user.delete_namespace_via_marker(marker_id, all_queues) + +if __name__ == "__main__": + logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False) + + logger.debug('Starting namespace GC worker') + worker = NamespaceGCWorker(namespace_gc_queue, poll_period_seconds=POLL_PERIOD_SECONDS) + worker.start()