From f13ced72e32ca1858576843662d0853f82425b91 Mon Sep 17 00:00:00 2001 From: glic3 Date: Mon, 4 May 2015 16:19:58 +0200 Subject: [PATCH] Improvemnts on installation --- TODO.md | 2 + orchestra/bin/orchestra-admin | 6 ++- .../project_template/project_name/settings.py | 1 + orchestra/contrib/accounts/apps.py | 6 ++- .../contrib/accounts/management/__init__.py | 8 ++++ orchestra/contrib/accounts/models.py | 5 --- orchestra/contrib/domains/bin/named-checkzone | Bin 26680 -> 0 bytes orchestra/contrib/domains/validators.py | 10 ++++- orchestra/contrib/orders/__init__.py | 1 + orchestra/contrib/orders/apps.py | 15 +++++++ orchestra/contrib/orders/models.py | 41 +----------------- orchestra/contrib/orders/signals.py | 39 +++++++++++++++++ orchestra/contrib/payments/methods/options.py | 9 +++- orchestra/contrib/resources/apps.py | 7 ++- orchestra/contrib/systemusers/apps.py | 22 ++++++++++ orchestra/contrib/systemusers/models.py | 3 -- orchestra/core/validators.py | 17 +++++--- orchestra/urls.py | 4 +- requirements.txt | 3 -- 19 files changed, 137 insertions(+), 62 deletions(-) delete mode 100755 orchestra/contrib/domains/bin/named-checkzone create mode 100644 orchestra/contrib/orders/apps.py create mode 100644 orchestra/contrib/orders/signals.py diff --git a/TODO.md b/TODO.md index 9a88a19a..c1d7ad1f 100644 --- a/TODO.md +++ b/TODO.md @@ -391,4 +391,6 @@ TODO mount the filesystem with "nosuid" option # wkhtmltopdf -> reportlab +# MAKE DEPENDENCIES OPTIONAL, check on deploy and warn that functionallity will not be available + diff --git a/orchestra/bin/orchestra-admin b/orchestra/bin/orchestra-admin index 90df6bbc..35448916 100755 --- a/orchestra/bin/orchestra-admin +++ b/orchestra/bin/orchestra-admin @@ -126,13 +126,17 @@ function install_requirements () { python3-pip \ python3-dev \ libxml2-dev \ + bind9utils \ libxslt1-dev \ wkhtmltopdf \ xvfb \ ca-certificates \ gettext" - PIP=$(wget https://raw.githubusercontent.com/glic3rinu/django-orchestra/master/requirements.txt -q -O - | tr '\n' ' ') + PIP="$(wget https://raw.githubusercontent.com/glic3rinu/django-orchestra/master/requirements.txt -q -O - | tr '\n' ' ') \ + https://github.com/glic3rinu/passlib/archive/master.zip \ + cracklib \ + lxml==3.3.5" if $testing; then APT="${APT} \ diff --git a/orchestra/conf/project_template/project_name/settings.py b/orchestra/conf/project_template/project_name/settings.py index 0d239ea6..6c63c438 100644 --- a/orchestra/conf/project_template/project_name/settings.py +++ b/orchestra/conf/project_template/project_name/settings.py @@ -66,6 +66,7 @@ INSTALLED_APPS = [ 'passlib.ext.django', 'django_countries', # 'django_mailer', +# 'debug_toolbar', # Django.contrib 'django.contrib.auth', diff --git a/orchestra/contrib/accounts/apps.py b/orchestra/contrib/accounts/apps.py index 0e3980bd..e3d54378 100644 --- a/orchestra/contrib/accounts/apps.py +++ b/orchestra/contrib/accounts/apps.py @@ -2,7 +2,7 @@ from django.apps import AppConfig from django.db.models.signals import post_migrate from django.utils.translation import ugettext_lazy as _ -from .management import create_initial_superuser +from orchestra.core import services, accounts class AccountConfig(AppConfig): @@ -10,5 +10,9 @@ class AccountConfig(AppConfig): verbose_name = _("Accounts") def ready(self): + from .management import create_initial_superuser + from .models import Account + services.register(Account, menu=False) + accounts.register(Account) post_migrate.connect(create_initial_superuser, dispatch_uid="orchestra.contrib.accounts.management.createsuperuser") diff --git a/orchestra/contrib/accounts/management/__init__.py b/orchestra/contrib/accounts/management/__init__.py index 896207c2..c77b34aa 100644 --- a/orchestra/contrib/accounts/management/__init__.py +++ b/orchestra/contrib/accounts/management/__init__.py @@ -2,7 +2,9 @@ import sys import textwrap from django.contrib.auth import get_user_model +from django.core.exceptions import FieldError from django.core.management import execute_from_command_line +from django.db import models def create_initial_superuser(**kwargs): @@ -15,5 +17,11 @@ def create_initial_superuser(**kwargs): """) ) + from ..models import Account + try: + Account.systemusers.related.model.objects.filter(account_id=1).exists() + except FieldError: + # avoid creating a systemuser when systemuser table is not ready + Account.save = models.Model.save manager = sys.argv[0] execute_from_command_line(argv=[manager, 'createsuperuser']) diff --git a/orchestra/contrib/accounts/models.py b/orchestra/contrib/accounts/models.py index 3ba10b56..5033eeed 100644 --- a/orchestra/contrib/accounts/models.py +++ b/orchestra/contrib/accounts/models.py @@ -7,7 +7,6 @@ from django.utils.translation import ugettext_lazy as _ from orchestra.contrib.orchestration.middlewares import OperationsMiddleware from orchestra.contrib.orchestration import Operation -from orchestra.core import services, accounts from orchestra.utils import send_email_template from . import settings @@ -156,7 +155,3 @@ class Account(auth.AbstractBaseUser): continue related.append(rel) return related - - -services.register(Account, menu=False) -accounts.register(Account) diff --git a/orchestra/contrib/domains/bin/named-checkzone b/orchestra/contrib/domains/bin/named-checkzone deleted file mode 100755 index 3d2961c8933300d2194e02007471fdbc5a96b0d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26680 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 diff --git a/orchestra/contrib/domains/validators.py b/orchestra/contrib/domains/validators.py index 7147c9c1..0b5a67b2 100644 --- a/orchestra/contrib/domains/validators.py +++ b/orchestra/contrib/domains/validators.py @@ -1,3 +1,4 @@ +import logging import os import re @@ -11,6 +12,9 @@ from orchestra.utils.sys import run from .. import domains +logger = logging.getLogger(__name__) + + def validate_allowed_domain(value): context = { 'site_dir': paths.get_site_dir() @@ -114,9 +118,11 @@ def validate_zone(zone): with open(zone_path, 'wb') as f: f.write(zone.encode('ascii')) # Don't use /dev/stdin becuase the 'argument list is too long' error - check = run(' '.join([checkzone, zone_name, zone_path]), error_codes=[0,1], display=False) + check = run(' '.join([checkzone, zone_name, zone_path]), error_codes=[0,1,127], display=False) finally: os.unlink(zone_path) - if check.return_code == 1: + if check.return_code == 127: + logger.error("Cannot validate domain zone: %s not installed." % checkzone) + elif check.return_code == 1: errors = re.compile(r'zone.*: (.*)').findall(check.stdout)[:-1] raise ValidationError(', '.join(errors)) diff --git a/orchestra/contrib/orders/__init__.py b/orchestra/contrib/orders/__init__.py index e69de29b..753c362c 100644 --- a/orchestra/contrib/orders/__init__.py +++ b/orchestra/contrib/orders/__init__.py @@ -0,0 +1 @@ +default_app_config = 'orchestra.contrib.orders.apps.OrdersConfig' diff --git a/orchestra/contrib/orders/apps.py b/orchestra/contrib/orders/apps.py new file mode 100644 index 00000000..39934323 --- /dev/null +++ b/orchestra/contrib/orders/apps.py @@ -0,0 +1,15 @@ +from django.apps import AppConfig + +from orchestra.core import accounts +from orchestra.utils import database_ready + + +class OrdersConfig(AppConfig): + name = 'orchestra.contrib.orders' + verbose_name = 'Orders' + + def ready(self): + from .models import Order + accounts.register(Order) + if database_ready(): + from . import signals diff --git a/orchestra/contrib/orders/models.py b/orchestra/contrib/orders/models.py index 87652add..51ff7f44 100644 --- a/orchestra/contrib/orders/models.py +++ b/orchestra/contrib/orders/models.py @@ -5,18 +5,16 @@ import logging from django.db import models from django.db.models import F, Q from django.apps import apps -from django.db.models.signals import post_delete, post_save, pre_delete -from django.dispatch import receiver from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from orchestra.core import accounts, services +from orchestra.core import services from orchestra.models import queryset from orchestra.utils.python import import_class -from . import helpers, settings +from . import settings logger = logging.getLogger(__name__) @@ -273,38 +271,3 @@ class MetricStorage(models.Model): else: last.updated_on = now last.save(update_fields=['updated_on']) - - -accounts.register(Order) - - -# TODO perhas use cache = caches.get_request_cache() to cache an account delete and don't processes get_related_objects() if the case -# FIXME https://code.djangoproject.com/ticket/24576 -# TODO build a cache hash table {model: related, model: None} -@receiver(post_delete, dispatch_uid="orders.cancel_orders") -def cancel_orders(sender, **kwargs): - if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS: - instance = kwargs['instance'] - # Account delete will delete all related orders, no need to maintain order consistency - if isinstance(instance, Order.account.field.rel.to): - return - if type(instance) in services: - for order in Order.objects.by_object(instance).active(): - order.cancel() - elif not hasattr(instance, 'account'): - # FIXME Indeterminate behaviour - related = helpers.get_related_object(instance) - if related and related != instance: - type(related).objects.get(pk=related.pk) - - -@receiver(post_save, dispatch_uid="orders.update_orders") -def update_orders(sender, **kwargs): - if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS: - instance = kwargs['instance'] - if type(instance) in services: - Order.update_orders(instance) - elif not hasattr(instance, 'account'): - related = helpers.get_related_object(instance) - if related and related != instance: - Order.update_orders(related) diff --git a/orchestra/contrib/orders/signals.py b/orchestra/contrib/orders/signals.py new file mode 100644 index 00000000..58f5cc84 --- /dev/null +++ b/orchestra/contrib/orders/signals.py @@ -0,0 +1,39 @@ +from django.db.models.signals import post_delete, post_save, pre_delete +from django.dispatch import receiver + +from orchestra.core import services + +from . import helpers, settings +from .models import Order + + +# TODO perhas use cache = caches.get_request_cache() to cache an account delete and don't processes get_related_objects() if the case +# FIXME https://code.djangoproject.com/ticket/24576 +# TODO build a cache hash table {model: related, model: None} +@receiver(post_delete, dispatch_uid="orders.cancel_orders") +def cancel_orders(sender, **kwargs): + if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS: + instance = kwargs['instance'] + # Account delete will delete all related orders, no need to maintain order consistency + if isinstance(instance, Order.account.field.rel.to): + return + if type(instance) in services: + for order in Order.objects.by_object(instance).active(): + order.cancel() + elif not hasattr(instance, 'account'): + # FIXME Indeterminate behaviour + related = helpers.get_related_object(instance) + if related and related != instance: + type(related).objects.get(pk=related.pk) + + +@receiver(post_save, dispatch_uid="orders.update_orders") +def update_orders(sender, **kwargs): + if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS: + instance = kwargs['instance'] + if type(instance) in services: + Order.update_orders(instance) + elif not hasattr(instance, 'account'): + related = helpers.get_related_object(instance) + if related and related != instance: + Order.update_orders(related) diff --git a/orchestra/contrib/payments/methods/options.py b/orchestra/contrib/payments/methods/options.py index 092e96dc..fce3215c 100644 --- a/orchestra/contrib/payments/methods/options.py +++ b/orchestra/contrib/payments/methods/options.py @@ -1,3 +1,4 @@ +import logging from dateutil import relativedelta from orchestra import plugins @@ -7,6 +8,9 @@ from orchestra.utils.python import import_class from .. import settings +logger = logging.getLogger(__name__) + + class PaymentMethod(plugins.Plugin): label_field = 'label' number_field = 'number' @@ -19,7 +23,10 @@ class PaymentMethod(plugins.Plugin): def get_plugins(cls): plugins = [] for cls in settings.PAYMENTS_ENABLED_METHODS: - plugins.append(import_class(cls)) + try: + plugins.append(import_class(cls)) + except ImportError as exc: + logger.error(str(exc)) return plugins def get_label(self): diff --git a/orchestra/contrib/resources/apps.py b/orchestra/contrib/resources/apps.py index b543e9bc..aa49c144 100644 --- a/orchestra/contrib/resources/apps.py +++ b/orchestra/contrib/resources/apps.py @@ -1,3 +1,4 @@ +from django import db from django.apps import AppConfig from orchestra.utils import database_ready @@ -10,7 +11,11 @@ class ResourcesConfig(AppConfig): def ready(self): if database_ready(): from .models import create_resource_relation - create_resource_relation() + try: + create_resource_relation() + except db.utils.OperationalError: + # Not ready afterall + pass def reload_relations(self): from .admin import insert_resource_inlines diff --git a/orchestra/contrib/systemusers/apps.py b/orchestra/contrib/systemusers/apps.py index b1cca6e6..418f364e 100644 --- a/orchestra/contrib/systemusers/apps.py +++ b/orchestra/contrib/systemusers/apps.py @@ -1,6 +1,28 @@ +import sys + from django.apps import AppConfig +from django.db.models.signals import post_migrate + +from orchestra.core import services class SystemUsersConfig(AppConfig): name = 'orchestra.contrib.systemusers' verbose_name = "System users" + + def ready(self): + from .models import SystemUser + services.register(SystemUser) + if 'migrate' in sys.argv and 'accounts' not in sys.argv: + post_migrate.connect(self.create_initial_systemuser, + dispatch_uid="orchestra.contrib.systemusers.apps.create_initial_systemuser") + + def create_initial_systemuser(self, **kwargs): + from .models import SystemUser + Account = SystemUser.account.field.related.model + for account in Account.objects.filter(is_superuser=True, main_systemuser_id__isnull=True): + systemuser = SystemUser.objects.create(username=account.username, + password=account.password, account=account) + account.main_systemuser = systemuser + account.save() + sys.stdout.write("Created initial systemuser %s.\n" % systemuser.username) diff --git a/orchestra/contrib/systemusers/models.py b/orchestra/contrib/systemusers/models.py index 59a8cc96..11190f93 100644 --- a/orchestra/contrib/systemusers/models.py +++ b/orchestra/contrib/systemusers/models.py @@ -108,6 +108,3 @@ class SystemUser(models.Model): def get_home(self): return os.path.normpath(os.path.join(self.home, self.directory)) - - -services.register(SystemUser) diff --git a/orchestra/core/validators.py b/orchestra/core/validators.py index 90fb0950..ae8906ef 100644 --- a/orchestra/core/validators.py +++ b/orchestra/core/validators.py @@ -1,11 +1,7 @@ +import logging import re -try: - import crack -except: - import cracklib as crack import phonenumbers - from django.core import validators from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ @@ -14,6 +10,9 @@ from IPy import IP from ..utils.python import import_class +logger = logging.getLogger(__name__) + + def all_valid(*args): """ helper function to merge multiple validators at once """ if len(args) == 1: @@ -103,6 +102,14 @@ def validate_username(value): def validate_password(value): + try: + import crack + except: + try: + import cracklib as crack + except: + logger.error("Can not validate password. Cracklib bindings are not installed.") + return try: crack.VeryFascistCheck(value) except ValueError as message: diff --git a/orchestra/urls.py b/orchestra/urls.py index 74cc45ae..f0053a51 100644 --- a/orchestra/urls.py +++ b/orchestra/urls.py @@ -3,11 +3,13 @@ from django.conf import settings from django.conf.urls import patterns, include, url from . import api +from .utils.apps import isinstalled admin.autodiscover() api.autodiscover() + urlpatterns = patterns('', # Admin url(r'^admin/', include(admin.site.urls)), @@ -27,7 +29,7 @@ urlpatterns = patterns('', ) -if settings.DEBUG: +if isinstalled('debug_toolbar'): import debug_toolbar urlpatterns += patterns('', url(r'^__debug__/', include(debug_toolbar.urls)), diff --git a/requirements.txt b/requirements.txt index 610e5292..9981a207 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -cracklib django==1.8.1 django-celery-email==1.0.4 django-fluent-dashboard==0.5 @@ -16,9 +15,7 @@ paramiko==1.15.1 ecdsa==0.11 Pygments==1.6 django-filter==0.7 -https://github.com/glic3rinu/passlib/archive/master.zip jsonfield==0.9.22 -lxml==3.3.5 python-dateutil==2.2 django-iban==0.3.0 requests