diff --git a/etc/docker/dev/docker-compose.autotests.yml b/etc/docker/dev/docker-compose.autotests.yml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/etc/docker/dev/docker-compose.yml b/etc/docker/dev/docker-compose.yml index 897e793f9b8..d7ab68e921f 100644 --- a/etc/docker/dev/docker-compose.yml +++ b/etc/docker/dev/docker-compose.yml @@ -3,10 +3,13 @@ services: rucioclient: image: docker.io/rucio/rucio-dev:latest-alma9 command: ["sleep", "infinity"] + profiles: + - client volumes: - ../../certs/rucio_ca.pem:/etc/grid-security/certificates/5fca1cb1.0:z - ../../certs/hostcert_rucio.pem:/etc/grid-security/hostcert.pem:z - ../../certs/hostcert_rucio.key.pem:/etc/grid-security/hostkey.pem:z + - ../../certs/rucio_ca.pem:/opt/rucio/etc/rucio_ca.pem:z - ../../certs/ruciouser.pem:/opt/rucio/etc/usercert.pem:z - ../../certs/ruciouser.key.pem:/opt/rucio/etc/userkey.pem:z - ../../certs/ruciouser.certkey.pem:/opt/rucio/etc/usercertkey.pem:z @@ -26,6 +29,7 @@ services: - ../../certs/rucio_ca.pem:/etc/grid-security/certificates/5fca1cb1.0:z - ../../certs/hostcert_rucio.pem:/etc/grid-security/hostcert.pem:z - ../../certs/hostcert_rucio.key.pem:/etc/grid-security/hostkey.pem:z + - ../../certs/rucio_ca.pem:/opt/rucio/etc/rucio_ca.pem:z - ../../certs/ruciouser.pem:/opt/rucio/etc/usercert.pem:z - ../../certs/ruciouser.key.pem:/opt/rucio/etc/userkey.pem:z - ../../certs/ruciouser.certkey.pem:/opt/rucio/etc/usercertkey.pem:z @@ -73,10 +77,19 @@ services: - ACTIVEMQ_CONFIG_SCHEDULERENABLED=true - ACTIVEMQ_USERS_hermes=supersecret - ACTIVEMQ_CONFIG_QUEUES_events=/queue/events' - ruciomy8: + postgres14: + image: docker.io/postgres:14 + profiles: + - postgres14 + environment: + - POSTGRES_USER=rucio + - POSTGRES_DB=rucio + - POSTGRES_PASSWORD=rucio + command: ["-c", "fsync=off","-c", "synchronous_commit=off","-c", "full_page_writes=off"] + mysql8: image: docker.io/mysql:8 profiles: - - alldb + - mysql8 environment: - MYSQL_USER=rucio - MYSQL_PASSWORD=rucio @@ -86,7 +99,7 @@ services: oracle: image: docker.io/gvenzl/oracle-xe:21-slim profiles: - - alldb + - oracle environment: - ORACLE_PASSWORD=rucio - ORACLE_ALLOW_REMOTE=true diff --git a/etc/docker/test/extra/alembic_mysql8.ini b/etc/docker/test/extra/alembic_mysql8.ini index dc5b5d73eb1..9844e10adf5 100644 --- a/etc/docker/test/extra/alembic_mysql8.ini +++ b/etc/docker/test/extra/alembic_mysql8.ini @@ -24,7 +24,7 @@ script_location = lib/rucio/db/sqla/migrate_repo/ # the 'revision' command, regardless of autogenerate # revision_environment = false -sqlalchemy.url = mysql+pymysql://root:secret@mysql8/mysql +sqlalchemy.url = mysql+pymysql://rucio:rucio@mysql8/rucio version_table_schema = dev # Logging configuration diff --git a/etc/docker/test/extra/alembic_oracle.ini b/etc/docker/test/extra/alembic_oracle.ini index ef3eb0ced54..7ed7f5d74e1 100644 --- a/etc/docker/test/extra/alembic_oracle.ini +++ b/etc/docker/test/extra/alembic_oracle.ini @@ -24,7 +24,7 @@ script_location = lib/rucio/db/sqla/migrate_repo/ # the 'revision' command, regardless of autogenerate # revision_environment = false -sqlalchemy.url = oracle://system:oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE))) +sqlalchemy.url = oracle://system:rucio@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE))) version_table_schema = SYSTEM # Logging configuration diff --git a/etc/docker/test/extra/alembic_postgres14.ini b/etc/docker/test/extra/alembic_postgres14.ini index 7d9e03824d9..56b3b58e7d8 100644 --- a/etc/docker/test/extra/alembic_postgres14.ini +++ b/etc/docker/test/extra/alembic_postgres14.ini @@ -24,7 +24,7 @@ script_location = lib/rucio/db/sqla/migrate_repo/ # the 'revision' command, regardless of autogenerate # revision_environment = false -sqlalchemy.url = postgresql://postgres:secret@postgres14/postgres +sqlalchemy.url = postgresql://rucio:rucio@postgres14/rucio version_table_schema = dev # Logging configuration diff --git a/etc/docker/test/extra/rucio_multi_vo_ts2_postgres14.cfg b/etc/docker/test/extra/rucio_multi_vo_ts2_postgres14.cfg index 070eb53d549..c586954447e 100644 --- a/etc/docker/test/extra/rucio_multi_vo_ts2_postgres14.cfg +++ b/etc/docker/test/extra/rucio_multi_vo_ts2_postgres14.cfg @@ -20,7 +20,7 @@ request_retries = 3 vo = testvo2 [database] -default = postgresql://postgres:secret@postgres14/postgres +default = postgresql://rucio:rucio@postgres14/rucio schema = dev pool_recycle=3600 echo=0 diff --git a/etc/docker/test/extra/rucio_multi_vo_tst_postgres14.cfg b/etc/docker/test/extra/rucio_multi_vo_tst_postgres14.cfg index ac2d54b176d..15dbf99804a 100644 --- a/etc/docker/test/extra/rucio_multi_vo_tst_postgres14.cfg +++ b/etc/docker/test/extra/rucio_multi_vo_tst_postgres14.cfg @@ -20,7 +20,7 @@ request_retries = 3 vo = testvo1 [database] -default = postgresql://postgres:secret@postgres14/postgres +default = postgresql://rucio:rucio@postgres14/rucio schema = dev pool_recycle=3600 echo=0 diff --git a/etc/docker/test/extra/rucio_mysql8.cfg b/etc/docker/test/extra/rucio_mysql8.cfg index eefa7f6cab3..16e41a7470e 100644 --- a/etc/docker/test/extra/rucio_mysql8.cfg +++ b/etc/docker/test/extra/rucio_mysql8.cfg @@ -17,7 +17,7 @@ account = root request_retries = 3 [database] -default = mysql+pymysql://root:secret@mysql8/mysql +default = mysql+pymysql://rucio:rucio@mysql8/rucio schema=dev pool_recycle=3600 echo=0 diff --git a/etc/docker/test/extra/rucio_oracle.cfg b/etc/docker/test/extra/rucio_oracle.cfg index 1bf43941397..63ac281ba86 100644 --- a/etc/docker/test/extra/rucio_oracle.cfg +++ b/etc/docker/test/extra/rucio_oracle.cfg @@ -17,7 +17,7 @@ account = root request_retries = 3 [database] -default = oracle://system:oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE))) +default = oracle://system:rucio@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE))) schema=system pool_recycle=3600 echo=0 diff --git a/etc/docker/test/extra/rucio_postgres14.cfg b/etc/docker/test/extra/rucio_postgres14.cfg index abaafe9b1f3..6ac4b0d490c 100644 --- a/etc/docker/test/extra/rucio_postgres14.cfg +++ b/etc/docker/test/extra/rucio_postgres14.cfg @@ -17,7 +17,7 @@ account = root request_retries = 3 [database] -default = postgresql://postgres:secret@postgres14/postgres +default = postgresql://rucio:rucio@postgres14/rucio schema=dev pool_recycle=3600 echo=0 diff --git a/tools/test/before_script.sh b/tools/test/before_script.sh index c7925e6403a..cfa4e2c9ae3 100755 --- a/tools/test/before_script.sh +++ b/tools/test/before_script.sh @@ -53,7 +53,7 @@ elif [ $RDBMS == "mysql8" ]; then date for i in {1..30}; do sleep 4 - cont=$(bash -c 'ping=`docker '"$CONTAINER_RUNTIME_ARGS"' exec '"$CON_DB"' mysqladmin --user=root --password=secret ping`; echo $ping 1>&2; echo $ping | grep "mysqld is alive" 1>&2; echo $?') + cont=$(bash -c 'ping=`docker '"$CONTAINER_RUNTIME_ARGS"' exec '"$CON_DB"' mysqladmin --user=rucio --password=rucio ping`; echo $ping 1>&2; echo $ping | grep "mysqld is alive" 1>&2; echo $?') [ "$cont" -eq "0" ] && break done date diff --git a/tools/test/run_tests.py b/tools/test/run_tests.py index 68ec43f3e77..6e8428f396e 100755 --- a/tools/test/run_tests.py +++ b/tools/test/run_tests.py @@ -15,6 +15,8 @@ # limitations under the License. import json +import io +import itertools import multiprocessing import os import pathlib @@ -24,11 +26,32 @@ import time import traceback import uuid -from collections.abc import Callable from datetime import datetime -from typing import Optional +from textwrap import dedent +from typing import Optional, Union, NoReturn -from suites import run, Container, rdbms_container, services, CumulativeContextManager, service_hostnames, env_args +import yaml + + +def run(*args, check=True, return_stdout=False, env=None) -> Union[NoReturn, io.TextIOBase]: + kwargs = {'check': check, 'stdout': sys.stderr, 'stderr': subprocess.STDOUT} + if env is not None: + kwargs['env'] = env + if return_stdout: + kwargs['stderr'] = sys.stderr + kwargs['stdout'] = subprocess.PIPE + args = [str(a) for a in args] + print("** Running", " ".join(map(lambda a: repr(a) if ' ' in a else a, args)), kwargs, file=sys.stderr, flush=True) + proc = subprocess.run(args, **kwargs) + if return_stdout: + return proc.stdout + + +def env_args(caseenv): + environment_args = list(itertools.chain(*map(lambda x: ('--env', f'{x[0]}={x[1]}'), caseenv.items()))) + environment_args.append('--env') + environment_args.append('GITHUB_ACTIONS') + return environment_args def matches(small: dict, group: dict): @@ -177,8 +200,6 @@ def run_case(caseenv, image, use_podman, use_namespace, use_httpd, copy_rucio_lo success = run_with_httpd( caseenv=caseenv, image=image, - use_podman=use_podman, - pod=pod, namespace_args=namespace_args, namespace_env=namespace_env, copy_rucio_logs=copy_rucio_logs, @@ -254,74 +275,69 @@ def run_test_directly( def run_with_httpd( caseenv: dict[str, str], image: str, - use_podman: bool, - pod: str, namespace_args: list[str], namespace_env: dict[str, str], copy_rucio_logs: bool, logs_dir: pathlib.Path, tests: list[str], ) -> bool: - pod_net_arg = ['--pod', pod] if use_podman else [] # Running rucio container from given image - with Container(image, runtime_args=namespace_args, run_args=pod_net_arg, environment=caseenv) as rucio_container: + from tempfile import NamedTemporaryFile + with (NamedTemporaryFile() as compose_override_file): + + project_name = os.urandom(8).hex() + compose_common_args = ( + '-p', project_name, + '--file', 'etc/docker/dev/docker-compose.yml', + '--file', compose_override_file.name, + ) + compose_override_content = yaml.dump({ + 'services': { + 'rucio': { + 'image': image, + 'volumes': ['../../../:/usr/local/src/rucio/:Z'], + 'environment': [f'{k}={v}' for k, v in caseenv.items()], + }, + 'ruciodb': { + 'profiles': ['donotstart'], + } + } + }) + with open(compose_override_file.name, 'w') as f: + f.write(dedent(compose_override_content)) + rdbms = caseenv.get('RDBMS', '') + print("Overriding docker-compose configuration with: \n", compose_override_content) try: - network_arg = ('--network', 'container:' + rucio_container.cid) - container_run_args = pod_net_arg if use_podman else network_arg - additional_containers = [] - - def create_cnt(cnt_class: Callable) -> Container: - return cnt_class( - runtime_args=namespace_args, - run_args=container_run_args, - ) - - db_container = None - rdbms = caseenv.get('RDBMS', '') - if rdbms: - service_key = caseenv.get('SERVICES', 'default') - db_container_class = rdbms_container.get(rdbms, None) - if db_container_class: - db_container = create_cnt(db_container_class) - additional_containers.append(db_container) - additional_containers += list(map(create_cnt, services[service_key])) - - with CumulativeContextManager(*additional_containers): - db_env = dict() - if db_container: - db_env['CON_DB'] = db_container.cid - - # Running before_script.sh - run( - './tools/test/before_script.sh', - env={ - **os.environ, - **caseenv, - **namespace_env, - **db_env, - "CONTAINER_RUNTIME_ARGS": ' '.join(namespace_args), - "CON_RUCIO": rucio_container.cid, - }, - ) - - # register service hostnames - run('docker', *namespace_args, 'exec', rucio_container.cid, '/bin/sh', '-c', f'echo "127.0.0.1 {" ".join(service_hostnames)}" | tee -a /etc/hosts') + # Start docker compose + run('docker-compose', *compose_common_args, '--profile', rdbms, 'up', '-d') + # Running before_script.sh + run( + './tools/test/before_script.sh', + env={ + **os.environ, + **caseenv, + **namespace_env, + "CONTAINER_RUNTIME_ARGS": ' '.join(namespace_args), + "CON_RUCIO": f'{project_name}_rucio_1', + "CON_DB": f'{project_name}_{rdbms}_1', + }, + ) - # Running install_script.sh - run('docker', *namespace_args, 'exec', rucio_container.cid, './tools/test/install_script.sh') + # Running install_script.sh + run('docker', *namespace_args, 'exec', f'{project_name}_rucio_1', './tools/test/install_script.sh') - # Running test.sh - if tests: - tests_env = ('--env', 'TESTS=' + ' '.join(tests)) - tests_arg = ('-p', ) - else: - tests_env = () - tests_arg = () + # Running test.sh + if tests: + tests_env = ('--env', 'TESTS=' + ' '.join(tests)) + tests_arg = ('-p', ) + else: + tests_env = () + tests_arg = () - run('docker', *namespace_args, 'exec', *tests_env, rucio_container.cid, './tools/test/test.sh', *tests_arg) + run('docker', *namespace_args, 'exec', *tests_env, f'{project_name}_rucio_1', './tools/test/test.sh', *tests_arg) - # if everything went through without an exception, mark this case as a success - return True + # if everything went through without an exception, mark this case as a success + return True except subprocess.CalledProcessError as error: print( f"** Process '{error.cmd}' exited with code {error.returncode}", @@ -330,12 +346,12 @@ def create_cnt(cnt_class: Callable) -> Container: flush=True, ) finally: - run('docker', *namespace_args, 'logs', rucio_container.cid, check=False) + run('docker', *namespace_args, 'logs', f'{project_name}_rucio_1', check=False) if copy_rucio_logs: try: if logs_dir.exists(): shutil.rmtree(logs_dir) - run('docker', *namespace_args, 'cp', f'{rucio_container.cid}:/var/log', str(logs_dir)) + run('docker', *namespace_args, 'cp', f'{project_name}_rucio_1:/var/log', str(logs_dir)) except Exception: print( "** Error on retrieving logs for", @@ -346,6 +362,7 @@ def create_cnt(cnt_class: Callable) -> Container: file=sys.stderr, flush=True, ) + run('docker-compose', *compose_common_args, 'down', check=False) return False diff --git a/tools/test/suites.py b/tools/test/suites.py deleted file mode 100644 index 5d802239c94..00000000000 --- a/tools/test/suites.py +++ /dev/null @@ -1,263 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright European Organization for Nuclear Research (CERN) since 2012 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import io -import itertools -import subprocess -import sys -from typing import Any, NoReturn, Optional, Union - -DEFAULT_TIMEOUT = 10 -DEFAULT_DB_TIMEOUT = 27 - - -def run(*args, check=True, return_stdout=False, env=None) -> Union[NoReturn, io.TextIOBase]: - kwargs = {'check': check, 'stdout': sys.stderr, 'stderr': subprocess.STDOUT} - if env is not None: - kwargs['env'] = env - if return_stdout: - kwargs['stderr'] = sys.stderr - kwargs['stdout'] = subprocess.PIPE - args = [str(a) for a in args] - print("** Running", " ".join(map(lambda a: repr(a) if ' ' in a else a, args)), kwargs, file=sys.stderr, flush=True) - proc = subprocess.run(args, **kwargs) - if return_stdout: - return proc.stdout - - -def env_args(caseenv): - environment_args = list(itertools.chain(*map(lambda x: ('--env', f'{x[0]}={x[1]}'), caseenv.items()))) - environment_args.append('--env') - environment_args.append('GITHUB_ACTIONS') - return environment_args - - -class Container: - def __init__( - self, - image: "str", - *args, - runtime_args: Optional[list[str]] = None, - run_args: Optional[list[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_TIMEOUT, - ): - if runtime_args is None: - runtime_args = [] - self.runtime_args = runtime_args - if run_args is None: - run_args = [] - if environment is None: - environment = {} - self.stop_timeout = stop_timeout - self.args = ['docker', *runtime_args, 'run', '--detach', *run_args, *(env_args(environment)), image, *args] - self.cid = None - - def __enter__(self): - stdout = run(*self.args, return_stdout=True) - self.cid = stdout.decode().strip() - if not self.cid: - raise RuntimeError("Could not determine container id after starting the container") - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - run('docker', *self.runtime_args, 'stop', f'--time={self.stop_timeout}', self.cid, check=False) - run('docker', *self.runtime_args, 'rm', '--force', '--volumes', self.cid, check=False) - - def wait(self): - run('docker', *self.runtime_args, 'wait', self.cid, check=False) - - -class CumulativeContextManager: - def __init__(self, *context_managers): - self.context_managers = context_managers - - def __enter__(self): - for mgr in self.context_managers: - mgr.__enter__() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - for mgr in self.context_managers: - mgr.__exit__(exc_type, exc_val, exc_tb) - - -class OracleDB(Container): - def __init__( - self, - runtime_args: Optional[tuple[str]] = None, - run_args: Optional[tuple[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_DB_TIMEOUT, - ): - if run_args is None: - run_args = tuple() - run_args = ("--no-healthcheck",) + run_args - if environment is None: - environment = dict() - environment['processes'] = "1000" - environment["sessions"] = "1105" - environment["transactions"] = "1215" - environment["ORACLE_ALLOW_REMOTE"] = "true" - environment["ORACLE_PASSWORD"] = "oracle" - environment["ORACLE_DISABLE_ASYNCH_IO"] = "true" - super(OracleDB, self).__init__( - "docker.io/gvenzl/oracle-xe:18.4.0", - runtime_args=runtime_args, - run_args=run_args, - environment=environment, - stop_timeout=stop_timeout, - ) - - -class MySQL5(Container): - def __init__( - self, - runtime_args: Optional[tuple[str]] = None, - run_args: Optional[tuple[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_DB_TIMEOUT, - ): - if environment is None: - environment = dict() - environment["MYSQL_ROOT_PASSWORD"] = "secret" - environment["MYSQL_ROOT_HOST"] = "%" - super(MySQL5, self).__init__( - "docker.io/mysql/mysql-server:5.7", - runtime_args=runtime_args, - run_args=run_args, - environment=environment, - stop_timeout=stop_timeout, - ) - - -class MySQL8(Container): - def __init__( - self, - runtime_args: Optional[tuple[str]] = None, - run_args: Optional[tuple[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_DB_TIMEOUT, - ): - if environment is None: - environment = dict() - environment["MYSQL_ROOT_PASSWORD"] = "secret" - environment["MYSQL_ROOT_HOST"] = "%" - super(MySQL8, self).__init__( - "docker.io/mysql/mysql-server:8.0", - "--default-authentication-plugin=mysql_native_password", - "--character-set-server=latin1", - runtime_args=runtime_args, - run_args=run_args, - environment=environment, - stop_timeout=stop_timeout, - ) - - -class Postgres14(Container): - def __init__( - self, - runtime_args: Optional[tuple[str]] = None, - run_args: Optional[tuple[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_DB_TIMEOUT, - ): - if environment is None: - environment = dict() - environment["POSTGRES_PASSWORD"] = "secret" - super(Postgres14, self).__init__( - "docker.io/postgres:14", - "-c", "max_connections=300", - runtime_args=runtime_args, - run_args=run_args, - environment=environment, - stop_timeout=stop_timeout, - ) - - -class ActiveMQ(Container): - def __init__( - self, - runtime_args: Optional[tuple[str]] = None, - run_args: Optional[tuple[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_DB_TIMEOUT, - ): - super(ActiveMQ, self).__init__( - "docker.io/webcenter/activemq:latest", - runtime_args=runtime_args, - run_args=run_args, - environment=environment, - stop_timeout=stop_timeout, - ) - - -class InfluxDB(Container): - def __init__( - self, - runtime_args: Optional[tuple[str]] = None, - run_args: Optional[tuple[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_DB_TIMEOUT, - ): - if environment is None: - environment = dict() - environment["DOCKER_INFLUXDB_INIT_MODE"] = "setup" - environment["DOCKER_INFLUXDB_INIT_USERNAME"] = "myusername" - environment["DOCKER_INFLUXDB_INIT_PASSWORD"] = "passwordpasswordpassword" - environment["DOCKER_INFLUXDB_INIT_ORG"] = "rucio" - environment["DOCKER_INFLUXDB_INIT_BUCKET"] = "rucio" - environment["DOCKER_INFLUXDB_INIT_ADMIN_TOKEN"] = "mytoken" - super(InfluxDB, self).__init__( - "docker.io/influxdb:latest", - runtime_args=runtime_args, - run_args=run_args, - environment=environment, - stop_timeout=stop_timeout, - ) - - -class Elasticsearch(Container): - def __init__( - self, - runtime_args: Optional[tuple[str]] = None, - run_args: Optional[tuple[str]] = None, - environment: Optional[dict[str, str]] = None, - stop_timeout: int = DEFAULT_DB_TIMEOUT, - ): - if environment is None: - environment = dict() - environment["discovery.type"] = "single-node" - super(Elasticsearch, self).__init__( - "docker.elastic.co/elasticsearch/elasticsearch:6.4.2", - runtime_args=runtime_args, - run_args=run_args, - environment=environment, - stop_timeout=stop_timeout, - ) - - -rdbms_container: dict[str, Any] = { - "oracle": OracleDB, - "mysql5": MySQL5, - "mysql8": MySQL8, - "postgres14": Postgres14, - "sqlite": None, -} -services = { - 'default': [ActiveMQ], - 'influxdb_elastic': [ActiveMQ, InfluxDB, Elasticsearch], -} -service_hostnames = ['activemq', 'influxdb', 'elasticsearch'] + list(rdbms_container.keys())