~fginther/vmbuilder/new-artful-builder

2 by Ben Howard
Adding Azure image generation scripts
1
#!/bin/bash
2
3
VERBOSITY=0
4
TEMP_D=""
5
DEF_DISK_FORMAT="raw"
6
DEF_FILESYSTEM="iso9660"
7
8
error() { echo "$@" 1>&2; }
9
errorp() { printf "$@" 1>&2; }
10
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
11
failp() { [ $# -eq 0 ] || errorp "$@"; exit 1; }
12
13
Usage() {
14
    cat <<EOF
15
Usage: ${0##*/} [ options ] output user-data [meta-data]
16
17
   Create a disk for cloud-init to utilize nocloud
18
19
   options:
20
     -h | --help            show usage
21
     -d | --disk-format D   disk format to output. default: raw
22
     -f | --filesystem  F   filesystem format (vfat or iso), default: iso9660
23
24
     -i | --interfaces  F   write network interfaces file into metadata
25
     -m | --dsmode      M   add 'dsmode' ('local' or 'net') to the metadata
26
                            default in cloud-init is 'net', meaning network is
27
                            required.
28
29
   Example:
30
    * cat my-user-data
31
      #cloud-config
32
      password: passw0rd
33
      chpasswd: { expire: False }
34
      ssh_pwauth: True
35
    * echo "instance-id: \$(uuidgen || echo i-abcdefg)" > my-meta-data
36
    * ${0##*/} my-seed.img my-user-data my-meta-data
37
EOF
38
}
39
40
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
41
cleanup() {
42
    [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
43
}
44
45
debug() {
46
    local level=${1}; shift;
47
    [ "${level}" -gt "${VERBOSITY}" ] && return
48
    error "${@}"
49
}
50
51
short_opts="hi:d:f:m:o:v"
52
long_opts="disk-format:,dsmode:,filesystem:,help,interfaces:,output:,verbose"
53
getopt_out=$(getopt --name "${0##*/}" \
54
    --options "${short_opts}" --long "${long_opts}" -- "$@") &&
55
    eval set -- "${getopt_out}" ||
56
    bad_Usage
57
58
## <<insert default variables here>>
59
output=""
60
userdata=""
61
metadata=""
62
filesystem=$DEF_FILESYSTEM
63
diskformat=$DEF_DISK_FORMAT
64
interfaces=_unset
65
dsmode=""
66
67
68
while [ $# -ne 0 ]; do
69
    cur=${1}; next=${2};
70
    case "$cur" in
71
        -h|--help) Usage ; exit 0;;
72
        -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
73
        -d|--disk-format) diskformat=$next; shift;;
74
        -f|--filesystem) filesystem=$next; shift;;
75
        -m|--dsmode) dsmode=$next; shift;;
76
        -i|--interfaces) interfaces=$next; shift;;
77
        --) shift; break;;
78
    esac
79
    shift;
80
done
81
82
## check arguments here
83
## how many args do you expect?
84
[ $# -ge 1 ] || bad_Usage "must provide output, userdata"
85
[ $# -le 3 ] || bad_Usage "confused by additional args"
86
87
output=$1
88
userdata=$2
89
metadata=$3
90
91
[ -n "$metadata" -a "${interfaces}" != "_unset" ] &&
92
    fail "metadata and --interfaces are incompatible"
93
[ -n "$metadata" -a -n "$dsmode" ] &&
94
    fail "metadata and dsmode are incompatible"
95
[ "$interfaces" = "_unset" -o -r "$interfaces" ] ||
96
    fail "$interfaces: not a readable file"
97
98
TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
99
    fail "failed to make tempdir"
100
trap cleanup EXIT
101
102
if [ -n "$metadata" ]; then
103
    cp "$metadata" "$TEMP_D/meta-data" || fail "$metadata: failed to copy"
104
else
105
    {
106
    echo "instance-id: iid-local01"
107
    [ -n "$dsmode" ] && echo "dsmode: $dsmode"
108
    [ -n "$interfaces" ] && echo "interfaces: |" &&
109
        sed 's,^,  ,' "$interfaces"
110
    } > "$TEMP_D/meta-data"
111
fi
112
113
if [ "$userdata" = "-" ]; then
114
    cat > "$TEMP_D/user-data" || fail "failed to read from stdin"
115
else
116
    cp "$userdata" "$TEMP_D/user-data" || fail "$userdata: failed to copy"
117
fi
118
119
## alternatively, create a vfat filesystem with same files
120
img="$TEMP_D/seed.img"
121
truncate --size 100K "$img" || fail "failed truncate image"
122
123
case "$filesystem" in
124
    iso9660|iso)
125
        genisoimage  -output "$img" -volid cidata \
126
            -joliet -rock "$TEMP_D/user-data" "$TEMP_D/meta-data" \
127
            > "$TEMP_D/err" 2>&1 ||
128
            { cat "$TEMP_D/err" 1>&2; fail "failed to genisoimage"; }
129
        ;;
130
    vfat)
131
        mkfs.vfat -n cidata "$img" || fail "failed mkfs.vfat"
132
        mcopy -oi "$img" "$TEMP_D/user-data" "$TEMP_D/meta-data" :: ||
133
            fail "failed to copy user-data, meta-data to img"
134
        ;;
135
    *) fail "unknown filesystem $filesystem";;
136
esac
137
138
[ "$output" = "-" ] && output="$TEMP_D/final"
139
qemu-img convert -f raw -O "$diskformat" "$img" "$output" ||
140
    fail "failed to convert to disk format $diskformat"
141
142
[ "$output" != "$TEMP_D/final" ] || { cat "$output" && output="-"; } ||
143
    fail "failed to write to -"
144
145
error "wrote ${output} with filesystem=$filesystem and diskformat=$diskformat"
146
# vi: ts=4 noexpandtab
147