Add single SQL Server variant

sqlserver
Dan Caseley 2021-02-13 23:41:49 +00:00
parent fdd2932d3e
commit 864a0e0fd7
No known key found for this signature in database
GPG Key ID: 2D0A6EF1391F1F97
12 changed files with 477 additions and 2 deletions

3
.env
View File

@ -1 +1,2 @@
OPENFIRE_TAG=latest
OPENFIRE_TAG=latest
OPENFIRE_DB_TAG=v4.5.4

View File

@ -0,0 +1,60 @@
version: '3.7'
services:
db:
image: mcr.microsoft.com/mssql/server:2019-latest
ports:
- "1433:1433"
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=SecurePa55w0rd
- OPENFIRE_DB_TAG
volumes:
- ./scripts/sqlserver:/scripts:ro
- ./sql/sqlserver:/tmp/openfiredb
entrypoint: [ "/bin/bash", "-c", "/scripts/run-and-import-data.sh" ]
networks:
openfire-sqlserver-net:
ipv4_address: 172.70.0.11
lb:
image: nginx:stable
ports:
- "55222:55222"
- "57070:57070"
- "57443:57443"
volumes:
- ./nginx/clustered/nginx.conf:/etc/nginx/nginx.conf
networks:
openfire-sqlserver-net:
ipv4_address: 172.70.0.99
xmpp:
image: "openfire:${OPENFIRE_TAG}"
ports:
- "5222:5222"
- "5269:5269"
- "7070:7070"
- "7444:7443"
- "9090:9090"
depends_on:
- "db"
volumes:
- ./wait-for-it.sh:/wait-for-it.sh
- ./_data/xmpp/sqlserver/conf:/var/lib/openfire/conf
command: ["/wait-for-it.sh", "-t", "30", "-s", "db:1433", "--", "/sbin/entrypoint.sh"]
networks:
openfire-sqlserver-net:
ipv4_address: 172.70.0.10
extra_hosts:
- "xmpp.localhost.example:172.50.0.10"
- "conference.xmpp.localhost.example:172.50.0.10"
networks:
openfire-sqlserver-net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.70.0.0/24

View File

@ -0,0 +1,44 @@
#!/bin/bash
#set -euo pipefail
mkdir -p /tmp/openfiredb
DEFAULT_OPENFIRE_DB_TAG="v3.9.3"
DBURL_MODERN="https://raw.githubusercontent.com/igniterealtime/Openfire/$OPENFIRE_DB_TAG/distribution/src/database/openfire_sqlserver.sql"
DBURL_LEGACY="https://raw.githubusercontent.com/igniterealtime/Openfire/$OPENFIRE_DB_TAG/src/database/openfire_sqlserver.sql"
urlexists(){
wget --quiet --spider $1
}
if urlexists "$DBURL_MODERN"; then
DBURL=$DBURL_MODERN
elif urlexists "$DBURL_MODERN"; then
DBURL=$DBURL_LEGACY
else
echo "Could not find the bootstrap databse for the specified tag: $OPENFIRE_DB_TAG. Reverting to using tag: $DEFAULT_OPENFIRE_DB_TAG"
DBURL="https://raw.githubusercontent.com/igniterealtime/Openfire/$DEFAULT_OPENFIRE_DB_TAG/src/database/openfire_sqlserver.sql"
fi
echo "Downloading Openfire bootstrap database from $DBURL"
wget --quiet $DBURL --output-document=/tmp/openfiredb/openfire_sqlserver.sql
/opt/mssql/bin/sqlservr & #Start SQL Server`
/scripts/wait-for-it.sh -t 30 127.0.0.1:1433
for i in {1..50};
do
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$SA_PASSWORD" -d master -Q "CREATE DATABASE openfire;"
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$SA_PASSWORD" -d openfire -i /tmp/openfiredb/openfire_sqlserver.sql
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$SA_PASSWORD" -d openfire -i /tmp/openfiredb/openfire_data.sql
if [ $? -eq 0 ]
then
echo "Openfire data imported to SQL Server"
break
else
echo "not ready yet..."
sleep 1
fi
done
sleep infinity # Keep the container running forever

View File

