diff --git a/.gitignore b/.gitignore index 75b784ab7..b3ea8f373 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,8 @@ /rebar.lock /log/ Mnesia.nonode@nohost/ -# Binaries created with tools/make-{binaries,packages}: +# Binaries created with tools/make-{binaries,installers,packages}: /ejabberd_*.deb /ejabberd-*.rpm +/ejabberd-*.run /ejabberd-*.tar.gz diff --git a/tools/make-installers b/tools/make-installers new file mode 100755 index 000000000..10f8023d6 --- /dev/null +++ b/tools/make-installers @@ -0,0 +1,217 @@ +#!/bin/sh + +# Build installers for Linux/x64 and Linux/arm64. +# +# Author: Holger Weiss . +# +# Copyright (c) 2022 ProcessOne, SARL. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e +set -u + +myself=${0##*/} +architectures='x64 arm64' +iteration=1 + +usage() +{ + echo >&2 "Usage: $myself [-i ]" + exit 2 +} + +while getopts i: opt +do + case $opt in + i) + iteration="$OPTARG" + ;; + \?) + usage + ;; + esac +done +shift $((OPTIND - 1)) + +if ! [ -e 'mix.exs' ] || ! [ -e "tools/$myself" ] +then + echo >&2 "Please call this script from the repository's root directory." + exit 2 +elif [ $# -ne 0 ] +then + usage +fi +if type 'makeself' >'/dev/null' +then makeself='makeself' +elif type 'makeself.sh' >'/dev/null' +then makeself='makeself.sh' +else + echo >&2 'This script requires makeself: https://makeself.io' + exit 1 +fi + +rel_name='ejabberd' +rel_vsn=$(git describe | sed -e 's/-g.*//' -e 's/-/./' | tr -d '[:space:]') +code_path="/opt/$rel_name-$rel_vsn" +data_path="/opt/$rel_name" +conf_path="$data_path/conf" +pem_file="$conf_path/server.pem" +url='https://docs.ejabberd.im/admin/upgrade/#specific-version-upgrade-notes' +tmp_dir=$(mktemp -d "/tmp/.$rel_name.XXXXXX") + +trap 'rm -rf "$tmp_dir"' INT TERM EXIT +umask 022 + +create_setup_script() +{ + local dir="$1" + local tarball="$2" + + cat >"$dir/setup" <<-EOF + #!/bin/sh + + set -e + set -u + + export PATH='/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin' + + user_agrees() + { + local question="\$*" + + if [ -t 0 ] + then + read -p "\$question (y/n) [n] " response + response="\$(printf '%s' "\$response" | + tr '[:upper:]' '[:lower:]')" + if [ "\$response" = 'y' ] || [ "\$response" = 'yes' ] + then return 0 + else return 1 + fi + else # Assume 'yes' if not running interactively. + return 0 + fi + } + + if [ \$(id -u) != 0 ] + then + echo >&2 'The installer must be run with superuser privileges.' + exit 1 + fi + + if [ -e '/run/systemd/system' ] + then is_systemd=true + else is_systemd=false + fi + if [ -e '$data_path' ] + then is_upgrade=true + else is_upgrade=false + fi + if id -u '$rel_name' >'/dev/null' 2>&1 + then user_exists=true + else user_exists=false + fi + + echo 'The following installation paths will be used:' + echo '- $code_path' + if [ \$is_upgrade = true ] + then echo "- $data_path (existing files won't be modified)" + else echo '- $data_path' + fi + if [ \$is_systemd = true ] + then echo '- /etc/systemd/system/$rel_name.service' + fi + if [ \$user_exists = false ] + then echo 'The $rel_name user is going to be created.' + fi + if [ \$is_systemd = true ] && [ \$is_upgrade = false ] + then echo 'The $rel_name service is going to be enabled and started.' + fi + if ! user_agrees 'Install $rel_name $rel_vsn now?' + then + echo 'Aborting installation.' + exit 1 + fi + + if [ \$user_exists = false ] + then useradd -r -d '$data_path' '$rel_name' + fi + + host=\$(hostname --fqdn 2>'/dev/null' || :) + if [ -z "\$host" ] + then host='localhost' + fi + + tar --skip-old-files -C "\$(dirname '$code_path')" -xf '$tarball' + chown -R -h 'root:root' '$code_path' + chown 'root:$rel_name' '$code_path/lib/epam-'*'/priv/bin/epam' + chmod '4750' '$code_path/lib/epam-'*'/priv/bin/epam' + if [ \$is_upgrade = false ] + then + sed -i "s/ - localhost$/ - \$host/" '$conf_path/$rel_name.yml' + openssl req -x509 \ + -batch \ + -nodes \ + -newkey rsa:4096 \ + -keyout '$pem_file' \ + -out '$pem_file' \ + -days 3650 \ + -subj "/CN=\$host" >'/dev/null' 2>&1 || : + if [ -e '$pem_file' ] + then chown '$rel_name:$rel_name' '$pem_file' + else echo 'Failed to create a TLS certificate for ejabberd.' >&2 + fi + fi + + if [ \$is_systemd = true ] + then + cp '$code_path/bin/$rel_name.service' '/etc/systemd/system/' + systemctl -q daemon-reload + if [ \$is_upgrade = false ] + then systemctl -q --now enable '$rel_name' + fi + elif [ \$is_upgrade = false ] + then + echo 'You might want to install an init script (see the' + echo '$code_path/bin directory for an example).' + fi + echo '$rel_name $rel_vsn has been installed successfully.' + + if [ \$is_upgrade = true ] + then + echo 'Please check the following web site for upgrade notes:' + echo + echo '$url' + echo + echo 'If everything looks fine, restart the $rel_name service.' + fi + EOF + chmod +x "$dir/setup" +} + +for arch in $architectures +do + tar_name="$rel_name-$rel_vsn-linux-$arch.tar" + tgz_name="$tar_name.gz" + installer_name="$rel_name-$rel_vsn-$iteration-linux-$arch.run" + + test -e "$tgz_name" || tools/make-binaries + echo "$myself: Putting together installer for $arch ..." + gzip -c -d <"$tgz_name" >"$tmp_dir/$tar_name" + create_setup_script "$tmp_dir" "$tar_name" + "$makeself" "$tmp_dir" "$installer_name" "$rel_name $rel_vsn" './setup' + find "$tmp_dir" -mindepth 1 -delete +done +echo "$myself: Created installers successfully."