Source code for idmtools_platform_local.infrastructure.postgres
"""idmtools postgres service. Used for experiment data.
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
"""
import time
from dataclasses import dataclass
from logging import getLogger, DEBUG
from typing import Dict, NoReturn
from docker.models.containers import Container
from idmtools.core.system_information import get_system_information
from idmtools_platform_local.infrastructure.base_service_container import BaseServiceContainer
logger = getLogger(__name__)
[docs]@dataclass
class PostgresContainer(BaseServiceContainer):
"""Defines the postgres container for the local platform."""
host_data_directory: str = None
port: int = 5432
mem_limit: str = '128m'
mem_reservation: str = '32m'
run_as: str = None
image: str = 'postgres:11.4'
container_name: str = 'idmtools_postgres'
# TODO Make this secure by loading from keyring or encrypted file and then pass through docker screts
password: str = 'idmtools'
data_volume_name: str = 'idmtools_local_postgres'
config_prefix: str = 'postgres_'
def __post_init__(self):
"""Constructor."""
system_info = get_system_information()
if self.run_as is None:
self.run_as = system_info.user_group_str
[docs] def get_configuration(self) -> Dict:
"""
Returns the docker config for the postgres container.
Returns:
(dict) Dictionary representing the docker config for the postgres container
"""
postgres_volumes = {
self.data_volume_name: dict(bind='/var/lib/postgresql/data', mode='rw')
}
port_bindings = self._get_optional_port_bindings(self.port, 5432)
container_config = self.get_common_config(container_name=self.container_name, image=self.image,
port_bindings=port_bindings,
volumes=postgres_volumes, mem_limit=self.mem_limit,
network=self.network,
mem_reservation=self.mem_reservation,
environment=['POSTGRES_USER=idmtools',
f'POSTGRES_PASSWORD={self.password}'])
if logger.isEnabledFor(DEBUG):
logger.debug(f"Postgres Config: {container_config}")
return container_config
[docs] def create(self, spinner=None) -> Container:
"""Create our postgres container.
Here we create the postgres data volume before creating the container.
"""
self.create_postgres_volume()
result = super().create(spinner)
# postgres will restart once so we should watch it again
time.sleep(0.5)
self.wait_on_status(result)
return result
[docs] def create_postgres_volume(self) -> NoReturn:
"""
Creates our postgres volume.
Returns:
None
"""
postgres_volume = self.client.volumes.list(filters=dict(name=self.data_volume_name))
if not postgres_volume:
self.client.volumes.create(name=self.data_volume_name)