Compare commits

..

3 commits

4 changed files with 33 additions and 24 deletions

View file

@ -43,17 +43,21 @@ class WoodpeckerRunner(Thread):
result = RunnerResult() result = RunnerResult()
try: try:
service = self.get_service(self._event.files) services = self.get_service(self._event.files)
if service is None: if len(services) == 0:
logger.info("No service found.") logger.info("No service found.")
result.success = True result.success = True
else: else:
service_path = f"{self._root}/compose/{service}/docker-compose.yml"
self._git.checkout(self._event.commit) self._git.checkout(self._event.commit)
for file in self._event.files: paths = []
if file.__contains__('.mo.'): for service in services:
self._mo.process(Path(f"{self._root}{file}").absolute()) service_path = f"{self._root}/compose/{service}/docker-compose.yml"
self._docker.reload(Path(service_path).absolute()) for file in self._event.files:
if file.__contains__('.mo.'):
self._mo.process(Path(f"{self._root}{file}").absolute())
paths.append(service_path)
for service_path in paths:
self._docker.reload(Path(service_path).absolute())
result.success = True result.success = True
except Exception as e: except Exception as e:
result.throwable = e result.throwable = e
@ -61,20 +65,14 @@ class WoodpeckerRunner(Thread):
asyncio.run(dispatch(result)) asyncio.run(dispatch(result))
@staticmethod @staticmethod
def get_service(files: list[str]) -> str | None: def get_service(files: list[str]) -> list[str]:
supported_files = [] supported_files = []
for f in files: for f in files:
f_parts = f.split("/") f_parts = f.split("/")
if f_parts[0] in ["compose", "files"]: if f_parts[0] in ["compose", "files"]:
supported_files.append(f_parts[1]) supported_files.append(f_parts[1])
match len(set(supported_files)): # TODO: check service priorities (NGINX last)
case 0: return list(dict.fromkeys(supported_files))
return None
case 1:
return supported_files[0]
case _:
logger.error(f"Multiple services were provided: {', '.join(supported_files)}")
raise Exception("Multiple services are not supported.")
@injectable(singleton=True) @injectable(singleton=True)

View file

@ -15,6 +15,8 @@ class DockerService:
def reload(self, compose_path: Path): def reload(self, compose_path: Path):
os.chdir(compose_path.parent) os.chdir(compose_path.parent)
self._client.compose.ps() # TODO: Check if container needs to be reloaded from scratch
self._client.compose.down(remove_orphans=True) # if len(self._client.compose.ps()) > 0:
# self._client.compose.restart()
# return
self._client.compose.up(detach=True) self._client.compose.up(detach=True)

View file

@ -32,19 +32,23 @@ class NamingCache:
class ApplicationFormatter(Formatter): class ApplicationFormatter(Formatter):
def __init__(self, handler_prefix: str = ''): def __init__(self, handler_prefix: str = '', include_timestamp: bool = True):
super().__init__() super().__init__()
self._logger_names = NamingCache() self._logger_names = NamingCache()
self._handler_prefix = handler_prefix self._handler_prefix = handler_prefix
self._include_timestamp = include_timestamp
def format(self, record): def format(self, record):
from datetime import datetime from datetime import datetime
timestamp = datetime.fromtimestamp(record.created).isoformat(sep=' ', timespec='milliseconds') if self._include_timestamp:
timestamp = datetime.fromtimestamp(record.created).isoformat(sep=' ', timespec='milliseconds') + ' '
else:
timestamp = ''
level = record.levelname.replace('WARNING', 'WARN').rjust(5) level = record.levelname.replace('WARNING', 'WARN').rjust(5)
thread_name = record.threadName.replace(' (', '#').replace(')', '').rjust(16)[-16:] # TODO: NamingCache? thread_name = record.threadName.replace(' (', '#').replace(')', '').rjust(16)[-16:] # TODO: NamingCache?
logger_name = self._logger_names[f"{self._handler_prefix}{record.name}"] logger_name = self._logger_names[f"{self._handler_prefix}{record.name}"]
message = record.getMessage() message = record.getMessage()
formatted = f"{timestamp} {level} [{thread_name}] {logger_name} : {message}" formatted = f"{timestamp}{level} [{thread_name}] {logger_name} : {message}"
if record.exc_info: if record.exc_info:
formatted += "\n" + self.formatException(record.exc_info) formatted += "\n" + self.formatException(record.exc_info)
@ -62,7 +66,7 @@ class HandlerFactory:
def create(target: Target, handler_prefix: str = '', file_path: Path = None) -> List[Handler]: def create(target: Target, handler_prefix: str = '', file_path: Path = None) -> List[Handler]:
def console_handler(prefix: str = ''): def console_handler(prefix: str = ''):
handler = StreamHandler() handler = StreamHandler()
handler.setFormatter(ApplicationFormatter(prefix)) handler.setFormatter(ApplicationFormatter(prefix, include_timestamp=False))
handler.setLevel('INFO') handler.setLevel('INFO')
return handler return handler

View file

@ -4,8 +4,13 @@ files = [".gitignore", "compose/nginx/docker-compose.yaml", "config/heimdall.kdb
"files/nginx/cert/key.mo.pem", "files/nginx/conf.d/default.conf", "files/nginx/conf.d/forge.conf", "files/nginx/cert/key.mo.pem", "files/nginx/conf.d/default.conf", "files/nginx/conf.d/forge.conf",
"files/nginx/conf.d/mqtt.conf", "files/nginx/conf.d/nextcloud.conf", "files/nginx/conf.d/zitadel.conf", "files/nginx/conf.d/mqtt.conf", "files/nginx/conf.d/nextcloud.conf", "files/nginx/conf.d/zitadel.conf",
"files/nginx/nginx.conf"] "files/nginx/nginx.conf"]
files2 = [".gitignore", "compose/nginx/docker-compose.yaml", "compose/nginx2/docker-compose.yaml"]
def test_get_service(): def test_get_service_single():
service = woodpecker.WoodpeckerRunner.get_service(files) service = woodpecker.WoodpeckerRunner.get_service(files)
assert service == 'nginx' assert service == ['nginx']
def test_get_service_multi():
services = woodpecker.WoodpeckerRunner.get_service(files2)
assert services == ['nginx', 'nginx2']