From 9a8c603cae6f8e5e6377258c9613f78be2cfcfdc Mon Sep 17 00:00:00 2001 From: Thomas Queste Date: Mon, 13 May 2024 12:28:06 +0200 Subject: [PATCH 1/7] chore: upgrade to Radicale 3.2.0 --- Dockerfile | 2 +- test_image_prod.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 891d2db..4130505 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG COMMIT_ID ENV COMMIT_ID ${COMMIT_ID} ARG VERSION -ENV VERSION ${VERSION:-3.1.9} +ENV VERSION ${VERSION:-3.2.0} ARG BUILD_UID ENV BUILD_UID ${BUILD_UID:-2999} diff --git a/test_image_prod.py b/test_image_prod.py index 279fb42..e039eb4 100644 --- a/test_image_prod.py +++ b/test_image_prod.py @@ -42,7 +42,7 @@ def test_port(host): def test_version(host): - assert host.check_output('/venv/bin/radicale --version') == '3.1.9' + assert host.check_output('/venv/bin/radicale --version') == '3.2.0' def test_user(host): From 5a7d3a9e0de5f7e19356f7bf5fdd02d0ca25bdb5 Mon Sep 17 00:00:00 2001 From: Thomas Queste Date: Mon, 13 May 2024 12:29:20 +0200 Subject: [PATCH 2/7] doc: update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 691c257..58622ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [3.2.0.0] - 2024-05-13 + +## Changed + +- [Update to Radicale 3.2.0](https://github.com/tomsquest/docker-radicale/pull/147) + + ## [3.1.9.1] - 2024-03-18 ## Changed From 7f4a2bc033236b8c358d143b3e1a5345b8d01f8b Mon Sep 17 00:00:00 2001 From: Thomas Queste Date: Tue, 21 May 2024 18:55:55 +0200 Subject: [PATCH 3/7] chore: update config with Radicale one (only comments were changed) --- config | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/config b/config index d5e2b58..92a2bf1 100644 --- a/config +++ b/config @@ -14,7 +14,8 @@ # CalDAV server hostnames separated by a comma # IPv4 syntax: address:port # IPv6 syntax: [address]:port -# For example: 0.0.0.0:9999, [::]:9999 +# Hostname syntax (using "getaddrinfo" to resolve to IPv4/IPv6 adress(es)): hostname:port +# For example: 0.0.0.0:9999, [::]:9999, localhost:9999 #hosts = localhost:5232 hosts = 0.0.0.0:5232 @@ -60,8 +61,8 @@ hosts = 0.0.0.0:5232 #htpasswd_filename = /etc/radicale/users # Htpasswd encryption method -# Value: plain | bcrypt | md5 -# bcrypt requires the installation of radicale[bcrypt]. +# Value: plain | bcrypt | md5 | sha256 | sha512 | autodetect +# bcrypt requires the installation of 'bcrypt' module. #htpasswd_encryption = md5 # Incorrect authentication delay (seconds) @@ -70,6 +71,9 @@ hosts = 0.0.0.0:5232 # Message displayed in the client when a password is needed #realm = Radicale - Password Required +# Сonvert username to lowercase, must be true for case-insensitive auth providers +#lc_username = False + [rights] @@ -80,6 +84,9 @@ hosts = 0.0.0.0:5232 # File for rights management from_file #file = /etc/radicale/rights +# Permit delete of a collection (global) +#permit_delete_collection = True + [storage] @@ -95,7 +102,7 @@ filesystem_folder = /data/collections #max_sync_token_age = 2592000 # Command that is run after changes to storage -# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s) +# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"") #hook = @@ -110,7 +117,7 @@ filesystem_folder = /data/collections # Threshold for the logger # Value: debug | info | warning | error | critical -#level = warning +#level = info # Don't include passwords in logs #mask_passwords = True @@ -120,3 +127,12 @@ filesystem_folder = /data/collections # Additional HTTP headers #Access-Control-Allow-Origin = * + +[hook] + +# Hook types +# Value: none | rabbitmq +#type = none +#rabbitmq_endpoint = +#rabbitmq_topic = +#rabbitmq_queue_type = classic \ No newline at end of file From 33401050c7bba126aebad400d47193eed2133e4e Mon Sep 17 00:00:00 2001 From: Thomas Queste Date: Tue, 21 May 2024 18:56:20 +0200 Subject: [PATCH 4/7] doc: use pipenv to run test to avoid activating the env --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b0c8fd..6607d7b 100644 --- a/README.md +++ b/README.md @@ -315,7 +315,7 @@ To run the tests: 1. `pip install pipenv` 2. `pipenv install -d` -3. `pytest -v` +3. `pipenv run pytest -v` ## Releasing From f087f0011609a451d34b086ba0387eb7c62e8bc9 Mon Sep 17 00:00:00 2001 From: Thomas Queste Date: Wed, 22 May 2024 12:23:27 +0200 Subject: [PATCH 5/7] style: reformat test_image_prod.py --- test_image_prod.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test_image_prod.py b/test_image_prod.py index e039eb4..a266b64 100644 --- a/test_image_prod.py +++ b/test_image_prod.py @@ -1,6 +1,5 @@ -import subprocess - import pytest +import subprocess import testinfra From ddbfc2abcd6c6b5c9757c44a69b23d033b11f99c Mon Sep 17 00:00:00 2001 From: Thomas Queste Date: Wed, 22 May 2024 12:23:45 +0200 Subject: [PATCH 6/7] fix(test): version must be 3.2.0 to support new hook section in config --- test_image_custom_build.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test_image_custom_build.py b/test_image_custom_build.py index 64d20d2..05d8fa9 100644 --- a/test_image_custom_build.py +++ b/test_image_custom_build.py @@ -2,11 +2,12 @@ import subprocess import testinfra + @pytest.fixture(scope='session') def host(): subprocess.check_call( ['docker', 'build', '-t', 'radicale-under-test', - '--build-arg', 'VERSION=3.0.0', + '--build-arg', 'VERSION=3.2.0', '--build-arg', 'BUILD_UID=6666', '--build-arg', 'BUILD_GID=7777', '.' @@ -18,17 +19,21 @@ def host(): # teardown subprocess.check_call(['docker', 'rm', '-f', docker_id]) + def test_process(host): process = host.process.get(comm='radicale') assert process.pid == 1 assert process.user == 'radicale' assert process.group == 'radicale' + def test_port(host): assert host.socket('tcp://0.0.0.0:5232').is_listening + def test_version(host): - assert host.check_output('/venv/bin/radicale --version') == '3.0.0' + assert host.check_output('/venv/bin/radicale --version') == '3.2.0' + def test_user(host): user = 'radicale' @@ -37,6 +42,7 @@ def test_user(host): assert host.user(user).shell == '/bin/false' assert 'radicale L ' in host.check_output('passwd --status radicale') + def test_data_folder_writable(host): folder = '/data' assert host.file(folder).user == 'radicale' From 0807ce0387a5dd48eab8dbf73ec9341dcc102295 Mon Sep 17 00:00:00 2001 From: Thomas Queste Date: Wed, 22 May 2024 12:25:23 +0200 Subject: [PATCH 7/7] style: reformat python using ruff --- test_image_custom_build.py | 52 +++++++++++++++++----------- test_image_prod.py | 70 ++++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 50 deletions(-) diff --git a/test_image_custom_build.py b/test_image_custom_build.py index 05d8fa9..61f2890 100644 --- a/test_image_custom_build.py +++ b/test_image_custom_build.py @@ -3,48 +3,60 @@ import testinfra -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def host(): subprocess.check_call( - ['docker', 'build', '-t', 'radicale-under-test', - '--build-arg', 'VERSION=3.2.0', - '--build-arg', 'BUILD_UID=6666', - '--build-arg', 'BUILD_GID=7777', - '.' - ]) - docker_id = subprocess.check_output(['docker', 'run', '-d', 'radicale-under-test']).decode().strip() + [ + "docker", + "build", + "-t", + "radicale-under-test", + "--build-arg", + "VERSION=3.2.0", + "--build-arg", + "BUILD_UID=6666", + "--build-arg", + "BUILD_GID=7777", + ".", + ] + ) + docker_id = ( + subprocess.check_output(["docker", "run", "-d", "radicale-under-test"]) + .decode() + .strip() + ) yield testinfra.get_host("docker://" + docker_id) # teardown - subprocess.check_call(['docker', 'rm', '-f', docker_id]) + subprocess.check_call(["docker", "rm", "-f", docker_id]) def test_process(host): - process = host.process.get(comm='radicale') + process = host.process.get(comm="radicale") assert process.pid == 1 - assert process.user == 'radicale' - assert process.group == 'radicale' + assert process.user == "radicale" + assert process.group == "radicale" def test_port(host): - assert host.socket('tcp://0.0.0.0:5232').is_listening + assert host.socket("tcp://0.0.0.0:5232").is_listening def test_version(host): - assert host.check_output('/venv/bin/radicale --version') == '3.2.0' + assert host.check_output("/venv/bin/radicale --version") == "3.2.0" def test_user(host): - user = 'radicale' + user = "radicale" assert host.user(user).uid == 6666 assert host.user(user).gid == 7777 - assert host.user(user).shell == '/bin/false' - assert 'radicale L ' in host.check_output('passwd --status radicale') + assert host.user(user).shell == "/bin/false" + assert "radicale L " in host.check_output("passwd --status radicale") def test_data_folder_writable(host): - folder = '/data' - assert host.file(folder).user == 'radicale' - assert host.file(folder).group == 'radicale' + folder = "/data" + assert host.file(folder).user == "radicale" + assert host.file(folder).group == "radicale" assert host.file(folder).mode == 0o770 diff --git a/test_image_prod.py b/test_image_prod.py index a266b64..d8ad249 100644 --- a/test_image_prod.py +++ b/test_image_prod.py @@ -3,57 +3,67 @@ import testinfra -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def host(): - subprocess.check_call(['docker', 'build', '-t', 'radicale-under-test', '.']) - docker_id = subprocess.check_output([ - 'docker', 'run', '-d', - '--init', - '--read-only', - '--security-opt=no-new-privileges:true', - # Not able to use cap-drop=all and make the container start - # '--cap-drop', 'ALL', - # '--cap-add', 'SYS_ADMIN', - # '--cap-add', 'CHOWN', - # '--cap-add', 'SETUID', - # '--cap-add', 'SETGID', - # '--cap-add', 'KILL', - '--pids-limit', '50', - '--memory', '256M', - 'radicale-under-test' - ]).decode().strip() + subprocess.check_call(["docker", "build", "-t", "radicale-under-test", "."]) + docker_id = ( + subprocess.check_output( + [ + "docker", + "run", + "-d", + "--init", + "--read-only", + "--security-opt=no-new-privileges:true", + # Not able to use cap-drop=all and make the container start + # '--cap-drop', 'ALL', + # '--cap-add', 'SYS_ADMIN', + # '--cap-add', 'CHOWN', + # '--cap-add', 'SETUID', + # '--cap-add', 'SETGID', + # '--cap-add', 'KILL', + "--pids-limit", + "50", + "--memory", + "256M", + "radicale-under-test", + ] + ) + .decode() + .strip() + ) yield testinfra.get_host("docker://" + docker_id) # teardown - subprocess.check_call(['docker', 'rm', '-f', docker_id]) + subprocess.check_call(["docker", "rm", "-f", docker_id]) def test_process(host): - process = host.process.get(comm='radicale') + process = host.process.get(comm="radicale") assert process.pid != 1 - assert process.user == 'radicale' - assert process.group == 'radicale' + assert process.user == "radicale" + assert process.group == "radicale" def test_port(host): - assert host.socket('tcp://0.0.0.0:5232').is_listening + assert host.socket("tcp://0.0.0.0:5232").is_listening def test_version(host): - assert host.check_output('/venv/bin/radicale --version') == '3.2.0' + assert host.check_output("/venv/bin/radicale --version") == "3.2.0" def test_user(host): - user = 'radicale' + user = "radicale" assert host.user(user).uid == 2999 assert host.user(user).gid == 2999 - assert host.user(user).shell == '/bin/false' - assert 'radicale L ' in host.check_output('passwd --status radicale') + assert host.user(user).shell == "/bin/false" + assert "radicale L " in host.check_output("passwd --status radicale") def test_data_folder_writable(host): - folder = '/data' - assert host.file(folder).user == 'radicale' - assert host.file(folder).group == 'radicale' + folder = "/data" + assert host.file(folder).user == "radicale" + assert host.file(folder).group == "radicale" assert host.file(folder).mode == 0o770