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