#!/usr/bin/python3 # Copyright (C) 2018-2019 Lars Wirzenius # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import logging import logging.handlers import os import sys import apifw import slog import yaml import ick2 transactions = slog.Counter() def counter(): return 'HTTP transaction {}'.format(transactions.increment()) def dict_logger(log, stack_info=None): ick2.log.log(exc_info=stack_info, **log) default_config = { 'token-public-key': None, 'token-audience': None, 'token-issuer': None, 'log': [], 'blobdir': None, } def load_config(filename, defconf): conf = yaml.safe_load(open(filename, 'r')) actual_config = dict(defconf) actual_config.update(conf) return actual_config def check_config(config, musthave): for key in config: if key not in musthave: raise Exception('Config %s is not known' % key) for key in musthave: if config.get(key) is None: raise Exception('Config %s must not be None' % key) def main(): logger = logging.getLogger() logger.setLevel(logging.DEBUG) handler = logging.StreamHandler(sys.stderr) logger.addHandler(handler) logging.info('Starting artifact store main program') try: name = 'ARTIFACT_STORE_CONFIG' config_filename = os.environ.get(name) logging.info('config filename %r', config_filename) if not config_filename: msg = 'No %s defined in environment' % name logging.error(msg) raise Exception(msg) logging.info('reading config from %r', config_filename) config = load_config(config_filename, default_config) logging.info('config is %r', config) ick2.setup_logging(config) check_config(config, default_config) ick2.log.log('info', msg_text='Artifact store starts', config=config) api = ick2.BlobAPI() ick2.log.log('info', msg_text='created BlobAPI') api.set_blob_directory(config['blobdir']) ick2.log.log('info', msg_text='called BlobAPI.set_blob_directory') application = apifw.create_bottle_application( api, counter, dict_logger, config) ick2.log.log('info', msg_text='called apifw.create_bottle_application') return application except SystemExit: raise except BaseException as e: logging.error(str(e)) ick2.log.log( 'error', msg_text='Uncaught exception', exception=str(e), exc_info=True) sys.exit(1) app = main() # If we are running this program directly with Python, and not via # gunicorn, we can use the Bottle built-in debug server, which can # make some things easier to debug. if __name__ == '__main__': print('running in debug mode') app.run(host='127.0.0.1', port=5555)