~dpigott/lava-master-image-scripts/fix-stty-bug

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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
#!/bin/sh
set -e

# LAVA create master version
LAVA_VERSION=2013.01
LAVA_URL=https://launchpad.net/lava-master-image-scripts

# Common root filesystem that is the base for all boards
COMMON_ROOTFS=linaro-o-nano-tar-20120221-0.tar.gz
COMMON_ROOTFS_URL=http://releases.linaro.org/12.02/ubuntu/oneiric-images/nano/$COMMON_ROOTFS
COMMON_ROOTFS_MD5=0d98d935488b56bbd8b291315944bb7d

# When non-empty the tool is verbose
export VERBOSE=

# When non-empty the tool will stop just before jumping into the rootfs
export DEBUG=

# Used during partitioning on first boot - size of the testrootsfs partition
# defaults to 4G (4 GigaBytes)
export ROOTFS_SIZE="4G"

# Used during partitioning on first boot - size of the userdata partition
# defaults to 2G (2 GigaBytes)
export USERDATA_SIZE="2G"

# TODO: change to BOARD
dev=

# Check if this installation is supported
LAVA_SUPPORTED=0

# When non-empty then vanilla image is re-built
REBUILD_VANILLA=

# Place for various big files we make
if [ "x$XDG_CACHE_HOME" = "x" ]; then
    XDG_CACHE_HOME="$HOME/.cache"
fi
CACHE_DIR="$XDG_CACHE_HOME/lava/master-image-scripts"

# Output image name, defaults to $dev-master.img
OUTPUT_IMAGE=


os_check() {
    # Sadly we need to use kernel and userspace features
    # that are not available on earlier versions
    case `lsb_release -i -s` in
        Debian)
            case `lsb_release -c -s` in
                wheezy|sid)
                    export LAVA_SUPPORTED=1
                    ;;
            esac
            ;;
        Ubuntu)
            case `lsb_release -c -s` in
                natty|precise|quantal)
                    export LAVA_SUPPORTED=1
                    ;;
            esac
            ;;
    esac
}


show_version() {
    # Display the version line
    echo "lava-create-master $LAVA_VERSION"
}


show_usage() {
    # Display the usage line
    echo "Usage: lava-create-master [--rebuild-vanilla] [--verbose] (--help | --version | DEVICE) [ --output|-o IMAGE] [--rootfs-size|-r SIZE] [--userdata-size|-u SIZE]"
}


