Random fixes

This commit is contained in:
Marc Aymerich 2015-05-09 17:08:45 +00:00
parent 13cf3a41ed
commit 0d63a4ddad
29 changed files with 112 additions and 78 deletions

View File

@ -354,4 +354,4 @@ make django admin taskstate uncollapse fucking traceback, ( if exists ?)
# backend.context and backned.instance provided when an action is called? like forms.cleaned_data: do it on manager.generation(backend.context = backend.get_context()) or in backend.__getattr__ ? also backend.head,tail,content switching on manager.generate()?
# replace return_code by exit_code everywhere
resorce monitoring more efficient, less mem an better queries for calc current data

View File

@ -5,6 +5,7 @@ from django.utils.translation import ungettext, ugettext_lazy as _
from .. import settings
from .decorators import action_with_confirmation
from .forms import SendEmailForm
@ -107,3 +108,25 @@ class SendEmail(object):
})
# Display the confirmation page
return render(request, self.template, self.context)
@action_with_confirmation()
def disable(modeladmin, request, queryset):
num = 0
for obj in queryset:
obj.disable()
modeladmin.log_change(request, obj, _("Disabled"))
num += 1
opts = modeladmin.model._meta
context = {
'verbose_name': opts.verbose_name,
'verbose_name_plural': opts.verbose_name_plural,
'num': num
}
msg = ungettext(
_("Selected %(verbose_name)s and related services has been disabled.") % context,
_("%(num)s selected %(verbose_name_plural)s and related services have been disabled.") % context,
num)
modeladmin.message_user(request, msg)
disable.url_name = 'disable'
disable.verbose_name = _("Disable")

View File

@ -12,28 +12,11 @@ from django.utils.html import format_html
from django.utils.text import capfirst
from django.utils.translation import ungettext, ugettext_lazy as _
from orchestra.admin.decorators import action_with_confirmation
from orchestra.core import services
from . import settings
@action_with_confirmation()
def disable(modeladmin, request, queryset):
num = 0
for account in queryset:
account.disable()
modeladmin.log_change(request, account, _("Disabled"))
num += 1
msg = ungettext(
_("Selected account and related services has been disabled."),
_("%s selected accounts and related services have been disabled.") % num,
num)
modeladmin.message_user(request, msg)
disable.url_name = 'disable'
disable.verbose_name = _("Disable")
def list_contacts(modeladmin, request, queryset):
ids = queryset.values_list('id', flat=True)
if not ids:

View File

@ -12,12 +12,12 @@ from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import SendEmail
from orchestra.admin.actions import SendEmail, disable
from orchestra.admin.utils import wrap_admin_view, admin_link, set_url_query, change_url
from orchestra.core import services, accounts
from orchestra.forms import UserChangeForm
from .actions import disable, list_contacts, service_report, delete_related_services
from .actions import list_contacts, service_report, delete_related_services
from .filters import HasMainUserListFilter
from .forms import AccountCreationForm
from .models import Account

View File

@ -114,7 +114,7 @@ class DomainTestMixin(object):
'server_addr': server_addr
}
dig_soa = 'dig @%(server_addr)s %(domain_name)s|grep "\sSOA\s"'
soa = run(dig_soa % context, error_codes=[0,1]).stdout
soa = run(dig_soa % context, valid_codes=(0, 1)).stdout
if soa:
soa = soa.split()
self.assertEqual('IN', soa[2])

View File

@ -118,11 +118,11 @@ def validate_zone(zone):
with open(zone_path, 'wb') as f:
f.write(zone.encode('ascii'))
# 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,127], display=False)
check = run(' '.join([checkzone, zone_name, zone_path]), valid_codes=(0,1,127), display=False)
finally:
os.unlink(zone_path)
if check.return_code == 127:
if check.exit_code == 127:
logger.error("Cannot validate domain zone: %s not installed." % checkzone)
elif check.return_code == 1:
elif check.exit_code == 1:
errors = re.compile(r'zone.*: (.*)').findall(check.stdout)[:-1]
raise ValidationError(', '.join(errors))

View File

@ -4,6 +4,7 @@ from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable
from orchestra.admin.utils import admin_link
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
from orchestra.contrib.accounts.filters import IsActiveListFilter
@ -52,6 +53,7 @@ class ListAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedModel
add_form = ListCreationForm
list_select_related = ('account', 'address_domain',)
filter_by_account_fields = ['address_domain']
actions = (disable,)
address_domain_link = admin_link('address_domain', order='address_domain__name')

