├── .dockerignore
├── .env
├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── 10_bug_report.yml
│ ├── 15_feature_request.yml
│ └── config.yml
├── dependabot.yml
└── workflows
│ ├── build-latest.yaml
│ └── deploy-image.yaml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── build_data
├── broker.xml
├── cluster.properties
├── community_plugins.py
├── community_plugins.txt
├── context.xml
├── controlflow.properties
├── embedded-broker.properties
├── extensions.sh
├── geowebcache-diskquota-jdbc.xml
├── geowebcache-diskquota.xml
├── google_fonts.txt
├── gwc-gs.xml
├── hazelcast_cluster
│ ├── cluster.properties
│ ├── hazelcast.xml
│ └── web.xml
├── index.jsp
├── jdbcconfig
│ ├── jdbcconfig.properties
│ └── scripts
│ │ ├── dropdb.h2.sql
│ │ ├── dropdb.mssql.sql
│ │ ├── dropdb.mysql.sql
│ │ ├── dropdb.oracle.sql
│ │ ├── dropdb.postgres.sql
│ │ ├── initdb.h2.sql
│ │ ├── initdb.mssql.sql
│ │ ├── initdb.mysql.sql
│ │ ├── initdb.oracle.sql
│ │ └── initdb.postgres.sql
├── jdbcstore
│ ├── jdbcstore.properties
│ └── scripts
│ │ ├── drop.h2.sql
│ │ ├── drop.postgres.sql
│ │ ├── init.h2.sql
│ │ └── init.postgres.sql
├── jdom2-2.0.6.1.jar
├── letsencrypt-tomcat.xsl
├── log4j.properties
├── logging.properties
├── plugin_download.sh
├── required_plugins.txt
├── stable_plugins.py
├── stable_plugins.txt
├── tomcat-users.xml
└── web.xml
├── clustering
├── README.md
├── activemq-docker
│ ├── Dockerfile
│ ├── activemq.xml
│ └── setup-jars.sh
├── docker-compose-external.yml
└── docker-compose.yml
├── docker-compose-build.yml
├── docker-compose-nginx.yml
├── docker-compose.yml
├── docs
├── 404.html
├── Environment-Variables
│ └── index.html
├── Getting-the-image
│ └── index.html
├── Kubernetes
│ └── index.html
├── Mounting-Configs
│ └── index.html
├── Running-the-Image
│ └── index.html
├── Support-and-credits
│ └── index.html
├── assets
│ ├── images
│ │ └── favicon.png
│ ├── javascripts
│ │ ├── bundle.a00a7c5e.min.js
│ │ ├── bundle.a00a7c5e.min.js.map
│ │ ├── lunr
│ │ │ ├── min
│ │ │ │ ├── lunr.ar.min.js
│ │ │ │ ├── lunr.da.min.js
│ │ │ │ ├── lunr.de.min.js
│ │ │ │ ├── lunr.du.min.js
│ │ │ │ ├── lunr.es.min.js
│ │ │ │ ├── lunr.fi.min.js
│ │ │ │ ├── lunr.fr.min.js
│ │ │ │ ├── lunr.hi.min.js
│ │ │ │ ├── lunr.hu.min.js
│ │ │ │ ├── lunr.it.min.js
│ │ │ │ ├── lunr.ja.min.js
│ │ │ │ ├── lunr.jp.min.js
│ │ │ │ ├── lunr.ko.min.js
│ │ │ │ ├── lunr.multi.min.js
│ │ │ │ ├── lunr.nl.min.js
│ │ │ │ ├── lunr.no.min.js
│ │ │ │ ├── lunr.pt.min.js
│ │ │ │ ├── lunr.ro.min.js
│ │ │ │ ├── lunr.ru.min.js
│ │ │ │ ├── lunr.stemmer.support.min.js
│ │ │ │ ├── lunr.sv.min.js
│ │ │ │ ├── lunr.ta.min.js
│ │ │ │ ├── lunr.th.min.js
│ │ │ │ ├── lunr.tr.min.js
│ │ │ │ ├── lunr.vi.min.js
│ │ │ │ └── lunr.zh.min.js
│ │ │ ├── tinyseg.js
│ │ │ └── wordcut.js
│ │ └── workers
│ │ │ ├── search.db81ec45.min.js
│ │ │ └── search.db81ec45.min.js.map
│ └── stylesheets
│ │ ├── main.0d440cfe.min.css
│ │ ├── main.0d440cfe.min.css.map
│ │ ├── palette.2505c338.min.css
│ │ └── palette.2505c338.min.css.map
├── index.html
├── search
│ └── search_index.json
├── sitemap.xml
└── sitemap.xml.gz
├── resources
├── README.txt
└── overlays
│ └── README.txt
├── scenario_tests
├── .gitignore
├── README.md
├── backup_restore
│ ├── docker-compose.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ ├── test_geoserver_backup.py
│ │ └── test_geoserver_restore.py
├── clustering
│ ├── docker-compose-external.yml
│ ├── docker-compose.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── init.sql
│ │ ├── test.sh
│ │ ├── test_clustering_master.py
│ │ └── test_clustering_node.py
├── context
│ ├── docker-compose.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ └── test_context.py
├── disk-quota
│ ├── docker-compose.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ └── test_disk_quota.py
├── gwc
│ ├── docker-compose-gwc.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ └── test_gwc.py
├── jdbconfig
│ ├── docker-compose-postgis-jndi.yml
│ ├── docker-compose.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ └── test_jdbconfig.py
├── libjpeg
│ ├── docker-compose.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ └── test_libjpeg.py
├── logging_profile
│ ├── assets
│ │ └── logging.xml
│ ├── docker-compose.yml
│ ├── test.sh
│ ├── tests
│ │ └── test.sh
│ └── version.xml
├── login
│ ├── docker-compose.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ └── test_login.py
├── stores
│ ├── docker-compose-gdal.yml
│ ├── docker-compose-postgis-jndi.yml
│ ├── test.sh
│ └── tests
│ │ ├── __init__.py
│ │ ├── test.sh
│ │ ├── test_gdal.py
│ │ └── test_jndi.py
├── test-env.sh
└── utils
│ └── requirements.txt
├── scripts
├── entrypoint.sh
├── env-data.sh
├── functions.sh
├── setup.sh
├── start.sh
└── update_passwords.sh
├── sites-enabled
└── nginx.conf
└── upgrade_geoserver_version.sh
/.dockerignore:
--------------------------------------------------------------------------------
1 | docker-env/*
2 | Dockerfile
3 | .git*
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.sh text eol=lf
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [kartoza]
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/10_bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Bug/Crash report
2 | description: Create a bug report to help us improve docker-geoserver.
3 | labels:
4 | - 'Bug'
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Thanks for taking the time to fill out this bug report correctly.
10 |
11 | Please report only issues related to the docker-geoserver.
12 |
13 | If the issue is related to an extension, you should file the issue in the [GeoServer jira](https://osgeo-org.atlassian.net/projects/GEOS/summary).
14 |
15 |
16 | - type: textarea
17 | id: what
18 | attributes:
19 | label: What is the bug or the crash?
20 | validations:
21 | required: true
22 |
23 | - type: textarea
24 | id: steps
25 | attributes:
26 | label: Steps to reproduce the issue
27 | description: |
28 | Steps, sample docker-compose to reproduce the behavior. Screencasts or screenshots are more than welcome, you can drag&drop them in the text box.
29 | 1. Go to '...'
30 | 2. Click on '...'
31 | 3. Scroll down to '...'
32 | 4. See error
33 | validations:
34 | required: true
35 |
36 | - type: textarea
37 | id: about-info
38 | attributes:
39 | label: Versions
40 | description: |
41 | Check the version of GeoServer in the UI or docker-compose. Finally paste here.
42 | Do not make a screenshot.
43 | validations:
44 | required: true
45 |
46 |
47 | - type: textarea
48 | id: additional-context
49 | attributes:
50 | label: Additional context
51 | description: |
52 | Add any other context about the problem here.
53 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/15_feature_request.yml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | description: Suggest a feature idea for docker-geoserver.
3 | labels:
4 | - 'Feature Request'
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Thanks for taking the time to fill out this feature request correctly.
10 |
11 | - type: textarea
12 | id: what
13 | attributes:
14 | label: Feature description
15 | description: A clear and concise description of what you want to happen. Ex. docker-geoserver would rock even more if [...]
16 | validations:
17 | required: true
18 |
19 | - type: textarea
20 | id: Additional
21 | attributes:
22 | label: Additional context
23 | description: |
24 | Add any other context or screenshots about the feature request here. Open source is community driven, please consider a way to support this work either by getting a support contract, find someone to submit a pull request.
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
3 | contact_links:
4 |
5 | - name: Question
6 | url: https://gis.stackexchange.com/
7 | about: >
8 | Questions should go to the geoserver-user mailing list at https://sourceforge.net/projects/geoserver/lists/geoserver-users
9 | or other support forums such as https://gis.stackexchange.com/.
10 | GitHub issues are for bug reports and suggestions for new features.
11 |
12 | - name: GeoServer extensions issue
13 | # There must be a link to make this option valid for GitHub
14 | url: https://docs.geoserver.org/stable/en/user/extensions/index.html
15 | about: >
16 | If the issue concerns an community extension / stable extension then it can't be fixed
17 | by this docker orchestration. Please raise your issue in the dedicated bug tracker for that specific extension.
18 | Issues related to how the extensions are packaged will not be resolved here.
19 |
20 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | resources/*
2 | !resources/plugins/
3 | resources/plugins/*
4 | !resources/plugins/README.txt
5 | !resources/overlays/
6 | resources/overlays/*
7 | !resources/overlays/README.txt
8 | .idea
9 | btsync-media.env
10 | btsync-db.env
11 | geoserver-data
12 | scenario_tests/clustering/tests/__pycache__*
13 | scenario_tests/context/tests/__pycache__*
14 | scenario_tests/disk-quota/tests/__pycache__*
15 | scenario_tests/gwc/tests/__pycache__*
16 | scenario_tests/login/tests/__pycache__*
17 | scenario_tests/stores/tests/__pycache__*
18 | scenario_tests/libjpeg/tests/__pycache__*
19 | .DS_Store
20 |
--------------------------------------------------------------------------------
/build_data/broker.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
14 |
15 |
16 |
19 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/build_data/cluster.properties:
--------------------------------------------------------------------------------
1 | CLUSTER_CONFIG_DIR=${CLUSTER_CONFIG_DIR}
2 | instanceName=${INSTANCE_STRING}
3 | readOnly=${READONLY}
4 | durable=${CLUSTER_DURABILITY}
5 | brokerURL=failover:(${BROKER_URL})
6 | embeddedBroker=${EMBEDDED_BROKER}
7 | connection.retry=${CLUSTER_CONNECTION_RETRY_COUNT}
8 | toggleMaster=${TOGGLE_MASTER}
9 | xbeanURL=./broker.xml
10 | embeddedBrokerProperties=embedded-broker.properties
11 | topicName=VirtualTopic.geoserver
12 | connection=enabled
13 | toggleSlave=${TOGGLE_SLAVE}
14 | connection.maxwait=${CLUSTER_CONNECTION_MAX_WAIT}
15 | group=geoserver-cluster
16 |
--------------------------------------------------------------------------------
/build_data/community_plugins.py:
--------------------------------------------------------------------------------
1 | # Usage python3 community_plugins.py 2.23.x
2 | import requests
3 | from bs4 import BeautifulSoup
4 | import argparse
5 |
6 | parser = argparse.ArgumentParser()
7 | parser.add_argument("version", help="GeoServer version number, e.g. 2.23.x")
8 | args = parser.parse_args()
9 |
10 | url = "https://build.geoserver.org/geoserver/%s/community-latest/" % args.version
11 |
12 |
13 | response = requests.get(url)
14 | soup = BeautifulSoup(response.content, "html.parser")
15 |
16 | plugin_list = []
17 | for link in soup.find_all("a"):
18 | href = link.get("href")
19 | if href and href.endswith(".zip"):
20 | plugin_list.append(href.split("/")[-1])
21 |
22 | with open('community_plugins.txt', 'w') as f:
23 | for plugin in plugin_list:
24 | _version = args.version.replace(".x", "")
25 | sub_string = "geoserver-%s-SNAPSHOT-" % _version
26 | plugin_file = plugin.replace("%s" % sub_string, "")
27 | plugin_name = plugin_file.replace(".zip", "")
28 | f.write(plugin_name + '\n')
29 |
--------------------------------------------------------------------------------
/build_data/community_plugins.txt:
--------------------------------------------------------------------------------
1 | activeMQ-broker-plugin
2 | backup-restore-plugin
3 | cog-azure-plugin
4 | cog-google-plugin
5 | cog-http-plugin
6 | cog-s3-plugin
7 | colormap-plugin
8 | cov-json-plugin
9 | datadir-catalog-loader-plugin
10 | dds-plugin
11 | dyndimension-plugin
12 | elasticsearch-plugin
13 | features-autopopulate-plugin
14 | features-templating-plugin
15 | flatgeobuf-plugin
16 | gdal-wcs-plugin
17 | gdal-wps-plugin
18 | geopkg-plugin
19 | gpx-plugin
20 | graticule-plugin
21 | gsr-plugin
22 | gwc-azure-blobstore-plugin
23 | gwc-distributed-plugin
24 | gwc-mbtiles-plugin
25 | gwc-sqlite-plugin
26 | hz-cluster-plugin
27 | imagemap-plugin
28 | importer-jdbc-plugin
29 | jdbcconfig-plugin
30 | jdbc-metrics-plugin
31 | jdbcstore-plugin
32 | jms-cluster-plugin
33 | jwt-headers-plugin
34 | libdeflate-plugin
35 | mbtiles-plugin
36 | mbtiles-store-plugin
37 | mongodb-schemaless-plugin
38 | monitor-kafka-plugin
39 | ncwms-plugin
40 | netcdf-ghrsst-plugin
41 | notification-plugin
42 | ogcapi-coverages-plugin
43 | ogcapi-dggs-plugin
44 | ogcapi-features-plugin
45 | ogcapi-images-plugin
46 | ogcapi-maps-plugin
47 | ogcapi-styles-plugin
48 | ogcapi-tiled-features-plugin
49 | ogcapi-tiles-plugin
50 | ogr-datastore-plugin
51 | opensearch-eo-plugin
52 | pgraster-plugin
53 | proxy-base-ext-plugin
54 | s3-geotiff-plugin
55 | sec-keycloak-plugin
56 | sec-oauth2-geonode-plugin
57 | sec-oauth2-github-plugin
58 | sec-oauth2-google-plugin
59 | sec-oauth2-openid-connect-plugin
60 | smart-data-loader-plugin
61 | solr-plugin
62 | spatialjson-plugin
63 | stac-datastore-plugin
64 | taskmanager-core-plugin
65 | taskmanager-s3-plugin
66 | vector-mosaic-plugin
67 | vsi-plugin
68 | webp-plugin
69 | wfs-freemarker-plugin
70 | wps-longitudinal-profile-plugin
71 | wps-remote-plugin
72 | xslt-plugin
--------------------------------------------------------------------------------
/build_data/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
36 |
38 |
39 |
--------------------------------------------------------------------------------
/build_data/controlflow.properties:
--------------------------------------------------------------------------------
1 | timeout=${REQUEST_TIMEOUT}
2 | ows.global=${PARALLEL_REQUEST}
3 | ows.wms.getmap=${GETMAP}
4 | ows.wfs.getfeature.application/msexcel=${REQUEST_EXCEL}
5 | user=${SINGLE_USER}
6 | ows.gwc=${GWC_REQUEST}
7 | user.ows.wps.execute=${WPS_REQUEST}
8 | user.ows.wms.getmap=${USER_WMS_REQUEST}
9 | ip=${THROTTLE_REQUEST_PER_IP}
10 | #ip.blacklist=,,...
--------------------------------------------------------------------------------
/build_data/embedded-broker.properties:
--------------------------------------------------------------------------------
1 | activemq.jmx.useJmx=false
2 | activemq.jmx.port=1098
3 | activemq.jmx.host=localhost
4 | activemq.jmx.createConnector=false
5 | activemq.transportConnectors.server.uri=${BROKER_URL}?maximumConnections=1000&wireFormat.maxFrameSize=104857600&jms.useAsyncSend=true&transport.daemon=true&trace=true
6 | activemq.transportConnectors.server.discoveryURI=multicast://default
7 | activemq.broker.persistent=true
8 | activemq.base=./
9 | activemq.broker.systemUsage.memoryUsage=128 mb
10 | activemq.broker.systemUsage.storeUsage=1 gb
11 | activemq.broker.systemUsage.tempUsage=128 mb
12 |
--------------------------------------------------------------------------------
/build_data/extensions.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -eux
3 |
4 |
5 | VERSION=$(cat /tmp/pass.txt)
6 | GS_VERSION_LATEST="${VERSION:0:5}"x
7 |
8 | cd /work/
9 |
10 | python3 stable_plugins.py ${VERSION} https://sourceforge.net/projects/geoserver/files/GeoServer
11 |
12 | python3 community_plugins.py ${GS_VERSION_LATEST}
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/build_data/geowebcache-diskquota-jdbc.xml:
--------------------------------------------------------------------------------
1 |
2 | PostgreSQL
3 |
4 | org.postgresql.Driver
5 | jdbc:postgresql://${HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?${SSL_PARAMETERS}¤tSchema=${POSTGRES_SCHEMA}
6 | ${POSTGRES_USER}
7 | ${POSTGRES_PASS}
8 | 1
9 | 100
10 | 10000
11 | 50
12 |
13 |
--------------------------------------------------------------------------------
/build_data/geowebcache-diskquota.xml:
--------------------------------------------------------------------------------
1 |
2 | true
3 | ${DISK_QUOTA_FREQUENCY}
4 | SECONDS
5 | 2
6 | LFU
7 |
8 | ${DISK_QUOTA_SIZE}
9 | GiB
10 |
11 | ${DISK_QUOTA_BACKEND}
12 |
--------------------------------------------------------------------------------
/build_data/gwc-gs.xml:
--------------------------------------------------------------------------------
1 |
2 | 1.1.0
3 | ${WMS_DIR_INTEGRATION}
4 | ${REQUIRE_TILED_PARAMETER}
5 | ${WMSC_ENABLED}
6 | ${TMS_ENABLED}
7 | ${SECURITY_ENABLED}
8 | false
9 | true
10 | class org.geowebcache.storage.blobstore.memory.guava.GuavaCacheProvider
11 |
12 |
13 | class org.geowebcache.storage.blobstore.memory.guava.GuavaCacheProvider
14 |
15 | 16
16 | NULL
17 | 4
18 | 120
19 |
20 |
21 |
22 | true
23 | true
24 | 4
25 | 4
26 | 0
27 |
28 | WebMercatorQuad
29 | EPSG:4326
30 | WebMercatorQuadx2
31 | EPSG:900913
32 |
33 |
34 | image/png
35 | image/jpeg
36 |
37 |
38 | application/vnd.mapbox-vector-tile
39 | image/png
40 | image/jpeg
41 |
42 |
43 | application/vnd.mapbox-vector-tile
44 | image/png
45 | image/jpeg
46 |
47 |
--------------------------------------------------------------------------------
/build_data/hazelcast_cluster/cluster.properties:
--------------------------------------------------------------------------------
1 | enabled = true
2 | sync_method = event
3 | sync_delay = 5
4 | session_sharing = true
5 | session_sticky = false
6 | acktimeout = 2000
7 | #Disabling the hazelcast shutdown hook
8 | shutdown_hook_enable = false
9 | #Setting the hazelcast logging type to log4j
10 | logging_type = "log4j"
11 | logger.com-hazelcast.name = com.hazelcast
12 | logger.com-hazelcast.level = INFO
--------------------------------------------------------------------------------
/build_data/index.jsp:
--------------------------------------------------------------------------------
1 | <%
2 | final String redirectURL = "/geoserver/web/";
3 | response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
4 | response.setHeader("Location", redirectURL);
5 | %>
6 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/jdbcconfig.properties:
--------------------------------------------------------------------------------
1 | #Default GeoServer JDBC loader driver and connection pool options. Edit as appropriate.
2 | #Mon Feb 05 14:49:17 GMT 2024
3 | initdb=true
4 | pool.timeBetweenEvictionRunsMillis=-1L
5 | import=true
6 | pool.poolPreparedStatements=true
7 | pool.testWhileIdle=false
8 | pool.validationQuery=SELECT now()
9 | pool.minIdle=4
10 | enabled=${JDBC_CONFIG_ENABLED}
11 | pool.maxOpenPreparedStatements=50
12 | password=${POSTGRES_PASS}
13 | jdbcUrl=jdbc:postgresql://${HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?${SSL_PARAMETERS}
14 | driverClassName=org.postgresql.Driver
15 | pool.maxActive=10
16 | initScript=${GEOSERVER_DATA_DIR}/jdbcconfig/scripts/initdb.postgres.sql
17 | debugMode=false
18 | pool.testOnBorrow=true
19 | username=${POSTGRES_USER}
20 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/scripts/dropdb.h2.sql:
--------------------------------------------------------------------------------
1 | DROP VIEW IF EXISTS service;
2 | DROP VIEW IF EXISTS settings;
3 | DROP VIEW IF EXISTS global;
4 | DROP VIEW IF EXISTS layergroup_style;
5 | DROP VIEW IF EXISTS layergroup_layer;
6 | DROP VIEW IF EXISTS layergroup;
7 | DROP VIEW IF EXISTS layer_style;
8 | DROP VIEW IF EXISTS layer;
9 | DROP VIEW IF EXISTS style;
10 | DROP VIEW IF EXISTS wmslayer;
11 | DROP VIEW IF EXISTS wmsstore;
12 | DROP VIEW IF EXISTS wmtslayer;
13 | DROP VIEW IF EXISTS wmtsstore;
14 | DROP VIEW IF EXISTS coverage;
15 | DROP VIEW IF EXISTS coveragestore;
16 | DROP VIEW IF EXISTS featuretype;
17 | DROP VIEW IF EXISTS datastore;
18 | DROP VIEW IF EXISTS workspace;
19 |
20 | ? ALTER TABLE object_property DROP CONSTRAINT fk_object_property;
21 | ? ALTER TABLE property_type DROP CONSTRAINT fk_type_property_type;
22 | ? ALTER TABLE object DROP CONSTRAINT fk_object_type;
23 | ? ALTER TABLE property_type DROP CONSTRAINT fk_property_type_target_property;
24 | ? ALTER TABLE object_property DROP CONSTRAINT fk_object_property_property_type;
25 |
26 | DROP TABLE object IF EXISTS;
27 | DROP TABLE object_property IF EXISTS;
28 | DROP TABLE type IF EXISTS;
29 | DROP TABLE property_type IF EXISTS;
30 | DROP TABLE default_object IF EXISTS;
31 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/scripts/dropdb.mssql.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE OBJECT_PROPERTY DROP CONSTRAINT FK_OBJECT_PROPERTY;
2 | ALTER TABLE PROPERTY_TYPE DROP CONSTRAINT FK_TYPE_PROPERTY_TYPE;
3 | ALTER TABLE OBJECT DROP CONSTRAINT FK_OBJECT_TYPE;
4 | ALTER TABLE PROPERTY_TYPE DROP CONSTRAINT FK_PROPERTY_TYPE_TARGET_PROPERTY;
5 | ALTER TABLE OBJECT_PROPERTY DROP CONSTRAINT FK_OBJECT_PROPERTY_PROPERTY_TYPE;
6 | DROP TABLE OBJECT;
7 | DROP TABLE OBJECT_PROPERTY;
8 | DROP TABLE TYPE;
9 | DROP TABLE PROPERTY_TYPE;
10 | DROP TABLE DEFAULT_OBJECT;
11 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/scripts/dropdb.mysql.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE OBJECT_PROPERTY DROP FOREIGN KEY FK_OBJECT_PROPERTY;
2 | ALTER TABLE PROPERTY_TYPE DROP FOREIGN KEY FK_TYPE_PROPERTY_TYPE;
3 | ALTER TABLE OBJECT DROP FOREIGN KEY FK_OBJECT_TYPE;
4 | ALTER TABLE PROPERTY_TYPE DROP FOREIGN KEY FK_PROPERTY_TYPE_TARGET_PROPERTY;
5 | ALTER TABLE OBJECT_PROPERTY DROP FOREIGN KEY FK_OBJECT_PROPERTY_PROPERTY_TYPE;
6 | DROP TABLE IF EXISTS OBJECT;
7 | DROP TABLE IF EXISTS OBJECT_PROPERTY;
8 | DROP TABLE IF EXISTS TYPE;
9 | DROP TABLE IF EXISTS PROPERTY_TYPE;
10 | DROP TABLE IF EXISTS DEFAULT_OBJECT;
11 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/scripts/dropdb.oracle.sql:
--------------------------------------------------------------------------------
1 | DROP VIEW service;
2 | DROP VIEW settings;
3 | DROP VIEW global;
4 | DROP VIEW layergroup_style;
5 | DROP VIEW layergroup_layer;
6 | DROP VIEW layergroup;
7 | DROP VIEW layer_style;
8 | DROP VIEW layer;
9 | DROP VIEW style;
10 | DROP VIEW wmslayer;
11 | DROP VIEW wmsstore;
12 | DROP VIEW coverage;
13 | DROP VIEW coveragestore;
14 | DROP VIEW featuretype;
15 | DROP VIEW datastore;
16 | DROP VIEW workspace;
17 |
18 | DROP TABLE OBJECT CASCADE CONSTRAINTS;
19 | DROP TABLE OBJECT_PROPERTY CASCADE CONSTRAINTS;
20 | DROP TABLE TYPE CASCADE CONSTRAINTS;
21 | DROP TABLE PROPERTY_TYPE CASCADE CONSTRAINTS;
22 | DROP TABLE DEFAULT_OBJECT CASCADE CONSTRAINTS;
23 | DROP SEQUENCE SEQ_OBJECT;
24 | DROP SEQUENCE SEQ_TYPE;
25 | DROP SEQUENCE SEQ_PROPERTY_TYPE;
26 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/scripts/dropdb.postgres.sql:
--------------------------------------------------------------------------------
1 | DROP VIEW IF EXISTS service;
2 | DROP VIEW IF EXISTS settings;
3 | DROP VIEW IF EXISTS global;
4 | DROP VIEW IF EXISTS layergroup_style;
5 | DROP VIEW IF EXISTS layergroup_layer;
6 | DROP VIEW IF EXISTS layergroup;
7 | DROP VIEW IF EXISTS layer_style;
8 | DROP VIEW IF EXISTS layer;
9 | DROP VIEW IF EXISTS style;
10 | DROP VIEW IF EXISTS wmslayer;
11 | DROP VIEW IF EXISTS wmsstore;
12 | DROP VIEW IF EXISTS wmtslayer;
13 | DROP VIEW IF EXISTS wmtsstore;
14 | DROP VIEW IF EXISTS coverage;
15 | DROP VIEW IF EXISTS coveragestore;
16 | DROP VIEW IF EXISTS featuretype;
17 | DROP VIEW IF EXISTS datastore;
18 | DROP VIEW IF EXISTS workspace;
19 |
20 | ? ALTER TABLE object_property DROP CONSTRAINT fk_object_property;
21 | ? ALTER TABLE property_type DROP CONSTRAINT fk_type_property_type;
22 | ? ALTER TABLE object DROP CONSTRAINT fk_object_type;
23 | ? ALTER TABLE property_type DROP CONSTRAINT fk_property_type_target_property;
24 | ? ALTER TABLE object_property DROP CONSTRAINT fk_object_property_property_type;
25 |
26 | DROP TABLE IF EXISTS object CASCADE;
27 | DROP TABLE IF EXISTS object_property CASCADE;
28 | DROP TABLE IF EXISTS type CASCADE;
29 | DROP TABLE IF EXISTS property_type CASCADE;
30 | DROP TABLE IF EXISTS default_object CASCADE;
31 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/scripts/initdb.mssql.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE OBJECT (OID int IDENTITY NOT NULL, TYPE_ID int NOT NULL, ID varchar(255) NOT NULL, BLOB text NOT NULL, PRIMARY KEY (OID));
2 | CREATE TABLE OBJECT_PROPERTY (OID int NOT NULL, PROPERTY_TYPE int NOT NULL, ID varchar(255) NOT NULL, RELATED_OID int NULL, RELATED_PROPERTY_TYPE int NULL, COLINDEX int NOT NULL, VALUE varchar(max) NULL, PRIMARY KEY (OID, PROPERTY_TYPE, COLINDEX));
3 | CREATE TABLE TYPE (OID int IDENTITY NOT NULL, TYPENAME varchar(255) NOT NULL, PRIMARY KEY (OID));
4 | CREATE TABLE PROPERTY_TYPE (OID int IDENTITY NOT NULL, TARGET_PROPERTY int NULL, TYPE_ID int NOT NULL, NAME varchar(255) NOT NULL, COLLECTION bit NOT NULL, TEXT bit NOT NULL, PRIMARY KEY (OID));
5 | CREATE TABLE DEFAULT_OBJECT (DEF_KEY varchar(255) NOT NULL, ID varchar(255) NOT NULL);
6 | ALTER TABLE OBJECT_PROPERTY ADD CONSTRAINT FK_OBJECT_PROPERTY FOREIGN KEY (OID) REFERENCES OBJECT (OID) ON DELETE Cascade;
7 | ALTER TABLE PROPERTY_TYPE ADD CONSTRAINT FK_TYPE_PROPERTY_TYPE FOREIGN KEY (TYPE_ID) REFERENCES TYPE (OID);
8 | ALTER TABLE OBJECT ADD CONSTRAINT FK_OBJECT_TYPE FOREIGN KEY (TYPE_ID) REFERENCES TYPE (OID);
9 | ALTER TABLE PROPERTY_TYPE ADD CONSTRAINT FK_PROPERTY_TYPE_TARGET_PROPERTY FOREIGN KEY (TARGET_PROPERTY) REFERENCES PROPERTY_TYPE (OID);
10 | ALTER TABLE OBJECT_PROPERTY ADD CONSTRAINT FK_OBJECT_PROPERTY_PROPERTY_TYPE FOREIGN KEY (PROPERTY_TYPE) REFERENCES PROPERTY_TYPE (OID);
11 | CREATE UNIQUE INDEX OBJECT_OID ON OBJECT (OID);
12 | CREATE INDEX OBJECT_TYPE_ID ON OBJECT (TYPE_ID);
13 | CREATE UNIQUE INDEX OBJECT_ID ON OBJECT (ID);
14 | CREATE INDEX OBJECT_PROPERTY_OID ON OBJECT_PROPERTY (OID);
15 | CREATE INDEX OBJECT_PROPERTY_PROPERTY_TYPE ON OBJECT_PROPERTY (PROPERTY_TYPE);
16 | CREATE INDEX OBJECT_PROPERTY_ID ON OBJECT_PROPERTY (ID);
17 | CREATE INDEX OBJECT_PROPERTY_RELATED_OID ON OBJECT_PROPERTY (RELATED_OID);
18 | CREATE INDEX OBJECT_PROPERTY_RELATED_PROPERTY_TYPE ON OBJECT_PROPERTY (RELATED_PROPERTY_TYPE);
19 | CREATE INDEX OBJECT_PROPERTY_COLINDEX ON OBJECT_PROPERTY (COLINDEX);
20 | CREATE INDEX OBJECT_PROPERTY_VALUE ON OBJECT_PROPERTY (VALUE);
21 | CREATE UNIQUE INDEX TYPE_OID ON TYPE (OID);
22 | CREATE UNIQUE INDEX TYPE_TYPENAME ON TYPE (TYPENAME);
23 | CREATE UNIQUE INDEX PROPERTY_TYPE_OID ON PROPERTY_TYPE (OID);
24 | CREATE INDEX PROPERTY_TYPE_TARGET_PROPERTY ON PROPERTY_TYPE (TARGET_PROPERTY);
25 | CREATE INDEX PROPERTY_TYPE_TYPE_ID ON PROPERTY_TYPE (TYPE_ID);
26 | CREATE INDEX PROPERTY_TYPE_NAME ON PROPERTY_TYPE (NAME);
27 | CREATE INDEX PROPERTY_TYPE_COLLECTION ON PROPERTY_TYPE (COLLECTION);
28 | CREATE UNIQUE INDEX DEFAULT_OBJECT_DEF_KEY ON DEFAULT_OBJECT (DEF_KEY);
29 | CREATE INDEX DEFAULT_OBJECT_ID ON DEFAULT_OBJECT (ID);
30 |
--------------------------------------------------------------------------------
/build_data/jdbcconfig/scripts/initdb.mysql.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE OBJECT (OID int(11) NOT NULL AUTO_INCREMENT, TYPE_ID int(11) NOT NULL, ID varchar(255) NOT NULL, BLOB text NOT NULL, PRIMARY KEY (OID), UNIQUE INDEX (OID), INDEX (TYPE_ID), UNIQUE INDEX (ID));
2 | CREATE TABLE OBJECT_PROPERTY (OID int(11) NOT NULL, PROPERTY_TYPE int(11) NOT NULL, ID varchar(255) NOT NULL, RELATED_OID int(11), RELATED_PROPERTY_TYPE int(11), COLINDEX int(11) NOT NULL, VALUE varchar(1023), PRIMARY KEY (OID, PROPERTY_TYPE, COLINDEX), INDEX (OID), INDEX (PROPERTY_TYPE), INDEX (ID), INDEX (RELATED_OID), INDEX (RELATED_PROPERTY_TYPE), INDEX (COLINDEX), INDEX (VALUE));
3 | CREATE TABLE TYPE (OID int(11) NOT NULL AUTO_INCREMENT, TYPENAME varchar(255) NOT NULL, PRIMARY KEY (OID), UNIQUE INDEX (OID), UNIQUE INDEX (TYPENAME));
4 | CREATE TABLE PROPERTY_TYPE (OID int(11) NOT NULL AUTO_INCREMENT, TARGET_PROPERTY int(11), TYPE_ID int(11) NOT NULL, NAME varchar(255) NOT NULL, COLLECTION tinyint(1) NOT NULL, TEXT tinyint(1) NOT NULL, PRIMARY KEY (OID), UNIQUE INDEX (OID), INDEX (TARGET_PROPERTY), INDEX (TYPE_ID), INDEX (NAME), INDEX (COLLECTION));
5 | CREATE TABLE DEFAULT_OBJECT (DEF_KEY varchar(255) NOT NULL, ID varchar(255) NOT NULL, UNIQUE INDEX (DEF_KEY), INDEX (ID));
6 | ALTER TABLE OBJECT_PROPERTY ADD INDEX FK_OBJECT_PROPERTY (OID), ADD CONSTRAINT FK_OBJECT_PROPERTY FOREIGN KEY (OID) REFERENCES OBJECT (OID) ON DELETE Cascade;
7 | ALTER TABLE PROPERTY_TYPE ADD INDEX FK_TYPE_PROPERTY_TYPE (TYPE_ID), ADD CONSTRAINT FK_TYPE_PROPERTY_TYPE FOREIGN KEY (TYPE_ID) REFERENCES TYPE (OID);
8 | ALTER TABLE OBJECT ADD INDEX FK_OBJECT_TYPE (TYPE_ID), ADD CONSTRAINT FK_OBJECT_TYPE FOREIGN KEY (TYPE_ID) REFERENCES TYPE (OID);
9 | ALTER TABLE PROPERTY_TYPE ADD INDEX FK_PROPERTY_TYPE_TARGET_PROPERTY (TARGET_PROPERTY), ADD CONSTRAINT FK_PROPERTY_TYPE_TARGET_PROPERTY FOREIGN KEY (TARGET_PROPERTY) REFERENCES PROPERTY_TYPE (OID);
10 | ALTER TABLE OBJECT_PROPERTY ADD INDEX FK_OBJECT_PROPERTY_PROPERTY_TYPE (PROPERTY_TYPE), ADD CONSTRAINT FK_OBJECT_PROPERTY_PROPERTY_TYPE FOREIGN KEY (PROPERTY_TYPE) REFERENCES PROPERTY_TYPE (OID);
11 |
--------------------------------------------------------------------------------
/build_data/jdbcstore/jdbcstore.properties:
--------------------------------------------------------------------------------
1 | #Default GeoServer JDBC loader driver and connection pool options. Edit as appropriate.
2 | #Fri Feb 09 07:18:57 GMT 2024
3 | initdb=true
4 | pool.timeBetweenEvictionRunsMillis=-1L
5 | deleteDestinationOnRename=true
6 | import=true
7 | pool.poolPreparedStatements=true
8 | pool.testWhileIdle=false
9 | pool.validationQuery=SELECT now()
10 | pool.minIdle=4
11 | ignoreDirs=${JDBC_IGNORE_PATHS}
12 | enabled=${JDBC_STORE_ENABLED}
13 | pool.maxOpenPreparedStatements=50
14 | password=${POSTGRES_PASS}
15 | jdbcUrl=jdbc:postgresql://${HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?${SSL_PARAMETERS}
16 | driverClassName=org.postgresql.Driver
17 | pool.maxActive=10
18 | initScript=${GEOSERVER_DATA_DIR}/jdbcstore/scripts/init.postgres.sql
19 | pool.testOnBorrow=true
20 | username=${POSTGRES_USER}
21 |
--------------------------------------------------------------------------------
/build_data/jdbcstore/scripts/drop.h2.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE resources CASCADE;
2 |
--------------------------------------------------------------------------------
/build_data/jdbcstore/scripts/drop.postgres.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE resources CASCADE;
2 |
--------------------------------------------------------------------------------
/build_data/jdbcstore/scripts/init.h2.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE resources
2 | (
3 | oid integer AUTO_INCREMENT NOT NULL,
4 | name character varying NOT NULL,
5 | parent integer,
6 | last_modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
7 | content binary,
8 | CONSTRAINT resources_pkey PRIMARY KEY (oid),
9 | CONSTRAINT resources_parent_fkey FOREIGN KEY (parent)
10 | REFERENCES resources (oid)
11 | ON UPDATE RESTRICT ON DELETE CASCADE,
12 | CONSTRAINT resources_parent_name_key UNIQUE (parent, name),
13 | CONSTRAINT resources_only_one_root_check CHECK (parent IS NOT NULL OR oid = 0)
14 | );
15 |
16 | CREATE INDEX resources_parent_name_idx
17 | ON resources (parent NULLS FIRST, name NULLS FIRST);
18 |
19 | INSERT INTO resources (oid, name, parent, content) VALUES (0, '', NULL, NULL);
20 |
21 | ALTER TABLE resources ALTER COLUMN oid RESTART WITH 1;
22 |
23 |
--------------------------------------------------------------------------------
/build_data/jdbcstore/scripts/init.postgres.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE resources
2 | (
3 | oid serial NOT NULL,
4 | name character varying NOT NULL,
5 | parent integer,
6 | last_modified timestamp without time zone NOT NULL DEFAULT timezone('UTC'::text, now()),
7 | content bytea,
8 | CONSTRAINT resources_pkey PRIMARY KEY (oid),
9 | CONSTRAINT resources_parent_fkey FOREIGN KEY (parent)
10 | REFERENCES resources (oid)
11 | ON UPDATE RESTRICT ON DELETE CASCADE,
12 | CONSTRAINT resources_parent_name_key UNIQUE (parent, name),
13 | CONSTRAINT resources_only_one_root_check CHECK (parent IS NOT NULL OR oid = 0)
14 | );
15 |
16 | CREATE INDEX resources_parent_name_idx
17 | ON resources (parent NULLS FIRST, name NULLS FIRST);
18 |
19 | INSERT INTO resources (oid, name, parent, content) VALUES (0, '', NULL, NULL);
20 |
21 |
--------------------------------------------------------------------------------
/build_data/jdom2-2.0.6.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/build_data/jdom2-2.0.6.1.jar
--------------------------------------------------------------------------------
/build_data/letsencrypt-tomcat.xsl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/build_data/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.appender.logfile = org.apache.log4j.RollingFileAppender
2 | log4j.appender.logfile.File = ${LOG_PATH}
3 | log4j.appender.logfile.Append = true
4 | log4j.appender.logfile.layout = org.apache.log4j.PatternLayout
5 | log4j.appender.logfile.layout.ConversionPattern = %-5p %d [%t][%F:%L] : %m%n
6 |
7 | #configure stdout
8 | log4j.appender.stdout = org.apache.log4j.ConsoleAppender
9 | log4j.appender.stdout.Target = System.out
10 | log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
11 | log4j.appender.stdout.layout.ConversionPattern = %-5p %d [%t][%F:%L] : %m%n
12 |
13 | log4j.rootLogger = debug, logfile, stdout
14 |
15 |
--------------------------------------------------------------------------------
/build_data/logging.properties:
--------------------------------------------------------------------------------
1 | # Source: https://github.com/GoogleCloudPlatform/tomcat-runtime/pull/28/
2 | # Copyright 2017 Google Inc. All Rights Reserved.
3 | #
4 | # Licensed to the Apache Software Foundation (ASF) under one or more
5 | # contributor license agreements. See the NOTICE file distributed with
6 | # this work for additional information regarding copyright ownership.
7 | # The ASF licenses this file to You under the Apache License, Version 2.0
8 | # (the "License"); you may not use this file except in compliance with
9 | # the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 |
19 | # Configure Tomcat to only log to stdout, rather than files. This ensures all
20 | # logs can be collected by the container runtime.
21 |
22 | handlers = java.util.logging.ConsoleHandler
23 | .handlers = java.util.logging.ConsoleHandler
24 |
25 | java.util.logging.ConsoleHandler.level = ${CONSOLE_HANDLER_LEVEL}
26 | java.util.logging.ConsoleHandler.formatter = java.util.logging.OneLineFormatter
27 |
28 | org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
29 | org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = java.util.logging.ConsoleHandler
30 |
31 | org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
32 | org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = java.util.logging.ConsoleHandler
33 |
34 | org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
35 | org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = java.util.logging.ConsoleHandler
36 |
--------------------------------------------------------------------------------
/build_data/plugin_download.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -eux
3 |
4 | mkdir -p /work/required_plugins
5 | mkdir -p /work/stable_plugins
6 | mkdir -p /work/community_plugins
7 | mkdir -p /work/geoserver_war/
8 |
9 | # Build a curl config to download all required plugins
10 | awk '{print "url = \"'"${STABLE_PLUGIN_BASE_URL}/${GS_VERSION}"'/extensions/geoserver-'"${GS_VERSION}"'-"$0".zip\"\noutput = \"/work/required_plugins/"$0".zip\"\n--fail\n--location\n"}' < /work/required_plugins.txt > /work/curl.cfg
11 |
12 |
13 | # Add in all stable plugins
14 | awk '{print "url = \"'"${STABLE_PLUGIN_BASE_URL}/${GS_VERSION}"'/extensions/geoserver-'"${GS_VERSION}"'-"$0".zip\"\noutput = \"/work/stable_plugins/"$0".zip\"\n--fail\n--location\n"}' < /work/stable_plugins.txt >> /work/curl.cfg
15 |
16 |
17 |
18 | # Add in all community plugins
19 | awk '{print "url = \"https://build.geoserver.org/geoserver/'"${GS_VERSION:0:5}"'x/community-latest/geoserver-'"${GS_VERSION:0:4}"'-SNAPSHOT-"$0".zip\"\noutput = \"/work/community_plugins/"$0".zip\"\n--fail\n--location\n"}' < /work/community_plugins.txt >> /work/curl.cfg
20 |
21 |
22 | if [[ "${WAR_URL}" == *\.zip ]]; then
23 | destination="/work/geoserver_war/geoserver.zip"
24 | curl --progress-bar -fLvo "${destination}" "${WAR_URL}" || exit 1
25 | else
26 | destination=/work/geoserver_war/geoserver.war
27 | curl --progress-bar -fLvo "${destination}" "${WAR_URL}" || exit 1
28 | fi
29 |
30 | # Download Jetty Services
31 | curl --progress-bar -fLvo /work/required_plugins/jetty-servlets.jar https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-servlets/11.0.9/jetty-servlets-11.0.9.jar
32 |
33 | # Download jetty-util
34 | curl --progress-bar -fLvo /work/required_plugins/jetty-util.jar https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-util/11.0.9/jetty-util-11.0.9.jar
35 |
36 | curl --progress-bar -fLvo /work/required_plugins/marlin.jar https://github.com/bourgesl/marlin-renderer/releases/download/v0_9_4_8/marlin-0.9.4.8-Unsafe-OpenJDK11.jar
37 |
38 | # Download everything!
39 | for attempt in {1..5}; do
40 | echo "Attempt $attempt of downloading plugins"
41 | if curl --progress-bar -vK /work/curl.cfg; then
42 | echo "Download successful"
43 | break
44 | else
45 | echo "Download failed, retrying in 10 seconds..."
46 | sleep 10
47 | fi
48 | done
49 |
--------------------------------------------------------------------------------
/build_data/required_plugins.txt:
--------------------------------------------------------------------------------
1 | control-flow-plugin
2 | csw-iso-plugin
3 | csw-plugin
4 | gdal-plugin
5 | inspire-plugin
6 | libjpeg-turbo-plugin
7 | monitor-plugin
8 | pyramid-plugin
9 | vectortiles-plugin
10 | wps-plugin
11 |
--------------------------------------------------------------------------------
/build_data/stable_plugins.py:
--------------------------------------------------------------------------------
1 | # Usage: python3 stable_plugins.py 2.23.0 https://sourceforge.net/projects/geoserver/files/GeoServer
2 | # python3 stable_plugins.py version GeoServer_Base_URL
3 | import requests
4 | from bs4 import BeautifulSoup
5 |
6 | import argparse
7 |
8 | parser = argparse.ArgumentParser()
9 | parser.add_argument("version", help="GeoServer version number, e.g. 2.23.0")
10 | parser.add_argument("base_url",
11 | help="Base URL to download GeoServer extensions i.e, e.g."
12 | " https://sourceforge.net/projects/geoserver/files/GeoServer")
13 | args = parser.parse_args()
14 |
15 | url = '%s/%s/extensions' % (args.base_url, args.version)
16 | print(url)
17 | response = requests.get(url)
18 | soup = BeautifulSoup(response.content, 'html.parser')
19 |
20 | plugin_list = []
21 | for link in soup.find_all('a'):
22 | href = link.get('href')
23 |
24 | if href is not None:
25 | if href.endswith('/download') and href.startswith('https'):
26 | plugin_base = href.replace("%s/" % url, "")
27 | plugin_name = plugin_base.replace('.zip/download', '')
28 | plugin_base_name = plugin_name.replace("geoserver-%s-" % args.version, "")
29 | plugin_list.append(plugin_base_name)
30 |
31 | required_plugins = set()
32 | with open('required_plugins.txt', 'r') as f:
33 | for plugin in f:
34 | plugin = plugin.strip()
35 | if plugin:
36 | required_plugins.add(plugin)
37 |
38 | with open('stable_plugins.txt', 'w') as f:
39 | for plugin in plugin_list:
40 | if plugin not in required_plugins:
41 | f.write(plugin + '\n')
42 |
--------------------------------------------------------------------------------
/build_data/stable_plugins.txt:
--------------------------------------------------------------------------------
1 | app-schema-plugin
2 | authkey-plugin
3 | cas-plugin
4 | charts-plugin
5 | css-plugin
6 | db2-plugin
7 | dxf-plugin
8 | excel-plugin
9 | feature-pregeneralized-plugin
10 | geofence-plugin
11 | geofence-server-plugin
12 | geofence-wps-plugin
13 | geopkg-output-plugin
14 | grib-plugin
15 | gwc-s3-plugin
16 | h2-plugin
17 | iau-plugin
18 | importer-plugin
19 | jp2k-plugin
20 | mapml-plugin
21 | mbstyle-plugin
22 | metadata-plugin
23 | mongodb-plugin
24 | mysql-plugin
25 | netcdf-out-plugin
26 | netcdf-plugin
27 | ogr-wfs-plugin
28 | ogr-wps-plugin
29 | oracle-plugin
30 | params-extractor-plugin
31 | printing-plugin
32 | querylayer-plugin
33 | rat-plugin
34 | sldservice-plugin
35 | sqlserver-plugin
36 | wcs2_0-eo-plugin
37 | web-resource-plugin
38 | wmts-multi-dimensional-plugin
39 | wps-cluster-hazelcast-plugin
40 | wps-download-plugin
41 | wps-jdbc-plugin
42 | ysld-plugin
--------------------------------------------------------------------------------
/build_data/tomcat-users.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
22 |
30 |
37 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/clustering/README.md:
--------------------------------------------------------------------------------
1 | # Clustering using JMS Plugin
2 | GeoServer supports clustering using JMS cluster plugin or using the ActiveMQ-broker.
3 |
4 | ## JMS cluster plugin
5 | This setup uses the JMS cluster plugin which uses an embedded broker. A docker-compose.yml
6 | is provided in the clustering folder which simulates the replication using
7 | a shared data directory.
8 |
9 | The environment variables associated with replication are listed below
10 | * `CLUSTERING=True` - Specified whether clustering should be activated.
11 | * `BROKER_URL=tcp://0.0.0.0:61661` - This links to the internal broker provided by the JMS cluster plugin.
12 | This value will be different for (Master-Node)
13 | * `READONLY=disabled` - Determines if the GeoServer instance is Read only
14 | * `RANDOMSTRING=87ee2a9b6802b6da_master` - Used to create a unique CLUSTER_CONFIG_DIR for each instance. Not mandatory as the container can self generate this.
15 | * `INSTANCE_STRING=d8a167a4e61b5415ec263` - Used to differentiate cluster instance names. Not mandatory as the container can self generate this.
16 | * `CLUSTER_DURABILITY=false`
17 | * `TOGGLE_MASTER=true` - Differentiates if the instance will be a Master
18 | * `TOGGLE_SLAVE=true` - Differentiates if the instance will be a Node
19 | * `EMBEDDED_BROKER=disabled` - Should be disabled for the Node
20 | * `CLUSTER_CONNECTION_RETRY_COUNT=10` - How many times try to connect to broker
21 | * `CLUSTER_CONNECTION_MAX_WAIT=500` - Wait time between connection to broker retry (in milliseconds)
22 | * `EXISTING_DATA_DIR` - If you are using an existing data directory, you need to set `CLUSTER_CONFIG_DIR`
23 | otherwise the container is will hang and not start. Additionally, it will check if all the files
24 | needed for clustering exists, otherwise it will fail.
25 |
26 | ## ActiveMQ-broker
27 |
28 | You can additionally run the clustering using an external broker. To run this
29 | you will need to build the image locally and run the stack:
30 |
31 | ```bash
32 | docker compose -f docker-compose-external.yml up -d --build
33 | ```
34 |
35 | or run in a single step
36 |
37 | ```bash
38 | docker compose -f docker-compose-external.yml up -d
39 | ```
--------------------------------------------------------------------------------
/clustering/activemq-docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM bellsoft/liberica-openjdk-alpine:13 AS activemq-prod
2 |
3 | LABEL maintainer="Alessio Fabiani "
4 |
5 | ENV ACTIVEMQ_VERSION=5.17.1
6 | ENV ACTIVEMQ=apache-activemq-$ACTIVEMQ_VERSION
7 | ENV ACTIVEMQ_HOME=/opt/activemq/
8 | ENV ACTIVEMQ_CONF=$ACTIVEMQ_HOME/conf/
9 | ENV ACTIVEMQ_LIB=$ACTIVEMQ_HOME/lib/optional/
10 |
11 |
12 | RUN apk add --update curl && \
13 | rm -rf /var/cache/apk/* && \
14 | mkdir -p /opt && \
15 | curl -s -S https://archive.apache.org/dist/activemq/$ACTIVEMQ_VERSION/$ACTIVEMQ-bin.tar.gz | tar -xvz -C /opt && \
16 | mv /opt/$ACTIVEMQ $ACTIVEMQ_HOME && \
17 | addgroup -S activemq && \
18 | adduser -S -H -G activemq -h $ACTIVEMQ_HOME activemq && \
19 | chown -R activemq:activemq $ACTIVEMQ_HOME && \
20 | chown -h activemq:activemq $ACTIVEMQ_HOME
21 |
22 | ADD setup-jars.sh /setup-jars.sh
23 | RUN chmod +x /*.sh;/setup-jars.sh
24 |
25 | COPY activemq.xml $ACTIVEMQ_CONF/activemq.xml
26 |
27 | # EXPOSE 1883 5672 8161 61613 61614 61616
28 |
29 | USER activemq
30 | WORKDIR $ACTIVEMQ_HOME
31 |
32 | CMD ["/bin/sh", "-c", "bin/activemq console"]
33 |
--------------------------------------------------------------------------------
/clustering/activemq-docker/setup-jars.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | wget -c --tries=2 https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar \
4 | -O "${ACTIVEMQ_LIB}"/slf4j-api-1.7.21.jar
5 | wget -c --tries=2 https://repo1.maven.org/maven2/org/postgresql/postgresql/42.4.0/postgresql-42.4.0.jar \
6 | -O "${ACTIVEMQ_LIB}"/postgresql-42.4.0.jar
7 | wget -c --tries=2 https://repo1.maven.org/maven2/org/osgi/org.osgi.compendium/4.3.1/org.osgi.compendium-4.3.1.jar \
8 | -O "${ACTIVEMQ_LIB}"/org.osgi.compendium-4.3.1.jar
9 | wget -c --tries=2 https://repo1.maven.org/maven2/org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-dbcp/1.4_3/org.apache.servicemix.bundles.commons-dbcp-1.4_3-sources.jar \
10 | -O "${ACTIVEMQ_LIB}"/org.apache.servicemix.bundles.commons-dbcp-1.4_3-sources.jar
11 | wget -c --tries=2 https://repo1.maven.org/maven2/com/zaxxer/HikariCP/2.7.2/HikariCP-2.7.2.jar \
12 | -O "${ACTIVEMQ_LIB}"/HikariCP-2.7.2.jar
--------------------------------------------------------------------------------
/clustering/docker-compose-external.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Common template for ActiveMQ services below
4 | x-common-activemq:
5 | &default-common-activemq
6 | image: kartoza/activemq-docker:manual-build
7 | build: activemq-docker
8 | restart: on-failure
9 |
10 | services:
11 |
12 | db:
13 | image: kartoza/postgis:16-3.4
14 | volumes:
15 | - geo-db-data:/var/lib/postgresql
16 | ports:
17 | - "5432"
18 | environment:
19 | - POSTGRES_DB=gis,data,sample
20 | - POSTGRES_USER=docker
21 | - POSTGRES_PASS=docker
22 | - ALLOW_IP_RANGE=0.0.0.0/0
23 | - FORCE_SSL=TRUE
24 | restart: on-failure
25 | healthcheck:
26 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker -d gis"
27 |
28 | broker1:
29 | << : *default-common-activemq
30 | environment:
31 | - JAVA_HOME=/opt/java/openjdk
32 | - HOST=db
33 | - POSTGRES_PORT=5432
34 | - POSTGRES_DB=gis
35 | - POSTGRES_USER=docker
36 | - POSTGRES_PASS=docker
37 | - ACTIVEMQ_SERVER_URI=tcp://broker1:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600&jms.useAsyncSend=false&transport.daemon=true
38 | - ACTIVEMQ_SERVER_DISCOVERYURI=multicast://default
39 | - SSL_MODE=ALLOW
40 | depends_on:
41 | db:
42 | condition: service_healthy
43 | healthcheck:
44 | test: netstat -ltn | grep -c ":61616"
45 | interval: 30s
46 | timeout: 10s
47 | retries: 10
48 |
49 | broker2:
50 | << : *default-common-activemq
51 | environment:
52 | - JAVA_HOME=/opt/java/openjdk
53 | - HOST=db
54 | - POSTGRES_PORT=5432
55 | - POSTGRES_DB=data
56 | - POSTGRES_USER=docker
57 | - POSTGRES_PASS=docker
58 | - ACTIVEMQ_SERVER_URI=tcp://broker2:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600&jms.useAsyncSend=false&transport.daemon=true
59 | - ACTIVEMQ_SERVER_DISCOVERYURI=multicast://default
60 | - SSL_MODE=ALLOW
61 | depends_on:
62 | db:
63 | condition: service_healthy
64 | broker1:
65 | condition: service_healthy
66 | healthcheck:
67 | test: netstat -ltn | grep -c ":61616"
68 | interval: 30s
69 | timeout: 10s
70 | retries: 10
71 |
72 | broker3:
73 | << : *default-common-activemq
74 | environment:
75 | - JAVA_HOME=/opt/java/openjdk
76 | - HOST=db
77 | - POSTGRES_PORT=5432
78 | - POSTGRES_DB=sample
79 | - POSTGRES_USER=docker
80 | - POSTGRES_PASS=docker
81 | - ACTIVEMQ_SERVER_URI=tcp://broker3:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600&jms.useAsyncSend=false&transport.daemon=true
82 | - ACTIVEMQ_SERVER_DISCOVERYURI=multicast://default
83 | - SSL_MODE=ALLOW
84 | depends_on:
85 | db:
86 | condition: service_healthy
87 | broker1:
88 | condition: service_healthy
89 | healthcheck:
90 | test: netstat -ltn | grep -c ":61616"
91 | interval: 30s
92 | timeout: 10s
93 | retries: 10
94 |
95 | master:
96 | image: kartoza/geoserver:2.24.0
97 | ports:
98 | - "8081:8080"
99 | environment:
100 | - CLUSTERING=true
101 | - CLUSTER_DURABILITY=false
102 | - DB_BACKEND=POSTGRES
103 | - HOST=db
104 | - POSTGRES_PORT=5432
105 | - POSTGRES_DB=gis
106 | - POSTGRES_USER=docker
107 | - POSTGRES_PASS=docker
108 | - SSL_MODE=ALLOW
109 | - BROKER_URL=failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
110 | - READONLY=disabled
111 | - TOGGLE_MASTER=true
112 | - TOGGLE_SLAVE=false
113 | - EMBEDDED_BROKER=disabled
114 | - RUN_AS_ROOT=TRUE
115 | - GEOSERVER_ADMIN_USER=admin
116 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
117 | - STABLE_EXTENSIONS=
118 | - COMMUNITY_EXTENSIONS=jms-cluster-plugin
119 | volumes:
120 | - geoserver-cluster-data:/opt/geoserver/data_dir
121 |
122 |
123 | node:
124 | image: kartoza/geoserver:2.24.0
125 | ports:
126 | - "8082:8080"
127 | environment:
128 | - CLUSTERING=true
129 | - CLUSTER_DURABILITY=false
130 | - DB_BACKEND=POSTGRES
131 | - HOST=db
132 | - POSTGRES_PORT=5432
133 | - POSTGRES_DB=gis
134 | - POSTGRES_USER=docker
135 | - POSTGRES_PASS=docker
136 | - SSL_MODE=ALLOW
137 | - BROKER_URL=failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
138 | - READONLY=enabled
139 | - TOGGLE_MASTER=false
140 | - TOGGLE_SLAVE=true
141 | - EMBEDDED_BROKER=disabled
142 | - RUN_AS_ROOT=TRUE
143 | - GEOSERVER_ADMIN_USER=admin
144 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
145 | - STABLE_EXTENSIONS=
146 | - COMMUNITY_EXTENSIONS=jms-cluster-plugin
147 | volumes:
148 | - geoserver-cluster-data:/opt/geoserver/data_dir
149 |
150 | volumes:
151 | geoserver-cluster-data:
152 | geo-db-data:
153 |
--------------------------------------------------------------------------------
/clustering/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-cluster-data:
4 | geoserver-cluster-gwc-data:
5 | geo-db-data:
6 |
7 | services:
8 | db:
9 | image: kartoza/postgis:17-3.5
10 | volumes:
11 | - geo-db-data:/var/lib/postgresql
12 | environment:
13 | - POSTGRES_DB=gis
14 | - POSTGRES_USER=docker
15 | - POSTGRES_PASS=docker
16 | - ALLOW_IP_RANGE=0.0.0.0/0
17 | - FORCE_SSL=TRUE
18 | restart: on-failure
19 | healthcheck:
20 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker -d gis"
21 | master:
22 | image: kartoza/geoserver:2.27.1
23 | volumes:
24 | - geoserver-cluster-data:/opt/geoserver/data_dir
25 | - geoserver-cluster-gwc-data:/opt/geoserver/gwc
26 | ports:
27 | - "8081:8080"
28 | environment:
29 | - GEOWEBCACHE_CACHE_DIR=/opt/geoserver/gwc
30 | - BROKER_URL=tcp://0.0.0.0:61661
31 | - READONLY=disabled
32 | - CLUSTER_DURABILITY=false
33 | - CLUSTERING=True
34 | - TOGGLE_MASTER=true
35 | - TOGGLE_SLAVE=true
36 | - DB_BACKEND=POSTGRES
37 | - HOST=db
38 | - POSTGRES_PORT=5432
39 | - POSTGRES_DB=gis
40 | - POSTGRES_USER=docker
41 | - POSTGRES_PASS=docker
42 | - SSL_MODE=allow
43 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
44 | - GEOSERVER_ADMIN_USER=admin
45 | # prevent some errors the option below
46 | #- ADDITIONAL_JAVA_STARTUP_OPTIONS="--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED"
47 | restart: on-failure
48 | depends_on:
49 | db:
50 | condition: service_healthy
51 | healthcheck:
52 | test: "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u admin:'myawesomegeoserver' http://localhost:8080/geoserver/rest/about/version.xml"
53 | interval: 1m30s
54 | timeout: 10s
55 | retries: 3
56 | node:
57 | image: kartoza/geoserver:2.27.1
58 | volumes:
59 | - geoserver-cluster-data:/opt/geoserver/data_dir
60 | - geoserver-cluster-gwc-data:/opt/geoserver/gwc
61 | ports:
62 | - "8082:8080"
63 | environment:
64 | - GEOWEBCACHE_CACHE_DIR=/opt/geoserver/gwc
65 | - BROKER_URL=tcp://master:61661
66 | - READONLY=disabled
67 | - CLUSTER_DURABILITY=false
68 | - CLUSTERING=True
69 | - TOGGLE_MASTER=true
70 | - TOGGLE_SLAVE=true
71 | - EMBEDDED_BROKER=disabled
72 | - HOST=db
73 | - POSTGRES_PORT=5432
74 | - POSTGRES_DB=gis
75 | - POSTGRES_USER=docker
76 | - POSTGRES_PASS=docker
77 | - SSL_MODE=allow
78 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
79 | - GEOSERVER_ADMIN_USER=admin
80 | # prevent some errors the option below
81 | #- ADDITIONAL_JAVA_STARTUP_OPTIONS="--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED"
82 | restart: on-failure
83 | depends_on:
84 | master:
85 | condition: service_started
86 | db:
87 | condition: service_healthy
88 | healthcheck:
89 | test: "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u admin:'myawesomegeoserver' http://localhost:8080/geoserver/rest/about/version.xml"
90 | interval: 1m30s
91 | timeout: 10s
92 | retries: 3
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/docker-compose-build.yml:
--------------------------------------------------------------------------------
1 | volumes:
2 | geoserver-data:
3 | settings:
4 | services:
5 | geoserver-prod:
6 | image: kartoza/geoserver:${GS_VERSION}
7 | volumes:
8 | - geoserver-data:/opt/geoserver/data_dir
9 | - settings:/settings
10 | ports:
11 | - ${GEOSERVER_PORT}:8080
12 | restart: on-failure
13 | environment:
14 | - GEOSERVER_DATA_DIR=${GEOSERVER_DATA_DIR}
15 | - GEOWEBCACHE_CACHE_DIR=${GEOWEBCACHE_CACHE_DIR}
16 | - GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD}
17 | - GEOSERVER_ADMIN_USER=${GEOSERVER_ADMIN_USER}
18 | - INITIAL_MEMORY=${INITIAL_MEMORY}
19 | - MAXIMUM_MEMORY=${MAXIMUM_MEMORY}
20 | - RECREATE_DATADIR=${RECREATE_DATADIR}
21 | - HTTP_PROXY_NAME
22 | - HTTP_PROXY_PORT
23 | - STABLE_EXTENSIONS=${STABLE_EXTENSIONS}
24 | - COMMUNITY_EXTENSIONS=${COMMUNITY_EXTENSIONS}
25 | healthcheck:
26 | test: [ "CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml" ]
27 | interval: 1m
28 | timeout: 10s
29 | retries: 3
30 | start_period: 1m
31 | build:
32 | context: .
33 | # Use yaml anchor for reusability
34 | args: &build-args-anchor
35 | IMAGE_VERSION: ${IMAGE_VERSION}
36 | JAVA_HOME: ${JAVA_HOME}
37 | GS_VERSION: ${GS_VERSION}
38 | WAR_URL: ${WAR_URL}
39 | STABLE_PLUGIN_BASE_URL: ${STABLE_PLUGIN_BASE_URL}
40 | ACTIVATE_GDAL_PLUGIN: ${ACTIVATE_GDAL_PLUGIN}
41 | target: geoserver-prod
42 |
43 | geoserver-test:
44 | image: kartoza/geoserver:manual-build
45 | build:
46 | context: .
47 | args:
48 | <<: *build-args-anchor
49 | target: geoserver-test
--------------------------------------------------------------------------------
/docker-compose-nginx.yml:
--------------------------------------------------------------------------------
1 | volumes:
2 | geoserver-data:
3 | geo-db-data:
4 |
5 | services:
6 | db:
7 | image: kartoza/postgis:${POSTGIS_VERSION_TAG}
8 | volumes:
9 | - geo-db-data:/var/lib/postgresql
10 | ports:
11 | - ${POSTGRES_PORT}:5432
12 | environment:
13 | - POSTGRES_DB=${POSTGRES_DB}
14 | - POSTGRES_USER=${POSTGRES_USER}
15 | - POSTGRES_PASS=${POSTGRES_PASS}
16 | - ALLOW_IP_RANGE=${ALLOW_IP_RANGE}
17 | - FORCE_SSL=TRUE
18 | restart: on-failure
19 | healthcheck:
20 | test: "PGPASSWORD=${POSTGRES_PASS} pg_isready -h 127.0.0.1 -U ${POSTGRES_USER} -d ${POSTGRES_DB}"
21 | interval: 30s
22 | timeout: 10s
23 | retries: 3
24 | start_period: 1m
25 |
26 | geoserver:
27 | image: kartoza/geoserver:${GS_VERSION}
28 | volumes:
29 | - geoserver-data:/opt/geoserver/data_dir
30 | restart: on-failure
31 | environment:
32 | - GEOSERVER_DATA_DIR=${GEOSERVER_DATA_DIR}
33 | - GEOWEBCACHE_CACHE_DIR=${GEOWEBCACHE_CACHE_DIR}
34 | - GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD}
35 | - GEOSERVER_ADMIN_USER=${GEOSERVER_ADMIN_USER}
36 | - INITIAL_MEMORY=${INITIAL_MEMORY}
37 | - MAXIMUM_MEMORY=${MAXIMUM_MEMORY}
38 | depends_on:
39 | db:
40 | condition: service_healthy
41 | healthcheck:
42 | test: [ "CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml" ]
43 | interval: 1m30s
44 | timeout: 10s
45 | retries: 3
46 | start_period: 1m
47 |
48 | nginx:
49 | image: nginx
50 | volumes:
51 | - ./sites-enabled:/etc/nginx/conf.d:ro
52 | logging:
53 | driver: json-file
54 | options:
55 | max-size: 200m
56 | max-file: '10'
57 | depends_on:
58 | - geoserver
59 | ports:
60 | - "80:80"
61 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | volumes:
2 | geoserver-data:
3 | geo-db-data:
4 | geoserver-gwc:
5 | geoserver-settings:
6 |
7 | services:
8 | db:
9 | image: kartoza/postgis:${POSTGIS_VERSION_TAG}
10 | volumes:
11 | - geo-db-data:/var/lib/postgresql
12 | ports:
13 | - "${POSTGRES_PORT}:5432"
14 | environment:
15 | - POSTGRES_DB=${POSTGRES_DB}
16 | - POSTGRES_USER=${POSTGRES_USER}
17 | - POSTGRES_PASS=${POSTGRES_PASS}
18 | - ALLOW_IP_RANGE=${ALLOW_IP_RANGE}
19 | - FORCE_SSL=TRUE
20 | restart: on-failure
21 | healthcheck:
22 | test: "pg_isready -h 127.0.0.1 -U ${POSTGRES_USER}"
23 | interval: 1m30s
24 | timeout: 10s
25 | retries: 3
26 | start_period: 1m
27 |
28 | geoserver:
29 | image: kartoza/geoserver:${GS_VERSION}
30 | volumes:
31 | - geoserver-data:/opt/geoserver/data_dir
32 | - geoserver-gwc:/opt/geoserver/gwc
33 | - geoserver-settings:/settings
34 | ports:
35 | - "${GEOSERVER_PORT}:8080"
36 | restart: on-failure
37 | environment:
38 | - GEOSERVER_DATA_DIR=${GEOSERVER_DATA_DIR}
39 | - GEOWEBCACHE_CACHE_DIR=${GEOWEBCACHE_CACHE_DIR}
40 | - GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD}
41 | - GEOSERVER_ADMIN_USER=${GEOSERVER_ADMIN_USER}
42 | - INITIAL_MEMORY=${INITIAL_MEMORY}
43 | - MAXIMUM_MEMORY=${MAXIMUM_MEMORY}
44 | - STABLE_EXTENSIONS=${STABLE_EXTENSIONS}
45 | - COMMUNITY_EXTENSIONS=${COMMUNITY_EXTENSIONS}
46 | - GEOSERVER_CONTEXT_ROOT=${GEOSERVER_CONTEXT_ROOT}
47 | - ROOT_WEBAPP_REDIRECT=true
48 | - CONSOLE_HANDLER_LEVEL=${CONSOLE_HANDLER_LEVEL}
49 | depends_on:
50 | db:
51 | condition: service_healthy
52 | healthcheck:
53 | test: [ "CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml" ]
54 | interval: 1m30s
55 | timeout: 10s
56 | retries: 3
57 | start_period: 1m
58 |
--------------------------------------------------------------------------------
/docs/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/docs/assets/images/favicon.png
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.da.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Lunr languages, `Danish` language
3 | * https://github.com/MihaiValentin/lunr-languages
4 | *
5 | * Copyright 2014, Mihai Valentin
6 | * http://www.mozilla.org/MPL/
7 | */
8 | /*!
9 | * based on
10 | * Snowball JavaScript Library v0.3
11 | * http://code.google.com/p/urim/
12 | * http://snowball.tartarus.org/
13 | *
14 | * Copyright 2010, Oleg Mazko
15 | * http://www.mozilla.org/MPL/
16 | */
17 |
18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){var e,r=f.cursor+3;if(d=f.limit,0<=r&&r<=f.limit){for(a=r;;){if(e=f.cursor,f.in_grouping(w,97,248)){f.cursor=e;break}if(f.cursor=e,e>=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.de.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Lunr languages, `German` language
3 | * https://github.com/MihaiValentin/lunr-languages
4 | *
5 | * Copyright 2014, Mihai Valentin
6 | * http://www.mozilla.org/MPL/
7 | */
8 | /*!
9 | * based on
10 | * Snowball JavaScript Library v0.3
11 | * http://code.google.com/p/urim/
12 | * http://snowball.tartarus.org/
13 | *
14 | * Copyright 2010, Oleg Mazko
15 | * http://www.mozilla.org/MPL/
16 | */
17 |
18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.du.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Lunr languages, `Dutch` language
3 | * https://github.com/MihaiValentin/lunr-languages
4 | *
5 | * Copyright 2014, Mihai Valentin
6 | * http://www.mozilla.org/MPL/
7 | */
8 | /*!
9 | * based on
10 | * Snowball JavaScript Library v0.3
11 | * http://code.google.com/p/urim/
12 | * http://snowball.tartarus.org/
13 | *
14 | * Copyright 2010, Oleg Mazko
15 | * http://www.mozilla.org/MPL/
16 | */
17 |
18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.hi.min.js:
--------------------------------------------------------------------------------
1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.ja.min.js:
--------------------------------------------------------------------------------
1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.no.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Lunr languages, `Norwegian` language
3 | * https://github.com/MihaiValentin/lunr-languages
4 | *
5 | * Copyright 2014, Mihai Valentin
6 | * http://www.mozilla.org/MPL/
7 | */
8 | /*!
9 | * based on
10 | * Snowball JavaScript Library v0.3
11 | * http://code.google.com/p/urim/
12 | * http://snowball.tartarus.org/
13 | *
14 | * Copyright 2010, Oleg Mazko
15 | * http://www.mozilla.org/MPL/
16 | */
17 |
18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.stemmer.support.min.js:
--------------------------------------------------------------------------------
1 | !function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.sv.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Lunr languages, `Swedish` language
3 | * https://github.com/MihaiValentin/lunr-languages
4 | *
5 | * Copyright 2014, Mihai Valentin
6 | * http://www.mozilla.org/MPL/
7 | */
8 | /*!
9 | * based on
10 | * Snowball JavaScript Library v0.3
11 | * http://code.google.com/p/urim/
12 | * http://snowball.tartarus.org/
13 | *
14 | * Copyright 2010, Oleg Mazko
15 | * http://www.mozilla.org/MPL/
16 | */
17 |
18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.ta.min.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="-உஊ-ஏஐ-ஙச-ட-னப-யர-ஹ-ிீ-ொ-ௐ---௩௪-௯௰-௹௺-a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.th.min.js:
--------------------------------------------------------------------------------
1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[-]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.vi.min.js:
--------------------------------------------------------------------------------
1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}});
--------------------------------------------------------------------------------
/docs/assets/javascripts/lunr/min/lunr.zh.min.js:
--------------------------------------------------------------------------------
1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}});
--------------------------------------------------------------------------------
/docs/assets/stylesheets/palette.2505c338.min.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["src/assets/stylesheets/palette/_scheme.scss","../../../src/assets/stylesheets/palette.scss","src/assets/stylesheets/palette/_accent.scss","src/assets/stylesheets/palette/_primary.scss","src/assets/stylesheets/utilities/_break.scss"],"names":[],"mappings":"AA2BA,cAGE,6BAKE,YAAA,CAGA,mDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CACA,mDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CAGA,gDAAA,CACA,gDAAA,CAGA,4BAAA,CACA,iCAAA,CACA,kCAAA,CACA,mCAAA,CACA,mCAAA,CACA,kCAAA,CACA,iCAAA,CACA,+CAAA,CACA,6DAAA,CACA,gEAAA,CACA,4DAAA,CACA,4DAAA,CACA,6DAAA,CAGA,6CAAA,CAGA,+CAAA,CAGA,iCAAA,CAGA,uDAAA,CACA,6DAAA,CACA,2DAAA,CAGA,yDAAA,CAGA,mDAAA,CACA,mDAAA,CAGA,qDAAA,CACA,wDAAA,CAGA,0DAAA,CAKA,8DAAA,CAKA,0DCxDF,CD6DE,kHAEE,YC3DJ,CD+DE,gHAEE,eC7DJ,CDoFE,yDACE,4BClFJ,CDiFE,2DACE,4BC/EJ,CD8EE,gEACE,4BC5EJ,CD2EE,2DACE,4BCzEJ,CDwEE,yDACE,4BCtEJ,CDqEE,0DACE,4BCnEJ,CDkEE,gEACE,4BChEJ,CD+DE,0DACE,4BC7DJ,CD4DE,2OACE,4BCjDJ,CDwDA,+FAGE,iCCtDF,CACF,CCjDE,2BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD6CN,CCvDE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDoDN,CC9DE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD2DN,CCrEE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDkEN,CC5EE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDyEN,CCnFE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDgFN,CC1FE,kCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDuFN,CCjGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD8FN,CCxGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDqGN,CC/GE,6BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD4GN,CCtHE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDmHN,CC7HE,4BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD6HN,CCpIE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDoIN,CC3IE,6BACE,yBAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD2IN,CClJE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDkJN,CCzJE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDsJN,CE3JE,4BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwJN,CEnKE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgKN,CE3KE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwKN,CEnLE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgLN,CE3LE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwLN,CEnME,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgMN,CE3ME,mCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwMN,CEnNE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgNN,CE3NE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwNN,CEnOE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgON,CE3OE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwON,CEnPE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFmPN,CE3PE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCF2PN,CEnQE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFmQN,CE3QE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCF2QN,CEnRE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgRN,CE3RE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwRN,CEnSE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BF4RN,CE5SE,kCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BFqSN,CEtRE,sEACE,4BFyRJ,CE1RE,+DACE,4BF6RJ,CE9RE,iEACE,4BFiSJ,CElSE,gEACE,4BFqSJ,CEtSE,iEACE,4BFySJ,CEhSA,8BACE,0BAAA,CACA,sCAAA,CACA,qCAAA,CACA,+BAAA,CACA,sCAAA,CAGA,4BFiSF,CE9RE,yCACE,+BFgSJ,CE7RI,kDAEE,0CAAA,CACA,sCAAA,CAFA,UFiSN,CG7MI,mCD1EA,+CACE,0BF0RJ,CEvRI,qDACE,0BFyRN,CEpRE,iEACE,eFsRJ,CACF,CGxNI,sCDvDA,uCACE,oCFkRJ,CACF,CEzQA,8BACE,0BAAA,CACA,sCAAA,CACA,gCAAA,CACA,0BAAA,CACA,sCAAA,CAGA,4BF0QF,CEvQE,yCACE,+BFyQJ,CEtQI,kDAEE,0CAAA,CACA,sCAAA,CAFA,UF0QN,CEnQE,yCACE,qBFqQJ,CG9NI,wCDhCA,8CACE,0BFiQJ,CACF,CGtPI,mCDJA,+CACE,0BF6PJ,CE1PI,qDACE,0BF4PN,CACF,CG3OI,wCDTA,iFACE,qBFuPJ,CACF,CGnQI,sCDmBA,uCACE,qBFmPJ,CACF","file":"palette.css"}
--------------------------------------------------------------------------------
/docs/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | None
5 | 2023-02-01
6 | daily
7 |
8 |
9 | None
10 | 2023-02-01
11 | daily
12 |
13 |
14 | None
15 | 2023-02-01
16 | daily
17 |
18 |
19 | None
20 | 2023-02-01
21 | daily
22 |
23 |
24 | None
25 | 2023-02-01
26 | daily
27 |
28 |
29 | None
30 | 2023-02-01
31 | daily
32 |
33 |
34 | None
35 | 2023-02-01
36 | daily
37 |
38 |
--------------------------------------------------------------------------------
/docs/sitemap.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/docs/sitemap.xml.gz
--------------------------------------------------------------------------------
/resources/README.txt:
--------------------------------------------------------------------------------
1 | Resources needed in the image at build time should be placed here.
2 |
--------------------------------------------------------------------------------
/resources/overlays/README.txt:
--------------------------------------------------------------------------------
1 | To include files in the container file system at arbitrary locations, build
2 | a directory structure from / here and include the files at the desired location.
3 |
4 | For example, to include a static Tomcat setenv.sh in the build, place it at:
5 |
6 | resources/overlays/usr/local/tomcat/bin/setenv.sh
7 |
8 | Other overlay examples include static GeoServer data directories, the Marlin renderer, etc.
9 |
10 | Note that overlay files will overwrite existing destination files, and that
11 | files in the overlay root will be copied to the container root
12 | (e.g. resources/overlay/somefile.txt will be copied to /somefile.txt).
13 |
14 | Be careful!
15 |
--------------------------------------------------------------------------------
/scenario_tests/.gitignore:
--------------------------------------------------------------------------------
1 | docker-compose.override.yml
2 |
--------------------------------------------------------------------------------
/scenario_tests/README.md:
--------------------------------------------------------------------------------
1 | # TESTING GUIDE
2 |
3 |
4 | ## TL;DR; How to run the test
5 |
6 | Go into root repo and run
7 |
8 | ```
9 | ./build-test.sh
10 | ```
11 |
12 | It will create a tagged image `kartoza/geoserver:${TAG:-manual-build}`
13 |
14 | Each scenario tests in this directory use this image.
15 |
16 | To run each scenario test, go into the scenario directory and run test script:
17 |
18 | ```
19 | # Testing login scenario
20 | cd login
21 | ./test.sh
22 | ```
23 |
24 |
25 | ## Making new tests
26 |
27 | Create new directory in this folder (`scenario_tests`).
28 | Directory should contains:
29 |
30 | - Host level test script called `test.sh`
31 | - `docker-compose.yml` file for the service setup
32 | - `.env` file if needed for `docker-compose.yml` settings
33 | - `tests` directory which contains your test scripts. The testing architecture will
34 | execute `test.sh` script in this directory (service level), if you use generic host level `test.sh` script.
35 |
36 |
37 | Explanations:
38 |
39 | Host level test script is used to set up the docker service, then run the unit test when
40 | the service is ready. You can copy and paste from existing `login` for generic script.
41 |
42 | `docker-compose.yml` file should mount your `tests` directory and provides settings
43 | needed by the service that are going to be tested.
44 |
45 | `tests` directory contains the actual test script that will be run from *inside*
46 | the service. For example, in `login` scenario `test.sh` (service level scripts)
47 | will start python unittest script with necessary variables.
48 |
49 | Add your scenario to travis config:
50 |
51 | In `env[]` list there will be a `SCENARIO` variable to set.
52 | Add your environment variable needed to run your test in `env[]` list.
53 | For example, if you have new scenario folder `my_test`, then the env key
54 | will look like this:
55 |
56 | ```
57 | env:
58 | - SCENARIO=gwc
59 | - SCENARIO=plugins
60 | - SCENARIO=my_test EXTRA_SETTING_1=value1 EXTRA_SETTING_2=value2 EXTRA_SETTING_3=value3
61 | ```
62 |
--------------------------------------------------------------------------------
/scenario_tests/backup_restore/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 | geoserver-data:
5 | geoserver-backup-dir:
6 |
7 |
8 | services:
9 |
10 | geoserver:
11 | image: 'kartoza/geoserver:${TAG:-manual-build}'
12 | restart: 'always'
13 | volumes:
14 | - geoserver-data-dir:/opt/geoserver/data_dir
15 | - geoserver-backup-dir:/settings
16 | - ./tests:/tests
17 | environment:
18 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
19 | GEOSERVER_ADMIN_USER: admin
20 | SAMPLE_DATA: true
21 | CONSOLE_HANDLER_LEVEL: WARNING
22 | COMMUNITY_EXTENSIONS: backup-restore-plugin
23 | TEST_CLASS: test_geoserver_backup.TestGeoServerBackup
24 | ports:
25 | - "8080:8080"
26 | healthcheck:
27 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
28 | interval: 1m30s
29 | timeout: 10s
30 | retries: 3
31 |
32 | restore:
33 | image: 'kartoza/geoserver:${TAG:-manual-build}'
34 | restart: 'always'
35 | volumes:
36 | - geoserver-data:/opt/geoserver/data_dir
37 | - geoserver-backup-dir:/settings
38 | - ./tests:/tests
39 | environment:
40 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
41 | GEOSERVER_ADMIN_USER: admin
42 | CONSOLE_HANDLER_LEVEL: WARNING
43 | RECREATE_DATADIR: TRUE
44 | COMMUNITY_EXTENSIONS: backup-restore-plugin
45 | TEST_CLASS: test_geoserver_restore.TestGeoServerRestore
46 | ports:
47 | - "8080"
48 | healthcheck:
49 | test: [ "CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml" ]
50 | interval: 1m30s
51 | timeout: 10s
52 | retries: 3
53 |
54 |
55 |
--------------------------------------------------------------------------------
/scenario_tests/backup_restore/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ${VERSION} -f docker-compose.yml up -d
11 |
12 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
13 | ${VERSION} -f docker-compose.yml logs -f &
14 | fi
15 |
16 |
17 | services=("geoserver")
18 |
19 | for service in "${services[@]}"; do
20 |
21 | # Execute tests
22 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
23 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
24 | echo -e "\e[32m ---------------------------------------- \033[0m"
25 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
26 | ${VERSION} -f docker-compose.yml exec $service /bin/bash /tests/test.sh
27 |
28 | done
29 |
30 | services=("restore")
31 |
32 | for service in "${services[@]}"; do
33 |
34 | # Execute tests
35 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
36 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
37 | echo -e "\e[32m ---------------------------------------- \033[0m"
38 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
39 | ${VERSION} -f docker-compose.yml exec $service /bin/bash /tests/test.sh
40 |
41 | done
42 |
43 | ${VERSION} -f docker-compose.yml down -v
44 |
--------------------------------------------------------------------------------
/scenario_tests/backup_restore/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/backup_restore/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/backup_restore/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/backup_restore/tests/test_geoserver_backup.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import requests
3 | from requests.auth import HTTPBasicAuth
4 | from os import environ, mkdir, chmod
5 | from os.path import join, exists
6 | from shutil import chown
7 | import json
8 | import time
9 |
10 |
11 | class TestGeoServerBackup(unittest.TestCase):
12 |
13 | def setUp(self):
14 | """Set up the base URL, authentication, and create the zip file."""
15 | self.gs_url = 'http://localhost:8080/geoserver'
16 | self.geo_username = environ.get('GEOSERVER_ADMIN_USER', 'admin')
17 | self.geo_password = environ.get('GEOSERVER_ADMIN_PASSWORD', 'myawesomegeoserver')
18 | self.username = 'geoserveruser'
19 | self.group_name = 'geoserverusers'
20 | self.backup_path = "/settings/backup/"
21 |
22 | def test_create_backup(self):
23 | """Test creating a GeoServer backup using the Backup and Restore plugin."""
24 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
25 | base_url = f"{self.gs_url}/rest/br/backup/"
26 | if not exists(self.backup_path):
27 | mkdir(self.backup_path)
28 | backup_file = join(self.backup_path, 'geoserver.zip')
29 | # Create the empty zip file
30 | with open(backup_file, "wb") as f:
31 | pass
32 |
33 | # Change ownership of the zip file
34 | chmod(self.backup_path, 0o777)
35 | chown(backup_file, user=self.username, group=self.group_name)
36 | headers = {
37 | "Content-Type": "application/json"
38 | }
39 |
40 | payload = {
41 | "backup": {
42 | "archiveFile": backup_file,
43 | "overwrite": True,
44 | "options": {},
45 | "filter": "name IN ('tiger')"
46 | }
47 | }
48 |
49 | # Send the POST request to trigger the backup
50 | response = requests.post(base_url, json=payload, auth=auth, headers=headers)
51 | response_data = json.loads(response.text)
52 | execution_id = response_data["backup"]["execution"]["id"]
53 | execution_url = f"{self.gs_url}/rest/br/backup/{execution_id}.json"
54 | # wait for backup to complete
55 | time.sleep(40)
56 | response_execution_request = requests.get(execution_url, auth=auth)
57 | if response_execution_request.status_code == 200:
58 | try:
59 | response_execution_json = response_execution_request.json()
60 | response_status = response_execution_json["backup"]["execution"]["status"]
61 | self.assertEqual(response_status, 'COMPLETED', "backup initiated successfully")
62 | except ValueError as e:
63 | print("Error parsing JSON:", e)
64 | print("Raw response content:", response_execution_request.text)
65 | else:
66 | print(f"Request failed with status code {response_execution_request.status_code}")
67 | print("Response content:", response_execution_request.text)
68 |
69 | # Verify the response status code
70 | self.assertEqual(response.status_code, 201, "backup initiated successfully")
71 |
72 |
73 | if __name__ == "__main__":
74 | unittest.main()
75 |
--------------------------------------------------------------------------------
/scenario_tests/backup_restore/tests/test_geoserver_restore.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import unittest
3 | import requests
4 | from requests.auth import HTTPBasicAuth
5 | from os import environ, chmod
6 | from os.path import join, exists
7 | import json
8 | import time
9 |
10 |
11 | class TestGeoServerRestore(unittest.TestCase):
12 |
13 | def setUp(self):
14 | """Set up the base URL, authentication, and create the zip file."""
15 | self.gs_url = 'http://localhost:8080/geoserver'
16 | self.geo_username = environ.get('GEOSERVER_ADMIN_USER', 'admin')
17 | self.geo_password = environ.get('GEOSERVER_ADMIN_PASSWORD', 'myawesomegeoserver')
18 | self.backup_path = "/settings/backup/"
19 |
20 | def test_restore_backup(self):
21 | """Test restoring an existing backup of a GeoServer instance using the Backup and Restore plugin."""
22 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
23 | base_url = f"{self.gs_url}/rest/br/restore/"
24 | backup_file = join(self.backup_path, 'geoserver.zip')
25 | chmod(self.backup_path, 0o777)
26 | if not exists(backup_file):
27 | sys.exit()
28 |
29 | headers = {
30 | "Content-Type": "application/json"
31 | }
32 |
33 | payload = {
34 | "restore": {
35 | "archiveFile": backup_file,
36 | "options": {
37 | "option": ["BK_BEST_EFFORT=true"]
38 | }
39 | }
40 | }
41 |
42 | # Send the POST request to trigger the backup
43 | response = requests.post(base_url, json=payload, auth=auth, headers=headers)
44 | response_data = json.loads(response.text)
45 | execution_id = response_data["restore"]["execution"]["id"]
46 | execution_url = f"{self.gs_url}/rest/br/restore/{execution_id}.json"
47 | # wait for backup to complete
48 | time.sleep(30)
49 | response_execution_request = requests.get(execution_url, auth=auth)
50 | if response_execution_request.status_code == 200:
51 | try:
52 | response_execution_json = response_execution_request.json()
53 | response_status = response_execution_json["restore"]["execution"]["status"]
54 | self.assertEqual(response_status, 'COMPLETED', "backup initiated successfully")
55 | except ValueError as e:
56 | print("Error parsing JSON:", e)
57 | print("Raw response content:", response_execution_request.text)
58 | else:
59 | print(f"Request failed with status code {response_execution_request.status_code}")
60 | print("Response content:", response_execution_request.text)
61 |
62 | # Verify the response status code
63 | self.assertEqual(response.status_code, 201, "backup initiated successfully")
64 |
65 |
66 | if __name__ == "__main__":
67 | unittest.main()
68 |
--------------------------------------------------------------------------------
/scenario_tests/clustering/docker-compose-external.yml:
--------------------------------------------------------------------------------
1 | # Common template for ActiveMQ services below
2 | x-common-activemq:
3 | &default-common-activemq
4 | image: kartoza/activemq-docker:manual-build
5 | #build: activemq-docker
6 | restart: on-failure
7 |
8 | services:
9 |
10 | db:
11 | image: kartoza/postgis:17-3.5
12 | volumes:
13 | - geo-db-data:/var/lib/postgresql
14 | - ./tests/init.sql:/docker-entrypoint-initdb.d/init.sql
15 | environment:
16 | - POSTGRES_DB=gis,data,sample
17 | - POSTGRES_USER=docker
18 | - POSTGRES_PASS=docker
19 | - ALLOW_IP_RANGE=0.0.0.0/0
20 | - FORCE_SSL=TRUE
21 | restart: on-failure
22 | healthcheck:
23 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker"
24 |
25 | broker1:
26 | << : *default-common-activemq
27 | environment:
28 | - JAVA_HOME=/opt/java/openjdk
29 | - HOST=db
30 | - POSTGRES_PORT=5432
31 | - POSTGRES_DB=gis
32 | - POSTGRES_USER=docker
33 | - POSTGRES_PASS=docker
34 | - ACTIVEMQ_SERVER_URI=tcp://broker1:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600&jms.useAsyncSend=false&transport.daemon=true
35 | - ACTIVEMQ_SERVER_DISCOVERYURI=multicast://default
36 | - SSL_MODE=ALLOW
37 | depends_on:
38 | db:
39 | condition: service_healthy
40 | healthcheck:
41 | test: netstat -ltn | grep -c ":61616"
42 | interval: 30s
43 | timeout: 10s
44 | retries: 10
45 |
46 | broker2:
47 | << : *default-common-activemq
48 | environment:
49 | - JAVA_HOME=/opt/java/openjdk
50 | - HOST=db
51 | - POSTGRES_PORT=5432
52 | - POSTGRES_DB=data
53 | - POSTGRES_USER=docker
54 | - POSTGRES_PASS=docker
55 | - ACTIVEMQ_SERVER_URI=tcp://broker2:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600&jms.useAsyncSend=false&transport.daemon=true
56 | - ACTIVEMQ_SERVER_DISCOVERYURI=multicast://default
57 | - SSL_MODE=ALLOW
58 | depends_on:
59 | db:
60 | condition: service_healthy
61 | broker1:
62 | condition: service_healthy
63 | healthcheck:
64 | test: netstat -ltn | grep -c ":61616"
65 | interval: 30s
66 | timeout: 10s
67 | retries: 10
68 |
69 | broker3:
70 | << : *default-common-activemq
71 | environment:
72 | - JAVA_HOME=/opt/java/openjdk
73 | - HOST=db
74 | - POSTGRES_PORT=5432
75 | - POSTGRES_DB=sample
76 | - POSTGRES_USER=docker
77 | - POSTGRES_PASS=docker
78 | - ACTIVEMQ_SERVER_URI=tcp://broker3:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600&jms.useAsyncSend=false&transport.daemon=true
79 | - ACTIVEMQ_SERVER_DISCOVERYURI=multicast://default
80 | - SSL_MODE=ALLOW
81 | depends_on:
82 | db:
83 | condition: service_healthy
84 | broker1:
85 | condition: service_healthy
86 | healthcheck:
87 | test: netstat -ltn | grep -c ":61616"
88 | interval: 30s
89 | timeout: 10s
90 | retries: 10
91 |
92 | master:
93 | image: kartoza/geoserver:manual-build
94 | environment:
95 | - CLUSTERING=true
96 | - CLUSTER_DURABILITY=false
97 | - DB_BACKEND=POSTGRES
98 | - HOST=db
99 | - POSTGRES_PORT=5432
100 | - POSTGRES_DB=gis
101 | - POSTGRES_USER=docker
102 | - POSTGRES_PASS=docker
103 | #- POSTGRES_SCHEMA=gwc
104 | - SSL_MODE=ALLOW
105 | - BROKER_URL=failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
106 | - READONLY=disabled
107 | - TOGGLE_MASTER=true
108 | - TOGGLE_SLAVE=false
109 | - EMBEDDED_BROKER=disabled
110 | - RUN_AS_ROOT=TRUE
111 | - GEOSERVER_ADMIN_USER=admin
112 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
113 | - CONSOLE_HANDLER_LEVEL=WARNING
114 | - STABLE_EXTENSIONS=
115 | - COMMUNITY_EXTENSIONS=jms-cluster-plugin
116 | - TEST_CLASS=test_clustering_master.GeoServerClusteringMaster
117 | volumes:
118 | - geoserver-cluster-data:/opt/geoserver/data_dir
119 | - ./tests:/tests
120 | ports:
121 | - "8081:8080"
122 | healthcheck:
123 | test: ["CMD-SHELL","curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u admin:myawesomegeoserver http://localhost:8080/geoserver/rest/about/version.xml"]
124 | interval: 1m30s
125 | timeout: 10s
126 | retries: 3
127 |
128 |
129 | node:
130 | image: kartoza/geoserver:manual-build
131 | environment:
132 | - CLUSTERING=true
133 | - CLUSTER_DURABILITY=false
134 | - DB_BACKEND=POSTGRES
135 | - HOST=db
136 | - POSTGRES_PORT=5432
137 | - POSTGRES_DB=gis
138 | - POSTGRES_USER=docker
139 | - POSTGRES_PASS=docker
140 | #- POSTGRES_SCHEMA=gwc
141 | - SSL_MODE=ALLOW
142 | - BROKER_URL=failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
143 | - READONLY=enabled
144 | - TOGGLE_MASTER=false
145 | - TOGGLE_SLAVE=true
146 | - EMBEDDED_BROKER=disabled
147 | - RUN_AS_ROOT=TRUE
148 | - GEOSERVER_ADMIN_USER=admin
149 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
150 | - CONSOLE_HANDLER_LEVEL=WARNING
151 | - STABLE_EXTENSIONS=
152 | - COMMUNITY_EXTENSIONS=jms-cluster-plugin
153 | - TEST_CLASS=test_clustering_node.GeoServerClusteringNode
154 | volumes:
155 | - geoserver-cluster-data:/opt/geoserver/data_dir
156 | - ./tests:/tests
157 | ports:
158 | - "8082:8080"
159 | healthcheck:
160 | test: "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u admin:myawesomegeoserver http://localhost:8080/geoserver/rest/about/version.xml"
161 | interval: 1m30s
162 | timeout: 10s
163 | retries: 3
164 |
165 | volumes:
166 | geoserver-cluster-data:
167 | geo-db-data:
168 |
--------------------------------------------------------------------------------
/scenario_tests/clustering/docker-compose.yml:
--------------------------------------------------------------------------------
1 | volumes:
2 | geoserver-cluster-data:
3 | geo-db-data:
4 |
5 | services:
6 | db:
7 | image: kartoza/postgis:17-3.5
8 | volumes:
9 | - geo-db-data:/var/lib/postgresql
10 | - ./tests/init.sql:/docker-entrypoint-initdb.d/init.sql
11 | environment:
12 | - POSTGRES_DB=gis
13 | - POSTGRES_USER=docker
14 | - POSTGRES_PASS=docker
15 | - ALLOW_IP_RANGE=0.0.0.0/0
16 | - FORCE_SSL=FALSE
17 | restart: on-failure
18 | healthcheck:
19 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker"
20 | master:
21 | image: 'kartoza/geoserver:${TAG:-manual-build}'
22 | volumes:
23 | - geoserver-cluster-data:/opt/geoserver/data_dir
24 | - ./tests:/tests
25 | environment:
26 | - BROKER_URL=tcp://0.0.0.0:61661
27 | - READONLY=disabled
28 | - CLUSTER_DURABILITY=false
29 | - CLUSTERING=True
30 | - TOGGLE_MASTER=true
31 | - TOGGLE_SLAVE=true
32 | - DB_BACKEND=POSTGRES
33 | - HOST=db
34 | - POSTGRES_PORT=5432
35 | - POSTGRES_DB=gis
36 | - POSTGRES_USER=docker
37 | - POSTGRES_PASS=docker
38 | - SSL_MODE=allow
39 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
40 | - GEOSERVER_ADMIN_USER=admin
41 | - CONSOLE_HANDLER_LEVEL=WARNING
42 | - TEST_CLASS=test_clustering_master.GeoServerClusteringMaster
43 | ports:
44 | - "8081:8080"
45 | restart: on-failure
46 | depends_on:
47 | db:
48 | condition: service_healthy
49 | healthcheck:
50 | test: "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u admin:'myawesomegeoserver' http://localhost:8080/geoserver/rest/about/version.xml"
51 | interval: 1m30s
52 | timeout: 10s
53 | retries: 3
54 | node:
55 | image: 'kartoza/geoserver:${TAG:-manual-build}'
56 | volumes:
57 | - geoserver-cluster-data:/opt/geoserver/data_dir
58 | - ./tests:/tests
59 | environment:
60 | - BROKER_URL=tcp://master:61661
61 | - READONLY=disabled
62 | - CLUSTER_DURABILITY=false
63 | - CLUSTERING=True
64 | - TOGGLE_MASTER=true
65 | - TOGGLE_SLAVE=true
66 | - EMBEDDED_BROKER=disabled
67 | - HOST=db
68 | - POSTGRES_PORT=5432
69 | - POSTGRES_DB=gis
70 | - POSTGRES_USER=docker
71 | - POSTGRES_PASS=docker
72 | - SSL_MODE=allow
73 | - GEOSERVER_ADMIN_PASSWORD=myawesomegeoserver
74 | - GEOSERVER_ADMIN_USER=admin
75 | - CONSOLE_HANDLER_LEVEL=WARNING
76 | - TEST_CLASS=test_clustering_node.GeoServerClusteringNode
77 | ports:
78 | - "8082:8080"
79 | restart: on-failure
80 | depends_on:
81 | master:
82 | condition: service_started
83 | db:
84 | condition: service_healthy
85 | healthcheck:
86 | test: ["CMD-SHELL","curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u admin:'myawesomegeoserver' http://localhost:8080/geoserver/rest/about/version.xml"]
87 | interval: 1m30s
88 | timeout: 10s
89 | retries: 3
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/scenario_tests/clustering/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ################################
11 | #Test using internal jms cluster
12 | ################################
13 | echo -e "------------------------------------------------------"
14 | echo -e "[Unit Test] Running testing using internal: JMS plugin"
15 |
16 | ${VERSION} -f docker-compose.yml up -d
17 |
18 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
19 | ${VERSION} -f docker-compose.yml logs -f &
20 | fi
21 |
22 |
23 | # Test Master
24 | services=("master")
25 |
26 | for service in "${services[@]}"; do
27 |
28 | # Execute tests
29 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
30 | test_url_availability http://localhost:8081/geoserver/rest/about/version.xml
31 | echo "Execute test for $service"
32 | ${VERSION} -f docker-compose.yml exec "${service}" /bin/bash /tests/test.sh
33 |
34 | done
35 |
36 | # Test Node
37 | services=("node")
38 |
39 | for service in "${services[@]}"; do
40 |
41 | # Execute tests
42 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
43 | test_url_availability http://localhost:8082/geoserver/rest/about/version.xml
44 | echo "Execute test for $service"
45 | ${VERSION} -f docker-compose.yml exec "${service}" /bin/bash /tests/test.sh
46 |
47 | done
48 |
49 | ${VERSION} -f docker-compose.yml down -v
50 |
51 | #############################
52 | #Test using external ActiveMQ
53 | #############################
54 |
55 | echo -e "------------------------------------------------------"
56 | echo -e "[Unit Test] Running testing using internal: ActiveMQ"
57 |
58 | ${VERSION} -f docker-compose-external.yml up -d
59 |
60 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
61 | ${VERSION} -f docker-compose-external.yml logs -f &
62 | fi
63 |
64 |
65 |
66 | # Test Master
67 | services=("master")
68 |
69 | for service in "${services[@]}"; do
70 |
71 | # Execute tests
72 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
73 | test_url_availability http://localhost:8081/geoserver/rest/about/version.xml
74 | echo -e "\e[32m ---------------------------------------- \033[0m"
75 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
76 | ${VERSION} -f docker-compose-external.yml exec "${service}" /bin/bash /tests/test.sh
77 |
78 | done
79 |
80 | # Test Node
81 | services=("node")
82 |
83 | for service in "${services[@]}"; do
84 |
85 | # Execute tests
86 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
87 | test_url_availability http://localhost:8082/geoserver/rest/about/version.xml
88 | echo -e "\e[32m ---------------------------------------- \033[0m"
89 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
90 | ${VERSION} -f docker-compose-external.yml exec "${service}" /bin/bash /tests/test.sh
91 |
92 | done
93 |
94 | ${VERSION} -f docker-compose-external.yml down -v
--------------------------------------------------------------------------------
/scenario_tests/clustering/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/clustering/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/clustering/tests/init.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS states (
2 | id integer not null
3 | constraint pkey primary key,
4 | geom geometry(Point, 4326),
5 | name varchar(30),
6 | alias varchar(30),
7 | description varchar(255)
8 | );
9 |
10 | INSERT INTO states (id, geom, name, alias, description)
11 | VALUES
12 | (
13 | 1,
14 | st_setsrid(st_point(107.6097, 6.9120), 4326),
15 | 'Bandung',
16 | 'Paris van Java',
17 | 'Asia-Africa conference was held here'
18 | ) ON CONFLICT DO NOTHING;
19 |
20 |
21 |
--------------------------------------------------------------------------------
/scenario_tests/clustering/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/clustering/tests/test_clustering_master.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from os import environ
3 |
4 | from geo.Geoserver import Geoserver
5 | from requests import get, post, exceptions
6 | from requests.auth import HTTPBasicAuth
7 | from shutil import copy
8 |
9 |
10 | class GeoServerClusteringMaster(unittest.TestCase):
11 |
12 | def setUp(self):
13 | # Define the GeoServer URL
14 | self.gs_url = 'http://localhost:8080/geoserver'
15 | # Define the PostGIS JNDI store name
16 | self.store_name = 'gis'
17 | self.geo_username = environ.get('GEOSERVER_ADMIN_USER', 'admin')
18 | self.geo_password = environ.get('GEOSERVER_ADMIN_PASSWORD', 'myawesomegeoserver')
19 | self.geo_workspace_name = 'demo'
20 |
21 | def test_publish_store(self):
22 | geo = Geoserver(self.gs_url, username='%s' % self.geo_username, password='%s' % self.geo_password)
23 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
24 | # create workspace
25 | geo.create_workspace(workspace='%s' % self.geo_workspace_name)
26 | geo.set_default_workspace('%s' % self.geo_workspace_name)
27 |
28 | # Create the XML payload for the JNDI store configuration
29 | xml = """
30 |
31 | {name}
32 | PostGIS
33 | true
34 |
35 | db
36 | 5432
37 | gis
38 | docker
39 | docker
40 | public
41 | true
42 | 1000
43 | true
44 | false
45 | true
46 | 1
47 | false
48 | FAST
49 | postgis
50 | true
51 | ALLOW
52 |
53 | false
54 |
55 | """.format(name=self.store_name)
56 |
57 | # Publish the store
58 | response = post(self.gs_url + '/rest/workspaces/%s/datastores' % self.geo_workspace_name, auth=auth,
59 | headers={'Content-type': 'text/xml'},
60 | data=xml)
61 |
62 | # Check that the response has a status code of 201 (Created)
63 | self.assertEqual(response.status_code, 201)
64 |
65 | # Check that the store exists
66 | data_source_url = '%s/rest/workspaces/%s/datastores/%s.json' % (
67 | self.gs_url, self.geo_workspace_name, self.store_name)
68 | response = get(data_source_url, auth=auth)
69 |
70 | # Check that the response has a status code of 200 (OK)
71 | self.assertEqual(response.status_code, 200)
72 |
73 | # Publish layer into GeoServer
74 | geo.publish_featurestore(workspace='%s'
75 | % self.geo_workspace_name, store_name='%s' % self.store_name,
76 | pg_table='states')
77 | copy("/usr/local/tomcat/data/styles/default_point.sld", "/usr/local/tomcat/data/styles/states.sld")
78 | layer_sld_file = "/usr/local/tomcat/data/styles/states.sld"
79 | geo.upload_style(path=str(layer_sld_file), workspace=self.geo_workspace_name)
80 | geo.publish_style(layer_name='states', style_name='states', workspace=self.geo_workspace_name)
81 | self.assertEqual(response.status_code, 200)
82 |
83 | # Check that the layer exists
84 | layer_url = '%s/rest/workspaces/%s/layers/states.json' % (
85 | self.gs_url, self.geo_workspace_name)
86 | response = get(layer_url, auth=auth)
87 |
88 | # Check that the response has a status code of 200 (OK)
89 | self.assertEqual(response.status_code, 200)
90 |
91 |
92 | if __name__ == '__main__':
93 | unittest.main()
94 |
--------------------------------------------------------------------------------
/scenario_tests/clustering/tests/test_clustering_node.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from os import environ
3 | from requests import get, exceptions
4 | from requests.auth import HTTPBasicAuth
5 |
6 |
7 | class GeoServerClusteringNode(unittest.TestCase):
8 |
9 | def setUp(self):
10 | # Define the GeoServer URL
11 | self.gs_url = 'http://localhost:8080/geoserver'
12 | # Define the PostGIS store name
13 | self.store_name = 'gis'
14 | self.geo_username = environ.get('GEOSERVER_ADMIN_USER', 'admin')
15 | self.geo_password = environ.get('GEOSERVER_ADMIN_PASSWORD', 'myawesomegeoserver')
16 | self.geo_workspace_name = 'demo'
17 |
18 | def check_workspace_exists(self, auth):
19 | rest_url = '%s/rest/workspaces/%s.json' % (self.gs_url, self.geo_workspace_name)
20 | response = get(rest_url, auth=auth)
21 | return response.status_code == 200
22 |
23 | def check_data_store_exists(self, auth):
24 | data_source_url = '%s/rest/workspaces/%s/datastores/%s.json' % (
25 | self.gs_url, self.geo_workspace_name, self.store_name)
26 | response = get(data_source_url, auth=auth)
27 | return response.status_code == 200
28 |
29 | def check_layer_exists(self, auth, layer_name):
30 | layer_url = '%s/rest/workspaces/%s/layers/%s.json' % (
31 | self.gs_url, self.geo_workspace_name, layer_name)
32 | response = get(layer_url, auth=auth)
33 | return response.status_code == 200
34 |
35 | def check_style_exists(self, auth, layer_name):
36 | style_url = '%s/rest/workspaces/%s/styles/%s.json' % (
37 | self.gs_url, self.geo_workspace_name, layer_name)
38 | response = get(style_url, auth=auth)
39 | return response.status_code == 200
40 |
41 | def test_workspace_exists(self):
42 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
43 | workspace_exists = self.check_workspace_exists(auth)
44 | self.assertTrue(workspace_exists, "Workspace does not exist")
45 |
46 | def test_data_store_exists(self):
47 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
48 | data_store_exists = self.check_data_store_exists(auth)
49 | self.assertTrue(data_store_exists, "Data store does not exist")
50 |
51 | def test_layer_exists(self):
52 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
53 | layer_name = 'states'
54 | layer_exists = self.check_layer_exists(auth, layer_name)
55 | self.assertTrue(layer_exists, "Layer does not exist")
56 |
57 | def test_layer_style_exists(self):
58 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
59 | layer_name = 'states'
60 | layer_exists = self.check_style_exists(auth, layer_name)
61 | self.assertTrue(layer_exists, "Style does not exist")
62 |
63 |
64 | if __name__ == '__main__':
65 | unittest.main()
66 |
--------------------------------------------------------------------------------
/scenario_tests/context/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 |
5 |
6 | services:
7 | geoserver:
8 | image: 'kartoza/geoserver:${TAG:-manual-build}'
9 | restart: 'always'
10 | volumes:
11 | - geoserver-data-dir:/opt/geoserver/data_dir
12 | - ./tests:/tests
13 | ports:
14 | - "8080:8080"
15 | environment:
16 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
17 | GEOSERVER_ADMIN_USER: admin
18 | INITIAL_MEMORY: 2G
19 | MAXIMUM_MEMORY: 4G
20 | GEOSERVER_CONTEXT_ROOT: foobar
21 | CONSOLE_HANDLER_LEVEL: WARNING
22 | TEST_CLASS: test_context.TestGeoServerREST
23 | healthcheck:
24 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/foobar/rest/about/version.xml"]
25 | interval: 1m30s
26 | timeout: 10s
27 | retries: 3
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/scenario_tests/context/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ####################################
11 | #Test using default created password
12 | #####################################
13 | echo -e "[Unit Test] Running GEOSERVER_CONTEXT_ROOT tests with GEOSERVER_CONTEXT_ROOT set to foobar"
14 |
15 | ${VERSION} up -d
16 |
17 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
18 | ${VERSION} logs -f &
19 | fi
20 |
21 |
22 | # Set default values
23 | PASS="myawesomegeoserver"
24 | USER="admin"
25 |
26 | services=("geoserver")
27 |
28 | for service in "${services[@]}"; do
29 |
30 |
31 | # Execute tests
32 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
33 | test_url_availability http://localhost:8080/foobar/rest/about/version.xml "$PASS" "$USER"
34 | echo "Execute test for $service"
35 | ${VERSION} exec -T "${service}" /bin/bash /tests/test.sh
36 |
37 | done
38 |
39 | ${VERSION} down -v
40 |
41 | ####################################
42 | #Test using updated password
43 | #####################################
44 | echo -e "[Unit Test] Running GEOSERVER_CONTEXT_ROOT tests with GEOSERVER_CONTEXT_ROOT set to foobar#geoserver"
45 | sed -i 's/foobar/foobar#geoserver/g' docker-compose.yml
46 | # Bring the services up again
47 | ${VERSION} up -d geoserver
48 |
49 | services=("geoserver")
50 |
51 | for service in "${services[@]}"; do
52 |
53 | # Execute tests
54 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
55 | test_url_availability http://localhost:8080/foobar/geoserver/rest/about/version.xml "$PASS" "$USER"
56 | echo -e "\e[32m ---------------------------------------- \033[0m"
57 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
58 | ${VERSION} exec -T "${service}" /bin/bash /tests/test.sh
59 |
60 | done
61 |
62 | ${VERSION} down -v
63 | sed -i 's/foobar#geoserver/foobar/g' docker-compose.yml
--------------------------------------------------------------------------------
/scenario_tests/context/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/context/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/context/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/context/tests/test_context.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import unittest
3 | from os import environ
4 |
5 |
6 | class TestGeoServerREST(unittest.TestCase):
7 |
8 | def setUp(self):
9 | # Login to GeoServer and get the authentication cookies
10 | self.geo_context = environ.get('GEOSERVER_CONTEXT_ROOT').replace("#", '/')
11 | self.base_url = f'http://localhost:8080/{self.geo_context}'
12 | self.login_url = f'{self.base_url}/j_spring_security_check'
13 | self.password = environ['GEOSERVER_ADMIN_PASSWORD']
14 |
15 | self.session = requests.Session()
16 | login_data = {
17 | 'username': 'admin',
18 | 'password': self.password,
19 | 'submit': 'Login'
20 | }
21 | response = self.session.post(self.login_url, data=login_data)
22 | self.assertEqual(response.status_code, 200)
23 |
24 | def test_rest_endpoints_accessible(self):
25 | # Test if the REST endpoints are accessible as a logged user
26 | url = f'{self.base_url}/rest/workspaces.json'
27 | response = self.session.get(url)
28 | self.assertEqual(response.status_code, 200)
29 | self.assertTrue(response.json())
30 |
31 | def tearDown(self):
32 | # Logout from GeoServer
33 | logout_url = f'{self.base_url}/j_spring_security_logout'
34 | response = self.session.post(logout_url)
35 | self.assertEqual(response.status_code, 200)
36 |
--------------------------------------------------------------------------------
/scenario_tests/disk-quota/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 | postgis-data:
5 |
6 |
7 | services:
8 | db:
9 | image: kartoza/postgis:17-3.5
10 | volumes:
11 | - postgis-data:/var/lib/postgresql
12 | environment:
13 | - POSTGRES_DB=gis,gwc
14 | - POSTGRES_USER=docker
15 | - POSTGRES_PASS=docker
16 | - ALLOW_IP_RANGE=0.0.0.0/0
17 | - POSTGRES_MULTIPLE_EXTENSIONS=postgis,hstore,postgis_topology,postgis_raster,pgrouting
18 | - RUN_AS_ROOT=true
19 | - FORCE_SSL=TRUE
20 | restart: on-failure
21 | healthcheck:
22 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker"
23 |
24 | geoserver:
25 | image: 'kartoza/geoserver:${TAG:-manual-build}'
26 | restart: 'always'
27 | volumes:
28 | - geoserver-data-dir:/opt/geoserver/data_dir
29 | - ./tests:/tests
30 | environment:
31 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
32 | GEOSERVER_ADMIN_USER: admin
33 | INITIAL_MEMORY: 2G
34 | MAXIMUM_MEMORY: 4G
35 | HOST: db
36 | POSTGRES_DB: gwc
37 | POSTGRES_USER: docker
38 | POSTGRES_PASS: docker
39 | POSTGRES_PORT: 5432
40 | SSL_MODE: allow
41 | POSTGRES_SCHEMA: public
42 | DISK_QUOTA_SIZE: 5
43 | DB_BACKEND: POSTGRES
44 | SAMPLE_DATA: true
45 | CONSOLE_HANDLER_LEVEL: WARNING
46 | TEST_CLASS: test_disk_quota.TestGeoServerDISKQUOTA
47 | depends_on:
48 | db:
49 | condition: service_healthy
50 | ports:
51 | - "8080:8080"
52 | healthcheck:
53 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
54 | interval: 1m30s
55 | timeout: 10s
56 | retries: 3
57 |
58 |
59 |
--------------------------------------------------------------------------------
/scenario_tests/disk-quota/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ${VERSION} -f docker-compose.yml up -d
11 |
12 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
13 | ${VERSION} -f docker-compose.yml logs -f &
14 | fi
15 |
16 |
17 |
18 |
19 | services=("geoserver")
20 |
21 | for service in "${services[@]}"; do
22 |
23 | # Execute tests
24 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
25 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
26 | echo -e "\e[32m ---------------------------------------- \033[0m"
27 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
28 | ${VERSION} -f docker-compose.yml exec $service /bin/bash /tests/test.sh
29 |
30 | done
31 |
32 | ${VERSION} -f docker-compose.yml down -v
33 |
--------------------------------------------------------------------------------
/scenario_tests/disk-quota/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/disk-quota/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/disk-quota/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/disk-quota/tests/test_disk_quota.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from os import environ
3 | from psycopg2 import connect, OperationalError
4 |
5 |
6 | class TestGeoServerDISKQUOTA(unittest.TestCase):
7 |
8 | def setUp(self):
9 | self.db_schema = environ.get('POSTGRES_SCHEMA', 'public')
10 | try:
11 | self.db_conn = connect(
12 | dbname=environ.get('POSTGRES_DB', 'gis'),
13 | user=environ.get('POSTGRES_USER', 'docker'),
14 | password=environ.get('POSTGRES_PASS', 'docker'),
15 | host=environ.get('HOST', 'db'),
16 | port=environ.get('POSTGRES_PORT', 5432),
17 | sslmode=environ.get('SSL_MODE', 'allow')
18 | )
19 | except OperationalError as e:
20 | self.fail(f"Failed to connect to the database: {e}")
21 |
22 | def test_seed_vector_layer(self):
23 |
24 | with self.db_conn.cursor() as cursor:
25 | query = "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tilepage' \
26 | and table_schema = '%s');" % self.db_schema
27 | cursor.execute(query)
28 | table_exists = cursor.fetchone()[0]
29 | self.assertTrue(table_exists, "Table 'tilepage' does not exist")
30 |
31 | def tearDown(self):
32 | self.db_conn.close()
33 |
34 |
35 | if __name__ == '__main__':
36 | unittest.main()
37 |
--------------------------------------------------------------------------------
/scenario_tests/gwc/docker-compose-gwc.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | volumes:
4 | geoserver-data-dir:
5 |
6 | services:
7 |
8 | geoserver:
9 | image: 'kartoza/geoserver:${TAG:-manual-build}'
10 | restart: 'always'
11 | volumes:
12 | - geoserver-data-dir:/opt/geoserver/data_dir
13 | - ./tests:/tests
14 | environment:
15 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
16 | GEOSERVER_ADMIN_USER: admin
17 | INITIAL_MEMORY: 2G
18 | MAXIMUM_MEMORY: 4G
19 | RECREATE_DATADIR: TRUE
20 | SAMPLE_DATA: true
21 | CONSOLE_HANDLER_LEVEL: WARNING
22 | TEST_CLASS: test_gwc.TestGeoServerGWC
23 | ports:
24 | - "8080:8080"
25 | healthcheck:
26 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
27 | interval: 1m30s
28 | timeout: 10s
29 | retries: 3
30 |
31 |
32 |
--------------------------------------------------------------------------------
/scenario_tests/gwc/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ${VERSION} -f docker-compose-gwc.yml up -d
11 |
12 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
13 | ${VERSION} -f docker-compose-gwc.yml logs -f &
14 | fi
15 |
16 |
17 |
18 |
19 | services=("geoserver")
20 |
21 | for service in "${services[@]}"; do
22 |
23 | # Execute tests
24 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
25 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
26 | ${VERSION} -f docker-compose-gwc.yml ps
27 | echo -e "\e[32m ---------------------------------------- \033[0m"
28 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
29 | ${VERSION} -f docker-compose-gwc.yml exec $service /bin/bash /tests/test.sh
30 |
31 | done
32 |
33 | ${VERSION} -f docker-compose-gwc.yml down -v
34 |
--------------------------------------------------------------------------------
/scenario_tests/gwc/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/gwc/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/gwc/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/gwc/tests/test_gwc.py:
--------------------------------------------------------------------------------
1 | import time
2 | import unittest
3 | from os import environ, remove
4 | from PIL import Image
5 | from requests import get, post
6 | from requests.auth import HTTPBasicAuth
7 |
8 |
9 | class TestGeoServerGWC(unittest.TestCase):
10 |
11 | def setUp(self):
12 | # Define the GeoServer URL
13 | self.gs_url = 'http://localhost:8080/geoserver'
14 | self.store_name = 'states_shapefile'
15 | self.geo_username = environ.get('GEOSERVER_ADMIN_USER', 'admin')
16 | self.geo_password = environ.get('GEOSERVER_ADMIN_PASSWORD', 'myawesomegeoserver')
17 | self.geo_workspace_name = 'topp'
18 |
19 | def test_seed_vector_layer(self):
20 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
21 |
22 | # Seed the vector layer
23 |
24 | layer_name = '%s:states' % self.geo_workspace_name
25 | gwc_url = f'{self.gs_url}/gwc/rest/seed/%s.xml' % layer_name
26 |
27 | # Set the GWC seed request parameters
28 | headers = {'Content-type': 'text/xml'}
29 | data = '%s43261' \
30 | '6image/pngseed2' \
31 | 'cql_filter:STATE_ABBR=\'TX\'' % layer_name
32 |
33 | post(gwc_url, headers=headers, data=data, auth=auth)
34 |
35 | time.sleep(30)
36 | wms_request = f'{self.gs_url}/ows?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=31.31110495617180689,\
37 | -101.7342329829540404,32.41516971387711976,-99.82891832338629001&CRS=EPSG:4326&WIDTH=1564&HEIGHT=906\
38 | &LAYERS=%s&STYLES=&FORMAT=image/png&DPI=96 &TILED=true \
39 | &MAP_RESOLUTION=96&FORMAT_OPTIONS=dpi:96&TRANSPARENT=TRUE' % layer_name
40 | response = get(wms_request)
41 |
42 | # Save the response as a JPEG file
43 | with open('output.png', 'wb') as f:
44 | f.write(response.content)
45 |
46 | try:
47 | img = Image.open('output.png')
48 | img.verify()
49 | valid_image = True
50 | except (IOError, Image.DecompressionBombError):
51 | valid_image = False
52 | remove('output.png')
53 |
54 | # Verify that the seeding was successful
55 | self.assertEqual(response.status_code, 200)
56 | self.assertTrue(valid_image)
57 |
58 |
59 | if __name__ == '__main__':
60 | unittest.main()
61 |
--------------------------------------------------------------------------------
/scenario_tests/jdbconfig/docker-compose-postgis-jndi.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 | postgis-data:
5 |
6 |
7 | services:
8 | db:
9 | image: kartoza/postgis:17-3.5
10 | volumes:
11 | - postgis-data:/var/lib/postgresql
12 | environment:
13 | - POSTGRES_DB=gis
14 | - POSTGRES_USER=docker
15 | - POSTGRES_PASS=docker
16 | - ALLOW_IP_RANGE=0.0.0.0/0
17 | - POSTGRES_MULTIPLE_EXTENSIONS=postgis,hstore,postgis_topology,postgis_raster,pgrouting
18 | - RUN_AS_ROOT=true
19 | restart: on-failure
20 | healthcheck:
21 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker"
22 |
23 | geoserver:
24 | image: 'kartoza/geoserver:${TAG:-manual-build}'
25 | restart: 'always'
26 | volumes:
27 | - geoserver-data-dir:/opt/geoserver/data_dir
28 | - ./tests:/tests
29 | environment:
30 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
31 | GEOSERVER_ADMIN_USER: admin
32 | INITIAL_MEMORY: 2G
33 | MAXIMUM_MEMORY: 4G
34 | POSTGRES_JNDI: TRUE
35 | POSTGRES_PORT: 5432
36 | HOST: db
37 | POSTGRES_DB: gis
38 | POSTGRES_USER: docker
39 | POSTGRES_PASS: docker
40 | RECREATE_DATADIR: TRUE
41 | CONSOLE_HANDLER_LEVEL: WARNING
42 | SAMPLE_DATA: true
43 | DB_BACKEND: POSTGRES
44 | COMMUNITY_EXTENSIONS: jdbcconfig-plugin,jdbcstore-plugin
45 | TEST_CLASS: test_jdbconfig.TestGeoServerJDBCONFIG
46 | depends_on:
47 | db:
48 | condition: service_healthy
49 | ports:
50 | - "8080:8080"
51 | healthcheck:
52 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
53 | interval: 1m30s
54 | timeout: 10s
55 | retries: 3
56 |
57 |
58 |
--------------------------------------------------------------------------------
/scenario_tests/jdbconfig/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 | postgis-data:
5 |
6 |
7 | services:
8 | db:
9 | image: kartoza/postgis:17-3.5
10 | volumes:
11 | - postgis-data:/var/lib/postgresql
12 | environment:
13 | - POSTGRES_DB=gis,gwc
14 | - POSTGRES_USER=docker
15 | - POSTGRES_PASS=docker
16 | - ALLOW_IP_RANGE=0.0.0.0/0
17 | - POSTGRES_MULTIPLE_EXTENSIONS=postgis,hstore,postgis_topology,postgis_raster,pgrouting
18 | - RUN_AS_ROOT=true
19 | - FORCE_SSL=TRUE
20 | restart: on-failure
21 | healthcheck:
22 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker"
23 |
24 | geoserver:
25 | image: 'kartoza/geoserver:${TAG:-manual-build}'
26 | restart: 'always'
27 | volumes:
28 | - geoserver-data-dir:/opt/geoserver/data_dir
29 | - ./tests:/tests
30 | environment:
31 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
32 | GEOSERVER_ADMIN_USER: admin
33 | HOST: db
34 | POSTGRES_DB: gis
35 | POSTGRES_USER: docker
36 | POSTGRES_PASS: docker
37 | POSTGRES_PORT: 5432
38 | SSL_MODE: allow
39 | POSTGRES_SCHEMA: public
40 | DISK_QUOTA_SIZE: 5
41 | DB_BACKEND: POSTGRES
42 | SAMPLE_DATA: true
43 | CONSOLE_HANDLER_LEVEL: WARNING
44 | COMMUNITY_EXTENSIONS: jdbcconfig-plugin,jdbcstore-plugin
45 | TEST_CLASS: test_jdbconfig.TestGeoServerJDBCONFIG
46 | depends_on:
47 | db:
48 | condition: service_healthy
49 | ports:
50 | - "8080:8080"
51 | healthcheck:
52 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
53 | interval: 1m30s
54 | timeout: 10s
55 | retries: 3
56 |
57 |
58 |
--------------------------------------------------------------------------------
/scenario_tests/jdbconfig/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 |
11 | ${VERSION} -f docker-compose.yml up -d
12 |
13 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
14 | ${VERSION} -f docker-compose.yml logs -f &
15 | fi
16 |
17 |
18 |
19 |
20 | services=("geoserver")
21 |
22 | for service in "${services[@]}"; do
23 |
24 | # Execute tests
25 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
26 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
27 | echo -e "\e[32m ---------------------------------------- \033[0m"
28 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
29 | ${VERSION} -f docker-compose.yml exec $service /bin/bash /tests/test.sh
30 |
31 | done
32 |
33 | ${VERSION} -f docker-compose.yml down -v
34 |
35 |
36 | #JNDI
37 | ${VERSION} -f docker-compose-postgis-jndi.yml up -d
38 |
39 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
40 | ${VERSION} -f docker-compose-postgis-jndi.yml logs -f &
41 | fi
42 |
43 |
44 |
45 |
46 | services=("geoserver")
47 |
48 | for service in "${services[@]}"; do
49 |
50 | # Execute tests
51 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
52 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
53 | echo -e "\e[32m ---------------------------------------- \033[0m"
54 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
55 | ${VERSION} -f docker-compose-postgis-jndi.yml exec $service /bin/bash /tests/test.sh
56 |
57 | done
58 |
59 | ${VERSION} -f docker-compose-postgis-jndi.yml down -v
--------------------------------------------------------------------------------
/scenario_tests/jdbconfig/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/jdbconfig/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/jdbconfig/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/jdbconfig/tests/test_jdbconfig.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from os import environ, remove
3 | from psycopg2 import connect, OperationalError
4 | from requests import get
5 | from PIL import Image
6 |
7 |
8 | class TestGeoServerJDBCONFIG(unittest.TestCase):
9 |
10 | def setUp(self):
11 | self.gs_url = 'http://localhost:8080/geoserver'
12 | try:
13 | self.db_conn = connect(
14 | dbname=environ.get('POSTGRES_DB', 'gis'),
15 | user=environ.get('POSTGRES_USER', 'docker'),
16 | password=environ.get('POSTGRES_PASS', 'docker'),
17 | host=environ.get('HOST', 'db'),
18 | port=environ.get('POSTGRES_PORT', 5432),
19 | sslmode=environ.get('SSL_MODE', 'allow')
20 | )
21 | except OperationalError as e:
22 | self.fail(f"Failed to connect to the database: {e}")
23 |
24 | def test_seed_vector_layer(self):
25 |
26 | with self.db_conn.cursor() as cursor:
27 | query = "SELECT EXISTS (SELECT 1 FROM workspace WHERE name = 'topp');"
28 | cursor.execute(query)
29 | table_exists = cursor.fetchone()[0]
30 | self.assertTrue(table_exists, "Workspace 'topp' does not exist")
31 | wms_request = f'{self.gs_url}/ows?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=31.31110495617180689,\
32 | -101.7342329829540404,32.41516971387711976,-99.82891832338629001&CRS=EPSG:4326&WIDTH=1564&HEIGHT=906\
33 | &LAYERS=topp:states&STYLES=&FORMAT=image/png&DPI=96 &TILED=true \
34 | &MAP_RESOLUTION=96&FORMAT_OPTIONS=dpi:96&TRANSPARENT=TRUE'
35 | response = get(wms_request)
36 | with open('output.png', 'wb') as f:
37 | f.write(response.content)
38 |
39 | try:
40 | img = Image.open('output.png')
41 | img.verify()
42 | valid_image = True
43 | except (IOError, Image.DecompressionBombError):
44 | valid_image = False
45 | remove('output.png')
46 |
47 | # Verify that the seeding was successful
48 | self.assertEqual(response.status_code, 200)
49 | self.assertTrue(valid_image)
50 |
51 | def tearDown(self):
52 | self.db_conn.close()
53 |
54 |
55 | if __name__ == '__main__':
56 | unittest.main()
57 |
--------------------------------------------------------------------------------
/scenario_tests/libjpeg/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 |
5 | services:
6 |
7 | geoserver:
8 | image: 'kartoza/geoserver:${TAG:-manual-build}'
9 | restart: 'always'
10 | volumes:
11 | - geoserver-data-dir:/opt/geoserver/data_dir
12 | - ./tests:/tests
13 | environment:
14 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
15 | GEOSERVER_ADMIN_USER: admin
16 | INITIAL_MEMORY: 2G
17 | MAXIMUM_MEMORY: 4G
18 | SAMPLE_DATA: true
19 | CONSOLE_HANDLER_LEVEL: WARNING
20 | TEST_CLASS: test_libjpeg.TestGeoServerTURBO
21 | ports:
22 | - "8080:8080"
23 | healthcheck:
24 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
25 | interval: 1m30s
26 | timeout: 10s
27 | retries: 3
28 |
29 |
30 |
--------------------------------------------------------------------------------
/scenario_tests/libjpeg/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ${VERSION} -f docker-compose.yml up -d
11 |
12 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
13 | ${VERSION} -f docker-compose.yml logs -f &
14 | fi
15 |
16 |
17 |
18 |
19 | services=("geoserver")
20 |
21 | for service in "${services[@]}"; do
22 |
23 | # Execute tests
24 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
25 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
26 | ${VERSION} -f docker-compose.yml ps
27 | echo -e "\e[32m ---------------------------------------- \033[0m"
28 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
29 | ${VERSION} -f docker-compose.yml exec $service /bin/bash /tests/test.sh
30 |
31 | done
32 |
33 | ${VERSION} -f docker-compose.yml down -v
34 |
--------------------------------------------------------------------------------
/scenario_tests/libjpeg/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/libjpeg/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/libjpeg/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/libjpeg/tests/test_libjpeg.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from requests import get
3 | from parameterized import parameterized
4 | from PIL import Image
5 | from os import remove
6 |
7 | class TestGeoServerTURBO(unittest.TestCase):
8 |
9 | def setUp(self):
10 | # Define the GeoServer URL
11 | self.gs_url = 'http://localhost:8080/geoserver'
12 | self.geo_workspace_name = 'topp'
13 |
14 | @parameterized.expand([
15 | ('jpeg',),
16 | ('vnd.jpeg-png',),
17 | ('vnd.jpeg-png8',),
18 | ])
19 | def test_wms_vector_layer(self, output):
20 | layer_name = '%s:states' % self.geo_workspace_name
21 | wms_request = f'{self.gs_url}/ows?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=31.31110495617180689,\
22 | -101.7342329829540404,32.41516971387711976,-99.82891832338629001&CRS=EPSG:4326&WIDTH=1564&HEIGHT=906\
23 | &LAYERS=%s&STYLES=&FORMAT=image/%s&DPI=96 &TILED=true \
24 | &MAP_RESOLUTION=96&FORMAT_OPTIONS=dpi:96&TRANSPARENT=TRUE' % (layer_name, output)
25 | response = get(wms_request)
26 |
27 | # Save the response as a JPEG file
28 | with open('output.jpg', 'wb') as f:
29 | f.write(response.content)
30 |
31 | try:
32 | img = Image.open('output.jpg')
33 | img.verify()
34 | valid_image = True
35 | except (IOError, Image.DecompressionBombError):
36 | valid_image = False
37 | remove('output.jpg')
38 | # Verify that the wms request was successful
39 | self.assertEqual(response.status_code, 200)
40 | self.assertTrue(valid_image)
41 |
42 |
43 | if __name__ == '__main__':
44 | unittest.main()
45 |
--------------------------------------------------------------------------------
/scenario_tests/logging_profile/assets/logging.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | GEOSERVER_DEVELOPER_LOGGING
4 | /opt/geoserver/data_dir/logs/geoserver.log
5 | true
6 |
7 |
8 |
--------------------------------------------------------------------------------
/scenario_tests/logging_profile/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir-one:
4 | geoserver-data-dir-two:
5 | geoserver-data-dir-three:
6 |
7 |
8 | services:
9 | geoserver_one:
10 | image: 'kartoza/geoserver:${TAG:-manual-build}'
11 | restart: 'always'
12 | volumes:
13 | - geoserver-data-dir-one:/opt/geoserver/data_dir
14 | - ./tests:/tests
15 | - ./assets/logging.xml:/opt/geoserver/data_dir/logging.xml
16 | environment:
17 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
18 | GEOSERVER_ADMIN_USER: admin
19 | EXPECTED_LOGGING_PROFILE: GEOSERVER_DEVELOPER_LOGGING
20 | INITIAL_MEMORY: 2G
21 | MAXIMUM_MEMORY: 4G
22 | CONTAINER_NAME: geoserver_one
23 | CONSOLE_HANDLER_LEVEL: WARNING
24 | ports:
25 | - "8081:8080"
26 | healthcheck:
27 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
28 | interval: 1m30s
29 | timeout: 10s
30 | retries: 3
31 |
32 | geoserver_two:
33 | image: 'kartoza/geoserver:${TAG:-manual-build}'
34 | restart: 'always'
35 | volumes:
36 | - geoserver-data-dir-two:/opt/geoserver/data_dir
37 | - ./tests:/tests
38 | environment:
39 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
40 | GEOSERVER_ADMIN_USER: admin
41 | GEOSERVER_LOG_PROFILE: VERBOSE_LOGGING
42 | EXPECTED_LOGGING_PROFILE: VERBOSE_LOGGING
43 | INITIAL_MEMORY: 2G
44 | MAXIMUM_MEMORY: 4G
45 | CONTAINER_NAME: geoserver_two
46 | CONSOLE_HANDLER_LEVEL: WARNING
47 | ports:
48 | - "8082:8080"
49 | healthcheck:
50 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$$(cat /opt/geoserver/data_dir/security/pass.txt) http://localhost:8080/geoserver/rest/about/version.xml"]
51 | interval: 1m30s
52 | timeout: 10s
53 | retries: 3
54 |
55 | geoserver_three:
56 | image: 'kartoza/geoserver:${TAG:-manual-build}'
57 | restart: 'always'
58 | volumes:
59 | - geoserver-data-dir-three:/opt/geoserver/data_dir
60 | - ./tests:/tests
61 | environment:
62 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
63 | GEOSERVER_ADMIN_USER: admin
64 | EXPECTED_LOGGING_PROFILE: DEFAULT_LOGGING
65 | INITIAL_MEMORY: 2G
66 | MAXIMUM_MEMORY: 4G
67 | CONTAINER_NAME: geoserver_three
68 | CONSOLE_HANDLER_LEVEL: WARNING
69 | ports:
70 | - "8083:8080"
71 | healthcheck:
72 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$$(cat /opt/geoserver/data_dir/security/pass.txt) http://localhost:8080/geoserver/rest/about/version.xml"]
73 | interval: 1m30s
74 | timeout: 10s
75 | retries: 3
76 |
77 |
--------------------------------------------------------------------------------
/scenario_tests/logging_profile/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ${VERSION} up -d
11 |
12 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
13 | ${VERSION} logs -f &
14 | fi
15 |
16 | services=("geoserver_one" "geoserver_two" "geoserver_three")
17 | for index in "${!services[@]}"; do
18 | read service <<< "${services[$index]}"
19 | PORT="808$((index +1))"
20 |
21 | sleep 30
22 | test_url_availability http://localhost:$PORT/geoserver/rest/about/version.xml
23 | echo "Execute test for $service"
24 | ${VERSION} exec -T $service /bin/bash /tests/test.sh
25 |
26 | done
27 |
28 | ${VERSION} down -v
--------------------------------------------------------------------------------
/scenario_tests/logging_profile/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source /scripts/env-data.sh
4 |
5 | set -euo pipefail
6 |
7 | # Ensure EXPECTED is set
8 | : "${EXPECTED_LOGGING_PROFILE:?EXPECTED_LOGGING_PROFILE environment variable must be set}"
9 |
10 | # Extract value between ... using sed
11 | level=$(sed -n 's:.*\(.*\).*:\1:p' "${GEOSERVER_DATA_DIR}"/logging.xml)
12 |
13 | # Compare and fail if not equal
14 | if [[ "$level" != "$EXPECTED_LOGGING_PROFILE" ]]; then
15 | echo "ERROR: Logging profile level mismatch at $CONTAINER_NAME. Found: '$level', EXPECTED_LOGGING_PROFILE: '$EXPECTED_LOGGING_PROFILE'" >&2
16 | exit 1
17 | fi
18 |
19 | echo "PASS: Test case passed at $CONTAINER_NAME. Logging profile level matches EXPECTED_LOGGING_PROFILE value: $level"
20 |
--------------------------------------------------------------------------------
/scenario_tests/logging_profile/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 03-Apr-2025 22:47
4 | 2.27.0
5 | 22e0b4aa0f2bc5f01c649ba0418ba3242c5fcbf0
6 |
7 |
8 | 02-Apr-2025 15:59
9 | 33.0
10 | 2f4be07eaece931a7f6f3cd2b903a95e4ef3a41f
11 |
12 |
13 | 1.27.0
14 | 230de11bf247f7e6ac994c7383ba6b4958fddcdf/230de11bf247f7e6ac994c7383ba6b4958fddcdf
15 |
16 |
--------------------------------------------------------------------------------
/scenario_tests/login/docker-compose.yml:
--------------------------------------------------------------------------------
1 |
2 | services:
3 | geoserver:
4 | image: 'kartoza/geoserver:${TAG:-manual-build}'
5 | restart: 'always'
6 | volumes:
7 | - ./tests:/tests
8 | environment:
9 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
10 | GEOSERVER_ADMIN_USER: admin
11 | INITIAL_MEMORY: 2G
12 | MAXIMUM_MEMORY: 4G
13 | CONTAINER_NAME: geoserver
14 | CONSOLE_HANDLER_LEVEL: WARNING
15 | TEST_CLASS: test_login.TestGeoServerREST
16 | ports:
17 | - "8081:8080"
18 | healthcheck:
19 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
20 | interval: 1m30s
21 | timeout: 10s
22 | retries: 3
23 |
24 | server:
25 | image: 'kartoza/geoserver:${TAG:-manual-build}'
26 | restart: 'always'
27 | volumes:
28 | - ./tests:/tests
29 | environment:
30 | GEOSERVER_ADMIN_USER: admin
31 | INITIAL_MEMORY: 2G
32 | MAXIMUM_MEMORY: 4G
33 | CONTAINER_NAME: server
34 | CONSOLE_HANDLER_LEVEL: WARNING
35 | TEST_CLASS: test_login.TestGeoServerREST
36 | ports:
37 | - "8082:8080"
38 | healthcheck:
39 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$$(cat /opt/geoserver/data_dir/security/pass.txt) http://localhost:8080/geoserver/rest/about/version.xml"]
40 | interval: 1m30s
41 | timeout: 10s
42 | retries: 3
43 |
44 | credentials:
45 | image: 'kartoza/geoserver:${TAG:-manual-build}'
46 | restart: 'always'
47 | volumes:
48 | - ./tests:/tests
49 | environment:
50 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
51 | GEOSERVER_ADMIN_USER: myadmin
52 | INITIAL_MEMORY: 2G
53 | MAXIMUM_MEMORY: 4G
54 | CONTAINER_NAME: credentials
55 | CONSOLE_HANDLER_LEVEL: WARNING
56 | TEST_CLASS: test_login.TestGeoServerREST
57 | ports:
58 | - "8083:8080"
59 | healthcheck:
60 | test: [ "CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml" ]
61 | interval: 1m30s
62 | timeout: 10s
63 | retries: 3
64 |
65 |
--------------------------------------------------------------------------------
/scenario_tests/login/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 | ${VERSION} up -d
11 |
12 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
13 | ${VERSION} logs -f &
14 | fi
15 |
16 |
17 | services=("geoserver" "server" "credentials")
18 | START_PORT=8081
19 |
20 | for i in "${!services[@]}"; do
21 | service="${services[$i]}"
22 | PORT=$((START_PORT + i))
23 |
24 | # Set default values
25 | PASS="myawesomegeoserver"
26 | USER="admin"
27 |
28 | # Service-specific overrides
29 | if [[ "$service" == "server" ]]; then
30 | PASS=$(docker compose exec server cat /opt/geoserver/data_dir/security/pass.txt)
31 | elif [[ "$service" == "credentials" ]]; then
32 | USER="myadmin"
33 | fi
34 |
35 | sleep 30
36 | echo -e "[Unit Test] Test URL availability for: \e[1;31m $service \033[0m"
37 | test_url_availability "http://localhost:$PORT/geoserver/rest/about/version.xml" "$PASS" "$USER"
38 |
39 | echo -e "\e[32m ---------------------------------------- \033[0m"
40 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
41 | ${VERSION} exec -T "$service" /bin/bash /tests/test.sh
42 | done
43 |
44 | ${VERSION} down -v
45 |
46 |
--------------------------------------------------------------------------------
/scenario_tests/login/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/login/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/login/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/login/tests/test_login.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import unittest
3 | from os import environ
4 |
5 |
6 | class TestGeoServerREST(unittest.TestCase):
7 |
8 | def setUp(self):
9 | # Login to GeoServer and get the authentication cookies
10 | self.base_url = 'http://localhost:8080/geoserver'
11 | self.login_url = f'{self.base_url}/j_spring_security_check'
12 | self.container_name = environ['CONTAINER_NAME']
13 |
14 | if self.container_name == 'geoserver':
15 | self.password = environ['GEOSERVER_ADMIN_PASSWORD']
16 | self.username = 'admin'
17 | elif self.container_name == 'credentials':
18 | self.password = environ['GEOSERVER_ADMIN_PASSWORD']
19 | self.username = 'myadmin'
20 | elif self.container_name == 'server':
21 | self.username = 'admin'
22 | with open('/opt/geoserver/data_dir/security/pass.txt', 'r') as file:
23 | file_pass = file.read()
24 | self.password = file_pass.replace("\n", "")
25 | self.session = requests.Session()
26 | login_data = {
27 | 'username': self.username,
28 | 'password': self.password,
29 | 'submit': 'Login'
30 | }
31 | response = self.session.post(self.login_url, data=login_data)
32 | self.assertEqual(response.status_code, 200)
33 |
34 | def test_rest_endpoints_accessible(self):
35 | # Test if the REST endpoints are accessible as a logged user
36 | url = f'{self.base_url}/rest/workspaces.json'
37 | response = self.session.get(url)
38 | self.assertEqual(response.status_code, 200)
39 | self.assertTrue(response.json())
40 |
41 | def tearDown(self):
42 | # Logout from GeoServer
43 | logout_url = f'{self.base_url}/j_spring_security_logout'
44 | response = self.session.post(logout_url)
45 | self.assertEqual(response.status_code, 200)
46 |
--------------------------------------------------------------------------------
/scenario_tests/stores/docker-compose-gdal.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 |
5 | services:
6 |
7 | geoserver:
8 | image: 'kartoza/geoserver:${TAG:-manual-build}'
9 | restart: 'always'
10 | volumes:
11 | - geoserver-data-dir:/opt/geoserver/data_dir
12 | - ./tests:/tests
13 | environment:
14 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
15 | GEOSERVER_ADMIN_USER: admin
16 | CONSOLE_HANDLER_LEVEL: WARNING
17 | TEST_CLASS: test_gdal.TestGeoServerGDAL
18 | ports:
19 | - "8080:8080"
20 | healthcheck:
21 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
22 | interval: 1m30s
23 | timeout: 10s
24 | retries: 3
25 |
26 |
27 |
--------------------------------------------------------------------------------
/scenario_tests/stores/docker-compose-postgis-jndi.yml:
--------------------------------------------------------------------------------
1 |
2 | volumes:
3 | geoserver-data-dir:
4 | postgis-data:
5 |
6 |
7 | services:
8 | db:
9 | image: kartoza/postgis:17-3.5
10 | volumes:
11 | - postgis-data:/var/lib/postgresql
12 | environment:
13 | - POSTGRES_DB=gis
14 | - POSTGRES_USER=docker
15 | - POSTGRES_PASS=docker
16 | - ALLOW_IP_RANGE=0.0.0.0/0
17 | - POSTGRES_MULTIPLE_EXTENSIONS=postgis,hstore,postgis_topology,postgis_raster,pgrouting
18 | - RUN_AS_ROOT=true
19 | restart: on-failure
20 | healthcheck:
21 | test: "PGPASSWORD=docker pg_isready -h 127.0.0.1 -U docker"
22 |
23 | geoserver:
24 | image: 'kartoza/geoserver:${TAG:-manual-build}'
25 | restart: 'always'
26 | volumes:
27 | - geoserver-data-dir:/opt/geoserver/data_dir
28 | - ./tests:/tests
29 | environment:
30 | GEOSERVER_ADMIN_PASSWORD: myawesomegeoserver
31 | GEOSERVER_ADMIN_USER: admin
32 | INITIAL_MEMORY: 2G
33 | MAXIMUM_MEMORY: 4G
34 | POSTGRES_JNDI: TRUE
35 | HOST: db
36 | POSTGRES_DB: gis
37 | POSTGRES_USER: docker
38 | POSTGRES_PASS: docker
39 | RECREATE_DATADIR: TRUE
40 | CONSOLE_HANDLER_LEVEL: WARNING
41 | TEST_CLASS: test_jndi.TestGeoServerJNDI
42 | depends_on:
43 | db:
44 | condition: service_healthy
45 | ports:
46 | - "8080:8080"
47 | healthcheck:
48 | test: ["CMD-SHELL", "curl --fail --silent --write-out 'HTTP CODE : %{http_code}\n' --output /dev/null -u $${GEOSERVER_ADMIN_USER}:$${GEOSERVER_ADMIN_PASSWORD} http://localhost:8080/geoserver/rest/about/version.xml"]
49 | interval: 1m30s
50 | timeout: 10s
51 | retries: 3
52 |
53 |
54 |
--------------------------------------------------------------------------------
/scenario_tests/stores/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit immediately if test fails
4 | set -e
5 |
6 | source ../test-env.sh
7 |
8 | # Run service
9 |
10 |
11 | # JNDI store
12 | ${VERSION} -f docker-compose-postgis-jndi.yml up -d
13 |
14 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
15 | ${VERSION} -f docker-compose-postgis-jndi.yml logs -f &
16 | fi
17 |
18 |
19 |
20 | services=("geoserver")
21 |
22 | for service in "${services[@]}"; do
23 |
24 | # Execute tests
25 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
26 | echo -e "\e[32m ---------------------------------------- \033[0m"
27 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
28 | ${VERSION} -f docker-compose-postgis-jndi.yml exec $service /bin/bash /tests/test.sh
29 |
30 | done
31 |
32 | ${VERSION} -f docker-compose-postgis-jndi.yml down -v
33 |
34 | # Run GDAL
35 | ${VERSION} -f docker-compose-gdal.yml up -d
36 |
37 | if [[ -n "${PRINT_TEST_LOGS}" ]]; then
38 | ${VERSION} -f docker-compose-gdal.yml logs -f &
39 | fi
40 |
41 |
42 |
43 |
44 | services=("geoserver")
45 |
46 | for service in "${services[@]}"; do
47 |
48 | # Execute tests
49 | test_url_availability http://localhost:8080/geoserver/rest/about/version.xml
50 | echo -e "\e[32m ---------------------------------------- \033[0m"
51 | echo -e "[Unit Test] Execute test for: \e[1;31m $service \033[0m"
52 | ${VERSION} -f docker-compose-gdal.yml exec $service /bin/bash /tests/test.sh
53 |
54 | done
55 |
56 | ${VERSION} -f docker-compose-gdal.yml down -v
57 |
--------------------------------------------------------------------------------
/scenario_tests/stores/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kartoza/docker-geoserver/664140445e0e1591662734410663450553b650fb/scenario_tests/stores/tests/__init__.py
--------------------------------------------------------------------------------
/scenario_tests/stores/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | source /scripts/env-data.sh
6 |
7 | # execute tests
8 | pushd /tests
9 |
10 | cat << EOF
11 | Settings used:
12 |
13 | GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_ADMIN_PASSWORD}
14 | GEOSERVER_ADMIN_USER: ${GEOSERVER_ADMIN_USER}
15 | EOF
16 |
17 | python3 -m unittest -v ${TEST_CLASS}
18 |
--------------------------------------------------------------------------------
/scenario_tests/stores/tests/test_gdal.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from os import environ, chown
3 | from subprocess import check_call
4 | from requests import get, post, exceptions
5 | from requests.auth import HTTPBasicAuth
6 | from geo.Geoserver import Geoserver
7 |
8 |
9 | class TestGeoServerGDAL(unittest.TestCase):
10 |
11 | def setUp(self):
12 | # Define the GeoServer URL
13 | self.gs_url = 'http://localhost:8080/geoserver'
14 | self.store_name = 'sfdem'
15 | self.geo_username = environ.get('GEOSERVER_ADMIN_USER', 'admin')
16 | self.geo_password = environ.get('GEOSERVER_ADMIN_PASSWORD', 'myawesomegeoserver')
17 | self.geo_workspace_name = 'kartoza'
18 | self.geo_data_dir = '/usr/local/tomcat/data/data/sf'
19 |
20 | def test_publish_gdal_store(self):
21 | # Generate tiles
22 | built_vrt = f'gdalbuildvrt {self.geo_data_dir}/sfdem.vrt {self.geo_data_dir}/sfdem.tif'
23 | check_call(built_vrt, shell=True)
24 | vrt_path = f'{self.geo_data_dir}/sfdem.vrt'
25 | chown(vrt_path, 1000, 1000)
26 |
27 | geo = Geoserver(self.gs_url, username=self.geo_username, password=self.geo_password)
28 |
29 | auth = HTTPBasicAuth(self.geo_username, self.geo_password)
30 |
31 | # Create a workspace if it doesn't exist
32 |
33 | geo.create_workspace(workspace=self.geo_workspace_name)
34 | geo.set_default_workspace(self.geo_workspace_name)
35 |
36 | # Create a GDAL store
37 | store_data = f'''
38 |
39 | {self.store_name}
40 | {self.geo_workspace_name}
41 | true
42 | VRT
43 |
44 | '''
45 | store_url = f'{self.gs_url}/rest/workspaces/{self.geo_workspace_name}/coveragestores'
46 | response = post(store_url, data=store_data, auth=auth, headers={'Content-Type': 'application/xml'})
47 | self.assertEqual(response.status_code, 201)
48 |
49 | # Upload the VRT file to the store
50 | vrt_upload_url = f'{self.gs_url}/rest/workspaces/{self.geo_workspace_name}/coveragestores/{self.store_name}/external.vrt?configure=first&coverageName={self.store_name}'
51 | curl_command = f'curl -u {self.geo_username}:{self.geo_password} -v -XPUT -H "Content-type: text/plain" -d "file:{vrt_path}" {vrt_upload_url}'
52 | check_call(curl_command, shell=True)
53 |
54 | # Check that the published layer exists
55 | layer_source_url = f'{self.gs_url}/{self.geo_workspace_name}/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/jpeg&TRANSPARENT=true&STYLES&LAYERS={self.geo_workspace_name}:{self.store_name}&exceptions=application/vnd.ogc.se_inimage&SRS=EPSG:26713&WIDTH=768&HEIGHT=578&BBOX=594739.7048312925,4919224.415741393,602069.4450795503,4924731.264860202'
56 | response = get(layer_source_url)
57 |
58 | # Check that the response has a status code of 200 (OK)
59 | self.assertEqual(response.status_code, 200)
60 |
61 |
62 | if __name__ == '__main__':
63 | unittest.main()
64 |
--------------------------------------------------------------------------------
/scenario_tests/stores/tests/test_jndi.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from os import environ
3 |
4 | from geo.Geoserver import Geoserver
5 | from requests import get, post, exceptions, delete
6 | from requests.auth import HTTPBasicAuth
7 | from subprocess import check_call
8 |
9 |
10 | class TestGeoServerJNDI(unittest.TestCase):
11 |
12 | def setUp(self):
13 | # Define the GeoServer URL
14 | self.gs_url = 'http://localhost:8080/geoserver'
15 | # Define the PostGIS JNDI store name
16 | self.jndi_store_name = 'gis'
17 | self.geo_username = environ.get('GEOSERVER_ADMIN_USER', 'admin')
18 | self.geo_password = environ.get('GEOSERVER_ADMIN_PASSWORD', 'myawesomegeoserver')
19 | self.geo_workspace_name = 'demo'
20 |
21 | def test_publish_jndi_store(self):
22 |
23 | # Import shp into DB
24 | db_importer = '''ogr2ogr -progress -append -skipfailures -a_srs "EPSG:4326" -nlt PROMOTE_TO_MULTI \
25 | -f "PostgreSQL" PG:"dbname=gis port=5432 user=docker password=docker host=db" \
26 | /usr/local/tomcat/data/data/shapefiles/states.shp '''
27 | check_call(db_importer, shell=True)
28 |
29 | geo = Geoserver(self.gs_url, username='%s' % self.geo_username, password='%s' % self.geo_password)
30 |
31 | auth = HTTPBasicAuth('%s' % self.geo_username, '%s' % self.geo_password)
32 | # create workspace
33 | geo.create_workspace(workspace='%s' % self.geo_workspace_name)
34 | geo.set_default_workspace('%s' % self.geo_workspace_name)
35 |
36 | # Create the XML payload for the JNDI store configuration
37 | xml = """
38 |
39 | {name}
40 | PostGIS (JNDI)
41 | true
42 |
43 | public
44 | true
45 | 1000
46 | true
47 | false
48 | true
49 | 1
50 | false
51 | FAST
52 | java:comp/env/jdbc/postgres
53 | postgis
54 | true
55 |
56 | false
57 |
58 | """.format(name=self.jndi_store_name)
59 |
60 | # Publish the JNDI store
61 | response = post(self.gs_url + '/rest/workspaces/%s/datastores' % self.geo_workspace_name, auth=auth,
62 | headers={'Content-type': 'text/xml'},
63 | data=xml)
64 |
65 | # Publish layer into geoserver
66 | geo.publish_featurestore(workspace='%s'
67 | % self.geo_workspace_name, store_name='%s' % self.jndi_store_name,
68 | pg_table='states')
69 | # Check that the response has a status code of 201 (Created)
70 | self.assertEqual(response.status_code, 201)
71 |
72 | # Check that the JNDI store exists
73 | data_source_url = '%s/rest/workspaces/%s/datastores/%s.json' % (
74 | self.gs_url, self.geo_workspace_name, self.jndi_store_name)
75 | response = get(data_source_url, auth=auth)
76 |
77 | # Check that the response has a status code of 200 (OK)
78 | self.assertEqual(response.status_code, 200)
79 |
80 |
81 | if __name__ == '__main__':
82 | unittest.main()
83 |
--------------------------------------------------------------------------------
/scenario_tests/test-env.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Display test environment variable
4 |
5 | cat << EOF
6 | Test environment:
7 |
8 | Compose Project : ${COMPOSE_PROJECT_NAME}
9 | Compose File : ${COMPOSE_PROJECT_FILE}
10 | Image tag : ${TAG}
11 |
12 | EOF
13 |
14 |
15 | export VERSION='docker compose'
16 |
17 |
18 | function test_url_availability() {
19 | URL=$1
20 | PASS=$2
21 | USERNAME=$3
22 | if [ -z "$2" ]; then
23 | PASS=myawesomegeoserver
24 | fi
25 | if [ -z "$2" ]; then
26 | USERNAME=admin
27 | fi
28 | timeout=300
29 | start_time=$(date +%s)
30 |
31 | while true; do
32 | current_time=$(date +%s)
33 | elapsed_time=$((current_time - start_time))
34 |
35 | if [ $elapsed_time -ge $timeout ]; then
36 | echo "Timeout reached. Exiting trying to connect to service endpoint."
37 | exit 1
38 | fi
39 |
40 |
41 |
42 | result=$(wget -S --user ${USERNAME} --password ${PASS} --max-redirect=0 ${URL} 2>&1 | grep "HTTP/1.1 " | tail -n 1 | awk '{print $2}')
43 |
44 | if [[ $result -eq 200 ]]; then
45 | echo "Rest endpoint ${URL} is accessible with the provided credentials ${USERNAME} and password ${PASS}"
46 | if [[ -f version.xml ]];then
47 | rm version.xml
48 | fi
49 | break
50 | else
51 | echo "Access to ${URL}, with credentials username ${USERNAME} and password ${PASS} did not succeed, retrying in 5 seconds"
52 | sleep 5
53 | fi
54 | done
55 |
56 | }
57 |
58 |
59 |
--------------------------------------------------------------------------------
/scenario_tests/utils/requirements.txt:
--------------------------------------------------------------------------------
1 | geoserver-rest
2 | psycopg2-binary
3 | requests
4 | parameterized
5 | pillow
6 |
--------------------------------------------------------------------------------
/scripts/setup.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Download geoserver extensions and other resources
3 |
4 | source /scripts/env-data.sh
5 | source /scripts/functions.sh
6 |
7 | resources_dir="/tmp/resources"
8 | GS_VERSION=$(cat /scripts/geoserver_version.txt)
9 | create_dir ${resources_dir}/plugins/gdal
10 | create_dir /usr/share/fonts/opentype
11 | create_dir /tomcat_apps
12 | create_dir "${CATALINA_HOME}"/postgres_config
13 | create_dir "${STABLE_PLUGINS_DIR}"
14 | create_dir "${COMMUNITY_PLUGINS_DIR}"
15 | create_dir "${GEOSERVER_HOME}"
16 | create_dir "${FONTS_DIR}"
17 | create_dir "${REQUIRED_PLUGINS_DIR}"
18 |
19 | pushd "${CATALINA_HOME}" || exit
20 |
21 |
22 | # Download geoserver and install it
23 | package_geoserver
24 |
25 | # Copy config files
26 | cp /build_data/stable_plugins.txt "${STABLE_PLUGINS_DIR}"
27 | cp /build_data/community_plugins.txt "${COMMUNITY_PLUGINS_DIR}"
28 | cp /build_data/letsencrypt-tomcat.xsl "${CATALINA_HOME}"/conf/ssl-tomcat.xsl
29 |
30 | pushd "${STABLE_PLUGINS_DIR}" || exit
31 |
32 | # Install libjpeg-turbo
33 | system_architecture=$(dpkg --print-architecture)
34 | # Fixes https://github.com/kartoza/docker-geoserver/issues/673
35 | libjpeg_version=2.1.5.1
36 | libjpeg_deb_name="libjpeg-turbo-official_${libjpeg_version}_${system_architecture}.deb"
37 | libjpeg_deb="${resources_dir}/${libjpeg_deb_name}"
38 | if [[ ! -f "${libjpeg_deb}" ]]; then
39 | curl -vfLo "${libjpeg_deb}" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/${libjpeg_version}/${libjpeg_deb_name}"
40 | fi
41 |
42 | dpkg -i "${libjpeg_deb}"
43 |
44 | pushd "${CATALINA_HOME}" || exit
45 |
46 | # Install Marlin render https://www.geocat.net/docs/geoserver-enterprise/2020.5/install/production/marlin.html
47 | cp ${REQUIRED_PLUGINS_DIR}/marlin.jar ${CATALINA_HOME}/lib/marlin.jar
48 |
49 | # Install jetty-servlets
50 | if [[ -f ${GEOSERVER_HOME}/start.jar ]]; then
51 | cp ${REQUIRED_PLUGINS_DIR}/jetty-servlets-11.0.9.jar "${GEOSERVER_HOME}"/webapps/"${GEOSERVER_CONTEXT_ROOT}"/WEB-INF/lib/
52 | fi
53 |
54 | # Install jetty-util
55 | if [[ -f ${GEOSERVER_HOME}/start.jar ]]; then
56 | cp ${REQUIRED_PLUGINS_DIR}/jetty-util.jar "${GEOSERVER_HOME}"/webapps/"${GEOSERVER_CONTEXT_ROOT}"/WEB-INF/lib/
57 | fi
58 |
59 | # Overlay files and directories in resources/overlays if they exist
60 | rm -f /tmp/resources/overlays/README.txt &&
61 | if ls /tmp/resources/overlays/* >/dev/null 2>&1; then
62 | cp -rf /tmp/resources/overlays/* /
63 | fi
64 |
65 |
66 | # Package tomcat webapps - useful to activate later
67 | if [[ -d "${CATALINA_HOME}"/webapps.dist ]]; then
68 | mv "${CATALINA_HOME}"/webapps.dist /tomcat_apps
69 | zip -r "${REQUIRED_PLUGINS_DIR}"/tomcat_apps.zip /tomcat_apps
70 | rm -r /tomcat_apps
71 | else
72 | cp -r "${CATALINA_HOME}"/webapps/ROOT /tomcat_apps
73 | cp -r "${CATALINA_HOME}"/webapps/docs /tomcat_apps
74 | cp -r "${CATALINA_HOME}"/webapps/examples /tomcat_apps
75 | cp -r "${CATALINA_HOME}"/webapps/host-manager /tomcat_apps
76 | cp -r "${CATALINA_HOME}"/webapps/manager /tomcat_apps
77 | zip -r "${REQUIRED_PLUGINS_DIR}"/tomcat_apps.zip /tomcat_apps
78 | rm -rf /tomcat_apps
79 | fi
80 |
81 | pushd ${CATALINA_HOME}/lib || exit
82 | create_dir org/apache/catalina/util/ && \
83 | unzip -j catalina.jar org/apache/catalina/util/ServerInfo.properties -d org/apache/catalina/util/ && \
84 | sed -i 's/server.info=.*/server.info=Apache Tomcat/g' org/apache/catalina/util/ServerInfo.properties && \
85 | zip -ur catalina.jar org/apache/catalina/util/ServerInfo.properties && rm -rf org
86 | # Setting restrictive umask container-wide
87 | echo "session optional pam_umask.so" >> /etc/pam.d/common-session && \
88 | sed -i 's/UMASK.*022/UMASK 007/g' /etc/login.defs
89 |
90 | pushd /scripts || exit
91 | # Delete resources after installation
92 | rm -rf /tmp/resources
93 |
94 | # Delete resources which will be setup on first run
95 | delete_file "${CATALINA_HOME}"/conf/web.xml
--------------------------------------------------------------------------------
/scripts/update_passwords.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Credits https://github.com/geosolutions-it/docker-geoserver for this script that allows a user to pass a password
4 | # or username on runtime.
5 |
6 | # Source the functions from other bash scripts
7 |
8 | source /scripts/env-data.sh
9 | source /scripts/functions.sh
10 |
11 | # Setup install directory
12 | GEOSERVER_INSTALL_DIR="$(detect_install_dir)"
13 |
14 |
15 |
16 | if [[ "${USE_DEFAULT_CREDENTIALS}" =~ [Ff][Aa][Ll][Ss][Ee] ]]; then
17 | USERS_XML=${USERS_XML:-${GEOSERVER_DATA_DIR}/security/usergroup/default/users.xml}
18 | ROLES_XML=${ROLES_XML:-${GEOSERVER_DATA_DIR}/security/role/default/roles.xml}
19 | CLASSPATH=${CLASSPATH:-${GEOSERVER_INSTALL_DIR}/webapps/${GEOSERVER_CONTEXT_ROOT}/WEB-INF/lib/}
20 |
21 | function password_reset() {
22 | if [[ ! -f ${EXTRA_CONFIG_DIR}/.security.lock ]];then
23 | cp -r ${CATALINA_HOME}/security ${GEOSERVER_DATA_DIR}
24 | sed -i '/false<\/readOnly>/a false<\/loginEnabled>' ${GEOSERVER_DATA_DIR}/security/config.xml
25 | touch ${EXTRA_CONFIG_DIR}/.security.lock
26 | else
27 | create_dir ${GEOSERVER_DATA_DIR}/security
28 | cp -r ${CATALINA_HOME}/security/role ${GEOSERVER_DATA_DIR}/security/
29 | cp -r ${CATALINA_HOME}/security/usergroup ${GEOSERVER_DATA_DIR}/security/
30 | cp -r ${CATALINA_HOME}/security/config.xml ${GEOSERVER_DATA_DIR}/security/
31 | fi
32 |
33 | # Set random password if none provided
34 | file_env 'GEOSERVER_ADMIN_PASSWORD'
35 | if [[ -z ${GEOSERVER_ADMIN_PASSWORD} ]]; then
36 | generate_random_string 15
37 | GEOSERVER_ADMIN_PASSWORD=${RAND}
38 | echo $GEOSERVER_ADMIN_PASSWORD >${GEOSERVER_DATA_DIR}/security/pass.txt
39 | if [[ ${SHOW_PASSWORD} =~ [Tt][Rr][Uu][Ee] ]];then
40 | echo -e "\e[32m -------------------------------------------------------------------------------- \033[0m"
41 | echo -e "[Entrypoint] GENERATED GeoServer Random PASSWORD is: \e[1;31m $GEOSERVER_ADMIN_PASSWORD \033[0m"
42 | fi
43 | echo "GEOSERVER_ADMIN_PASSWORD" >> /tmp/set_vars.txt
44 | unset RAND
45 | fi
46 |
47 | # Get current GeoServer admin user
48 | file_env GEOSERVER_ADMIN_USER
49 |
50 |
51 | export GEOSERVER_ADMIN_DEFAULT_USER='admin'
52 |
53 |
54 | # Get encrypted admin password
55 | #export GEOSERVER_ADMIN_DEFAULT_ENCRYPTED_PASSWORD="$(sed -n 's/.*password="\([^"]*\)".*/\1/p' ${USERS_XML})"
56 |
57 | export PWD_HASH=$(make_hash $GEOSERVER_ADMIN_PASSWORD $CLASSPATH $HASHING_ALGORITHM)
58 | ESCAPED_GEOSERVER_ADMIN_USER=$(printf '%s\n' "$GEOSERVER_ADMIN_USER" | sed 's/[&/\]/\\&/g')
59 | ESCAPED_PWD_HASH=$(printf '%s\n' "$PWD_HASH" | sed 's/[&/\]/\\&/g')
60 | sed -i "s/name=\"[^\"]*\"/name=\"$ESCAPED_GEOSERVER_ADMIN_USER\"/; s/password=\"[^\"]*\"/password=\"$ESCAPED_PWD_HASH\"/" $USERS_XML
61 |
62 | # Set password encoding
63 | sed -i 's/pbePasswordEncoder/strongPbePasswordEncoder/g' ${GEOSERVER_DATA_DIR}/security/config.xml
64 |
65 | # roles.xml setup
66 | cp $ROLES_XML $ROLES_XML.orig
67 | #
68 | cat $ROLES_XML.orig | sed -e "s/ username=\"${GEOSERVER_ADMIN_DEFAULT_USER}\"/ username=\"${GEOSERVER_ADMIN_USER}\"/" > $ROLES_XML
69 |
70 |
71 | } # end password reset
72 |
73 | if [[ -f ${USERS_XML} ]]; then
74 | user_count=$(grep -o '