Skip to content

Commit

Permalink
fixes for running the app via 'python3 -m ansible-webui'
Browse files Browse the repository at this point in the history
  • Loading branch information
ansibleguy committed Jan 17, 2024
1 parent 8819ae2 commit 946b75c
Show file tree
Hide file tree
Showing 23 changed files with 173 additions and 99 deletions.
34 changes: 33 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 1
timeout-minutes: 3

steps:
- name: Checkout
Expand All @@ -35,6 +35,7 @@ jobs:
- name: Install dependencies
run: |
pip install -r requirements_test.txt
pip install -r requirements_build.txt
pip install -r requirements.txt
shell: bash

Expand All @@ -54,6 +55,37 @@ jobs:
shell: bash
working-directory: ansible-webui/

- name: Testing to start Ansible-WebUI
run: |
timeout 2 python3 ansible-webui
ec="$?"
if [[ "$ec" != "124" ]]
then
exit 1
fi
shell: bash

- name: Running Tests
run: python3 -m pytest
shell: bash

- name: Testing to build Ansible-WebUI with PIP
run: |
path_repo="$(pwd)"
cd /tmp
tmp_venv="/tmp/ansible-webui-venv/$(date +%s)"
python3 -m virtualenv "$tmp_venv" >/dev/null
source "${tmp_venv}/bin/activate"
python3 -m pip install -e "$path_repo" >/dev/null
timeout 2 python3 -m ansible-webui
ec="$?"
deactivate
rm -rf "$tmp_venv"
if [[ "$ec" != "124" ]]
then
exit 1
fi
shell: bash
5 changes: 5 additions & 0 deletions CONTRIBUTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ Admin user for testing:
* User: `ansible`
* Pwd: `automateMe`

Test to build the app using PIP:
```bash
bash ${REPO}/scripts/run_pip_build.sh
```

Run tests and lint:

