-
Notifications
You must be signed in to change notification settings - Fork 2
/
podman_partial_image
executable file
·119 lines (100 loc) · 2.86 KB
/
podman_partial_image
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/bin/sh
# SPDX-License-Identifier: MIT
# SC2039: local is ok for dash and busybox ash
# shellcheck disable=SC2039
error() {
printf "%s\n" "$@" >&2
exit 1
}
usage() {
echo "Usage: $0 [-b base [-b base...]] [-o out.tar] archive [archive..]"
echo "base = image name recognizable by podman image inspect, to be removed from archive"
echo "archive = image name recognizable by podman save"
echo
echo "By default intermediate copies are stored in /var/tmp,"
echo "set TMPDIR to change that directory"
}
inspect_image() {
local image="$1"
podman inspect --format "{{.RootFS.Layers}}" "$image" |
sed -e 's/^\[//g' -e 's/\]$//g' -e 's/\<sha256://g' -e 's/ /\n/g' >> "$TMPDIR/known_hashs"
}
trim_archives() {
local hash tar_options="" file
if ! podman save -m --format=docker-archive "$@" | tar -C "$TMPDIR/archive" -x; then
local avail warning=""
avail="$(findmnt -nr --bytes -o AVAIL --target "$TMPDIR")"
if [ -n "$avail" ] && [ "$avail" -lt "$((1024*1024))" ]; then
warning="
Filesystem looks full: try setting TMPDIR to an USB device mount point or free up space first"
fi
error "Could not extract images: $*$warning"
fi
while read -r hash; do
file="$TMPDIR/archive/$hash.tar"
[ -e "$file" ] || continue
# podman verifies the archive contains a tar for all layers even if they're not used
rm -f "$file" && touch -d "@0" "$file" && chmod 444 "$file" \
|| error "Could not truncate layer in archive"
done < "$TMPDIR/known_hashs"
if [ -n "$RENAME" ]; then
# shellcheck disable=SC2086 # split RENAME on purpose
sed -i $RENAME "$TMPDIR/archive/manifest.json" "$TMPDIR/archive/repositories"
fi
# podman generates archives in which owner is set to root,
# busybox tar doesn't allow that so only add option for GNU tar
if tar --version | grep -q GNU; then
tar_options="--owner root --group root --numeric-owner"
fi
# shellcheck disable=SC2086 # split tar_options on purpose
( cd "$TMPDIR/archive"; tar ${tar_options} -c [0-9a-z]*; ) > "$OUTPUT" \
|| error "Could not create new archive"
}
main() {
local OUTPUT=image.tar
local RENAME
local tmp
tmp=$(mktemp -d "${TMPDIR:-/var/tmp}/make_partial_image.XXXXXX") \
|| error "Could not create temp dir"
export TMPDIR="$tmp"
# shellcheck disable=SC2064 # expand TMPDIR now
trap "rm -rf \"$TMPDIR\"" EXIT
mkdir "$TMPDIR/archive"
touch "$TMPDIR/known_hashs"
while [ $# -gt 0 ]; do
case "$1" in
-b|--base)
[ $# -ge 2 ] || error "Missing argument to $1"
inspect_image "$2"
shift 2
;;
-o|--output)
[ $# -ge 2 ] || error "Missing argument to $1"
OUTPUT="$2"
shift 2
;;
-R|--rename)
[ $# -ge 2 ] || error "Missing argument to $1"
RENAME="$RENAME -e $2"
shift 2
;;
-h|--help)
usage
exit 0
;;
--)
shift
break
;;
-*)
error "Invalid argument $1"
;;
*)
break
;;
esac
done
[ $# -lt 1 ] && usage && exit 1
trim_archives "$@"
}
main "$@"