Skip to content

Commit

Permalink
imp: support docker compose v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Tardo committed Aug 23, 2023
1 parent aeb850f commit be231aa
Show file tree
Hide file tree
Showing 11 changed files with 288 additions and 268 deletions.
22 changes: 17 additions & 5 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ _envops:
variable_start_string: "{{"

# Other Copier configurations
_min_copier_version: "7.0.1"
_min_copier_version: "8.1.0"
_exclude:
- _macros
- _traefik*_labels.yml
Expand Down Expand Up @@ -168,6 +168,7 @@ odoo_oci_image:
you are not using a registry.
Example: docker.io/myteam/example-odoo
default: ""

project_author:
type: str
Expand Down Expand Up @@ -215,6 +216,7 @@ gitlab_url:
💡 If you don't use Gitlab, leave this empty and ignore all other Gitlab questions.
Example: `https://gitlab.com/Tecnativa/your-doodba-project`.
default: ""

domains_prod:
type: yaml
Expand Down Expand Up @@ -270,6 +272,7 @@ domains_prod:
💡 The 1st host from the 1st domain that has no `path_prefixes` will be considered
the main one. In the example above, it'd be `www.main.com`.
default: ""

domains_test:
type: yaml
Expand Down Expand Up @@ -325,6 +328,7 @@ domains_test:
💡 The 1st host from the 1st domain that has no `path_prefixes` will be considered
the main one. In the example above, it'd be `demo1.main.com`.
default: ""

paths_without_crawlers:
multiline: true
Expand Down Expand Up @@ -366,10 +370,10 @@ postgres_version:
"14": "14"
"15": "15"
validator: >-
{% if postgres_version|int > 0 %} {% if (odoo_version >= 16.0 and
{% if postgres_version|int > 0 %} {% if (odoo_version >= 16.0 and
postgres_version|int < 12) or (odoo_version >= 14.0 and postgres_version|int < 10)
%} The postgres version is too low for the selected Odoo version. {% elif
odoo_version <= 12.0 and postgres_version|int > 14 %} The postgres version is too
odoo_version <= 12.0 and postgres_version|int > 13 %} The postgres version is too
high for the selected Odoo version. {% endif %} {% endif %}
postgres_username:
Expand Down Expand Up @@ -433,6 +437,7 @@ smtp_default_from:
In case an email coming out from odoo doesn't have a valid `From:` header address,
which address should be the default one that sends the email?
default: ""

smtp_relay_host:
type: str
Expand All @@ -448,6 +453,7 @@ smtp_relay_host:
So, what is your SMTP host?
Example: mail.example.com
default: ""

smtp_relay_port:
type: int
Expand All @@ -465,6 +471,7 @@ smtp_relay_user:
Indicate the user to connect in the SMTP server you just defined.
For Odoo to work fine, this user needs to be able to do mail spoofing.
default: ""

smtp_relay_password:
secret: true
Expand Down Expand Up @@ -500,6 +507,7 @@ smtp_canonical_default:
(https://en.wikipedia.org/wiki/SRS).
What's your canonical domain?
default: ""

smtp_canonical_domains:
when: *has_smtp
Expand All @@ -511,6 +519,7 @@ smtp_canonical_domains:
You do not need to repeat the canonical domain you indicated above.
Example: [examplemail.com, example.org]
default: ""

backup_dst:
type: str
Expand All @@ -526,6 +535,7 @@ backup_dst:
If you don't want backups, leave this empty.
Where should the backups be stored?
default: ""

backup_image_version:
type: str
Expand All @@ -548,12 +558,14 @@ backup_email_from:
configured.
What email address should it use to send them?
default: ""

backup_email_to:
type: str
when: *backup_present
help: >-
Where to send those backup reports?
default: ""

backup_deletion:
default: false
Expand All @@ -579,15 +591,15 @@ backup_tz:
backup_aws_access_key_id:
secret: true
type: str
default: null
default: ""
when: &backup_aws "{{ 's3:' in backup_dst|string }}"
help: >-
If you're using AWS S3 to store backups, provide here your access key ID.
backup_aws_secret_access_key:
secret: true
type: str
default: null
default: ""
when: *backup_aws
help: >-
If you're using AWS S3 to store backups, provide here your secret access key.
Expand Down
4 changes: 3 additions & 1 deletion tasks_downstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
"build"
]["args"]["ODOO_VERSION"]
)
DOCKER_COMPOSE_CMD = shutil.which("docker-compose") or "docker compose"
DOCKER_COMPOSE_CMD = (
shutil.which("docker-compose") or f"{shutil.which('docker')} compose"
)

