diff --git a/.snapcraft/README.md b/.snapcraft/README.md new file mode 100644 index 000000000000..f0197f2dc65b --- /dev/null +++ b/.snapcraft/README.md @@ -0,0 +1,61 @@ +![Rocket.Chat logo](https://rocket.chat/images/logo/logo-dark.svg?v3) + +# rocketchat-server snap for Ubuntu Core (all arch) + +Features: +* bundles ubuntu distribution specific and RC compatible mongodb version +* oplog tailing for mongo by default +* mongodb backup command +* mongodb restore command +* caddy reverse proxy built-in - capable of handling free lestencrypt ssl + +Note: + +Currently, this repository is mirrored on launchpad, and used to build latest ARMHF and i386 snaps. + +You can download recent builds here: +https://code.launchpad.net/~sing-li/+snap/rocketchat-server + +Due an issue with the existing installed base of amd64 users (existing snap always installed mongodb 3.2 [#issue](https://github.com/RocketChat/rocketchat-server-snap/issues/3)), this snap is not currently used for amd64 builds. + +### Test installation + +Download the latest snap file of the corresponding architecture to your Ubuntu Core 16 or 16.04LTS server. + +`sudo snap install ./rocketchat-server-xxxxxxxx.snap --dangerous` + + +### Development or compile your own snap + +Make sure you have `snapcraft` installed. + +``` +git clone https://github.com/RocketChat/rocketchat-server-snap +cd rocketchat-server-snap +snapcraft snap +``` + +### Regression tests (run for amd64, i386 and armhf): +- snapcraft runs properly +- snap installs properly +- all services start automatically +- rc service shows a 5-second restart delay while waiting for mongo + - to test manually, stop rc, stop mongo, start rc, wait 20s or so, start mongo +- rc can be successfully restarted via the "Restart the server" button under Admin > Settings > General +- rc service shows a 5-second delay when restarted via this button +- all commands execute successfully: + - initcaddy + - modify the Caddyfile to test: + - self-signed TLS certificate (use the "tls self_signed" caddy directive) + - changing ports (with and without TLS) + - using IP address (only works without TLS) + - successfully acquiring a Let's Encrypt certificate (requires a registered domain) + - backupdb + - should run only with sudo + - restoredb + - ideally, stop rc service prior to running this (mongo must be running) + - should run only with sudo + - use any file outside of $snap_common (should fail) + - use the file created with backupdb + - use a dummy .tgz file without actual data + - with and without a "parties" directory in the archive diff --git a/.snapcraft/candidate/snapcraft.yaml b/.snapcraft/candidate/snapcraft.yaml index 4bab82b5b24f..567d2e479002 100644 --- a/.snapcraft/candidate/snapcraft.yaml +++ b/.snapcraft/candidate/snapcraft.yaml @@ -11,6 +11,7 @@ version: #{RC_VERSION} summary: Rocket.Chat server description: Have your own Slack like online chat, built with Meteor. https://rocket.chat/ confinement: strict +assumes: [snapd2.21] apps: rocketchat-server: command: startRocketChat @@ -24,6 +25,12 @@ apps: command: env LC_ALL=C caddy -conf=$SNAP_DATA/Caddyfile -host=localhost:8080 daemon: simple plugs: [network, network-bind] + mongo: + command: env LC_ALL=C mongo + plugs: [network] + restoredb: + command: env LC_ALL=C restoredb + plugs: [network] backupdb: command: env LC_ALL=c rcbackup plugs: [network] @@ -48,7 +55,7 @@ parts: lib/node_modules: node_modules rocketchat-server: plugin: dump - after: [mongodb] + after: [node] source: https://rocket.chat/releases/release-candidate/download source-type: tar stage-packages: @@ -59,22 +66,15 @@ parts: - .node_version.txt - usr - lib - snap: - - programs - - main.js - - .node_version.txt - - usr - - lib mongodb: - source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.7.tgz + build-packages: + - wget + source: ./ + prepare: ./resources/preparemongo plugin: dump stage-packages: - libssl1.0.0 - stage: - - usr - - bin - - lib - snap: + prime: - usr - bin - lib @@ -83,23 +83,20 @@ parts: source: resources/ organize: rcbackup: bin/rcbackup + restoredb: bin/restoredb startmongo: bin/startmongo startRocketChat: bin/startRocketChat initreplset.js: bin/initreplset.js Caddyfile: bin/Caddyfile initcaddy: bin/initcaddy - snap: + prime: - bin caddy: - plugin: go - go-importpath: github.com/mholt/caddy - source: https://github.com/mholt/caddy - source-type: git - source-commit: 53e117802fedd5915eeb32907873d8786a4b2936 - snap: - - bin/caddy - after: [go] - go: - source-tag: go1.8 - stage: - - bin + prepare: ./resources/preparecaddy + plugin: dump + source: ./ + prime: + - bin + organize: + caddy: bin/caddy + after: [mongodb] diff --git a/.snapcraft/edge/snapcraft.yaml b/.snapcraft/edge/snapcraft.yaml index 00a0782a212a..2934d80e5907 100644 --- a/.snapcraft/edge/snapcraft.yaml +++ b/.snapcraft/edge/snapcraft.yaml @@ -11,6 +11,7 @@ version: #{RC_VERSION} summary: Rocket.Chat server description: Have your own Slack like online chat, built with Meteor. https://rocket.chat/ confinement: strict +assumes: [snapd2.21] apps: rocketchat-server: command: startRocketChat @@ -24,6 +25,12 @@ apps: command: env LC_ALL=C caddy -conf=$SNAP_DATA/Caddyfile -host=localhost:8080 daemon: simple plugs: [network, network-bind] + mongo: + command: env LC_ALL=C mongo + plugs: [network] + restoredb: + command: env LC_ALL=C restoredb + plugs: [network] backupdb: command: env LC_ALL=c rcbackup plugs: [network] @@ -48,7 +55,7 @@ parts: lib/node_modules: node_modules rocketchat-server: plugin: dump - after: [mongodb] + after: [node] source: https://rocket.chat/releases/develop/download source-type: tar stage-packages: @@ -59,22 +66,15 @@ parts: - .node_version.txt - usr - lib - snap: - - programs - - main.js - - .node_version.txt - - usr - - lib mongodb: - source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.7.tgz + build-packages: + - wget + source: ./ + prepare: ./resources/preparemongo plugin: dump stage-packages: - libssl1.0.0 - stage: - - usr - - bin - - lib - snap: + prime: - usr - bin - lib @@ -83,23 +83,20 @@ parts: source: resources/ organize: rcbackup: bin/rcbackup + restoredb: bin/restoredb startmongo: bin/startmongo startRocketChat: bin/startRocketChat initreplset.js: bin/initreplset.js Caddyfile: bin/Caddyfile initcaddy: bin/initcaddy - snap: + prime: - bin caddy: - plugin: go - go-importpath: github.com/mholt/caddy - source: https://github.com/mholt/caddy - source-type: git - source-commit: 53e117802fedd5915eeb32907873d8786a4b2936 - snap: - - bin/caddy - after: [go] - go: - source-tag: go1.8 - stage: - - bin + prepare: ./resources/preparecaddy + plugin: dump + source: ./ + prime: + - bin + organize: + caddy: bin/caddy + after: [mongodb] diff --git a/.snapcraft/resources/preparecaddy b/.snapcraft/resources/preparecaddy new file mode 100755 index 000000000000..86d530554c04 --- /dev/null +++ b/.snapcraft/resources/preparecaddy @@ -0,0 +1,36 @@ +#! /bin/bash + +caddy_bin="caddy" +caddy_dl_ext=".tar.gz" + +# NOTE: `uname -m` is more accurate and universal than `arch` +# See https://en.wikipedia.org/wiki/Uname +unamem="$(uname -m)" +if [[ $unamem == *aarch64* ]]; then + caddy_arch="arm64" +elif [[ $unamem == *64* ]]; then + caddy_arch="amd64" +elif [[ $unamem == *86* ]]; then + caddy_arch="386" +elif [[ $unamem == *armv5* ]]; then + caddy_arch="arm" + caddy_arm="5" +elif [[ $unamem == *armv6l* ]]; then + caddy_arch="arm" + caddy_arm="6" +elif [[ $unamem == *armv7l* ]]; then + caddy_arch="arm" + caddy_arm="7" +else + echo "Aborted, unsupported or unknown architecture: $unamem" + return 2 +fi + +echo "Downloading Caddy for $caddy_os/$caddy_arch$caddy_arm..." +caddy_file="caddy_linux_$caddy_arch${caddy_arm}_custom$caddy_dl_ext" +caddy_url="https://caddyserver.com/download/linux/$caddy_arch$caddy_arm?plugins=$caddy_plugins" +echo "$caddy_url" + +wget --quiet "$caddy_url" -O "$caddy_file" +tar -xzf $caddy_file -C . "$caddy_bin" +chmod +x $caddy_bin diff --git a/.snapcraft/resources/preparemongo b/.snapcraft/resources/preparemongo new file mode 100755 index 000000000000..332dd7d46847 --- /dev/null +++ b/.snapcraft/resources/preparemongo @@ -0,0 +1,22 @@ +#! /bin/bash + +if [[ $(uname -m) == "x86_64" ]] +then + wget --backups=0 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.7.tgz" + tar -zxf ./mongodb-linux-x86_64-ubuntu1604-3.2.7.tgz --strip-components=1 +else + IFS=" " read -a links <<< $(apt-get -y --print-uris install mongodb | egrep -o "https?://[^']+") + for link in ${links[@]} + do + wget --backups=0 ${link} + done + + IFS=" " read -a deb_pkgs <<< $(ls ./ | egrep "\.deb") + for pkg in ${deb_pkgs[@]} + do + echo "Extracting ${pkg}..." + dpkg-deb -R ${pkg} ./ + done + + mv usr/bin bin +fi diff --git a/.snapcraft/resources/restoredb b/.snapcraft/resources/restoredb new file mode 100755 index 000000000000..cedf9e1358d8 --- /dev/null +++ b/.snapcraft/resources/restoredb @@ -0,0 +1,72 @@ +#! /bin/bash + +if [[ ${EUID} != 0 ]] +then + echo "[-] This task must be run with 'sudo'." + exit +fi + +backup_file=${1} +if [[ ! -f ${backup_file} ]] +then + echo "[-] Usage: snap run rocketchat-server.restoredb ${SNAP_COMMON}/backup_file.tgz" + exit +fi + +cd ${backup_file%/*} +if [[ -z $(pwd | grep "${SNAP_COMMON}") ]] +then + echo "[-] Backup file must be within ${SNAP_COMMON}." + exit +fi + +function ask_backup { + echo -n "\ +*** ATTENTION *** +* Your current database WILL BE DROPPED prior to the restore! +* Would you like to make a backup of the current database before proceeding? +* (y/n/Q)> " + + read choice + [[ "${choice,,}" = n* ]] && return + [[ "${choice,,}" = y* ]] && backupdb.sh && return + exit +} + +function warn { + echo "[!] ${1}" + echo "[*] Check ${restore_dir}/${log_name} for details." +} + +function abort { + echo "[!] ${1}" + echo "[*] Check ${restore_dir}/${log_name} for details." + echo "[-] Restore aborted!" + exit +} + +mongo parties --eval "db.getCollectionNames()" | grep "\[ \]" >> /dev/null || ask_backup +echo "[*] Extracting backup file..." +restore_dir="${SNAP_COMMON}/restore" +log_name="extraction.log" +mkdir -p ${restore_dir} +cd ${restore_dir} +tar --no-same-owner --overwrite -zxvf ${backup_file} &> "${restore_dir}/${log_name}" +[[ $? != 0 ]] && abort "Failed to extract backup files to ${restore_dir}!" +echo "[*] Restoring data..." +data_dir=$(tail "${restore_dir}/${log_name}" | grep parties/. | head -n 1) +[[ -z ${data_dir} ]] && abort "Restore data not found within ${backup_file}! + Please check that your backup file contains the backup data within the \"parties\" directory." +data_dir=$(dirname ${data_dir}) +log_name="mongorestore.log" +mongorestore --db parties --noIndexRestore --drop ${data_dir} &> "${restore_dir}/${log_name}" +[[ $? != 0 ]] && abort "Failed to execute mongorestore from ${data_dir}!" +# If mongorestore.log only has a few lines, it likely didn't find the dump files +log_lines=$(wc -l < "${restore_dir}/${log_name}") +[[ ${log_lines} -lt 24 ]] && warn "Little or no restore data found within ${backup_file}! + Please check that your backup file contains all the backup data within the \"parties\" directory." +echo "[*] Preparing database..." +log_name="mongoprepare.log" +mongo parties --eval "db.repairDatabase()" --verbose &> "${restore_dir}/${log_name}" +[[ $? != 0 ]] && abort "Failed to prepare database for usage!" +echo "[+] Restore completed! Please restart the snap.rocketchat services to verify." diff --git a/.snapcraft/stable/snapcraft.yaml b/.snapcraft/stable/snapcraft.yaml index 9fca9ec62b6f..e548ef967a89 100644 --- a/.snapcraft/stable/snapcraft.yaml +++ b/.snapcraft/stable/snapcraft.yaml @@ -11,6 +11,7 @@ version: #{RC_VERSION} summary: Rocket.Chat server description: Have your own Slack like online chat, built with Meteor. https://rocket.chat/ confinement: strict +assumes: [snapd2.21] apps: rocketchat-server: command: startRocketChat @@ -24,6 +25,12 @@ apps: command: env LC_ALL=C caddy -conf=$SNAP_DATA/Caddyfile -host=localhost:8080 daemon: simple plugs: [network, network-bind] + mongo: + command: env LC_ALL=C mongo + plugs: [network] + restoredb: + command: env LC_ALL=C restoredb + plugs: [network] backupdb: command: env LC_ALL=c rcbackup plugs: [network] @@ -48,7 +55,7 @@ parts: lib/node_modules: node_modules rocketchat-server: plugin: dump - after: [mongodb] + after: [node] source: https://rocket.chat/releases/latest/download source-type: tar stage-packages: @@ -59,22 +66,15 @@ parts: - .node_version.txt - usr - lib - snap: - - programs - - main.js - - .node_version.txt - - usr - - lib mongodb: - source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.7.tgz + build-packages: + - wget + source: ./ + prepare: ./resources/preparemongo plugin: dump stage-packages: - libssl1.0.0 - stage: - - usr - - bin - - lib - snap: + prime: - usr - bin - lib @@ -83,23 +83,20 @@ parts: source: resources/ organize: rcbackup: bin/rcbackup + restoredb: bin/restoredb startmongo: bin/startmongo startRocketChat: bin/startRocketChat initreplset.js: bin/initreplset.js Caddyfile: bin/Caddyfile initcaddy: bin/initcaddy - snap: + prime: - bin caddy: - plugin: go - go-importpath: github.com/mholt/caddy - source: https://github.com/mholt/caddy - source-type: git - source-commit: 53e117802fedd5915eeb32907873d8786a4b2936 - snap: - - bin/caddy - after: [go] - go: - source-tag: go1.8 - stage: - - bin + prepare: ./resources/preparecaddy + plugin: dump + source: ./ + prime: + - bin + organize: + caddy: bin/caddy + after: [mongodb]