Source code for planemo.database.postgres_docker

"""Module describes a :class:`DatabaseSource` for managed, dockerized postgres databases."""

import time

from galaxy.tool_util.deps import (
    docker_util,
    dockerfiles,
)
from galaxy.util import unicodify
from galaxy.util.commands import execute

from .interface import DatabaseSource
from .postgres import (
    _CommandBuilder,
    ExecutesPostgresSqlMixin,
)

DEFAULT_CONTAINER_NAME = "planemopostgres"
DEFAULT_POSTGRES_PASSWORD = "mysecretpassword"
DEFAULT_POSTGRES_PORT_EXPOSE = 15432


def docker_ps(args, **kwds):
    return docker_util.command_list("ps", args, **kwds)


def docker_exec(name, commands=[], **kwds):
    return docker_util.command_list("exec", [name] + commands, **kwds)


def is_running_container(name=DEFAULT_CONTAINER_NAME, **kwds):
    ps_command = docker_ps(["--format", "{{.Names}}"], **kwds)
    running_containers = unicodify(execute(ps_command))
    containers = running_containers.splitlines()
    return name in containers


def start_postgres_docker(
    name=DEFAULT_CONTAINER_NAME, password=DEFAULT_POSTGRES_PASSWORD, port=DEFAULT_POSTGRES_PORT_EXPOSE, **kwds
):
    run_command = docker_util.command_list(
        "run",
        ["-p", "%d:5432" % port, "--name", name, "-e", "POSTGRES_PASSWORD=%s" % password, "--rm", "-d", "postgres"],
        **kwds,
    )
    execute(run_command)


def stop_postgres_docker(name=DEFAULT_CONTAINER_NAME, **kwds):
    stop_command = docker_util.command_list("stop", [name], **kwds)
    execute(stop_command)


[docs] class DockerPostgresDatabaseSource(ExecutesPostgresSqlMixin, DatabaseSource): """Postgres database running inside a Docker container.""" def __init__(self, **kwds): """Construct a postgres database source from planemo configuration.""" self.psql_path = "psql" self.database_user = "postgres" self.database_password = DEFAULT_POSTGRES_PASSWORD self.database_host = "localhost" # TODO: Make docker host self.database_port = DEFAULT_POSTGRES_PORT_EXPOSE self._kwds = kwds self._docker_host_kwds = dockerfiles.docker_host_args(**kwds) if not is_running_container(**self._docker_host_kwds): start_postgres_docker(**self._docker_host_kwds) # Hack to give docker a bit of time to boot up and allow psql to start. time.sleep(30)
[docs] def sqlalchemy_url(self, identifier): """Return URL or form postgresql://username:password@localhost/mydatabase.""" return "postgresql://%s:%s@%s:%d/%s" % ( self.database_user, self.database_password, self.database_host, self.database_port, identifier, )
def _psql_command_builder(self, *args): base_command = docker_exec(DEFAULT_CONTAINER_NAME, [self.psql_path], **self._docker_host_kwds) command_builder = _CommandBuilder(*base_command) # Print only tuples so output is easier to parse command_builder.append_command("--tuples-only") command_builder.append_command("--username", self.database_user) command_builder.append_command("-P", "pager=off") command_builder.extend_command(args) return command_builder
__all__ = ("DockerPostgresDatabaseSource",)