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 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/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 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 diff --git a/test_image_custom_build.py b/test_image_custom_build.py index 64d20d2..61f2890 100644 --- a/test_image_custom_build.py +++ b/test_image_custom_build.py @@ -2,43 +2,61 @@ import subprocess 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.0.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.0.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 279fb42..d8ad249 100644 --- a/test_image_prod.py +++ b/test_image_prod.py @@ -1,60 +1,69 @@ -import subprocess - import pytest +import subprocess 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.1.9' + 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