2018-11-13 21:55:59 +01:00
|
|
|
"""WordOps main application entry point."""
|
2019-09-05 11:47:04 +02:00
|
|
|
import sys
|
2019-11-11 19:06:11 +01:00
|
|
|
from os import geteuid
|
2019-09-05 11:47:04 +02:00
|
|
|
|
|
|
|
|
from cement.core.exc import CaughtSignal, FrameworkError
|
2019-09-23 15:43:23 +02:00
|
|
|
from cement.core.foundation import CementApp
|
2019-03-14 13:11:54 +01:00
|
|
|
from cement.ext.ext_argparse import ArgParseArgumentHandler
|
2019-09-05 11:47:04 +02:00
|
|
|
from cement.utils.misc import init_defaults
|
|
|
|
|
|
|
|
|
|
from wo.core import exc
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
# Application default. Should update config/wo.conf to reflect any
|
|
|
|
|
# changes, or additions here.
|
|
|
|
|
defaults = init_defaults('wo')
|
|
|
|
|
|
|
|
|
|
# All internal/external plugin configurations are loaded from here
|
|
|
|
|
defaults['wo']['plugin_config_dir'] = '/etc/wo/plugins.d'
|
|
|
|
|
|
|
|
|
|
# External plugins (generally, do not ship with application code)
|
|
|
|
|
defaults['wo']['plugin_dir'] = '/var/lib/wo/plugins'
|
|
|
|
|
|
|
|
|
|
# External templates (generally, do not ship with application code)
|
|
|
|
|
defaults['wo']['template_dir'] = '/var/lib/wo/templates'
|
|
|
|
|
|
|
|
|
|
|
2019-11-11 19:06:11 +01:00
|
|
|
def encode_output(app, text):
|
|
|
|
|
""" Encode the output to be suitable for the terminal
|
|
|
|
|
|
|
|
|
|
:param app: The Cement App (unused)
|
|
|
|
|
:param text: The rendered text
|
|
|
|
|
:return: The encoded text
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
return text.encode("utf-8")
|
|
|
|
|
|
|
|
|
|
|
2018-11-13 21:55:59 +01:00
|
|
|
class WOArgHandler(ArgParseArgumentHandler):
|
|
|
|
|
class Meta:
|
|
|
|
|
label = 'wo_args_handler'
|
|
|
|
|
|
|
|
|
|
def error(self, message):
|
|
|
|
|
super(WOArgHandler, self).error("unknown args")
|
|
|
|
|
|
|
|
|
|
|
2019-09-15 14:54:48 +02:00
|
|
|
class WOApp(CementApp):
|
2018-11-13 21:55:59 +01:00
|
|
|
class Meta:
|
|
|
|
|
label = 'wo'
|
|
|
|
|
|
|
|
|
|
config_defaults = defaults
|
|
|
|
|
|
|
|
|
|
# All built-in application bootstrapping (always run)
|
|
|
|
|
bootstrap = 'wo.cli.bootstrap'
|
|
|
|
|
|
2019-11-03 23:07:24 +01:00
|
|
|
# Internal plugins (ship with application code)
|
2018-11-13 21:55:59 +01:00
|
|
|
plugin_bootstrap = 'wo.cli.plugins'
|
|
|
|
|
|
|
|
|
|
# Internal templates (ship with application code)
|
|
|
|
|
template_module = 'wo.cli.templates'
|
|
|
|
|
|
2019-12-03 19:48:18 +01:00
|
|
|
extensions = ['mustache', 'argcomplete', 'colorlog']
|
2018-11-13 21:55:59 +01:00
|
|
|
|
2019-11-11 19:06:11 +01:00
|
|
|
hooks = [
|
|
|
|
|
("post_render", encode_output)
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
output_handler = 'mustache'
|
2018-11-13 21:55:59 +01:00
|
|
|
|
2019-12-03 19:48:18 +01:00
|
|
|
log_handler = 'colorlog'
|
2018-11-13 21:55:59 +01:00
|
|
|
|
2019-12-03 19:48:18 +01:00
|
|
|
arg_handler = WOArgHandler
|
2019-08-18 00:00:52 +02:00
|
|
|
exit_on_close = True
|
|
|
|
|
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
class WOTestApp(WOApp):
|
|
|
|
|
"""A test app that is better suited for testing."""
|
|
|
|
|
class Meta:
|
2019-11-03 23:07:24 +01:00
|
|
|
# default argv to empty (don't use sys.argv)
|
2018-11-13 21:55:59 +01:00
|
|
|
argv = []
|
2019-11-03 23:07:24 +01:00
|
|
|
|
|
|
|
|
# don't look for config files (could break tests)
|
2018-11-13 21:55:59 +01:00
|
|
|
config_files = []
|
2019-11-03 23:07:24 +01:00
|
|
|
|
|
|
|
|
# don't call sys.exit() when app.close() is called in tests
|
|
|
|
|
exit_on_close = False
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
# Define the applicaiton object outside of main, as some libraries might wish
|
|
|
|
|
# to import it as a global (rather than passing it into another class/func)
|
2019-11-03 23:07:24 +01:00
|
|
|
app = WOApp()
|
2019-09-15 14:54:48 +02:00
|
|
|
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
def main():
|
2019-11-03 23:07:24 +01:00
|
|
|
with app:
|
2019-10-23 00:40:11 +02:00
|
|
|
try:
|
|
|
|
|
global sys
|
|
|
|
|
|
|
|
|
|
# if not root...kick out
|
2019-11-11 19:06:11 +01:00
|
|
|
if not geteuid() == 0:
|
2019-10-23 00:40:11 +02:00
|
|
|
print("\nNon-privileged users cant use WordOps. "
|
|
|
|
|
"Switch to root or invoke sudo.\n")
|
|
|
|
|
app.close(1)
|
|
|
|
|
app.run()
|
|
|
|
|
except AssertionError as e:
|
|
|
|
|
print("AssertionError => %s" % e.args[0])
|
|
|
|
|
app.exit_code = 1
|
|
|
|
|
except exc.WOError as e:
|
|
|
|
|
# Catch our application errors and exit 1 (error)
|
2019-11-03 23:07:24 +01:00
|
|
|
print('WOError > %s' % e)
|
2019-10-23 00:40:11 +02:00
|
|
|
app.exit_code = 1
|
|
|
|
|
except CaughtSignal as e:
|
|
|
|
|
# Default Cement signals are SIGINT and SIGTERM, exit 0 (non-error)
|
|
|
|
|
print('CaughtSignal > %s' % e)
|
|
|
|
|
app.exit_code = 0
|
2019-11-11 19:06:11 +01:00
|
|
|
except FrameworkError as e:
|
|
|
|
|
# Catch framework errors and exit 1 (error)
|
|
|
|
|
print('FrameworkError > %s' % e)
|
|
|
|
|
app.exit_code = 1
|
2019-10-23 00:40:11 +02:00
|
|
|
finally:
|
2019-12-03 19:48:18 +01:00
|
|
|
# Maybe we want to see a full-stack trace for the above
|
|
|
|
|
# exceptions, but only if --debug was passed?
|
2019-10-23 00:40:11 +02:00
|
|
|
if app.debug:
|
|
|
|
|
import traceback
|
2019-12-03 19:48:18 +01:00
|
|
|
traceback.print_exc()
|
2018-11-13 21:55:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|