diff --git a/config/confluence.cfg.cluster.xml.j2 b/config/confluence.cfg.cluster.xml.j2
new file mode 100644
index 0000000..c0b0132
--- /dev/null
+++ b/config/confluence.cfg.cluster.xml.j2
@@ -0,0 +1,16 @@
+
+
+
+ true
+ {{ atl_product_home_shared }}
+ {{ atl_product_home_shared }}
+ {{ atl_hazelcast_network_aws_iam_role }}
+ {{ atl_hazelcast_network_aws_iam_region }}
+ {{ atl_hazelcast_network_aws_host_header }}
+ {{ atl_hazelcast_network_aws_tag_key }}
+ {{ atl_hazelcast_network_aws_tag_value }}
+ aws
+ {{ atl_aws_stack_name }}
+ 1
+
+
diff --git a/config/confluence.cfg.db.xml.j2 b/config/confluence.cfg.db.xml.j2
new file mode 100644
index 0000000..c72b39f
--- /dev/null
+++ b/config/confluence.cfg.db.xml.j2
@@ -0,0 +1,19 @@
+
+
+
+ {{ atl_db_choice }}
+ {{ atl_db_dialect }}
+ {{ atl_db_driver }}
+ {{ atl_jdbc_url }}
+ {{ atl_jdbc_user }}
+ {{ atl_jdbc_password }}
+ {{ atl_db_poolminsize }}
+ {{ atl_db_poolmaxsize }}
+ {{ atl_db_timeout }}
+ {{ atl_db_idletestperiod }}
+ {{ atl_db_maxstatements }}
+ {{ atl_db_validate }}
+ {{ atl_db_acquireincrement }}
+ {{ atl_db_validationquery }}
+
+
diff --git a/config/confluence.cfg.head.xml.j2 b/config/confluence.cfg.head.xml.j2
new file mode 100644
index 0000000..521bfb8
--- /dev/null
+++ b/config/confluence.cfg.head.xml.j2
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ setupstart
+ custom
+ 0
+
+
+ database-type-standard
+ ${localHome}/temp
+ ${confluenceHome}/attachments
+
+
+
diff --git a/config/confluence.cfg.tail.xml.j2 b/config/confluence.cfg.tail.xml.j2
new file mode 100644
index 0000000..225be14
--- /dev/null
+++ b/config/confluence.cfg.tail.xml.j2
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/config/confluence.cfg.xml.j2 b/config/confluence.cfg.xml.j2
deleted file mode 100644
index 4b5368c..0000000
--- a/config/confluence.cfg.xml.j2
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- setupstart
- custom
- 0
-
-
- postgresql
- database-type-standard
- com.atlassian.confluence.impl.hibernate.dialect.PostgreSQLDialect
- ${localHome}/temp
- ${confluenceHome}/attachments
-
- {{ atl_db_driver }}
- {{ atl_jdbc_url }}
- {{ atl_jdbc_user }}
- {{ atl_jdbc_password }}
- {{ atl_db_poolminsize }}
- {{ atl_db_poolmaxsize }}
- {{ atl_db_timeout }}
- {{ atl_db_idletestperiod }}
- {{ atl_db_maxstatements }}
- {{ atl_db_validate }}
- {{ atl_db_acquireincrement }}
- select version();
-
- {{ atl_product_home_shared }}
- true
- {{ atl_product_home_shared }}
- {{ atl_hazelcast_network_aws_iam_role }}
- {{ atl_hazelcast_network_aws_iam_region }}
- {{ atl_hazelcast_network_aws_host_header }}
- {{ atl_hazelcast_network_aws_tag_key }}
- {{ atl_hazelcast_network_aws_tag_value }}
- aws
- {{ atl_aws_stack_name }}
- 1
-
-
-
diff --git a/entrypoint.sh b/entrypoint.sh
index ef4bc16..464e836 100755
--- a/entrypoint.sh
+++ b/entrypoint.sh
@@ -43,7 +43,58 @@ log "Generating ${CONFLUENCE_INSTALL_DIR}/conf/server.xml"
> ${CONFLUENCE_INSTALL_DIR}/conf/server.xml
######################################################################
-# Configure login properties
+# Confluence config files
+
+log "Generating ${CONFLUENCE_HOME}/confluence.cfg.xml"
+
+/opt/atlassian/bin/templater.sh \
+ /opt/atlassian/etc/confluence.cfg.head.xml.j2 \
+ > ${CONFLUENCE_HOME}/confluence.cfg.xml
+
+: ${ATL_JDBC_URL:=}
+if [[ ! -z "$ATL_JDBC_URL" ]]; then
+ declare -A databases=(
+ ["mysql-driver"]="com.mysql.jdbc.Driver"
+ ["mysql-dialect"]="com.atlassian.confluence.impl.hibernate.dialect.MySQLDialect"
+ ["postgresql-driver"]="org.postgresql.Driver"
+ ["postgresql-dialect"]="com.atlassian.confluence.impl.hibernate.dialect.PostgreSQLDialect"
+ ["mssql-driver"]="com.microsoft.sqlserver.jdbc.SQLServerDriver"
+ ["mssql-dialect"]="com.atlassian.confluence.impl.hibernate.dialect.SQLServerDialect"
+ ["oracle12c-driver"]="oracle.jdbc.driver.OracleDriver"
+ ["oracle12c-dialect"]="com.atlassian.confluence.impl.hibernate.dialect.OracleDialect"
+ )
+
+ # Must be supplied
+ export atl_jdbc_url=${ATL_JDBC_URL}
+ export atl_jdbc_user=${ATL_JDBC_USER}
+ export atl_jdbc_password=${ATL_JDBC_PASSWORD}
+ export atl_db_choice=${ATL_DB_TYPE}
+
+ export atl_db_driver=${databases[${atl_db_choice}"-driver"]}
+ export atl_db_dialect=${databases[${atl_db_choice}"-dialect"]}
+
+ # Defaults, can be overridden
+ export atl_db_poolmaxsize=${ATL_DB_POOLMAXSIZE:=100}
+ export atl_db_poolminsize=${ATL_DB_POOLMINSIZE:=20}
+ export atl_db_timeout=${ATL_DB_TIMEOUT:=30}
+ export atl_db_idletestperiod=${ATL_DB_IDLETESTPERIOD:=100}
+ export atl_db_maxstatements=${ATL_DB_MAXSTATEMENTS:=0}
+ export atl_db_validate=${ATL_DB_VALIDATE:=false}
+ export atl_db_acquireincrement=${ATL_DB_ACQUIREINCREMENT:=1}
+ export atl_db_validationquery=${ATL_DB_VALIDATIONQUERY:=select 1}
+
+ /opt/atlassian/bin/templater.sh \
+ /opt/atlassian/etc/confluence.cfg.db.xml.j2 \
+ >> ${CONFLUENCE_HOME}/confluence.cfg.xml
+
+fi
+
+/opt/atlassian/bin/templater.sh \
+ /opt/atlassian/etc/confluence.cfg.tail.xml.j2 \
+ >> ${CONFLUENCE_HOME}/confluence.cfg.xml
+chown ${RUN_USER}.${RUN_GROUP} ${CONFLUENCE_HOME}/confluence.cfg.xml
+chmod 0640 ${CONFLUENCE_HOME}/confluence.cfg.xml
+
# The default is two weeks, in seconds, same as the seraph default.
export atl_autologin_cookie_age=${ATL_AUTOLOGIN_COOKIE_AGE:=1209600}
@@ -54,6 +105,14 @@ log "Generating ${CONFLUENCE_INSTALL_DIR}/confluence/WEB-INF/classes/seraph-conf
> ${CONFLUENCE_INSTALL_DIR}/confluence/WEB-INF/classes/seraph-config.xml
+export atl_product_home=${CONFLUENCE_HOME}
+
+log "Generating ${CONFLUENCE_INSTALL_DIR}/confluence/WEB-INF/classes/confluence-init.properties"
+/opt/atlassian/bin/templater.sh \
+ /opt/atlassian/etc/confluence-init.properties.j2 \
+ > ${CONFLUENCE_INSTALL_DIR}/confluence/WEB-INF/classes/confluence-init.properties
+
+
# Start Confluence as the correct user
if [ "${UID}" -eq 0 ]; then
echo "User is currently root. Will change directory ownership to ${RUN_USER}:${RUN_GROUP}, then downgrade permission to ${RUN_USER}"
diff --git a/scripts/templater.sh b/scripts/templater.sh
index 2062369..f0855cc 100755
--- a/scripts/templater.sh
+++ b/scripts/templater.sh
@@ -16,6 +16,8 @@ vars=$(grep -oE '\{\{\s*[A-Za-z0-9_]+\s*\}\}' "$template" | sort | uniq | sed -e
if [[ -z "$vars" ]]; then
echo "Warning: No variable was found in $template, syntax is {{VAR}}" >&2
+ cat $template
+ exit
fi
var_value() {
diff --git a/tests/test_image.py b/tests/test_image.py
index 6283202..cfe3623 100644
--- a/tests/test_image.py
+++ b/tests/test_image.py
@@ -31,6 +31,16 @@ def wait_for_proc(container, proc_str, max_wait=10):
raise TimeoutError("Failed to find target process")
+def wait_for_file(container, path, max_wait=10):
+ waited = 0
+ while waited < max_wait:
+ if container.file(path).exists:
+ return
+ time.sleep(0.1)
+ waited += 0.1
+
+ raise TimeoutError("Failed to find target process")
+
######################################################################
# Tests
@@ -140,7 +150,7 @@ def test_server_xml_params(docker_cli, image):
def test_seraph_defaults(docker_cli, image):
container = run_image(docker_cli, image)
- _jvm = wait_for_proc(container, "org.apache.catalina.startup.Bootstrap")
+ wait_for_file(container, "/opt/atlassian/confluence/confluence/WEB-INF/classes/seraph-config.xml")
xml = etree.fromstring(container.file('/opt/atlassian/confluence/confluence/WEB-INF/classes/seraph-config.xml').content)
param = xml.xpath('//param-name[text()="autologin.cookie.age"]')[0].getnext()
@@ -149,7 +159,7 @@ def test_seraph_defaults(docker_cli, image):
def test_seraph_login_set(docker_cli, image):
container = run_image(docker_cli, image, environment={"ATL_AUTOLOGIN_COOKIE_AGE": "TEST_VAL"})
- _jvm = wait_for_proc(container, "org.apache.catalina.startup.Bootstrap")
+ wait_for_file(container, "/opt/atlassian/confluence/confluence/WEB-INF/classes/seraph-config.xml")
xml = etree.fromstring(container.file('/opt/atlassian/confluence/confluence/WEB-INF/classes/seraph-config.xml').content)
param = xml.xpath('//param-name[text()="autologin.cookie.age"]')[0].getnext()
@@ -158,26 +168,73 @@ def test_seraph_login_set(docker_cli, image):
def test_conf_init_set(docker_cli, image):
container = run_image(docker_cli, image, environment={"CONFLUENCE_HOME": "/tmp/"})
- _jvm = wait_for_proc(container, "org.apache.catalina.startup.Bootstrap")
+ wait_for_file(container, "/opt/atlassian/confluence/confluence/WEB-INF/classes/confluence-init.properties")
init = container.file('/opt/atlassian/confluence/confluence/WEB-INF/classes/confluence-init.properties')
assert init.contains("confluence.home = /tmp/")
-#
-# def test_confluence_cfg_xml_defaults(docker_cli, image):
-# environment = {
-#
-# }
-# container = docker_cli.containers.run(image, environment=environment, detach=True)
-# confluence_cfg_xml = get_fileobj_from_container(container, '/var/atlassian/application-data/confluence/confluence.cfg.xml')
-# xml = etree.parse(confluence_cfg_xml)
-#
-#
-# def test_confluence_cfg_xml_params(docker_cli, image):
-# environment = {
-#
-# }
-# container = docker_cli.containers.run(image, environment=environment, detach=True)
-# confluence_cfg_xml = get_fileobj_from_container(container, '/var/atlassian/application-data/confluence/confluence.cfg.xml')
-# xml = etree.parse(confluence_cfg_xml)
+def test_confluence_xml_default(docker_cli, image):
+ container = run_image(docker_cli, image)
+ wait_for_file(container, "/opt/atlassian/confluence/confluence/WEB-INF/classes/confluence-init.properties")
+ #_jvm = wait_for_proc(container, "org.apache.catalina.startup.Bootstrap")
+
+ xml = etree.fromstring(container.file('/var/atlassian/application-data/confluence/confluence.cfg.xml').content)
+ assert xml.xpath('/confluence-configuration/buildNumber')[0].text == "0"
+ assert xml.xpath('/confluence-configuration/properties/property[@name="hibernate.connection.url"]') == []
+
+def test_confluence_xml_postgres(docker_cli, image):
+ environment = {
+ 'ATL_DB_TYPE': 'postgresql',
+ 'ATL_JDBC_URL': 'atl_jdbc_url',
+ 'ATL_JDBC_USER': 'atl_jdbc_user',
+ 'ATL_JDBC_PASSWORD': 'atl_jdbc_password'
+ }
+ container = run_image(docker_cli, image, environment=environment)
+ wait_for_file(container, "/opt/atlassian/confluence/confluence/WEB-INF/classes/confluence-init.properties")
+
+ xml = etree.fromstring(container.file('/var/atlassian/application-data/confluence/confluence.cfg.xml').content)
+ assert xml.xpath('//property[@name="hibernate.connection.url"]')[0].text == "atl_jdbc_url"
+ assert xml.xpath('//property[@name="hibernate.connection.username"]')[0].text == "atl_jdbc_user"
+ assert xml.xpath('//property[@name="hibernate.connection.password"]')[0].text == "atl_jdbc_password"
+ assert xml.xpath('//property[@name="confluence.database.choice"]')[0].text == "postgresql"
+ assert xml.xpath('//property[@name="hibernate.dialect"]')[0].text == "com.atlassian.confluence.impl.hibernate.dialect.PostgreSQLDialect"
+ assert xml.xpath('//property[@name="hibernate.connection.driver_class"]')[0].text == "org.postgresql.Driver"
+
+ assert xml.xpath('//property[@name="hibernate.c3p0.min_size"]')[0].text == "20"
+ assert xml.xpath('//property[@name="hibernate.c3p0.max_size"]')[0].text == "100"
+ assert xml.xpath('//property[@name="hibernate.c3p0.timeout"]')[0].text == "30"
+ assert xml.xpath('//property[@name="hibernate.c3p0.idle_test_period"]')[0].text == "100"
+ assert xml.xpath('//property[@name="hibernate.c3p0.max_statements"]')[0].text == "0"
+ assert xml.xpath('//property[@name="hibernate.c3p0.validate"]')[0].text == "false"
+ assert xml.xpath('//property[@name="hibernate.c3p0.acquire_increment"]')[0].text == "1"
+ assert xml.xpath('//property[@name="hibernate.c3p0.preferredTestQuery"]')[0].text == "select 1"
+
+def test_confluence_xml_postgres_all_set(docker_cli, image):
+ environment = {
+ 'ATL_DB_TYPE': 'postgresql',
+ 'ATL_JDBC_URL': 'atl_jdbc_url',
+ 'ATL_JDBC_USER': 'atl_jdbc_user',
+ 'ATL_JDBC_PASSWORD': 'atl_jdbc_password',
+ 'ATL_DB_POOLMAXSIZE': 'x100',
+ 'ATL_DB_POOLMINSIZE': 'x20',
+ 'ATL_DB_TIMEOUT': 'x30',
+ 'ATL_DB_IDLETESTPERIOD': 'x100',
+ 'ATL_DB_MAXSTATEMENTS': 'x0',
+ 'ATL_DB_VALIDATE': 'xfalse',
+ 'ATL_DB_ACQUIREINCREMENT': 'x1',
+ 'ATL_DB_VALIDATIONQUERY': 'xselect 1'
+ }
+ container = run_image(docker_cli, image, environment=environment)
+ wait_for_file(container, "/opt/atlassian/confluence/confluence/WEB-INF/classes/confluence-init.properties")
+
+ xml = etree.fromstring(container.file('/var/atlassian/application-data/confluence/confluence.cfg.xml').content)
+
+ assert xml.xpath('//property[@name="hibernate.c3p0.min_size"]')[0].text == "x20"
+ assert xml.xpath('//property[@name="hibernate.c3p0.max_size"]')[0].text == "x100"
+ assert xml.xpath('//property[@name="hibernate.c3p0.timeout"]')[0].text == "x30"
+ assert xml.xpath('//property[@name="hibernate.c3p0.idle_test_period"]')[0].text == "x100"
+ assert xml.xpath('//property[@name="hibernate.c3p0.max_statements"]')[0].text == "x0"
+ assert xml.xpath('//property[@name="hibernate.c3p0.validate"]')[0].text == "xfalse"
+ assert xml.xpath('//property[@name="hibernate.c3p0.acquire_increment"]')[0].text == "x1"
+ assert xml.xpath('//property[@name="hibernate.c3p0.preferredTestQuery"]')[0].text == "xselect 1"