meerschaum 2.3.5.dev0__tar.gz → 2.3.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meerschaum-2.3.5.dev0/meerschaum.egg-info → meerschaum-2.3.6}/PKG-INFO +1 -1
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/arguments/__init__.py +2 -1
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/arguments/_parse_arguments.py +86 -7
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/entry.py +29 -13
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/api.py +16 -16
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/start.py +3 -1
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/_events.py +11 -7
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_actions.py +0 -98
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_jobs.py +38 -18
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_default.py +0 -1
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_version.py +1 -1
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/stack/__init__.py +0 -2
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/static/__init__.py +2 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_actions.py +22 -36
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_jobs.py +1 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/jobs/_Job.py +26 -8
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/jobs/systemd.py +20 -8
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/prompt.py +1 -1
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6/meerschaum.egg-info}/PKG-INFO +1 -1
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/LICENSE +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/NOTICE +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/README.md +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/__main__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/arguments/_parser.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/docs/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/docs/index.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/gui/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/gui/app/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/gui/app/_windows.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/gui/app/actions.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/gui/app/pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/shell/Shell.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/shell/ShellCompleter.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/shell/ValidAutoSuggest.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/shell/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/shell/resources/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/shell/updates.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/term/TermPageHandler.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/term/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/term/tools.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/attach.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/bootstrap.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/clear.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/copy.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/deduplicate.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/delete.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/drop.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/edit.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/install.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/login.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/os.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/pause.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/python.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/register.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/reload.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/restart.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/setup.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/sh.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/show.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/sql.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/stack.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/stop.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/sync.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/tag.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/uninstall.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/upgrade.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/actions/verify.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/_chain.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/_oauth2.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/_websockets.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/actions.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/assets/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/assets/ansi_up.js +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/assets/banner_1920x320.png +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/assets/favicon.ico +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/assets/logo_48x48.png +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/assets/logo_500x500.png +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/callbacks/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/callbacks/custom.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/callbacks/dashboard.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/callbacks/jobs.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/callbacks/login.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/callbacks/plugins.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/callbacks/register.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/components.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/connectors.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/graphs.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/jobs.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/keys.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/pages/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/pages/dashboard.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/pages/error.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/pages/login.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/pages/plugins.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/pages/register.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/plugins.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/sync.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/users.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/websockets.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/dash/webterm.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/models/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/models/_interfaces.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/models/_locations.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/models/_metrics.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/models/_pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/css/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/css/bootstrap.min.css +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/css/dash.css +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/css/dbc_dark.css +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/css/styles.css +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/css/xterm.css +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/ico/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/ico/logo.ico +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/js/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/js/action_button.js +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/js/main.js +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/js/terminado.js +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/js/xterm.js +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/static/png/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/templates/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/templates/index.html +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/templates/old_index.html +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/templates/secret.html +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/resources/templates/termpage.html +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_connectors.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_index.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_login.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_misc.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_plugins.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_users.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_version.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/routes/_webterm.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/api/tables/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_dash.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_edit.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_environment.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_formatting.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_jobs.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_patch.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_paths.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_preprocess.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_read_config.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_shell.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/_sync.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/paths.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/resources/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/stack/grafana/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/stack/mosquitto/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/stack/mosquitto/resources/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/config/stack/resources/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/Connector.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/APIConnector.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_fetch.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_login.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_misc.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_plugins.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_request.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_uri.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/api/_users.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/parse.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/plugin/PluginConnector.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/plugin/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/poll.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/SQLConnector.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_cli.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_create_engine.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_fetch.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_instance.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_plugins.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_sql.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_uri.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/_users.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/tables/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/tables/types.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/connectors/sql/tools.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_attributes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_bootstrap.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_clear.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_data.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_deduplicate.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_delete.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_drop.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_dtypes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_edit.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_fetch.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_register.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_show.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_sync.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Pipe/_verify.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/Plugin/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/User/_User.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/User/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/core/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/jobs/_Executor.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/jobs/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/plugins/_Plugin.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/plugins/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/plugins/bootstrap.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/_get_pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/daemon/Daemon.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/daemon/RotatingFile.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/daemon/StdinFile.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/daemon/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/daemon/_names.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/dataframe.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/debug.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/dtypes/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/dtypes/sql.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/formatting/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/formatting/_jobs.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/formatting/_pipes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/formatting/_pprint.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/formatting/_shell.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/interactive.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/misc.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/networking.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/packages/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/packages/_packages.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/packages/lazy_loader.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/pool.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/process.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/schedule.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/sql.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/threading.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/typing.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/venv/_Venv.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/venv/__init__.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/warnings.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/utils/yaml.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum.egg-info/SOURCES.txt +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum.egg-info/dependency_links.txt +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum.egg-info/entry_points.txt +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum.egg-info/requires.txt +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum.egg-info/top_level.txt +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum.egg-info/zip-safe +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/setup.cfg +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/setup.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_actions.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_arguments.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_deduplicate.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_jobs.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_pipes_dtypes.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_sql.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_sync.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_users.py +0 -0
- {meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/tests/test_verify.py +0 -0
@@ -9,7 +9,8 @@ This package includes argument parsing utilities.
|
|
9
9
|
from meerschaum._internal.arguments._parse_arguments import (
|
10
10
|
parse_arguments, parse_line, remove_leading_action,
|
11
11
|
parse_dict_to_sysargs, split_chained_sysargs, split_pipeline_sysargs,
|
12
|
-
sysargs_has_api_executor_keys,
|
12
|
+
sysargs_has_api_executor_keys, get_pipeline_sysargs,
|
13
|
+
compress_pipeline_sysargs, remove_api_executor_keys,
|
13
14
|
)
|
14
15
|
from meerschaum._internal.arguments._parser import parser
|
15
16
|
from meerschaum.plugins import add_plugin_argument
|
{meerschaum-2.3.5.dev0 → meerschaum-2.3.6}/meerschaum/_internal/arguments/_parse_arguments.py
RENAMED
@@ -424,12 +424,91 @@ def sysargs_has_api_executor_keys(sysargs: List[str]) -> bool:
|
|
424
424
|
if '-e' not in sysargs and '--executor-keys' not in sysargs:
|
425
425
|
return False
|
426
426
|
|
427
|
-
|
428
|
-
|
429
|
-
|
427
|
+
for i, arg in enumerate(sysargs):
|
428
|
+
if arg not in ('-e', '--executor-keys'):
|
429
|
+
continue
|
430
430
|
|
431
|
-
|
432
|
-
|
431
|
+
executor_keys_ix = i + 1
|
432
|
+
if len(sysargs) <= executor_keys_ix:
|
433
|
+
return False
|
434
|
+
|
435
|
+
executor_keys = sysargs[executor_keys_ix]
|
436
|
+
if executor_keys.startswith('api:'):
|
437
|
+
return True
|
438
|
+
|
439
|
+
return False
|
440
|
+
|
441
|
+
|
442
|
+
def remove_api_executor_keys(sysargs: List[str]) -> List[str]:
|
443
|
+
"""
|
444
|
+
Remove any api executor keys from `sysargs`.
|
445
|
+
"""
|
446
|
+
from meerschaum.utils.misc import flatten_list
|
447
|
+
|
448
|
+
if not sysargs_has_api_executor_keys(sysargs):
|
449
|
+
return sysargs
|
450
|
+
|
451
|
+
skip_indices = set(flatten_list(
|
452
|
+
[
|
453
|
+
[i, i+1]
|
454
|
+
for i, arg in enumerate(sysargs)
|
455
|
+
if arg in ('-e', '--executor-keys')
|
456
|
+
]
|
457
|
+
))
|
458
|
+
|
459
|
+
return [
|
460
|
+
arg
|
461
|
+
for i, arg in enumerate(sysargs)
|
462
|
+
if i not in skip_indices
|
463
|
+
]
|
433
464
|
|
434
|
-
|
435
|
-
|
465
|
+
|
466
|
+
def get_pipeline_sysargs(
|
467
|
+
sysargs: List[str],
|
468
|
+
pipeline_args: List[str],
|
469
|
+
_patch_args: Optional[Dict[str, Any]] = None,
|
470
|
+
) -> List[str]:
|
471
|
+
"""
|
472
|
+
Parse `sysargs` and `pipeline_args` into a single `start pipeline` sysargs.
|
473
|
+
"""
|
474
|
+
import shlex
|
475
|
+
start_pipeline_params = {
|
476
|
+
'sub_args_line': shlex.join(sysargs),
|
477
|
+
'patch_args': _patch_args,
|
478
|
+
}
|
479
|
+
return (
|
480
|
+
['start', 'pipeline']
|
481
|
+
+ [str(arg) for arg in pipeline_args]
|
482
|
+
+ ['-P', json.dumps(start_pipeline_params, separators=(',', ':'))]
|
483
|
+
)
|
484
|
+
|
485
|
+
|
486
|
+
def compress_pipeline_sysargs(pipeline_sysargs: List[str]) -> List[str]:
|
487
|
+
"""
|
488
|
+
Given a `start pipeline` sysargs, return a condensed syntax rendition.
|
489
|
+
"""
|
490
|
+
import shlex
|
491
|
+
|
492
|
+
if pipeline_sysargs[:2] != ['start', 'pipeline']:
|
493
|
+
return pipeline_sysargs
|
494
|
+
|
495
|
+
if '-P' not in pipeline_sysargs:
|
496
|
+
return pipeline_sysargs
|
497
|
+
|
498
|
+
params_ix = pipeline_sysargs.index('-P')
|
499
|
+
pipeline_args = pipeline_sysargs[2:params_ix]
|
500
|
+
params_str = pipeline_sysargs[-1]
|
501
|
+
try:
|
502
|
+
start_pipeline_params = json.loads(params_str)
|
503
|
+
except Exception:
|
504
|
+
return pipeline_sysargs
|
505
|
+
|
506
|
+
sub_args_line = start_pipeline_params.get('sub_args_line', None)
|
507
|
+
if not sub_args_line:
|
508
|
+
return pipeline_sysargs
|
509
|
+
|
510
|
+
return (
|
511
|
+
shlex.split(sub_args_line)
|
512
|
+
+ [':']
|
513
|
+
+ pipeline_args
|
514
|
+
)
|
@@ -11,6 +11,8 @@ from __future__ import annotations
|
|
11
11
|
|
12
12
|
import os
|
13
13
|
import sys
|
14
|
+
import pathlib
|
15
|
+
|
14
16
|
from meerschaum.utils.typing import SuccessTuple, List, Optional, Dict, Callable, Any
|
15
17
|
from meerschaum.config.static import STATIC_CONFIG as _STATIC_CONFIG
|
16
18
|
|
@@ -19,8 +21,17 @@ if (_STATIC_CONFIG['environment']['systemd_log_path']) in os.environ:
|
|
19
21
|
from meerschaum.utils.daemon import RotatingFile as _RotatingFile, StdinFile as _StdinFile
|
20
22
|
from meerschaum.config import get_config as _get_config
|
21
23
|
|
22
|
-
_systemd_result_path =
|
23
|
-
|
24
|
+
_systemd_result_path = pathlib.Path(
|
25
|
+
os.environ[_STATIC_CONFIG['environment']['systemd_result_path']]
|
26
|
+
)
|
27
|
+
_systemd_log_path = pathlib.Path(
|
28
|
+
os.environ[_STATIC_CONFIG['environment']['systemd_log_path']]
|
29
|
+
)
|
30
|
+
_systemd_delete_job = (
|
31
|
+
(os.environ.get(_STATIC_CONFIG['environment']['systemd_delete_job'], None) or '0')
|
32
|
+
not in (None, '0', 'false')
|
33
|
+
)
|
34
|
+
_job_name = os.environ[_STATIC_CONFIG['environment']['daemon_id']]
|
24
35
|
_systemd_log = _RotatingFile(
|
25
36
|
_systemd_log_path,
|
26
37
|
write_timestamps=True,
|
@@ -51,6 +62,7 @@ def entry(
|
|
51
62
|
split_chained_sysargs,
|
52
63
|
split_pipeline_sysargs,
|
53
64
|
sysargs_has_api_executor_keys,
|
65
|
+
get_pipeline_sysargs,
|
54
66
|
)
|
55
67
|
from meerschaum.config.static import STATIC_CONFIG
|
56
68
|
if sysargs is None:
|
@@ -72,15 +84,7 @@ def entry(
|
|
72
84
|
else split_chained_sysargs(sysargs)
|
73
85
|
)
|
74
86
|
if pipeline_args:
|
75
|
-
|
76
|
-
'sub_args_line': shlex.join(sysargs),
|
77
|
-
'patch_args': _patch_args,
|
78
|
-
}
|
79
|
-
chained_sysargs = [
|
80
|
-
['start', 'pipeline']
|
81
|
-
+ [str(arg) for arg in pipeline_args]
|
82
|
-
+ ['-P', json.dumps(start_pipeline_params, separators=(',', ':'))]
|
83
|
-
]
|
87
|
+
chained_sysargs = [get_pipeline_sysargs(sysargs, pipeline_args, _patch_args=_patch_args)]
|
84
88
|
|
85
89
|
results: List[SuccessTuple] = []
|
86
90
|
|
@@ -169,8 +173,20 @@ def entry(
|
|
169
173
|
|
170
174
|
if _systemd_result_path:
|
171
175
|
import json
|
172
|
-
|
173
|
-
|
176
|
+
from meerschaum.utils.warnings import warn
|
177
|
+
import meerschaum as mrsm
|
178
|
+
|
179
|
+
job = mrsm.Job(_job_name, executor_keys='systemd')
|
180
|
+
if job.delete_after_completion:
|
181
|
+
delete_success, delete_msg = job.delete()
|
182
|
+
mrsm.pprint((delete_success, delete_msg))
|
183
|
+
else:
|
184
|
+
try:
|
185
|
+
if _systemd_result_path.parent.exists():
|
186
|
+
with open(_systemd_result_path, 'w+', encoding='utf-8') as f:
|
187
|
+
json.dump((success, msg), f)
|
188
|
+
except Exception as e:
|
189
|
+
warn(f"Failed to write job result:\n{e}")
|
174
190
|
|
175
191
|
return success, msg
|
176
192
|
|
@@ -89,22 +89,22 @@ def api(
|
|
89
89
|
return success, message
|
90
90
|
|
91
91
|
def _api_start(
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
92
|
+
action: Optional[List[str]] = None,
|
93
|
+
host: Optional[str] = None,
|
94
|
+
port: Optional[int] = None,
|
95
|
+
workers: Optional[int] = None,
|
96
|
+
mrsm_instance: Optional[str] = None,
|
97
|
+
no_dash: bool = False,
|
98
|
+
no_auth: bool = False,
|
99
|
+
private: bool = False,
|
100
|
+
secure: bool = False,
|
101
|
+
debug: bool = False,
|
102
|
+
nopretty: bool = False,
|
103
|
+
production: bool = False,
|
104
|
+
keyfile: Optional[str] = None,
|
105
|
+
certfile: Optional[str] = None,
|
106
|
+
**kw: Any
|
107
|
+
) -> SuccessTuple:
|
108
108
|
"""Start the API server.
|
109
109
|
|
110
110
|
Parameters
|
@@ -89,6 +89,7 @@ def _start_jobs(
|
|
89
89
|
name: Optional[str] = None,
|
90
90
|
sysargs: Optional[List[str]] = None,
|
91
91
|
executor_keys: Optional[str] = None,
|
92
|
+
rm: bool = False,
|
92
93
|
debug: bool = False,
|
93
94
|
**kw
|
94
95
|
) -> SuccessTuple:
|
@@ -210,7 +211,7 @@ def _start_jobs(
|
|
210
211
|
|
211
212
|
def _run_new_job(name: Optional[str] = None):
|
212
213
|
name = name or get_new_daemon_name()
|
213
|
-
job = Job(name, sysargs, executor_keys=executor_keys)
|
214
|
+
job = Job(name, sysargs, executor_keys=executor_keys, delete_after_completion=rm)
|
214
215
|
return job.start(debug=debug), name
|
215
216
|
|
216
217
|
def _run_existing_job(name: str):
|
@@ -568,6 +569,7 @@ def _start_pipeline(
|
|
568
569
|
else 1
|
569
570
|
)
|
570
571
|
|
572
|
+
params = params or {}
|
571
573
|
sub_args_line = params.get('sub_args_line', None)
|
572
574
|
patch_args = params.get('patch_args', None)
|
573
575
|
|
@@ -20,12 +20,14 @@ from meerschaum.connectors.poll import retry_connect
|
|
20
20
|
from meerschaum.utils.warnings import warn
|
21
21
|
from meerschaum._internal.term.tools import is_webterm_running
|
22
22
|
from meerschaum.jobs import (
|
23
|
+
get_jobs,
|
23
24
|
start_check_jobs_thread,
|
24
25
|
stop_check_jobs_thread,
|
25
26
|
get_executor_keys_from_context,
|
26
27
|
)
|
28
|
+
from meerschaum.config.static import STATIC_CONFIG
|
27
29
|
|
28
|
-
|
30
|
+
TEMP_PREFIX: str = STATIC_CONFIG['api']['jobs']['temp_prefix']
|
29
31
|
|
30
32
|
@app.on_event("startup")
|
31
33
|
async def startup():
|
@@ -51,8 +53,7 @@ async def startup():
|
|
51
53
|
await shutdown()
|
52
54
|
os._exit(1)
|
53
55
|
|
54
|
-
|
55
|
-
start_check_jobs_thread()
|
56
|
+
start_check_jobs_thread()
|
56
57
|
|
57
58
|
|
58
59
|
@app.on_event("shutdown")
|
@@ -65,11 +66,14 @@ async def shutdown():
|
|
65
66
|
if get_api_connector().type == 'sql':
|
66
67
|
get_api_connector().engine.dispose()
|
67
68
|
|
68
|
-
|
69
|
-
stop_check_jobs_thread()
|
69
|
+
stop_check_jobs_thread()
|
70
70
|
|
71
|
-
|
72
|
-
|
71
|
+
temp_jobs = {
|
72
|
+
name: job
|
73
|
+
for name, job in get_jobs(include_hidden=True).items()
|
74
|
+
if name.startswith(TEMP_PREFIX)
|
75
|
+
}
|
76
|
+
for job in temp_jobs.values():
|
73
77
|
job.delete()
|
74
78
|
|
75
79
|
### Terminate any running jobs left over.
|
@@ -67,104 +67,6 @@ def get_actions(
|
|
67
67
|
return list(actions)
|
68
68
|
|
69
69
|
|
70
|
-
async def notify_client(client, content: str):
|
71
|
-
"""
|
72
|
-
Send a line of text to a client.
|
73
|
-
"""
|
74
|
-
try:
|
75
|
-
await client.send_text(content)
|
76
|
-
except (RuntimeError, WebSocketDisconnect, Exception):
|
77
|
-
raise StopMonitoringLogs
|
78
|
-
|
79
|
-
_temp_jobs = {}
|
80
|
-
@app.websocket(actions_endpoint + '/ws')
|
81
|
-
async def do_action_websocket(websocket: WebSocket):
|
82
|
-
"""
|
83
|
-
Execute an action and stream the output to the client.
|
84
|
-
"""
|
85
|
-
await websocket.accept()
|
86
|
-
|
87
|
-
stop_event = asyncio.Event()
|
88
|
-
job_name = '.' + generate_password(12)
|
89
|
-
job = None
|
90
|
-
|
91
|
-
async def monitor_logs(job):
|
92
|
-
success, msg = job.start()
|
93
|
-
await job.monitor_logs_async(
|
94
|
-
partial(notify_client, websocket),
|
95
|
-
stop_event=stop_event,
|
96
|
-
stop_on_exit=True,
|
97
|
-
)
|
98
|
-
|
99
|
-
try:
|
100
|
-
token = await websocket.receive_text()
|
101
|
-
user = await manager.get_current_user(token) if not no_auth else None
|
102
|
-
if user is None and not no_auth:
|
103
|
-
stop_event.set()
|
104
|
-
if job is not None:
|
105
|
-
job.delete()
|
106
|
-
_ = _temp_jobs.pop(job_name, None)
|
107
|
-
raise fastapi.HTTPException(
|
108
|
-
status_code=401,
|
109
|
-
detail="Invalid credentials.",
|
110
|
-
)
|
111
|
-
|
112
|
-
auth_success, auth_msg = (
|
113
|
-
is_user_allowed_to_execute(user)
|
114
|
-
if not no_auth
|
115
|
-
else (True, "Success")
|
116
|
-
)
|
117
|
-
auth_payload = {
|
118
|
-
'is_authenticated': auth_success,
|
119
|
-
'timestamp': datetime.now(timezone.utc).isoformat(),
|
120
|
-
}
|
121
|
-
await websocket.send_json(auth_payload)
|
122
|
-
if not auth_success:
|
123
|
-
stop_event.set()
|
124
|
-
job.stop()
|
125
|
-
await websocket.close()
|
126
|
-
|
127
|
-
sysargs = clean_sysargs(await websocket.receive_json())
|
128
|
-
job = Job(
|
129
|
-
job_name,
|
130
|
-
sysargs,
|
131
|
-
executor_keys='local',
|
132
|
-
_properties={
|
133
|
-
'logs': {
|
134
|
-
'write_timestamps': False,
|
135
|
-
},
|
136
|
-
},
|
137
|
-
)
|
138
|
-
_temp_jobs[job_name] = job
|
139
|
-
monitor_task = asyncio.create_task(monitor_logs(job))
|
140
|
-
|
141
|
-
### NOTE: Await incoming text to trigger `WebSocketDisconnect`.
|
142
|
-
while True:
|
143
|
-
await websocket.receive_text()
|
144
|
-
|
145
|
-
except fastapi.HTTPException:
|
146
|
-
await websocket.send_text("Invalid credentials.")
|
147
|
-
await websocket.close()
|
148
|
-
except (WebSocketDisconnect, asyncio.CancelledError):
|
149
|
-
stop_event.set()
|
150
|
-
job.stop()
|
151
|
-
except Exception:
|
152
|
-
stop_event.set()
|
153
|
-
job.stop()
|
154
|
-
warn(f"Error in logs websocket:\n{traceback.format_exc()}")
|
155
|
-
finally:
|
156
|
-
stop_event.set()
|
157
|
-
job.stop()
|
158
|
-
monitor_task.cancel()
|
159
|
-
if job is not None:
|
160
|
-
job.delete()
|
161
|
-
_ = _temp_jobs.pop(job_name, None)
|
162
|
-
try:
|
163
|
-
await websocket.close()
|
164
|
-
except RuntimeError:
|
165
|
-
pass
|
166
|
-
|
167
|
-
|
168
70
|
@app.post(actions_endpoint + "/{action}", tags=['Actions'])
|
169
71
|
def do_action_legacy(
|
170
72
|
action: str,
|
@@ -40,7 +40,15 @@ from meerschaum.config.static import STATIC_CONFIG
|
|
40
40
|
|
41
41
|
JOBS_STDIN_MESSAGE: str = STATIC_CONFIG['api']['jobs']['stdin_message']
|
42
42
|
JOBS_STOP_MESSAGE: str = STATIC_CONFIG['api']['jobs']['stop_message']
|
43
|
-
EXECUTOR_KEYS: str =
|
43
|
+
EXECUTOR_KEYS: str = 'local'
|
44
|
+
|
45
|
+
|
46
|
+
def _get_job(name: str):
|
47
|
+
systemd_job = Job(name, executor_keys='systemd')
|
48
|
+
if systemd_job.exists():
|
49
|
+
return systemd_job
|
50
|
+
|
51
|
+
return Job(name, executor_keys=EXECUTOR_KEYS)
|
44
52
|
|
45
53
|
|
46
54
|
@app.get(endpoints['jobs'], tags=['Jobs'])
|
@@ -52,7 +60,7 @@ def get_jobs(
|
|
52
60
|
"""
|
53
61
|
Return metadata about the current jobs.
|
54
62
|
"""
|
55
|
-
jobs = _get_jobs(executor_keys=EXECUTOR_KEYS, combine_local_and_systemd=
|
63
|
+
jobs = _get_jobs(executor_keys=EXECUTOR_KEYS, combine_local_and_systemd=True)
|
56
64
|
return {
|
57
65
|
name: {
|
58
66
|
'sysargs': job.sysargs,
|
@@ -83,7 +91,7 @@ def get_job(
|
|
83
91
|
"""
|
84
92
|
Return metadata for a single job.
|
85
93
|
"""
|
86
|
-
job =
|
94
|
+
job = _get_job(name)
|
87
95
|
if not job.exists():
|
88
96
|
raise fastapi.HTTPException(
|
89
97
|
status_code=404,
|
@@ -163,7 +171,7 @@ def delete_job(
|
|
163
171
|
"""
|
164
172
|
Delete a job.
|
165
173
|
"""
|
166
|
-
job =
|
174
|
+
job = _get_job(name)
|
167
175
|
return job.delete()
|
168
176
|
|
169
177
|
|
@@ -177,7 +185,7 @@ def get_job_exists(
|
|
177
185
|
"""
|
178
186
|
Return whether a job exists.
|
179
187
|
"""
|
180
|
-
job =
|
188
|
+
job = _get_job(name)
|
181
189
|
return job.exists()
|
182
190
|
|
183
191
|
|
@@ -192,7 +200,7 @@ def get_logs(
|
|
192
200
|
Return a job's log text.
|
193
201
|
To stream log text, connect to the WebSocket endpoint `/logs/{name}/ws`.
|
194
202
|
"""
|
195
|
-
job =
|
203
|
+
job = _get_job(name)
|
196
204
|
if not job.exists():
|
197
205
|
raise fastapi.HTTPException(
|
198
206
|
status_code=404,
|
@@ -212,7 +220,7 @@ def start_job(
|
|
212
220
|
"""
|
213
221
|
Start a job if stopped.
|
214
222
|
"""
|
215
|
-
job =
|
223
|
+
job = _get_job(name)
|
216
224
|
if not job.exists():
|
217
225
|
raise fastapi.HTTPException(
|
218
226
|
status_code=404,
|
@@ -231,7 +239,7 @@ def stop_job(
|
|
231
239
|
"""
|
232
240
|
Stop a job if running.
|
233
241
|
"""
|
234
|
-
job =
|
242
|
+
job = _get_job(name)
|
235
243
|
if not job.exists():
|
236
244
|
raise fastapi.HTTPException(
|
237
245
|
status_code=404,
|
@@ -250,7 +258,7 @@ def pause_job(
|
|
250
258
|
"""
|
251
259
|
Pause a job if running.
|
252
260
|
"""
|
253
|
-
job =
|
261
|
+
job = _get_job(name)
|
254
262
|
if not job.exists():
|
255
263
|
raise fastapi.HTTPException(
|
256
264
|
status_code=404,
|
@@ -269,7 +277,7 @@ def get_stop_time(
|
|
269
277
|
"""
|
270
278
|
Get the timestamp when the job was manually stopped.
|
271
279
|
"""
|
272
|
-
job =
|
280
|
+
job = _get_job(name)
|
273
281
|
return job.stop_time
|
274
282
|
|
275
283
|
|
@@ -283,12 +291,13 @@ def get_is_blocking_on_stdin(
|
|
283
291
|
"""
|
284
292
|
Return whether a job is blocking on stdin.
|
285
293
|
"""
|
286
|
-
job =
|
294
|
+
job = _get_job(name)
|
287
295
|
return job.is_blocking_on_stdin()
|
288
296
|
|
289
297
|
|
290
298
|
_job_clients = defaultdict(lambda: [])
|
291
299
|
_job_stop_events = defaultdict(lambda: asyncio.Event())
|
300
|
+
_job_queues = defaultdict(lambda: asyncio.Queue())
|
292
301
|
async def notify_clients(name: str, websocket: WebSocket, content: str):
|
293
302
|
"""
|
294
303
|
Write the given content to all connected clients.
|
@@ -315,12 +324,16 @@ async def get_input_from_clients(name: str, websocket: WebSocket) -> str:
|
|
315
324
|
async def _read_client(client):
|
316
325
|
try:
|
317
326
|
await client.send_text(JOBS_STDIN_MESSAGE)
|
318
|
-
data = await
|
327
|
+
data = await _job_queues[name].get()
|
319
328
|
except WebSocketDisconnect:
|
320
329
|
if client in _job_clients[name]:
|
321
330
|
_job_clients[name].remove(client)
|
331
|
+
if not _job_clients[name]:
|
332
|
+
_job_stop_events[name].set()
|
322
333
|
except Exception:
|
323
334
|
pass
|
335
|
+
finally:
|
336
|
+
_job_queues[name].task_done()
|
324
337
|
return data
|
325
338
|
|
326
339
|
read_tasks = [
|
@@ -357,10 +370,12 @@ async def logs_websocket(name: str, websocket: WebSocket):
|
|
357
370
|
Stream logs from a job over a websocket.
|
358
371
|
"""
|
359
372
|
await websocket.accept()
|
360
|
-
job =
|
373
|
+
job = _get_job(name)
|
361
374
|
_job_clients[name].append(websocket)
|
362
375
|
|
376
|
+
_task = None
|
363
377
|
async def monitor_logs():
|
378
|
+
nonlocal _task
|
364
379
|
try:
|
365
380
|
callback_function = partial(
|
366
381
|
notify_clients,
|
@@ -377,16 +392,17 @@ async def logs_websocket(name: str, websocket: WebSocket):
|
|
377
392
|
name,
|
378
393
|
websocket,
|
379
394
|
)
|
380
|
-
|
395
|
+
_task = asyncio.create_task(job.monitor_logs_async(
|
381
396
|
callback_function=callback_function,
|
382
397
|
input_callback_function=input_callback_function,
|
383
398
|
stop_callback_function=stop_callback_function,
|
384
399
|
stop_event=_job_stop_events[name],
|
385
400
|
stop_on_exit=True,
|
386
401
|
accept_input=True,
|
387
|
-
)
|
402
|
+
))
|
388
403
|
except Exception:
|
389
404
|
warn(traceback.format_exc())
|
405
|
+
_task.cancel()
|
390
406
|
|
391
407
|
try:
|
392
408
|
token = await websocket.receive_text()
|
@@ -397,13 +413,17 @@ async def logs_websocket(name: str, websocket: WebSocket):
|
|
397
413
|
detail="Invalid credentials.",
|
398
414
|
)
|
399
415
|
monitor_task = asyncio.create_task(monitor_logs())
|
400
|
-
|
416
|
+
while True:
|
417
|
+
text = await websocket.receive_text()
|
418
|
+
await _job_queues[name].put(text)
|
419
|
+
|
401
420
|
except fastapi.HTTPException:
|
402
421
|
await websocket.send_text("Invalid credentials.")
|
403
422
|
await websocket.close()
|
404
423
|
except WebSocketDisconnect:
|
405
|
-
|
406
|
-
|
424
|
+
if not _job_clients[name]:
|
425
|
+
_job_stop_events[name].set()
|
426
|
+
monitor_task.cancel()
|
407
427
|
except asyncio.CancelledError:
|
408
428
|
pass
|
409
429
|
except Exception:
|
@@ -56,7 +56,6 @@ env_dict['MEERSCHAUM_API_CONFIG'] = json.dumps(
|
|
56
56
|
|
57
57
|
volumes = {
|
58
58
|
'api_root': '/meerschaum',
|
59
|
-
'api_user_local': '/home/meerschaum/.local',
|
60
59
|
'meerschaum_db_data': '/var/lib/postgresql/data',
|
61
60
|
'grafana_storage': '/var/lib/grafana',
|
62
61
|
}
|
@@ -160,7 +159,6 @@ default_docker_compose_config = {
|
|
160
159
|
},
|
161
160
|
'volumes' : [
|
162
161
|
'api_root:' + volumes['api_root'],
|
163
|
-
'api_user_local:' + volumes['api_user_local'],
|
164
162
|
],
|
165
163
|
},
|
166
164
|
'grafana': {
|
@@ -46,6 +46,7 @@ STATIC_CONFIG: Dict[str, Any] = {
|
|
46
46
|
'stdin_message': 'MRSM_STDIN',
|
47
47
|
'stop_message': 'MRSM_STOP',
|
48
48
|
'metadata_cache_seconds': 5,
|
49
|
+
'temp_prefix': '.api-temp-',
|
49
50
|
},
|
50
51
|
},
|
51
52
|
'sql': {
|
@@ -73,6 +74,7 @@ STATIC_CONFIG: Dict[str, Any] = {
|
|
73
74
|
'systemd_log_path': 'MRSM_SYSTEMD_LOG_PATH',
|
74
75
|
'systemd_stdin_path': 'MRSM_SYSTEMD_STDIN_PATH',
|
75
76
|
'systemd_result_path': 'MRSM_SYSTEMD_RESULT_PATH',
|
77
|
+
'systemd_delete_job': 'MRSM_SYSTEMD_DELETE_JOB',
|
76
78
|
'uri_regex': r'MRSM_([a-zA-Z0-9]*)_(\d*[a-zA-Z][a-zA-Z0-9-_+]*$)',
|
77
79
|
'prefix': 'MRSM_',
|
78
80
|
},
|