@ -0,0 +1,184 @@
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
#Source: https://github.com/vishnubob/wait-for-it/blob/81b1373f17855a4dc21156cfe1694c31d7d1792e/wait-for-it.sh
WAITFORIT_cmdname=${0##*/}
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()
{
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
fi
WAITFORIT_start_ts=$(date +%s)
while :
do
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
WAITFORIT_result=$?
else
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
WAITFORIT_result=$?
fi
if [[ $WAITFORIT_result -eq 0 ]]; then
WAITFORIT_end_ts=$(date +%s)
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
break
fi
sleep 1
done
return $WAITFORIT_result
}
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
WAITFORIT_hostport=(${1//:/ })
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
shift 1
;;
--child)
WAITFORIT_CHILD=1
shift 1
;;
-q | --quiet)
WAITFORIT_QUIET=1
shift 1
;;
-s | --strict)
WAITFORIT_STRICT=1
shift 1
;;
-h)
WAITFORIT_HOST="$2"
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
WAITFORIT_HOST="${1#*=}"
shift 1
;;
-p)
WAITFORIT_PORT="$2"
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
WAITFORIT_PORT="${1#*=}"
shift 1
;;
-t)
WAITFORIT_TIMEOUT="$2"
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
WAITFORIT_TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
WAITFORIT_CLI=("$@")
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
# Check to see if timeout is from busybox?
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
WAITFORIT_BUSYTIMEFLAG=""
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
WAITFORIT_ISBUSY=1
# Check if busybox timeout uses -t flag
# (recent Alpine versions don't support -t anymore)
if timeout &>/dev/stdout | grep -q -e '-t '; then
WAITFORIT_BUSYTIMEFLAG="-t"
fi
else
WAITFORIT_ISBUSY=0
fi
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
wait_for
WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for
WAITFORIT_RESULT=$?
fi
fi
if [[ $WAITFORIT_CLI != "" ]]; then
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT
fi

View File

