Improvemnts on installation

This commit is contained in:
glic3 2015-05-04 16:19:58 +02:00
parent 3207f7de8b
commit f13ced72e3
19 changed files with 137 additions and 62 deletions

View File

@ -391,4 +391,6 @@ TODO mount the filesystem with "nosuid" option
# wkhtmltopdf -> reportlab # wkhtmltopdf -> reportlab
# MAKE DEPENDENCIES OPTIONAL, check on deploy and warn that functionallity will not be available

View File

@ -126,13 +126,17 @@ function install_requirements () {
python3-pip \ python3-pip \
python3-dev \ python3-dev \
libxml2-dev \ libxml2-dev \
bind9utils \
libxslt1-dev \ libxslt1-dev \
wkhtmltopdf \ wkhtmltopdf \
xvfb \ xvfb \
ca-certificates \ ca-certificates \
gettext" 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 if $testing; then
APT="${APT} \ APT="${APT} \

View File

@ -66,6 +66,7 @@ INSTALLED_APPS = [
'passlib.ext.django', 'passlib.ext.django',
'django_countries', 'django_countries',
# 'django_mailer', # 'django_mailer',
# 'debug_toolbar',
# Django.contrib # Django.contrib
'django.contrib.auth', 'django.contrib.auth',

View File

@ -2,7 +2,7 @@ from django.apps import AppConfig
from django.db.models.signals import post_migrate from django.db.models.signals import post_migrate
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from .management import create_initial_superuser from orchestra.core import services, accounts
class AccountConfig(AppConfig): class AccountConfig(AppConfig):
@ -10,5 +10,9 @@ class AccountConfig(AppConfig):
verbose_name = _("Accounts") verbose_name = _("Accounts")
def ready(self): 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, post_migrate.connect(create_initial_superuser,
dispatch_uid="orchestra.contrib.accounts.management.createsuperuser") dispatch_uid="orchestra.contrib.accounts.management.createsuperuser")

View File

@ -2,7 +2,9 @@ import sys
import textwrap import textwrap
from django.contrib.auth import get_user_model 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.core.management import execute_from_command_line
from django.db import models
def create_initial_superuser(**kwargs): 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] manager = sys.argv[0]
execute_from_command_line(argv=[manager, 'createsuperuser']) execute_from_command_line(argv=[manager, 'createsuperuser'])

View File

@ -7,7 +7,6 @@ from django.utils.translation import ugettext_lazy as _
from orchestra.contrib.orchestration.middlewares import OperationsMiddleware from orchestra.contrib.orchestration.middlewares import OperationsMiddleware
from orchestra.contrib.orchestration import Operation from orchestra.contrib.orchestration import Operation
from orchestra.core import services, accounts
from orchestra.utils import send_email_template from orchestra.utils import send_email_template
from . import settings from . import settings
@ -156,7 +155,3 @@ class Account(auth.AbstractBaseUser):
continue continue
related.append(rel) related.append(rel)
return related return related
services.register(Account, menu=False)
accounts.register(Account)

View File

@ -1,3 +1,4 @@
import logging
import os import os
import re import re
@ -11,6 +12,9 @@ from orchestra.utils.sys import run
from .. import domains from .. import domains
logger = logging.getLogger(__name__)
def validate_allowed_domain(value): def validate_allowed_domain(value):
context = { context = {
'site_dir': paths.get_site_dir() 'site_dir': paths.get_site_dir()
@ -114,9 +118,11 @@ def validate_zone(zone):
with open(zone_path, 'wb') as f: with open(zone_path, 'wb') as f:
f.write(zone.encode('ascii')) f.write(zone.encode('ascii'))
# Don't use /dev/stdin becuase the 'argument list is too long' error # 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: finally:
os.unlink(zone_path) 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] errors = re.compile(r'zone.*: (.*)').findall(check.stdout)[:-1]
raise ValidationError(', '.join(errors)) raise ValidationError(', '.join(errors))

View File

@ -0,0 +1 @@
default_app_config = 'orchestra.contrib.orders.apps.OrdersConfig'

View File

@ -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

View File

@ -5,18 +5,16 @@ import logging
from django.db import models from django.db import models
from django.db.models import F, Q from django.db.models import F, Q
from django.apps import apps 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.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ 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.models import queryset
from orchestra.utils.python import import_class from orchestra.utils.python import import_class
from . import helpers, settings from . import settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -273,38 +271,3 @@ class MetricStorage(models.Model):
else: else:
last.updated_on = now last.updated_on = now
last.save(update_fields=['updated_on']) 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)

