changeset 597:79a31a3c947b

admin: Better production config for FoodTruck, provide proper first site. * Use a `settings` object to configure Flask. * Accept an `app.cfg` file in the admin folder to configure Flask. * Get a proper first site name when the cookie isn't set yet.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 20 Jan 2016 21:39:18 -0800
parents e2c91ba44d6c
children 3cec8634209a
files foodtruck/config.py foodtruck/settings.py foodtruck/views/baking.py foodtruck/web.py foodtruck/wsgiutil.py piecrust/commands/builtin/admin.py
diffstat 5 files changed, 65 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/foodtruck/config.py	Wed Jan 20 21:36:51 2016 -0800
+++ b/foodtruck/config.py	Wed Jan 20 21:39:18 2016 -0800
@@ -10,8 +10,9 @@
 logger = logging.getLogger(__name__)
 
 
-def get_foodtruck_config():
-    cfg_path = os.path.join(os.getcwd(), 'foodtruck.yml')
+def get_foodtruck_config(dirname=None):
+    dirname = dirname or os.getcwd()
+    cfg_path = os.path.join(dirname, 'foodtruck.yml')
     return FoodTruckConfiguration(cfg_path)
 
 
--- a/foodtruck/views/baking.py	Wed Jan 20 21:36:51 2016 -0800
+++ b/foodtruck/views/baking.py	Wed Jan 20 21:39:18 2016 -0800
@@ -24,9 +24,10 @@
     raise KeyboardInterrupt()
 
 
-# Make sure CTRL+C works correctly.
-signal.signal(signal.SIGINT,
-              lambda *args: _shutdown_server_and_raise_sigint())
+if app.config['FOODTRUCK_CMDLINE_MODE']:
+    # Make sure CTRL+C works correctly.
+    signal.signal(signal.SIGINT,
+                  lambda *args: _shutdown_server_and_raise_sigint())
 
 
 class _BakeLogReader(object):
--- a/foodtruck/web.py	Wed Jan 20 21:36:51 2016 -0800
+++ b/foodtruck/web.py	Wed Jan 20 21:39:18 2016 -0800
@@ -1,3 +1,5 @@
+import os
+import os.path
 import logging
 from flask import Flask, g, request, render_template
 from .config import (
@@ -8,10 +10,19 @@
 logger = logging.getLogger(__name__)
 
 app = Flask(__name__)
+app.config.from_object('foodtruck.settings')
+app.config.from_envvar('FOODTRUCK_SETTINGS', silent=True)
 
-c = get_foodtruck_config()
-app.secret_key = c.get('foodtruck/secret_key')
-del c
+admin_root = app.config['FOODTRUCK_ROOT'] or os.getcwd()
+config_path = os.path.join(admin_root, 'app.cfg')
+if os.path.isfile(config_path):
+    app.config.from_pyfile(config_path)
+
+if app.config['DEBUG']:
+    l = logging.getLogger()
+    l.setLevel(logging.DEBUG)
+
+app.logger.debug("Using FoodTruck admin root: %s" % admin_root)
 
 
 def after_this_request(f):
@@ -36,11 +47,20 @@
 
 @app.before_request
 def _setup_foodtruck_globals():
+    def _get_config():
+        return get_foodtruck_config(admin_root)
+
     def _get_sites():
-        s = FoodTruckSites(g.config,
-                           request.cookies.get('foodtruck_site_name'))
+        current = request.cookies.get('foodtruck_site_name')
+        if current is None:
+            names = g.config.get('sites')
+            if not names or not isinstance(names, dict):
+                raise FoodTruckConfigNotFoundError()
+            current = next(iter(names.keys()))
+        s = FoodTruckSites(g.config, current)
         return s
-    g.config = LazySomething(get_foodtruck_config)
+
+    g.config = LazySomething(_get_config)
     g.sites = LazySomething(_get_sites)
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foodtruck/wsgiutil.py	Wed Jan 20 21:39:18 2016 -0800
@@ -0,0 +1,23 @@
+import logging
+
+
+logger = logging.getLogger()
+
+
+def get_wsgi_app(admin_root=None, log_file=None,
+                 max_log_bytes=4096, log_backup_count=0,
+                 log_level=logging.INFO):
+    if log_file:
+        from logging.handlers import RotatingFileHandler
+        handler = RotatingFileHandler(log_file, maxBytes=max_log_bytes,
+                                      backupCount=log_backup_count)
+        handler.setLevel(log_level)
+        logging.getLogger().addHandler(handler)
+
+    logger.debug("Creating WSGI application.")
+    if admin_root:
+        import foodtruck.settings
+        foodtruck.settings.FOODTRUCK_ROOT = admin_root
+    from foodtruck.web import app
+    return app
+
--- a/piecrust/commands/builtin/admin.py	Wed Jan 20 21:36:51 2016 -0800
+++ b/piecrust/commands/builtin/admin.py	Wed Jan 20 21:39:18 2016 -0800
@@ -39,6 +39,8 @@
         return ctx.args.sub_func(ctx)
 
     def _runFoodTruck(self, ctx):
+        from foodtruck import settings
+        settings.FOODTRUCK_CMDLINE_MODE = True
         from foodtruck.main import run_foodtruck
         run_foodtruck(debug=ctx.args.debug)
 
@@ -61,21 +63,25 @@
             admin_password = hashpw
 
         ft_config = """
-foodtruck:
-    secret_key: %(secret_key)s
 security:
     username: %(username)s
     # You can generate another hashed password with `chef admin genpass`.
     password: %(password)s
 """
         ft_config = ft_config % {
-                'secret_key': secret_key,
                 'username': admin_username,
                 'password': admin_password
                 }
         with open('foodtruck.yml', 'w', encoding='utf8') as fp:
             fp.write(ft_config)
 
+        flask_config = """
+secret_key = '%(secret_key)s'
+"""
+        flask_config = flask_config % {'secret_key': secret_key}
+        with open('app.cfg', 'w', encoding='utf8') as fp:
+            fp.write(flask_config)
+
     def _generatePassword(self, ctx):
         import bcrypt
         binpw = ctx.args.password.encode('utf8')