add docs
This commit is contained in:
@@ -16,8 +16,13 @@ logger.setLevel(logging.DEBUG) #TODO: add something to change log levles
|
||||
|
||||
class Setup:
|
||||
|
||||
"""Setup class ensuring appropriate files and symlinks are created for a Composer instance"""
|
||||
|
||||
@staticmethod
|
||||
def create_symlink():
|
||||
|
||||
"""Creates a symlink between the path stored in HOST_DATA_PATH and store/data"""
|
||||
|
||||
host_data_env = getenv("HOST_DATA_PATH", None)
|
||||
if host_data_env is None:
|
||||
logger.info(f"HOST_DATA_PATH is not set, symlink not created")
|
||||
@@ -35,42 +40,65 @@ class Setup:
|
||||
|
||||
@staticmethod
|
||||
def populate_store():
|
||||
|
||||
"""Creates empty store/stack/.env file if it doesn't exist"""
|
||||
|
||||
Path("store/stack").mkdir(parents=True, exist_ok=True)
|
||||
Path("store/stack/.env").touch(exist_ok=True)
|
||||
|
||||
|
||||
class Composer:
|
||||
|
||||
"""Composer instance to manage a single docker compose stack
|
||||
|
||||
Attributes:
|
||||
docker: DockerClient instance used to interact with the compose stack
|
||||
services: list of Service objects defined by the stack
|
||||
"""
|
||||
|
||||
services = []
|
||||
docker = DockerClient(
|
||||
compose_files=["store/stack/compose.yml"],
|
||||
compose_env_files=["store/stack/.env"]
|
||||
)
|
||||
|
||||
def __init__(self, remote_url):
|
||||
|
||||
"""Initializes the Composer based on a remote_url
|
||||
|
||||
Args:
|
||||
remote_url: string containing the https location of the repo
|
||||
"""
|
||||
|
||||
if not Path("store/stack/.git").exists():
|
||||
self.repo = Repo.init("store/stack")
|
||||
self._add_remote(remote_url)
|
||||
self.repo.create_remote('origin', url)
|
||||
else:
|
||||
self.repo = Repo("store/stack")
|
||||
self.repo.remotes.origin.pull('master')
|
||||
self.docker = DockerClient(
|
||||
compose_files=["store/stack/compose.yml"],
|
||||
compose_env_files=["store/stack/.env"]
|
||||
)
|
||||
if self.docker.compose.config(return_json=True)["name"] != "stack":
|
||||
logger.warn(f"Composer stack name is wrong, either make sure it is set manually or keep it store/stack")
|
||||
self.start_update_job()
|
||||
self._create_services()
|
||||
self.set_status("up")
|
||||
logger.info("Composer started and services created")
|
||||
|
||||
def _add_remote(self, url):
|
||||
self.repo.create_remote('origin', url)
|
||||
|
||||
def _create_services(self):
|
||||
|
||||
"""Recreates service list after the Composer stack is updated"""
|
||||
|
||||
for service in self.services:
|
||||
self.services[service].close()
|
||||
services_dict = self.docker.compose.config().services
|
||||
self.services = {service: Service(service, services_dict[service].labels, self) for service in services_dict}
|
||||
|
||||
def start_update_job(self):
|
||||
|
||||
"""Schedules a recurring update based on the UPDATE environment variable
|
||||
|
||||
Each update occurs after an interval of UPDATE minutes. If UPDATE does not contain a valid integer in minutes, defaults to 1 minute.
|
||||
"""
|
||||
|
||||
update_time = getenv("UPDATE", 1)
|
||||
try:
|
||||
self.update_time = int(update_time)
|
||||
@@ -81,6 +109,13 @@ class Composer:
|
||||
schedule.every(self.update_time).minutes.do(self.update)
|
||||
|
||||
def set_status(self, status):
|
||||
|
||||
"""Sets the running status of the compose stack
|
||||
|
||||
Args:
|
||||
status: string containing "up", "down", or "restart" corresponding to the respective running state of the composer
|
||||
"""
|
||||
|
||||
try:
|
||||
if status == "up":
|
||||
self.docker.compose.up(
|
||||
@@ -103,6 +138,9 @@ class Composer:
|
||||
logger.critical(f"Setting status of composer failed: {error}")
|
||||
|
||||
def update(self):
|
||||
|
||||
"""Updates the Composer stack based on the remote repo"""
|
||||
|
||||
current = self.repo.head.commit
|
||||
self.repo.remotes.origin.pull('master')
|
||||
if current != self.repo.head.commit:
|
||||
@@ -112,23 +150,54 @@ class Composer:
|
||||
|
||||
class Service:
|
||||
|
||||
update_task = None
|
||||
"""Service instance meant to represent a container in a Composer stack
|
||||
|
||||
Attributes:
|
||||
labels: labels given to the service
|
||||
name: name given to the service
|
||||
parent: Composer instance containing the service
|
||||
"""
|
||||
|
||||
def __init__(self, name, labels, parent):
|
||||
|
||||
"""Initializes the Service instance
|
||||
|
||||
Args:
|
||||
name: name given to the service
|
||||
labels: labels given to the service
|
||||
parent: Composer instance containing the service
|
||||
"""
|
||||
|
||||
self.name = name
|
||||
self.labels = labels
|
||||
self.parent = parent
|
||||
self.update_task = self.start_update_job()
|
||||
self._update_task = self.start_update_job()
|
||||
|
||||
def close(self):
|
||||
|
||||
"""Safely removes the service instance"""
|
||||
|
||||
if self.update_time is None:
|
||||
return None
|
||||
schedule.cancel_job(self.update_task)
|
||||
schedule.cancel_job(self._update_task)
|
||||
|
||||
def get_status(self):
|
||||
|
||||
"""Gets the running status of the service
|
||||
|
||||
Returns:
|
||||
"up" or "down" depending on the running status of the service
|
||||
"""
|
||||
|
||||
return "up" if bool(self.parent.docker.compose.ps(services=[self.name])) else "down"
|
||||
|
||||
def start_update_job(self):
|
||||
|
||||
"""Schedules a recurring update based on the composer.update label
|
||||
|
||||
Each update occurs after an interval of composer.update minutes. If composer.update does not contain a valid integer in minutes, defaults to the parent Composer's update_time.
|
||||
"""
|
||||
|
||||
self.update_time = self.parent.update_time
|
||||
if 'composer.update' in self.labels:
|
||||
try:
|
||||
@@ -142,6 +211,13 @@ class Service:
|
||||
return None
|
||||
|
||||
def set_status(self, status):
|
||||
|
||||
"""Sets the running status of the service
|
||||
|
||||
Args:
|
||||
status: string containing "up", "down", or "restart" corresponding to the respective running state of the service
|
||||
"""
|
||||
|
||||
try:
|
||||
if status == "up":
|
||||
self.parent.docker.compose.up(
|
||||
@@ -166,14 +242,9 @@ class Service:
|
||||
logger.critical(error)
|
||||
|
||||
def update(self, restart=True):
|
||||
try:
|
||||
self.parent.docker.compose.build(
|
||||
quiet=True,
|
||||
services=[self.name]
|
||||
)
|
||||
except DockerException:
|
||||
logger.warn(f"Failed to build docker image for service {self.name} - cancelling container update")
|
||||
return None
|
||||
|
||||
"""Updates the Composer stack based on container images"""
|
||||
|
||||
self.parent.docker.compose.pull(
|
||||
ignore_pull_failures=True,
|
||||
quiet=True,
|
||||
|
||||
Reference in New Issue
Block a user