From 18ac8e3e6080bf6aa5e43bdc4f3cde85601ac9ae Mon Sep 17 00:00:00 2001 From: Marc Aymerich Date: Fri, 2 Oct 2015 09:31:32 +0000 Subject: [PATCH] Fixes on deployment --- TODO.md | 9 ++ orchestra/bin/orchestra-admin | 2 +- orchestra/conf/project_template/manage.py | 4 +- orchestra/contrib/saas/services/phplist.py | 3 +- .../management/commands/setuppostgres.py | 91 ++++++++++++++----- scripts/containers/deploy.sh | 3 - 6 files changed, 81 insertions(+), 31 deletions(-) diff --git a/TODO.md b/TODO.md index a4f19153..05fc5899 100644 --- a/TODO.md +++ b/TODO.md @@ -413,3 +413,12 @@ http://makandracards.com/makandra/24933-chrome-34+-firefox-38+-ie11+-ignore-auto mkhomedir_helper or create ssh homes with bash.rc and such + +# validate saas setting allow_custom_url check that websites have a related declared directive +# warnings if some plugins are disabled, like make routes red + +# replace cached by https://docs.python.org/3/library/functools.html#functools.lru_cache +# replace IPy by https://docs.python.org/3/library/ipaddress.html#module-ipaddress +# replace show emails by https://docs.python.org/3/library/email.contentmanager.html#module-email.contentmanager +# https://docs.python.org/3/library/functools.html#functools.cmp_to_key +# tzinfo=datetime.timezone.utc diff --git a/orchestra/bin/orchestra-admin b/orchestra/bin/orchestra-admin index bbcf2b6f..f899581f 100755 --- a/orchestra/bin/orchestra-admin +++ b/orchestra/bin/orchestra-admin @@ -20,7 +20,7 @@ function help () { function print_help () { - cat <<- EOF + cat <<- EOF ${bold}NAME${normal} ${bold}orchestra-admin${normal} - Orchetsra administration script diff --git a/orchestra/conf/project_template/manage.py b/orchestra/conf/project_template/manage.py index e0bfc980..ee4b9652 100755 --- a/orchestra/conf/project_template/manage.py +++ b/orchestra/conf/project_template/manage.py @@ -4,9 +4,9 @@ import sys if __name__ == "__main__": - if sys.version_info < (3, 4): + if sys.version_info < (3, 3): cmd = ' '.join(sys.argv) - sys.stderr.write("Sorry, you need at least Python 3.4, try with:\n$ python3 %s\n" % cmd) + sys.stderr.write("Sorry, Orchestra requires at least Python 3.3, try with:\n$ python3 %s\n" % cmd) sys.exit(1) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") from django.core.management import execute_from_command_line diff --git a/orchestra/contrib/saas/services/phplist.py b/orchestra/contrib/saas/services/phplist.py index 39116278..c7aa0524 100644 --- a/orchestra/contrib/saas/services/phplist.py +++ b/orchestra/contrib/saas/services/phplist.py @@ -116,5 +116,4 @@ class PHPListService(DBSoftwareService): mailbox_name = self.instance.data.get('mailbox_name') or self.get_mailbox_name() mailbox_id = self.instance.data.get('mailbox_id') qs = Q(Q(name=mailbox_name) | Q(id=mailbox_id)) - for mailbox in account.mailboxes.filter(qs): - mailbox.delete() + account.mailboxes.filter(qs).delete() diff --git a/orchestra/management/commands/setuppostgres.py b/orchestra/management/commands/setuppostgres.py index 176915d4..6cca8264 100644 --- a/orchestra/management/commands/setuppostgres.py +++ b/orchestra/management/commands/setuppostgres.py @@ -2,25 +2,41 @@ import os import textwrap from optparse import make_option +from django.conf import settings from django.core.management.base import BaseCommand from orchestra.utils.paths import get_project_dir +from orchestra.utils.python import random_ascii from orchestra.utils.sys import run, check_root class Command(BaseCommand): def __init__(self, *args, **kwargs): super(Command, self).__init__(*args, **kwargs) + # Get defaults from settings, if exists + try: + defaults = settings.DATABASES['default'] + except (AttributeError, KeyError): + defaults = {} + else: + if defaults['ENGINE'] != 'django.db.backends.postgresql_psycopg2': + defaults = {} + self.option_list = BaseCommand.option_list + ( - make_option('--db_name', dest='db_name', default='orchestra', + make_option('--db_name', dest='db_name', + default=defaults.get('DB_NAME', 'orchestra'), help='Specifies the database to create.'), - make_option('--db_user', dest='db_user', default='orchestra', + make_option('--db_user', dest='db_user', + default=defaults.get('DB_USER', 'orchestra'), help='Specifies the database to create.'), - make_option('--db_password', dest='db_password', default='orchestra', + make_option('--db_password', dest='db_password', + default=defaults.get('PASSWORD'), + help='Specifies the database password, random if not specified.'), + make_option('--db_host', dest='db_host', + default=defaults.get('HOST', 'localhost'), help='Specifies the database to create.'), - make_option('--db_host', dest='db_host', default='localhost', - help='Specifies the database to create.'), - make_option('--db_port', dest='db_port', default='5432', + make_option('--db_port', dest='db_port', + default=defaults.get('PORT', '5432'), help='Specifies the database to create.'), make_option('--noinput', action='store_false', dest='interactive', default=True, help='Tells Django to NOT prompt the user for input of any kind. ' @@ -31,37 +47,64 @@ class Command(BaseCommand): option_list = BaseCommand.option_list help = 'Setup PostgreSQL database.' + def run_postgres(self, cmd, *args, **kwargs): + cmd = cmd.replace("'", "\\'") + return run('su postgres -c "psql -c \\"%s\\""' % cmd, *args, **kwargs) + + def run_postgres2(self, cmd, *args, **kwargs): + return run('echo su postgres -c "psql -c \\"%s\\""' % cmd, *args, **kwargs) + @check_root def handle(self, *args, **options): - # Configure firmware generation + interactive = options.get('interactive') + db_password = options.get('db_password') context = { 'db_name': options.get('db_name'), 'db_user': options.get('db_user'), - 'db_password': options.get('db_password'), + 'db_password': db_password, 'db_host': options.get('db_host'), 'db_port': options.get('db_port'), + 'default_db_password': db_password or random_ascii(10), } - run(textwrap.dedent("""\ - su postgres -c "psql -c \\"CREATE USER %(db_user)s PASSWORD '%(db_password)s';\\"" || { - su postgres -c "psql -c \\"ALTER USER %(db_user)s WITH PASSWORD '%(db_password)s';\\"" - } - su postgres -c "psql -c \\"CREATE DATABASE %(db_name)s OWNER %(db_user)s;\\""\ - """) % context, valid_codes=(0,1) - ) + create_user = "CREATE USER %(db_user)s PASSWORD '%(db_password)s';" + alter_user = "ALTER USER %(db_user)s WITH PASSWORD '%(db_password)s';" + create_database = "CREATE DATABASE %(db_name)s OWNER %(db_user)s;" + + # Create or update user + if self.run_postgres(create_user % context, valid_codes=(0,1)).exit_code == 1: + if interactive and not options.get('db_password'): + msg = ("Postgres user '%(db_user)s' already exists, " + "please provide a password [%(default_db_password)s]: " % context) + context['db_password'] = input(msg) or context['default_db_password'] + self.run_postgres2(alter_user % context) + elif options.get('db_password'): + self.run_postgres2(alter_user % context) + else: + raise CommandError("Postgres user '%(db_user)s' already exists and " + "--db_pass has not been provided." % context) + self.run_postgres2(create_database % context) + +# run(textwrap.dedent("""\ +# su postgres -c "psql -c \\"CREATE USER %(db_user)s PASSWORD '%(db_password)s';\\"" || { +# su postgres -c "psql -c \\"ALTER USER %(db_user)s WITH PASSWORD '%(db_password)s';\\"" +# } +# 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\s*=\s*{' %(settings)s" % context, valid_codes=(0,1)).exit_code == 0: # Update existing settings_file - run(textwrap.dedent("""\ - sed -i "s/'ENGINE':[^#]*/'ENGINE': 'django.db.backends.postgresql_psycopg2',/" %(settings)s - sed -i "s/'NAME':[^#]*/'NAME': '%(db_name)s',/" %(settings)s - sed -i "s/'USER':[^#]*/'USER': '%(db_user)s',/" %(settings)s - sed -i "s/'PASSWORD':[^#]*/'PASSWORD': '%(db_password)s',/" %(settings)s - sed -i "s/'HOST':[^#]*/'HOST': '%(db_host)s',/" %(settings)s - sed -i "s/'PORT':[^#]*/'PORT': '%(db_port)s',/" %(settings)s\ + run(textwrap.dedent("""sed -i \\ + -e "s/'ENGINE':[^#]*/'ENGINE': 'django.db.backends.postgresql_psycopg2', /" \\ + -e "s/'NAME':[^#]*/'NAME': '%(db_name)s', /" \\ + -e "s/'USER':[^#]*/'USER': '%(db_user)s', /" \\ + -e "s/'PASSWORD':[^#]*/'PASSWORD': '%(db_password)s', /" \\ + -e "s/'HOST':[^#]*/'HOST': '%(db_host)s', /" \\ + -e "s/'PORT':[^#]*/'PORT': '%(db_port)s', /" %(settings)s\ """) % context ) else: @@ -77,5 +120,7 @@ class Command(BaseCommand): 'ATOMIC_REQUESTS': True, } }""") % context - context.update({'db_config': db_config}) + context.update({ + 'db_config': db_config + }) run('echo "%(db_config)s" >> %(settings)s' % context) diff --git a/scripts/containers/deploy.sh b/scripts/containers/deploy.sh index 298816a4..d66b0c72 100644 --- a/scripts/containers/deploy.sh +++ b/scripts/containers/deploy.sh @@ -36,11 +36,8 @@ function main () { fi done - # TODO Password: Password (again): # TODO detect if already installed and don't ask stupid question # TODO setupceleryd shoudl change orchestra_start/stop/restart_services - # TODO setuppostgres should configure the fucking backend - read -p "Enter a new database password: " db_password while true; do read -p "Do you want to use celery or cronbeat for task execution [cronbeat]? " task