Random fixes
This commit is contained in:
parent
0e850d6e2d
commit
d96afe41fa
2
TODO.md
2
TODO.md
|
@ -462,3 +462,5 @@ with open(file) as handler:
|
|||
# Bill amend and related transaction, what to do? allow edit transaction ammount of amends when their are pending execution
|
||||
|
||||
# DASHBOARD: Show owned tickets, scheduled actions, maintenance operations (diff domains)
|
||||
|
||||
# Add confirmation step on transaction actions like process transaction
|
||||
|
|
|
@ -26,11 +26,11 @@ from .models import (Bill, Invoice, AmendmentInvoice, Fee, AmendmentFee, ProForm
|
|||
|
||||
PAYMENT_STATE_COLORS = {
|
||||
Bill.OPEN: 'grey',
|
||||
Bill.CREATED: 'darkorange',
|
||||
Bill.CREATED: 'magenta',
|
||||
Bill.PROCESSED: 'darkorange',
|
||||
Bill.AMENDED: 'blue',
|
||||
Bill.PAID: 'green',
|
||||
Bill.EXECUTED: 'darkorange',
|
||||
Bill.EXECUTED: 'olive',
|
||||
Bill.BAD_DEBT: 'red',
|
||||
Bill.INCOMPLETE: 'red',
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ class BillAdmin(BillAdminMixin, ExtendedModelAdmin):
|
|||
)
|
||||
list_filter = (
|
||||
BillTypeListFilter, 'is_open', 'is_sent', TotalListFilter, PaymentStateListFilter,
|
||||
AmendedListFilter
|
||||
AmendedListFilter, 'account__is_active',
|
||||
)
|
||||
add_fields = ('account', 'type', 'amend_of', 'is_open', 'due_on', 'comments')
|
||||
change_list_template = 'admin/bills/bill/change_list.html'
|
||||
|
|
|
@ -77,12 +77,12 @@ class Bind9MasterDomainController(ServiceController):
|
|||
)
|
||||
if 'zone_path' in context:
|
||||
context['zone_subdomains_path'] = re.sub(r'^(.*/)', r'\1*.', context['zone_path'])
|
||||
self.append('rm -f %(zone_subdomains_path)s' % context)
|
||||
self.append('rm -f -- %(zone_subdomains_path)s' % context)
|
||||
|
||||
def delete(self, domain):
|
||||
context = self.get_context(domain)
|
||||
self.append('# Delete zone file for %(name)s' % context)
|
||||
self.append('rm -f %(zone_path)s;' % context)
|
||||
self.append('rm -f -- %(zone_path)s;' % context)
|
||||
self.delete_conf(context)
|
||||
|
||||
def delete_conf(self, context):
|
||||
|
|
|
@ -27,7 +27,7 @@ class LetsEncryptController(ServiceController):
|
|||
self.append(" --webroot-path %(webroot)s \\" % context)
|
||||
self.append(" --email %(email)s \\" % context)
|
||||
self.append(" -d %(domains)s \\" % context)
|
||||
self.cleanup.append("rm -rf %(webroot)s/.well-known" % context)
|
||||
self.cleanup.append("rm -rf -- %(webroot)s/.well-known" % context)
|
||||
|
||||
def commit(self):
|
||||
self.append(" || exit_code=$?")
|
||||
|
@ -49,6 +49,6 @@ class LetsEncryptController(ServiceController):
|
|||
return {
|
||||
'letsencrypt_auto': settings.LETSENCRYPT_AUTO_PATH,
|
||||
'webroot': content.webapp.get_path(),
|
||||
'email': website.account.email,
|
||||
'email': settings.LETSENCRYPT_EMAIL or website.account.email,
|
||||
'domains': ' \\\n -d '.join(website.encrypt_domains),
|
||||
}
|
||||
|
|
|
@ -9,3 +9,9 @@ LETSENCRYPT_AUTO_PATH = Setting('LETSENCRYPT_AUTO_PATH',
|
|||
LETSENCRYPT_LIVE_PATH = Setting('LETSENCRYPT_LIVE_PATH',
|
||||
'/etc/letsencrypt/live'
|
||||
)
|
||||
|
||||
|
||||
LETSENCRYPT_EMAIL = Setting('LETSENCRYPT_EMAIL',
|
||||
'',
|
||||
help_text="Uses account.email by default",
|
||||
)
|
||||
|
|
|
@ -52,7 +52,7 @@ class MailmanVirtualDomainController(ServiceController):
|
|||
|
||||
def delete(self, mail_list):
|
||||
context = self.get_context(mail_list)
|
||||
self.include_virtual_alias_domain(context)
|
||||
self.exclude_virtual_alias_domain(context)
|
||||
|
||||
def commit(self):
|
||||
context = self.get_context_files()
|
||||
|
|
|
@ -24,7 +24,7 @@ class SieveFilteringMixin:
|
|||
context['box'] = box
|
||||
self.append(textwrap.dedent("""
|
||||
# Create %(box)s mailbox
|
||||
su %(user)s --shell /bin/bash << 'EOF'
|
||||
su - %(user)s --shell /bin/bash << 'EOF'
|
||||
mkdir -p "%(maildir)s/.%(box)s"
|
||||
EOF
|
||||
if ! grep '%(box)s' %(maildir)s/subscriptions > /dev/null; then
|
||||
|
@ -39,7 +39,7 @@ class SieveFilteringMixin:
|
|||
context['filtering'] = ('# %(banner)s\n' + content) % context
|
||||
self.append(textwrap.dedent("""\
|
||||
# Create and compile orchestra sieve filtering
|
||||
su %(user)s --shell /bin/bash << 'EOF'
|
||||
su - %(user)s --shell /bin/bash << 'EOF'
|
||||
mkdir -p $(dirname "%(filtering_path)s")
|
||||
cat << ' EOF' > %(filtering_path)s
|
||||
%(filtering)s
|
||||
|
@ -97,7 +97,7 @@ class UNIXUserMaildirController(SieveFilteringMixin, ServiceController):
|
|||
#unit_to_bytes(mailbox.resources.disk.unit)
|
||||
self.append(textwrap.dedent("""
|
||||
# Set Maildir quota for %(user)s
|
||||
su %(user)s --shell /bin/bash << 'EOF'
|
||||
su - %(user)s --shell /bin/bash << 'EOF'
|
||||
mkdir -p %(maildir)s
|
||||
EOF
|
||||
if [ ! -f %(maildir)s/maildirsize ]; then
|
||||
|
@ -121,7 +121,7 @@ class UNIXUserMaildirController(SieveFilteringMixin, ServiceController):
|
|||
""") % context
|
||||
)
|
||||
else:
|
||||
self.append("rm -fr %(base_home)s" % context)
|
||||
self.append("rm -fr -- %(base_home)s" % context)
|
||||
self.append(textwrap.dedent("""
|
||||
nohup bash -c '{ sleep 2 && killall -u %(user)s -s KILL; }' &> /dev/null &
|
||||
killall -u %(user)s || true
|
||||
|
@ -195,7 +195,7 @@ class UNIXUserMaildirController(SieveFilteringMixin, ServiceController):
|
|||
# if context['deleted_home']:
|
||||
# self.append("mv %(home)s %(deleted_home)s || exit_code=$?" % context)
|
||||
# else:
|
||||
# self.append("rm -fr %(home)s" % context)
|
||||
# self.append("rm -fr -- %(home)s" % context)
|
||||
#
|
||||
# def get_extra_fields(self, mailbox, context):
|
||||
# context['quota'] = self.get_quota(mailbox)
|
||||
|
|
|
@ -45,9 +45,9 @@ def keep_log(execute, log, operations):
|
|||
if not log.is_success:
|
||||
send_report(execute, args, log)
|
||||
stdout = log.stdout.strip()
|
||||
stdout and logger.debug('STDOUT %s', stdout)
|
||||
stdout and logger.debug('STDOUT %s', stdout.encode('ascii', errors='replace').decode())
|
||||
stderr = log.stderr.strip()
|
||||
stderr and logger.debug('STDERR %s', stderr)
|
||||
stderr and logger.debug('STDERR %s', stderr.encode('ascii', errors='replace').decode())
|
||||
return wrapper
|
||||
|
||||
|
||||
|
@ -197,6 +197,7 @@ def collect(instance, action, **kwargs):
|
|||
# Only schedule operations if the router has execution routes
|
||||
routes = router.objects.get_for_operation(operation, cache=route_cache)
|
||||
if routes:
|
||||
logger.debug("Operation %s collected for execution" % operation)
|
||||
operation.routes = routes
|
||||
if iaction != Operation.DELETE:
|
||||
# usually we expect to be using last object state,
|
||||
|
|
|
@ -97,7 +97,7 @@ class OperationsMiddleware(object):
|
|||
|
||||
def process_response(self, request, response):
|
||||
""" Processes pending backend operations """
|
||||
if not isinstance(response, HttpResponseServerError):
|
||||
if response.status_code != 500:
|
||||
operations = self.get_pending_operations()
|
||||
if operations:
|
||||
try:
|
||||
|
|
|
@ -285,7 +285,7 @@ class MetricStorageQuerySet(models.QuerySet):
|
|||
last.save()
|
||||
else:
|
||||
error = decimal.Decimal(str(settings.ORDERS_METRIC_ERROR))
|
||||
if value > last.value+error or value < last.value-error:
|
||||
if (value > last.value+error or value < last.value-error) or (value == 0 and last.value > 0):
|
||||
self.create(order=order, value=value, updated_on=now)
|
||||
else:
|
||||
last.updated_on = now
|
||||
|
|
|
@ -26,6 +26,8 @@ ORDERS_EXCLUDED_APPS = Setting('ORDERS_EXCLUDED_APPS',
|
|||
'orchestration',
|
||||
'bills',
|
||||
'services',
|
||||
'mailer',
|
||||
'issues',
|
||||
),
|
||||
help_text="Prevent inspecting these apps for service accounting."
|
||||
)
|
||||
|
|
|
@ -77,7 +77,7 @@ Notice that two optional forms can be provided `form` and `change_form`. When no
|
|||
A backend class is required to interface with the web application and perform `save()` and `delete()` operations on it.
|
||||
|
||||
- The more reliable way of interfacing with the application is by means of a CLI (e.g. [Moodle](backends/moodle.py)), but not all CMS come with this tool.
|
||||
- The second preferable way is using some sort of API, possibly HTTP-based (e.g. [gitLab](backends/gitlab.py)). This is less reliable because additional moving parts are used underneath the interface; a busy web server can timeout our requests.
|
||||
- The second preferable way is using some sort of networked API, possibly HTTP-based (e.g. [gitLab](backends/gitlab.py)). This is less reliable because additional moving parts are used underneath the interface; a busy web server can timeout our requests.
|
||||
- The least preferred way is interfacing with an HTTP-HTML interface designed for human consumption, really painful to implement but sometimes is the only way (e.g. [WordPress](backends/wordpressmu.py)).
|
||||
|
||||
Some applications do not support multi-tenancy by default, but we can hack the configuration file of such apps and generate *table prefix* or *database name* based on some property of the URL. Example of this services are [moodle](backends/moodle.py) and [phplist](backends/phplist.py) respectively.
|
||||
|
|
|
@ -88,7 +88,7 @@ class MoodleMuController(ServiceController):
|
|||
self.append(textwrap.dedent("""\
|
||||
# Configuring Moodle crontabs
|
||||
if ! crontab -u %(user)s -l | grep 'Moodle:"%(site_name)s"' > /dev/null; then
|
||||
cat << EOF | su %(user)s --shell /bin/bash -c 'crontab'
|
||||
cat << EOF | su - %(user)s --shell /bin/bash -c 'crontab'
|
||||
$(crontab -u %(user)s -l)
|
||||
|
||||
# %(banner)s - Moodle:"%(site_name)s"
|
||||
|
@ -139,7 +139,7 @@ class MoodleMuController(ServiceController):
|
|||
self.append(textwrap.dedent("""\
|
||||
crontab -u %(user)s -l \\
|
||||
| grep -v 'Moodle:"%(site_name)s"\\|%(crontab_regex)s' \\
|
||||
| su %(user)s --shell /bin/bash -c 'crontab'
|
||||
| su - %(user)s --shell /bin/bash -c 'crontab'
|
||||
""") % context
|
||||
)
|
||||
self.delete_site_map(context)
|
||||
|
|
|
@ -88,7 +88,7 @@ class PhpListSaaSController(ServiceController):
|
|||
self.append(textwrap.dedent("""\
|
||||
# Configuring phpList crontabs
|
||||
if ! crontab -u %(user)s -l | grep 'phpList:"%(site_name)s"' > /dev/null; then
|
||||
cat << EOF | su %(user)s --shell /bin/bash -c 'crontab'
|
||||
cat << EOF | su - %(user)s --shell /bin/bash -c 'crontab'
|
||||
$(crontab -u %(user)s -l)
|
||||
|
||||
# %(banner)s - phpList:"%(site_name)s"
|
||||
|
@ -105,7 +105,7 @@ class PhpListSaaSController(ServiceController):
|
|||
self.append(textwrap.dedent("""\
|
||||
crontab -u %(user)s -l \\
|
||||
| grep -v 'phpList:"%(site_name)s"\\|%(crontab_regex)s' \\
|
||||
| su %(user)s --shell /bin/bash -c 'crontab'
|
||||
| su - %(user)s --shell /bin/bash -c 'crontab'
|
||||
""") % context
|
||||
)
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ def create_link(modeladmin, request, queryset):
|
|||
messages.error(request, "Users from the same account should be selected.")
|
||||
return
|
||||
user = queryset[0]
|
||||
form = LinkForm(user)
|
||||
form = LinkForm(user, queryset=queryset)
|
||||
action_value = 'create_link'
|
||||
if request.POST.get('post') == 'generic_confirmation':
|
||||
form = LinkForm(user, request.POST, queryset=queryset)
|
||||
|
|
|
@ -115,7 +115,7 @@ class UNIXUserController(ServiceController):
|
|||
""") % context
|
||||
)
|
||||
else:
|
||||
self.append("rm -fr '%(base_home)s'" % context)
|
||||
self.append("rm -fr -- '%(base_home)s'" % context)
|
||||
|
||||
def grant_permissions(self, user, context):
|
||||
context['perms'] = user.set_perm_perms
|
||||
|
@ -206,7 +206,7 @@ class UNIXUserController(ServiceController):
|
|||
})
|
||||
self.append(textwrap.dedent("""\
|
||||
# Create link
|
||||
su %(user)s --shell /bin/bash << 'EOF' || exit_code=1
|
||||
su - %(user)s --shell /bin/bash << 'EOF' || exit_code=1
|
||||
if [[ ! -e '%(link_name)s' ]]; then
|
||||
ln -s '%(link_target)s' '%(link_name)s'
|
||||
else
|
||||
|
|
|
@ -96,8 +96,7 @@ class LinkForm(forms.Form):
|
|||
widget=forms.TextInput(attrs={'size':'70'}),
|
||||
help_text=_("Relative path to chosen directory."))
|
||||
link_name = forms.CharField(label=_("Link name"), required=False, initial='',
|
||||
widget=forms.TextInput(attrs={'size':'70'}),
|
||||
help_text=_("If left blank or relative path: link will be created in each user home."))
|
||||
widget=forms.TextInput(attrs={'size':'70'}))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.instance = args[0]
|
||||
|
@ -110,6 +109,12 @@ class LinkForm(forms.Form):
|
|||
self.fields['base_home'].choices = (
|
||||
(user.get_base_home(), user.get_base_home()) for user in related_users
|
||||
)
|
||||
if len(self.queryset) == 1:
|
||||
user = self.instance
|
||||
help_text = _("If left blank or relative path: the link will be created in %s home.") % user
|
||||
else:
|
||||
help_text = _("If left blank or relative path: the link will be created in each user home.")
|
||||
self.fields['link_name'].help_text = help_text
|
||||
|
||||
def clean_home_extension(self):
|
||||
home_extension = self.cleaned_data['home_extension']
|
||||
|
|
|
@ -70,7 +70,7 @@ class MoodleController(WebAppServiceMixin, ServiceController):
|
|||
# Run install moodle cli command on the background, because it takes so long...
|
||||
stdout=$(mktemp)
|
||||
stderr=$(mktemp)
|
||||
nohup su %(user)s --shell /bin/bash << 'EOF' > $stdout 2> $stderr &
|
||||
nohup su - %(user)s --shell /bin/bash << 'EOF' > $stdout 2> $stderr &
|
||||
php %(app_path)s/admin/cli/install_database.php \\
|
||||
--fullname="%(site_name)s" \\
|
||||
--shortname="%(site_name)s" \\
|
||||
|
|
Loading…
Reference in a new issue