View File

@ -55,6 +55,10 @@ class List(models.Model):
def active(self):
return self.is_active and self.account.is_active
def disable(self):
self.is_active = False
self.save(update_fields=('is_active',))
def get_address_name(self):
return self.address_name or self.name

View File

@ -8,6 +8,7 @@ from django.db.models.functions import Concat
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable
from orchestra.admin.utils import admin_link, change_url
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
from orchestra.contrib.accounts.filters import IsActiveListFilter
@ -65,6 +66,12 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
add_form = MailboxCreationForm
form = MailboxChangeForm
list_prefetch_related = ('addresses__domain',)
actions = (disable,)
def __init__(self, *args, **kwargs):
super(MailboxAdmin, self).__init__(*args, **kwargs)
if settings.MAILBOXES_LOCAL_ADDRESS_DOMAIN:
type(self).actions = self.actions + (SendMailboxEmail(),)
def display_addresses(self, mailbox):
addresses = []
@ -82,13 +89,6 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
display_filtering.admin_order_field = 'filtering'
display_filtering.allow_tags = True
def get_actions(self, request):
if settings.MAILBOXES_LOCAL_ADDRESS_DOMAIN:
type(self).actions = (SendMailboxEmail(),)
else:
type(self).actions = ()
return super(MailboxAdmin, self).get_actions(request)
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'filtering':
kwargs['widget'] = OpenCustomFilteringOnSelect()

View File

@ -42,6 +42,10 @@ class Mailbox(models.Model):
except type(self).account.field.rel.to.DoesNotExist:
return self.is_active
def disable(self):
self.is_active = False
self.save(update_fields=('is_active',))
def set_password(self, raw_password):
self.password = make_password(raw_password)

View File

@ -62,7 +62,7 @@ def validate_sieve(value):
test = run(' '.join([sievetest, test_path, '/dev/null']), silent=True)
finally:
os.unlink(test_path)
if test.return_code:
if test.exit_code:
errors = []
for line in test.stderr.decode('utf8').splitlines():
error = re.match(r'^.*(line\s+[0-9]+:.*)', line)

View File

@ -3,13 +3,13 @@ from orchestra.contrib.settings import Setting
PLANS_RATE_METHODS = Setting('PLANS_RATE_METHODS',
(
'orchestra.contrib.plans.rating.step_price',
'orchestra.contrib.plans.rating.match_price',
'orchestra.contrib.plans.rating.best_price',
'orchestra.contrib.plans.ratings.step_price',
'orchestra.contrib.plans.ratings.match_price',
'orchestra.contrib.plans.ratings.best_price',
)
)
PLANS_DEFAULT_RATE_METHOD = Setting('PLANS_DEFAULT_RATE_METHOD',
'orchestra.contrib.plans.rating.step_price',
'orchestra.contrib.plans.ratings.step_price',
)

View File

@ -8,7 +8,7 @@ from .backends import ServiceMonitor
@task(name='resources.Monitor')
def monitor(resource_id, ids=None):
with LockFile('/dev/shm/resources.monitor-%i.lock' % resource_id, expire=60*60):
with LockFile('/dev/shm/resources.monitor-%i.lock' % resource_id, expire=60*60, unlocked=bool(ids)):
from .models import ResourceData, Resource
resource = Resource.objects.get(pk=resource_id)
resource_model = resource.content_type.model_class()

View File

