summaryrefslogtreecommitdiff
path: root/src/with-btrfs-seed
blob: 9f0147ebeea4211ee830ffd282db45a61d8fe330 (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
#!/bin/sh

usage()
{
    print >&2 <<EOF
usage: $0 <file.iso> [command] [args ...]

  default command is bash
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"
    [ $# = 0 ] && usage 0

    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
    btrfstune -f -S 0 "$iso_file_clone" 2>/dev/null   || error "btrfstune failed"
    mount -o rw,loop "$iso_file_clone" "$mountpoint"  || error "failed to mount $iso_file"

    chroot "$mountpoint" "$@"
    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
}

main "$@"