diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 18fbbf8..15e43b0 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -35,8 +35,8 @@ jobs:
- name: Install dependencies
run: |
- pip install -r requirements_lint.txt
- pip install -r requirements.txt
+ pip install -r requirements_lint.txt >/dev/null
+ pip install -r requirements.txt >/dev/null
shell: bash
- name: Running PyLint
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b7e1ae5..9da8cc1 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -22,20 +22,17 @@ jobs:
python-version: '3.10'
- name: Install dependencies
- run: pip install -r requirements_build.txt
+ run: pip install -r requirements_build.txt >/dev/null
shell: bash
- name: Extract tag name
id: version
run: echo ::set-output name=TAG_NAME::$(echo $GITHUB_REF | cut -d / -f 3 | cut -c 2-)
- - name: Update version in setup.py
- run: >-
- sed -i 's/version=.*/version="${{ steps.version.outputs.TAG_NAME }}",/g' setup.py
- sed -i 's/VERSION =.*/VERSION = "${{ steps.version.outputs.TAG_NAME }}"/g' ansible-webui/aw/config/hardcoded.py
-
- name: Building
- run: python3 -m build
+ run: |
+ echo "${{ steps.version.outputs.TAG_NAME }}" > VERSION
+ python3 -m build
shell: bash
- name: Publish to PyPI
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 575d7b8..37c7dbc 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -34,9 +34,9 @@ jobs:
- name: Install dependencies
run: |
- pip install -r requirements_test.txt
- pip install -r requirements_build.txt
- pip install -r requirements.txt
+ pip install -r requirements_test.txt >/dev/null
+ pip install -r requirements_build.txt >/dev/null
+ pip install -r requirements.txt >/dev/null
shell: bash
- name: Testing DB migrations for errors & warnings
@@ -46,12 +46,12 @@ jobs:
m2=$(python3 manage.py migrate 2>&1)
if echo "$m2" | grep -q 'WARNING'; then exit 1;fi
shell: bash
- working-directory: ansible-webui/
+ working-directory: src/ansible-webui/
- name: Testing to start Ansible-WebUI
run: |
set +e
- timeout 2 python3 ansible-webui
+ timeout 2 python3 src/ansible-webui
ec="$?"
if [[ "$ec" != "124" ]]
then
diff --git a/.gitignore b/.gitignore
index c5c4ac1..877842d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@ venv/
ansible_webui.egg-info/
__pychache__.py
**/aw.db
-**/aw.dev.db
\ No newline at end of file
+**/aw.dev.db
+VERSION
\ No newline at end of file
diff --git a/.pylintrc b/.pylintrc
index 0be883c..5a887fe 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -1,3 +1,6 @@
+[MASTER]
+init-hook='import sys; sys.path.append("src/ansible-webui/")'
+
[MAIN]
# Analyse import fallback blocks. This can be used to support both Python 2 and
@@ -52,7 +55,8 @@ ignore=CVS
# ignore-list. The regex matches against paths and can be in Posix or Windows
# format. Because '\\' represents the directory delimiter on Windows systems,
# it can't be used as an escape character.
-ignore-paths=venv/*
+ignore-paths=venv/*,
+ src/ansible-webui/aw/migrations/*
# Files or directories matching the regular expression patterns are skipped.
# The regex matches against base names, not paths. The default value ignores
@@ -279,16 +283,17 @@ valid-metaclass-classmethod-first-arg=mcs
# List of regular expressions of class ancestor names to ignore when counting
# public methods (see R0903)
exclude-too-few-public-methods=
+# todo: exclude models
# List of qualified class names to ignore when counting class parents (see
# R0901)
ignored-parents=
# Maximum number of arguments for function / method.
-max-args=5
+max-args=7
# Maximum number of attributes for a class (see R0902).
-max-attributes=7
+max-attributes=10
# Maximum number of boolean expressions in an if statement (see R0916).
max-bool-expr=5
@@ -424,6 +429,9 @@ confidence=HIGH,
disable=C0114, C0115, C0116, # no inline docs
C0103, # var-naming..
W0511, # todo comments
+ W0707, # has reasons
+ R0903, # todo: exclude models
+ E0401
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
diff --git a/ansible-webui/aw/permission.py b/ansible-webui/aw/permission.py
deleted file mode 100644
index 981d817..0000000
--- a/ansible-webui/aw/permission.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from aw.config.hardcoded import PERMISSIONS
-
-
-def _group_check(user, permission: str) -> bool:
- if user and user.groups.filter(name=PERMISSIONS[permission]).exists():
- return True
-
- return False
-
-
-# def authorized_to_access(user) -> bool:
-# return _group_check(user, 'access')
-
-
-def authorized_to_exec(user) -> bool:
- return _group_check(user, 'exec')
-
-
-def authorized_to_write(user) -> bool:
- return _group_check(user, 'write')
diff --git a/ansible-webui/main.py b/ansible-webui/main.py
deleted file mode 100644
index 081d40c..0000000
--- a/ansible-webui/main.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import signal
-from os import getpid
-from os import kill as os_kill
-from time import sleep
-from sys import exit as sys_exit
-from threading import Thread
-from platform import uname
-
-# pylint: disable=E0401,C0413
-from gunicorn.arbiter import Arbiter
-from django import setup as django_setup
-
-from aw.config.main import init_globals
-
-init_globals()
-
-from base.webserver import init_webserver
-
-
-def main():
- if uname().system.lower() != 'linux':
- raise SystemError('Currently only linux systems are supported!')
-
- django_setup()
-
- init_scheduler()
- init_webserver()
-
-
-def init_scheduler():
- # pylint: disable=C0415
- from base.scheduler import Scheduler
- scheduler = Scheduler()
- scheduler_thread = Thread(target=scheduler.start)
-
- # override gunicorn signal handling to allow for graceful shutdown
- Arbiter.SIGNALS.remove(signal.SIGHUP)
- Arbiter.SIGNALS.remove(signal.SIGINT)
- Arbiter.SIGNALS.remove(signal.SIGTERM)
-
- def signal_exit(signum=None, stack=None):
- del stack
- scheduler.stop(signum)
- os_kill(getpid(), signal.SIGQUIT) # trigger 'Arbiter.stop'
- sleep(3)
- sys_exit(0)
-
- def signal_reload(signum=None, stack=None):
- del stack
- scheduler.reload(signum)
-
- signal.signal(signal.SIGHUP, signal_reload)
- signal.signal(signal.SIGINT, signal_exit)
- signal.signal(signal.SIGTERM, signal_exit)
-
- scheduler_thread.start()
diff --git a/pyproject.toml b/pyproject.toml
index f1bfca4..1dced2b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,3 +1,30 @@
[build-system]
-requires = ['setuptools>=42']
-build-backend = 'setuptools.build_meta'
+requires = ["setuptools >= 61.0"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "ansible-webui"
+authors = [
+ {name = "AnsibleGuy", email = "contact@ansibleguy.net"},
+]
+description = "Basic WebUI for using Ansible"
+readme = "README.md"
+requires-python = ">=3.5"
+keywords = ["ansible", "webui", "automation", "iac"]
+license = {file = "LICENSE.txt"}
+classifiers = [
+ 'Programming Language :: Python :: 3',
+ 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
+ 'Framework :: Django',
+]
+dynamic = ["dependencies", "version"]
+
+[project.urls]
+Homepage = "https://github.com/ansibleguy/ansible-webui"
+Documentation = "https://ansible-webui.readthedocs.io/"
+Repository = "https://github.com/ansibleguy/ansible-webui.git"
+Issues = "https://github.com/ansibleguy/issues"
+
+[tool.setuptools.dynamic]
+dependencies = {file = ["requirements.txt"]}
+version = {file = ["VERSION"]}
diff --git a/scripts/migrate_db.sh b/scripts/migrate_db.sh
index d3b0148..53c8d9f 100644
--- a/scripts/migrate_db.sh
+++ b/scripts/migrate_db.sh
@@ -19,7 +19,7 @@ then
git ls-files . --exclude-standard --others | grep 'migrations' | xargs --no-run-if-empty rm
fi
-cd "$(pwd)/ansible-webui/"
+cd "$(pwd)/src/ansible-webui/"
echo ''
echo 'Creating migrations'
diff --git a/scripts/run_pip_build.sh b/scripts/run_pip_build.sh
index 51839f8..30098bb 100644
--- a/scripts/run_pip_build.sh
+++ b/scripts/run_pip_build.sh
@@ -23,12 +23,15 @@ echo ''
echo 'Building & Installing Module using PIP'
echo ''
+bash ./scripts/update_version.sh
+
python3 -m pip install -e "$path_repo" >/dev/null
echo ''
echo 'Starting app'
echo ''
+cd /tmp
python3 -m ansible-webui
echo ''
diff --git a/scripts/run_shared.sh b/scripts/run_shared.sh
index e5b46d4..b6b744d 100644
--- a/scripts/run_shared.sh
+++ b/scripts/run_shared.sh
@@ -9,7 +9,7 @@ function log() {
}
cd "$(pwd)/.."
-TEST_DB="$(pwd)/ansible-webui/aw.${AW_ENV}.db"
+TEST_DB="$(pwd)/src/ansible-webui/aw.${AW_ENV}.db"
TEST_MIGRATE=''
if [ -f "$TEST_DB" ] && [[ "$TEST_QUIET" != "1" ]]
@@ -38,11 +38,16 @@ then
python3 -m pip install --upgrade -r ../requirements.txt >/dev/null
fi
+log 'SETTING VERSION'
+bash ./scripts/update_version.sh
+version="$(cat './VERSION')"
+export AW_VERSION="$version"
+
log 'INITIALIZING DATABASE SCHEMA'
bash ./scripts/migrate_db.sh "$TEST_MIGRATE"
log 'CREATING USERS'
-python3 ansible-webui/manage.py createsuperuser --noinput || true
+python3 ./src/ansible-webui/manage.py createsuperuser --noinput || true
log 'STARTING APP'
-python3 ansible-webui
+python3 ./src/ansible-webui
diff --git a/scripts/update_version.sh b/scripts/update_version.sh
new file mode 100644
index 0000000..4c81618
--- /dev/null
+++ b/scripts/update_version.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -e
+
+cd "$(dirname "$0")/.."
+
+#last_tag="$(git describe --exact-match --abbrev=0)"
+last_tag="0.0.1"
+echo "${last_tag}.dev" > "$(dirname "$0")/../VERSION"
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 3958585..0000000
--- a/setup.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import setuptools
-
-with open('README.md', 'r', encoding='utf-8') as info:
- long_description = info.read()
-
-with open('requirements.txt', 'r', encoding='utf-8') as reqs:
- requirements = [req for req in reqs.readlines() if not req.startswith('#') or req.strip() == '']
-
-setuptools.setup(
- name='ansible-webui',
- version='0.0.1',
- author='AnsibleGuy',
- author_email='contact@ansibleguy.net',
- description='Basic WebUI for using Ansible',
- long_description=long_description,
- long_description_content_type='text/markdown',
- url='https://github.com/ansibleguy/ansible-webui',
- project_urls={
- 'Repository': 'https://github.com/ansibleguy/ansible-webui',
- 'Bug Tracker': 'https://github.com/ansibleguy/ansible-webui/issues',
- },
- classifiers=[
- 'Programming Language :: Python :: 3',
- 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
- 'Operating System :: OS Independent',
- ],
- python_requires='>=3.5',
- install_requires=requirements,
-)
diff --git a/ansible-webui/__init__.py b/src/ansible-webui/__init__.py
similarity index 100%
rename from ansible-webui/__init__.py
rename to src/ansible-webui/__init__.py
diff --git a/ansible-webui/__main__.py b/src/ansible-webui/__main__.py
similarity index 86%
rename from ansible-webui/__main__.py
rename to src/ansible-webui/__main__.py
index 02b0cf8..ab15a3b 100644
--- a/ansible-webui/__main__.py
+++ b/src/ansible-webui/__main__.py
@@ -14,11 +14,12 @@
sys_path.append(os_path.dirname(os_path.abspath(__file__)))
from main import main
- from aw.config.hardcoded import VERSION
+ from aw.config.main import VERSION
if len(sys_argv) > 1:
if sys_argv[1] == 'version':
print(VERSION)
sys_exit(0)
+ print(f'Ansible-WebUI Version {VERSION}')
main()
diff --git a/ansible-webui/aw/__init__.py b/src/ansible-webui/aw/__init__.py
similarity index 100%
rename from ansible-webui/aw/__init__.py
rename to src/ansible-webui/aw/__init__.py
diff --git a/ansible-webui/aw/admin.py b/src/ansible-webui/aw/admin.py
similarity index 100%
rename from ansible-webui/aw/admin.py
rename to src/ansible-webui/aw/admin.py
diff --git a/ansible-webui/aw/apps.py b/src/ansible-webui/aw/apps.py
similarity index 100%
rename from ansible-webui/aw/apps.py
rename to src/ansible-webui/aw/apps.py
diff --git a/ansible-webui/aw/config/__init__.py b/src/ansible-webui/aw/config/__init__.py
similarity index 100%
rename from ansible-webui/aw/config/__init__.py
rename to src/ansible-webui/aw/config/__init__.py
diff --git a/ansible-webui/aw/config/environment.py b/src/ansible-webui/aw/config/environment.py
similarity index 100%
rename from ansible-webui/aw/config/environment.py
rename to src/ansible-webui/aw/config/environment.py
diff --git a/ansible-webui/aw/config/hardcoded.py b/src/ansible-webui/aw/config/hardcoded.py
similarity index 72%
rename from ansible-webui/aw/config/hardcoded.py
rename to src/ansible-webui/aw/config/hardcoded.py
index 5daa823..d0b8856 100644
--- a/ansible-webui/aw/config/hardcoded.py
+++ b/src/ansible-webui/aw/config/hardcoded.py
@@ -1,5 +1,3 @@
-VERSION = "0.0.1"
-
ENV_KEY_DEPLOYMENT = 'AW_ENV'
ENV_KEY_SERVE_STATIC = 'AW_STATIC'
ENV_KEY_DB = 'AW_DB'
@@ -11,9 +9,3 @@
LOGOUT_PATH = '/o/'
LOG_TIME_FORMAT = '%Y-%m-%d %H:%M:%S %z'
RUNNER_TMP_DIR_TIME_FORMAT = '%Y-%m-%d_%H-%M-%S'
-
-PERMISSIONS = dict(
- access='AW_ACCESS',
- write='AW_WRITE',
- exec='AW_EXEC',
-)
diff --git a/ansible-webui/aw/config/main.py b/src/ansible-webui/aw/config/main.py
similarity index 80%
rename from ansible-webui/aw/config/main.py
rename to src/ansible-webui/aw/config/main.py
index 46d45e8..cf4890b 100644
--- a/ansible-webui/aw/config/main.py
+++ b/src/ansible-webui/aw/config/main.py
@@ -1,11 +1,16 @@
from os import environ
+from importlib.metadata import version
from pytz import all_timezones
from aw.config.environment import ENVIRON_FALLBACK
+VERSION = environ['AW_VERSION'] if 'AW_VERSION' in environ else version('ansible-webui')
+
+
def init_globals():
+ # pylint: disable=W0601
global config
config = {}
diff --git a/ansible-webui/aw/config/navigation.py b/src/ansible-webui/aw/config/navigation.py
similarity index 93%
rename from ansible-webui/aw/config/navigation.py
rename to src/ansible-webui/aw/config/navigation.py
index 89ecf91..c14f5a9 100644
--- a/ansible-webui/aw/config/navigation.py
+++ b/src/ansible-webui/aw/config/navigation.py
@@ -34,7 +34,8 @@
'login': False,
},
'LO': {
- 'element': '',
+ 'element': '',
'url': LOGOUT_PATH,
'login': True,
},
diff --git a/ansible-webui/aw/execute/__init__.py b/src/ansible-webui/aw/execute/__init__.py
similarity index 100%
rename from ansible-webui/aw/execute/__init__.py
rename to src/ansible-webui/aw/execute/__init__.py
diff --git a/ansible-webui/aw/execute/play.py b/src/ansible-webui/aw/execute/play.py
similarity index 100%
rename from ansible-webui/aw/execute/play.py
rename to src/ansible-webui/aw/execute/play.py
diff --git a/ansible-webui/aw/execute/util.py b/src/ansible-webui/aw/execute/util.py
similarity index 98%
rename from ansible-webui/aw/execute/util.py
rename to src/ansible-webui/aw/execute/util.py
index 45f31ce..f68ab1d 100644
--- a/ansible-webui/aw/execute/util.py
+++ b/src/ansible-webui/aw/execute/util.py
@@ -74,7 +74,7 @@ def _runner_options(job: Job, execution: JobExecution) -> dict:
}
-def runner_prep(job: Job, execution: (JobExecution, None)):
+def runner_prep(job: Job, execution: (JobExecution, None)) -> dict:
if execution is None:
execution = JobExecution(user=None, job=job, comment='Scheduled')
@@ -106,6 +106,8 @@ def runner_prep(job: Job, execution: (JobExecution, None)):
_update_execution_status(execution, status='Running')
+ return opts
+
def runner_cleanup(opts: dict):
rmtree(opts['private_data_dir'])
diff --git a/ansible-webui/aw/main.py b/src/ansible-webui/aw/main.py
similarity index 100%
rename from ansible-webui/aw/main.py
rename to src/ansible-webui/aw/main.py
diff --git a/ansible-webui/aw/migrations/__init__.py b/src/ansible-webui/aw/migrations/__init__.py
similarity index 100%
rename from ansible-webui/aw/migrations/__init__.py
rename to src/ansible-webui/aw/migrations/__init__.py
diff --git a/ansible-webui/aw/model/__init__.py b/src/ansible-webui/aw/model/__init__.py
similarity index 100%
rename from ansible-webui/aw/model/__init__.py
rename to src/ansible-webui/aw/model/__init__.py
diff --git a/ansible-webui/aw/model/base.py b/src/ansible-webui/aw/model/base.py
similarity index 100%
rename from ansible-webui/aw/model/base.py
rename to src/ansible-webui/aw/model/base.py
diff --git a/ansible-webui/aw/model/job.py b/src/ansible-webui/aw/model/job.py
similarity index 96%
rename from ansible-webui/aw/model/job.py
rename to src/ansible-webui/aw/model/job.py
index a71ff0e..4843c59 100644
--- a/ansible-webui/aw/model/job.py
+++ b/src/ansible-webui/aw/model/job.py
@@ -101,8 +101,8 @@ class JobExecutionResultHost(BareModel):
tasks_ignored = models.PositiveSmallIntegerField(default=0)
tasks_changed = models.PositiveSmallIntegerField(default=0)
- error = models.ForeignKey(JobError, on_delete=models.CASCADE, related_name=f"jobresulthost_fk_error")
- result = models.ForeignKey(JobExecutionResult, on_delete=models.CASCADE, related_name=f"jobresulthost_fk_result")
+ error = models.ForeignKey(JobError, on_delete=models.CASCADE, related_name='jobresulthost_fk_error')
+ result = models.ForeignKey(JobExecutionResult, on_delete=models.CASCADE, related_name='jobresulthost_fk_result')
def __str__(self) -> str:
if int(self.tasks_failed) > 0:
@@ -126,11 +126,11 @@ class JobExecution(MetaJob):
# NOTE: scheduled execution will have no user
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True,
- related_name=f"jobexec_fk_user"
+ related_name='jobexec_fk_user'
)
- job = models.ForeignKey(Job, on_delete=models.CASCADE, related_name=f"jobexec_fk_job")
+ job = models.ForeignKey(Job, on_delete=models.CASCADE, related_name='jobexec_fk_job')
result = models.ForeignKey(
- JobExecutionResult, on_delete=models.CASCADE, related_name=f"jobexec_fk_result",
+ JobExecutionResult, on_delete=models.CASCADE, related_name='jobexec_fk_result',
null=True, default=None, # execution is created before result is available
)
status = models.PositiveSmallIntegerField(default=0, choices=CHOICES_JOB_EXEC_STATUS)
diff --git a/ansible-webui/aw/models.py b/src/ansible-webui/aw/models.py
similarity index 85%
rename from ansible-webui/aw/models.py
rename to src/ansible-webui/aw/models.py
index fac465c..651182d 100644
--- a/ansible-webui/aw/models.py
+++ b/src/ansible-webui/aw/models.py
@@ -1,2 +1,3 @@
+# pylint: disable=W0611
from aw.model.job import JobError, JobExecution, Job, JobPermission, JobPermissionMemberGroup, \
JobPermissionMemberUser, JobExecutionResult
diff --git a/ansible-webui/aw/route.py b/src/ansible-webui/aw/route.py
similarity index 84%
rename from ansible-webui/aw/route.py
rename to src/ansible-webui/aw/route.py
index d324a21..54e714c 100644
--- a/ansible-webui/aw/route.py
+++ b/src/ansible-webui/aw/route.py
@@ -1,10 +1,9 @@
-from django.contrib.auth.decorators import login_required, user_passes_test
+from django.contrib.auth.decorators import login_required # user_passes_test
from django.shortcuts import HttpResponse, redirect, render
from django.conf import settings
from django.contrib.auth.views import logout_then_login
from aw.config.hardcoded import LOGIN_PATH
-from aw.permission import authorized_to_exec, authorized_to_write
def _deny(request) -> (bool, HttpResponse):
@@ -16,6 +15,7 @@ def _deny(request) -> (bool, HttpResponse):
@login_required
def ui(request, **kwargs):
+ del kwargs
bad, deny = _deny(request)
if bad:
return deny
@@ -29,20 +29,23 @@ def ui(request, **kwargs):
return render(request, status=200, template_name='fallback.html', context={'content': 'OK - read'})
+# @user_passes_test(authorized_to_write, login_url=LOGIN_PATH)
@login_required
-@user_passes_test(authorized_to_write, login_url=LOGIN_PATH)
def ui_write(request, **kwargs):
+ del kwargs
return render(request, status=200, template_name='fallback.html', context={'content': 'OK - write'})
+# @user_passes_test(authorized_to_exec, login_url=LOGIN_PATH)
@login_required
-@user_passes_test(authorized_to_exec, login_url=LOGIN_PATH)
def ui_exec(request, **kwargs):
+ del kwargs
return render(request, status=200, template_name='fallback.html', context={'content': 'OK - exec'})
@login_required
def manage(request, **kwargs):
+ del kwargs
return render(request, status=200, template_name='fallback.html', context={
'content': ''
@@ -50,10 +53,12 @@ def manage(request, **kwargs):
def not_implemented(request, **kwargs):
+ del kwargs
return render(request, status=404, template_name='fallback.html', context={'content': 'Not yet implemented'})
def catchall(request, **kwargs):
+ del kwargs
if request.user.is_authenticated:
return redirect(settings.LOGIN_REDIRECT_URL)
@@ -61,4 +66,5 @@ def catchall(request, **kwargs):
def logout(request, **kwargs):
+ del kwargs
return logout_then_login(request)
diff --git a/ansible-webui/aw/settings.py b/src/ansible-webui/aw/settings.py
similarity index 98%
rename from ansible-webui/aw/settings.py
rename to src/ansible-webui/aw/settings.py
index d580eae..748de3e 100644
--- a/ansible-webui/aw/settings.py
+++ b/src/ansible-webui/aw/settings.py
@@ -1,13 +1,11 @@
from pathlib import Path
from os import environ
-# Build paths inside the project like this: BASE_DIR / 'subdir'.
-BASE_DIR = Path(__file__).resolve().parent.parent
-
from aw.config.main import config
from aw.config.hardcoded import LOGIN_PATH, ENV_KEY_DB
from aw.utils.deployment import deployment_dev, deployment_prod
+BASE_DIR = Path(__file__).resolve().parent.parent
DEBUG = deployment_dev()
ALLOWED_HOSTS = ['*']
diff --git a/ansible-webui/aw/static/css/aw.css b/src/ansible-webui/aw/static/css/aw.css
similarity index 100%
rename from ansible-webui/aw/static/css/aw.css
rename to src/ansible-webui/aw/static/css/aw.css
diff --git a/ansible-webui/aw/static/css/aw_mobile.css b/src/ansible-webui/aw/static/css/aw_mobile.css
similarity index 100%
rename from ansible-webui/aw/static/css/aw_mobile.css
rename to src/ansible-webui/aw/static/css/aw_mobile.css
diff --git a/ansible-webui/aw/templates/body.html b/src/ansible-webui/aw/templates/body.html
similarity index 100%
rename from ansible-webui/aw/templates/body.html
rename to src/ansible-webui/aw/templates/body.html
diff --git a/ansible-webui/aw/templates/error/403.html b/src/ansible-webui/aw/templates/error/403.html
similarity index 100%
rename from ansible-webui/aw/templates/error/403.html
rename to src/ansible-webui/aw/templates/error/403.html
diff --git a/ansible-webui/aw/templates/error/500.html b/src/ansible-webui/aw/templates/error/500.html
similarity index 100%
rename from ansible-webui/aw/templates/error/500.html
rename to src/ansible-webui/aw/templates/error/500.html
diff --git a/ansible-webui/aw/templates/error/js_disabled.html b/src/ansible-webui/aw/templates/error/js_disabled.html
similarity index 100%
rename from ansible-webui/aw/templates/error/js_disabled.html
rename to src/ansible-webui/aw/templates/error/js_disabled.html
diff --git a/ansible-webui/aw/templates/fallback.html b/src/ansible-webui/aw/templates/fallback.html
similarity index 100%
rename from ansible-webui/aw/templates/fallback.html
rename to src/ansible-webui/aw/templates/fallback.html
diff --git a/ansible-webui/aw/templates/head.html b/src/ansible-webui/aw/templates/head.html
similarity index 100%
rename from ansible-webui/aw/templates/head.html
rename to src/ansible-webui/aw/templates/head.html
diff --git a/ansible-webui/aw/templates/nav.html b/src/ansible-webui/aw/templates/nav.html
similarity index 100%
rename from ansible-webui/aw/templates/nav.html
rename to src/ansible-webui/aw/templates/nav.html
diff --git a/ansible-webui/aw/templates/registration/login.html b/src/ansible-webui/aw/templates/registration/login.html
similarity index 100%
rename from ansible-webui/aw/templates/registration/login.html
rename to src/ansible-webui/aw/templates/registration/login.html
diff --git a/ansible-webui/aw/templatetags/__init__.py b/src/ansible-webui/aw/templatetags/__init__.py
similarity index 100%
rename from ansible-webui/aw/templatetags/__init__.py
rename to src/ansible-webui/aw/templatetags/__init__.py
diff --git a/ansible-webui/aw/templatetags/util.py b/src/ansible-webui/aw/templatetags/util.py
similarity index 93%
rename from ansible-webui/aw/templatetags/util.py
rename to src/ansible-webui/aw/templatetags/util.py
index 44f1d5b..bef2202 100644
--- a/ansible-webui/aw/templatetags/util.py
+++ b/src/ansible-webui/aw/templatetags/util.py
@@ -1,6 +1,6 @@
from django import template
-from aw.config.hardcoded import VERSION
+from aw.config.main import VERSION
from aw.config.navigation import NAVIGATION
diff --git a/ansible-webui/aw/utils/__init__.py b/src/ansible-webui/aw/utils/__init__.py
similarity index 100%
rename from ansible-webui/aw/utils/__init__.py
rename to src/ansible-webui/aw/utils/__init__.py
diff --git a/ansible-webui/aw/utils/debug.py b/src/ansible-webui/aw/utils/debug.py
similarity index 100%
rename from ansible-webui/aw/utils/debug.py
rename to src/ansible-webui/aw/utils/debug.py
diff --git a/ansible-webui/aw/utils/deployment.py b/src/ansible-webui/aw/utils/deployment.py
similarity index 100%
rename from ansible-webui/aw/utils/deployment.py
rename to src/ansible-webui/aw/utils/deployment.py
diff --git a/ansible-webui/aw/utils/handlers.py b/src/ansible-webui/aw/utils/handlers.py
similarity index 100%
rename from ansible-webui/aw/utils/handlers.py
rename to src/ansible-webui/aw/utils/handlers.py
diff --git a/ansible-webui/aw/utils/util.py b/src/ansible-webui/aw/utils/util.py
similarity index 94%
rename from ansible-webui/aw/utils/util.py
rename to src/ansible-webui/aw/utils/util.py
index 1ba9dee..35ed0d0 100644
--- a/ansible-webui/aw/utils/util.py
+++ b/src/ansible-webui/aw/utils/util.py
@@ -13,3 +13,5 @@ def get_choice_key_by_value(choices: list[tuple], value):
for k, v in choices:
if v == value:
return k
+
+ return None
diff --git a/ansible-webui/aw/utils/util_test.py b/src/ansible-webui/aw/utils/util_test.py
similarity index 100%
rename from ansible-webui/aw/utils/util_test.py
rename to src/ansible-webui/aw/utils/util_test.py
diff --git a/ansible-webui/base/__init__.py b/src/ansible-webui/base/__init__.py
similarity index 100%
rename from ansible-webui/base/__init__.py
rename to src/ansible-webui/base/__init__.py
diff --git a/ansible-webui/base/scheduler.py b/src/ansible-webui/base/scheduler.py
similarity index 64%
rename from ansible-webui/base/scheduler.py
rename to src/ansible-webui/base/scheduler.py
index 025c6aa..7cb27b0 100644
--- a/ansible-webui/base/scheduler.py
+++ b/src/ansible-webui/base/scheduler.py
@@ -1,5 +1,12 @@
+import signal
+from os import getpid
+from os import kill as os_kill
+from sys import exit as sys_exit
+from threading import Thread
from time import sleep, time
+from gunicorn.arbiter import Arbiter
+
from base.threader import ThreadManager
from aw.utils.debug import log
from aw.config.hardcoded import RELOAD_INTERVAL
@@ -45,8 +52,8 @@ def _signum_log(signum):
def _thread(self, job: Job, execution: JobExecution = None):
# todo: creation of execution object for ad-hoc execution (with user-provided values)
- self.thread_manager.add_thread(job)
- self.thread_manager.start_thread(job)
+ self.thread_manager.add_thread(job=job, execution=execution)
+ self.thread_manager.start_thread(job=job)
def start(self):
log('Starting..', level=3)
@@ -57,6 +64,7 @@ def start(self):
self._run()
def _run(self):
+ # pylint: disable=W0718
try:
sleep(self.WAIT_TIME)
log('Entering Scheduler runtime', level=7)
@@ -76,3 +84,30 @@ def _run(self):
print(f'ERROR: {err}')
self.stop()
return
+
+
+def init_scheduler():
+ scheduler = Scheduler()
+ scheduler_thread = Thread(target=scheduler.start)
+
+ # override gunicorn signal handling to allow for graceful shutdown
+ Arbiter.SIGNALS.remove(signal.SIGHUP)
+ Arbiter.SIGNALS.remove(signal.SIGINT)
+ Arbiter.SIGNALS.remove(signal.SIGTERM)
+
+ def signal_exit(signum=None, stack=None):
+ del stack
+ scheduler.stop(signum)
+ os_kill(getpid(), signal.SIGQUIT) # trigger 'Arbiter.stop'
+ sleep(3)
+ sys_exit(0)
+
+ def signal_reload(signum=None, stack=None):
+ del stack
+ scheduler.reload(signum)
+
+ signal.signal(signal.SIGHUP, signal_reload)
+ signal.signal(signal.SIGINT, signal_exit)
+ signal.signal(signal.SIGTERM, signal_exit)
+
+ scheduler_thread.start()
diff --git a/ansible-webui/base/serve_static.py b/src/ansible-webui/base/serve_static.py
similarity index 92%
rename from ansible-webui/base/serve_static.py
rename to src/ansible-webui/base/serve_static.py
index a929d93..b85e172 100644
--- a/ansible-webui/base/serve_static.py
+++ b/src/ansible-webui/base/serve_static.py
@@ -22,12 +22,13 @@ def serve(request, path, **kwargs):
if not absolute_path:
if path.endswith("/") or path == "":
raise Http404('Directory indexes are not allowed here.')
- raise Http404("'%s' could not be found" % path)
+ raise Http404(f"'{path}' could not be found")
document_root, path = os_path.split(absolute_path)
return static.serve(request, path, document_root=document_root, **kwargs)
+# pylint: disable=C0209
urlpatterns_static = [re_path(
r"^%s(?P.*)$" % regex_escape(settings.STATIC_URL.lstrip('/')), serve,
)]
diff --git a/ansible-webui/base/threader.py b/src/ansible-webui/base/threader.py
similarity index 89%
rename from ansible-webui/base/threader.py
rename to src/ansible-webui/base/threader.py
index 04c613e..b666cdb 100644
--- a/ansible-webui/base/threader.py
+++ b/src/ansible-webui/base/threader.py
@@ -52,17 +52,15 @@ def run(self) -> None:
self.manager.threads.remove(self.job)
return
- else:
- wait_sec = self.cron.next()
- log(f"Next execution of job {self.log_name} in {wait_sec}s", level=7)
- while not self.state_stop.wait(wait_sec):
- if self.state_stop.is_set():
- log(f"Exiting thread {self.log_name}", level=5)
- break
-
- else:
- log(f"Starting job {self.log_name}", level=5)
- self.run_playbook()
+ wait_sec = self.cron.next()
+ log(f"Next execution of job {self.log_name} in {wait_sec}s", level=7)
+ while not self.state_stop.wait(wait_sec):
+ if self.state_stop.is_set():
+ log(f"Exiting thread {self.log_name}", level=5)
+ break
+
+ log(f"Starting job {self.log_name}", level=5)
+ self.run_playbook()
except ValueError as err:
log(f"Got unexpected error while executing job {self.log_name}: '{err}'")
diff --git a/ansible-webui/base/webserver.py b/src/ansible-webui/base/webserver.py
similarity index 91%
rename from ansible-webui/base/webserver.py
rename to src/ansible-webui/base/webserver.py
index 5516ee2..2034676 100644
--- a/ansible-webui/base/webserver.py
+++ b/src/ansible-webui/base/webserver.py
@@ -39,15 +39,17 @@ def load_config(self):
def init_webserver():
gunicorn.SERVER = ''.join(random_choice(ascii_letters) for _ in range(10))
- run_options = {
+ opts = {
'workers': (cpu_count() * 2) + 1,
**OPTIONS_PROD
}
if deployment_dev():
warn_if_development()
- run_options = {**run_options, **OPTIONS_DEV}
+ opts = {**opts, **OPTIONS_DEV}
+
+ print(f"Listening on http://{opts['bind']}")
StandaloneApplication(
app_uri="aw.main:app",
- options=run_options
+ options=opts
).run()
diff --git a/src/ansible-webui/main.py b/src/ansible-webui/main.py
new file mode 100644
index 0000000..6b1ecb9
--- /dev/null
+++ b/src/ansible-webui/main.py
@@ -0,0 +1,21 @@
+from platform import uname
+
+from django import setup as django_setup
+
+from aw.config.main import init_globals
+
+init_globals()
+
+
+def main():
+ if uname().system.lower() != 'linux':
+ raise SystemError('Currently only linux systems are supported!')
+
+ django_setup()
+
+ # pylint: disable=C0415
+ from base.webserver import init_webserver
+ from base.scheduler import init_scheduler
+
+ init_scheduler()
+ init_webserver()
diff --git a/ansible-webui/manage.py b/src/ansible-webui/manage.py
similarity index 100%
rename from ansible-webui/manage.py
rename to src/ansible-webui/manage.py
diff --git a/ansible-webui/route.py b/src/ansible-webui/route.py
similarity index 100%
rename from ansible-webui/route.py
rename to src/ansible-webui/route.py