From e3285bef364a675f97b9e4f08c47a45405399561 Mon Sep 17 00:00:00 2001 From: JocelynDelalande Date: Mon, 23 Oct 2017 18:05:50 +0200 Subject: Enhance install process by generating config files from templates (#275) * Add a command to generate configuration examples Config files are generated from templates (which remplace previous example files). - solve the issue of hard-to-explain configuration examples - ease pkg path seeking (avoid it, actually) - add working defaults for sqlite and unix socket paths (instead of /replace/me/path/example) - move settings comments from default_settings.py to ihatemoney.cfg.j2, as it is the one that will be facing user. * Use generate-config command in install doc Also follow the new working defaults of templates for socket and db path. * Fix doc settings table On the long term, plaintext tables might destroy humanity. * Mention templates dir URL in documentation As requested by @almet --- ihatemoney/conf-templates/apache-vhost.conf.j2 | 19 ++++++++++++ ihatemoney/conf-templates/gunicorn.conf.py.j2 | 8 ++++++ ihatemoney/conf-templates/ihatemoney.cfg.j2 | 36 +++++++++++++++++++++++ ihatemoney/conf-templates/nginx.conf.j2 | 28 ++++++++++++++++++ ihatemoney/conf-templates/supervisord.conf.j2 | 6 ++++ ihatemoney/default_settings.py | 31 ++------------------ ihatemoney/manage.py | 40 +++++++++++++++++++++++++- 7 files changed, 138 insertions(+), 30 deletions(-) create mode 100644 ihatemoney/conf-templates/apache-vhost.conf.j2 create mode 100644 ihatemoney/conf-templates/gunicorn.conf.py.j2 create mode 100644 ihatemoney/conf-templates/ihatemoney.cfg.j2 create mode 100644 ihatemoney/conf-templates/nginx.conf.j2 create mode 100644 ihatemoney/conf-templates/supervisord.conf.j2 (limited to 'ihatemoney') diff --git a/ihatemoney/conf-templates/apache-vhost.conf.j2 b/ihatemoney/conf-templates/apache-vhost.conf.j2 new file mode 100644 index 0000000..cb0167f --- /dev/null +++ b/ihatemoney/conf-templates/apache-vhost.conf.j2 @@ -0,0 +1,19 @@ + + ServerAdmin admin@example.com # CUSTOMIZE + ServerName ihatemoney.example.com # CUSTOMIZE + + WSGIDaemonProcess ihatemoney user=www-data group=www-data threads=5 python-path={{ pkg_path }} {% if venv_path %}python-home={{ venv_path }}{% endif %} + WSGIScriptAlias / {{ pkg_path }}/wsgi.py + + ErrorLog /var/log/apache2/ihatemoney.example.com_error.log + CustomLog /var/log/apache2/ihatemoney.example.com_access.log combined + + + WSGIProcessGroup ihatemoney + WSGIApplicationGroup %{GLOBAL} + Order deny,allow + Allow from all + + + Alias /static/ {{ pkg_path }}/static/ + diff --git a/ihatemoney/conf-templates/gunicorn.conf.py.j2 b/ihatemoney/conf-templates/gunicorn.conf.py.j2 new file mode 100644 index 0000000..2c4492d --- /dev/null +++ b/ihatemoney/conf-templates/gunicorn.conf.py.j2 @@ -0,0 +1,8 @@ +backlog = 2048 +daemon = False +debug = True +workers = 3 +# log to stdout, +logfile = "-" # Is the default setting for gunicorn>=20 +loglevel = "info" +bind = "unix:/tmp/ihatemoney.gunicorn.sock" diff --git a/ihatemoney/conf-templates/ihatemoney.cfg.j2 b/ihatemoney/conf-templates/ihatemoney.cfg.j2 new file mode 100644 index 0000000..5dfb9d4 --- /dev/null +++ b/ihatemoney/conf-templates/ihatemoney.cfg.j2 @@ -0,0 +1,36 @@ +# You can find more information about what these settings mean in the +# documentation, available online at +# http://ihatemoney.readthedocs.io/en/latest/installation.html#configuration + +# Turn this on if you want to have more output on what's happening under the +# hood. DO NOT TURN IT ON IN PRODUCTION. +DEBUG = False + +# The database URI, reprensenting the type of database and how to connect to it. +# Enter an absolute path here. +SQLALCHEMY_DATABASE_URI = 'sqlite:///var/lib/ihatemoney/ihatemoney.sqlite' +SQLACHEMY_ECHO = DEBUG + +# Will likely become the default value in flask-sqlalchemy >=3 ; could be removed +# then: +SQLALCHEMY_TRACK_MODIFICATIONS = False + +# This secret key is random and auto-generated, it protects cookies and user sessions +SECRET_KEY = "{{ secret_key }}" + +# A python tuple describing the name and email adress of the sender of the mails. +MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") # CUSTOMIZE + +# If set to True, a demonstration project will be activated. +ACTIVATE_DEMO_PROJECT = True + +# If not empty, the specified password must be entered to create new projects. +# DO NOT enter the password in cleartext. Generate a password hash with +# "ihatemoney generate_password_hash" instead. +ADMIN_PASSWORD = "" + +# If set to True (default value) anyone can create a new project. +ALLOW_PUBLIC_PROJECT_CREATION = True + +# If set to True, an administration dashboard is available. +ACTIVATE_ADMIN_DASHBOARD = False diff --git a/ihatemoney/conf-templates/nginx.conf.j2 b/ihatemoney/conf-templates/nginx.conf.j2 new file mode 100644 index 0000000..42b45fc --- /dev/null +++ b/ihatemoney/conf-templates/nginx.conf.j2 @@ -0,0 +1,28 @@ +server { + server_name ihatemoney.example.com; # CUSTOMIZE + keepalive_timeout 5; + + location /static/ { + alias {{ pkg_path }}/static/; + } + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_redirect off; + proxy_connect_timeout 90; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_buffer_size 16k; + proxy_buffers 8 16k; + proxy_busy_buffers_size 32k; + proxy_intercept_errors on; + if (!-f $request_filename) { + proxy_pass http://ihatemoney_backend; + break; + } + } +} + +upstream ihatemoney_backend { + server unix:/tmp/ihatemoney.gunicorn.sock; +} diff --git a/ihatemoney/conf-templates/supervisord.conf.j2 b/ihatemoney/conf-templates/supervisord.conf.j2 new file mode 100644 index 0000000..fa16c0c --- /dev/null +++ b/ihatemoney/conf-templates/supervisord.conf.j2 @@ -0,0 +1,6 @@ +[program:ihatemoney] +command={{ venv_path }}/bin/gunicorn -c /etc/ihatemoney/gunicorn.conf.py ihatemoney.wsgi:application +user=ihatemoney +autostart=true +autorestart=true +redirect_stderr=true diff --git a/ihatemoney/default_settings.py b/ihatemoney/default_settings.py index c7ce297..6033d0a 100644 --- a/ihatemoney/default_settings.py +++ b/ihatemoney/default_settings.py @@ -1,37 +1,10 @@ -# You can find more information about what these settings mean in the -# documentation, available online at -# http://ihatemoney.readthedocs.io/en/latest/installation.html#configuration - -# Turn this on if you want to have more output on what's happening under the -# hood. -DEBUG = False - -# The database URI, reprensenting the type of database and how to connect to it. -# Enter an absolute path here. +# Verbose and documented settings are in conf-templates/ihatemoney.cfg.j2 +DEBUG = SQLACHEMY_ECHO = False SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/ihatemoney.db' -SQLACHEMY_ECHO = DEBUG - -# Will likely become the default value in flask-sqlalchemy >=3 ; could be removed -# then: SQLALCHEMY_TRACK_MODIFICATIONS = False - -# You need to change this secret key, otherwise bad things might happen to your -# users. SECRET_KEY = "tralala" - -# A python tuple describing the name and email adress of the sender of the mails. MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") - -# If set to True, a demonstration project will be activated. ACTIVATE_DEMO_PROJECT = True - -# If not empty, the specified password must be entered to create new projects. -# DO NOT enter the password in cleartext. Generate a password hash with -# "ihatemoney generate_password_hash" instead. ADMIN_PASSWORD = "" - -# If set to True (default value) anyone can create a new project. ALLOW_PUBLIC_PROJECT_CREATION = True - -# If set to True, an administration dashboard is available. ACTIVATE_ADMIN_DASHBOARD = False diff --git a/ihatemoney/manage.py b/ihatemoney/manage.py index 6f63a98..c1821c5 100755 --- a/ihatemoney/manage.py +++ b/ihatemoney/manage.py @@ -1,8 +1,13 @@ #!/usr/bin/env python +import os +import pkgutil +import random from getpass import getpass -from flask_script import Manager, Command + +from flask_script import Manager, Command, Option from flask_migrate import Migrate, MigrateCommand +from jinja2 import Template from werkzeug.security import generate_password_hash from ihatemoney.run import create_app @@ -18,6 +23,38 @@ class GeneratePasswordHash(Command): print(generate_password_hash(password)) +class ConfigTemplate(Command): + def get_options(self): + return [ + Option('config_file', choices=[ + 'ihatemoney.cfg', + 'apache-vhost.conf', + 'gunicorn.conf.py', + 'supervisord.conf', + 'nginx.conf', + ]), + ] + + @staticmethod + def gen_secret_key(): + return ''.join([ + random.SystemRandom().choice( + 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') + for i in range(50)]) + + def run(self, config_file): + template_content = pkgutil.get_data( + 'ihatemoney', + os.path.join('conf-templates/', config_file) + '.j2' + ).decode('utf-8') + + print(Template(template_content).render( + pkg_path=os.path.abspath(os.path.dirname(__file__)), + venv_path=os.environ.get('VIRTUAL_ENV'), + secret_key=self.gen_secret_key(), + )) + + def main(): app = create_app() Migrate(app, db) @@ -25,6 +62,7 @@ def main(): manager = Manager(app) manager.add_command('db', MigrateCommand) manager.add_command('generate_password_hash', GeneratePasswordHash) + manager.add_command('generate-config', ConfigTemplate) manager.run() -- cgit v1.1