diff --git a/update-portainer-ce/run.sh b/update-portainer-ce/run.sh index d7bee12..d17b8d4 100644 --- a/update-portainer-ce/run.sh +++ b/update-portainer-ce/run.sh @@ -25,77 +25,107 @@ print_decorative_line # Function to check if a command succeeded check_command() { - # Check if the last command executed successfully (exit status 0) if [ $? -ne 0 ]; then - # Print an error message if the command failed echo "Error: $1" - # Exit the script with a status of 1 to indicate an error exit 1 fi } -# Function to get the current Portainer version +# Function to get current Portainer version get_current_version() { local version - # Check if the Portainer container is running + # Check if Portainer container is running if docker ps --format '{{.Names}}' | grep -q '^portainer$'; then - # Try to get the version from the running container using the 'portainer --version' command + # Try to get version from running container version=$(docker exec portainer portainer --version 2>/dev/null | awk '{print $2}') - # If that fails, try to get the version from the container's labels + # If that fails, try to get version from container labels if [ -z "$version" ] || [ "$version" = "runtime" ]; then version=$(docker inspect -f '{{index .Config.Labels "org.opencontainers.image.version"}}' portainer 2>/dev/null) fi - # If still empty, get the version from the image tag + # If still empty, get the image tag if [ -z "$version" ]; then version=$(docker inspect -f '{{.Config.Image}}' portainer | awk -F: '{print $2}') - [ -z "$version" ] && version="latest" # Default to "latest" if no specific tag is found + [ -z "$version" ] && version="latest" fi else - # Check if the Portainer container exists but is not running + # Check if Portainer container exists but is not running if docker ps -a --format '{{.Names}}' | grep -q '^portainer$'; then version=$(docker inspect -f '{{index .Config.Labels "org.opencontainers.image.version"}}' portainer 2>/dev/null) - # Set version as unknown if the container exists but isn't running [ -z "$version" ] && version="Unknown (container exists but is not running)" else - # Check if the Portainer image exists on the system + # Check if Portainer image exists if docker images portainer/portainer-ce -q | grep -q .; then - # Set version as unknown if only the image exists version="Unknown (image exists)" fi fi fi - # If no version information is found, assume Portainer is not installed + # If still empty, assume not installed if [ -z "$version" ]; then echo "Not installed" else - echo "$version" # Print the found version + echo "$version" fi } -# Get the current Portainer version +# Function to get the last three Portainer versions +get_last_three_versions() { + curl -s https://api.github.com/repos/portainer/portainer/releases | grep -m 3 '"tag_name":' | awk -F'"' '{print $4}' +} + +# Function to remove existing Portainer images +remove_existing_images() { + echo "Checking for existing Portainer images..." + existing_images=$(docker images portainer/portainer-ce -q) + if [ -n "$existing_images" ]; then + echo "Removing existing Portainer images..." + docker rmi $existing_images + check_command "Failed to remove existing Portainer images" + else + echo "No existing Portainer images found. Proceeding with installation." + fi +} + +# Get current Portainer version current_version=$(get_current_version) -# Fetch the latest available version of Portainer from GitHub API -latest_version=$(curl -s https://api.github.com/repos/portainer/portainer/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")') -# Check if the command to fetch the latest version was successful -check_command "Failed to fetch the latest Portainer version" +# Get the last three versions +mapfile -t versions < <(get_last_three_versions) -# Print the current and latest versions echo "Current Portainer version: $current_version" -echo "Latest Portainer version: $latest_version" +echo "Available versions:" +for i in "${!versions[@]}"; do + echo "$((i+1)). ${versions[i]}" +done +echo "4. Latest (${versions[0]})" + +# Ask user to choose a version +while true; do + read -p "Which version would you like to install? (1-4, default is 4): " choice + choice=${choice:-4} + if [[ "$choice" =~ ^[1-4]$ ]]; then + if [ "$choice" -eq 4 ]; then + version_to_install=${versions[0]} + else + version_to_install=${versions[$((choice-1))]} + fi + break + else + echo "Invalid choice. Please enter a number between 1 and 4." + fi +done + +echo "You have chosen to install Portainer version: $version_to_install" echo echo "This script will perform the following actions:" echo "1. Stop and remove the current Portainer container (if running)" -echo "2. Remove the existing Portainer image" -echo "3. Pull the latest Portainer image" -echo "4. Create and start a new Portainer container" +echo "2. Remove any existing Portainer images" +echo "3. Pull Portainer image version $version_to_install" +echo "4. Create and start a new Portainer container with version $version_to_install" echo - -# Prompt the user to confirm whether to proceed with the update read -p "Do you want to proceed with the update? (y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then @@ -106,31 +136,21 @@ fi # Stop and remove the current Portainer container if it exists if docker ps -a --format '{{.Names}}' | grep -q '^portainer$'; then echo "Stopping and removing the current Portainer container..." - docker stop portainer # Stop the running Portainer container + docker stop portainer check_command "Failed to stop Portainer container" - docker rm portainer # Remove the stopped Portainer container + docker rm portainer check_command "Failed to remove Portainer container" else - echo "No existing Portainer container found. Proceeding with update." + echo "No existing Portainer container found. Proceeding with installation." fi -# Check if there are any existing Docker images for Portainer -if docker images portainer/portainer-ce -q | grep -q .; then - # If an image exists, print a message indicating its removal - echo "Removing the existing Portainer image..." - # Remove the existing Portainer image - docker rmi portainer/portainer-ce - # Check if the removal command was successful and print an error message if it failed - check_command "Failed to remove Portainer image" -else - # If no image exists, print a message indicating that there is no image to remove - echo "No existing Portainer image found. Proceeding with update." -fi +# Remove existing Portainer images +remove_existing_images -# Pull the latest Portainer image from the repository -echo "Pulling the latest Portainer image..." -docker pull portainer/portainer-ce:$latest_version -check_command "Failed to pull latest Portainer image" +# Pull the selected Portainer image +echo "Pulling Portainer image version $version_to_install..." +docker pull portainer/portainer-ce:$version_to_install +check_command "Failed to pull Portainer image" # Create and start a new Portainer container echo "Creating and starting a new Portainer container..." @@ -141,11 +161,11 @@ docker run -d \ --restart always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ - portainer/portainer-ce:$latest_version + portainer/portainer-ce:$version_to_install check_command "Failed to create and start new Portainer container" -echo "Portainer has been updated and restarted successfully." +echo "Portainer has been updated to version $version_to_install and restarted successfully." -# Verify the new version of Portainer +# Verify the new version new_version=$(get_current_version) echo "New Portainer version: $new_version"