```bash
Expand Down
15 changes: 0 additions & 15 deletions ansible-webui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +0,0 @@
#!/usr/bin/env python3

if __name__ == '__main__':
# pylint: disable=E0401
from sys import argv as sys_argv
from sys import exit as sys_exit
from main import main
from aw.config.hardcoded import VERSION

if len(sys_argv) > 1:
if sys_argv[1] == 'version':
print(VERSION)
sys_exit(0)

main()
24 changes: 24 additions & 0 deletions ansible-webui/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python3

if __name__ == '__main__':
# pylint: disable=E0401
from sys import argv as sys_argv
from sys import exit as sys_exit
from sys import path as sys_path
from os import path as os_path

try:
from main import main

except ModuleNotFoundError:
sys_path.append(os_path.dirname(os_path.abspath(__file__)))
from main import main

from aw.config.hardcoded import VERSION

if len(sys_argv) > 1:
if sys_argv[1] == 'version':
print(VERSION)
sys_exit(0)

main()
4 changes: 4 additions & 0 deletions ansible-webui/aw/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ def init_globals():
global config
config = {}

environ.setdefault('DJANGO_SETTINGS_MODULE', 'aw.settings')
environ['PYTHONIOENCODING'] = 'utf8'
environ['PYTHONUNBUFFERED'] = '1'

for cnf_key, values in ENVIRON_FALLBACK.items():
for env_key in values['keys']:
if env_key in environ:
Expand Down
2 changes: 1 addition & 1 deletion ansible-webui/aw/execute/play.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from aw.execute.util import runner_cleanup, runner_prep, parse_run_result


def ansible_playbook(job: Job, execution: JobExecution):
def ansible_playbook(job: Job, execution: (JobExecution, None)):
time_start = datetime.now()
opts = runner_prep(job=job, execution=execution)

Expand Down
5 changes: 4 additions & 1 deletion ansible-webui/aw/execute/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ def _runner_options(job: Job, execution: JobExecution) -> dict:
}


def runner_prep(job: Job, execution: JobExecution):
def runner_prep(job: Job, execution: (JobExecution, None)):
if execution is None:
execution = JobExecution(user=None, job=job, comment='Scheduled')

_update_execution_status(execution, status='Starting')

opts = _runner_options(job=job, execution=execution)
Expand Down
6 changes: 0 additions & 6 deletions ansible-webui/aw/main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
from os import environ

from django.core.wsgi import get_wsgi_application

environ.setdefault('DJANGO_SETTINGS_MODULE', 'aw.settings')
environ['PYTHONIOENCODING'] = 'utf8'
environ['PYTHONUNBUFFERED'] = '1'

app = get_wsgi_application()
4 changes: 3 additions & 1 deletion ansible-webui/aw/model/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ def __str__(self) -> str:


class JobExecution(MetaJob):
# NOTE: scheduled execution will have no user
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.PROTECT, blank=True, null=True,
settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True,
related_name=f"jobexec_fk_user"
)
job = models.ForeignKey(Job, on_delete=models.CASCADE, related_name=f"jobexec_fk_job")
Expand All @@ -133,6 +134,7 @@ class JobExecution(MetaJob):
null=True, default=None, # execution is created before result is available
)
status = models.PositiveSmallIntegerField(default=0, choices=CHOICES_JOB_EXEC_STATUS)
comment = models.CharField(max_length=300, null=True, default=None)

def __str__(self) -> str:
status_name = CHOICES_JOB_EXEC_STATUS[int(self.status)][1]
Expand Down
1 change: 0 additions & 1 deletion ansible-webui/aw/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
X_FRAME_OPTIONS = 'SAMEORIGIN'

# Application definition
INSTALLED_APPS = [
'aw.apps.AwConfig',
'django.contrib.admin',
Expand Down
2 changes: 1 addition & 1 deletion ansible-webui/aw/utils/handlers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.shortcuts import render

from utils.debug import log
from aw.utils.debug import log


class AnsibleConfigError(Exception):
Expand Down
17 changes: 8 additions & 9 deletions ansible-webui/base/scheduler.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
from time import sleep, time

from base.threader import Loop as Threader
from base.threader import ThreadManager
from aw.utils.debug import log
from aw.config.hardcoded import RELOAD_INTERVAL

# NOTE: not able to use models here because of dependency on django-init
# from aw.model.job import Job
from aw.model.job import Job, JobExecution


class Scheduler:
WAIT_TIME = 1

def __init__(self):
self.threader = Threader()
self.thread_manager = ThreadManager()
self.stopping = False
self.reloading = False

Expand All @@ -23,7 +21,7 @@ def stop(self, signum=None):
self.stopping = True

log('Stopping job-threads', level=6)
self.threader.stop()
self.thread_manager.stop()

sleep(self.WAIT_TIME)
log('Finished!')
Expand All @@ -45,9 +43,10 @@ def reload(self, signum=None):
def _signum_log(signum):
log(f'Scheduler got signal {signum}')

def _thread(self, job):
self.threader.add_thread(job)
self.threader.start_thread(job)
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)

def start(self):
log('Starting..', level=3)
Expand Down
File renamed without changes.
32 changes: 18 additions & 14 deletions ansible-webui/base/threader.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@

from aw.utils.debug import log
from aw.config import hardcoded
from aw.model.job import Job, JobExecution
from aw.execute.play import ansible_playbook

# NOTE: not able to use models here because of dependency on django-init
# from aw.model.job import Job


class Workload(Thread):
def __init__(self, job, loop_instance, name: str, once: bool = False, daemon: bool = True):
def __init__(self, job: Job, manager, name: str, execution: JobExecution, once: bool = False, daemon: bool = True):
Thread.__init__(self, daemon=daemon, name=name)
self.job = job
self.loop_instance = loop_instance
self.execution = execution
self.manager = manager
self.once = once
self.started = False
self.state_stop = Event()
Expand All @@ -40,13 +39,17 @@ def stop(self) -> bool:
self.started = False
return True

def run_playbook(self):
ansible_playbook(job=self.job, execution=self.execution)

def run(self) -> None:
self.started = True
log(f"Entering runtime of thread {self.log_name}", level=7)
try:
if self.once:
ansible_playbook(self.job)
Loop.stop_thread(self.loop_instance, self.job)
self.run_playbook()
self.stop()
self.manager.threads.remove(self.job)
return

else:
Expand All @@ -59,14 +62,14 @@ def run(self) -> None:

else:
log(f"Starting job {self.log_name}", level=5)
ansible_playbook(self.job)
self.run_playbook()

except ValueError as err:
log(f"Got unexpected error while executing job {self.log_name}: '{err}'")
self.run()


class Loop:
class ThreadManager:
def __init__(self):
self.threads = set()
self.thread_nr = 0
Expand All @@ -79,13 +82,14 @@ def start(self) -> None:
if not thread.started:
thread.start()

def add_thread(self, job, once: bool = False):
def add_thread(self, job: Job, execution: JobExecution = None, once: bool = False):
log(f"Adding thread for \"{job.name}\" with schedule \"{job.schedule}\"", level=7)
self.thread_nr += 1
self.threads.add(
Workload(
job=job,
loop_instance=self,
execution=execution,
manager=self,
once=once,
name=f"Thread #{self.thread_nr}",
)
Expand All @@ -108,7 +112,7 @@ def stop(self) -> bool:
log('All threads stopped', level=3)
return True

def stop_thread(self, job):
def stop_thread(self, job: Job):
log(f"Stopping thread for \"{job.name}\"", level=6)
for thread in self.threads:
if thread.job.job_id == job.job_id:
Expand All @@ -119,15 +123,15 @@ def stop_thread(self, job):
del job
break

def start_thread(self, job) -> None:
def start_thread(self, job: Job) -> None:
for thread in self.threads:
if thread.job.job_id == job.job_id:
if not thread.started:
thread.start()
log(f"Thread {job.name} started.", level=5)
break

def replace_thread(self, job) -> None:
def replace_thread(self, job: Job) -> None:
log(f"Reloading thread for \"{job.name}\"", level=6)
self.stop_thread(job)
self.add_thread(job)
Expand Down
6 changes: 3 additions & 3 deletions ansible-webui/base/webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def load_config(self):
self.cfg.set(key.lower(), value)


def create_webserver() -> WSGIApplication:
def init_webserver():
gunicorn.SERVER = ''.join(random_choice(ascii_letters) for _ in range(10))
run_options = {
'workers': (cpu_count() * 2) + 1,
Expand All @@ -47,7 +47,7 @@ def create_webserver() -> WSGIApplication:
warn_if_development()
run_options = {**run_options, **OPTIONS_DEV}

return StandaloneApplication(
StandaloneApplication(
app_uri="aw.main:app",
options=run_options
)
).run()
Loading

0 comments on commit 946b75c

Please sign in to comment.