From e4074ccaddc2f2843228f92072c92e1825ae6327 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Mon, 23 Oct 2017 09:49:08 +0200 Subject: [PATCH] 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. --- CHANGELOG.rst | 1 + conf/apache-vhost.conf | 18 --------- conf/gunicorn.conf.py | 7 ---- conf/supervisord.conf | 6 --- .../conf-templates/apache-vhost.conf.j2 | 19 +++++++++ ihatemoney/conf-templates/gunicorn.conf.py.j2 | 8 ++++ ihatemoney/conf-templates/ihatemoney.cfg.j2 | 36 +++++++++++++++++ .../conf-templates/nginx.conf.j2 | 8 ++-- ihatemoney/conf-templates/supervisord.conf.j2 | 6 +++ ihatemoney/default_settings.py | 31 +------------- ihatemoney/manage.py | 40 ++++++++++++++++++- 11 files changed, 114 insertions(+), 66 deletions(-) delete mode 100644 conf/apache-vhost.conf delete mode 100644 conf/gunicorn.conf.py delete mode 100644 conf/supervisord.conf 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 rename conf/nginx.conf => ihatemoney/conf-templates/nginx.conf.j2 (67%) create mode 100644 ihatemoney/conf-templates/supervisord.conf.j2 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a7430779..4eb8c811 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,6 +21,7 @@ Changed Added ===== +- ``ihatemoney generate-config`` to give working examples of config files (#275) - Statistics tab (#257) - Python3.6 support (#259) - ALLOW_PUBLIC_PROJECT_CREATION setting (#262) diff --git a/conf/apache-vhost.conf b/conf/apache-vhost.conf deleted file mode 100644 index 1a84e7f7..00000000 --- a/conf/apache-vhost.conf +++ /dev/null @@ -1,18 +0,0 @@ - - ServerAdmin admin@example.com - ServerName ihatemoney.example.com - # Uncomment the python-home option if you use a virtualenv - WSGIDaemonProcess ihatemoney user=www-data group=www-data threads=5 python-path=/path/to/ihatemoney/ihatemoney # python-home=/path/to/your/venv - WSGIScriptAlias / /path/to/ihatemoney/ihatemoney/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 value may be some messy path, within python libs. -# You may want to use "find $VIRTUAL_ENV -path */ihatemoney*/static" to find it. -Alias /static/ /path/to/ihatemoney/ihatemoney/static/ - diff --git a/conf/gunicorn.conf.py b/conf/gunicorn.conf.py deleted file mode 100644 index 017a6709..00000000 --- a/conf/gunicorn.conf.py +++ /dev/null @@ -1,7 +0,0 @@ -backlog = 2048 -daemon = False -debug = True -workers = 3 -logfile = "/path/to/your/app/ihatemoney.gunicorn.log" -loglevel = "info" -bind = "unix:/path/to/your/app/ihatemoney.gunicorn.sock" diff --git a/conf/supervisord.conf b/conf/supervisord.conf deleted file mode 100644 index 8d3ac70e..00000000 --- a/conf/supervisord.conf +++ /dev/null @@ -1,6 +0,0 @@ -[program:ihatemoney] -command=/path/to/your/app/venv/bin/gunicorn -c /etc/ihatemoney/gunicorn.conf.py ihatemoney.wsgi:application -user=www -autostart=true -autorestart=true -redirect_stderr=True diff --git a/ihatemoney/conf-templates/apache-vhost.conf.j2 b/ihatemoney/conf-templates/apache-vhost.conf.j2 new file mode 100644 index 00000000..cb0167f5 --- /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 00000000..2c4492de --- /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 00000000..5dfb9d47 --- /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/conf/nginx.conf b/ihatemoney/conf-templates/nginx.conf.j2 similarity index 67% rename from conf/nginx.conf rename to ihatemoney/conf-templates/nginx.conf.j2 index 0fe26f02..42b45fc0 100644 --- a/conf/nginx.conf +++ b/ihatemoney/conf-templates/nginx.conf.j2 @@ -1,11 +1,9 @@ server { - server_name yourur; + server_name ihatemoney.example.com; # CUSTOMIZE keepalive_timeout 5; location /static/ { - # Alias value may be some messy path, within python libs. - # You may want to use "find $VIRTUAL_ENV -path */ihatemoney*/static" to find it. - alias /path/to/app/ihatemoney/static/; + alias {{ pkg_path }}/static/; } location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -26,5 +24,5 @@ server { } upstream ihatemoney_backend { - server unix:/path/to/app/ihatemoney.gunicorn.sock; + 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 00000000..fa16c0cf --- /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 c7ce2973..6033d0ab 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 6f63a98c..c1821c59 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()