[scripts]: add update-container script for upgrade/downgrades (#1173)

- Closes #1171
This commit is contained in:
Saehej Kang
2026-02-24 17:52:13 -08:00
committed by GitHub
parent 899081d094
commit 339a3895c0
3 changed files with 171 additions and 8 deletions
+2
View File
@@ -111,6 +111,8 @@ $(STAGING_DIR):
@install "$(BUILD_BIN_DIR)/container-core-images" "$(join $(STAGING_DIR), libexec/container/plugins/container-core-images/bin/container-core-images)"
@install config/container-core-images-config.json "$(join $(STAGING_DIR), libexec/container/plugins/container-core-images/config.json)"
@echo Install update script
@install scripts/update-container.sh "$(join $(STAGING_DIR), bin/update-container.sh)"
@echo Install uninstaller script
@install scripts/uninstall-container.sh "$(join $(STAGING_DIR), bin/uninstall-container.sh)"
+30 -8
View File
@@ -16,14 +16,7 @@ You need a Mac with Apple silicon to run `container`. To build it, see the [BUIL
`container` is supported on macOS 26, since it takes advantage of new features and enhancements to virtualization and networking in this release. We do not support older versions of macOS and the `container` maintainers typically will not address issues that cannot be reproduced on the macOS 26.
### Install or upgrade
If you're upgrading, first stop and uninstall your existing `container` (the `-k` flag keeps your user data, while `-d` removes it):
```bash
container system stop
/usr/local/bin/uninstall-container.sh -k
```
### Initial install
Download the latest signed installer package for `container` from the [GitHub release page](https://github.com/apple/container/releases).
@@ -35,6 +28,35 @@ Start the system service with:
container system start
```
### Upgrade or downgrade
For both upgrading and downgrading, you can manually download and install the signed installer package by following the steps from [initial install](#initial-install) or use the `update-container.sh` script (installed to `/usr/local/bin`).
If you're upgrading and downgrading, you must stop your existing `container`:
```bash
container system stop
```
For upgrading to the latest release version, simply run the command below:
```bash
/usr/local/bin/update-container.sh
```
If you're downgrading, you must uninstall your existing `container` (the `-k` flag keeps your user data, while `-d` removes it):
```bash
/usr/local/bin/uninstall-container.sh -k
/usr/local/bin/update-container.sh -v 0.3.0
```
Start the system service with:
```bash
container system start
```
### Uninstall
Use the `uninstall-container.sh` script (installed to `/usr/local/bin`) to remove `container` from your system. To remove your user data along with the tool, run:
+139
View File
@@ -0,0 +1,139 @@
#!/bin/bash
# Copyright © 2026 Apple Inc. and the container project authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -uo pipefail
INSTALL_DIR="/usr/local"
OPTS=0
LATEST=false
VERSION=
TMP_DIR=
# Release Info
RELEASE_URL=
RELEASE_JSON=
RELEASE_VERSION=
# Package Info
PKG_URL=
PKG_FILE=
PRIMARY_PKG=
FALLBACK_PKG=
check_installed_version() {
local target_version="$1"
if command -v container &>/dev/null; then
local installed_version
installed_version=$(container --version | awk '{print $4}')
installed_version=${installed_version%\)}
if [[ "$installed_version" == "$target_version" ]]; then
return 0
fi
fi
return 1
}
usage() {
echo "Usage: $0 {-v <version>}"
echo "Update container"
echo
echo "Options:"
echo "v <version> Install a specific release version"
echo "No argument Defaults to latest release version"
exit 1
}
while getopts ":v:" arg; do
case "$arg" in
v)
VERSION="$OPTARG"
((OPTS+=1))
;;
*)
echo "Invalid option: -${OPTARG}"
usage
;;
esac
done
# Default to install the latest release version
if [ "$OPTS" -eq 0 ]; then
LATEST=true
fi
# Check if container is still running
CONTAINER_RUNNING=$(launchctl list | grep -e 'com\.apple\.container\W')
if [ -n "$CONTAINER_RUNNING" ]; then
echo '`container` is still running. Please ensure the service is stopped by running `container system stop`'
exit 1
fi
if [ "$EUID" -ne 0 ]; then
echo "This script requires admin privileges to update files under $INSTALL_DIR"
fi
# Temporary directory creation for install/download
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT
error() { echo "Error: $*" >&2; exit 1; }
# Determine the release URL and version
if [[ "$LATEST" == true ]]; then
RELEASE_URL="https://api.github.com/repos/apple/container/releases/latest"
RELEASE_VERSION=$(curl -fsSL "$RELEASE_URL" | jq -r '.tag_name')
if check_installed_version "$RELEASE_VERSION"; then
echo "Container is already on latest version $RELEASE_VERSION"
exit 0
else
echo "Updating to latest version $RELEASE_VERSION"
fi
elif [[ -n "$VERSION" ]]; then
RELEASE_URL="https://api.github.com/repos/apple/container/releases/tags/$VERSION"
RELEASE_VERSION="$VERSION"
if check_installed_version "$RELEASE_VERSION"; then
echo "Container is already on version $RELEASE_VERSION"
exit 0
else
echo "Updating to release version $RELEASE_VERSION"
fi
fi
# Fetch the release json
RELEASE_JSON=$(curl -fsSL "$RELEASE_URL") || {
error $([[ "$LATEST" == true ]] && echo "Failed fetching latest release" || echo "Release '$VERSION' not found")
}
# Possible package names
PRIMARY_PKG="container-installer-signed.pkg"
FALLBACK_PKG="container-$RELEASE_VERSION-installer-signed.pkg"
# Find the package URL
PKG_URL=$(echo "$RELEASE_JSON" | jq -r \
--arg primary "$PRIMARY_PKG" \
--arg fallback "$FALLBACK_PKG" \
'.assets[] | select(.name == $primary or .name == $fallback) | .browser_download_url' | head -n1)
[[ -n "$PKG_URL" ]] || error "Neither $PRIMARY_PKG nor $FALLBACK_PKG found"
PKG_FILE="$TMP_DIR/$(basename "$PKG_URL")"
echo "Downloading package from: $PKG_URL..."
curl -fSL "$PKG_URL" -o "$PKG_FILE"
[[ -s "$PKG_FILE" ]] || error "Downloaded package is empty"
echo "Installing package to $INSTALL_DIR..."
sudo installer -pkg "$PKG_FILE" -target / >/dev/null 2>&1 || error "Installer failed"
echo "Installed successfully"
container --version || error "'container' command not found"