@ -2,6 +2,7 @@ from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable
from orchestra.contrib.accounts.admin import AccountAdminMixin
from orchestra.plugins.admin import SelectPluginAdminMixin
@ -17,6 +18,7 @@ class SaaSAdmin(SelectPluginAdminMixin, ChangePasswordAdminMixin, AccountAdminMi
plugin = SoftwareService
plugin_field = 'service'
plugin_title = 'Software as a Service'
actions = (disable,)
def display_site_domain(self, saas):
site_domain = saas.get_site_domain()

View File

@ -61,6 +61,10 @@ class SaaS(models.Model):
def active(self):
return self.is_active and self.account.is_active
def disable(self):
self.is_active = False
self.save(update_fields=('is_active',))
def clean(self):
if not self.pk:
self.name = self.name.lower()

View File

@ -23,7 +23,7 @@
nominal_price=28.10&
tax=21&
pricing_period=BILLING_PERIOD&
rate_algorithm=STEP_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.step_price&
on_cancel=COMPENSATE&
payment_style=PREPAY">Mailbox</option>
<option value="./?description=Mailbox%20allocated%20disk&
@ -41,7 +41,7 @@
nominal_price=20.00&
tax=21&
pricing_period=&
rate_algorithm=MATCH_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.match_price&
on_cancel=DISCOUNT&
payment_style=PREPAY">Mailbox allocated disk</option>
<option value="./?description=Database&
@ -58,7 +58,7 @@
nominal_price=24.79&
tax=21&
pricing_period=BILLING_PERIOD&
rate_algorithm=STEP_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.step_price&
on_cancel=COMPENSATE&
payment_style=PREPAY">Database</option>
<option value="./?description=Basic%20domain&
@ -76,7 +76,7 @@
nominal_price=19.01&
tax=21&
pricing_period=BILLING_PERIOD&
rate_algorithm=STEP_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.step_price&
on_cancel=NOTHING&
payment_style=PREPAY">Basic domain</option>
<option value="./?description=Domain%20.cat%20extra&
@ -94,7 +94,7 @@
nominal_price=26.59&
tax=21&
pricing_period=BILLING_PERIOD&
rate_algorithm=STEP_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.step_price&
on_cancel=NOTHING&
payment_style=PREPAY">Domain .cat extra</option>
<option value="./?description=FTP%20account&
@ -112,7 +112,7 @@
nominal_price=28.10&
tax=21&
pricing_period=BILLING_PERIOD&
rate_algorithm=STEP_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.step_price&
on_cancel=COMPENSATE&
payment_style=PREPAY">FTP account</option>
<option value="./?description=Traffic&
@ -130,7 +130,7 @@
nominal_price=4.50&
tax=21&
pricing_period=BILLING_PERIOD&
rate_algorithm=MATCH_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.match_price&
on_cancel=NOTHING&
payment_style=POSTPAY">Traffic</option>
<option value="./?description=Traffic%20prepay&
@ -148,7 +148,7 @@
nominal_price=3.00&
tax=21&
pricing_period=MONTHLY&
rate_algorithm=MATCH_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.match_price&
on_cancel=REFUND&
payment_style=PREPAY">Traffic prepay</option>
<option value="./?description=Development&
@ -166,7 +166,7 @@
nominal_price=40.00&
tax=21&
pricing_period=BILLING_PERIOD&
rate_algorithm=STEP_PRICE&
rate_algorithm=orchestra.contrib.plans.ratings.step_price&
on_cancel=NOTHING&
payment_style=PREPAY">Develompent</option>
{% endoneliner %}

View File

@ -66,7 +66,7 @@ class SettingView(generic.edit.FormView):
if not self.request.POST.get('confirmation'):
settings_file = parser.get_settings_file()
new_content = parser.apply(changes)
diff = sys.run("cat <<EOF | diff %s -\n%s\nEOF" % (settings_file, new_content), error_codes=[1, 0]).stdout
diff = sys.run("cat <<EOF | diff %s -\n%s\nEOF" % (settings_file, new_content), valid_codes=(1, 0)).stdout
context = self.get_context_data(form=form)
context['diff'] = diff
return self.render_to_response(context)

View File

@ -2,6 +2,7 @@ from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.admin.actions import disable
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
from orchestra.contrib.accounts.filters import IsActiveListFilter
@ -40,7 +41,7 @@ class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, Extende
add_form = SystemUserCreationForm
form = SystemUserChangeForm
ordering = ('-id',)
actions = (delete_selected, grant_permission,)
actions = (delete_selected, grant_permission, disable)
change_view_actions = actions
def display_main(self, user):

View File

@ -68,6 +68,10 @@ class SystemUser(models.Model):
def has_shell(self):
return self.shell not in settings.SYSTEMUSERS_DISABLED_SHELLS
def disable(self):
self.is_active = False
self.save(update_fields=('is_active',))
def get_description(self):
return self.get_shell_display()

View File

@ -62,7 +62,7 @@ class SystemUserMixin(object):
def validate_user(self, username):
idcmd = sshr(self.MASTER_SERVER, "id %s" % username)
self.assertEqual(0, idcmd.return_code)
self.assertEqual(0, idcmd.exit_code)
user = SystemUser.objects.get(username=username)
groups = list(user.groups.values_list('username', flat=True))
groups.append(user.username)
@ -336,7 +336,7 @@ class AdminSystemUserTest(AdminSystemUserMixin, BaseLiveServerTestCase):
self.assertNotEqual(url, self.selenium.current_url)
self.addCleanup(self.delete_account, account_username)
self.assertEqual(0, sshr(self.MASTER_SERVER, "id %s" % account_username).return_code)
self.assertEqual(0, sshr(self.MASTER_SERVER, "id %s" % account_username).exit_code)
@snapshot_on_error
def test_delete_account(self):

View File

@ -7,6 +7,7 @@ from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin.actions import disable
from orchestra.admin.utils import admin_link, change_url
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
from orchestra.forms.widgets import DynamicHelpTextSelect
@ -68,6 +69,7 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
filter_by_account_fields = ['domains']
list_prefetch_related = ('domains', 'content_set__webapp')
search_fields = ('name', 'account__username', 'domains__name', 'content__webapp__name')
actions = (disable,)
def display_domains(self, website):
domains = []

View File

@ -51,6 +51,10 @@ class Website(models.Model):
def active(self):
return self.is_active and self.account.is_active
def disable(self):
self.is_active = False
self.save(update_fields=('is_active',))
def get_settings_context(self):
""" format settings strings """
return {

View File

@ -195,13 +195,14 @@ class Command(BaseCommand):
processes = %(processes)d
chmod-socket = 664
stats = /run/uwsgi/%%(deb-confnamespace)/%%(deb-confname)/statsocket
vacuum = true
uid = %(user)s
gid = %(group)s
env = HOME=%(home)s
touch-reload = %(project_dir)s/wsgi.py
enable-threads = true
max-requests = 500
vacuum = true # Remove socket stop
enable-threads = true # Initializes the GIL
max-requests = 500 # Mitigates memory leaks
lazy-apps = true # Don't share database connections
"""
) % context
@ -220,11 +221,11 @@ class Command(BaseCommand):
for extra_context in (nginx, uwsgi):
context.update(extra_context)
diff = run("echo '%(conf)s' | diff - %(file)s" % context, error_codes=[0,1,2])
if diff.return_code == 2:
diff = run("echo '%(conf)s' | diff - %(file)s" % context, valid_codes=(0,1,2))
if diff.exit_code == 2:
# File does not exist
run("echo '%(conf)s' > %(file)s" % context, display=True)
elif diff.return_code == 1:
elif diff.exit_code == 1:
# File is different, save the old one
if interactive:
msg = ("\n\nFile %(file)s be updated, do you like to overide "
@ -244,13 +245,13 @@ class Command(BaseCommand):
if server_name:
run('ln -s /etc/nginx/sites-available/%(server_name)s.conf /etc/nginx/sites-enabled/' % context,
error_codes=[0,1], display=True)
valid_codes=[0,1], display=True)
else:
run('rm /etc/nginx/sites-enabled/default')
run('ln -s /etc/nginx/sites-available/%(project_name)s.conf /etc/nginx/sites-enabled/' % context,
error_codes=[0,1], display=True)
valid_codes=[0,1], display=True)
run('ln -s /etc/uwsgi/apps-available/%(project_name)s.ini /etc/uwsgi/apps-enabled/' % context,
error_codes=[0,1], display=True)
valid_codes=[0,1], display=True)
rotate = textwrap.dedent("""\
/var/log/nginx/*.log {

View File

@ -223,7 +223,7 @@ password_query = \
run("chmod go= %(dovecot_dir)s/dovecot-sql.conf.ext" % context)
file_name = "%(postfix_dir)s/master.cf" % context
grep_dovecot = run("grep dovecot %s" % file_name, error_codes=[0,1])
grep_dovecot = run("grep dovecot %s" % file_name, valid_codes=(0,1))
if grep_dovecot == '':
run("#Processing %s" % file_name)
dovecot_master="""
@ -264,8 +264,8 @@ amavis unix - - n - 5 smtp
#Postfix
mailname = run("cat /etc/mailname", error_codes=[0,1])
hostname = run("hostname", error_codes=[0,1])
mailname = run("cat /etc/mailname", vallid_codes=[0,1])
hostname = run("hostname", valid_codes=[0,1])
if mailname != hostname:
file_name = "/etc/mailname"
run("#Processing %s" % file_name)

View File

@ -40,11 +40,11 @@ class Command(BaseCommand):
'db_host': options.get('db_host'),
'db_port': options.get('db_port') }
run('su postgres -c "psql -c \\"CREATE USER %(db_user)s PASSWORD \'%(db_password)s\';\\""' % context, error_codes=[0,1])
run('su postgres -c "psql -c \\"CREATE DATABASE %(db_name)s OWNER %(db_user)s;\\""' % context, error_codes=[0,1])
run('su postgres -c "psql -c \\"CREATE USER %(db_user)s PASSWORD \'%(db_password)s\';\\""' % context, valid_codes=(0,1))
run('su postgres -c "psql -c \\"CREATE DATABASE %(db_name)s OWNER %(db_user)s;\\""' % context, valid_codes=(0,1))
context.update({'settings': os.path.join(get_project_dir(), 'settings.py')})
if run("grep 'DATABASES' %(settings)s" % context, error_codes=[0,1]).return_code == 0:
if run("grep 'DATABASES' %(settings)s" % context, valid_codes=(0,1)).exit_code == 0:
# Update existing settings_file
run("sed -i \"s/'ENGINE': '\w*',/'ENGINE': 'django.db.backends.postgresql_psycopg2',/\" %(settings)s" % context)
run("sed -i \"s/'NAME': '.*',/'NAME': '%(db_name)s',/\" %(settings)s" % context)

View File

@ -11,9 +11,9 @@ def run_tuple(services, action, options, optional=False):
services = [services]
for service in services:
if options.get(service):
error_codes = [0,1] if optional else [0]
e = run('service %s %s' % (service, action), error_codes=error_codes)
if e.return_code == 1:
valid_codes = (0,1) if optional else (0,)
e = run('service %s %s' % (service, action), valid_codes=valid_codes)
if e.exit_code == 1:
return False
return True

View File

@ -17,7 +17,7 @@ r = functools.partial(run, silent=False)
def get_existing_pip_installation():
""" returns current pip installation path """
if run("pip freeze|grep django-orchestra", error_codes=[0,1]).return_code == 0:
if run("pip freeze|grep django-orchestra", valid_codes=(0,1)).exit_code == 0:
for lib_path in get_python_lib(), get_python_lib(prefix="/usr/local"):
existing_path = os.path.abspath(os.path.join(lib_path, "orchestra"))
if os.path.exists(existing_path):

View File

@ -93,16 +93,16 @@ def runiterator(command, display=False, stdin=b''):
state = _Attribute(stdout)
state.stderr = stderr
state.return_code = p.poll()
state.exit_code = p.poll()
state.command = command
yield state
if state.return_code != None:
if state.exit_code != None:
p.stdout.close()
p.stderr.close()
raise StopIteration
def join(iterator, display=False, silent=False, error_codes=[0]):
def join(iterator, display=False, silent=False, valid_codes=(0,)):
""" joins the iterator process """
stdout = b''
stderr = b''
@ -110,18 +110,18 @@ def join(iterator, display=False, silent=False, error_codes=[0]):
stdout += state.stdout
stderr += state.stderr
return_code = state.return_code
exit_code = state.exit_code
out = _Attribute(stdout.strip())
err = stderr.strip()
out.failed = False
out.return_code = return_code
out.exit_code = exit_code
out.stderr = err
if return_code not in error_codes:
if exit_code not in valid_codes:
out.failed = True
msg = "\nrun() encountered an error (return code %s) while executing '%s'\n"
msg = msg % (return_code, state.command)
msg = msg % (exit_code, state.command)
if display:
sys.stderr.write("\n\033[1;31mCommandError: %s %s\033[m\n" % (msg, err))
if not silent:
@ -131,12 +131,12 @@ def join(iterator, display=False, silent=False, error_codes=[0]):
return out
def run(command, display=False, error_codes=[0], silent=False, stdin=b'', async=False):
def run(command, display=False, valid_codes=(0,), silent=False, stdin=b'', async=False):
iterator = runiterator(command, display, stdin)
next(iterator)
if async:
return iterator
return join(iterator, display=display, silent=silent, error_codes=error_codes)
return join(iterator, display=display, silent=silent, valid_codes=valie_codes)
def sshrun(addr, command, *args, **kwargs):