summaryrefslogtreecommitdiff
path: root/src/partvi
blob: b50b918acafb0bf74aed394fa9453c3ceab86d3c (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/bin/bash
shopt -s nullglob
PATH=/sbin:$PATH

msg() { printf '%s: %s: %s\n' "$0" "$1" "$2" >&2; }
die() { msg Error "${*:-exiting on fatal error.}"; exit 1; }
warn() { msg Warning "${*:-Something is wrong.}"; }
notice() { msg Notice "$*"; }

validate_name()
{
        case "$1" in
        *[^a-zA-Z0-9_]*) false ;;
        *) true ;;
        esac
}

read_config_file()
{
        validate_name "$img" || { warn "invalid name: $img"; return 1; }
        while read line
        do
                line=${line%%#*} # ignore comments
                k=${line%%=*}
                v=${line#*=}
                [ "$k" -a "$k" != "$line" ] || return
                eval "conf_${1}_$k=\$v"
        done < "$1".conf
}

inquire_var() { _inquire_var "$img" "$1"; }
_inquire_var()
{
        local v
        v=conf_${1}_${2}
        v=${!v}
        if [ "$v" ]
        then
                eval "$2=\$v"
        else
                false
        fi
}

require_var() { _require_var "$img" "$1"; }
_require_var()
{
        _inquire_var "$@" || die "Missing required field '$2' for image file '$1'"
}

get_root_hash()
{
        sed -ne 's/^Root hash:[ \t]*//p' "$1"
}

builddir=_build
mkdir -p "$builddir"

for f in part*.conf
do
        img=${f%.conf}

        read_config_file "$img" || warn "Received error return from command: read_config_file $img"
        require_var name

        require_var type
        case "$type" in
                efi-system-partition|bios-grub|samizdat-*) ;;
                dm-verity-hashes|dm-verity-data) require_var data_path ;;
                *) die "invalid type: $type" ;;
        esac

        imgfile=$builddir/$img

        if inquire_var rebuild
        then
                case "$rebuild" in
                        always) ;;
                        never) ;;
                        *) die "invalid value for field 'rebuild': $rebuild" ;;
                esac
        fi

        if [ "$rebuild" = 'always' ] || [ ! -e "$imgfile" -a "$rebuild" != 'never' ]
        then

                if [ -e "$imgfile" ]
                then
                        notice "Image file exists: $imgfile"
                fi

                case "$type" in
                        dm-verity-hashes|dm-verity-data)
                                require_var data_path
                                [ -f "$data_path" ]
                                [ -f "$data_path".verity ]
                                [ -f "$data_path".verity.log ]
                                root_hash=$(get_root_hash "$data_path".verity.log)
                                [ ${#root_hash} = 64 ]
                        ;;
                        *)
                                require_var allocation
                                tmp=$imgfile~tmp
                                fallocate -l "$allocation" "$tmp"
                        ;;
                esac

                case "$type" in
                        efi-system-partition) mkfs.vfat "$tmp" || die "mkfs.vfat failed" ;;
                        bios-grub)            mkfs.vfat "$tmp" || die "mkfs.vfat failed" ;;
                        samizdat-keys)        mkfs.btrfs "$tmp" || die "mkfs.btrfs failed" ;;
                        dm-verity-data)
                                partuuid=${root_hash:0:32}
                                cp -f -T --reflink "$data_path" "$builddir"/"$partuuid"
                                ln -sfT "$partuuid" "$tmp"
                        ;;
                        dm-verity-hashes)
                                partuuid=${root_hash:32:32}
                                cp -f -T --reflink "$data_path".verity "$builddir"/"$partuuid"
                                ln -sfT "$partuuid" "$tmp"
                        ;;
                        *) die "Unrecognized type: $type" ;;
                esac
                mv -T "$tmp" "$imgfile"
                notice "Successfully wrote $imgfile"
        fi
done