View File

@ -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)

View File

@ -1,3 +1,4 @@
import logging
from dateutil import relativedelta from dateutil import relativedelta
from orchestra import plugins from orchestra import plugins
@ -7,6 +8,9 @@ from orchestra.utils.python import import_class
from .. import settings from .. import settings
logger = logging.getLogger(__name__)
class PaymentMethod(plugins.Plugin): class PaymentMethod(plugins.Plugin):
label_field = 'label' label_field = 'label'
number_field = 'number' number_field = 'number'
@ -19,7 +23,10 @@ class PaymentMethod(plugins.Plugin):
def get_plugins(cls): def get_plugins(cls):
plugins = [] plugins = []
for cls in settings.PAYMENTS_ENABLED_METHODS: 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 return plugins
def get_label(self): def get_label(self):

View File

@ -1,3 +1,4 @@
from django import db
from django.apps import AppConfig from django.apps import AppConfig
from orchestra.utils import database_ready from orchestra.utils import database_ready
@ -10,7 +11,11 @@ class ResourcesConfig(AppConfig):
def ready(self): def ready(self):
if database_ready(): if database_ready():
from .models import create_resource_relation 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): def reload_relations(self):
from .admin import insert_resource_inlines from .admin import insert_resource_inlines

View File

@ -1,6 +1,28 @@
import sys
from django.apps import AppConfig from django.apps import AppConfig
from django.db.models.signals import post_migrate
from orchestra.core import services
class SystemUsersConfig(AppConfig): class SystemUsersConfig(AppConfig):
name = 'orchestra.contrib.systemusers' name = 'orchestra.contrib.systemusers'
verbose_name = "System users" 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)

View File

@ -108,6 +108,3 @@ class SystemUser(models.Model):
def get_home(self): def get_home(self):
return os.path.normpath(os.path.join(self.home, self.directory)) return os.path.normpath(os.path.join(self.home, self.directory))
services.register(SystemUser)

View File

@ -1,11 +1,7 @@
import logging
import re import re
try:
import crack
except:
import cracklib as crack
import phonenumbers import phonenumbers
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -14,6 +10,9 @@ from IPy import IP
from ..utils.python import import_class from ..utils.python import import_class
logger = logging.getLogger(__name__)
def all_valid(*args): def all_valid(*args):
""" helper function to merge multiple validators at once """ """ helper function to merge multiple validators at once """
if len(args) == 1: if len(args) == 1:
@ -103,6 +102,14 @@ def validate_username(value):
def validate_password(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: try:
crack.VeryFascistCheck(value) crack.VeryFascistCheck(value)
except ValueError as message: except ValueError as message:

View File

@ -3,11 +3,13 @@ from django.conf import settings
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from . import api from . import api
from .utils.apps import isinstalled
admin.autodiscover() admin.autodiscover()
api.autodiscover() api.autodiscover()
urlpatterns = patterns('', urlpatterns = patterns('',
# Admin # Admin
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
@ -27,7 +29,7 @@ urlpatterns = patterns('',
) )
if settings.DEBUG: if isinstalled('debug_toolbar'):
import debug_toolbar import debug_toolbar
urlpatterns += patterns('', urlpatterns += patterns('',
url(r'^__debug__/', include(debug_toolbar.urls)), url(r'^__debug__/', include(debug_toolbar.urls)),

View File

@ -1,4 +1,3 @@
cracklib
django==1.8.1 django==1.8.1
django-celery-email==1.0.4 django-celery-email==1.0.4
django-fluent-dashboard==0.5 django-fluent-dashboard==0.5
@ -16,9 +15,7 @@ paramiko==1.15.1
ecdsa==0.11 ecdsa==0.11
Pygments==1.6 Pygments==1.6
django-filter==0.7 django-filter==0.7
https://github.com/glic3rinu/passlib/archive/master.zip
jsonfield==0.9.22 jsonfield==0.9.22
lxml==3.3.5
python-dateutil==2.2 python-dateutil==2.2
django-iban==0.3.0 django-iban==0.3.0
requests requests