Update tools.func

This commit is contained in:
CanbiZ 2025-11-12 15:18:18 +01:00
parent a6f0a333a5
commit f9a5ea27f3

View File

@ -4628,3 +4628,214 @@ function setup_yq() {
cache_installed_version "yq" "$FINAL_VERSION" cache_installed_version "yq" "$FINAL_VERSION"
msg_ok "Setup yq $FINAL_VERSION" msg_ok "Setup yq $FINAL_VERSION"
} }
# ------------------------------------------------------------------------------
# Docker Engine Installation and Management (All-In-One)
#
# Description:
# - Detects and migrates old Docker installations
# - Installs/Updates Docker Engine via official repository
# - Optional: Installs/Updates Portainer CE
# - Updates running containers interactively
# - Cleans up legacy repository files
#
# Usage:
# setup_docker
# DOCKER_PORTAINER="true" setup_docker
# DOCKER_LOG_DRIVER="json-file" setup_docker
#
# Variables:
# DOCKER_PORTAINER - Install Portainer CE (optional, "true" to enable)
# DOCKER_LOG_DRIVER - Log driver (optional, default: "journald")
# DOCKER_SKIP_UPDATES - Skip container update check (optional, "true" to skip)
#
# Features:
# - Migrates from get.docker.com to repository-based installation
# - Updates Docker Engine if newer version available
# - Interactive container update with multi-select
# - Portainer installation and update support
# ------------------------------------------------------------------------------
function setup_docker() {
local docker_installed=false
local portainer_installed=false
# Check if Docker is already installed
if command -v docker &>/dev/null; then
docker_installed=true
DOCKER_CURRENT_VERSION=$(docker --version | grep -oP '\d+\.\d+\.\d+' | head -1)
msg_info "Docker $DOCKER_CURRENT_VERSION detected"
fi
# Check if Portainer is running
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q '^portainer$'; then
portainer_installed=true
msg_info "Portainer container detected"
fi
# Cleanup old repository configurations
if [ -f /etc/apt/sources.list.d/docker.list ]; then
msg_info "Migrating from old Docker repository format"
rm -f /etc/apt/sources.list.d/docker.list
rm -f /etc/apt/keyrings/docker.asc
fi
# Setup/Update Docker repository
msg_info "Setting up Docker Repository"
setup_deb822_repo \
"docker" \
"https://download.docker.com/linux/$(get_os_info id)/gpg" \
"https://download.docker.com/linux/$(get_os_info id)" \
"$(get_os_info codename)" \
"stable" \
"$(dpkg --print-architecture)"
# Install or upgrade Docker
if [ "$docker_installed" = true ]; then
msg_info "Checking for Docker updates"
DOCKER_LATEST_VERSION=$(apt-cache policy docker-ce | grep Candidate | awk '{print $2}' | cut -d':' -f2 | cut -d'-' -f1)
if [ "$DOCKER_CURRENT_VERSION" != "$DOCKER_LATEST_VERSION" ]; then
msg_info "Updating Docker $DOCKER_CURRENT_VERSION → $DOCKER_LATEST_VERSION"
$STD apt-get install -y --only-upgrade \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
msg_ok "Updated Docker to $DOCKER_LATEST_VERSION"
else
msg_ok "Docker is up-to-date ($DOCKER_CURRENT_VERSION)"
fi
else
msg_info "Installing Docker"
$STD apt-get install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
DOCKER_CURRENT_VERSION=$(docker --version | grep -oP '\d+\.\d+\.\d+' | head -1)
msg_ok "Installed Docker $DOCKER_CURRENT_VERSION"
fi
# Configure daemon.json
local log_driver="${DOCKER_LOG_DRIVER:-journald}"
mkdir -p /etc/docker
if [ ! -f /etc/docker/daemon.json ]; then
cat <<EOF >/etc/docker/daemon.json
{
"log-driver": "$log_driver"
}
EOF
fi
# Enable and start Docker
systemctl enable -q --now docker
# Portainer Management
if [[ "${DOCKER_PORTAINER:-}" == "true" ]]; then
if [ "$portainer_installed" = true ]; then
msg_info "Checking for Portainer updates"
PORTAINER_CURRENT=$(docker inspect portainer --format='{{.Config.Image}}' 2>/dev/null | cut -d':' -f2)
PORTAINER_LATEST=$(curl -fsSL https://registry.hub.docker.com/v2/repositories/portainer/portainer-ce/tags?page_size=100 | grep -oP '"name":"\K[0-9]+\.[0-9]+\.[0-9]+"' | head -1 | tr -d '"')
if [ "$PORTAINER_CURRENT" != "$PORTAINER_LATEST" ]; then
read -r -p "${TAB3}Update Portainer $PORTAINER_CURRENT → $PORTAINER_LATEST? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Updating Portainer"
docker stop portainer
docker rm portainer
docker pull portainer/portainer-ce:latest
docker run -d \
-p 9000:9000 \
-p 9443:9443 \
--name=portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
msg_ok "Updated Portainer to $PORTAINER_LATEST"
fi
else
msg_ok "Portainer is up-to-date ($PORTAINER_CURRENT)"
fi
else
msg_info "Installing Portainer"
docker volume create portainer_data
docker run -d \
-p 9000:9000 \
-p 9443:9443 \
--name=portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
LOCAL_IP=$(hostname -I | awk '{print $1}')
msg_ok "Installed Portainer (http://${LOCAL_IP}:9000)"
fi
fi
# Interactive Container Update Check
if [[ "${DOCKER_SKIP_UPDATES:-}" != "true" ]] && [ "$docker_installed" = true ]; then
msg_info "Checking for container updates"
# Get list of running containers with update status
local containers_with_updates=()
local container_info=()
local index=1
while IFS= read -r container; do
local name=$(echo "$container" | awk '{print $1}')
local image=$(echo "$container" | awk '{print $2}')
local current_digest=$(docker inspect "$name" --format='{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
# Pull latest image digest
docker pull "$image" >/dev/null 2>&1
local latest_digest=$(docker inspect "$image" --format='{{.Id}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
if [ "$current_digest" != "$latest_digest" ]; then
containers_with_updates+=("$name")
container_info+=("${index}) ${name} (${image})")
((index++))
fi
done < <(docker ps --format '{{.Names}} {{.Image}}')
if [ ${#containers_with_updates[@]} -gt 0 ]; then
echo ""
echo "${TAB3}Container updates available:"
for info in "${container_info[@]}"; do
echo "${TAB3} $info"
done
echo ""
read -r -p "${TAB3}Select containers to update (e.g., 1,3,5 or 'all' or 'none'): " selection
if [[ ${selection,,} == "all" ]]; then
for container in "${containers_with_updates[@]}"; do
msg_info "Updating container: $container"
docker stop "$container"
docker rm "$container"
# Note: This requires the original docker run command - best to recreate via compose
msg_ok "Stopped and removed $container (please recreate with updated image)"
done
elif [[ ${selection,,} != "none" ]]; then
IFS=',' read -ra SELECTED <<<"$selection"
for num in "${SELECTED[@]}"; do
num=$(echo "$num" | xargs) # trim whitespace
if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le "${#containers_with_updates[@]}" ]; then
container="${containers_with_updates[$((num - 1))]}"
msg_info "Updating container: $container"
docker stop "$container"
docker rm "$container"
msg_ok "Stopped and removed $container (please recreate with updated image)"
fi
done
fi
else
msg_ok "All containers are up-to-date"
fi
fi
msg_ok "Docker setup completed"
}