Random fixes

This commit is contained in:
Marc Aymerich 2015-05-13 13:52:20 +00:00
parent 17739129d3
commit cc4ecee4dd
10 changed files with 70 additions and 42 deletions

View file

@ -38,8 +38,6 @@ Django-orchestra can be installed on any Linux system, however it is **strongly
```bash ```bash
sudo apt-get install python3-psycopg2 postgresql sudo apt-get install python3-psycopg2 postgresql
sudo python3 manage.py setuppostgres --db_password <password> sudo python3 manage.py setuppostgres --db_password <password>
# admin_tools needs accounts and does not have migrations
python3 manage.py migrate accounts
python3 manage.py migrate python3 manage.py migrate
``` ```

View file

@ -49,7 +49,6 @@ pip3 install -r \
# Create a new Orchestra site # Create a new Orchestra site
orchestra-admin startproject panel orchestra-admin startproject panel
python3 panel/manage.py migrate accounts
python3 panel/manage.py migrate python3 panel/manage.py migrate
python3 panel/manage.py runserver python3 panel/manage.py runserver

View file

@ -57,7 +57,7 @@
* print open invoices as proforma? * print open invoices as proforma?
* env ORCHESTRA_MASTER_SERVER='test1.orchestra.lan' ORCHESTRA_SECOND_SERVER='test2.orchestra.lan' ORCHESTRA_SLAVE_SERVER='test3.orchestra.lan' python manage.py test orchestra.apps.domains.tests.functional_tests.tests:AdminBind9BackendDomainTest --nologcapture * env ORCHESTRA_MASTER_SERVER='test1.orchestra.lan' ORCHESTRA_SECOND_SERVER='test2.orchestra.lan' ORCHESTRA_SLAVE_SERVER='test3.orchestra.lan' python3 manage.py test orchestra.contrib.domains.tests.functional_tests.tests:AdminBind9BackendDomainTest --nologcapture
* ForeignKey.swappable * ForeignKey.swappable
* Field.editable * Field.editable
@ -360,3 +360,5 @@ resorce monitoring more efficient, less mem an better queries for calc current d
# Tests can not run because django.db.utils.ProgrammingError: relation "accounts_account" does not exist # Tests can not run because django.db.utils.ProgrammingError: relation "accounts_account" does not exist
# autoresponses on mailboxes, not addresses or remove them # autoresponses on mailboxes, not addresses or remove them
# Async particular actions?

View file

@ -5,10 +5,12 @@ from django.contrib.contenttypes.models import ContentType
from django.utils import timezone from django.utils import timezone
from orchestra.contrib.systemusers.models import SystemUser from orchestra.contrib.systemusers.models import SystemUser
from orchestra.contrib.plans.models import Plan
from orchestra.utils.python import cmp_to_key
from orchestra.utils.tests import BaseTestCase from orchestra.utils.tests import BaseTestCase
from .. import helpers from .. import helpers
from ..models import Service, Plan from ..models import Service
class Order(object): class Order(object):
@ -40,7 +42,7 @@ class HandlerTests(BaseTestCase):
is_fee=False, is_fee=False,
metric='', metric='',
pricing_period=Service.NEVER, pricing_period=Service.NEVER,
rate_algorithm='STEP_PRICE', rate_algorithm='orchestra.contrib.plans.ratings.step_price',
on_cancel=Service.DISCOUNT, on_cancel=Service.DISCOUNT,
payment_style=Service.PREPAY, payment_style=Service.PREPAY,
tax=0, tax=0,
@ -144,7 +146,7 @@ class HandlerTests(BaseTestCase):
order6 = Order( order6 = Order(
registered_on=now+datetime.timedelta(days=8)) registered_on=now+datetime.timedelta(days=8))
orders = [order3, order, order1, order2, order4, order5, order6] orders = [order3, order, order1, order2, order4, order5, order6]
self.assertEqual(orders, sorted(orders, cmp=helpers.cmp_billed_until_or_registered_on)) self.assertEqual(orders, sorted(orders, key=cmp_to_key(helpers.cmp_billed_until_or_registered_on)))
def test_compensation(self): def test_compensation(self):
now = timezone.now().date() now = timezone.now().date()
@ -192,7 +194,7 @@ class HandlerTests(BaseTestCase):
[now+datetime.timedelta(days=100), now+datetime.timedelta(days=102), order], [now+datetime.timedelta(days=100), now+datetime.timedelta(days=102), order],
]) ])
porders = [order3, order, order1, order2, order4, order5, order6] porders = [order3, order, order1, order2, order4, order5, order6]
porders = sorted(porders, cmp=helpers.cmp_billed_until_or_registered_on) porders = sorted(porders, key=cmp_to_key(helpers.cmp_billed_until_or_registered_on))
compensations = [] compensations = []
receivers = [] receivers = []
for order in porders: for order in porders:
@ -223,10 +225,19 @@ class HandlerTests(BaseTestCase):
results = service.get_rates(account, cache=False) results = service.get_rates(account, cache=False)
results = service.rate_method(results, 30) results = service.rate_method(results, 30)
rates = [ rates = [
{'price': decimal.Decimal('0.00'), 'quantity': 2}, {
{'price': decimal.Decimal('10.00'), 'quantity': 1}, 'price': decimal.Decimal('0.00'),
{'price': decimal.Decimal('9.00'), 'quantity': 6}, 'quantity': 2
{'price': decimal.Decimal('1.00'), 'quantity': 21} }, {
'price': decimal.Decimal('10.00'),
'quantity': 1
}, {
'price': decimal.Decimal('9.00'),
'quantity': 6
}, {
'price': decimal.Decimal('1.00'),
'quantity': 21
}
] ]
for rate, result in zip(rates, results): for rate, result in zip(rates, results):
self.assertEqual(rate['price'], result.price) self.assertEqual(rate['price'], result.price)
@ -280,7 +291,7 @@ class HandlerTests(BaseTestCase):
self.assertEqual(rate['price'], result.price) self.assertEqual(rate['price'], result.price)
self.assertEqual(rate['quantity'], result.quantity) self.assertEqual(rate['quantity'], result.quantity)
service.rate_algorithm = service.MATCH_PRICE service.rate_algorithm = 'orchestra.contrib.plans.ratings.match_price'
service.save() service.save()
results = service.get_rates(account, cache=False) results = service.get_rates(account, cache=False)
results = service.rate_method(results, 30) results = service.rate_method(results, 30)
@ -313,9 +324,16 @@ class HandlerTests(BaseTestCase):
results = service.get_rates(account, cache=False) results = service.get_rates(account, cache=False)
results = service.rate_method(results, 30) results = service.rate_method(results, 30)
rates = [ rates = [
{'price': decimal.Decimal('10.00'), 'quantity': 3}, {
{'price': decimal.Decimal('9.00'), 'quantity': 6}, 'price': decimal.Decimal('10.00'),
{'price': decimal.Decimal('1.00'), 'quantity': 21} 'quantity': 3
}, {
'price': decimal.Decimal('9.00'),
'quantity': 6
}, {
'price': decimal.Decimal('1.00'),
'quantity': 21
}
] ]
for rate, result in zip(rates, results): for rate, result in zip(rates, results):
self.assertEqual(rate['price'], result.price) self.assertEqual(rate['price'], result.price)

View file

@ -32,10 +32,17 @@ class UNIXUserBackend(ServiceController):
# TODO userd add will fail if %(user)s group already exists # TODO userd add will fail if %(user)s group already exists
self.append(textwrap.dedent(""" self.append(textwrap.dedent("""
if [[ $( id %(user)s ) ]]; then if [[ $( id %(user)s ) ]]; then
usermod %(user)s --password '%(password)s' --shell %(shell)s %(groups_arg)s usermod %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s
else else
useradd %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s || {
# User is logged in, kill and retry
if [[ $? -eq 8 ]]; then
pkill -u %(user)s; sleep 2
pkill -9 -u %(user)s; sleep 1
useradd %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s useradd %(user)s --home %(home)s --password '%(password)s' --shell %(shell)s %(groups_arg)s
fi fi
}
fi
mkdir -p %(base_home)s mkdir -p %(base_home)s
chmod 750 %(base_home)s chmod 750 %(base_home)s
chown %(user)s:%(user)s %(base_home)s""") % context chown %(user)s:%(user)s %(base_home)s""") % context
@ -43,7 +50,9 @@ class UNIXUserBackend(ServiceController):
if context['home'] != context['base_home']: if context['home'] != context['base_home']:
self.append(textwrap.dedent(""" self.append(textwrap.dedent("""
if [[ $(mount | grep "^$(df %(home)s|grep '^/')\s" | grep acl) ]]; then if [[ $(mount | grep "^$(df %(home)s|grep '^/')\s" | grep acl) ]]; then
# Accountn group as the owner
chown %(mainuser)s:%(mainuser)s %(home)s chown %(mainuser)s:%(mainuser)s %(home)s
chmod g+s %(home)s
# Home access # Home access
setfacl -m u:%(user)s:--x '%(mainuser_home)s' setfacl -m u:%(user)s:--x '%(mainuser_home)s'
# Grant perms to future files within the directory # Grant perms to future files within the directory

View file

@ -33,16 +33,15 @@ class SystemUserFormMixin(object):
self.fields['home'].widget = forms.Select(choices=choices) self.fields['home'].widget = forms.Select(choices=choices)
if self.instance.pk and (self.instance.is_main or self.instance.has_shell): if self.instance.pk and (self.instance.is_main or self.instance.has_shell):
# hidde home option for shell users # hidde home option for shell users
self.fields['home'].widget = forms.HiddenInput() self.fields['home'].widget.input_type = 'hidden'
self.fields['directory'].widget = forms.HiddenInput() self.fields['directory'].widget.input_type = 'hidden'
elif self.instance.pk and (self.instance.get_base_home() == self.instance.home): elif self.instance.pk and (self.instance.get_base_home() == self.instance.home):
self.fields['directory'].widget = forms.HiddenInput() self.fields['directory'].widget = forms.HiddenInput()
else: else:
self.fields['directory'].widget = forms.TextInput(attrs={'size':'70'}) self.fields['directory'].widget = forms.TextInput(attrs={'size':'70'})
if not self.instance.pk or not self.instance.is_main: if not self.instance.pk or not self.instance.is_main:
# Some javascript for hidde home/directory inputs when convinient # Some javascript for hidde home/directory inputs when convinient
self.fields['shell'].widget.attrs = { self.fields['shell'].widget.attrs['onChange'] = textwrap.dedent("""\
'onChange': textwrap.dedent("""\
field = $(".field-home, .field-directory"); field = $(".field-home, .field-directory");
input = $("#id_home, #id_directory"); input = $("#id_home, #id_directory");
if ($.inArray(this.value, %s) < 0) { if ($.inArray(this.value, %s) < 0) {
@ -50,10 +49,9 @@ class SystemUserFormMixin(object):
} else { } else {
field.removeClass("hidden"); field.removeClass("hidden");
input.removeAttr("type"); input.removeAttr("type");
};""" % str(list(settings.SYSTEMUSERS_DISABLED_SHELLS))) };""" % str(list(settings.SYSTEMUSERS_DISABLED_SHELLS))
} )
self.fields['home'].widget.attrs = { self.fields['home'].widget.attrs['onChange'] = textwrap.dedent("""\
'onChange': textwrap.dedent("""\
field = $(".field-box.field-directory"); field = $(".field-box.field-directory");
input = $("#id_directory"); input = $("#id_directory");
if (this.value.search("%s") > 0) { if (this.value.search("%s") > 0) {
@ -61,16 +59,20 @@ class SystemUserFormMixin(object):
} else { } else {
field.removeClass("hidden"); field.removeClass("hidden");
input.removeAttr("type"); input.removeAttr("type");
};""" % username) };""" % username
} )
def clean(self): def clean(self):
super(SystemUserFormMixin, self).clean() super(SystemUserFormMixin, self).clean()
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
home = cleaned_data.get('home') home = cleaned_data.get('home')
shell = cleaned_data.get('shell')
if home and self.MOCK_USERNAME in home: if home and self.MOCK_USERNAME in home:
username = cleaned_data.get('username', '') username = cleaned_data.get('username', '')
cleaned_data['home'] = home.replace(self.MOCK_USERNAME, username) cleaned_data['home'] = home.replace(self.MOCK_USERNAME, username)
elif home and shell not in settings.SYSTEMUSERS_DISABLED_SHELLS:
cleaned_data['home'] = ''
cleaned_data['directory'] = ''
validate_home(self.instance, cleaned_data, self.account) validate_home(self.instance, cleaned_data, self.account)
return cleaned_data return cleaned_data

View file

@ -1,6 +1,7 @@
import os import os
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from orchestra.contrib.orchestration import Operation from orchestra.contrib.orchestration import Operation

View file

@ -7,7 +7,6 @@ from django.contrib.auth import BACKEND_SESSION_KEY, SESSION_KEY
from django.contrib.sessions.backends.db import SessionStore from django.contrib.sessions.backends.db import SessionStore
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import LiveServerTestCase, TestCase from django.test import LiveServerTestCase, TestCase
from orm.api import Api
from selenium.webdriver.firefox.webdriver import WebDriver from selenium.webdriver.firefox.webdriver import WebDriver
from xvfbwrapper import Xvfb from xvfbwrapper import Xvfb
@ -88,6 +87,7 @@ class BaseLiveServerTestCase(AppDependencyMixin, LiveServerTestCase):
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org') return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
def setUp(self): def setUp(self):
from orm.api import Api
super(BaseLiveServerTestCase, self).setUp() super(BaseLiveServerTestCase, self).setUp()
self.rest = Api(self.live_server_url + '/api/') self.rest = Api(self.live_server_url + '/api/')
self.rest.enable_logging() self.rest.enable_logging()

View file

@ -1,7 +1,7 @@
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
https://bitbucket.org/izi/django-admin-tools/get/a0abfffd76a0.zip https://github.com/glic3rinu/django-admin-tools/archive/master.zip
IPy==0.81 IPy==0.81
django-extensions==1.5.2 django-extensions==1.5.2
django-transaction-signals==1.0.0 django-transaction-signals==1.0.0

View file

@ -94,7 +94,6 @@ chown $USER:$USER /home/orchestra/panel/orchestra.log
# admin_tools needs accounts and does not have migrations # admin_tools needs accounts and does not have migrations
if [[ ! $(sudo su postgres -c "psql orchestra -q -c 'SELECT * FROM accounts_account LIMIT 1;' 2> /dev/null") ]]; then if [[ ! $(sudo su postgres -c "psql orchestra -q -c 'SELECT * FROM accounts_account LIMIT 1;' 2> /dev/null") ]]; then
surun "$PYTHON_BIN $MANAGE migrate --noinput accounts"
surun "$PYTHON_BIN $MANAGE migrate --noinput" surun "$PYTHON_BIN $MANAGE migrate --noinput"
else else
surun "$PYTHON_BIN $MANAGE postupgradeorchestra --from $CURRENT_VERSION" surun "$PYTHON_BIN $MANAGE postupgradeorchestra --from $CURRENT_VERSION"