def collect_static() -> bool: from django.core.management import execute_from_command_line # from django.conf import settings # if not os.listdir(settings.STATIC_ROOT): wf('Collecting static files... ', False) execute_from_command_line( ['./manage.py', 'collectstatic', '-c', '--noinput', '-v0']) wf('[+]\n') return True
def modeltranslation_sync_translation_fields(): # if modeltranslation present ensure it's migrations applied too if 'modeltranslation' in settings.INSTALLED_APPS: wf('Applying translations for models... ', False) execute_from_command_line( ['./manage.py', 'sync_translation_fields', '--noinput']) wf('[+]\n') return True
def migrate(*argv) -> bool: """ Runs Django migrate command. :return: always ``True`` """ wf('Applying migrations... ', False) execute_from_command_line(['./manage.py', 'migrate'] + list(argv)) wf('[+]\n') return True
def ensure_databases_alive(max_retries: int = 100, retry_timeout: int = 5, exit_on_failure: bool = True) -> bool: """ Checks every database alias in ``settings.DATABASES`` until it becomes available. After ``max_retries`` attempts to reach any backend are failed it returns ``False``. If ``exit_on_failure`` is set it shuts down with ``exit(1)``. For every database alias it tries to ``SELECT 1``. If no errors raised it checks the next alias. :param exit_on_failure: set to ``True`` if there's no sense to continue :param int max_retries: number of attempts to reach every database; default is ``100`` :param int retry_timeout: timeout in seconds between attempts :return: ``True`` if all backends are available, ``False`` if any backend check failed """ template = """ ============================= Checking database connection `{CONNECTION}`: Engine: {ENGINE} Host: {HOST} Database: {NAME} User: {USER} Password: {PASSWORD} =============================\n""" for connection_name in connections: _db_settings = dict.fromkeys( ['ENGINE', 'HOST', 'NAME', 'USER', 'PASSWORD']) _db_settings.update(settings.DATABASES[connection_name]) _db_settings['CONNECTION'] = connection_name if _db_settings.get('PASSWORD'): _db_settings['PASSWORD'] = '******' wf(template.format(**_db_settings)) wf('Checking db connection alive... ', False) for i in range(max_retries): try: cursor = connections[connection_name].cursor() cursor.execute('SELECT 1') cursor.fetchone() wf('[+]\n') break except OperationalError as e: wf(str(e)) sleep(retry_timeout) else: wf('Tried %s time(s). Shutting down.\n' % max_retries) exit_on_failure and exit(1) return False return True
def print_config_read_queue(self, use_color: bool = False, max_col_width: int = 50): """ Prints all read (in call order) options. :param max_col_width: limit column width, ``50`` by default :param use_color: use terminal colors :return: nothing """ wf( self.format_config_read_queue(use_color=use_color, max_col_width=max_col_width)) wf('\n')
def create_admin(user_config_path: str = 'CONFIG.superuser') -> bool: from django.conf import settings wf('Creating superuser... ', False) username, email, password = [ dot_path(settings, '{0}.{1}'.format(user_config_path, 'username')), dot_path(settings, '{0}.{1}'.format(user_config_path, 'email')), dot_path(settings, '{0}.{1}'.format(user_config_path, 'password')), ] if not all([username, email]): wf('[SKIP: username and email should not be empty]\n') return False from django.db import IntegrityError try: execute_from_command_line([ './manage.py', 'createsuperuser', '--username', username, '--email', email, '--noinput' ]) except IntegrityError: pass if password: # after `execute_from_command_line` models are loaded from django.contrib.auth.models import User user = User.objects.get(username=username) # do not change password if it was set before if not user.has_usable_password(): user.set_password(password) user.save() else: wf('[SKIP update password: password is empty]\n') wf('[+]\n') return True
def create_admin(user_config_path: str = 'CONFIG.superuser') -> bool: """ Creates a superuser from a specified dict/object bundle located at ``user_config_path``. Skips if the specified object contains no email or no username. If a user with the specified username already exists and has no usable password it updates user's password with a specified one. ``user_config_path`` can accept any path to a deep nested object, like dict of dicts, object of dicts of objects, and so on. Let's assume you have this weird config in your ``settings.py``: :: class MyConfigObject: my_var = { 'user': { 'username': '******', 'password': '******', 'email': '*****@*****.**', } } local_config = MyConfigObject() To access the ``'user'`` bundle you have to specify: ``local_config.my_var.user``. :param user_config_path: dot-separated path to object or dict, default is ``'CONFIG.superuser'`` :return: ``True`` if user has been created, ``False`` otherwise """ from django.conf import settings wf('Creating superuser... ', False) username, email, password = [ dot_path(settings, '{0}.{1}'.format(user_config_path, 'username')), dot_path(settings, '{0}.{1}'.format(user_config_path, 'email')), dot_path(settings, '{0}.{1}'.format(user_config_path, 'password')), ] if not all([username, email]): wf('[SKIP: username and email should not be empty]\n') return False from django.db import IntegrityError try: execute_from_command_line([ './manage.py', 'createsuperuser', '--username', username, '--email', email, '--noinput' ]) except IntegrityError: pass if password: # after `execute_from_command_line` models are loaded from django.contrib.auth.models import User user = User.objects.get(username=username) # do not change password if it was set before if not user.has_usable_password(): user.set_password(password) user.save() else: wf('[SKIP update password: password is empty]\n') wf('[+]\n') return True
def modeltranslation_sync_translation_fields() -> bool: """ Runs ``modeltranslation``'s ``sync_translation_fields`` manage.py command: ``execute_from_command_line(['./manage.py', 'sync_translation_fields', '--noinput'])`` :return: ``None`` if modeltranslation is not specified is ``INSTALLED_APPS``, ``True`` if all synced. """ # if modeltranslation present ensure it's migrations applied too if 'modeltranslation' in settings.INSTALLED_APPS: wf('Applying translations for models... ', False) execute_from_command_line( ['./manage.py', 'sync_translation_fields', '--noinput']) wf('[+]\n') return True
def ensure_caches_alive(max_retries: int = 100) -> bool: for cache_alias in settings.CACHES.keys(): cache = caches[cache_alias] wf('Checking redis connection alive for cache `%s`... ' % cache_alias, False) for i in range(max_retries): try: cache.set('loaded', 1) wf('[+]\n') return True except Exception as e: wf(str(e) + '\n') sleep(5) else: wf('Tried %s time(s). Shutting down.\n' % max_retries) exit()
def ensure_databases_alive(max_retries: int = 100, retry_timeout: int = 5) -> bool: template = """ ============================= Checking database connection `{CONNECTION}`: Engine: {ENGINE} Host: {HOST} Database: {NAME} User: {USER} Password: {PASSWORD} =============================\n""" for connection_name in connections: _db_settings = dict.fromkeys( ['ENGINE', 'HOST', 'NAME', 'USER', 'PASSWORD']) _db_settings.update(settings.DATABASES[connection_name]) _db_settings['CONNECTION'] = connection_name if _db_settings.get('PASSWORD'): _db_settings['PASSWORD'] = '******' wf(template.format(**_db_settings)) wf('Checking db connection alive... ', False) for i in range(max_retries): try: cursor = connections[connection_name].cursor() cursor.execute('SELECT 1') cursor.fetchone() wf('[+]\n') return True except OperationalError as e: wf(str(e)) sleep(retry_timeout) else: wf('Tried %s time(s). Shutting down.\n' % max_retries) exit()
def ensure_caches_alive(max_retries: int = 100, retry_timeout: int = 5, exit_on_failure: bool = True) -> bool: """ Checks every cache backend alias in ``settings.CACHES`` until it becomes available. After ``max_retries`` attempts to reach any backend are failed it returns ``False``. If ``exit_on_failure`` is set it shuts down with ``exit(1)``. It sets the ``django-docker-helpers:available-check`` key for every cache backend to ensure it's receiving connections. If check is passed the key is deleted. :param exit_on_failure: set to ``True`` if there's no sense to continue :param int max_retries: a number of attempts to reach cache backend, default is ``100`` :param int retry_timeout: a timeout in seconds between attempts, default is ``5`` :return: ``True`` if all backends are available ``False`` if any backend check failed """ for cache_alias in settings.CACHES.keys(): cache = caches[cache_alias] wf( 'Checking if the cache backed is accessible for the alias `%s`... ' % cache_alias, False) for i in range(max_retries): try: cache.set('django-docker-helpers:available-check', '1') assert cache.get( 'django-docker-helpers:available-check') == '1' cache.delete('django-docker-helpers:available-check') wf('[+]\n') break except Exception as e: wf(str(e) + '\n') sleep(retry_timeout) else: wf('Tried %s time(s). Shutting down.\n' % max_retries) exit_on_failure and exit(1) return False return True
def migrate() -> bool: wf('Applying migrations... ', False) execute_from_command_line(['./manage.py', 'migrate']) wf('[+]\n') return True
def print_config_read_queue(self, color=False): wf('\n'.join(self.format_config_read_queue(color=color))) wf('\n')