Brings sanity to the passing of the config variable around the various submodules for use in the ZKConnection decorator.
134 lines
5.4 KiB
Python
Executable File
134 lines
5.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Daemon.py - PVC HTTP API daemon
|
|
# Part of the Parallel Virtual Cluster (PVC) system
|
|
#
|
|
# Copyright (C) 2018-2021 Joshua M. Boniface <joshua@boniface.me>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, version 3.
|
|
#
|
|
# 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 General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
#
|
|
###############################################################################
|
|
|
|
import os
|
|
import yaml
|
|
|
|
from distutils.util import strtobool as dustrtobool
|
|
|
|
# Version string for startup output
|
|
version = '0.9.18'
|
|
|
|
|
|
##########################################################
|
|
# Helper Functions
|
|
##########################################################
|
|
|
|
def strtobool(stringv):
|
|
if stringv is None:
|
|
return False
|
|
if isinstance(stringv, bool):
|
|
return bool(stringv)
|
|
try:
|
|
return bool(dustrtobool(stringv))
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
##########################################################
|
|
# Configuration Parsing
|
|
##########################################################
|
|
|
|
# Parse the configuration file
|
|
try:
|
|
pvcapid_config_file = os.environ['PVC_CONFIG_FILE']
|
|
except Exception:
|
|
print('Error: The "PVC_CONFIG_FILE" environment variable must be set before starting pvcapid.')
|
|
exit(1)
|
|
|
|
print('Loading configuration from file "{}"'.format(pvcapid_config_file))
|
|
|
|
# Read in the config
|
|
try:
|
|
with open(pvcapid_config_file, 'r') as cfgfile:
|
|
o_config = yaml.load(cfgfile, Loader=yaml.BaseLoader)
|
|
except Exception as e:
|
|
print('ERROR: Failed to parse configuration file: {}'.format(e))
|
|
exit(1)
|
|
|
|
try:
|
|
# Create the config object
|
|
config = {
|
|
'debug': strtobool(o_config['pvc']['debug']),
|
|
'coordinators': o_config['pvc']['coordinators'],
|
|
'listen_address': o_config['pvc']['api']['listen_address'],
|
|
'listen_port': int(o_config['pvc']['api']['listen_port']),
|
|
'auth_enabled': strtobool(o_config['pvc']['api']['authentication']['enabled']),
|
|
'auth_secret_key': o_config['pvc']['api']['authentication']['secret_key'],
|
|
'auth_tokens': o_config['pvc']['api']['authentication']['tokens'],
|
|
'ssl_enabled': strtobool(o_config['pvc']['api']['ssl']['enabled']),
|
|
'ssl_key_file': o_config['pvc']['api']['ssl']['key_file'],
|
|
'ssl_cert_file': o_config['pvc']['api']['ssl']['cert_file'],
|
|
'database_host': o_config['pvc']['provisioner']['database']['host'],
|
|
'database_port': int(o_config['pvc']['provisioner']['database']['port']),
|
|
'database_name': o_config['pvc']['provisioner']['database']['name'],
|
|
'database_user': o_config['pvc']['provisioner']['database']['user'],
|
|
'database_password': o_config['pvc']['provisioner']['database']['pass'],
|
|
'queue_host': o_config['pvc']['provisioner']['queue']['host'],
|
|
'queue_port': o_config['pvc']['provisioner']['queue']['port'],
|
|
'queue_path': o_config['pvc']['provisioner']['queue']['path'],
|
|
'storage_hosts': o_config['pvc']['provisioner']['ceph_cluster']['storage_hosts'],
|
|
'storage_domain': o_config['pvc']['provisioner']['ceph_cluster']['storage_domain'],
|
|
'ceph_monitor_port': o_config['pvc']['provisioner']['ceph_cluster']['ceph_monitor_port'],
|
|
'ceph_storage_secret_uuid': o_config['pvc']['provisioner']['ceph_cluster']['ceph_storage_secret_uuid']
|
|
}
|
|
|
|
# Use coordinators as storage hosts if not explicitly specified
|
|
if not config['storage_hosts']:
|
|
config['storage_hosts'] = config['coordinators']
|
|
|
|
except Exception as e:
|
|
print('ERROR: Failed to load configuration: {}'.format(e))
|
|
exit(1)
|
|
|
|
|
|
##########################################################
|
|
# Entrypoint
|
|
##########################################################
|
|
|
|
import pvcapid.flaskapi as pvc_api # noqa: E402
|
|
|
|
if config['ssl_enabled']:
|
|
context = (config['ssl_cert_file'], config['ssl_key_file'])
|
|
else:
|
|
context = None
|
|
|
|
# Print our startup messages
|
|
print('')
|
|
print('|--------------------------------------------------|')
|
|
print('| ######## ## ## ###### |')
|
|
print('| ## ## ## ## ## ## |')
|
|
print('| ## ## ## ## ## |')
|
|
print('| ######## ## ## ## |')
|
|
print('| ## ## ## ## |')
|
|
print('| ## ## ## ## ## |')
|
|
print('| ## ### ###### |')
|
|
print('|--------------------------------------------------|')
|
|
print('| Parallel Virtual Cluster API daemon v{0: <11} |'.format(version))
|
|
print('| API version: v{0: <34} |'.format(pvc_api.API_VERSION))
|
|
print('| Listen: {0: <40} |'.format('{}:{}'.format(config['listen_address'], config['listen_port'])))
|
|
print('| SSL: {0: <43} |'.format(str(config['ssl_enabled'])))
|
|
print('| Authentication: {0: <32} |'.format(str(config['auth_enabled'])))
|
|
print('|--------------------------------------------------|')
|
|
print('')
|
|
|
|
pvc_api.app.run(config['listen_address'], config['listen_port'], threaded=True, ssl_context=context)
|