blob: 637af5aadb93726a58d0ab940ceb3057a2bd3863 (
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
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
|
#!/bin/sh
usage()
{
cat >&2 <<EOF
usage: $0 [options] <file.iso> [command] [args ...]
options:
--resize <size>
--btrfs-options <mount options> (default: compress)
--no-chroot
EOF
exit $1
}
error()
{
printf '%s: Error: %s\n' "$0" "$*" >&2
exit 1
}
warning()
{
printf '%s: Warning: %s\n' "$0" "$*" >&2
}
have_root()
{
[ "$(id -u)" = 0 ]
}
main()
{
have_root || error "you are not root"
iso_file=$1
shift
iso_file_clone=${iso_file}.clone.tmp
mountpoint=${iso_file%.iso}.mnt.tmp
[ -f "$iso_file" ] || error "not a file: $iso_file"
[ ! -f "$iso_file_clone" ] || error "refusing to clobber existing file: $iso_file_clone"
[ -d "$mountpoint" ] || mkdir "$mountpoint" || error "could not create directory $mountpoint"
! mountpoint -q "$mountpoint" || error "directory is already a mountpoint: $mountpoint"
cp --reflink=always "$iso_file" "$iso_file_clone" || error "cp failed"
trap 'rm -f "$iso_file_clone"' EXIT
if [ "$RESIZE" ]; then
truncate --size="$RESIZE" "$iso_file_clone" || error "failed to resize image with truncate"
fi
btrfstune -f -S 0 "$iso_file_clone" 2>/dev/null || error "btrfstune failed"
mount_options=rw,loop${BTRFS_OPTIONS:+,$BTRFS_OPTIONS}
mount -o "$mount_options" "$iso_file_clone" "$mountpoint" || error "failed to mount $iso_file"
if [ "$RESIZE" ]; then
btrfs filesystem resize max "$mountpoint" || error "btrfs filesystem resize"
fi
if [ "$CHROOT" ]; then
chroot "$mountpoint" "$@"
else
"$@" "$mountpoint"
fi
result=$?
umount "$mountpoint" || warning "umount $mountpoint failed! You had better do something about it"
rmdir "$mountpoint"
if [ "$result" = 0 ]; then
btrfstune -S 1 "$iso_file_clone" || error "btrfstune failed. The original ISO is unmodified."
mv "$iso_file_clone" "$iso_file"
else
warning "The command executed within the chroot failed. The original ISO is unmodified."
rm "$iso_file_clone"
fi
}
[ $# = 0 ] && usage 0
CHROOT=y
eval set -- "$(getopt -o '' --long shrink,no-chroot,resize:,fork:,btrfs-options: -n "$0" -- "$@")" || error 'getopt error'
while [ $# -gt 0 ]; do
case "$1" in
--) shift; break;;
--resize) RESIZE=$2; shift 2;;
--fork) FORK=$2; shift 2;;
--btrfs-options) BTRFS_OPTIONS=$2; shift 2;;
--no-chroot) CHROOT=; shift;;
--shrink) SHRINK=y; shift;;
*) error "unrecognized option: $1"
esac
done
: ${BTRFS_OPTIONS:=compress}
[ "$FORK" ] && error "unimplemented option: --fork"
main "$@"
|