gitscope
https://dev.kronoz.win/r/marzneshin.git
script.sh · Bash
Blame Raw
  1#!/usr/bin/env bash
  2set -e
  3
  4APP_NAME="marzneshin"
  5NODE_NAME="marznode"
  6CONFIG_DIR="/etc/opt/$APP_NAME"
  7DATA_DIR="/var/lib/$APP_NAME"
  8NODE_DATA_DIR="/var/lib/$NODE_NAME"
  9COMPOSE_FILE="$CONFIG_DIR/docker-compose.yml"
 10
 11
 12colorized_echo() {
 13    local color=$1
 14    local text=$2
 15
 16    case $color in
 17        "red")
 18        printf "\e[91m${text}\e[0m\n";;
 19        "green")
 20        printf "\e[92m${text}\e[0m\n";;
 21        "yellow")
 22        printf "\e[93m${text}\e[0m\n";;
 23        "blue")
 24        printf "\e[94m${text}\e[0m\n";;
 25        "magenta")
 26        printf "\e[95m${text}\e[0m\n";;
 27        "cyan")
 28        printf "\e[96m${text}\e[0m\n";;
 29        *)
 30            echo "${text}"
 31        ;;
 32    esac
 33}
 34
 35check_running_as_root() {
 36    if [ "$(id -u)" != "0" ]; then
 37        colorized_echo red "This command must be run as root."
 38        exit 1
 39    fi
 40}
 41
 42detect_os() {
 43    # Detect the operating system
 44    if [ -f /etc/lsb-release ]; then
 45        OS=$(lsb_release -si)
 46        elif [ -f /etc/os-release ]; then
 47        OS=$(awk -F= '/^NAME/{print $2}' /etc/os-release | tr -d '"')
 48        elif [ -f /etc/redhat-release ]; then
 49        OS=$(cat /etc/redhat-release | awk '{print $1}')
 50        elif [ -f /etc/arch-release ]; then
 51        OS="Arch"
 52    else
 53        colorized_echo red "Unsupported operating system"
 54        exit 1
 55    fi
 56}
 57
 58detect_and_update_package_manager() {
 59    colorized_echo blue "Updating package manager"
 60    if [[ "$OS" == "Ubuntu"* ]] || [[ "$OS" == "Debian"* ]]; then
 61        PKG_MANAGER="apt-get"
 62        $PKG_MANAGER update
 63        elif [[ "$OS" == "CentOS"* ]] || [[ "$OS" == "AlmaLinux"* ]]; then
 64        PKG_MANAGER="yum"
 65        $PKG_MANAGER update -y
 66        $PKG_MANAGER install -y epel-release
 67        elif [ "$OS" == "Fedora"* ]; then
 68        PKG_MANAGER="dnf"
 69        $PKG_MANAGER update
 70        elif [ "$OS" == "Arch" ]; then
 71        PKG_MANAGER="pacman"
 72        $PKG_MANAGER -Sy
 73    else
 74        colorized_echo red "Unsupported operating system"
 75        exit 1
 76    fi
 77}
 78
 79detect_compose() {
 80    # Check if docker compose command exists
 81    if docker compose >/dev/null 2>&1; then
 82        COMPOSE='docker compose'
 83        elif docker-compose >/dev/null 2>&1; then
 84        COMPOSE='docker-compose'
 85    else
 86        colorized_echo red "docker compose not found"
 87        exit 1
 88    fi
 89}
 90
 91install_package () {
 92    if [ -z $PKG_MANAGER ]; then
 93        detect_and_update_package_manager
 94    fi
 95
 96    PACKAGE=$1
 97    colorized_echo blue "Installing $PACKAGE"
 98    if [[ "$OS" == "Ubuntu"* ]] || [[ "$OS" == "Debian"* ]]; then
 99        $PKG_MANAGER -y install "$PACKAGE"
100        elif [[ "$OS" == "CentOS"* ]] || [[ "$OS" == "AlmaLinux"* ]]; then
101        $PKG_MANAGER install -y "$PACKAGE"
102        elif [ "$OS" == "Fedora"* ]; then
103        $PKG_MANAGER install -y "$PACKAGE"
104        elif [ "$OS" == "Arch" ]; then
105        $PKG_MANAGER -S --noconfirm "$PACKAGE"
106    else
107        colorized_echo red "Unsupported operating system"
108        exit 1
109    fi
110}
111
112install_docker() {
113    # Install Docker and Docker Compose using the official installation script
114    colorized_echo blue "Installing Docker"
115    curl -fsSL https://get.docker.com | sh
116    colorized_echo green "Docker installed successfully"
117}
118
119install_marzneshin_script() {
120    FETCH_REPO="khodedawsh/marzneshin"
121    SCRIPT_URL="https://github.com/$FETCH_REPO/raw/master/script.sh"
122    colorized_echo blue "Installing marzneshin script"
123    curl -sSL $SCRIPT_URL | install -m 755 /dev/stdin /usr/local/bin/marzneshin
124    colorized_echo green "marzneshin script installed successfully"
125}
126
127install_marzneshin() {
128    # Fetch releases
129    FILES_URL_PREFIX="https://raw.githubusercontent.com/khodedawsh/marzneshin/master"
130
131    mkdir -p "$DATA_DIR"
132    mkdir -p "$CONFIG_DIR"
133
134    colorized_echo blue "Fetching compose file"
135    curl -sL "$FILES_URL_PREFIX/docker-compose.yml" -o "$CONFIG_DIR/docker-compose.yml"
136    colorized_echo green "File saved in $CONFIG_DIR/docker-compose.yml"
137
138    colorized_echo blue "Fetching .env file"
139    curl -sL "$FILES_URL_PREFIX/.env.example" -o "$CONFIG_DIR/.env"
140    sed -i 's/^# \(SQLALCHEMY_DATABASE_URL = .*\)$/\1/' "$CONFIG_DIR/.env"
141    sed -i 's~\(SQLALCHEMY_DATABASE_URL = \).*~\1"sqlite:///'$DATA_DIR'/db.sqlite3"~' "$CONFIG_DIR/.env"
142    colorized_echo green "File saved in $CONFIG_DIR/.env"
143
144    colorized_echo green "Marzneshin files downloaded successfully"
145}
146
147install_marznode_xray_config() {
148    mkdir -p "$NODE_DATA_DIR"
149    curl -sL "https://raw.githubusercontent.com/khodedawsh/marznode/master/xray_config.json" -o "$NODE_DATA_DIR/xray_config.json"
150    colorized_echo green "Sample xray config downloaded for marznode"
151}
152
153uninstall_marzneshin_script() {
154    if [ -f "/usr/local/bin/marzneshin" ]; then
155        colorized_echo yellow "Removing marzneshin script"
156        rm "/usr/local/bin/marzneshin"
157    fi
158}
159
160uninstall_marzneshin() {
161    if [ -d "$CONFIG_DIR" ]; then
162        colorized_echo yellow "Removing directory: $CONFIG_DIR"
163        rm -r "$CONFIG_DIR"
164    fi
165}
166
167uninstall_marzneshin_docker_images() {
168    images=$(docker images | grep marzneshin | awk '{print $3}')
169
170    if [ -n "$images" ]; then
171        colorized_echo yellow "Removing Docker images of Marzneshin"
172        for image in $images; do
173            if docker rmi "$image" >/dev/null 2>&1; then
174                colorized_echo yellow "Image $image removed"
175            fi
176        done
177    fi
178}
179
180uninstall_marzneshin_data_files() {
181    if [ -d "$DATA_DIR" ]; then
182        colorized_echo yellow "Removing directory: $DATA_DIR"
183        rm -r "$DATA_DIR"
184    fi
185}
186
187uninstall_marznode_data_files() {
188    if [ -d "$NODE_DATA_DIR" ]; then
189        colorized_echo yellow "Removing directory: $NODE_DATA_DIR"
190        rm -r "$NODE_DATA_DIR"
191    fi
192}
193
194
195up_marzneshin() {
196    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" up -d --remove-orphans
197}
198
199down_marzneshin() {
200    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" down
201}
202
203show_marzneshin_logs() {
204    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" logs
205}
206
207follow_marzneshin_logs() {
208    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" logs -f
209}
210
211marzneshin_cli() {
212    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" exec -e CLI_PROG_NAME="marzneshin cli" marzneshin /app/marzneshin-cli.py "$@"
213}
214
215
216update_marzneshin_script() {
217    FETCH_REPO="khodedawsh/marzneshin"
218    SCRIPT_URL="https://github.com/$FETCH_REPO/raw/master/script.sh"
219    colorized_echo blue "Updating marzneshin script"
220    curl -sSL $SCRIPT_URL | install -m 755 /dev/stdin /usr/local/bin/marzneshin
221    colorized_echo green "marzneshin script updated successfully"
222}
223
224update_marzneshin() {
225    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" pull
226}
227
228is_marzneshin_installed() {
229    if [ -d $CONFIG_DIR ]; then
230        return 0
231    else
232        return 1
233    fi
234}
235
236is_marzneshin_up() {
237    if [ -z "$($COMPOSE -f $COMPOSE_FILE ps -q -a)" ]; then
238        return 1
239    else
240        return 0
241    fi
242}
243
244install_command() {
245    check_running_as_root
246    # Check if marzneshin is already installed
247    if is_marzneshin_installed; then
248        colorized_echo red "Marzneshin is already installed at $CONFIG_DIR"
249        read -p "Do you want to override the previous installation? (y/n) "
250        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
251            colorized_echo red "Aborted installation"
252            exit 1
253        fi
254    fi
255    detect_os
256    if ! command -v jq >/dev/null 2>&1; then
257        install_package jq
258    fi
259    if ! command -v curl >/dev/null 2>&1; then
260        install_package curl
261    fi
262    if ! command -v docker >/dev/null 2>&1; then
263        install_docker
264    fi
265    detect_compose
266    install_marzneshin_script
267    install_marzneshin
268    install_marznode_xray_config
269    up_marzneshin
270    follow_marzneshin_logs
271}
272
273uninstall_command() {
274    check_running_as_root
275    # Check if marzneshin is installed
276    if ! is_marzneshin_installed; then
277        colorized_echo red "Marzneshin's not installed!"
278        exit 1
279    fi
280
281    read -p "Do you really want to uninstall Marzneshin? (y/n) "
282    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
283        colorized_echo red "Aborted"
284        exit 1
285    fi
286
287    detect_compose
288    if is_marzneshin_up; then
289        down_marzneshin
290    fi
291    uninstall_marzneshin_script
292    uninstall_marzneshin
293    uninstall_marzneshin_docker_images
294
295    read -p "Do you want to remove marzneshin & marznode data files too ($NODE_DATA_DIR, $DATA_DIR)? (y/n) "
296    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
297        colorized_echo green "Marzneshin uninstalled successfully"
298    else
299        uninstall_marzneshin_data_files
300	uninstall_marznode_data_files
301        colorized_echo green "Marzneshin uninstalled successfully"
302    fi
303}
304
305up_command() {
306    help() {
307        colorized_echo red "Usage: $0 up [options]"
308        echo ""
309        echo "OPTIONS:"
310        echo "  -h, --help        display this help message"
311        echo "  -n, --no-logs     do not follow logs after starting"
312    }
313
314    local no_logs=false
315    while [[ "$#" -gt 0 ]]; do
316        case "$1" in
317            -n|--no-logs)
318                no_logs=true
319            ;;
320            -h|--help)
321                help
322                exit 0
323            ;;
324            *)
325                echo "Error: Invalid option: $1" >&2
326                help
327                exit 0
328            ;;
329        esac
330        shift
331    done
332
333    # Check if marzneshin is installed
334    if ! is_marzneshin_installed; then
335        colorized_echo red "Marzneshin is not installed!"
336        exit 1
337    fi
338
339    detect_compose
340
341    if is_marzneshin_up; then
342        colorized_echo red "Marzneshin is already up"
343        exit 1
344    fi
345
346    up_marzneshin
347    if [ "$no_logs" = false ]; then
348        follow_marzneshin_logs
349    fi
350}
351
352down_command() {
353
354    # Check if marzneshin is installed
355    if ! is_marzneshin_installed; then
356        colorized_echo red "Marzneshin's not installed!"
357        exit 1
358    fi
359
360    detect_compose
361
362    if ! is_marzneshin_up; then
363        colorized_echo red "Marzneshin's already down"
364        exit 1
365    fi
366
367    down_marzneshin
368}
369
370restart_command() {
371    help() {
372        colorized_echo red "Usage: $0 restart [options]"
373        echo
374        echo "OPTIONS:"
375        echo "  -h, --help        display this help message"
376        echo "  -n, --no-logs     do not follow logs after starting"
377    }
378
379    local no_logs=false
380    while [[ "$#" -gt 0 ]]; do
381        case "$1" in
382            -n|--no-logs)
383                no_logs=true
384            ;;
385            -h|--help)
386                help
387                exit 0
388            ;;
389            *)
390                echo "Error: Invalid option: $1" >&2
391                help
392                exit 0
393            ;;
394        esac
395        shift
396    done
397
398    # Check if marzneshin is installed
399    if ! is_marzneshin_installed; then
400        colorized_echo red "Marzneshin's not installed!"
401        exit 1
402    fi
403
404    detect_compose
405
406    down_marzneshin
407    up_marzneshin
408    if [ "$no_logs" = false ]; then
409        follow_marzneshin_logs
410    fi
411}
412
413status_command() {
414
415    # Check if marzneshin is installed
416    if ! is_marzneshin_installed; then
417        echo -n "Status: "
418        colorized_echo red "Not Installed"
419        exit 1
420    fi
421
422    detect_compose
423
424    if ! is_marzneshin_up; then
425        echo -n "Status: "
426        colorized_echo blue "Down"
427        exit 1
428    fi
429
430    echo -n "Status: "
431    colorized_echo green "Up"
432
433    json=$($COMPOSE -f $COMPOSE_FILE ps -a --format=json)
434    services=$(echo "$json" | jq -r 'if type == "array" then .[] else . end | .Service')
435    states=$(echo "$json" | jq -r 'if type == "array" then .[] else . end | .State')
436    # Print out the service names and statuses
437    for i in $(seq 0 $(expr $(echo $services | wc -w) - 1)); do
438        service=$(echo $services | cut -d' ' -f $(expr $i + 1))
439        state=$(echo $states | cut -d' ' -f $(expr $i + 1))
440        echo -n "- $service: "
441        if [ "$state" == "running" ]; then
442            colorized_echo green $state
443        else
444            colorized_echo red $state
445        fi
446    done
447}
448
449logs_command() {
450    help() {
451        colorized_echo red "Usage: marzneshin logs [options]"
452        echo ""
453        echo "OPTIONS:"
454        echo "  -h, --help        display this help message"
455        echo "  -n, --no-follow   do not show follow logs"
456    }
457
458    local no_follow=false
459    while [[ "$#" -gt 0 ]]; do
460        case "$1" in
461            -n|--no-follow)
462                no_follow=true
463            ;;
464            -h|--help)
465                help
466                exit 0
467            ;;
468            *)
469                echo "Error: Invalid option: $1" >&2
470                help
471                exit 0
472            ;;
473        esac
474        shift
475    done
476
477    # Check if marzneshin is installed
478    if ! is_marzneshin_installed; then
479        colorized_echo red "Marzneshin is not installed!"
480        exit 1
481    fi
482
483    detect_compose
484
485    if ! is_marzneshin_up; then
486        colorized_echo red "Marzneshin is not up."
487        exit 1
488    fi
489
490    if [ "$no_follow" = true ]; then
491        show_marzneshin_logs
492    else
493        follow_marzneshin_logs
494    fi
495}
496
497cli_command() {
498    # Check if marzneshin is installed
499    if ! is_marzneshin_installed; then
500        colorized_echo red "Marzneshin is not installed!"
501        exit 1
502    fi
503
504    detect_compose
505
506    if ! is_marzneshin_up; then
507        colorized_echo red "Marzneshin is not up."
508        exit 1
509    fi
510
511    marzneshin_cli "$@"
512}
513
514update_command() {
515    check_running_as_root
516    # Check if marzneshin is installed
517    if ! is_marzneshin_installed; then
518        colorized_echo red "Marzneshin is not installed!"
519        exit 1
520    fi
521
522    detect_compose
523
524    update_marzneshin_script
525    colorized_echo blue "Pulling latest version"
526    update_marzneshin
527
528    colorized_echo blue "Restarting Marzneshin's services"
529    down_marzneshin
530    up_marzneshin
531
532    colorized_echo blue "Marzneshin updated successfully"
533}
534
535
536usage() {
537    colorized_echo red "Usage: $0 [command]"
538    echo
539    echo "Commands:"
540    echo "  up              Start services"
541    echo "  down            Stop services"
542    echo "  restart         Restart services"
543    echo "  status          Show status"
544    echo "  logs            Show logs"
545    echo "  cli             Marzneshin command-line interface"
546    echo "  install         Install Marzneshin"
547    echo "  update          Update latest version"
548    echo "  uninstall       Uninstall Marzneshin"
549    echo "  install-script  Install Marzneshin script"
550    echo
551}
552
553case "$1" in
554    up)
555    shift; up_command "$@";;
556    down)
557    shift; down_command "$@";;
558    restart)
559    shift; restart_command "$@";;
560    status)
561    shift; status_command "$@";;
562    logs)
563    shift; logs_command "$@";;
564    cli)
565    shift; cli_command "$@";;
566    install)
567    shift; install_command "$@";;
568    update)
569    shift; update_command "$@";;
570    uninstall)
571    shift; uninstall_command "$@";;
572    install-script)
573    shift; install_marzneshin_script "$@";;
574    *)
575    usage;;
576esac