More fixes for python 3 compat
This commit is contained in:
parent
b3946168f3
commit
4a8a77715c
12
TODO.md
12
TODO.md
|
@ -238,7 +238,7 @@ require_once(‘/etc/moodles/’.$moodle_host.‘config.php’);``` moodle/drupl
|
||||||
|
|
||||||
* billline quantity eval('10x100') instead of miningless description '(10*100)'
|
* billline quantity eval('10x100') instead of miningless description '(10*100)'
|
||||||
|
|
||||||
* IMPORTANT do more test, make sure billed until doesn't get uodated whhen services are billed with les metric, and don't upgrade billed_until when undoing under this circumstances
|
# FIXME do more test, make sure billed until doesn't get uodated whhen services are billed with les metric, and don't upgrade billed_until when undoing under this circumstances
|
||||||
* line 513: change threshold and one time service metric change should update last value if not billed, only record for recurring invoicing. postpay services should store the last metric for pricing period.
|
* line 513: change threshold and one time service metric change should update last value if not billed, only record for recurring invoicing. postpay services should store the last metric for pricing period.
|
||||||
* add ini, end dates on bill lines and breakup quanity into size(defaut:1) and metric
|
* add ini, end dates on bill lines and breakup quanity into size(defaut:1) and metric
|
||||||
* threshold for significative metric accountancy on services.handler
|
* threshold for significative metric accountancy on services.handler
|
||||||
|
@ -313,6 +313,16 @@ celery max-tasks-per-child
|
||||||
* webapp has_website list filter
|
* webapp has_website list filter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME account deletion generates a integrity error
|
||||||
|
|
||||||
|
|
||||||
apt-get install python3 python3-pip
|
apt-get install python3 python3-pip
|
||||||
cp /usr/local/lib/python2.7/dist-packages/orchestra.pth /usr/local/lib/python3.4/dist-packages/
|
cp /usr/local/lib/python2.7/dist-packages/orchestra.pth /usr/local/lib/python3.4/dist-packages/
|
||||||
glic3rinu's django-fluent-dashboard
|
glic3rinu's django-fluent-dashboard
|
||||||
|
* gevent is not ported to python3 :'(
|
||||||
|
* uwsgi python3
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME what to do when deleting accounts? set fk null and fill a username charfield? issues, invoices.. we whant all this to go away?
|
||||||
|
* implement delete All related services
|
||||||
|
|
|
@ -273,7 +273,7 @@ class BillLine(models.Model):
|
||||||
rate = models.DecimalField(_("rate"), blank=True, null=True, max_digits=12, decimal_places=2)
|
rate = models.DecimalField(_("rate"), blank=True, null=True, max_digits=12, decimal_places=2)
|
||||||
quantity = models.DecimalField(_("quantity"), max_digits=12, decimal_places=2)
|
quantity = models.DecimalField(_("quantity"), max_digits=12, decimal_places=2)
|
||||||
subtotal = models.DecimalField(_("subtotal"), max_digits=12, decimal_places=2)
|
subtotal = models.DecimalField(_("subtotal"), max_digits=12, decimal_places=2)
|
||||||
tax = models.PositiveIntegerField(_("tax"))
|
tax = models.DecimalField(_("tax"), max_digits=2, decimal_places=2)
|
||||||
# Undo
|
# Undo
|
||||||
# initial = models.DateTimeField(null=True)
|
# initial = models.DateTimeField(null=True)
|
||||||
# end = models.DateTimeField(null=True)
|
# end = models.DateTimeField(null=True)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import copy
|
import copy
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import parse_qs
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
|
@ -86,22 +86,25 @@ def SSH(backend, log, server, cmds, async=False):
|
||||||
# Log results
|
# Log results
|
||||||
logger.debug('%s running on %s' % (backend, server))
|
logger.debug('%s running on %s' % (backend, server))
|
||||||
if async:
|
if async:
|
||||||
|
second = False
|
||||||
while True:
|
while True:
|
||||||
# Non-blocking is the secret ingridient in the async sauce
|
# Non-blocking is the secret ingridient in the async sauce
|
||||||
select.select([channel], [], [])
|
select.select([channel], [], [])
|
||||||
if channel.recv_ready():
|
if channel.recv_ready():
|
||||||
part = channel.recv(1024)
|
part = channel.recv(1024).decode('utf-8')
|
||||||
while part:
|
while part:
|
||||||
log.stdout += part
|
log.stdout += part
|
||||||
part = channel.recv(1024)
|
part = channel.recv(1024).decode('utf-8')
|
||||||
if channel.recv_stderr_ready():
|
if channel.recv_stderr_ready():
|
||||||
part = channel.recv_stderr(1024)
|
part = channel.recv_stderr(1024).decode('utf-8')
|
||||||
while part:
|
while part:
|
||||||
log.stderr += part
|
log.stderr += part
|
||||||
part = channel.recv_stderr(1024)
|
part = channel.recv_stderr(1024).decode('utf-8')
|
||||||
log.save(update_fields=['stdout', 'stderr'])
|
log.save(update_fields=['stdout', 'stderr'])
|
||||||
if channel.exit_status_ready():
|
if channel.exit_status_ready():
|
||||||
break
|
if second:
|
||||||
|
break
|
||||||
|
second = True
|
||||||
else:
|
else:
|
||||||
log.stdout += channel.makefile('rb', -1).read().decode('utf-8')
|
log.stdout += channel.makefile('rb', -1).read().decode('utf-8')
|
||||||
log.stderr += channel.makefile_stderr('rb', -1).read().decode('utf-8')
|
log.stderr += channel.makefile_stderr('rb', -1).read().decode('utf-8')
|
||||||
|
|
|
@ -268,40 +268,46 @@ class MetricStorage(models.Model):
|
||||||
|
|
||||||
accounts.register(Order)
|
accounts.register(Order)
|
||||||
|
|
||||||
@receiver(pre_delete, dispatch_uid="orders.account_orders")
|
#@receiver(pre_delete, dispatch_uid="orders.account_orders")
|
||||||
def account_orders(sender, **kwargs):
|
#def account_orders(sender, **kwargs):
|
||||||
account = kwargs['instance']
|
# account = kwargs['instance']
|
||||||
if isinstance(account, Order.account.field.rel.to):
|
# if isinstance(account, Order.account.field.rel.to):
|
||||||
account._deleted = True
|
# account._deleted = True
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME account deletion generates a integrity error
|
||||||
# TODO build a cache hash table {model: related, model: None}
|
# TODO build a cache hash table {model: related, model: None}
|
||||||
@receiver(post_delete, dispatch_uid="orders.cancel_orders")
|
@receiver(post_delete, dispatch_uid="orders.cancel_orders")
|
||||||
def cancel_orders(sender, **kwargs):
|
def cancel_orders(sender, **kwargs):
|
||||||
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
|
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
|
||||||
instance = kwargs['instance']
|
instance = kwargs['instance']
|
||||||
# Account delete will delete all related orders, no need to maintain order consistency
|
# Account delete will delete all related orders, no need to maintain order consistency
|
||||||
if isinstance(instance, Order.account.field.rel.to):
|
# if isinstance(instance, Order.account.field.rel.to):
|
||||||
# print 'aaaaaaaaaaaaaAAAAAAAAAAAAAAAAaa'
|
# return
|
||||||
|
if sender is Order.account.field.rel.to:
|
||||||
return
|
return
|
||||||
# print 'delete', sender, kwargs
|
print('delete', sender, instance, instance.pk)
|
||||||
try:
|
|
||||||
print(instance.account.pk)
|
|
||||||
except Exception as e:
|
|
||||||
pass
|
|
||||||
if type(instance) in services:
|
if type(instance) in services:
|
||||||
for order in Order.objects.by_object(instance).active():
|
for order in Order.objects.by_object(instance).active():
|
||||||
order.cancel()
|
order.cancel()
|
||||||
elif not hasattr(instance, 'account'):
|
elif not hasattr(instance, 'account'):
|
||||||
related = helpers.get_related_object(instance)
|
related = helpers.get_related_object(instance)
|
||||||
|
# FIXME this shit returns objects that are already deleted
|
||||||
|
# Indeterminate behaviour
|
||||||
if related and related != instance:
|
if related and related != instance:
|
||||||
|
# if isinstance(related, Order.account.field.rel.to):
|
||||||
|
# return
|
||||||
|
print('related', type(related), related, related.pk)
|
||||||
|
# try:
|
||||||
|
# type(related).objects.get(pk=related.pk)
|
||||||
|
# except related.DoesNotExist:
|
||||||
|
# print('not exists', type(related), related, related.pk)
|
||||||
Order.update_orders(related)
|
Order.update_orders(related)
|
||||||
|
|
||||||
@receiver(post_save, dispatch_uid="orders.update_orders")
|
@receiver(post_save, dispatch_uid="orders.update_orders")
|
||||||
def update_orders(sender, **kwargs):
|
def update_orders(sender, **kwargs):
|
||||||
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
|
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
|
||||||
instance = kwargs['instance']
|
instance = kwargs['instance']
|
||||||
# print 'save', sender, kwargs
|
|
||||||
if type(instance) in services:
|
if type(instance) in services:
|
||||||
Order.update_orders(instance)
|
Order.update_orders(instance)
|
||||||
elif not hasattr(instance, 'account'):
|
elif not hasattr(instance, 'account'):
|
||||||
|
|
|
@ -63,11 +63,14 @@ class MonthlyAvg(MonthlySum):
|
||||||
)
|
)
|
||||||
|
|
||||||
def compute_usage(self, dataset):
|
def compute_usage(self, dataset):
|
||||||
last = dataset.latest()
|
result = 0
|
||||||
|
try:
|
||||||
|
last = dataset.latest()
|
||||||
|
except dataset.model.DoesNotExist:
|
||||||
|
return result
|
||||||
epoch = self.get_epoch()
|
epoch = self.get_epoch()
|
||||||
total = (last.created_at-epoch).total_seconds()
|
total = (last.created_at-epoch).total_seconds()
|
||||||
ini = epoch
|
ini = epoch
|
||||||
result = 0
|
|
||||||
for data in dataset:
|
for data in dataset:
|
||||||
slot = (data.created_at-ini).total_seconds()
|
slot = (data.created_at-ini).total_seconds()
|
||||||
result += data.value * decimal.Decimal(str(slot/total))
|
result += data.value * decimal.Decimal(str(slot/total))
|
||||||
|
|
|
@ -40,8 +40,8 @@ class SystemUserBackend(ServiceController):
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
{ sleep 2 && killall -u %(user)s -s KILL; } &
|
{ sleep 2 && killall -u %(user)s -s KILL; } &
|
||||||
killall -u %(user)s || true
|
killall -u %(user)s || true
|
||||||
userdel %(user)s || true
|
userdel %(user)s || exit_code=1
|
||||||
groupdel %(group)s || true""") % context
|
groupdel %(group)s || exit_code=1""") % context
|
||||||
)
|
)
|
||||||
self.delete_home(context, user)
|
self.delete_home(context, user)
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class SystemUserBackend(ServiceController):
|
||||||
def delete_home(self, context, user):
|
def delete_home(self, context, user):
|
||||||
if user.home.rstrip('/') == user.get_base_home().rstrip('/'):
|
if user.home.rstrip('/') == user.get_base_home().rstrip('/'):
|
||||||
# TODO delete instead of this shit
|
# TODO delete instead of this shit
|
||||||
self.append("mv %(home)s %(home)s.deleted" % context)
|
self.append("mv %(home)s %(home)s.deleted || exit_code=1" % context)
|
||||||
|
|
||||||
def get_groups(self, user):
|
def get_groups(self, user):
|
||||||
if user.is_main:
|
if user.is_main:
|
||||||
|
|
|
@ -119,13 +119,14 @@ function install_requirements () {
|
||||||
check_root
|
check_root
|
||||||
ORCHESTRA_PATH=$(get_orchestra_dir)
|
ORCHESTRA_PATH=$(get_orchestra_dir)
|
||||||
|
|
||||||
APT="python-pip \
|
APT="python3 \
|
||||||
python-psycopg2 \
|
python3-pip \
|
||||||
|
python3-psycopg2 \
|
||||||
postgresql \
|
postgresql \
|
||||||
rabbitmq-server \
|
rabbitmq-server \
|
||||||
python-dev \
|
python3-dev \
|
||||||
bind9utils \
|
bind9utils \
|
||||||
python-cracklib \
|
python3-cracklib \
|
||||||
libz-dev \
|
libz-dev \
|
||||||
libxml2-dev \
|
libxml2-dev \
|
||||||
libxslt1-dev \
|
libxslt1-dev \
|
||||||
|
@ -166,7 +167,7 @@ function install_requirements () {
|
||||||
APT="${APT} \
|
APT="${APT} \
|
||||||
iceweasel \
|
iceweasel \
|
||||||
dnsutils \
|
dnsutils \
|
||||||
python-mysqldb"
|
python3-mysqldb"
|
||||||
PIP="${PIP} \
|
PIP="${PIP} \
|
||||||
selenium \
|
selenium \
|
||||||
xvfbwrapper \
|
xvfbwrapper \
|
||||||
|
@ -199,7 +200,7 @@ function install_requirements () {
|
||||||
update-ca-certificates
|
update-ca-certificates
|
||||||
fi
|
fi
|
||||||
|
|
||||||
run pip install $PIP
|
run pip3 install $PIP
|
||||||
|
|
||||||
# Some versions of rabbitmq-server will not start automatically by default unless ...
|
# Some versions of rabbitmq-server will not start automatically by default unless ...
|
||||||
sed -i "s/# Default-Start:.*/# Default-Start: 2 3 4 5/" /etc/init.d/rabbitmq-server
|
sed -i "s/# Default-Start:.*/# Default-Start: 2 3 4 5/" /etc/init.d/rabbitmq-server
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Command(BaseCommand):
|
||||||
CELERYD_CHDIR="%(site_dir)s"
|
CELERYD_CHDIR="%(site_dir)s"
|
||||||
|
|
||||||
# How to call "manage.py celeryd_multi"
|
# How to call "manage.py celeryd_multi"
|
||||||
CELERYD_MULTI="$CELERYD_CHDIR/manage.py celeryd_multi"
|
CELERYD_MULTI="python3 $CELERYD_CHDIR/manage.py celeryd_multi"
|
||||||
|
|
||||||
# Extra arguments to celeryd
|
# Extra arguments to celeryd
|
||||||
CELERYD_OPTS="-P:w1 processes -c:w1 %(processes)s -Q:w1 celery"
|
CELERYD_OPTS="-P:w1 processes -c:w1 %(processes)s -Q:w1 celery"
|
||||||
|
@ -67,14 +67,14 @@ class Command(BaseCommand):
|
||||||
CELERYD_STATE_DB="$CELERYD_CHDIR/persistent_revokes"
|
CELERYD_STATE_DB="$CELERYD_CHDIR/persistent_revokes"
|
||||||
|
|
||||||
# Celeryev
|
# Celeryev
|
||||||
CELERYEV="$CELERYD_CHDIR/manage.py"
|
CELERYEV="python3 $CELERYD_CHDIR/manage.py"
|
||||||
CELERYEV_CAM="djcelery.snapshot.Camera"
|
CELERYEV_CAM="djcelery.snapshot.Camera"
|
||||||
CELERYEV_USER="$CELERYD_USER"
|
CELERYEV_USER="$CELERYD_USER"
|
||||||
CELERYEV_GROUP="$CELERYD_USER"
|
CELERYEV_GROUP="$CELERYD_USER"
|
||||||
CELERYEV_OPTS="celerycam"
|
CELERYEV_OPTS="celerycam"
|
||||||
|
|
||||||
# Celerybeat
|
# Celerybeat
|
||||||
CELERYBEAT="${CELERYD_CHDIR}/manage.py celerybeat"
|
CELERYBEAT="python3 ${CELERYD_CHDIR}/manage.py celerybeat"
|
||||||
CELERYBEAT_USER="$CELERYD_USER"
|
CELERYBEAT_USER="$CELERYD_USER"
|
||||||
CELERYBEAT_GROUP="$CELERYD_USER"
|
CELERYBEAT_GROUP="$CELERYD_USER"
|
||||||
CELERYBEAT_CHDIR="$CELERYD_CHDIR"
|
CELERYBEAT_CHDIR="$CELERYD_CHDIR"
|
||||||
|
|
Loading…
Reference in New Issue