@ -0,0 +1,50 @@
-- This is a hand-fettled script, adding data as per a v30 database structure
insert [ofProperty] ([name],[propValue],[encrypted],[iv])
select 'passwordKey','c3rlwT7ijt1TqK6',0,NULL UNION ALL
select 'provider.admin.className','org.jivesoftware.openfire.admin.DefaultAdminProvider',0,NULL UNION ALL
select 'provider.auth.className','org.jivesoftware.openfire.auth.DefaultAuthProvider',0,NULL UNION ALL
select 'provider.group.className','org.jivesoftware.openfire.group.DefaultGroupProvider',0,NULL UNION ALL
select 'provider.lockout.className','org.jivesoftware.openfire.lockout.DefaultLockOutProvider',0,NULL UNION ALL
select 'provider.securityAudit.className','org.jivesoftware.openfire.security.DefaultSecurityAuditProvider',0,NULL UNION ALL
select 'provider.user.className','org.jivesoftware.openfire.user.DefaultUserProvider',0,NULL UNION ALL
select 'provider.vcard.className','org.jivesoftware.openfire.vcard.DefaultVCardProvider',0,NULL UNION ALL
select 'update.lastCheck','1613237450302',0,NULL UNION ALL
select 'xmpp.auth.anonymous','false',0,NULL UNION ALL
select 'xmpp.domain','xmpp.localhost.example',0,NULL UNION ALL
select 'xmpp.socket.ssl.active','true',0,NULL;
insert [ofPubsubDefaultConf] ([serviceID],[leaf],[deliverPayloads],[maxPayloadSize],[persistItems],[maxItems],[notifyConfigChanges],[notifyDelete],[notifyRetract],[presenceBased],[sendItemSubscribe],[publisherModel],[subscriptionEnabled],[accessModel],[language],[replyPolicy],[associationPolicy],[maxLeafNodes])
select 'pubsub',0,0,0,0,0,1,1,1,0,0,'publishers',1,'open','English',NULL,'all',-1 UNION ALL
select 'pubsub',1,1,10485760,0,1,1,1,1,0,1,'publishers',1,'open','English',NULL,'all',-1;
insert [ofPubsubNode] ([serviceID],[nodeID],[leaf],[creationDate],[modificationDate],[parent],[deliverPayloads],[maxPayloadSize],[persistItems],[maxItems],[notifyConfigChanges],[notifyDelete],[notifyRetract],[presenceBased],[sendItemSubscribe],[publisherModel],[subscriptionEnabled],[configSubscription],[accessModel],[payloadType],[bodyXSLT],[dataformXSLT],[creator],[description],[language],[name],[replyPolicy],[associationPolicy],[maxLeafNodes])
select 'pubsub','',0,'001613237414897','001613237414897',NULL,0,0,0,0,1,1,1,0,0,'publishers',1,0,'open','','','','xmpp.localhost.example','','English','',NULL,'all',-1;
insert [ofPubsubAffiliation] ([serviceID],[nodeID],[jid],[affiliation])
select 'pubsub','','xmpp.localhost.example','owner';
insert [ofSecurityAuditLog] ([msgID],[username],[entryStamp],[summary],[node],[details])
select 1,'admin',1613237419902,'Successful admin console login attempt','xmpp.localhost.example','The user logged in successfully to the admin console from address 172.70.0.1. ' UNION ALL
select 2,'admin',1613238674561,'created new user user1','xmpp.localhost.example','name = null, email = null, admin = false' UNION ALL
select 3,'admin',1613238682953,'created new user user2','xmpp.localhost.example','name = null, email = null, admin = false' UNION ALL
select 4,'admin',1613238689939,'created new user user3','xmpp.localhost.example','name = null, email = null, admin = false';
insert [ofUser] ([username],[storedKey],[serverKey],[salt],[iterations],[plainPassword],[encryptedPassword],[name],[email],[creationDate],[modificationDate])
--select 'admin','4dhG3yvLGEUh0MFXReJjQapiJmg=','+ppXcL2tMyEAp/FpWCDRIBYZwYU=','0YV3ub/KtC1lsl3JrFC3LqMoeQDDZeyi',4096,NULL,'dd79bd6a56a8aeb4b41231a6d3f3b1c03c4693b79d0835ba','Administrator','admin@example.com','001613237412842','0 ' UNION ALL
select 'user1','3J7uvQQgUYbwcfCq1NdwJdg/OEY=','nBA5c2QxabhlkBXYjVWNdFIOeQ4=','Whx8l40WIZDqspBFAV1iKjukhyiv47zL',4096,NULL,'1c6e8b14c538038f959733e7ec89ef13c65a7d5a85fcf8f89b2b881ffadbcd21',NULL,NULL,'001613238674533','001613238674533' UNION ALL
select 'user2','Sh3vxOxEEYRrKwC8tjZRoeRY/YE=','qsAj/TFx0oyT3ik+paR8SJ/HqUY=','V9NJrs/aWWB1f0ljeAzeu2ya5ygS94kc',4096,NULL,'1590781e96b533cd1377a419ffce58b1c28368e54972a9ce9f311728b43e6f3d',NULL,NULL,'001613238682884','001613238682884' UNION ALL
select 'user3','ek+kMBQ1oGEvyZalK/UnTuC7Xro=','zWuQN3uWxyaIB7LUuJegvQe9Vmg=','m7vVvrcAEM22p4sxzUYfFRC2BxlzOI2Y',4096,NULL,'5f1678df99186bb99640b213fb4734c81c967a2114971cbc5c02c7466415d24b',NULL,NULL,'001613238689918','001613238689918';
insert [ofMucRoom] ([serviceID],[roomID],[creationDate],[modificationDate],[name],[naturalName],[description],[lockedDate],[emptyDate],[canChangeSubject],[maxUsers],[publicRoom],[moderated],[membersOnly],[canInvite],[roomPassword],[canDiscoverJID],[logEnabled],[subject],[rolesToBroadcast],[useReservedNick],[canChangeNick],[canRegister],[allowpm])
select 1,1,'001613248823513','001613248823537','muc1','MUC One','First MUC Room','000000000000000',NULL,0,30,1,0,0,0,NULL,1,1,'',7,0,1,1,0;
insert [ofMucAffiliation] ([roomID],[jid],[affiliation])
select 1,'admin@xmpp.localhost.example',10;
insert [ofMucConversationLog] ([roomID],[messageID],[sender],[nickname],[logTime],[subject],[body],[stanza])
select 1,1,'muc1@conference.xmpp.localhost.example',NULL,'001613248823526','',NULL,'<message type="groupchat" from="muc1@conference.xmpp.localhost.example" to="muc1@conference.xmpp.localhost.example"><subject></subject></message>';
--insert [ofVersion] ([name],[version])
--select 'openfire',30;

View File