_logger = getLogger(__name__)

Expand Down
112 changes: 49 additions & 63 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import json
import logging
import os
import shutil
import socket
import stat
import subprocess
import tempfile
import textwrap
from contextlib import contextmanager
from pathlib import Path
Expand All @@ -15,7 +14,6 @@
from packaging import version
from plumbum import ProcessExecutionError, local
from plumbum.cmd import git, invoke
from plumbum.machines.local import LocalCommand
from python_on_whales import DockerClient

_logger = logging.getLogger(__name__)
Expand All @@ -42,11 +40,11 @@
DBVER_PER_ODOO = {
11.0: {
"oldest": "10", # Odoo supports 9.6, but that version is not supported by the backup service and is necessary to be able to perform all tests
"latest": "14", # Debian stretch limitation: https://apt-archive.postgresql.org/pub/repos/apt/dists/stretch-pgdg/main/binary-amd64/Packages
"latest": "13", # DB Authentication method limitation
},
12.0: {
"oldest": "10", # Odoo supports 9.6, but that version is not supported by the backup service and is necessary to be able to perform all tests
"latest": "14", # Debian stretch limitation
"latest": "13",
},
13.0: {
"oldest": "10", # Odoo supports 9.6, but that version is not supported by the backup service and is necessary to be able to perform all tests
Expand All @@ -70,11 +68,6 @@
ALL_TRAEFIK_VERSIONS = ("latest", "1.7")


# we use the most recent version available for the tests
# but the old one is still supported
_has_docker_compose_v2 = subprocess.getstatusoutput("docker compose")[0] == 0


@pytest.fixture(autouse=True)
def skip_odoo_prereleases(supported_odoo_version: float, request):
"""Fixture to automatically skip tests for prereleased odoo versions."""
Expand Down Expand Up @@ -113,15 +106,15 @@ def supported_odoo_version(request) -> float:


@pytest.fixture()
def cloned_template(tmp_path_factory):
def cloned_template():
"""This repo cloned to a temporary destination.
The clone will include dirty changes, and it will have a 'test' tag in its HEAD.
It returns the local `Path` to the clone.
"""
patches = [git("diff", "--cached"), git("diff")]
with tmp_path_factory.mktemp("cloned_template_") as dirty_template_clone:
with tempfile.TemporaryDirectory("cloned_template_") as dirty_template_clone:
git("clone", ".", dirty_template_clone)
with local.cwd(dirty_template_clone):
git("config", "commit.gpgsign", "false")
Expand All @@ -139,15 +132,6 @@ def cloned_template(tmp_path_factory):
yield dirty_template_clone


def docker_compose() -> DockerClient:
def _run(compose_file: str = ""):
docker = DockerClient(compose_files=[compose_file])
yield docker
docker.compose.rm(stop=True, volumes=True)

return _run


@pytest.fixture()
def versionless_odoo_autoskip(request):
"""Fixture to automatically skip tests when testing for older odoo versions."""
Expand All @@ -160,22 +144,17 @@ def versionless_odoo_autoskip(request):


@pytest.fixture(params=ALL_TRAEFIK_VERSIONS)
def traefik_host(docker: LocalCommand, request):
def traefik_host(request):
"""Fixture to indicate where to find a running traefik instance."""
traefik_run = docker[
"container",
"run",
"--detach",
"--privileged",
"--network=inverseproxy_shared",
"--volume=/var/run/docker.sock:/var/run/docker.sock:ro",
f"traefik:{request.param}",
]
try:
if request.param == "latest" or version.parse(request.param) >= version.parse(
"2"
):
traefik_container = traefik_run(
docker = DockerClient()
if request.param == "latest" or version.parse(request.param) >= version.parse("2"):
traefik_container = docker.run(
f"traefik:{request.param}",
detach=True,
privileged=True,
networks=["inverseproxy_shared"],
volumes=[("/var/run/docker.sock", "/var/run/docker.sock", "ro")],
command=[
"--accessLog=true",
"--entrypoints.web-alt.address=:8080",
"--entrypoints.web-insecure.address=:80",
Expand All @@ -184,9 +163,16 @@ def traefik_host(docker: LocalCommand, request):
"--providers.docker.exposedByDefault=false",
"--providers.docker.network=inverseproxy_shared",
"--providers.docker=true",
).strip()
else:
traefik_container = traefik_run(
],
)
else:
traefik_container = docker.run(
f"traefik:{request.param}",
detach=True,
privileged=True,
networks=["inverseproxy_shared"],
volumes=[("/var/run/docker.sock", "/var/run/docker.sock", "ro")],
command=[
"--defaultEntryPoints=web-insecure,web-main",
"--docker.exposedByDefault=false",
"--docker.watch",
Expand All @@ -195,28 +181,24 @@ def traefik_host(docker: LocalCommand, request):
"--entryPoints=Name:web-insecure Address::80 Redirect.EntryPoint:web-main",
"--entryPoints=Name:web-main Address::443 Compress:on TLS TLS.minVersion:VersionTLS12",
"--logLevel=debug",
).strip()
traefik_details = json.loads(docker("container", "inspect", traefik_container))
assert (
len(traefik_details) == 1
), "Impossible... did you trigger a race condition?"
interesting_details = {
"ip": traefik_details[0]["NetworkSettings"]["Networks"][
"inverseproxy_shared"
]["IPAddress"],
"traefik_version": traefik_details[0]["Config"]["Labels"][
"org.opencontainers.image.version"
],
"traefik_image": traefik_details[0]["Image"],
}
interesting_details["hostname"] = f"{interesting_details['ip']}.sslip.io"
yield interesting_details
# Make sure there were no errors or warnings in logs
traefik_logs = docker("container", "logs", traefik_container)
assert " level=error " not in traefik_logs
assert " level=warn " not in traefik_logs
finally:
docker("container", "rm", "--force", traefik_container)
)
interesting_details = {
"ip": traefik_container.network_settings.networks[
"inverseproxy_shared"
].ip_address,
"traefik_version": traefik_container.config.labels[
"org.opencontainers.image.version"
],
"traefik_image": traefik_container.config.image,
}
interesting_details["hostname"] = f"{interesting_details['ip']}.sslip.io"
yield interesting_details
# Make sure there were no errors or warnings in logs
traefik_logs = docker.logs(traefik_container)
docker.remove(traefik_container, force=True)
assert " level=error " not in traefik_logs
assert " level=warn " not in traefik_logs


def teardown_function(function):
Expand Down Expand Up @@ -272,7 +254,8 @@ def generate_test_addon(
'version':'{odoo_version}.1.0.0',
'depends': {dependencies or '["base"]'},
'installable': {installable},
'auto_install': False
'auto_install': False,
'author': 'Tecnativa',
{"}"}
""",
f"{addon_name}/models/res_partner.py": """\
Expand Down Expand Up @@ -303,6 +286,7 @@ def some_method(self,test):
"depends": {dependencies or '["base"]'},
"installable": {installable},
"auto_install": False,
"author": "Tecnativa",
{"}"}
""",
f"{addon_name}/models/res_partner.py": '''\
Expand Down Expand Up @@ -334,8 +318,10 @@ def some_method(self, test):

def _containers_running(exec_path):
with local.cwd(exec_path):
if len(docker_compose("ps", "-aq").splitlines()) > 0:
_logger.error(docker_compose("ps", "-a"))
docker = DockerClient()
containers_list = docker.list(all=True)
if len(containers_list) > 0:
_logger.error(containers_list)
return True
return False

Expand Down
Loading

0 comments on commit be231aa

Please sign in to comment.