From 0b9a1f61dccdc11aa2566e52a129a6100533b895 Mon Sep 17 00:00:00 2001 From: Christopher Date: Fri, 5 Dec 2025 19:00:09 -0600 Subject: [PATCH 1/2] Improve Docker downgrade robustness and version reporting Enhances the downgrade_docker function to retry apt-get installs, verify package installation after errors, and provide more detailed status and version reporting for containerd. Also updates package hold/unhold logic to include docker-ce-rootless-extras and improves logging in both run.sh and test-script.sh for better diagnostics and validation. --- casaos-fix-docker-api-version/run.sh | 170 ++++++++++++++----- casaos-fix-docker-api-version/test-script.sh | 32 +++- 2 files changed, 154 insertions(+), 48 deletions(-) diff --git a/casaos-fix-docker-api-version/run.sh b/casaos-fix-docker-api-version/run.sh index 7f42075..e174a2e 100755 --- a/casaos-fix-docker-api-version/run.sh +++ b/casaos-fix-docker-api-version/run.sh @@ -59,7 +59,7 @@ print_info() { } echo "==========================================" -echo "BigBear CasaOS Docker Version Fix Script 2025.12.0" +echo "BigBear CasaOS Docker Version Fix Script 2025.12.1" echo "==========================================" echo "" echo "Here are some links:" @@ -1110,7 +1110,7 @@ downgrade_docker() { # Hold Docker packages to prevent auto-upgrade echo "Configuring Docker packages to prevent auto-upgrade..." - $SUDO apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 2>/dev/null || true + $SUDO apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 2>/dev/null || true echo "" # Check if Docker is already installed and remove it to ensure clean downgrade @@ -1124,7 +1124,7 @@ downgrade_docker() { timeout 30 $SUDO systemctl stop containerd 2>/dev/null || true sleep 2 - $SUDO apt-get remove --purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 2>/dev/null || true + $SUDO apt-get remove --purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 2>/dev/null || true # Clean up unused dependencies echo "Cleaning up unused dependencies..." @@ -1195,46 +1195,100 @@ downgrade_docker() { # Use timeout (10 minutes max for download/install) # Prevent services from starting during install to avoid hangs prevent_service_autostart - - if ! timeout 600 $SUDO apt-get install -y --allow-downgrades \ - docker-ce=${DOCKER_VERSION} \ - docker-ce-cli=${DOCKER_VERSION} \ - containerd.io=${CONTAINERD_FULL} \ - docker-buildx-plugin \ - docker-compose-plugin 2>&1 | tee /tmp/docker-install.log; then - allow_service_autostart - if [ ${PIPESTATUS[0]} -eq 124 ]; then - echo "" - echo "ERROR: Docker installation timed out after 10 minutes!" - echo "This usually means:" - echo " - Very slow network connection" - echo " - Repository mirror is overloaded or broken" - echo " - Package download is stuck" - echo "" - echo "Suggestion: Try the override.conf method instead to keep your current Docker" - else - echo "" - echo "ERROR: Docker installation failed!" - echo "Please check your internet connection and try again." - echo "" - echo "Attempted to install:" - echo " docker-ce=${DOCKER_VERSION}" - echo " docker-ce-cli=${DOCKER_VERSION}" - echo " containerd.io=${CONTAINERD_FULL}" - echo "" - echo "Installation log saved to: /tmp/docker-install.log" - fi - return 1 + # Ensure we always restore policy-rc.d even on early return + trap "allow_service_autostart" RETURN + + local install_attempt=1 + local max_install_attempts=2 + local apt_success=false + + while [ $install_attempt -le $max_install_attempts ]; do + echo "apt-get install attempt ${install_attempt}/${max_install_attempts}..." + if timeout 600 $SUDO apt-get install -y --allow-downgrades \ + docker-ce=${DOCKER_VERSION} \ + docker-ce-cli=${DOCKER_VERSION} \ + containerd.io=${CONTAINERD_FULL} \ + docker-buildx-plugin \ + docker-compose-plugin 2>&1 | tee /tmp/docker-install.log; then + apt_success=true + break + fi + + echo "" + echo "⚠ apt-get returned an error, verifying package installation..." + + local docker_installed=false + local containerd_installed=false + + # Check if docker-ce was installed with correct version + if dpkg -l docker-ce 2>/dev/null | grep -q "${DOCKER_VERSION}"; then + echo "✓ docker-ce ${DOCKER_VERSION} is installed" + docker_installed=true + fi + + # Check if containerd.io was installed with correct version + if dpkg -l containerd.io 2>/dev/null | grep -q "${CONTAINERD_FULL}"; then + echo "✓ containerd.io ${CONTAINERD_FULL} is installed" + containerd_installed=true + fi + + # If both packages are installed correctly, treat as success + if [ "$docker_installed" = true ] && [ "$containerd_installed" = true ]; then + echo "" + echo "✓ Packages were installed successfully despite apt-get warnings" + echo "This is usually due to non-critical post-install script issues" + echo "" + apt_success=true + break + fi + + if [ $install_attempt -lt $max_install_attempts ]; then + echo "Retrying apt-get install in 5 seconds..." + sleep 5 + fi + install_attempt=$((install_attempt + 1)) + done + + if [ "$apt_success" != true ]; then + # Actual installation failure + if [ ${PIPESTATUS[0]} -eq 124 ]; then + echo "" + echo "ERROR: Docker installation timed out after 10 minutes!" + echo "This usually means:" + echo " - Very slow network connection" + echo " - Repository mirror is overloaded or broken" + echo " - Package download is stuck" + echo "" + echo "Suggestion: Try the override.conf method instead to keep your current Docker" + else + echo "" + echo "ERROR: Docker installation failed!" + echo "Please check your internet connection and try again." + echo "" + echo "Attempted to install:" + echo " docker-ce=${DOCKER_VERSION}" + echo " docker-ce-cli=${DOCKER_VERSION}" + echo " containerd.io=${CONTAINERD_FULL}" + echo "" + echo "Installation log saved to: /tmp/docker-install.log" + fi + return 1 fi + echo "" + echo "✓ Package installation completed successfully" + echo "Now restoring service auto-start and configuring Docker..." + echo "" + allow_service_autostart echo "✓ Successfully installed Docker 28.x (API 1.47/1.48)" + echo "✓ Service auto-start policy restored" echo "" # Hold packages to prevent auto-upgrade echo "Holding Docker packages at current version..." - $SUDO apt-mark hold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + $SUDO apt-mark hold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras echo "" # Verify the dockerd binary version before starting @@ -1256,10 +1310,11 @@ downgrade_docker() { echo "" # Reload systemd and restart Docker service - echo "Reloading systemd daemon..." + echo "Step 7.0: Reloading systemd daemon..." $SUDO systemctl daemon-reload # Wait for systemd to fully process the reload sleep 2 + echo "✓ Systemd daemon reloaded" echo "" # Ensure Docker is completely stopped before starting @@ -1271,32 +1326,50 @@ downgrade_docker() { # Use the new function to ensure processes are stopped ensure_docker_processes_stopped - # Stop containerd to ensure clean slate - echo "Restarting containerd for clean state..." + # Stop containerd completely to ensure new version is loaded + echo "Step 7.2.1: Restarting containerd for clean state..." + echo "Stopping containerd service..." timeout 30 $SUDO systemctl stop containerd 2>/dev/null || true sleep 2 + + # Kill any lingering containerd processes to ensure old binary is not running if pgrep -x containerd >/dev/null 2>&1; then + echo "Forcefully stopping lingering containerd processes (to load new version)..." $SUDO pkill -9 containerd 2>/dev/null || true + sleep 3 + fi + + # Kill containerd-shim processes too + if pgrep containerd-shim >/dev/null 2>&1; then + echo "Stopping containerd-shim processes..." + $SUDO pkill -9 containerd-shim 2>/dev/null || true sleep 2 fi + + echo "Starting containerd with new version..." $SUDO systemctl start containerd 2>/dev/null || true # Wait for containerd to be fully ready before starting Docker echo "Waiting for containerd to be fully ready..." local containerd_ready=false - for i in {1..10}; do + for i in {1..15}; do if $SUDO systemctl is-active --quiet containerd 2>/dev/null; then containerd_ready=true echo "✓ containerd is ready" break fi - echo " Waiting for containerd... ($i/10)" + echo " Waiting for containerd... ($i/15)" sleep 1 done if [ "$containerd_ready" = false ]; then echo "⚠ WARNING: containerd may not be fully ready, proceeding anyway..." fi + + # Verify containerd binary version after restart + echo "Verifying containerd version..." + local containerd_version=$(timeout 5 containerd --version 2>/dev/null | head -n1 || echo "unknown") + echo "containerd binary: $containerd_version" echo "" # Enable and start docker socket first, then service @@ -1338,10 +1411,10 @@ downgrade_docker() { echo "==========================================" echo "" echo "Checking Docker status and logs..." - timeout 10 $SUDO systemctl status docker --no-pager -l || true + timeout 10 $SUDO systemctl status docker --no-pager -l | tee -a /tmp/docker-install.log || true echo "" echo "Recent Docker logs:" - timeout 10 $SUDO journalctl -u docker --no-pager -n 50 || true + timeout 10 $SUDO journalctl -u docker --no-pager -n 50 | tee -a /tmp/docker-install.log || true echo "" # Attempt to detect and fix the error @@ -1638,7 +1711,7 @@ main() { case "$1" in apply-override|override) echo "==========================================" - echo "BigBear CasaOS Docker Version Fix Script 2025.12.0" + echo "BigBear CasaOS Docker Version Fix Script 2025.12.1" echo "==========================================" echo "" apply_docker_api_override @@ -1646,7 +1719,7 @@ main() { ;; remove-override|no-override) echo "==========================================" - echo "BigBear CasaOS Docker Version Fix Script 2025.12.0" + echo "BigBear CasaOS Docker Version Fix Script 2025.12.1" echo "==========================================" echo "" remove_docker_api_override @@ -1654,7 +1727,7 @@ main() { ;; help|--help|-h) echo "==========================================" - echo "BigBear CasaOS Docker Version Fix Script 2025.12.0" + echo "BigBear CasaOS Docker Version Fix Script 2025.12.1" echo "==========================================" echo "" show_usage @@ -2086,9 +2159,18 @@ main() { echo "Docker Configuration Complete!" echo "==========================================" echo "" + + local containerd_pkg_version + containerd_pkg_version=$(dpkg -l containerd.io 2>/dev/null | awk 'NR>5 {print $3; exit}') + local containerd_bin_version + containerd_bin_version=$(timeout 5 containerd --version 2>/dev/null | head -n1) + echo "Installed Docker Package Versions:" timeout 10 dpkg -l 2>/dev/null | grep -E "docker-ce|containerd.io" | awk '{print " " $2 " = " $3}' || echo "Unable to query package versions" echo "" + echo "Containerd Package Version: ${containerd_pkg_version:-unknown}" + echo "Containerd Binary Version: ${containerd_bin_version:-Unable to get containerd binary version}" + echo "" echo "Docker Version Information:" timeout 10 $SUDO docker version 2>&1 || echo "Unable to get Docker version" echo "" diff --git a/casaos-fix-docker-api-version/test-script.sh b/casaos-fix-docker-api-version/test-script.sh index 6412a53..3ce816e 100755 --- a/casaos-fix-docker-api-version/test-script.sh +++ b/casaos-fix-docker-api-version/test-script.sh @@ -97,10 +97,14 @@ show_status() { local docker_version=$(get_docker_version) local api_version=$(get_docker_api_version) local dockerd_version=$(get_dockerd_binary_version) + local containerd_pkg=$(dpkg -l 2>/dev/null | grep containerd.io | awk 'NR==1 {print $3}') + local containerd_bin=$(containerd --version 2>/dev/null | awk '{print $3}') echo "Docker daemon version: $docker_version" echo "Docker API version: $api_version" echo "dockerd binary version: $dockerd_version" + echo "containerd package: ${containerd_pkg:-unknown}" + echo "containerd binary: ${containerd_bin:-unknown}" echo "" # Show package versions @@ -303,7 +307,7 @@ upgrade_docker_to_latest() { # Unhold packages if they're held print_info "Unholding Docker packages..." - $SUDO apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 2>/dev/null || true + $SUDO apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 2>/dev/null || true echo "" # Setup Docker repository if not already present @@ -337,7 +341,8 @@ upgrade_docker_to_latest() { docker-ce-cli \ containerd.io \ docker-buildx-plugin \ - docker-compose-plugin; then + docker-compose-plugin \ + docker-ce-rootless-extras; then print_success "Docker upgraded to latest version" else print_error "Failed to upgrade Docker" @@ -420,10 +425,14 @@ test_fix_script() { local after_version=$(get_docker_version) local after_api=$(get_docker_api_version) local dockerd_binary=$(get_dockerd_binary_version) + local containerd_pkg=$(dpkg -l 2>/dev/null | grep containerd.io | awk 'NR==1 {print $3}') + local containerd_bin=$(containerd --version 2>/dev/null | awk '{print $3}') echo "Docker version after fix: $after_version" echo "API version after fix: $after_api" echo "dockerd binary version: $dockerd_binary" + echo "containerd package: ${containerd_pkg:-unknown}" + echo "containerd binary: ${containerd_bin:-unknown}" echo "" # Check package versions @@ -458,6 +467,20 @@ test_fix_script() { print_error "✗ dockerd binary is NOT 28.x (got: $dockerd_binary)" success=false fi + + # Check containerd package/bin match expected 1.7.28 + if echo "$containerd_pkg" | grep -q "1.7.28"; then + print_success "✓ containerd package is 1.7.28 (${containerd_pkg})" + else + print_error "✗ containerd package is not 1.7.28 (got: ${containerd_pkg:-unknown})" + success=false + fi + if echo "$containerd_bin" | grep -q "^1.7.28"; then + print_success "✓ containerd binary is 1.7.28 (${containerd_bin})" + else + print_error "✗ containerd binary is not 1.7.28 (got: ${containerd_bin:-unknown})" + success=false + fi # Check if Docker is running if $SUDO systemctl is-active --quiet docker; then @@ -547,7 +570,7 @@ install_docker_version() { # Unhold packages if they're held print_info "Unholding Docker packages..." - $SUDO apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 2>/dev/null || true + $SUDO apt-mark unhold docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 2>/dev/null || true echo "" # Setup Docker repository if not already present @@ -592,7 +615,8 @@ install_docker_version() { docker-ce-cli=$full_version \ containerd.io \ docker-buildx-plugin \ - docker-compose-plugin; then + docker-compose-plugin \ + docker-ce-rootless-extras; then print_success "Docker $version installed successfully" else print_error "Failed to install Docker $version" From 85c82640a4cd89c361b87b6240c2691990ff7fb6 Mon Sep 17 00:00:00 2001 From: Christopher Date: Fri, 5 Dec 2025 19:07:22 -0600 Subject: [PATCH 2/2] Refactor variable assignment and improve containerd version check Refactored variable assignments in run.sh and test-script.sh to use separate declaration and assignment for better readability and shell compatibility. Updated the containerd version check in test-script.sh to accept both '1.7.28' and 'v1.7.28' formats. --- casaos-fix-docker-api-version/run.sh | 3 ++- casaos-fix-docker-api-version/test-script.sh | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/casaos-fix-docker-api-version/run.sh b/casaos-fix-docker-api-version/run.sh index e174a2e..8dc844e 100755 --- a/casaos-fix-docker-api-version/run.sh +++ b/casaos-fix-docker-api-version/run.sh @@ -1368,7 +1368,8 @@ downgrade_docker() { # Verify containerd binary version after restart echo "Verifying containerd version..." - local containerd_version=$(timeout 5 containerd --version 2>/dev/null | head -n1 || echo "unknown") + local containerd_version + containerd_version=$(timeout 5 containerd --version 2>/dev/null | head -n1 || echo "unknown") echo "containerd binary: $containerd_version" echo "" diff --git a/casaos-fix-docker-api-version/test-script.sh b/casaos-fix-docker-api-version/test-script.sh index 3ce816e..3624352 100755 --- a/casaos-fix-docker-api-version/test-script.sh +++ b/casaos-fix-docker-api-version/test-script.sh @@ -97,8 +97,10 @@ show_status() { local docker_version=$(get_docker_version) local api_version=$(get_docker_api_version) local dockerd_version=$(get_dockerd_binary_version) - local containerd_pkg=$(dpkg -l 2>/dev/null | grep containerd.io | awk 'NR==1 {print $3}') - local containerd_bin=$(containerd --version 2>/dev/null | awk '{print $3}') + local containerd_pkg + containerd_pkg=$(dpkg -l 2>/dev/null | grep containerd.io | awk 'NR==1 {print $3}') + local containerd_bin + containerd_bin=$(containerd --version 2>/dev/null | awk '{print $3}') echo "Docker daemon version: $docker_version" echo "Docker API version: $api_version" @@ -425,8 +427,10 @@ test_fix_script() { local after_version=$(get_docker_version) local after_api=$(get_docker_api_version) local dockerd_binary=$(get_dockerd_binary_version) - local containerd_pkg=$(dpkg -l 2>/dev/null | grep containerd.io | awk 'NR==1 {print $3}') - local containerd_bin=$(containerd --version 2>/dev/null | awk '{print $3}') + local containerd_pkg + containerd_pkg=$(dpkg -l 2>/dev/null | grep containerd.io | awk 'NR==1 {print $3}') + local containerd_bin + containerd_bin=$(containerd --version 2>/dev/null | awk '{print $3}') echo "Docker version after fix: $after_version" echo "API version after fix: $after_api" @@ -475,7 +479,7 @@ test_fix_script() { print_error "✗ containerd package is not 1.7.28 (got: ${containerd_pkg:-unknown})" success=false fi - if echo "$containerd_bin" | grep -q "^1.7.28"; then + if echo "$containerd_bin" | grep -q "^v\?1\.7\.28"; then print_success "✓ containerd binary is 1.7.28 (${containerd_bin})" else print_error "✗ containerd binary is not 1.7.28 (got: ${containerd_bin:-unknown})"