aboutsummaryrefslogtreecommitdiffstats
path: root/roles/jails/20_immich/templates/usr_local_bin_extract_image.sh
blob: e8226dd8eabb85b9bada402bff3e7298bb663c5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/bin/sh
# Extract a Docker image to a directory under /image/
# Usage: extract-image.sh <image-ref> <name>
# Example: extract-image.sh ghcr.io/immich-app/immich-server:v2.4.1 immich-server

set -eu

IMAGE="$1"
NAME="$2"
IMAGE_DIR="/image"
TARGET="${IMAGE_DIR}/${NAME}"
TMP_DIR="/tmp/oci-${NAME}"

echo "Extracting ${IMAGE} to ${TARGET}..."

# Clean up any previous extraction attempt
rm -rf "${TMP_DIR}"
mkdir -p "${TMP_DIR}"

# Pull image layers
skopeo copy --override-os linux "docker://${IMAGE}" "dir:${TMP_DIR}"

# Extract all layers in order into new rootfs
rm -rf "${TARGET}.new"
mkdir -p "${TARGET}.new"

# Parse layer digests from manifest and extract each layer
grep -o '"sha256:[a-f0-9]*"' "${TMP_DIR}/manifest.json" | \
    sed 's/"//g; s/sha256://' | \
    while read hash; do
        if [ -f "${TMP_DIR}/${hash}" ]; then
            echo "  Extracting layer ${hash}..."
            tar -xzf "${TMP_DIR}/${hash}" -C "${TARGET}.new" 2>/dev/null || \
            tar -xf "${TMP_DIR}/${hash}" -C "${TARGET}.new" 2>/dev/null || true
        fi
    done

# Swap in the new rootfs
if [ -d "${TARGET}" ]; then
    mv "${TARGET}" "${TARGET}.old"
fi
mv "${TARGET}.new" "${TARGET}"

# Cleanup
rm -rf "${TMP_DIR}" "${TARGET}.old"

echo "Done: ${TARGET}"