@ -6,8 +6,13 @@ if [ "$1" = "-c" ]; then
echo "Starting a clustered environment."
COMPOSE_FILE=docker-compose-clustered.yml
shift
elif [ "$1" = "-s" ]; then
echo "Starting a SQL Server environment."
cp ./wait-for-it.sh ./scripts/sqlserver/
COMPOSE_FILE=docker-compose-sqlserver.yml
shift
else
echo "Starting a federated environment (use -c to start a clustered environment instead)."
echo "Starting a federated environment (use -c to start a clustered environment or -s to start a SQL Server environment instead)."
fi
docker-compose -f $COMPOSE_FILE down

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file stores bootstrap properties needed by Openfire.
Property names must be in the format: "prop.name.is.blah=value"
That will be stored as:
<prop>
<name>
<is>
<blah>value</blah>
</is>
</name>
</prop>
Most properties are stored in the Openfire database. A
property viewer and editor is included in the admin console.
-->
<!-- root element, all properties must be under this element -->
<jive>
<adminConsole>
<!-- Disable either port by setting the value to -1 -->
<port>9090</port>
<securePort>9091</securePort>
</adminConsole>
<locale>en</locale>
<!-- Network settings. By default, Openfire will bind to all network interfaces.
Alternatively, you can specify a specific network interfaces that the server
will listen on. For example, 127.0.0.1. This setting is generally only useful
on multi-homed servers. -->
<!--
<network>
<interface></interface>
</network>
-->
<!--
One time token to gain temporary access to the admin console.
-->
<!--
<oneTimeAccessToken>secretToken</oneTimeAccessToken>
-->
<connectionProvider>
<className>org.jivesoftware.database.DefaultConnectionProvider</className>
</connectionProvider>
<database>
<defaultProvider>
<driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver>
<serverURL>jdbc:sqlserver://db:1433;databaseName=openfire;applicationName=Openfire</serverURL>
<username encrypted="true">de01ed40e11eabc294aeb88d83d3874e</username>
<password encrypted="true">d936bcac79f8f8191e519e7ce34306677e5e8a4aaf630f51bb129fe63d5e8ec5f241188b2aade145</password>
<testSQL>select 1</testSQL>
<testBeforeUse>false</testBeforeUse>
<testAfterUse>false</testAfterUse>
<testTimeout>500</testTimeout>
<timeBetweenEvictionRuns>30000</timeBetweenEvictionRuns>
<minIdleTime>900000</minIdleTime>
<maxWaitTime>500</maxWaitTime>
<minConnections>5</minConnections>
<maxConnections>25</maxConnections>
<connectionTimeout>1.0</connectionTimeout>
</defaultProvider>
</database>
<setup>true</setup>
<fqdn>xmpp.localhost.example</fqdn>
</jive>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file stores security-related properties needed by Openfire.
You may edit this file to manage encrypted properties and
encryption configuration value. Note however that you should not
edit this file while Openfire is running, or it may be overwritten.
It is important to note that Openfire will store encrypted property
values securely "at rest" (e.g. in the database or XML), but the
values will be managed as clear text strings in memory at runtime for
interoperability and performance reasons. Encrypted property values
are not visible via the Openfire console, but they may be edited or
deleted as needed.
-->
<security>
<encrypt>
<!-- This can be set to "AES" or "Blowfish" (default) at setup time -->
<algorithm>Blowfish</algorithm>
<key>
<!--
If this is a new server setup, you may set a custom encryption key
by setting a value for the <new /> encryption key element only.
To change the encryption key, provide values for both new and old
encryption keys here. The "old" key must match the unencrypted value
of the "current" key. The server will update the existing property
values in the database, re-encrypting them using the new key. After
the encrypted properties have been updated, the new key will itself
be encrypted and re-written into this file as <current />.
Note that if the current encryption key becomes invalid, any property
values secured by the original key will be inaccessible as well.
The key value can be any string, and it will be hashed, filled, and/or
truncated to produce a compatible key for the corresponding algorithm.
Note that leading and trailing spaces will be ignored. A strong key
will contain sixteen characters or more.
<old></old>
<new></new>
-->
<current></current>
</key>
<property>
<!--
This list includes the names of properties that have been marked for
encryption. Any XML properties (from openfire.xml) that are listed here
will be encrypted automatically upon first use. Other properties
(already in the database) can be added to this list at runtime via the
"System Properties" page in the Openfire console.
-->
<name>database.defaultProvider.username</name>
<name>database.defaultProvider.password</name>
</property>
</encrypt>
<!--
Any other property defined in this file will be treated as an encrypted
property. The value (in clear text) will be encrypted and migrated into
the Openfire database during the next startup. The property name will
be added to the list of encrypted properties and the clear text value
will be removed from this file.
<foo><bar>Secr3t$tr1ng!</bar></foo>
-->
</security>

View File

@ -0,0 +1 @@
This directory is used as a default location in which Openfire stores backups of keystore files.

Binary file not shown.

Binary file not shown.

Binary file not shown.