Last active
April 5, 2022 13:53
-
-
Save yumusb/682adeb2735658249985441eb12a6a1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# shellcheck disable=SC2268 | |
BIN_PATH=${BIN_PATH:-/usr/local/share/mtg} | |
TOML_PATH=${TOML_PATH:-/usr/local/etc/mtg} | |
curl() { | |
$(type -P curl) -L -q --retry 5 --retry-delay 10 --retry-max-time 60 "$@" | |
} | |
systemd_cat_config() { | |
if systemd-analyze --help | grep -qw 'cat-config'; then | |
systemd-analyze --no-pager cat-config "$@" | |
echo | |
else | |
echo "${aoi}~~~~~~~~~~~~~~~~" | |
cat "$@" "$1".d/* | |
echo "${aoi}~~~~~~~~~~~~~~~~" | |
echo "${red}warning: ${green}The systemd version on the current operating system is too low." | |
echo "${red}warning: ${green}Please consider to upgrade the systemd or the operating system.${reset}" | |
echo | |
fi | |
} | |
check_if_running_as_root() { | |
# If you want to run as another user, please modify $UID to be owned by this user | |
if [[ "$UID" -ne '0' ]]; then | |
echo "WARNING: The user currently executing this script is not root. You may encounter the insufficient privilege error." | |
read -r -p "Are you sure you want to continue? [y/n] " cont_without_been_root | |
if [[ x"${cont_without_been_root:0:1}" = x'y' ]]; then | |
echo "Continuing the installation with current user..." | |
else | |
echo "Not running with root, exiting..." | |
exit 1 | |
fi | |
fi | |
} | |
identify_the_operating_system_and_architecture() { | |
if [[ "$(uname)" == 'Linux' ]]; then | |
case "$(uname -m)" in | |
'i386' | 'i686') | |
MACHINE='386' | |
;; | |
'amd64' | 'x86_64') | |
MACHINE='amd64' | |
;; | |
*) | |
echo "error: The architecture is not supported." | |
exit 1 | |
;; | |
esac | |
if [[ ! -f '/etc/os-release' ]]; then | |
echo "error: Don't use outdated Linux distributions." | |
exit 1 | |
fi | |
if [[ -f /.dockerenv ]] || grep -q 'docker\|lxc' /proc/1/cgroup && [[ "$(type -P systemctl)" ]]; then | |
true | |
elif [[ -d /run/systemd/system ]] || grep -q systemd <(ls -l /sbin/init); then | |
true | |
else | |
echo "error: Only Linux distributions using systemd are supported." | |
exit 1 | |
fi | |
if [[ "$(type -P apt)" ]]; then | |
PACKAGE_MANAGEMENT_INSTALL='apt -y --no-install-recommends install' | |
PACKAGE_MANAGEMENT_REMOVE='apt purge' | |
package_provide_tput='ncurses-bin' | |
elif [[ "$(type -P dnf)" ]]; then | |
PACKAGE_MANAGEMENT_INSTALL='dnf -y install' | |
PACKAGE_MANAGEMENT_REMOVE='dnf remove' | |
package_provide_tput='ncurses' | |
elif [[ "$(type -P yum)" ]]; then | |
PACKAGE_MANAGEMENT_INSTALL='yum -y install' | |
PACKAGE_MANAGEMENT_REMOVE='yum remove' | |
package_provide_tput='ncurses' | |
elif [[ "$(type -P zypper)" ]]; then | |
PACKAGE_MANAGEMENT_INSTALL='zypper install -y --no-recommends' | |
PACKAGE_MANAGEMENT_REMOVE='zypper remove' | |
package_provide_tput='ncurses-utils' | |
elif [[ "$(type -P pacman)" ]]; then | |
PACKAGE_MANAGEMENT_INSTALL='pacman -Syu --noconfirm' | |
PACKAGE_MANAGEMENT_REMOVE='pacman -Rsn' | |
package_provide_tput='ncurses' | |
else | |
echo "error: The script does not support the package manager in this operating system." | |
exit 1 | |
fi | |
else | |
echo "error: This operating system is not supported." | |
exit 1 | |
fi | |
} | |
## Demo function for processing parameters | |
judgment_parameters() { | |
while [[ "$#" -gt '0' ]]; do | |
case "$1" in | |
'--remove') | |
if [[ "$#" -gt '1' ]]; then | |
echo 'error: Please enter the correct parameters.' | |
exit 1 | |
fi | |
REMOVE='1' | |
;; | |
'--version') | |
VERSION="${2:?error: Please specify the correct version.}" | |
break | |
;; | |
'--domain') | |
DOMAIN="${2:?error: Please input a domain.}" | |
shift | |
;; | |
'--port') | |
PORT="${2:?error: Please input a port to listen.}" | |
shift | |
;; | |
'-c' | '--check') | |
CHECK='1' | |
break | |
;; | |
'-f' | '--force') | |
FORCE='1' | |
break | |
;; | |
'-h' | '--help') | |
HELP='1' | |
break | |
;; | |
'-l' | '--local') | |
LOCAL_INSTALL='1' | |
LOCAL_FILE="${2:?error: Please specify the correct local file.}" | |
break | |
;; | |
'-p' | '--proxy') | |
if [[ -z "${2:?error: Please specify the proxy server address.}" ]]; then | |
exit 1 | |
fi | |
PROXY="$2" | |
shift | |
;; | |
*) | |
echo "$0: unknown option -- -" | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
} | |
install_software() { | |
package_name="$1" | |
file_to_detect="$2" | |
type -P "$file_to_detect" > /dev/null 2>&1 && return | |
if ${PACKAGE_MANAGEMENT_INSTALL} "$package_name"; then | |
echo "info: $package_name is installed." | |
else | |
echo "error: Installation of $package_name failed, please check your network." | |
exit 1 | |
fi | |
} | |
get_version() { | |
# 0: Install or update mtg. | |
# 1: Installed or no new version of mtg. | |
# 2: Install the specified version of mtg. | |
if [[ -n "$VERSION" ]]; then | |
RELEASE_VERSION="v${VERSION#v}" | |
return 2 | |
fi | |
# Determine the version number for mtg installed from a local file | |
if [[ -f '/usr/local/bin/mtg' ]]; then | |
VERSION="$(/usr/local/bin/mtg --version | awk 'NR==1 {print $1}')" | |
CURRENT_VERSION="v${VERSION#v}" | |
if [[ "$LOCAL_INSTALL" -eq '1' ]]; then | |
RELEASE_VERSION="$CURRENT_VERSION" | |
return | |
fi | |
fi | |
# Get mtg release version number | |
TMP_FILE="$(mktemp)" | |
if ! curl -x "${PROXY}" -sS -H "Accept: application/vnd.github.v3+json" -o "$TMP_FILE" 'https://api.github.com/repos/9seconds/mtg/releases/latest'; then | |
"rm" "$TMP_FILE" | |
echo 'error: Failed to get release list, please check your network.' | |
exit 1 | |
fi | |
RELEASE_LATEST="$(sed 'y/,/\n/' "$TMP_FILE" | grep 'tag_name' | awk -F '"' '{print $4}')" | |
"rm" "$TMP_FILE" | |
RELEASE_VERSION="v${RELEASE_LATEST#v}" | |
# Compare mtg version numbers | |
if [[ "$RELEASE_VERSION" != "$CURRENT_VERSION" ]]; then | |
RELEASE_VERSIONSION_NUMBER="${RELEASE_VERSION#v}" | |
RELEASE_MAJOR_VERSION_NUMBER="${RELEASE_VERSIONSION_NUMBER%%.*}" | |
RELEASE_MINOR_VERSION_NUMBER="$(echo "$RELEASE_VERSIONSION_NUMBER" | awk -F '.' '{print $2}')" | |
RELEASE_MINIMUM_VERSION_NUMBER="${RELEASE_VERSIONSION_NUMBER##*.}" | |
# shellcheck disable=SC2001 | |
CURRENT_VERSIONSION_NUMBER="$(echo "${CURRENT_VERSION#v}" | sed 's/-.*//')" | |
CURRENT_MAJOR_VERSION_NUMBER="${CURRENT_VERSIONSION_NUMBER%%.*}" | |
CURRENT_MINOR_VERSION_NUMBER="$(echo "$CURRENT_VERSIONSION_NUMBER" | awk -F '.' '{print $2}')" | |
CURRENT_MINIMUM_VERSION_NUMBER="${CURRENT_VERSIONSION_NUMBER##*.}" | |
if [[ "$RELEASE_MAJOR_VERSION_NUMBER" -gt "$CURRENT_MAJOR_VERSION_NUMBER" ]]; then | |
return 0 | |
elif [[ "$RELEASE_MAJOR_VERSION_NUMBER" -eq "$CURRENT_MAJOR_VERSION_NUMBER" ]]; then | |
if [[ "$RELEASE_MINOR_VERSION_NUMBER" -gt "$CURRENT_MINOR_VERSION_NUMBER" ]]; then | |
return 0 | |
elif [[ "$RELEASE_MINOR_VERSION_NUMBER" -eq "$CURRENT_MINOR_VERSION_NUMBER" ]]; then | |
if [[ "$RELEASE_MINIMUM_VERSION_NUMBER" -gt "$CURRENT_MINIMUM_VERSION_NUMBER" ]]; then | |
return 0 | |
else | |
return 1 | |
fi | |
else | |
return 1 | |
fi | |
else | |
return 1 | |
fi | |
elif [[ "$RELEASE_VERSION" == "$CURRENT_VERSION" ]]; then | |
return 1 | |
fi | |
} | |
download_mtg() { | |
RELEASE_VERSION_NUM=${RELEASE_VERSION#*v} | |
DOWNLOAD_LINK="https://github.com/9seconds/mtg/releases/download/$RELEASE_VERSION/mtg-$RELEASE_VERSION_NUM-linux-$MACHINE.tar.gz" | |
echo "Downloading mtg archive: $DOWNLOAD_LINK" | |
if ! curl -x "${PROXY}" -R -H 'Cache-Control: no-cache' -o "$TAR_GZ_FILE" "$DOWNLOAD_LINK"; then | |
echo 'error: Download failed! Please check your network or try again.' | |
return 1 | |
fi | |
} | |
decompression() { | |
if ! tar -xzvf "$1" -C "$TMP_DIRECTORY"; then | |
echo 'error: mtg decompression failed.' | |
"rm" -r "$TMP_DIRECTORY" | |
echo "removed: $TMP_DIRECTORY" | |
exit 1 | |
fi | |
echo "info: Extract the mtg package to $TMP_DIRECTORY and prepare it for installation." | |
} | |
install_file() { | |
NAME="$1" | |
if [[ "$NAME" == 'mtg' ]] ; then | |
install -m 755 "${TMP_DIRECTORY}/mtg-$RELEASE_VERSION_NUM-linux-$MACHINE/$NAME" "/usr/local/bin/$NAME" | |
fi | |
} | |
install_mtg() { | |
# Install mtg binary to /usr/local/bin/ and $BIN_PATH | |
install_file mtg | |
install -d "$BIN_PATH" | |
# Install mtg configuration file to $TOML_PATH | |
# shellcheck disable=SC2153 | |
# if [[ ! -d "$TOML_PATH" ]]; then | |
# install -d "$TOML_PATH" | |
# echo "mtg generate-secret $DOMAIN" | |
# MTG_SECRET = $(mtg generate-secret $DOMAIN) | |
# echo "secret = \"$MTG_SECRET\" | |
# bind-to = \"0.0.0.0:8443\"" > "${TOML_PATH}/mtg.toml" | |
# CONFIG_NEW='1' | |
# fi | |
install -d "$TOML_PATH" | |
if [[ -z "$DOMAIN" ]]; then | |
echo "DOMAIN is empty" | |
read -p "input a domain to use(fake):" DOMAIN | |
fi | |
if [[ -z $PORT ]]; then | |
echo "PORT is empty" | |
read -p "input a port to listen:" PORT | |
fi | |
echo "mtg generate-secret $DOMAIN" | |
MTG_SECRET=$(mtg generate-secret $DOMAIN) | |
echo "secret = \"$MTG_SECRET\" | |
bind-to = \"0.0.0.0:$PORT\"" > "${TOML_PATH}/mtg.toml" | |
} | |
install_startup_service_file() { | |
echo "[Unit] | |
Description=mtg - MTProto proxy server | |
Documentation=https://github.com/9seconds/mtg | |
After=network.target | |
[Service] | |
ExecStart=/usr/local/bin/mtg run ${TOML_PATH}/mtg.toml | |
Restart=always | |
RestartSec=3 | |
DynamicUser=true | |
AmbientCapabilities=CAP_NET_BIND_SERVICE | |
[Install] | |
WantedBy=multi-user.target" > /etc/systemd/system/mtg.service | |
systemd_cat_config /etc/systemd/system/mtg.service | |
# shellcheck disable=SC2154 | |
systemctl daemon-reload | |
SYSTEMD='1' | |
} | |
start_mtg() { | |
if [[ -f '/etc/systemd/system/mtg.service' ]]; then | |
if systemctl start "${mtg_CUSTOMIZE:-mtg}"; then | |
echo 'info: Start the mtg service.' | |
else | |
echo 'error: Failed to start mtg service.' | |
exit 1 | |
fi | |
fi | |
} | |
stop_mtg() { | |
mtg_CUSTOMIZE="$(systemctl list-units | grep 'mtg' | awk -F ' ' '{print $1}')" | |
if [[ -z "$mtg_CUSTOMIZE" ]]; then | |
local mtg_daemon_to_stop='mtg.service' | |
else | |
local mtg_daemon_to_stop="$mtg_CUSTOMIZE" | |
fi | |
if ! systemctl stop "$mtg_daemon_to_stop"; then | |
echo 'error: Stopping the mtg service failed.' | |
exit 1 | |
fi | |
echo 'info: Stop the mtg service.' | |
} | |
check_update() { | |
if [[ -f '/etc/systemd/system/mtg.service' ]]; then | |
get_version | |
local get_ver_exit_code=$? | |
if [[ "$get_ver_exit_code" -eq '0' ]]; then | |
echo "info: Found the latest release of mtg $RELEASE_VERSION . (Current release: $CURRENT_VERSION)" | |
elif [[ "$get_ver_exit_code" -eq '1' ]]; then | |
echo "info: No new version. The current version of mtg is $CURRENT_VERSION ." | |
fi | |
exit 0 | |
else | |
echo 'error: mtg is not installed.' | |
exit 1 | |
fi | |
} | |
remove_mtg() { | |
if systemctl list-unit-files | grep -qw 'mtg'; then | |
if [[ -n "$(pidof mtg)" ]]; then | |
stop_mtg | |
fi | |
if ! ("rm" -r '/usr/local/bin/mtg' \ | |
"$BIN_PATH" \ | |
'/etc/systemd/system/mtg.service' ); then | |
echo 'error: Failed to remove mtg.' | |
exit 1 | |
else | |
echo 'removed: /usr/local/bin/mtg' | |
echo "removed: $BIN_PATH" | |
echo 'removed: /etc/systemd/system/mtg.service' | |
echo 'Please execute the command: systemctl disable mtg' | |
echo "You may need to execute a command to remove dependent software: $PACKAGE_MANAGEMENT_REMOVE curl unzip" | |
echo 'info: mtg has been removed.' | |
echo 'info: If necessary, manually delete the configuration and log files.' | |
exit 0 | |
fi | |
else | |
echo 'error: mtg is not installed.' | |
exit 1 | |
fi | |
} | |
# Explanation of parameters in the script | |
show_help() { | |
echo "usage: $0 [--remove | --version number | -c | -f | -h | -l | -p]" | |
echo ' [-p address] [--version number | -c | -f]' | |
echo ' --remove Remove mtg' | |
echo ' --version Install the specified version of mtg, e.g., --version v4.18.0' | |
echo ' -c, --check Check if mtg can be updated' | |
echo ' -f, --force Force installation of the latest version of mtg' | |
echo ' -h, --help Show help' | |
echo ' -l, --local Install mtg from a local file' | |
echo ' -p, --proxy Download through a proxy server, e.g., -p http://127.0.0.1:8118 or -p socks5://127.0.0.1:1080' | |
echo ' --domain Fake Tls Domain, e.g., --domain baidu.com' | |
echo ' --port port to listen , e.g., --port 443' | |
exit 0 | |
} | |
main() { | |
check_if_running_as_root | |
identify_the_operating_system_and_architecture | |
judgment_parameters "$@" | |
install_software "$package_provide_tput" 'tput' | |
red=$(tput setaf 1) | |
green=$(tput setaf 2) | |
aoi=$(tput setaf 6) | |
reset=$(tput sgr0) | |
# Parameter information | |
[[ "$HELP" -eq '1' ]] && show_help | |
[[ "$CHECK" -eq '1' ]] && check_update | |
[[ "$REMOVE" -eq '1' ]] && remove_mtg | |
# Two very important variables | |
TMP_DIRECTORY="$(mktemp -d)" | |
TAR_GZ_FILE="${TMP_DIRECTORY}/mtg-linux-$MACHINE.tar.gz" | |
# Install mtg from a local file, but still need to make sure the network is available | |
if [[ "$LOCAL_INSTALL" -eq '1' ]]; then | |
echo 'warn: Install mtg from a local file, but still need to make sure the network is available.' | |
echo -n 'warn: Please make sure the file is valid because we cannot confirm it. (Press any key) ...' | |
read -r | |
install_software 'tar' 'tar' | |
decompression "$LOCAL_FILE" | |
else | |
# Normal way | |
install_software 'curl' 'curl' | |
get_version | |
NUMBER="$?" | |
if [[ "$NUMBER" -eq '0' ]] || [[ "$FORCE" -eq '1' ]] || [[ "$NUMBER" -eq 2 ]]; then | |
echo "info: Installing mtg $RELEASE_VERSION for $(uname -m)" | |
download_mtg | |
if [[ "$?" -eq '1' ]]; then | |
"rm" -r "$TMP_DIRECTORY" | |
echo "removed: $TMP_DIRECTORY" | |
exit 1 | |
fi | |
install_software 'tar' 'tar' | |
decompression "$TAR_GZ_FILE" | |
elif [[ "$NUMBER" -eq '1' ]]; then | |
echo "info: No new version. The current version of mtg is $CURRENT_VERSION ." | |
exit 0 | |
fi | |
fi | |
# Determine if mtg is running | |
if systemctl list-unit-files | grep -qw 'mtg'; then | |
if [[ -n "$(pidof mtg)" ]]; then | |
stop_mtg | |
mtg_RUNNING='1' | |
fi | |
fi | |
install_mtg | |
install_startup_service_file | |
echo 'installed: /usr/local/bin/mtg' | |
if [[ "$CONFIG_NEW" -eq '1' ]]; then | |
echo "installed: ${TOML_PATH}/mtg.toml" | |
fi | |
if [[ "$SYSTEMD" -eq '1' ]]; then | |
echo 'installed: /etc/systemd/system/mtg.service' | |
fi | |
"rm" -r "$TMP_DIRECTORY" | |
echo "removed: $TMP_DIRECTORY" | |
if [[ "$LOCAL_INSTALL" -eq '1' ]]; then | |
get_version | |
fi | |
echo "info: mtg $RELEASE_VERSION is installed." | |
echo "You may need to execute a command to remove dependent software: $PACKAGE_MANAGEMENT_REMOVE curl tar" | |
if [[ "$mtg_RUNNING" -eq '1' ]]; then | |
start_mtg | |
else | |
echo 'Please execute the command: systemctl enable mtg; systemctl start mtg' | |
start_mtg | |
fi | |
mtg access "${TOML_PATH}/mtg.toml" | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment