Skip to content

Commit

Permalink
Merge pull request #55 from ahembree/improve-actions-tests
Browse files Browse the repository at this point in the history
Improve actions tests
  • Loading branch information
ahembree authored Dec 13, 2023
2 parents dc282f5 + b92fa15 commit d8ae77d
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 7 deletions.
21 changes: 17 additions & 4 deletions .github/workflows/run-playbook.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: HMS-Docker Install Tests
run-name: Test OS Installs
name: Deployment Tests
run-name: Test Deployment
on:
push:
workflow_dispatch:
schedule:
- cron: '23 9 * * 0'

permissions:
contents: read
Expand All @@ -13,16 +14,19 @@ jobs:
steps:
- name: Check out repo code
uses: actions/checkout@v4

- name: Install ansible
run: |
sudo apt update
sudo apt install ansible make python3-pip
- name: Ensure base playbook requirements
run: |
mkdir -p ./vars/custom
cp vars/default/*.yml ./vars/custom
mv ./vars/custom/main.yml ./vars/custom/main_custom.yml
sudo make install-reqs
- name: Run playbook
run: >-
sudo ansible-playbook
Expand All @@ -32,5 +36,14 @@ jobs:
--diff
--extra-vars "
is_github_runner=yes
tautulli_jbops_enabled=yes
container_expose_ports=yes
hms_docker_plex_ssl_enabled=yes
separate_4k_instances_enable=yes
tautulli_include_jbops=yes
traefik_security_hardening=yes
"
- name: Check containers
run: |
sleep 10
sudo make verify-containers
104 changes: 104 additions & 0 deletions .github/workflows/scripts/check_containers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env python3

import sys
import docker
import os
import logging
import requests
from dotenv import load_dotenv

# Intended as the containers may host a self-signed certificate
import urllib3
urllib3.disable_warnings()

LOG_PATH = f"{os.path.dirname(os.path.abspath(__file__))}/backups.log"
logger = logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(name)s] [%(levelname)s] %(message)s",
handlers=[
logging.FileHandler(LOG_PATH, mode='a'),
logging.StreamHandler(),
])

logging.info(f'Initializing Docker client')
docker_client = docker.from_env()

def main():
container_list = docker_client.containers.list()

project = 'hms-docker'

requests_made = 0
success_codes = 0
failure_codes = 0

for cont in container_list:
try:
name = cont.name
logging.debug(f'Checking {name}')
if cont.labels['com.docker.compose.project'] == project:
workdir = cont.labels['com.docker.compose.project.working_dir']
load_dotenv(f'{workdir}/.env')
domain = os.getenv('HMSD_DOMAIN')
for port_exposures in cont.attrs['NetworkSettings']['Ports']:
port_map = cont.attrs['NetworkSettings']['Ports'][port_exposures]
if port_map is None or 'udp' in port_exposures:
continue
logging.debug(f'{name} is in project {project} and has tcp port exposure: {port_exposures}')
for mapping in port_map:
host_ip = mapping['HostIp']
host_port = mapping['HostPort']
if host_ip == '::':
continue
if host_ip == '0.0.0.0':
host_ip = '127.0.0.1'

try:
suffix = ''
ssl = False
if name == 'plex':
suffix = '/web'
ssl = True
if host_port != '32400':
logging.debug(f'Skipping {name} on {host_port} because it doesnt host a webpage')
continue
if name == 'transmission' and host_port == '8888':
logging.debug(f'Skipping {name} on {host_port} because its a proxy')
continue
if name == 'authentik-server':
name = 'authentik'
ssl = True
url = f'http{"s" if ssl else ""}://{host_ip}:{host_port}{suffix}'
host_header = f'{name}.home.{domain}'
logging.debug(f'getting {url} with Host header {host_header}')
# file deepcode ignore SSLVerificationBypass: Containers may host a self-signed certificate
response = requests.get(url, verify=False, headers={
'Host': host_header
})
requests_made += 1
status_code = response.status_code
if status_code == 200:
success_codes += 1
logging.info(f'{name}:{host_port} OK')
elif name == 'transmission-proxy' and status_code == '502':
success_codes += 1
else:
failure_codes += 1
logging.warning(f'{name}:{host_port} FAILED (Code: {status_code})')
except requests.exceptions.ConnectionError as e:
logging.error(f'Failed on port {host_port} with header {host_header}: {e}')

except KeyError as e:
logging.debug(f'{name} is not in the project {project}')
continue
fail_rate = failure_codes/requests_made
threshold = 0.34
if fail_rate > threshold:
logging.error(f'Failure rate exceeded {threshold}, it was {fail_rate}')
sys.exit(1)
else:
logging.info(f'Failure rate: {fail_rate}')
sys.exit(0)

if __name__ == '__main__':
main()
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@ apply: install-reqs
install-reqs:
@ansible-galaxy install -r galaxy-requirements.yml -p ./galaxy-roles

verify-containers:
@sudo python3 .github/workflows/scripts/check_containers.py

help:
@echo make basic :: for a basic config
@echo make advanced :: for an advanced config
@echo make basic :: setup a basic config
@echo make advanced :: setup an advanced config
@echo make check :: check for any changes without doing anything \(diff\)
@echo make apply :: apply any changes identified in the diff
@echo make install-reqs :: installs ansible galaxy role requirements
@echo make verify-containers :: checks containers exposed ports \(used in Actions\)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ansible-hms-docker

[![Ubuntu 22.04 LTS Install Test](https://github.com/ahembree/ansible-hms-docker/actions/workflows/run-playbook.yml/badge.svg)](https://github.com/ahembree/ansible-hms-docker/actions/workflows/run-playbook.yml)
[![Deployment Tests](https://github.com/ahembree/ansible-hms-docker/actions/workflows/run-playbook.yml/badge.svg)](https://github.com/ahembree/ansible-hms-docker/actions/workflows/run-playbook.yml)

Ansible Playbook to setup an automated Home Media Server stack running on Docker across a variety of platforms with support for GPUs, SSL, SSO, DDNS, and more.

Expand Down

0 comments on commit d8ae77d

Please sign in to comment.