From 06ca5c0100fba848203486f01a726704e1b682ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 11:21:28 +0000 Subject: [PATCH 01/10] Upgrade to GeoMapFish 2.9 --- .pre-commit-config.yaml | 35 ++++++++++++---- CONST_CHANGELOG.txt | 24 ++++++++--- .../.github/workflows/main.yaml | 6 +-- .../.github/workflows/rebuild.yaml | 8 ++-- .../.github/workflows/update_l10n.yaml | 6 +-- CONST_create_template/.pre-commit-config.yaml | 35 ++++++++++++++++ CONST_create_template/Dockerfile | 1 - CONST_create_template/Makefile | 22 +++++----- CONST_create_template/README.rst | 4 +- CONST_create_template/build | 25 +++++------ CONST_create_template/ci/config.yaml | 2 +- CONST_create_template/ci/docker-compose-check | 2 +- CONST_create_template/ci/requirements.txt | 2 +- CONST_create_template/docker-compose-db.yaml | 2 - CONST_create_template/docker-compose-lib.yaml | 35 ++++++++++------ .../docker-compose-qgis.yaml | 2 - .../docker-compose.override.sample.yaml | 7 +--- CONST_create_template/docker-compose.yaml | 2 - CONST_create_template/env.default | 6 +-- CONST_create_template/env.project | 2 +- CONST_create_template/geoportal/Dockerfile | 5 ++- .../geomapfish_geoportal-client.po | 21 +++++----- .../geomapfish_geoportal-client.po | 4 +- .../static-ngeo/api/api.css | 8 +++- .../static-ngeo/js/apps/Controllerdesktop.js | 4 +- .../js/apps/Controlleriframe_api.js | 2 +- .../static-ngeo/js/apps/Controllermobile.js | 2 +- .../js/apps/Controllermobile_alt.js | 2 +- .../static-ngeo/js/apps/Controlleroeedit.js | 6 +-- .../static/apihelp/index.html.tmpl | 2 +- .../geoportal/gunicorn.conf.py | 41 ++++++++++++++++++- CONST_create_template/geoportal/vars.yaml | 8 +++- .../geoportal/webpack.api.js | 4 +- .../geoportal/webpack.apps.js | 8 ++-- .../geoportal/webpack.commons.js | 1 - CONST_create_template/pyproject.toml | 2 +- CONST_create_template/scripts/db-backup | 3 +- CONST_create_template/scripts/db-restore | 6 +-- CONST_create_template/tests/test_app.py | 6 +-- CONST_create_template/tests/test_testapp.py | 2 +- .../tilegeneration/config.yaml.tmpl | 6 +-- build | 25 +++++------ ci/docker-compose-check | 2 +- ci/requirements.txt | 2 +- custom/custom/alembic/env.py | 1 + custom/custom/templates/layout.mako | 1 - docker-compose-lib.yaml | 35 ++++++++++------ docker-compose-qgis.yaml | 2 - env.default | 2 +- geoportal/CONST_config-schema.yaml | 5 +++ geoportal/CONST_vars.yaml | 25 ++++++----- .../static-ngeo/api/api.css | 8 +++- .../static-ngeo/js/apps/Controllerdesktop.js | 4 +- .../js/apps/Controlleriframe_api.js | 2 +- .../static-ngeo/js/apps/Controllermobile.js | 2 +- .../js/apps/Controllermobile_alt.js | 2 +- .../static-ngeo/js/apps/Controlleroeedit.js | 6 +-- .../static/apihelp/index.html.tmpl | 2 +- .../static/img/QGIS_logo_2017.svg | 2 +- .../static/story-map.html | 2 +- geoportal/gunicorn.conf.py | 41 ++++++++++++++++++- geoportal/vars.yaml | 2 +- geoportal/webpack.api.js | 4 +- geoportal/webpack.apps.js | 8 ++-- geoportal/webpack.commons.js | 1 - mapserver/Aster2056.prj | 2 +- mapserver/SRTM2056.prj | 2 +- mapserver/fonts.conf | 2 +- pyproject.toml | 2 +- qgisserver/bavaria_leisure_themes.qgs | 2 +- qgisserver/project_no_wfs.qgs | 2 +- scripts/db-backup | 3 +- scripts/db-restore | 6 +-- webcomponents/feedback.ts | 4 +- webcomponents/index.html | 2 +- 75 files changed, 380 insertions(+), 204 deletions(-) create mode 100644 CONST_create_template/.pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9416fc83e..2518e8f65 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,35 @@ # https://pre-commit.com/hooks.html +ci: + autoupdate_schedule: quarterly + skip: + - ripsecrets + repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace + args: + - --markdown-linebreak-ext=.md + - id: mixed-line-ending + args: + - --fix=lf - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.7.1 + rev: v3.1.0 hooks: - id: prettier - additional_dependencies: - - prettier@2.8.4 - - repo: https://github.com/sbrunner/jsonschema-validator - rev: 0.1.0 + - repo: https://github.com/PyCQA/autoflake + rev: v2.3.1 + hooks: + - id: autoflake + - repo: https://github.com/PyCQA/isort + rev: 5.13.2 + hooks: + - id: isort + - repo: https://github.com/psf/black + rev: 24.4.2 hooks: - - id: jsonschema-validator - files: ^ci/config\.yaml$ + - id: black diff --git a/CONST_CHANGELOG.txt b/CONST_CHANGELOG.txt index f5d7b6257..f58031fff 100644 --- a/CONST_CHANGELOG.txt +++ b/CONST_CHANGELOG.txt @@ -1,14 +1,28 @@ This file includes migration steps for each release of c2cgeoportal. ============= -Version 2.8.1 +Version 2.9.0 ============= -1. Update dependencies to use GDAL 3.7 +Information to know before starting the upgrade +=============================================== + +1. The build command will use Docker Compose version 2 (with the `docker compose` command). + +Information +=========== + +1. Hostname check: + We add a hostname check on the `came_from` parameter, in the oauth2 login, allowed by + `vars.authentication.allowed_hosts` and in the OGC server clear cache, allowed by `vars.allowed_hosts`. + The behavior change a little bit in the `shortener.allowed_hosts` and in the `authorized_referers`. + Now everywhere: + - If the hostname (with port) of the candidate URL equals to the request's header "Host", then it's OK. + - If the hostname (with port) of the candidate URL is in the allowed list, then it's OK. + And they should be netloc (hostname with port) without schema or path. - Use MapServer 8.0 with GDAL 3.7 (instead of 3.6) - Use QGIS server 3.28 with GDAL 3.7 (instead of 3.6) - Use GDAL 3.7 as based image (instead of 3.6) +2. We replace checks (formatting) done by `c2cciutils` by `pre-commit` hooks. + This will me more standard and transparent for the project. ============= Version 2.8.0 diff --git a/CONST_create_template/.github/workflows/main.yaml b/CONST_create_template/.github/workflows/main.yaml index 2c12c26e5..a8bde0e0a 100644 --- a/CONST_create_template/.github/workflows/main.yaml +++ b/CONST_create_template/.github/workflows/main.yaml @@ -16,7 +16,7 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # To publish the images to be used on Kubernetes # - uses: camptocamp/initialise-gopass-summon-action@v2 @@ -33,8 +33,8 @@ jobs: # - run: make secrets # - run: cat env.secrets |grep '^[# A-Z0-9_]\+='|sed -e 's/^[# A-Z0-9_]\+=\(.*\)/::add-mask::\1/g' - - name: Checks - run: c2cciutils-checks + - name: Environment information + run: c2cciutils-env # - name: Initialize the acceptance tests # run: make acceptance-init diff --git a/CONST_create_template/.github/workflows/rebuild.yaml b/CONST_create_template/.github/workflows/rebuild.yaml index 3358348af..cd71fd158 100644 --- a/CONST_create_template/.github/workflows/rebuild.yaml +++ b/CONST_create_template/.github/workflows/rebuild.yaml @@ -10,7 +10,7 @@ env: # Requires CI_GPG_PRIVATE_KEY and GOPASS_CI_GITHUB_TOKEN secrets. # OPENSHIFT_PROJECT: gs-gmf-geomapfish # The release branches - HELM_RELEASE_NAMES: int-2-8,prod-2-8 + HELM_RELEASE_NAMES: int-2-9,prod-2-9 jobs: rebuild: @@ -22,11 +22,11 @@ jobs: fail-fast: false matrix: branch: - - int-2-8 - - prod-2-8 + - int-2-9 + - prod-2-9 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: ref: ${{ matrix.branch }} diff --git a/CONST_create_template/.github/workflows/update_l10n.yaml b/CONST_create_template/.github/workflows/update_l10n.yaml index a9bf46842..966a3e022 100644 --- a/CONST_create_template/.github/workflows/update_l10n.yaml +++ b/CONST_create_template/.github/workflows/update_l10n.yaml @@ -15,13 +15,13 @@ jobs: fail-fast: false matrix: include: - - branch: int-2-8 + - branch: int-2-9 base_url: int.customer.ch - - branch: prod-2-8 + - branch: prod-2-9 base_url: prod.customer.ch steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: ref: ${{ matrix.branch }} token: ${{ secrets.GOPASS_CI_GITHUB_TOKEN }} diff --git a/CONST_create_template/.pre-commit-config.yaml b/CONST_create_template/.pre-commit-config.yaml new file mode 100644 index 000000000..2518e8f65 --- /dev/null +++ b/CONST_create_template/.pre-commit-config.yaml @@ -0,0 +1,35 @@ +# https://pre-commit.com/hooks.html + +ci: + autoupdate_schedule: quarterly + skip: + - ripsecrets + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace + args: + - --markdown-linebreak-ext=.md + - id: mixed-line-ending + args: + - --fix=lf + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.1.0 + hooks: + - id: prettier + - repo: https://github.com/PyCQA/autoflake + rev: v2.3.1 + hooks: + - id: autoflake + - repo: https://github.com/PyCQA/isort + rev: 5.13.2 + hooks: + - id: isort + - repo: https://github.com/psf/black + rev: 24.4.2 + hooks: + - id: black diff --git a/CONST_create_template/Dockerfile b/CONST_create_template/Dockerfile index a16720ee0..aa2c3eddb 100644 --- a/CONST_create_template/Dockerfile +++ b/CONST_create_template/Dockerfile @@ -62,7 +62,6 @@ RUN \ /usr/local/tomcat/webapps/ROOT/print-apps \ /etc/haproxy_dev \ /etc/haproxy \ - && adduser www-data root \ && sed 's#bind :80#bind *:443 ssl crt /etc/haproxy_dev/localhost.pem#g' /etc/haproxy/haproxy.cfg.tmpl \ > /etc/haproxy_dev/haproxy.cfg.tmpl \ && echo ' http-request set-header X-Forwarded-Proto https' >> /etc/haproxy_dev/haproxy.cfg.tmpl diff --git a/CONST_create_template/Makefile b/CONST_create_template/Makefile index ae6d8ca4a..38318f18f 100644 --- a/CONST_create_template/Makefile +++ b/CONST_create_template/Makefile @@ -16,30 +16,30 @@ update-po-from-url: ## Update the po files from the URL provide by PROJECT_PUBLI curl --fail --retry 5 --retry-delay 1 \ $(PROJECT_PUBLIC_URL)locale.pot > geoportal/${PACKAGE}_geoportal/locale/${PACKAGE}_geoportal-client${SUFFIX}.pot sed -i '/^"POT-Creation-Date: /d' geoportal/${PACKAGE}_geoportal/locale/${PACKAGE}_geoportal-client${SUFFIX}.pot - docker-compose run --rm -T tools update-po-only `id --user` `id --group` $(LANGUAGES) + docker compose run --rm -T tools update-po-only `id --user` `id --group` $(LANGUAGES) .PHONY: update-po update-po: ## Update the po files from the running composition - docker-compose exec -T tools sh -c "USER_ID=`id --user` GROUP_ID=`id --group` make --directory=geoportal update-po" + docker compose exec -T tools sh -c "USER_ID=`id --user` GROUP_ID=`id --group` make --directory=geoportal update-po" .PHONY: checks checks: prospector eslint ## Runs the checks .PHONY: prospector prospector: ## Runs the Prospector checks - docker-compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \ + docker compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \ prospector --output-format=pylint --die-on-tool-error .PHONY: eslint eslint: ## Runs the eslint checks - docker-compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \ + docker compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \ eslint $(find geomapfish -type f -name '*.js' -print 2> /dev/null) - docker-compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \ + docker compose run --entrypoint= --no-deps --rm --volume=$(CURDIR)/geoportal:/app geoportal \ eslint $(find geomapfish -type f -name '*.ts' -print 2> /dev/null) .PHONY: qgis qgis: ## Run QGIS desktop - docker-compose -f docker-compose.yaml -f docker-compose-qgis.yaml run --rm qgis + docker compose -f docker-compose.yaml -f docker-compose-qgis.yaml run --rm qgis secrets.tar.bz2.gpg: env.secrets ## Encrypt the secrets for committing changes tar -jcf secrets.tar.bz2 $^ @@ -57,14 +57,14 @@ secrets: ## Decrypt the secrets.tar.bz2.gpg file .PHONY: acceptance-init acceptance-init: ## Initialize the acceptance tests - docker-compose --file=docker-compose.yaml --file=docker-compose-db.yaml up -d db tools - docker-compose exec -T tools wait-db - docker-compose exec -T tools psql --command="DROP EXTENSION IF EXISTS postgis CASCADE" + docker compose --file=docker-compose.yaml --file=docker-compose-db.yaml up -d db tools + docker compose exec -T tools wait-db + docker compose exec -T tools psql --command="DROP EXTENSION IF EXISTS postgis CASCADE" scripts/db-restore --docker-compose-file=docker-compose.yaml --docker-compose-file=docker-compose-db.yaml \ --arg=--clean --arg=--if-exists --arg=--verbose $(DUMP_FILE) - docker-compose --file=docker-compose.yaml --file=docker-compose-db.yaml up -d + docker compose --file=docker-compose.yaml --file=docker-compose-db.yaml up -d .PHONY: acceptance acceptance: ## Run the acceptance tests - docker-compose exec -T tools pytest -vv tests/ + docker compose exec -T tools pytest -vv tests/ ci/docker-compose-check diff --git a/CONST_create_template/README.rst b/CONST_create_template/README.rst index daaf08928..5062c105d 100644 --- a/CONST_create_template/README.rst +++ b/CONST_create_template/README.rst @@ -1,7 +1,7 @@ demo_geomapfish project =================== -Read the `Documentation `_ +Read the `Documentation `_ Checkout -------- @@ -24,6 +24,6 @@ Run .. code:: - docker-compose up -d + docker compose up -d .. Feel free to add project-specific things. diff --git a/CONST_create_template/build b/CONST_create_template/build index 2a3a67f2b..8acca59a6 100755 --- a/CONST_create_template/build +++ b/CONST_create_template/build @@ -22,17 +22,13 @@ def run( args: argparse.Namespace, command: List[str], exit_on_error: bool = True, **kwargs: Any ) -> Optional[CompletedProcess]: if args.verbose or args.dry_run: - print(" ".join([shlex.quote(c) for c in command])) + print(shlex.join(command)) if not args.dry_run or "stdout" in kwargs: if args.stack_trace and exit_on_error and not "checks" in kwargs: kwargs["check"] = True process = subprocess.run(command, **kwargs) # nosec if exit_on_error and process.returncode != 0: - print( - "An error occurred during execution of `{}`".format( - " ".join([shlex.quote(c) for c in command]) - ) - ) + print(f"An error occurred during execution of `{shlex.join(command)}`") sys.exit(process.returncode) return process return None @@ -103,6 +99,7 @@ def main() -> None: sys.exit(1) sys.exit(0) + docker_compose_command = ["docker", "compose"] with open("project.yaml", encoding="utf-8") as project_file: project_env = yaml.load(project_file, Loader=yaml.SafeLoader)["env"] if len(args.env_files) != project_env["required_args"]: @@ -112,7 +109,7 @@ def main() -> None: print("Use env files: {}".format(", ".join(env_files))) for env_file in env_files: if not os.path.exists(env_file): - print("Error: the env file '{env_file}' does not exist.".format(env_file=env_file)) + print(f"Error: the env file '{env_file}' does not exist.") sys.exit(1) with open(".env", "w", encoding="utf-8") as dest: @@ -128,18 +125,18 @@ def main() -> None: git_hash = run(args, ["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE).stdout.decode().strip() - dest.write("SIMPLE={}\n".format(str(simple).upper())) - dest.write("GIT_HASH={git_hash}\n".format(git_hash=git_hash)) + dest.write(f"SIMPLE={str(simple).upper()}\n") + dest.write(f"GIT_HASH={git_hash}\n") dest.write("# Used env files: {}\n".format(", ".join(env_files))) if not args.env: - docker_compose_build_cmd = ["docker-compose", "build"] + docker_compose_build_cmd = [*docker_compose_command, "build"] if not args.no_pull: # Pull all the images if not args.service: - run(args, ["docker-compose", "pull", "--ignore-pull-failures"]) # nosec + run(args, [*docker_compose_command, "pull", "--ignore-buildable"]) # nosec docker_compose_build_cmd.append("--pull") if args.service: @@ -163,7 +160,7 @@ def main() -> None: service for service in run( args, - ["docker-compose", "ps", "--services", "--all"], + [*docker_compose_command, "ps", "--services", "--all"], stdout=subprocess.PIPE, exit_on_error=True, ) @@ -173,9 +170,9 @@ def main() -> None: ] if args.reload is not None: - run(args, ["docker-compose", "rm", "--force", "-v", "config"]) + run(args, [*docker_compose_command, "rm", "--force", "-v", "config"]) for service in services: - run(args, ["docker-compose", "up", "--detach", "--force-recreate", service]) + run(args, [*docker_compose_command, "up", "--detach", "--force-recreate", service]) if __name__ == "__main__": diff --git a/CONST_create_template/ci/config.yaml b/CONST_create_template/ci/config.yaml index 69d38da9f..8b738862e 100644 --- a/CONST_create_template/ci/config.yaml +++ b/CONST_create_template/ci/config.yaml @@ -1,4 +1,4 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/camptocamp/c2cciutils/1.4/c2cciutils/schema.json +# yaml-language-server: $schema=https://raw.githubusercontent.com/camptocamp/c2cciutils/master/c2cciutils/schema.json checks: codespell: False diff --git a/CONST_create_template/ci/docker-compose-check b/CONST_create_template/ci/docker-compose-check index 5feb9c31b..ed31693b9 100755 --- a/CONST_create_template/ci/docker-compose-check +++ b/CONST_create_template/ci/docker-compose-check @@ -11,7 +11,7 @@ def _main() -> None: services = [ s.strip() - for s in subprocess.run(["docker-compose", "ps"], check=True, stdout=subprocess.PIPE) + for s in subprocess.run(["docker", "compose", "ps"], check=True, stdout=subprocess.PIPE) .stdout.decode("utf-8") .splitlines() ] diff --git a/CONST_create_template/ci/requirements.txt b/CONST_create_template/ci/requirements.txt index 993e22779..140d774a5 100644 --- a/CONST_create_template/ci/requirements.txt +++ b/CONST_create_template/ci/requirements.txt @@ -1 +1 @@ -c2cciutils[checks,publish]==1.4.16 +c2cciutils[checks,publish]==1.6.21 diff --git a/CONST_create_template/docker-compose-db.yaml b/CONST_create_template/docker-compose-db.yaml index 6e5e99221..800dc8727 100644 --- a/CONST_create_template/docker-compose-db.yaml +++ b/CONST_create_template/docker-compose-db.yaml @@ -1,7 +1,5 @@ # This file is used by the acceptance tests to have a local database. -version: '2.3' - volumes: postgresql_data: diff --git a/CONST_create_template/docker-compose-lib.yaml b/CONST_create_template/docker-compose-lib.yaml index ef39976cb..8af69fa0f 100644 --- a/CONST_create_template/docker-compose-lib.yaml +++ b/CONST_create_template/docker-compose-lib.yaml @@ -1,7 +1,5 @@ # This file is managed by c2cgeoportal, it contains the default services configuration -version: '2.3' - services: config: image: ${DOCKER_BASE}-config:${DOCKER_TAG} @@ -77,7 +75,7 @@ services: - PGOPTIONS mapserver: - image: camptocamp/mapserver:8.0-gdal3.7 + image: camptocamp/mapserver:8.0-gdal3.6 user: www-data restart: unless-stopped entrypoint: [] @@ -137,7 +135,7 @@ services: restart: unless-stopped redis: - image: &redis-image redis:7.0 + image: redis:7.2 user: www-data restart: unless-stopped command: @@ -154,21 +152,32 @@ services: - '30' redis_master: - image: *redis-image + image: bitnami/redis:7.2.5 + environment: + - REDIS_REPLICATION_MODE=master + - ALLOW_EMPTY_PASSWORD=yes redis_slave: - image: *redis-image - command: redis-server --slaveof redis_master 6379 + image: bitnami/redis:7.2.5 + environment: + - REDIS_REPLICATION_MODE=slave + - REDIS_MASTER_HOST=redis_master + - ALLOW_EMPTY_PASSWORD=yes + depends_on: + - redis_master redis_sentinel: - image: camptocamp/c2cwsgiutils-redis-sentinel:6 + image: bitnami/redis-sentinel:7.2.5 environment: - - MASTER_NAME=mymaster - - QUORUM=1 - - MASTER=redis_master + - REDIS_MASTER_HOST=redis_master + - REDIS_MASTER_SET=mymaster + - ALLOW_EMPTY_PASSWORD=yes + depends_on: + - redis_master + - redis_slave tilecloudchain: - image: &tilecloudchain-image camptocamp/tilecloud-chain:1.17 + image: &tilecloudchain-image camptocamp/tilecloud-chain:1.20 user: www-data restart: unless-stopped environment: @@ -217,7 +226,7 @@ services: user: www-data restart: unless-stopped entrypoint: - - generate_tiles + - generate-tiles - --role=slave - --daemon environment: diff --git a/CONST_create_template/docker-compose-qgis.yaml b/CONST_create_template/docker-compose-qgis.yaml index af3860dd7..3a2bd3506 100644 --- a/CONST_create_template/docker-compose-qgis.yaml +++ b/CONST_create_template/docker-compose-qgis.yaml @@ -1,7 +1,5 @@ # This file is used to run QGIS client from the Docker image -version: '2' - services: qgis: extends: diff --git a/CONST_create_template/docker-compose.override.sample.yaml b/CONST_create_template/docker-compose.override.sample.yaml index 7c460042b..2d2359f70 100644 --- a/CONST_create_template/docker-compose.override.sample.yaml +++ b/CONST_create_template/docker-compose.override.sample.yaml @@ -1,8 +1,6 @@ # This file can be renamed as `docker-compose.override.yaml` and uncomment the desired lines for # development. The file `docker-compose.override.yaml` is ignored by Git by default. -version: '2.3' - services: geoportal: user: root @@ -27,6 +25,7 @@ services: ports: - 5678:5678 # For remote debugging using Visual Studio Code + # Also uncomment the PRINT_URL in geoportal # print: # extends: @@ -45,10 +44,6 @@ services: # - QGIS_SERVER_LOG_LEVEL=0 # - QGIS_CATCH_SEGV=1 # The result stack traces will be available in /var/log/qgis.log - tools: - volumes_from: - - config:rw - # # For Javascript project development. # The debug application will be available at ``https:////dev/.html``. # webpack_dev_server: diff --git a/CONST_create_template/docker-compose.yaml b/CONST_create_template/docker-compose.yaml index 2b70200bc..748dd4073 100644 --- a/CONST_create_template/docker-compose.yaml +++ b/CONST_create_template/docker-compose.yaml @@ -1,7 +1,5 @@ # The project Docker compose file. -version: '2.3' - volumes: postgresql_data: diff --git a/CONST_create_template/env.default b/CONST_create_template/env.default index 72f4a308e..725092046 100644 --- a/CONST_create_template/env.default +++ b/CONST_create_template/env.default @@ -1,7 +1,7 @@ # Default values for c2cgeoportal -GEOMAPFISH_VERSION=2.8.1.110 -GEOMAPFISH_MAIN_VERSION=2.8 -GEOMAPFISH_MAIN_MINOR_VERSION=2.8.1 +GEOMAPFISH_VERSION=2.9 +GEOMAPFISH_MAIN_VERSION=2.9 +GEOMAPFISH_MAIN_MINOR_VERSION=2.9.0 COMPOSE_PROJECT_NAME=geomapfish PACKAGE=geomapfish SRID=2056 diff --git a/CONST_create_template/env.project b/CONST_create_template/env.project index d3ef88947..5f55fe3c6 100644 --- a/CONST_create_template/env.project +++ b/CONST_create_template/env.project @@ -58,7 +58,7 @@ C2C_REDIS_URL=redis://redis:6379/0 # Set a strong password here for authentication on technical interfaces behind path /c2c C2C_SECRET= -# Or use connection via GitHub, see: https://camptocamp.github.io/c2cgeoportal/2.8/integrator/c2cwsgiutils.html#authentication +# Or use connection via GitHub, see: https://camptocamp.github.io/c2cgeoportal/2.9/integrator/c2cwsgiutils.html#authentication C2C_AUTH_GITHUB_REPOSITORY=camptocamp/geomapfish C2C_AUTH_GITHUB_ACCESS_TYPE=admin C2C_AUTH_GITHUB_CLIENT_ID=210aefe26259de1e9532 diff --git a/CONST_create_template/geoportal/Dockerfile b/CONST_create_template/geoportal/Dockerfile index 4489aa569..1c22fd855 100644 --- a/CONST_create_template/geoportal/Dockerfile +++ b/CONST_create_template/geoportal/Dockerfile @@ -41,8 +41,9 @@ RUN chmod go+w /etc/static-ngeo/ RUN --mount=type=cache,target=/root/.cache \ python3 -m pip install --disable-pip-version-check --editable=/app/ \ && python3 -m compileall -q /usr/local/lib/python3.* \ - -x '/(ptvsd|.*pydev.*|networkx)/' \ - && python3 -m compileall -q /app/geomapfish_geoportal -x /app/geomapfish_geoportal/static.* + -x '/(ptvsd|.*pydev.*|networkx|scaffolds|yaml_include)/' \ + && python3 -m compileall -q /app/geomapfish_geoportal -x /app/geomapfish_geoportal/static.* \ + && pip freeze > /requirements.txt ARG GIT_HASH RUN c2cwsgiutils-genversion ${GIT_HASH} diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/locale/de/LC_MESSAGES/geomapfish_geoportal-client.po b/CONST_create_template/geoportal/geomapfish_geoportal/locale/de/LC_MESSAGES/geomapfish_geoportal-client.po index 880b07871..fd1e53a94 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/locale/de/LC_MESSAGES/geomapfish_geoportal-client.po +++ b/CONST_create_template/geoportal/geomapfish_geoportal/locale/de/LC_MESSAGES/geomapfish_geoportal-client.po @@ -1,11 +1,12 @@ # # Translators: -# Stéphane Brunner , 2022 +# Stéphane Brunner , 2023 +# Wolfgang Kaltz , 2023 # msgid "" msgstr "" "Project-Id-Version: \n" -"Last-Translator: Stéphane Brunner , 2022\n" +"Last-Translator: Wolfgang Kaltz , 2023\n" "Language-Team: German (https://app.transifex.com/camptocamp/teams/36764/de/)\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -75,8 +76,8 @@ msgid "" "Draw a line on the map to display the corresponding elevation profile.\n" " Use double-click to finish the drawing." msgstr "" -"Zeichnen Sie eine Linie auf die Karte, um das entsprechende Höhenprofil " -"anzuzeigen. Schliessen Sie mit einem Doppelklick ab." +"Zeichnen Sie eine Linie auf die Karte, um das entsprechende Höhenprofil anzuzeigen.\n" +" Schliessen Sie mit einem Doppelklick ab." #: contribs/gmf/apps/desktop_alt.html:179 #: contribs/gmf/apps/desktop_alt/index.html.ejs:179 @@ -84,8 +85,8 @@ msgid "" "Draw a line on the map to display the corresponding elevation profile.\n" " Use double-click to finish the drawing." msgstr "" -"Zeichnen Sie eine Linie auf die Karte, um das entsprechende Höhenprofil " -"anzuzeigen. Schliessen Sie mit einem Doppelklick ab." +"Zeichnen Sie eine Linie auf die Karte, um das entsprechende Höhenprofil anzuzeigen.\n" +" Schliessen Sie mit einem Doppelklick ab." #: contribs/gmf/apps/desktop.html:149 contribs/gmf/apps/desktop.html:66 #: contribs/gmf/apps/desktop/index.html.ejs:149 @@ -135,7 +136,7 @@ msgstr "Höhenprofil" #: contribs/gmf/apps/desktop_alt/index.html.ejs:118 #: contribs/gmf/apps/desktop_alt/index.html.ejs:128 msgid "Filter" -msgstr "Filter" +msgstr "Filtrieren" #: contribs/gmf/apps/desktop_alt.html:207 #: contribs/gmf/apps/desktop_alt/index.html.ejs:207 @@ -250,7 +251,7 @@ msgstr "Abfrage" #: contribs/gmf/apps/desktop_alt.html:264 #: contribs/gmf/apps/desktop_alt/index.html.ejs:264 msgid "Routing" -msgstr "Routing" +msgstr "Routenplanung" #: contribs/gmf/apps/desktop.html:221 contribs/gmf/apps/desktop.html:85 #: contribs/gmf/apps/desktop/index.html.ejs:221 @@ -338,10 +339,10 @@ msgid "" "You're using the mobile application. Check out the standard application." msgstr "" -"Sie verwenden die mobile Anwendung. Wechsel zur Standard-Anwendung." #: contribs/gmf/apps/desktop_alt.html:92 #: contribs/gmf/apps/desktop_alt/index.html.ejs:92 msgid "debug" -msgstr "debug" +msgstr "Debug" diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/locale/fr/LC_MESSAGES/geomapfish_geoportal-client.po b/CONST_create_template/geoportal/geomapfish_geoportal/locale/fr/LC_MESSAGES/geomapfish_geoportal-client.po index ebd199827..0b894bd03 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/locale/fr/LC_MESSAGES/geomapfish_geoportal-client.po +++ b/CONST_create_template/geoportal/geomapfish_geoportal/locale/fr/LC_MESSAGES/geomapfish_geoportal-client.po @@ -1,11 +1,11 @@ # # Translators: -# Stéphane Brunner , 2022 +# Stéphane Brunner , 2023 # msgid "" msgstr "" "Project-Id-Version: \n" -"Last-Translator: Stéphane Brunner , 2022\n" +"Last-Translator: Stéphane Brunner , 2023\n" "Language-Team: French (https://app.transifex.com/camptocamp/teams/36764/fr/)\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/api/api.css b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/api/api.css index 9fc6d0502..ef5b2266b 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/api/api.css +++ b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/api/api.css @@ -85,12 +85,16 @@ .ol-rotate { top: 0.5em; right: 0.5em; - transition: opacity 0.25s linear, visibility 0s linear; + transition: + opacity 0.25s linear, + visibility 0s linear; } .ol-rotate.ol-hidden { opacity: 0; visibility: hidden; - transition: opacity 0.25s linear, visibility 0s linear 0.25s; + transition: + opacity 0.25s linear, + visibility 0s linear 0.25s; } .ol-zoom-extent { top: 4.643em; diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js index c6fa15b52..b98ff4308 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js +++ b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2016-2021 Camptocamp SA +// Copyright (c) 2016-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in @@ -68,7 +68,7 @@ geomapfishModule.run( ($templateCache) => { // @ts-ignore: webpack $templateCache.put('gmf/contextualdata', require('./contextualdata.html')); - } + }, ); geomapfishModule.controller('DesktopController', Controller); diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js index 5a2b3ab3e..8d7d110ef 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js +++ b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2015-2021 Camptocamp SA +// Copyright (c) 2015-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js index 6957b4896..0a64f0427 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js +++ b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2015-2021 Camptocamp SA +// Copyright (c) 2015-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js index c4739532f..8444ffbf0 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js +++ b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2015-2023 Camptocamp SA +// Copyright (c) 2015-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js index 5eb71ac1b..c582d59a3 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js +++ b/CONST_create_template/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2016-2021 Camptocamp SA +// Copyright (c) 2016-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in @@ -171,14 +171,14 @@ geomapfishModule.run( ($templateCache) => { // @ts-ignore: webpack $templateCache.put('gmf/contextualdata', require('./contextualdata.html')); - } + }, ); geomapfishModule.value( 'gmfPermalinkOptions', /** @type {import('gmf/options').gmfPermalinkOptions} */ ({ pointRecenterZoom: 10, - }) + }), ); geomapfishModule.controller('OEEditController', Controller); diff --git a/CONST_create_template/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl b/CONST_create_template/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl index 2e49d9b56..557da88d0 100644 --- a/CONST_create_template/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl +++ b/CONST_create_template/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl @@ -1,4 +1,4 @@ - + diff --git a/CONST_create_template/geoportal/gunicorn.conf.py b/CONST_create_template/geoportal/gunicorn.conf.py index 20e9b2ef1..5a360e3bc 100644 --- a/CONST_create_template/geoportal/gunicorn.conf.py +++ b/CONST_create_template/geoportal/gunicorn.conf.py @@ -32,7 +32,10 @@ import os -from c2cwsgiutils import get_config_defaults +import gunicorn.arbiter +import gunicorn.workers.base +from c2cwsgiutils import get_config_defaults, prometheus +from prometheus_client import multiprocess bind = ":8080" @@ -100,3 +103,39 @@ } raw_paste_global_conf = ["=".join(e) for e in get_config_defaults().items()] + + +def on_starting(server: gunicorn.arbiter.Arbiter) -> None: + """ + Will start the prometheus server. + + Called just before the master process is initialized. + """ + + del server + + prometheus.start() + + +def post_fork(server: gunicorn.arbiter.Arbiter, worker: gunicorn.workers.base.Worker) -> None: + """ + Will cleanup the configuration we get from the main process. + + Called just after a worker has been forked. + """ + + del server, worker + + prometheus.cleanup() + + +def child_exit(server: gunicorn.arbiter.Arbiter, worker: gunicorn.workers.base.Worker) -> None: + """ + Remove the metrics for the exited worker. + + Called just after a worker has been exited, in the master process. + """ + + del server + + multiprocess.mark_process_dead(worker.pid) diff --git a/CONST_create_template/geoportal/vars.yaml b/CONST_create_template/geoportal/vars.yaml index 78ad75a8f..ac36a0005 100644 --- a/CONST_create_template/geoportal/vars.yaml +++ b/CONST_create_template/geoportal/vars.yaml @@ -303,6 +303,9 @@ vars: host: '{REDIS_HOST}' port: '{REDIS_PORT}' db: '{REDIS_DB}' + password: '{REDIS_PASSWORD}' + connection_kwargs: + ssl: '{REDIS_SSL}' # Kubernetes version # arguments: &redis-cache-arguments # sentinels: @@ -347,7 +350,6 @@ update_paths: - admin_interface.functionalities - admin_interface.available_in_templates - api - - authorized_referers - cache.std.arguments - cache.ogc-server.arguments - cache.obj @@ -418,3 +420,7 @@ runtime_postprocess: - expression: int({}) vars: - cache.std.arguments.port + - expression: str({}).lower() in ("true", "yes", "1") + vars: + - cache.std.arguments.connection_kwargs.ssl + - cache.ogc-server.arguments.connection_kwargs.ssl diff --git a/CONST_create_template/geoportal/webpack.api.js b/CONST_create_template/geoportal/webpack.api.js index 793896621..839334e4b 100644 --- a/CONST_create_template/geoportal/webpack.api.js +++ b/CONST_create_template/geoportal/webpack.api.js @@ -7,7 +7,9 @@ const babelPresets = [ [ require.resolve('@babel/preset-env'), { - targets: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10', + targets: { + browsers: ['> 0.7% in CH', '> 0.7% in FR', 'Firefox ESR'], + }, modules: false, loose: true, }, diff --git a/CONST_create_template/geoportal/webpack.apps.js b/CONST_create_template/geoportal/webpack.apps.js index e75ca7298..a8541ab90 100644 --- a/CONST_create_template/geoportal/webpack.apps.js +++ b/CONST_create_template/geoportal/webpack.apps.js @@ -21,10 +21,10 @@ for (const filename of ls(path.resolve(__dirname, 'geomapfish_geoportal/static-n chunks: [name], vars: { entry_point: '${VISIBLE_ENTRY_POINT}', - version: '2.8.1.110', + version: '2.9', cache_version: '${CACHE_VERSION}', }, - }) + }), ); } @@ -32,7 +32,9 @@ const babelPresets = [ [ require.resolve('@babel/preset-env'), { - targets: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10', + targets: { + browsers: ['defaults', '> 0.7% in CH', '> 0.9% in FR', 'Firefox ESR', 'supports es6-class'], + }, modules: false, loose: true, }, diff --git a/CONST_create_template/geoportal/webpack.commons.js b/CONST_create_template/geoportal/webpack.commons.js index 43350c086..a00e4f6d7 100644 --- a/CONST_create_template/geoportal/webpack.commons.js +++ b/CONST_create_template/geoportal/webpack.commons.js @@ -5,7 +5,6 @@ const config = commons({ DllReferencePluginOptions: { context: '/usr/lib/', }, - browsers: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10', }); for (const plugin of config.plugins) { diff --git a/CONST_create_template/pyproject.toml b/CONST_create_template/pyproject.toml index f2514fa03..f1c321984 100644 --- a/CONST_create_template/pyproject.toml +++ b/CONST_create_template/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 110 -target-version = ['py38'] +target-version = ['py39'] [tool.isort] profile = "black" diff --git a/CONST_create_template/scripts/db-backup b/CONST_create_template/scripts/db-backup index faedb3ce8..f2b133b3d 100755 --- a/CONST_create_template/scripts/db-backup +++ b/CONST_create_template/scripts/db-backup @@ -89,7 +89,8 @@ def main() -> None: else: subprocess.run( [ - "docker-compose", + "docker", + "compose", "exec", "-T", "tools", diff --git a/CONST_create_template/scripts/db-restore b/CONST_create_template/scripts/db-restore index 7412cd801..5da9984ba 100755 --- a/CONST_create_template/scripts/db-restore +++ b/CONST_create_template/scripts/db-restore @@ -43,7 +43,7 @@ def main() -> None: "--docker-compose-file", action="append", default=[], - help="The docker-compose file to used.", + help="The docker compose file to used.", ) parser.add_argument( "--arg", @@ -92,8 +92,8 @@ def main() -> None: ) else: subprocess.run( - ["docker-compose"] - + ["--file={}".format(f) for f in args.docker_compose_file] + ["docker", "compose"] + + [f"--file={f}" for f in args.docker_compose_file] + [ "exec", "-T", diff --git a/CONST_create_template/tests/test_app.py b/CONST_create_template/tests/test_app.py index a1f91b5eb..f4f246ba6 100644 --- a/CONST_create_template/tests/test_app.py +++ b/CONST_create_template/tests/test_app.py @@ -1,5 +1,3 @@ -from typing import Dict - import pytest import requests @@ -7,7 +5,7 @@ @pytest.mark.parametrize( "url,params,timeout", [ - ("https://front", {}, 10), + ("https://front/", {}, 10), ("https://front/themes", {}, 120), ("https://front/static-geomapfish/0/locales/fr.json", {}, 2), ("https://front/dynamic.json", {"interface": "desktop"}, 10), @@ -25,7 +23,7 @@ ), ], ) -def test_url(url: str, params: Dict[str, str], timeout: int) -> None: +def test_url(url: str, params: dict[str, str], timeout: int) -> None: """Tests that some URL didn't return an error.""" response = requests.get(url, params=params, verify=False, timeout=timeout) # nosec assert response.status_code == 200, response.text diff --git a/CONST_create_template/tests/test_testapp.py b/CONST_create_template/tests/test_testapp.py index 3288581d0..aad6500ef 100644 --- a/CONST_create_template/tests/test_testapp.py +++ b/CONST_create_template/tests/test_testapp.py @@ -34,7 +34,7 @@ def test_desktop_alt(url: str) -> None: assert response.status_code == 200, response.text assert re.search( - r'', + r'', response.text, ), response.text assert re.search(r' Optional[CompletedProcess]: if args.verbose or args.dry_run: - print(" ".join([shlex.quote(c) for c in command])) + print(shlex.join(command)) if not args.dry_run or "stdout" in kwargs: if args.stack_trace and exit_on_error and not "checks" in kwargs: kwargs["check"] = True process = subprocess.run(command, **kwargs) # nosec if exit_on_error and process.returncode != 0: - print( - "An error occurred during execution of `{}`".format( - " ".join([shlex.quote(c) for c in command]) - ) - ) + print(f"An error occurred during execution of `{shlex.join(command)}`") sys.exit(process.returncode) return process return None @@ -103,6 +99,7 @@ def main() -> None: sys.exit(1) sys.exit(0) + docker_compose_command = ["docker", "compose"] with open("project.yaml", encoding="utf-8") as project_file: project_env = yaml.load(project_file, Loader=yaml.SafeLoader)["env"] if len(args.env_files) != project_env["required_args"]: @@ -112,7 +109,7 @@ def main() -> None: print("Use env files: {}".format(", ".join(env_files))) for env_file in env_files: if not os.path.exists(env_file): - print("Error: the env file '{env_file}' does not exist.".format(env_file=env_file)) + print(f"Error: the env file '{env_file}' does not exist.") sys.exit(1) with open(".env", "w", encoding="utf-8") as dest: @@ -128,18 +125,18 @@ def main() -> None: git_hash = run(args, ["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE).stdout.decode().strip() - dest.write("SIMPLE={}\n".format(str(simple).upper())) - dest.write("GIT_HASH={git_hash}\n".format(git_hash=git_hash)) + dest.write(f"SIMPLE={str(simple).upper()}\n") + dest.write(f"GIT_HASH={git_hash}\n") dest.write("# Used env files: {}\n".format(", ".join(env_files))) if not args.env: - docker_compose_build_cmd = ["docker-compose", "build"] + docker_compose_build_cmd = [*docker_compose_command, "build"] if not args.no_pull: # Pull all the images if not args.service: - run(args, ["docker-compose", "pull", "--ignore-pull-failures"]) # nosec + run(args, [*docker_compose_command, "pull", "--ignore-buildable"]) # nosec docker_compose_build_cmd.append("--pull") if args.service: @@ -163,7 +160,7 @@ def main() -> None: service for service in run( args, - ["docker-compose", "ps", "--services", "--all"], + [*docker_compose_command, "ps", "--services", "--all"], stdout=subprocess.PIPE, exit_on_error=True, ) @@ -173,9 +170,9 @@ def main() -> None: ] if args.reload is not None: - run(args, ["docker-compose", "rm", "--force", "-v", "config"]) + run(args, [*docker_compose_command, "rm", "--force", "-v", "config"]) for service in services: - run(args, ["docker-compose", "up", "--detach", "--force-recreate", service]) + run(args, [*docker_compose_command, "up", "--detach", "--force-recreate", service]) if __name__ == "__main__": diff --git a/ci/docker-compose-check b/ci/docker-compose-check index 5feb9c31b..ed31693b9 100755 --- a/ci/docker-compose-check +++ b/ci/docker-compose-check @@ -11,7 +11,7 @@ def _main() -> None: services = [ s.strip() - for s in subprocess.run(["docker-compose", "ps"], check=True, stdout=subprocess.PIPE) + for s in subprocess.run(["docker", "compose", "ps"], check=True, stdout=subprocess.PIPE) .stdout.decode("utf-8") .splitlines() ] diff --git a/ci/requirements.txt b/ci/requirements.txt index 993e22779..140d774a5 100644 --- a/ci/requirements.txt +++ b/ci/requirements.txt @@ -1 +1 @@ -c2cciutils[checks,publish]==1.4.16 +c2cciutils[checks,publish]==1.6.21 diff --git a/custom/custom/alembic/env.py b/custom/custom/alembic/env.py index 9340b4f0f..75f18d185 100644 --- a/custom/custom/alembic/env.py +++ b/custom/custom/alembic/env.py @@ -1,4 +1,5 @@ """Pyramid bootstrap environment. """ + from alembic import context from custom.models.meta import Base from pyramid.paster import get_appsettings, setup_logging diff --git a/custom/custom/templates/layout.mako b/custom/custom/templates/layout.mako index 34e06f5b5..0c28978dd 100644 --- a/custom/custom/templates/layout.mako +++ b/custom/custom/templates/layout.mako @@ -60,4 +60,3 @@ - diff --git a/docker-compose-lib.yaml b/docker-compose-lib.yaml index ef39976cb..8af69fa0f 100644 --- a/docker-compose-lib.yaml +++ b/docker-compose-lib.yaml @@ -1,7 +1,5 @@ # This file is managed by c2cgeoportal, it contains the default services configuration -version: '2.3' - services: config: image: ${DOCKER_BASE}-config:${DOCKER_TAG} @@ -77,7 +75,7 @@ services: - PGOPTIONS mapserver: - image: camptocamp/mapserver:8.0-gdal3.7 + image: camptocamp/mapserver:8.0-gdal3.6 user: www-data restart: unless-stopped entrypoint: [] @@ -137,7 +135,7 @@ services: restart: unless-stopped redis: - image: &redis-image redis:7.0 + image: redis:7.2 user: www-data restart: unless-stopped command: @@ -154,21 +152,32 @@ services: - '30' redis_master: - image: *redis-image + image: bitnami/redis:7.2.5 + environment: + - REDIS_REPLICATION_MODE=master + - ALLOW_EMPTY_PASSWORD=yes redis_slave: - image: *redis-image - command: redis-server --slaveof redis_master 6379 + image: bitnami/redis:7.2.5 + environment: + - REDIS_REPLICATION_MODE=slave + - REDIS_MASTER_HOST=redis_master + - ALLOW_EMPTY_PASSWORD=yes + depends_on: + - redis_master redis_sentinel: - image: camptocamp/c2cwsgiutils-redis-sentinel:6 + image: bitnami/redis-sentinel:7.2.5 environment: - - MASTER_NAME=mymaster - - QUORUM=1 - - MASTER=redis_master + - REDIS_MASTER_HOST=redis_master + - REDIS_MASTER_SET=mymaster + - ALLOW_EMPTY_PASSWORD=yes + depends_on: + - redis_master + - redis_slave tilecloudchain: - image: &tilecloudchain-image camptocamp/tilecloud-chain:1.17 + image: &tilecloudchain-image camptocamp/tilecloud-chain:1.20 user: www-data restart: unless-stopped environment: @@ -217,7 +226,7 @@ services: user: www-data restart: unless-stopped entrypoint: - - generate_tiles + - generate-tiles - --role=slave - --daemon environment: diff --git a/docker-compose-qgis.yaml b/docker-compose-qgis.yaml index af3860dd7..3a2bd3506 100644 --- a/docker-compose-qgis.yaml +++ b/docker-compose-qgis.yaml @@ -1,7 +1,5 @@ # This file is used to run QGIS client from the Docker image -version: '2' - services: qgis: extends: diff --git a/env.default b/env.default index ffcc26b5d..725092046 100644 --- a/env.default +++ b/env.default @@ -1,7 +1,7 @@ # Default values for c2cgeoportal GEOMAPFISH_VERSION=2.9 GEOMAPFISH_MAIN_VERSION=2.9 -GEOMAPFISH_MAIN_MINOR_VERSION=2.9 +GEOMAPFISH_MAIN_MINOR_VERSION=2.9.0 COMPOSE_PROJECT_NAME=geomapfish PACKAGE=geomapfish SRID=2056 diff --git a/geoportal/CONST_config-schema.yaml b/geoportal/CONST_config-schema.yaml index 4424e910e..3c3167bfd 100644 --- a/geoportal/CONST_config-schema.yaml +++ b/geoportal/CONST_config-schema.yaml @@ -409,6 +409,11 @@ mapping: model: type: str required: True + # Host allowed in the OGC server clear cache + allowed_hosts: + type: seq + sequence: + - type: str getitfixed: type: map diff --git a/geoportal/CONST_vars.yaml b/geoportal/CONST_vars.yaml index a417d7ab6..17ef37b04 100644 --- a/geoportal/CONST_vars.yaml +++ b/geoportal/CONST_vars.yaml @@ -21,13 +21,13 @@ vars: pool_recycle: '{SQLALCHEMY_POOL_RECYCLE}' pool_size: '{SQLALCHEMY_POOL_SIZE}' max_overflow: '{SQLALCHEMY_MAX_OVERFLOW}' - executemany_mode: batch + executemany_mode: values_plus_batch sqlalchemy_slave: url: postgresql://{PGUSER}:{PGPASSWORD}@{PGHOST_SLAVE}:{PGPORT_SLAVE}/{PGDATABASE}?sslmode={PGSSLMODE} pool_recycle: '{SQLALCHEMY_SLAVE_POOL_RECYCLE}' pool_size: '{SQLALCHEMY_SLAVE_POOL_SIZE}' max_overflow: '{SQLALCHEMY_SLAVE_MAX_OVERFLOW}' - executemany_mode: batch + executemany_mode: values_plus_batch # Session backend session: @@ -51,7 +51,6 @@ vars: ns: - geomapfish defaultNS: geomapfish - keySeparator: false debug: false detection: order: @@ -822,7 +821,7 @@ vars: description: > MapServer substitution of a variable in the mapfile. See the documentation here: - https://camptocamp.github.io/c2cgeoportal/2.8/administrator/mapfile.html?highlight=mapserver_substitution#variable-substitution + https://camptocamp.github.io/c2cgeoportal/2.9/administrator/mapfile.html?highlight=mapserver_substitution#variable-substitution - name: filterable_layers description: > Grant access for filtering considered layer. @@ -935,8 +934,6 @@ vars: shortener: # The base of created URL base_url: '{VISIBLE_WEB_PROTOCOL}://{VISIBLE_WEB_HOST}{VISIBLE_ENTRY_POINT}s/' - allowed_hosts: - - '{VISIBLE_WEB_HOST}' length: 4 # Define whether the MapServer proxy should hide the OGC capabilities. @@ -954,10 +951,13 @@ vars: lingua_extractor: {} content_security_policy_main_default_src_extra: '' + # Google Maps uses map.google.com and map.googleapis.com + # More info: https://developers.google.com/maps/documentation/javascript/content-security-policy?hl=fr#allowlist_csp + # Google Analytics 4 uses googletagmanager.com + # More info: https://developers.google.com/tag-platform/tag-manager/csp?hl=fr#google_analytics_4_google_analytics content_security_policy_main_script_src_extra: ' - https://maps.google.com/ - https://maps.googleapis.com/ - https://www.google-analytics.com/ + https://*.google.com/ + https://*.googleapis.com/ https://*.googletagmanager.com/' content_security_policy_main_style_src_extra: ' https://fonts.googleapis.com/' @@ -1241,8 +1241,7 @@ vars: level: 10 # What web page is authorized to use the API - authorized_referers: - - '{VISIBLE_WEB_PROTOCOL}://{VISIBLE_WEB_HOST}/' + authorized_referers: [] metrics: memory_maps_rss: False @@ -1335,6 +1334,10 @@ runtime_environment: default: '30' - name: REDIS_LOCK_TIMEOUT default: '120' # Two minutes + - name: REDIS_PASSWORD + default: '' + - name: REDIS_SSL + default: 'false' - name: REDIS_EXPIRATION_TIME default: '86400' # One day - name: TILEGENERATION_SQS_QUEUE diff --git a/geoportal/geomapfish_geoportal/static-ngeo/api/api.css b/geoportal/geomapfish_geoportal/static-ngeo/api/api.css index 9fc6d0502..ef5b2266b 100644 --- a/geoportal/geomapfish_geoportal/static-ngeo/api/api.css +++ b/geoportal/geomapfish_geoportal/static-ngeo/api/api.css @@ -85,12 +85,16 @@ .ol-rotate { top: 0.5em; right: 0.5em; - transition: opacity 0.25s linear, visibility 0s linear; + transition: + opacity 0.25s linear, + visibility 0s linear; } .ol-rotate.ol-hidden { opacity: 0; visibility: hidden; - transition: opacity 0.25s linear, visibility 0s linear 0.25s; + transition: + opacity 0.25s linear, + visibility 0s linear 0.25s; } .ol-zoom-extent { top: 4.643em; diff --git a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js index c6fa15b52..b98ff4308 100644 --- a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js +++ b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllerdesktop.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2016-2021 Camptocamp SA +// Copyright (c) 2016-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in @@ -68,7 +68,7 @@ geomapfishModule.run( ($templateCache) => { // @ts-ignore: webpack $templateCache.put('gmf/contextualdata', require('./contextualdata.html')); - } + }, ); geomapfishModule.controller('DesktopController', Controller); diff --git a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js index 5a2b3ab3e..8d7d110ef 100644 --- a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js +++ b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleriframe_api.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2015-2021 Camptocamp SA +// Copyright (c) 2015-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in diff --git a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js index 6957b4896..0a64f0427 100644 --- a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js +++ b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2015-2021 Camptocamp SA +// Copyright (c) 2015-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in diff --git a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js index c4739532f..8444ffbf0 100644 --- a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js +++ b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controllermobile_alt.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2015-2023 Camptocamp SA +// Copyright (c) 2015-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in diff --git a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js index 5eb71ac1b..c582d59a3 100644 --- a/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js +++ b/geoportal/geomapfish_geoportal/static-ngeo/js/apps/Controlleroeedit.js @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2016-2021 Camptocamp SA +// Copyright (c) 2016-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in @@ -171,14 +171,14 @@ geomapfishModule.run( ($templateCache) => { // @ts-ignore: webpack $templateCache.put('gmf/contextualdata', require('./contextualdata.html')); - } + }, ); geomapfishModule.value( 'gmfPermalinkOptions', /** @type {import('gmf/options').gmfPermalinkOptions} */ ({ pointRecenterZoom: 10, - }) + }), ); geomapfishModule.controller('OEEditController', Controller); diff --git a/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl b/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl index 2e49d9b56..557da88d0 100644 --- a/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl +++ b/geoportal/geomapfish_geoportal/static/apihelp/index.html.tmpl @@ -1,4 +1,4 @@ - + diff --git a/geoportal/geomapfish_geoportal/static/img/QGIS_logo_2017.svg b/geoportal/geomapfish_geoportal/static/img/QGIS_logo_2017.svg index 77caaf05a..83acb7c00 100644 --- a/geoportal/geomapfish_geoportal/static/img/QGIS_logo_2017.svg +++ b/geoportal/geomapfish_geoportal/static/img/QGIS_logo_2017.svg @@ -1,3 +1,3 @@ -image/svg+xml \ No newline at end of file +image/svg+xml diff --git a/geoportal/geomapfish_geoportal/static/story-map.html b/geoportal/geomapfish_geoportal/static/story-map.html index 8986a46c7..2c0f0a2df 100644 --- a/geoportal/geomapfish_geoportal/static/story-map.html +++ b/geoportal/geomapfish_geoportal/static/story-map.html @@ -1,4 +1,4 @@ - + diff --git a/geoportal/gunicorn.conf.py b/geoportal/gunicorn.conf.py index 20e9b2ef1..5a360e3bc 100644 --- a/geoportal/gunicorn.conf.py +++ b/geoportal/gunicorn.conf.py @@ -32,7 +32,10 @@ import os -from c2cwsgiutils import get_config_defaults +import gunicorn.arbiter +import gunicorn.workers.base +from c2cwsgiutils import get_config_defaults, prometheus +from prometheus_client import multiprocess bind = ":8080" @@ -100,3 +103,39 @@ } raw_paste_global_conf = ["=".join(e) for e in get_config_defaults().items()] + + +def on_starting(server: gunicorn.arbiter.Arbiter) -> None: + """ + Will start the prometheus server. + + Called just before the master process is initialized. + """ + + del server + + prometheus.start() + + +def post_fork(server: gunicorn.arbiter.Arbiter, worker: gunicorn.workers.base.Worker) -> None: + """ + Will cleanup the configuration we get from the main process. + + Called just after a worker has been forked. + """ + + del server, worker + + prometheus.cleanup() + + +def child_exit(server: gunicorn.arbiter.Arbiter, worker: gunicorn.workers.base.Worker) -> None: + """ + Remove the metrics for the exited worker. + + Called just after a worker has been exited, in the master process. + """ + + del server + + multiprocess.mark_process_dead(worker.pid) diff --git a/geoportal/vars.yaml b/geoportal/vars.yaml index 3bf92724f..7c561406f 100644 --- a/geoportal/vars.yaml +++ b/geoportal/vars.yaml @@ -883,7 +883,6 @@ update_paths: - admin_interface.functionalities - admin_interface.available_in_templates - api - - authorized_referers - cache.std.arguments - cache.ogc-server.arguments - cache.obj @@ -995,5 +994,6 @@ environment: runtime_postprocess: - expression: str({}).lower() in ("true", "yes", "1") vars: + - cache.std.arguments.port - cache.std.arguments.connection_kwargs.ssl - cache.ogc-server.arguments.connection_kwargs.ssl diff --git a/geoportal/webpack.api.js b/geoportal/webpack.api.js index 793896621..839334e4b 100644 --- a/geoportal/webpack.api.js +++ b/geoportal/webpack.api.js @@ -7,7 +7,9 @@ const babelPresets = [ [ require.resolve('@babel/preset-env'), { - targets: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10', + targets: { + browsers: ['> 0.7% in CH', '> 0.7% in FR', 'Firefox ESR'], + }, modules: false, loose: true, }, diff --git a/geoportal/webpack.apps.js b/geoportal/webpack.apps.js index e75ca7298..a8541ab90 100644 --- a/geoportal/webpack.apps.js +++ b/geoportal/webpack.apps.js @@ -21,10 +21,10 @@ for (const filename of ls(path.resolve(__dirname, 'geomapfish_geoportal/static-n chunks: [name], vars: { entry_point: '${VISIBLE_ENTRY_POINT}', - version: '2.8.1.110', + version: '2.9', cache_version: '${CACHE_VERSION}', }, - }) + }), ); } @@ -32,7 +32,9 @@ const babelPresets = [ [ require.resolve('@babel/preset-env'), { - targets: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10', + targets: { + browsers: ['defaults', '> 0.7% in CH', '> 0.9% in FR', 'Firefox ESR', 'supports es6-class'], + }, modules: false, loose: true, }, diff --git a/geoportal/webpack.commons.js b/geoportal/webpack.commons.js index 43350c086..a00e4f6d7 100644 --- a/geoportal/webpack.commons.js +++ b/geoportal/webpack.commons.js @@ -5,7 +5,6 @@ const config = commons({ DllReferencePluginOptions: { context: '/usr/lib/', }, - browsers: 'defaults, > 0.1% in CH, > 0.1% in FR, Firefox ESR and supports es6-class and not iOS < 10', }); for (const plugin of config.plugins) { diff --git a/mapserver/Aster2056.prj b/mapserver/Aster2056.prj index 55e14b154..8c6c3f860 100644 --- a/mapserver/Aster2056.prj +++ b/mapserver/Aster2056.prj @@ -1 +1 @@ -PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.43958333333333],PARAMETER["Latitude_Of_Center",46.9524055555556],UNIT["Meter",1.0]] \ No newline at end of file +PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.43958333333333],PARAMETER["Latitude_Of_Center",46.9524055555556],UNIT["Meter",1.0]] diff --git a/mapserver/SRTM2056.prj b/mapserver/SRTM2056.prj index 55e14b154..8c6c3f860 100644 --- a/mapserver/SRTM2056.prj +++ b/mapserver/SRTM2056.prj @@ -1 +1 @@ -PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.43958333333333],PARAMETER["Latitude_Of_Center",46.9524055555556],UNIT["Meter",1.0]] \ No newline at end of file +PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.43958333333333],PARAMETER["Latitude_Of_Center",46.9524055555556],UNIT["Meter",1.0]] diff --git a/mapserver/fonts.conf b/mapserver/fonts.conf index 42ba4a32f..549b99bc5 100644 --- a/mapserver/fonts.conf +++ b/mapserver/fonts.conf @@ -1,5 +1,5 @@ arial fonts/Arial.TTF -arial_bold fonts/Arialbd.TTF +arial_bold fonts/Arialbd.TTF verdana_bold fonts/Verdanab.TTF verdana_italic fonts/Verdanai.TTF verdana fonts/Verdana.TTF diff --git a/pyproject.toml b/pyproject.toml index f2514fa03..f1c321984 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 110 -target-version = ['py38'] +target-version = ['py39'] [tool.isort] profile = "black" diff --git a/qgisserver/bavaria_leisure_themes.qgs b/qgisserver/bavaria_leisure_themes.qgs index cf5229801..57cf5639c 100644 --- a/qgisserver/bavaria_leisure_themes.qgs +++ b/qgisserver/bavaria_leisure_themes.qgs @@ -4602,4 +4602,4 @@ def my_form_open(dialog, layer, feature): - \ No newline at end of file + diff --git a/qgisserver/project_no_wfs.qgs b/qgisserver/project_no_wfs.qgs index 11881b328..ed8b023c2 100644 --- a/qgisserver/project_no_wfs.qgs +++ b/qgisserver/project_no_wfs.qgs @@ -12439,4 +12439,4 @@ def my_form_open(dialog, layer, feature): - \ No newline at end of file + diff --git a/scripts/db-backup b/scripts/db-backup index faedb3ce8..f2b133b3d 100755 --- a/scripts/db-backup +++ b/scripts/db-backup @@ -89,7 +89,8 @@ def main() -> None: else: subprocess.run( [ - "docker-compose", + "docker", + "compose", "exec", "-T", "tools", diff --git a/scripts/db-restore b/scripts/db-restore index 7412cd801..5da9984ba 100755 --- a/scripts/db-restore +++ b/scripts/db-restore @@ -43,7 +43,7 @@ def main() -> None: "--docker-compose-file", action="append", default=[], - help="The docker-compose file to used.", + help="The docker compose file to used.", ) parser.add_argument( "--arg", @@ -92,8 +92,8 @@ def main() -> None: ) else: subprocess.run( - ["docker-compose"] - + ["--file={}".format(f) for f in args.docker_compose_file] + ["docker", "compose"] + + [f"--file={f}" for f in args.docker_compose_file] + [ "exec", "-T", diff --git a/webcomponents/feedback.ts b/webcomponents/feedback.ts index a86192414..a3aa23c42 100644 --- a/webcomponents/feedback.ts +++ b/webcomponents/feedback.ts @@ -32,7 +32,7 @@ export class ProjFeedback extends (window as any).gmfapi.elements.ToolPanelEleme this.url_ = new URL(configuration.sitnFeedbackPath, configuration.gmfBase).href; } }, - }) + }), ); window.addEventListener('popstate', () => { this.permalink = window.location.href; @@ -143,7 +143,7 @@ export class ProjFeedback extends (window as any).gmfapi.elements.ToolPanelEleme 'Merci! Votre demande est bien partie.', '', 'Suivant votre demande, une personne prendra bientôt contact avec vous.', - ].join('\n') + ].join('\n'), ); (window as any).gmfapi.store.panels.closeToolPanel(); }) diff --git a/webcomponents/index.html b/webcomponents/index.html index a388f54d8..fa5aa6ce4 100644 --- a/webcomponents/index.html +++ b/webcomponents/index.html @@ -1,4 +1,4 @@ - + From 2ea3e44e7bbb81fedff07d222177d7723956f298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 13:31:35 +0200 Subject: [PATCH 02/10] Update the used QGIS version --- env.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env.default b/env.default index 725092046..9cecc54a0 100644 --- a/env.default +++ b/env.default @@ -46,7 +46,7 @@ TILECLOUDCHAIN_INTERNAL_PORT=8080 MAPSERVER_URL=http://mapserver:8080/ TINYOWS_URL=http://tinyows:8080/ QGISSERVER_URL=http://qgisserver:8080/mapserv_proxy -QGIS_VERSION=3.28-gdal3.7 +QGIS_VERSION=3.34-gdal3.8 POSTGRES_TAG=13-postgis-3 DEVSERVER_HOST=webpack_dev_server:8080 From d60faac1ee100b640f2d8d0ba79db4398e51714a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 13:35:19 +0200 Subject: [PATCH 03/10] Fix build --- geoportal/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geoportal/Dockerfile b/geoportal/Dockerfile index 070094c14..6c9a6dec3 100644 --- a/geoportal/Dockerfile +++ b/geoportal/Dockerfile @@ -44,7 +44,7 @@ RUN chmod go+w /etc/static-ngeo/ RUN --mount=type=cache,target=/root/.cache \ python3 -m pip install --disable-pip-version-check --editable=/app/ \ && python3 -m compileall -q /usr/local/lib/python3.* \ - -x '/(ptvsd|.*pydev.*|networkx)/' \ + -x '/(ptvsd|.*pydev.*|networkx|scaffolds|yaml_include)/' \ && python3 -m compileall -q /app/geomapfish_geoportal -x /app/geomapfish_geoportal/static.* ARG GIT_HASH From ea9c7805cfffb494443a9a0fc8aae76781bbd041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 13:59:43 +0200 Subject: [PATCH 04/10] Disable getitfixed --- geoportal/vars.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geoportal/vars.yaml b/geoportal/vars.yaml index 7c561406f..eb98c1a97 100644 --- a/geoportal/vars.yaml +++ b/geoportal/vars.yaml @@ -541,7 +541,7 @@ vars: description: 'List of location, no more used?' getitfixed: - enabled: True + enabled: False map: *map_config admin_new_issue_email: From 72070846125f81a931eb196418990531a2268e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 14:06:06 +0200 Subject: [PATCH 05/10] Remove deprecated version --- docker-compose-db.yaml | 2 -- docker-compose.override.sample.yaml | 2 -- docker-compose.yaml | 2 -- 3 files changed, 6 deletions(-) diff --git a/docker-compose-db.yaml b/docker-compose-db.yaml index 33a491a16..18ce1c731 100644 --- a/docker-compose-db.yaml +++ b/docker-compose-db.yaml @@ -1,7 +1,5 @@ # This file is used by the acceptance tests to have a local database. -version: '2.3' - volumes: postgresql_data: diff --git a/docker-compose.override.sample.yaml b/docker-compose.override.sample.yaml index ad9379fbf..56a2a27a9 100644 --- a/docker-compose.override.sample.yaml +++ b/docker-compose.override.sample.yaml @@ -1,8 +1,6 @@ # This file can be renamed as `docker-compose.override.yaml` and uncomment the desired lines for # development. The file `docker-compose.override.yaml` is ignored by Git by default. -version: '2.3' - services: # config: # volumes: diff --git a/docker-compose.yaml b/docker-compose.yaml index 41cd6deef..b41e2010a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,7 +1,5 @@ # The project Docker compose file. -version: '2.3' - volumes: postgresql_data: From ec376a03540d0752bd25eab841ca5a33db54e3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 16:16:47 +0200 Subject: [PATCH 06/10] Fix Redis port --- geoportal/vars.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/geoportal/vars.yaml b/geoportal/vars.yaml index eb98c1a97..3345e1282 100644 --- a/geoportal/vars.yaml +++ b/geoportal/vars.yaml @@ -992,8 +992,10 @@ environment: - name: VERSION runtime_postprocess: - - expression: str({}).lower() in ("true", "yes", "1") + - expression: int({}) vars: - cache.std.arguments.port + - expression: str({}).lower() in ("true", "yes", "1") + vars: - cache.std.arguments.connection_kwargs.ssl - cache.ogc-server.arguments.connection_kwargs.ssl From bb5888da94ed633326e4b69096fb0bbe979013d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 16:55:30 +0200 Subject: [PATCH 07/10] Add sleep in acceptance-dev --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 15937bbb9..ce337861a 100644 --- a/Makefile +++ b/Makefile @@ -80,5 +80,6 @@ acceptance: ## Run the acceptance tests .PHONY: acceptance-dev acceptance-dev: docker compose --file=docker-compose.yaml --file=docker-compose-db.yaml --file=docker-compose.override.sample.yaml up -d + sleep 2 docker compose exec -T tools pytest tests/ ci/docker-compose-check From aefbee388a4f69f87e09947c3312d0745dc9a4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 17:17:31 +0200 Subject: [PATCH 08/10] Automatically update from base branch --- .github/workflows/uptodate.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/uptodate.yaml b/.github/workflows/uptodate.yaml index 6f4af24dd..8c7d8ed01 100644 --- a/.github/workflows/uptodate.yaml +++ b/.github/workflows/uptodate.yaml @@ -9,7 +9,7 @@ on: pull_request: env: - REF_BRANCH: prod-2-8 + REF_BRANCH: prod-2-9 jobs: main: @@ -29,5 +29,13 @@ jobs: - run: ci/cleanup ../ref - run: rm ci/cleanup - - run: diff --recursive --new-file ../ref . + - run: cd ..; diff --unified --recursive --new-file demo_geomapfish ref if: always() + - run: cd ..; diff --unified --recursive --new-file demo_geomapfish ref > /tmp/base.patch || true + if: failure() + - uses: actions/upload-artifact@v4 + with: + name: Update from base branch.patch + path: /tmp/base.patch + retention-days: 1 + if: failure() From a63e27e7e9bea0e58ff50d9fcbc887447118b6f8 Mon Sep 17 00:00:00 2001 From: "geo-ghci-int[bot]" <146321879+geo-ghci-int[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:45:32 +0000 Subject: [PATCH 09/10] Update from base branch From the artifact of the previous workflow run --- custom/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/Dockerfile b/custom/Dockerfile index 670a40d95..098f69fa8 100644 --- a/custom/Dockerfile +++ b/custom/Dockerfile @@ -1,4 +1,4 @@ -FROM osgeo/gdal:ubuntu-small-3.6.3 AS base-all +FROM ghcr.io/osgeo/gdal:ubuntu-small-3.6.2 AS base-all # Fail on error on pipe, see: https://github.com/hadolint/hadolint/wiki/DL4006. # Treat unset variables as an error when substituting. From 367d6506a3fad263f2958942b0fc017a69f9dc39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 26 Jun 2024 20:32:02 +0200 Subject: [PATCH 10/10] Don't run app diff on Renovate --- .github/workflows/uptodate.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/uptodate.yaml b/.github/workflows/uptodate.yaml index 8c7d8ed01..55ef4452d 100644 --- a/.github/workflows/uptodate.yaml +++ b/.github/workflows/uptodate.yaml @@ -16,6 +16,7 @@ jobs: runs-on: ubuntu-22.04 name: Compare simple and advance branch timeout-minutes: 10 + if: github.actor != 'renovate[bot]' steps: - uses: actions/checkout@v4