show_help() {
    # Display the help screen
    show_usage
    echo
    echo "available options:"
    echo
    printf -- " %-9s - %s\n" "--help" "This help screen"
    printf -- " %-9s - %s\n" "--version" "Version details"
    printf -- " %-9s - %s\n" "--verbose" "Display additional messages"
    printf -- " %-9s - %s\n" "--output" "Save the output as IMAGE"
    printf -- " %-9s - %s\n" "--rebuild-vanilla" "Always rebuild vanilla image"
    printf -- " %-9s - %s\n" "--rootfs-size" "Size of the testrootfs partition (default 4G)"
    printf -- " %-9s - %s\n" "--userdata-size" "Size of the userdata partition (default 2G), no meaning for iMX and Origen"
    echo
    echo "supported devices:"
    echo
    for conf_file in $(ls boards.d/*.conf | sort); do
        printf " %-9s - %s\n" \
            "$(basename $conf_file .conf)" \
            "$(. $conf_file && echo $DESC)"
    done
    echo
    echo "See: $LAVA_URL for more information"
}


parse_argv() {
    # Parse command line arguments
    # Sets: VERBOSE, dev
    while test -n "$1"; do
        case "$1" in
            --verbose)
                VERBOSE=1
                shift
                ;;
            --rebuild-vanilla)
                REBUILD_VANILLA=1
                shift
                ;;
            --debug)
                DEBUG=1
                shift
                ;;
            --version)
                show_version
                exit 0
                ;;
            --help)
                show_help
                exit 0
                ;;
            --output|-o)
                if [ "x$2" = "x" ]; then
                    echo "Error: $1 requires an argument"
                    exit 1
                fi
                OUTPUT_IMAGE="$2"
                shift 2
                ;;
            --rootfs-size|-r)
                ROOTFS_SIZE="$2"
                shift 2
                ;;
            --userdata-size|-r)
                USERDATA_SIZE="$2"
                shift 2
                ;;
            *)
                if [ -n "$dev" ]; then
                    show_usage
                    echo "Too many arguments, see --help for details"
                    exit 1
                else
                    dev="$1"
                    if [ "x$OUTPUT_IMAGE" = "x" ]; then
                        OUTPUT_IMAGE=${dev}-master.img
                    fi
                    shift
                fi
                ;;
        esac
    done
    if [ -z "$dev" ]; then
        show_usage
        echo "Insufficient arguments, see --help for details"
        exit 1
    fi
}


verbose() {
    # Display a message when running with --verbose
    test -n "$VERBOSE" && echo "$*" || :
}

not_verbose() {
    # Display a message when running without --verbose
    test -n "$VERBOSE" || echo "$*"
}


load_board_config() {
    # Load board configuration file
    if [ -r boards.d/$dev.conf ]; then
        . boards.d/$dev.conf
    else
        echo "Unsupported device: $dev"
        exit 1
    fi
}


rerun_via_sudo() {
    # We really need sudo so let's ask for that
    # and no, raw root is not good
    if [ "$(id -u)" != 0 ] || [ -z "$SUDO_USER" ]; then
        exec sudo $0 "$@"
        exit 1
    fi
}


enable_proxy_and_fix_locale() {
    . /etc/environment || :
    # We may want to source environment again to get http_proxy
    if test -n "$http_proxy"; then
        export http_proxy
        verbose "Using HTTP proxy: $http_proxy"
    fi
    # Since it also may contain locale settings let's revert to C.UTF-8
    # We don't want localization, it may break client side tools and parsing logic
    export LANG=C.UTF-8
}


check_md5_or_remove() {
    # Check the MD5 sum of $1 (it has to match $2) or remove the file.
    test ! -e "$1" && return 1
    if [ "$(md5sum "$1" | cut -d ' ' -f 1)" = "$2" ]; then
        return 0
    else
        rm -f "$1"
        return 1
    fi
}


download_and_md5() {
    # Download a file to $1 from URL $2.
    # The expected md5 checksum is $3
    check_md5_or_remove "$1" "$3" && return 0
    echo " * Downloading $2..."
    mkdir -p `dirname $1`
    if ! wget \
        --output-document="$1" \
        --user-agent="lava-create-master ($LAVA_VERSION)" \
        --quiet \
        "$2"; then
        if test -z "$LICENSE_WRAP"; then
            # don't report error if we might have to do license wrap
            echo "Error: unable to download: $1" >&2
        fi
        return 1
    fi
    if ! check_md5_or_remove "$1" "$3"; then
        if test -z "$LICENSE_WRAP"; then
            # don't report error if we might have to do license wrap
            echo "Error: checksum mismatch for $1" >&2
        fi
        return 1
    else
        return 0
    fi
}


chown_to_user() {
    chown $SUDO_USER.$(id -gn) "$1"
}


# Cleanup function
cleanup() {
    if [ -n "$MASTER_MNT" ]; then
        verbose " * Unmounting master rootfs..."
        # Unmount the root filesystem
        umount $MASTER_MNT
        rmdir $MASTER_MNT
    fi
    if [ -n "$LOOP_DEV" ]; then
        # Remove loopback partitions
        verbose " * Removing loopback device partitions..."
        kpartx -d $LOOP_DEV
        # Detach loopback device
        verbose " * Detaching loopback device..."
        losetup --detach $LOOP_DEV
    fi
    if [ -n "$UDISKS_INHIBIT_PID" ]; then
        # Kill udisks --inhibit
        verbose " * Stopping udisks --inhibit"
        kill $UDISKS_INHIBIT_PID
    fi
    if [ -n "$OLD_AUTOMOUNT" ]; then
        # Revert dconf settings
        verbose " * Restoring GNOME automount settings"
        sudo -u $SUDO_USER dconf write /org/gnome/desktop/media-handling/automount "$OLD_AUTOMOUNT"
    fi
    if [ -n "$OLD_AUTOMOUNT_OPEN" ]; then
        # Revert dconf settings
        sudo -u $SUDO_USER dconf write /org/gnome/desktop/media-handling/automount-open "$OLD_AUTOMOUNT_OPEN"
    fi
}


make_master() {
    if [ -z "$(which kpartx)" ]; then
        sudo apt-get -y install kpartx
        if [ $? -ne 0 ]; then
            echo "Failed to install kpartx" >&2
            exit 1
        fi
    fi
    # Cleanup on exit
    trap cleanup EXIT

    # Be friendly :-)
    echo "LAVA master images are easy to make, just three steps:"
    not_verbose "Note: run with --verbose to see details"
    echo

    # This seems to be a nice moment to do this
    enable_proxy_and_fix_locale

    # Step: 1
    echo "1) Preparing vanilla Linaro image"

    # Prevent gnome from popping up windows
    if [ -n "$(which dconf)" ] && [ -n "$DBUS_SESSION_BUS_ADDRESS" ]; then
        verbose " * Disabling GNOME auto-mount..."
        OLD_AUTOMOUNT=$(sudo -u $SUDO_USER dconf read /org/gnome/desktop/media-handling/automount)
        OLD_AUTOMOUNT_OPEN=$(sudo -u $SUDO_USER dconf read /org/gnome/desktop/media-handling/automount-open)
        sudo -u $SUDO_USER dconf write /org/gnome/desktop/media-handling/automount false
        sudo -u $SUDO_USER dconf write /org/gnome/desktop/media-handling/automount-open false
    fi

    # Inhibit udisks to prevent it from spawning silly windows
    if [ -n "$(which udisks)" ]; then
        verbose  " * Inhibiting udisks..."
        udisks --inhibit >/dev/null 2>&1 &
        UDISKS_INHIBIT_PID=$!
    fi

    # Rebuild the vanilla image if needed
    if [ -e $CACHE_DIR/pristine-images/$dev-vanilla.img ] && [ -z "$REBUILD_VANILLA" ]; then
        verbose " * Re-using existing vanilla image: $CACHE_DIR/pristine-images/$dev-vanilla.img"
    else
        # Try non-license download first in case we're in the lab
        verbose " * Downloading/checking hardware pack..."
        if ! download_and_md5 "$CACHE_DIR/image-pieces/$HWPACK" "$HWPACK_URL" "$HWPACK_MD5"; then
            if test -n "$LICENSE_WRAP"; then
                if ! ${dev}_download_and_md5 "$CACHE_DIR/image-pieces/$HWPACK" "$HWPACK_URL" "$HWPACK_MD5"; then
                    echo "Error: unable to download hwpack/verify license" >&2
                    exit 1
                fi
            else
                echo "Error: unable to download hwpack" >&2
                exit 1
            fi
        fi

        # chown hwpack for convenience
        chown_to_user "$CACHE_DIR/image-pieces/$HWPACK"

        # Download rootfs
        verbose " * Downloading/checking root filesystem..."
        if ! download_and_md5 "$CACHE_DIR/image-pieces/$ROOTFS" "$ROOTFS_URL" "$ROOTFS_MD5"; then
            echo "Error: unable to download rootfs" >&2
            exit 1
        fi

        # chown rootfs for convenience
        chown_to_user "$CACHE_DIR/image-pieces/$ROOTFS"

        # Use LMC to assemble the image
        mkdir -p $CACHE_DIR/pristine-images
        verbose " * Building vanilla image with linaro-media-create..."
        if ! linaro-media-create \
            --dev $LMC_DEV \
            --rootfs ext4 \
            --image-file $CACHE_DIR/pristine-images/$dev-vanilla.img \
            --image-size 1G \
            --align-boot-part \
            --binary $CACHE_DIR/image-pieces/$ROOTFS \
            --hwpack $CACHE_DIR/image-pieces/$HWPACK \
            --hwpack-force-yes; then
            echo "Error: linaro-media-create failed to construct a vanilla image" >&2
            rm -f "$CACHE_DIR/pristine-images/$dev-vanilla.img"
            exit 1
        fi

        # chown the file for convenience
        chown_to_user "$CACHE_DIR/pristine-images/$dev-vanilla.img"
    fi

    # Step 2:
    echo "2) Converting vanilla image to LAVA master image"

    verbose " * Creating a copy of vanilla image..."
    # Copy the vanilla image
    cp "$CACHE_DIR/pristine-images/$dev-vanilla.img" "$OUTPUT_IMAGE"

    # Attach loopback device
    verbose " * Attaching master image to loopback device..."
    LOOP_DEV=$(losetup --show --find "$OUTPUT_IMAGE")

    # Add partition devices
    verbose " * Adding partitions to the loopback device..."
    kpartx -av $LOOP_DEV

    # Get a mount point for master image
    verbose " * Creating temporary mount point for rootfs..."
    MASTER_MNT=$(mktemp --directory --suffix .lava.$dev.master)

    # Mount the root filesystem
    verbose " * Mounting rootfs..."
    LOOP_NAME=`basename ${LOOP_DEV}`
    mount /dev/mapper/${LOOP_NAME}p${ROOTFS_PARTITION} $MASTER_MNT

    # Update hostname to 'master'
    verbose " * Changing hostname to 'master'..."
    sed -e 's/linaro-nano/master/' -i \
        $MASTER_MNT/etc/hostname \
        $MASTER_MNT/etc/hosts

    # Enable eth0 if it is now enabled yet
    if ! grep --quiet --regexp="auto eth0" $MASTER_MNT/etc/network/interfaces; then
        verbose " * Enabling automating wired network connection..."
        echo "warning: LAVA needs to work around a buggy hardware pack" >&2
        echo "warning: Wired network connection (eth0) should be enabled by default" >&2
        echo "auto eth0" >> $MASTER_MNT/etc/network/interfaces
        echo "iface eth0 inet dhcp" >> $MASTER_MNT/etc/network/interfaces
    fi

    # Copy our master overlay to the rootfs
    # The extra options are there to make root
    # the owner of the files we're copying
    verbose " * Applying master image overlay to rootfs..."
    tar -C master-rootfs-extras -c . | tar -C $MASTER_MNT -x --no-same-owner --no-same-permissions

    # Expand variables in device.conf
    verbose " * Preparing device.conf file..."
    sed \
        -e "s!@LAVA_MASTER_IMAGE_UUID@!$(python -c 'import uuid; print uuid.uuid1()')!" \
        -e "s!@LAVA_MASTER_IMAGE_ROOTFS@!$ROOTFS!" \
        -e "s!@LAVA_MASTER_IMAGE_HWPACK@!$HWPACK!" \
        -e "s!@LAVA_DEVICE_TYPE@!$LAVA_DEV!" \
        -e "s!@LAVA_PRE_ENV@!$LAVA_PRE_ENV!" \
        -e "s!@LAVA_PARTITION_SCHEME@!$LAVA_PARTITION_SCHEME!" \
        -e "s!@LAVA_BOOT_DEVICE@!$LAVA_BOOT_DEVICE!" \
        -i \
        $MASTER_MNT/var/lib/lava/device.conf

    # Expand variables used in lava scripts
    verbose " * Expanding version strings used by lava scripts..."
    sed \
        -e "s!@LAVA_VERSION@!$LAVA_VERSION!" \
        -e "s!@LAVA_URL@!$LAVA_URL!" \
        -e "s!@LAVA_ROOTFS_SIZE@!$ROOTFS_SIZE!" \
        -e "s!@LAVA_USERDATA_SIZE@!$USERDATA_SIZE!" \
        -i \
        $MASTER_MNT/lib/lava/common

    # chown the file for convenience
    chown_to_user "$OUTPUT_IMAGE"

    cleanup
    trap - EXIT

    # Step 3:
    echo "3) Copy $OUTPUT_IMAGE to an SD card and boot your board to finish the process"
    echo
    echo "If you are using a desktop system, USB adapter or a virtual machine:"
    echo "$ sudo dd bs=4M if=$OUTPUT_IMAGE of=/dev/sdX"
    echo
    echo "If you are using a laptop then you may need to use this line:"
    echo "$ sudo dd bs=4M if=$OUTPUT_IMAGE of=/dev/mmcblkX"
    echo
    echo "Warning: make sure to select correct device name!"
}


main() {
    os_check
    if [ $LAVA_SUPPORTED = 0 ]; then
        echo "LAVA is not supported on this system"
        echo "------------------------------------"
        echo
        echo "This script depends on Linux kernel features that are not available"
        echo "on earlier Ubuntu releases. You should consider upgrading to the"
        echo "Ubuntu 12.04 Precise Pangolin that was released in May 2012"
        exit 1
    fi
    parse_argv "$@"
    load_board_config
    rerun_via_sudo "$@"
    make_master
}


main "$@"