From 21311998af8d9a127108799e4c5f1af910c99a2c Mon Sep 17 00:00:00 2001 From: Stepan Kasatkin Date: Sat, 22 Mar 2025 20:29:06 +0300 Subject: [PATCH] Initial commit --- docker-install.sh | 320 ++++++++++++++++++++++++++++++++++++++++++++++ version | 2 + 2 files changed, 322 insertions(+) create mode 100644 docker-install.sh create mode 100644 version diff --git a/docker-install.sh b/docker-install.sh new file mode 100644 index 0000000..4db2962 --- /dev/null +++ b/docker-install.sh @@ -0,0 +1,320 @@ +#!/bin/bash + +VERSION="1.0.0" +VERSION_NUM="1" +LAST_UPDATE="22.03.2025" + +GITLAB_URL="https://gl.wssk.ru/skasatkin/docker-rootless-install" + +GREEN=$(tput setaf 2) +RESET=$(tput sgr0) +RED=$(tput setaf 1) +CYAN=$(tput setaf 6) + +TIMESTAMP=$(date +"%Y%m%d-%H%M%S") +LOG_DIR="./.docker-install" +LOG_FILE="$LOG_DIR/$TIMESTAMP.log" + +mkdir -p "$LOG_DIR" + +find "$LOG_DIR" -type f -mtime +7 -exec rm {} \; + +function log() { + echo -e "$1" >> "$LOG_FILE" +} + +function progress() { + echo -ne "\r${CYAN}$1${RESET}\033[K" +} + +function done_msg() { + echo -e "\r${GREEN}✔ $1${RESET}\033[K" + log "✔ $1" +} + +function error_msg() { + echo -e "\r${RED}✖ $1${RESET}\033[K" + log "✖ $1" +} + +function run_with_live_tail() { + local command="$1" + local lines=4 + local buffer=() + local prev_output="" + + echo -e "${CYAN}$progress_message${RESET}" + + for ((i=0; i<$lines; i++)); do + echo "" + done + + move_cursor_up() { + echo -en "\033[${lines}A" + } + + eval "$command" 2>&1 | while IFS= read -r line; do + log "$line" + + if [[ "$line" == "$prev_output" ]]; then + continue + fi + prev_output="$line" + + buffer+=("$line") + if [ "${#buffer[@]}" -gt "$lines" ]; then + buffer=("${buffer[@]: -$lines}") + fi + + move_cursor_up + + for ((i=0; i<$lines; i++)); do + local output="${buffer[$i]}" + echo -en "\033[2K" + echo "$output" + done + done + + move_cursor_up + for ((i=0; i<$lines; i++)); do + echo -en "\033[2K" + echo "" + done +} + +function self_update() { + echo -e "${CYAN}Проверка обновлений...${RESET}" + + version_file=$(curl -s "$GITLAB_URL/-/raw/main/version") + + remote_version=$(echo "$version_file" | grep VERSION= | cut -d '=' -f2 | tr -d '"' | tr -d '\r') + remote_version_num=$(echo "$version_file" | grep VERSION_NUM= | cut -d '=' -f2 | tr -d '"' | tr -d '\r') + + + echo -e "${CYAN}Получена версия: ${remote_version} (${remote_version_num})${RESET}" + + if [[ $remote_version_num -gt $VERSION_NUM ]]; then + echo -e "${GREEN}Доступна новая версия: ${remote_version} (${remote_version_num})${RESET}" + echo -e "${CYAN}Скачиваю обновление...${RESET}" + + curl -s -o docker-install.sh "$GITLAB_URL/-/raw/main/docker-install.sh" && \ + chmod +x docker-install.sh + + echo -e "${GREEN}✅ Обновление завершено! Перезапусти скрипт.${RESET}" + f_exit + else + echo -e "${GREEN}Установлена последняя версия: $VERSION${RESET}" + fi +} + + +function install_docker() { + clear + log "=== Установка Docker (rootless)... ===" + echo -e "${GREEN}Установка Docker (rootless)...${RESET}" + + if [ -f "$HOME/bin/dockerd" ]; then + error_msg "⚠️ Rootless Docker уже установлен в $HOME/bin/dockerd" + echo "" + echo "👉 Для переустановки останови и удали:" + echo " systemctl --user stop docker" + echo " rm -f ~/bin/dockerd" + echo "" + echo -e "${RED}❗ Возвращаюсь в меню через 5 секунд...${RESET}" + sleep 5 + return 1 + fi + + progress_message="⏳ Устанавливаю Docker (rootless)..." + run_with_live_tail "curl -fsSL https://get.docker.com/rootless | sh'" + clear + + if [ $? -eq 0 ]; then + done_msg "Docker успешно установлен!" + else + error_msg "Ошибка при установке Docker!" + sleep 5 + return 1 + fi + + progress "⏳ Добавляю переменные окружения..." + grep -qxF 'export PATH=$HOME/bin:$PATH' ~/.bashrc || echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc + grep -qxF 'export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock' ~/.bashrc || echo 'export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock' >> ~/.bashrc + source ~/.bashrc + done_msg "Переменные окружения добавлены." + + echo -e "${CYAN}ℹ️ Но они могут не примениться. Поэтому перезайди в сессию или выполни:${RESET}" + echo -e "source ~/.bashrc" + + progress "⏳ Запускаю и активирую Docker (user systemd)..." + systemctl --user start docker + systemctl --user enable docker + done_msg "Docker запущен и добавлен в автозагрузку." + + return 0 +} + +function install_compose() { + clear + log "=== Установка Docker Compose... ===" + echo -e "${GREEN}Установка Docker Compose...${RESET}" + + if [ -f "$HOME/.docker/cli-plugins/docker-compose" ]; then + error_msg "⚠️ Docker Compose уже установлен в ~/.docker/cli-plugins/docker-compose" + echo "" + echo "👉 Для переустановки удали:" + echo " rm -f ~/.docker/cli-plugins/docker-compose" + echo "" + echo -e "${RED}❗ Возвращаюсь в меню через 5 секунд...${RESET}" + sleep 5 + return 1 + fi + + progress "⏳ Создаю папку для docker-compose..." + mkdir -p ~/.docker/cli-plugins/ + done_msg "Папка ~/.docker/cli-plugins готова." + + progress_message="⏳ Скачиваю Docker Compose..." + run_with_live_tail "curl -SL \"https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64\" -o ~/.docker/cli-plugins/docker-compose" + + if [ $? -eq 0 ]; then + done_msg "Docker Compose скачан!" + else + error_msg "Ошибка при скачивании Docker Compose!" + sleep 5 + return 1 + fi + + progress "⏳ Делаю docker-compose исполняемым..." + chmod +x ~/.docker/cli-plugins/docker-compose + done_msg "Права на выполнение добавлены." + + progress "⏳ Добавляю docker-compose в PATH..." + grep -qxF 'export PATH=$HOME/.docker/cli-plugins:$PATH' ~/.bashrc || echo 'export PATH=$HOME/.docker/cli-plugins:$PATH' >> ~/.bashrc + source ~/.bashrc + done_msg "Переменная окружения обновлена." + + return 0 +} + +function remove_docker() { + clear + log "=== Удаление Rootless Docker ===" + echo -e "${RED}⚠️ Это удалит Rootless Docker, Compose и ВСЕ данные пользователя!${RESET}" + + whiptail --title "Удаление Rootless Docker" --yesno "Действительно хочешь удалить Rootless Docker, Compose и ВСЕ данные?" 12 60 + response=$? + + if [[ $response -eq 0 ]]; then + progress "⏳ Удаляю контейнеры, тома и образы..." + if command -v docker >/dev/null 2>&1; then + docker container rm -f $(docker ps -aq) 2>/dev/null + docker volume rm $(docker volume ls -q) 2>/dev/null + docker image rm -f $(docker image ls -q) 2>/dev/null + done_msg "Контейнеры, тома и образы удалены." + else + error_msg "Docker не найден. Пропускаю удаление контейнеров и томов." + fi + + progress "⏳ Останавливаю Rootless Docker (user)..." + systemctl --user stop docker 2>/dev/null + systemctl --user disable docker 2>/dev/null + done_msg "Rootless Docker остановлен." + + progress "⏳ Удаляю systemd user сервисы..." + rm -f ~/.config/systemd/user/docker.service ~/.config/systemd/user/docker.socket + done_msg "Юниты удалены." + + progress "⏳ Удаляю исполняемые файлы Docker..." + rm -rf ~/bin/docker* 2>/dev/null + done_msg "Файлы из ~/bin удалены." + + progress "⏳ Чищу Docker data каталоги..." + rm -rf ~/.local/share/docker ~/.docker + done_msg "Данные Docker, какие возможно, удалены." + echo -e "Если что-то осталось, и важно удалить, напиши мне." + + echo -e "${GREEN}✔ Rootless Docker и все данные удалены!${RESET}" + else + error_msg "❌ Удаление отменено пользователем." + sleep 3 + return 1 + fi +} + +function f_exit() { + log "=== Завершение скрипта ===" + log "exit code: ${1:-0}" + echo -e "> logfile: $LOG_FILE" + echo "" + echo -e "${CYAN}Версия: $VERSION${RESET}" + echo -e "${CYAN}Последнее обновление: $LAST_UPDATE${RESET}" + echo -e "> logfile: $LOG_FILE" + echo "" + echo -e "${CYAN}ℹ️ Если менялись переменные окружения, они могут не примениться. Поэтому перезайди в сессию или выполни:${RESET}" + echo -e "source ~/.bashrc" + exit ${1:-0} +} + +function menu() { + while true; do + CHOICE=$(whiptail --title "Docker & Docker Compose ${VERSION}" --menu "\n\ + Stеpan Kasatkin\n\ + Версия: ${VERSION} | Обновлен: ${LAST_UPDATE}\n\n\ + Выбери действие (стрелки + Enter):" \ + 22 70 10 \ + "1" "Установить Docker (rootless)" \ + "2" "Установить Docker Compose" \ + "3" "Установить Docker + Compose" \ + "4" "Удалить Docker и ВСЕ данные" \ + "0" "Выход" 3>&1 1>&2 2>&3) + + + + RETVAL=$? + + if [[ $RETVAL -eq 1 || $RETVAL -eq 255 ]]; then + error_msg "❌ Отменено пользователем." + f_exit 1 + fi + + case $CHOICE in + 1) + install_docker + ;; + 2) + install_compose + ;; + 3) + install_docker + docker_status=$? + install_compose + compose_status=$? + + if [[ $docker_status -eq 0 && $compose_status -eq 0 ]]; then + done_msg "✅ Установка Docker и Compose завершена." + echo -e "${GREEN}👉 Проверка версий:${RESET}" + echo "docker --version" + echo "docker-compose version" + f_exit + fi + ;; + 4) + remove_docker + ;; + 0) + echo -e "${GREEN}Выход...${RESET}" + f_exit + ;; + *) + error_msg "❌ Неверный выбор!" + ;; + esac + done +} + +clear +echo -e "${GREEN}Docker & Docker Compose, Stepan Kasatkin${RESET}" +log "=== Запуск установщика Docker & Compose ===" +self_update +menu diff --git a/version b/version new file mode 100644 index 0000000..c793702 --- /dev/null +++ b/version @@ -0,0 +1,2 @@ +VERSION="1.0.0" +VERSION_NUM="100" \ No newline at end of file