gitscope
← marzneshin / v0.2.1 / script.sh
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    curl -sL "https://raw.githubusercontent.com/khodedawsh/marznode" -o "$NODE_DATA_DIR/xray_config.json"
149    colorized_echo green "Sample xray config downloaded for marznode"
150}
151
152uninstall_marzneshin_script() {
153    if [ -f "/usr/local/bin/marzneshin" ]; then
154        colorized_echo yellow "Removing marzneshin script"
155        rm "/usr/local/bin/marzneshin"
156    fi
157}
158
159uninstall_marzneshin() {
160    if [ -d "$CONFIG_DIR" ]; then
161        colorized_echo yellow "Removing directory: $CONFIG_DIR"
162        rm -r "$CONFIG_DIR"
163    fi
164}
165
166uninstall_marzneshin_docker_images() {
167    images=$(docker images | grep marzneshin | awk '{print $3}')
168
169    if [ -n "$images" ]; then
170        colorized_echo yellow "Removing Docker images of Marzneshin"
171        for image in $images; do
172            if docker rmi "$image" >/dev/null 2>&1; then
173                colorized_echo yellow "Image $image removed"
174            fi
175        done
176    fi
177}
178
179uninstall_marzneshin_data_files() {
180    if [ -d "$DATA_DIR" ]; then
181        colorized_echo yellow "Removing directory: $DATA_DIR"
182        rm -r "$DATA_DIR"
183    fi
184}
185
186uninstall_marznode_data_files() {
187    if [ -d "$NODE_DATA_DIR" ]; then
188        colorized_echo yellow "Removing directory: $NODE_DATA_DIR"
189        rm -r "$NODE_DATA_DIR"
190    fi
191}
192
193
194up_marzneshin() {
195    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" up -d --remove-orphans
196}
197
198down_marzneshin() {
199    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" down
200}
201
202show_marzneshin_logs() {
203    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" logs
204}
205
206follow_marzneshin_logs() {
207    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" logs -f
208}
209
210marzneshin_cli() {
211    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" exec -e CLI_PROG_NAME="marzneshin cli" marzneshin /app/marzneshin-cli.py "$@"
212}
213
214
215update_marzneshin_script() {
216    FETCH_REPO="khodedawsh/marzneshin"
217    SCRIPT_URL="https://github.com/$FETCH_REPO/raw/master/script.sh"
218    colorized_echo blue "Updating marzneshin script"
219    curl -sSL $SCRIPT_URL | install -m 755 /dev/stdin /usr/local/bin/marzneshin
220    colorized_echo green "marzneshin script updated successfully"
221}
222
223update_marzneshin() {
224    $COMPOSE -f $COMPOSE_FILE -p "$APP_NAME" pull
225}
226
227is_marzneshin_installed() {
228    if [ -d $CONFIG_DIR ]; then
229        return 0
230    else
231        return 1
232    fi
233}
234
235is_marzneshin_up() {
236    if [ -z "$($COMPOSE -f $COMPOSE_FILE ps -q -a)" ]; then
237        return 1
238    else
239        return 0
240    fi
241}
242
243install_command() {
244    check_running_as_root
245    # Check if marzneshin is already installed
246    if is_marzneshin_installed; then
247        colorized_echo red "Marzneshin is already installed at $CONFIG_DIR"
248        read -p "Do you want to override the previous installation? (y/n) "
249        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
250            colorized_echo red "Aborted installation"
251            exit 1
252        fi
253    fi
254    detect_os
255    if ! command -v jq >/dev/null 2>&1; then
256        install_package jq
257    fi
258    if ! command -v curl >/dev/null 2>&1; then
259        install_package curl
260    fi
261    if ! command -v docker >/dev/null 2>&1; then
262        install_docker
263    fi
264    detect_compose
265    install_marzneshin_script
266    install_marzneshin
267    install_marznode_xray_config
268    up_marzneshin
269    follow_marzneshin_logs
270}
271
272uninstall_command() {
273    check_running_as_root
274    # Check if marzneshin is installed
275    if ! is_marzneshin_installed; then
276        colorized_echo red "Marzneshin's not installed!"
277        exit 1
278    fi
279
280    read -p "Do you really want to uninstall Marzneshin? (y/n) "
281    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
282        colorized_echo red "Aborted"
283        exit 1
284    fi
285
286    detect_compose
287    if is_marzneshin_up; then
288        down_marzneshin
289    fi
290    uninstall_marzneshin_script
291    uninstall_marzneshin
292    uninstall_marzneshin_docker_images
293
294    read -p "Do you want to remove marzneshin & marznode data files too ($NODE_DATA_DIR, $DATA_DIR)? (y/n) "
295    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
296        colorized_echo green "Marzneshin uninstalled successfully"
297    else
298        uninstall_marzneshin_data_files
299	uninstall_marznode_data_files
300        colorized_echo green "Marzneshin uninstalled successfully"
301    fi
302}
303
304up_command() {
305    help() {
306        colorized_echo red "Usage: $0 up [options]"
307        echo ""
308        echo "OPTIONS:"
309        echo "  -h, --help        display this help message"
310        echo "  -n, --no-logs     do not follow logs after starting"
311    }
312
313    local no_logs=false
314    while [[ "$#" -gt 0 ]]; do
315        case "$1" in
316            -n|--no-logs)
317                no_logs=true
318            ;;
319            -h|--help)
320                help
321                exit 0
322            ;;
323            *)
324                echo "Error: Invalid option: $1" >&2
325                help
326                exit 0
327            ;;
328        esac
329        shift
330    done
331
332    # Check if marzneshin is installed
333    if ! is_marzneshin_installed; then
334        colorized_echo red "Marzneshin is not installed!"
335        exit 1
336    fi
337
338    detect_compose
339
340    if is_marzneshin_up; then
341        colorized_echo red "Marzneshin is already up"
342        exit 1
343    fi
344
345    up_marzneshin
346    if [ "$no_logs" = false ]; then
347        follow_marzneshin_logs
348    fi
349}
350
351down_command() {
352
353    # Check if marzneshin is installed
354    if ! is_marzneshin_installed; then
355        colorized_echo red "Marzneshin's not installed!"
356        exit 1
357    fi
358
359    detect_compose
360
361    if ! is_marzneshin_up; then
362        colorized_echo red "Marzneshin's already down"
363        exit 1
364    fi
365
366    down_marzneshin
367}
368
369restart_command() {
370    help() {
371        colorized_echo red "Usage: $0 restart [options]"
372        echo
373        echo "OPTIONS:"
374        echo "  -h, --help        display this help message"
375        echo "  -n, --no-logs     do not follow logs after starting"
376    }
377
378    local no_logs=false
379    while [[ "$#" -gt 0 ]]; do
380        case "$1" in
381            -n|--no-logs)
382                no_logs=true
383            ;;
384            -h|--help)
385                help
386                exit 0
387            ;;
388            *)
389                echo "Error: Invalid option: $1" >&2
390                help
391                exit 0
392            ;;
393        esac
394        shift
395    done
396
397    # Check if marzneshin is installed
398    if ! is_marzneshin_installed; then
399        colorized_echo red "Marzneshin's not installed!"
400        exit 1
401    fi
402
403    detect_compose
404
405    down_marzneshin
406    up_marzneshin
407    if [ "$no_logs" = false ]; then
408        follow_marzneshin_logs
409    fi
410}
411
412status_command() {
413
414    # Check if marzneshin is installed
415    if ! is_marzneshin_installed; then
416        echo -n "Status: "
417        colorized_echo red "Not Installed"
418        exit 1
419    fi
420
421    detect_compose
422
423    if ! is_marzneshin_up; then
424        echo -n "Status: "
425        colorized_echo blue "Down"
426        exit 1
427    fi
428
429    echo -n "Status: "
430    colorized_echo green "Up"
431
432    json=$($COMPOSE -f $COMPOSE_FILE ps -a --format=json)
433    services=$(echo "$json" | jq -r 'if type == "array" then .[] else . end | .Service')
434    states=$(echo "$json" | jq -r 'if type == "array" then .[] else . end | .State')
435    # Print out the service names and statuses
436    for i in $(seq 0 $(expr $(echo $services | wc -w) - 1)); do
437        service=$(echo $services | cut -d' ' -f $(expr $i + 1))
438        state=$(echo $states | cut -d' ' -f $(expr $i + 1))
439        echo -n "- $service: "
440        if [ "$state" == "running" ]; then
441            colorized_echo green $state
442        else
443            colorized_echo red $state
444        fi
445    done
446}
447
448logs_command() {
449    help() {
450        colorized_echo red "Usage: marzneshin logs [options]"
451        echo ""
452        echo "OPTIONS:"
453        echo "  -h, --help        display this help message"
454        echo "  -n, --no-follow   do not show follow logs"
455    }
456
457    local no_follow=false
458    while [[ "$#" -gt 0 ]]; do
459        case "$1" in
460            -n|--no-follow)
461                no_follow=true
462            ;;
463            -h|--help)
464                help
465                exit 0
466            ;;
467            *)
468                echo "Error: Invalid option: $1" >&2
469                help
470                exit 0
471            ;;
472        esac
473        shift
474    done
475
476    # Check if marzneshin is installed
477    if ! is_marzneshin_installed; then
478        colorized_echo red "Marzneshin is not installed!"
479        exit 1
480    fi
481
482    detect_compose
483
484    if ! is_marzneshin_up; then
485        colorized_echo red "Marzneshin is not up."
486        exit 1
487    fi
488
489    if [ "$no_follow" = true ]; then
490        show_marzneshin_logs
491    else
492        follow_marzneshin_logs
493    fi
494}
495
496cli_command() {
497    # Check if marzneshin is installed
498    if ! is_marzneshin_installed; then
499        colorized_echo red "Marzneshin is not installed!"
500        exit 1
501    fi
502
503    detect_compose
504
505    if ! is_marzneshin_up; then
506        colorized_echo red "Marzneshin is not up."
507        exit 1
508    fi
509
510    marzneshin_cli "$@"
511}
512
513update_command() {
514    check_running_as_root
515    # Check if marzneshin is installed
516    if ! is_marzneshin_installed; then
517        colorized_echo red "Marzneshin is not installed!"
518        exit 1
519    fi
520
521    detect_compose
522
523    update_marzneshin_script
524    colorized_echo blue "Pulling latest version"
525    update_marzneshin
526
527    colorized_echo blue "Restarting Marzneshin's services"
528    down_marzneshin
529    up_marzneshin
530
531    colorized_echo blue "Marzneshin updated successfully"
532}
533
534
535usage() {
536    colorized_echo red "Usage: $0 [command]"
537    echo
538    echo "Commands:"
539    echo "  up              Start services"
540    echo "  down            Stop services"
541    echo "  restart         Restart services"
542    echo "  status          Show status"
543    echo "  logs            Show logs"
544    echo "  cli             Marzneshin command-line interface"
545    echo "  install         Install Marzneshin"
546    echo "  update          Update latest version"
547    echo "  uninstall       Uninstall Marzneshin"
548    echo "  install-script  Install Marzneshin script"
549    echo
550}
551
552case "$1" in
553    up)
554    shift; up_command "$@";;
555    down)
556    shift; down_command "$@";;
557    restart)
558    shift; restart_command "$@";;
559    status)
560    shift; status_command "$@";;
561    logs)
562    shift; logs_command "$@";;
563    cli)
564    shift; cli_command "$@";;
565    install)
566    shift; install_command "$@";;
567    update)
568    shift; update_command "$@";;
569    uninstall)
570    shift; uninstall_command "$@";;
571    install-script)
572    shift; install_marzneshin_script "$@";;
573    *)
574    usage;;
575esac