diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5c29867cc89c..f54ea16d3834 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -361,27 +361,11 @@ jobs: (wget -O - "https://github.com/matrix-org/complement/archive/$BRANCH_NAME.tar.gz" | tar -xz --strip-components=1 -C complement) && break done - # Build initial Synapse image - - run: docker build -t matrixdotorg/synapse:latest -f docker/Dockerfile . - working-directory: synapse - env: - DOCKER_BUILDKIT: 1 - - # Build a ready-to-run Synapse image based on the initial image above. - # This new image includes a config file, keys for signing and TLS, and - # other settings to make it suitable for testing under Complement. - - run: docker build -t complement-synapse -f Synapse.Dockerfile . - working-directory: complement/dockerfiles - - # Run Complement - run: | set -o pipefail - go test -v -json -tags synapse_blacklist,msc2716,msc3030 ./tests/... 2>&1 | gotestfmt + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -json 2>&1 | gotestfmt shell: bash name: Run Complement Tests - env: - COMPLEMENT_BASE_IMAGE: complement-synapse:latest - working-directory: complement # a job which marks all the other jobs as complete, thus allowing PRs to be merged. tests-done: diff --git a/changelog.d/12404.misc b/changelog.d/12404.misc new file mode 100644 index 000000000000..00100fdfeffe --- /dev/null +++ b/changelog.d/12404.misc @@ -0,0 +1 @@ +Add files used to build the Docker image used for complement testing into the Synapse repository. diff --git a/docker/complement/Dockerfile b/docker/complement/Dockerfile new file mode 100644 index 000000000000..4823ce7364a9 --- /dev/null +++ b/docker/complement/Dockerfile @@ -0,0 +1,22 @@ +# A dockerfile which builds an image suitable for testing Synapse under +# complement. + +ARG SYNAPSE_VERSION=latest + +FROM matrixdotorg/synapse:${SYNAPSE_VERSION} + +ENV SERVER_NAME=localhost + +COPY conf/* /conf/ + +# generate a signing key +RUN generate_signing_key -o /conf/server.signing.key + +WORKDIR /data + +EXPOSE 8008 8448 + +ENTRYPOINT ["/conf/start.sh"] + +HEALTHCHECK --start-period=5s --interval=1s --timeout=1s \ + CMD curl -fSs http://localhost:8008/health || exit 1 diff --git a/docker/complement/README.md b/docker/complement/README.md new file mode 100644 index 000000000000..e075418e4a96 --- /dev/null +++ b/docker/complement/README.md @@ -0,0 +1 @@ +Stuff for building the docker image used for testing under complement. diff --git a/docker/complement/SynapseWorkers.Dockerfile b/docker/complement/SynapseWorkers.Dockerfile new file mode 100644 index 000000000000..982219a91e7e --- /dev/null +++ b/docker/complement/SynapseWorkers.Dockerfile @@ -0,0 +1,73 @@ +# This dockerfile builds on top of 'docker/Dockerfile-worker' in matrix-org/synapse +# by including a built-in postgres instance, as well as setting up the homeserver so +# that it is ready for testing via Complement. +# +# Instructions for building this image from those it depends on is detailed in this guide: +# https://github.com/matrix-org/synapse/blob/develop/docker/README-testing.md#testing-with-postgresql-and-single-or-multi-process-synapse +FROM matrixdotorg/synapse-workers + +# Download a caddy server to stand in front of nginx and terminate TLS using Complement's +# custom CA. +# We include this near the top of the file in order to cache the result. +RUN curl -OL "https://github.com/caddyserver/caddy/releases/download/v2.3.0/caddy_2.3.0_linux_amd64.tar.gz" && \ + tar xzf caddy_2.3.0_linux_amd64.tar.gz && rm caddy_2.3.0_linux_amd64.tar.gz && mv caddy /root + +# Install postgresql +RUN apt-get update +RUN apt-get install -y postgresql + +# Configure a user and create a database for Synapse +RUN pg_ctlcluster 13 main start && su postgres -c "echo \ + \"ALTER USER postgres PASSWORD 'somesecret'; \ + CREATE DATABASE synapse \ + ENCODING 'UTF8' \ + LC_COLLATE='C' \ + LC_CTYPE='C' \ + template=template0;\" | psql" && pg_ctlcluster 13 main stop + +# Modify the shared homeserver config with postgres support, certificate setup +# and the disabling of rate-limiting +COPY conf-workers/workers-shared.yaml /conf/workers/shared.yaml + +WORKDIR /data + +# Copy the caddy config +COPY conf-workers/caddy.complement.json /root/caddy.json + +# Expose caddy's listener ports +EXPOSE 8008 8448 + +ENTRYPOINT \ + # Replace the server name in the caddy config + sed -i "s/{{ server_name }}/${SERVER_NAME}/g" /root/caddy.json && \ + # Start postgres + pg_ctlcluster 13 main start 2>&1 && \ + # Start caddy + /root/caddy start --config /root/caddy.json 2>&1 && \ + # Set the server name of the homeserver + SYNAPSE_SERVER_NAME=${SERVER_NAME} \ + # No need to report stats here + SYNAPSE_REPORT_STATS=no \ + # Set postgres authentication details which will be placed in the homeserver config file + POSTGRES_PASSWORD=somesecret POSTGRES_USER=postgres POSTGRES_HOST=localhost \ + # Specify the workers to test with + SYNAPSE_WORKER_TYPES="\ + event_persister, \ + event_persister, \ + background_worker, \ + frontend_proxy, \ + event_creator, \ + user_dir, \ + media_repository, \ + federation_inbound, \ + federation_reader, \ + federation_sender, \ + synchrotron, \ + appservice, \ + pusher" \ + # Run the script that writes the necessary config files and starts supervisord, which in turn + # starts everything else + /configure_workers_and_start.py + +HEALTHCHECK --start-period=5s --interval=1s --timeout=1s \ + CMD /bin/sh /healthcheck.sh diff --git a/docker/complement/conf-workers/caddy.complement.json b/docker/complement/conf-workers/caddy.complement.json new file mode 100644 index 000000000000..09e2136af2e2 --- /dev/null +++ b/docker/complement/conf-workers/caddy.complement.json @@ -0,0 +1,72 @@ +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8448" + ], + "routes": [ + { + "match": [ + { + "host": [ + "{{ server_name }}" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "localhost:8008" + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + }, + "tls": { + "automation": { + "policies": [ + { + "subjects": [ + "{{ server_name }}" + ], + "issuers": [ + { + "module": "internal" + } + ], + "on_demand": true + } + ] + } + }, + "pki": { + "certificate_authorities": { + "local": { + "name": "Complement CA", + "root": { + "certificate": "/complement/ca/ca.crt", + "private_key": "/complement/ca/ca.key" + } + } + } + } + } + } diff --git a/docker/complement/conf-workers/workers-shared.yaml b/docker/complement/conf-workers/workers-shared.yaml new file mode 100644 index 000000000000..cdadb736f6ff --- /dev/null +++ b/docker/complement/conf-workers/workers-shared.yaml @@ -0,0 +1,77 @@ +## Server ## +report_stats: False +trusted_key_servers: [] +enable_registration: true +enable_registration_without_verification: true +bcrypt_rounds: 4 + +## Federation ## + +# disable verification of federation certificates +# +# TODO: Figure out why this is still needed even though we are making use of the custom CA +federation_verify_certificates: false + +# trust certs signed by Complement's CA +federation_custom_ca_list: +- /complement/ca/ca.crt + +# unblacklist RFC1918 addresses +federation_ip_range_blacklist: [] + +# Disable server rate-limiting +rc_federation: + window_size: 1000 + sleep_limit: 10 + sleep_delay: 500 + reject_limit: 99999 + concurrent: 3 + +rc_message: + per_second: 9999 + burst_count: 9999 + +rc_registration: + per_second: 9999 + burst_count: 9999 + +rc_login: + address: + per_second: 9999 + burst_count: 9999 + account: + per_second: 9999 + burst_count: 9999 + failed_attempts: + per_second: 9999 + burst_count: 9999 + +rc_admin_redaction: + per_second: 9999 + burst_count: 9999 + +rc_joins: + local: + per_second: 9999 + burst_count: 9999 + remote: + per_second: 9999 + burst_count: 9999 + +federation_rr_transactions_per_room_per_second: 9999 + +## Experimental Features ## + +experimental_features: + # Enable history backfilling support + msc2716_enabled: true + # Enable spaces support + spaces_enabled: true + # Enable jump to date endpoint + msc3030_enabled: true + +server_notices: + system_mxid_localpart: _server + system_mxid_display_name: "Server Alert" + system_mxid_avatar_url: "" + room_name: "Server Alert" diff --git a/docker/complement/conf/homeserver.yaml b/docker/complement/conf/homeserver.yaml new file mode 100644 index 000000000000..be53c4aa2e33 --- /dev/null +++ b/docker/complement/conf/homeserver.yaml @@ -0,0 +1,122 @@ +## Server ## + +server_name: SERVER_NAME +log_config: /conf/log_config.yaml +report_stats: False +signing_key_path: /conf/server.signing.key +trusted_key_servers: [] +enable_registration: true +enable_registration_without_verification: true + +## Listeners ## + +tls_certificate_path: /conf/server.tls.crt +tls_private_key_path: /conf/server.tls.key +bcrypt_rounds: 4 +registration_shared_secret: complement + +listeners: + - port: 8448 + bind_addresses: ['::'] + type: http + tls: true + resources: + - names: [federation] + + - port: 8008 + bind_addresses: ['::'] + type: http + + resources: + - names: [client] + +## Database ## + +database: + name: "sqlite3" + args: + # We avoid /data, as it is a volume and is not transferred when the container is committed, + # which is a fundamental necessity in complement. + database: "/conf/homeserver.db" + +## Federation ## + + +# disable verification of federation certificates +# +# TODO: this is temporary; see +# https://github.com/matrix-org/synapse/issues/11803 +federation_verify_certificates: false + +# trust certs signed by the complement CA +federation_custom_ca_list: +- /complement/ca/ca.crt + +# unblacklist RFC1918 addresses +ip_range_blacklist: [] + +# Disable server rate-limiting +rc_federation: + window_size: 1000 + sleep_limit: 10 + sleep_delay: 500 + reject_limit: 99999 + concurrent: 3 + +rc_message: + per_second: 9999 + burst_count: 9999 + +rc_registration: + per_second: 9999 + burst_count: 9999 + +rc_login: + address: + per_second: 9999 + burst_count: 9999 + account: + per_second: 9999 + burst_count: 9999 + failed_attempts: + per_second: 9999 + burst_count: 9999 + +rc_admin_redaction: + per_second: 9999 + burst_count: 9999 + +rc_joins: + local: + per_second: 9999 + burst_count: 9999 + remote: + per_second: 9999 + burst_count: 9999 + +federation_rr_transactions_per_room_per_second: 9999 + +## API Configuration ## + +# A list of application service config files to use +# +app_service_config_files: +AS_REGISTRATION_FILES + +## Experimental Features ## + +experimental_features: + # Enable spaces support + spaces_enabled: true + # Enable history backfilling support + msc2716_enabled: true + # server-side support for partial state in /send_join + msc3706_enabled: true + # Enable jump to date endpoint + msc3030_enabled: true + +server_notices: + system_mxid_localpart: _server + system_mxid_display_name: "Server Alert" + system_mxid_avatar_url: "" + room_name: "Server Alert" diff --git a/docker/complement/conf/log_config.yaml b/docker/complement/conf/log_config.yaml new file mode 100644 index 000000000000..c33fd6cd00a7 --- /dev/null +++ b/docker/complement/conf/log_config.yaml @@ -0,0 +1,24 @@ +version: 1 + +formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + +filters: + context: + (): synapse.logging.context.LoggingContextFilter + request: "" + +handlers: + console: + class: logging.StreamHandler + formatter: precise + filters: [context] + # log to stdout, for easier use with 'docker logs' + stream: 'ext://sys.stdout' + +root: + level: INFO + handlers: [console] + +disable_existing_loggers: false diff --git a/docker/complement/conf/start.sh b/docker/complement/conf/start.sh new file mode 100755 index 000000000000..5d8d0fe016cf --- /dev/null +++ b/docker/complement/conf/start.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +set -e + +sed -i "s/SERVER_NAME/${SERVER_NAME}/g" /conf/homeserver.yaml + +# Add the application service registration files to the homeserver.yaml config +for filename in /complement/appservice/*.yaml; do + [ -f "$filename" ] || break + + as_id=$(basename "$filename" .yaml) + + # Insert the path to the registration file and the AS_REGISTRATION_FILES marker after + # so we can add the next application service in the next iteration of this for loop + sed -i "s/AS_REGISTRATION_FILES/ - \/complement\/appservice\/${as_id}.yaml\nAS_REGISTRATION_FILES/g" /conf/homeserver.yaml +done +# Remove the AS_REGISTRATION_FILES entry +sed -i "s/AS_REGISTRATION_FILES//g" /conf/homeserver.yaml + +# generate an ssl key and cert for the server, signed by the complement CA +openssl genrsa -out /conf/server.tls.key 2048 + +openssl req -new -key /conf/server.tls.key -out /conf/server.tls.csr \ + -subj "/CN=${SERVER_NAME}" +openssl x509 -req -in /conf/server.tls.csr \ + -CA /complement/ca/ca.crt -CAkey /complement/ca/ca.key -set_serial 1 \ + -out /conf/server.tls.crt + +exec python -m synapse.app.homeserver -c /conf/homeserver.yaml "$@" + diff --git a/scripts-dev/complement.sh b/scripts-dev/complement.sh index d1b59ff0401b..05e9e470ed03 100755 --- a/scripts-dev/complement.sh +++ b/scripts-dev/complement.sh @@ -50,25 +50,18 @@ if [[ -n "$WORKERS" ]]; then export COMPLEMENT_BASE_IMAGE=complement-synapse-workers COMPLEMENT_DOCKERFILE=SynapseWorkers.Dockerfile + # And provide some more configuration to complement. - export COMPLEMENT_CA=true export COMPLEMENT_SPAWN_HS_TIMEOUT_SECS=25 else export COMPLEMENT_BASE_IMAGE=complement-synapse - COMPLEMENT_DOCKERFILE=Synapse.Dockerfile + COMPLEMENT_DOCKERFILE=Dockerfile fi # Build the Complement image from the Synapse image we just built. -docker build -t $COMPLEMENT_BASE_IMAGE -f "$COMPLEMENT_DIR/dockerfiles/$COMPLEMENT_DOCKERFILE" "$COMPLEMENT_DIR/dockerfiles" - -cd "$COMPLEMENT_DIR" - -EXTRA_COMPLEMENT_ARGS="" -if [[ -n "$1" ]]; then - # A test name regex has been set, supply it to Complement - EXTRA_COMPLEMENT_ARGS+="-run $1 " -fi +docker build -t $COMPLEMENT_BASE_IMAGE -f "docker/complement/$COMPLEMENT_DOCKERFILE" "docker/complement" # Run the tests! echo "Images built; running complement" -go test -v -tags synapse_blacklist,msc2716,msc3030 -count=1 $EXTRA_COMPLEMENT_ARGS ./tests/... +cd "$COMPLEMENT_DIR" +go test -v -tags synapse_blacklist,msc2716,msc3030 -count=1 "$@" ./tests/...