Random fixes
This commit is contained in:
parent
8fdec05908
commit
17739129d3
7
TODO.md
7
TODO.md
|
@ -340,7 +340,7 @@ TODO mount the filesystem with "nosuid" option
|
|||
# smtplib.SMTPConnectError: (421, b'4.7.0 mail.pangea.org Error: too many connections from 77.246.181.209')
|
||||
|
||||
# rename virtual_maps to virtual_alias_maps and remove virtual_alias_domains ?
|
||||
# virtdomains file is not ideal, prevent fake/error on domains there! and make sure this file is required!
|
||||
# virtdomains file is not ideal, prevent fake/error on domains there! and make sure to chekc if this file is required!
|
||||
|
||||
# Deprecate restart/start/stop services (do touch wsgi.py and fuck celery)
|
||||
orchestra-beat support for uwsgi cron
|
||||
|
@ -353,11 +353,10 @@ make django admin taskstate uncollapse fucking traceback, ( if exists ?)
|
|||
|
||||
resorce monitoring more efficient, less mem an better queries for calc current data
|
||||
|
||||
# best_price rating method
|
||||
# test best_price rating method
|
||||
|
||||
# bill this https://orchestra.pangea.org/admin/orders/order/8236/ should be already billed, <= vs <
|
||||
# Convert rating method from function to PluginClass
|
||||
# Tests can not run because django.db.utils.ProgrammingError: relation "accounts_account" does not exist
|
||||
|
||||
|
||||
|
||||
# autoresponses on mailboxes, not addresses or remove them
|
||||
|
|
|
@ -92,12 +92,11 @@ class BackendOperationInline(admin.TabularInline):
|
|||
}
|
||||
|
||||
def instance_link(self, operation):
|
||||
try:
|
||||
return admin_link('instance')(self, operation)
|
||||
except:
|
||||
return _("deleted {0} {1}").format(
|
||||
escape(operation.content_type), escape(operation.object_id)
|
||||
)
|
||||
link = admin_link('instance')(self, operation)
|
||||
if not link.startswith('<a'):
|
||||
return _("Deleted {0}").format(operation.instance_repr or '-'.join(
|
||||
(escape(operation.content_type), escape(operation.object_id))))
|
||||
return link
|
||||
instance_link.allow_tags = True
|
||||
instance_link.short_description = _("Instance")
|
||||
|
||||
|
|
|
@ -44,9 +44,7 @@ def keep_log(execute, log, operations):
|
|||
# Store and log the operation
|
||||
for operation in operations:
|
||||
logger.info("Executed %s" % str(operation))
|
||||
if operation.instance.pk:
|
||||
# Not all backends are called with objects saved on the database
|
||||
operation.store(log)
|
||||
operation.store(log)
|
||||
stdout = log.stdout.strip()
|
||||
stdout and logger.debug('STDOUT %s', stdout)
|
||||
stderr = log.stderr.strip()
|
||||
|
@ -146,8 +144,8 @@ def execute(scripts, serialize=False, async=None):
|
|||
|
||||
def collect(instance, action, **kwargs):
|
||||
""" collect operations """
|
||||
operations = kwargs.get('operations') or OrderedSet()
|
||||
route_cache = kwargs.get('route_cache') or {}
|
||||
operations = kwargs.get('operations', OrderedSet())
|
||||
route_cache = kwargs.get('route_cache', {})
|
||||
for backend_cls in ServiceBackend.get_backends():
|
||||
# Check if there exists a related instance to be executed for this backend and action
|
||||
instances = []
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orchestration', '0002_auto_20150506_1420'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='backendoperation',
|
||||
name='instance_repr',
|
||||
field=models.CharField(default='', max_length=256, verbose_name='instance representation'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='backendoperation',
|
||||
name='object_id',
|
||||
field=models.PositiveIntegerField(null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='route',
|
||||
name='async',
|
||||
field=models.BooleanField(default=False, help_text='Whether or not block the request/response cycle waitting this backend to finish its execution. Usually you want slave servers to run asynchronously.'),
|
||||
),
|
||||
]
|
|
@ -104,6 +104,17 @@ class BackendLog(models.Model):
|
|||
return ServiceBackend.get_backend(self.backend)
|
||||
|
||||
|
||||
class BackendOperationQuerySet(models.QuerySet):
|
||||
def create(self, **kwargs):
|
||||
instance = kwargs.get('instance')
|
||||
if instance and not instance.pk and 'instance_repr' not in kwargs:
|
||||
try:
|
||||
kwargs['instance_repr'] = str(instance)[:256]
|
||||
except:
|
||||
pass
|
||||
return super(BackendOperationQuerySet, self).create(**kwargs)
|
||||
|
||||
|
||||
class BackendOperation(models.Model):
|
||||
"""
|
||||
Encapsulates an operation, storing its related object, the action and the backend.
|
||||
|
@ -112,9 +123,11 @@ class BackendOperation(models.Model):
|
|||
backend = models.CharField(_("backend"), max_length=256)
|
||||
action = models.CharField(_("action"), max_length=64)
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
object_id = models.PositiveIntegerField()
|
||||
object_id = models.PositiveIntegerField(null=True)
|
||||
instance_repr = models.CharField(_("instance representation"), max_length=256)
|
||||
|
||||
instance = GenericForeignKey('content_type', 'object_id')
|
||||
objects = BackendOperationQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Operation")
|
||||
|
|
|
@ -431,6 +431,8 @@ class ServiceHandler(plugins.Plugin, metaclass=plugins.PluginMount):
|
|||
continue
|
||||
cini = order.billed_until
|
||||
bp = self.get_billing_point(order, bp=bp, **options)
|
||||
if order.billed_until and order.billed_until >= bp:
|
||||
continue
|
||||
order.new_billed_until = bp
|
||||
ini = min(ini, cini)
|
||||
end = max(end, bp)
|
||||
|
|
|
@ -33,10 +33,11 @@ def set_permission(modeladmin, request, queryset):
|
|||
cleaned_data = form.cleaned_data
|
||||
operations = []
|
||||
for user in queryset:
|
||||
user.set_perm_action = cleaned_data['set_action']
|
||||
user.set_perm_base_home = cleaned_data['base_home']
|
||||
user.set_perm_home_extension = cleaned_data['home_extension']
|
||||
user.set_perm_perms = cleaned_data['permissions']
|
||||
base_home = cleaned_data['base_home']
|
||||
extension = cleaned_data['home_extension']
|
||||
action = cleaned_data['set_action']
|
||||
perms = cleaned_data['permissions']
|
||||
user.set_permission(base_home, extension, action=action, perms=perms)
|
||||
operations.extend(Operation.create_for_action(user, 'set_permission'))
|
||||
verbose_action = get_verbose_choice(form.fields['set_action'].choices,
|
||||
user.set_perm_action)
|
||||
|
|
|
@ -86,14 +86,14 @@ class UNIXUserBackend(ServiceController):
|
|||
})
|
||||
exclude_acl = []
|
||||
for exclude in settings.SYSTEMUSERS_FORBIDDEN_PATHS:
|
||||
context['exclude_acl'] = exclude
|
||||
exclude_acl.append('-not -path "%(perm_to)s/%(exclude_acl)s"' % context)
|
||||
context['exclude_acl'] = os.path.join(context['perm_home'], exclude)
|
||||
exclude_acl.append('-not -path "%(exclude_acl)s"' % context)
|
||||
context['exclude_acl'] = ' \\\n -a '.join(exclude_acl) if exclude_acl else ''
|
||||
if user.set_perm_perms == 'read-write':
|
||||
if user.set_perm_perms == 'rw':
|
||||
context['perm_perms'] = 'rwx' if user.set_perm_action == 'grant' else '---'
|
||||
elif user.set_perm_perms == 'read-only':
|
||||
elif user.set_perm_perms == 'r':
|
||||
context['perm_perms'] = 'r-x' if user.set_perm_action == 'grant' else '-wx'
|
||||
elif user.set_perm_perms == 'write-only':
|
||||
elif user.set_perm_perms == 'w':
|
||||
context['perm_perms'] = '-wx' if user.set_perm_action == 'grant' else 'r-x'
|
||||
if user.set_perm_action == 'grant':
|
||||
self.append(textwrap.dedent("""\
|
||||
|
@ -105,8 +105,7 @@ class UNIXUserBackend(ServiceController):
|
|||
find '%(perm_to)s' -type d %(exclude_acl)s \\
|
||||
-exec setfacl -m d:u:%(user)s:%(perm_perms)s {} \\;
|
||||
# Account group as the owner of new files
|
||||
chmod g+s '%(perm_to)s'
|
||||
""") % context
|
||||
chmod g+s '%(perm_to)s'""") % context
|
||||
)
|
||||
if not user.is_main:
|
||||
self.append(textwrap.dedent("""\
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from django.contrib.admin import SimpleListFilter
|
||||
from django.db.models import F
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
|
@ -16,7 +15,6 @@ class IsMainListFilter(SimpleListFilter):
|
|||
|
||||
def queryset(self, request, queryset):
|
||||
if self.value() == 'True':
|
||||
return queryset.filter(account__main_systemuser_id=F('id'))
|
||||
return queryset.by_is_main()
|
||||
if self.value() == 'False':
|
||||
return queryset.exclude(account__main_systemuser_id=F('id'))
|
||||
|
||||
return queryset.by_is_main(is_main=False)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
import textwrap
|
||||
|
||||
from django import forms
|
||||
|
@ -94,9 +95,9 @@ class PermissionForm(forms.Form):
|
|||
widget=forms.TextInput(attrs={'size':'70'}), help_text=_("Relative to chosen home."))
|
||||
permissions = forms.ChoiceField(label=_("Permissions"), initial='read-write',
|
||||
choices=(
|
||||
('read-write', _("Read and write")),
|
||||
('read-only', _("Read only")),
|
||||
('write-only', _("Write only"))
|
||||
('rw', _("Read and write")),
|
||||
('r', _("Read only")),
|
||||
('w', _("Write only"))
|
||||
))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
|
|
@ -4,6 +4,7 @@ import os
|
|||
from django.contrib.auth.hashers import make_password
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.db.models import F
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -18,6 +19,12 @@ class SystemUserQuerySet(models.QuerySet):
|
|||
user.set_password(password)
|
||||
user.save(update_fields=['password'])
|
||||
return user
|
||||
|
||||
def by_is_main(self, is_main=True, **kwargs):
|
||||
if is_main:
|
||||
return self.filter(account__main_systemuser_id=F('id'))
|
||||
else:
|
||||
return self.exclude(account__main_systemuser_id=F('id'))
|
||||
|
||||
|
||||
class SystemUser(models.Model):
|
||||
|
@ -112,6 +119,12 @@ class SystemUser(models.Model):
|
|||
def set_password(self, raw_password):
|
||||
self.password = make_password(raw_password)
|
||||
|
||||
def set_permission(self, base_home, extension, perms='rw', action='grant'):
|
||||
self.set_perm_action = action
|
||||
self.set_perm_base_home = base_home
|
||||
self.set_perm_home_extension = extension
|
||||
self.set_perm_perms = perms
|
||||
|
||||
def get_base_home(self):
|
||||
context = {
|
||||
'user': self.username,
|
||||
|
|
|
@ -82,8 +82,10 @@ class PHPApp(AppType):
|
|||
options += list(webapp.options.all())
|
||||
init_vars = OrderedDict((opt.name, opt.value) for opt in options)
|
||||
# Enable functions
|
||||
enable_functions = init_vars.pop('enable_functions', None)
|
||||
if enable_functions:
|
||||
enable_functions = init_vars.pop('enable_functions', '')
|
||||
if enable_functions or self.is_fpm:
|
||||
# FPM: Defining 'disable_functions' or 'disable_classes' will not overwrite previously
|
||||
# defined php.ini values, but will append the new value
|
||||
enable_functions = set(enable_functions.split(','))
|
||||
disable_functions = []
|
||||
for function in self.PHP_DISABLED_FUNCTIONS:
|
||||
|
|
|
@ -27,7 +27,7 @@ def get_request_cache():
|
|||
|
||||
class RequestCacheMiddleware(object):
|
||||
def process_request(self, request):
|
||||
cache = _request_cache.get(currentThread()) or RequestCache()
|
||||
cache = _request_cache.get(currentThread(), RequestCache())
|
||||
_request_cache[currentThread()] = cache
|
||||
cache.clear()
|
||||
|
||||
|
|
Loading…
Reference in a new issue