Alex Deymo | 2b19cfb | 2015-03-26 00:35:07 -0700 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
| 3 | # Copyright 2015 The Chromium OS Authors. All rights reserved. |
| 4 | # Use of this source code is governed by a BSD-style license that can be |
| 5 | # found in the LICENSE file. |
| 6 | |
| 7 | set -e |
| 8 | |
| 9 | # cleanup <path> |
| 10 | # Unmount and remove the mountpoint <path> |
| 11 | cleanup() { |
| 12 | if ! sudo umount "$1" 2>/dev/null; then |
| 13 | if mountpoint -q "$1"; then |
| 14 | sync && sudo umount "$1" |
| 15 | fi |
| 16 | fi |
| 17 | rmdir "$1" |
| 18 | } |
| 19 | |
Alex Deymo | 2e9533b | 2015-06-26 20:57:06 -0700 | [diff] [blame^] | 20 | # add_files_default <mntdir> <block_size> |
| 21 | # Add several test files to the image mounted in <mntdir>. |
| 22 | add_files_default() { |
| 23 | local mntdir="$1" |
| 24 | local block_size="$2" |
Alex Deymo | 2b19cfb | 2015-03-26 00:35:07 -0700 | [diff] [blame] | 25 | |
| 26 | ### Generate the files used in unittest with descriptive names. |
| 27 | sudo touch "${mntdir}"/empty-file |
| 28 | |
| 29 | # regular: Regular files. |
| 30 | echo "small file" | sudo dd of="${mntdir}"/regular-small status=none |
| 31 | dd if=/dev/zero bs=1024 count=16 status=none | tr '\0' '\141' | |
| 32 | sudo dd of="${mntdir}"/regular-16k status=none |
| 33 | sudo dd if=/dev/zero of="${mntdir}"/regular-32k-zeros bs=1024 count=16 \ |
| 34 | status=none |
| 35 | |
| 36 | echo "with net_cap" | sudo dd of="${mntdir}"/regular-with_net_cap status=none |
| 37 | sudo setcap cap_net_raw=ep "${mntdir}"/regular-with_net_cap |
| 38 | |
| 39 | # sparse_empty: Files with no data blocks at all (only sparse holes). |
| 40 | sudo truncate --size=10240 "${mntdir}"/sparse_empty-10k |
| 41 | sudo truncate --size=$(( block_size * 2 )) "${mntdir}"/sparse_empty-2blocks |
| 42 | |
| 43 | # sparse: Files with some data blocks but also sparse holes. |
| 44 | echo -n "foo" | |
| 45 | sudo dd of="${mntdir}"/sparse-16k-last_block bs=1 \ |
| 46 | seek=$(( 16 * 1024 - 3)) status=none |
| 47 | |
| 48 | # ext2 inodes have 12 direct blocks, one indirect, one double indirect and |
| 49 | # one triple indirect. 10000 should be enough to have an indirect and double |
| 50 | # indirect block. |
| 51 | echo -n "foo" | |
| 52 | sudo dd of="${mntdir}"/sparse-10000blocks bs=1 \ |
| 53 | seek=$(( block_size * 10000 )) status=none |
| 54 | |
| 55 | sudo truncate --size=16384 "${mntdir}"/sparse-16k-first_block |
| 56 | echo "first block" | sudo dd of="${mntdir}"/sparse-16k-first_block status=none |
| 57 | |
| 58 | sudo truncate --size=16384 "${mntdir}"/sparse-16k-holes |
| 59 | echo "a" | sudo dd of="${mntdir}"/sparse-16k-holes bs=1 seek=100 status=none |
| 60 | echo "b" | sudo dd of="${mntdir}"/sparse-16k-holes bs=1 seek=10000 status=none |
| 61 | |
| 62 | # link: symlinks and hardlinks. |
| 63 | sudo ln -s "broken-link" "${mntdir}"/link-short_symlink |
| 64 | sudo ln -s $(dd if=/dev/zero bs=256 count=1 status=none | tr '\0' '\141') \ |
| 65 | "${mntdir}"/link-long_symlink |
| 66 | sudo ln "${mntdir}"/regular-16k "${mntdir}"/link-hard-regular-16k |
| 67 | |
| 68 | # Directories. |
| 69 | sudo mkdir -p "${mntdir}"/dir1/dir2/dir1 |
| 70 | echo "foo" | sudo tee "${mntdir}"/dir1/dir2/file >/dev/null |
| 71 | echo "bar" | sudo tee "${mntdir}"/dir1/file >/dev/null |
| 72 | |
| 73 | # removed: removed files that should not be listed. |
| 74 | echo "We will remove this file so it's contents will be somewhere in the " \ |
| 75 | "empty space data but it won't be all zeros." | |
| 76 | sudo dd of="${mntdir}"/removed conv=fsync status=none |
| 77 | sudo rm "${mntdir}"/removed |
Alex Deymo | 2e9533b | 2015-06-26 20:57:06 -0700 | [diff] [blame^] | 78 | } |
| 79 | |
| 80 | # add_files_ue_settings <mntdir> <block_size> |
| 81 | # Add the update_engine.conf settings file. This file contains the |
| 82 | add_files_ue_settings() { |
| 83 | local mntdir="$1" |
| 84 | |
| 85 | sudo mkdir -p "${mntdir}"/etc >/dev/null |
| 86 | sudo tee "${mntdir}"/etc/update_engine.conf >/dev/null <<EOF |
| 87 | PAYLOAD_MINOR_VERSION=1234 |
| 88 | EOF |
| 89 | # Example of a real lsb-release file released on link stable. |
| 90 | sudo tee "${mntdir}"/etc/lsb-release >/dev/null <<EOF |
| 91 | CHROMEOS_AUSERVER=https://tools.google.com/service/update2 |
| 92 | CHROMEOS_BOARD_APPID={F26D159B-52A3-491A-AE25-B23670A66B32} |
| 93 | CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1} |
| 94 | CHROMEOS_DEVSERVER= |
| 95 | CHROMEOS_RELEASE_APPID={F26D159B-52A3-491A-AE25-B23670A66B32} |
| 96 | CHROMEOS_RELEASE_BOARD=link-signed-mp-v4keys |
| 97 | CHROMEOS_RELEASE_BRANCH_NUMBER=63 |
| 98 | CHROMEOS_RELEASE_BUILD_NUMBER=6946 |
| 99 | CHROMEOS_RELEASE_BUILD_TYPE=Official Build |
| 100 | CHROMEOS_RELEASE_CHROME_MILESTONE=43 |
| 101 | CHROMEOS_RELEASE_DESCRIPTION=6946.63.0 (Official Build) stable-channel link |
| 102 | CHROMEOS_RELEASE_NAME=Chrome OS |
| 103 | CHROMEOS_RELEASE_PATCH_NUMBER=0 |
| 104 | CHROMEOS_RELEASE_TRACK=stable-channel |
| 105 | CHROMEOS_RELEASE_VERSION=6946.63.0 |
| 106 | GOOGLE_RELEASE=6946.63.0 |
| 107 | EOF |
| 108 | } |
| 109 | |
| 110 | # generate_fs <filename> <kind> <size> [block_size] [block_groups] |
| 111 | generate_fs() { |
| 112 | local filename="$1" |
| 113 | local kind="$2" |
| 114 | local size="$3" |
| 115 | local block_size="${4:-4096}" |
| 116 | local block_groups="${5:-}" |
| 117 | |
| 118 | local mkfs_opts=( -q -F -b "${block_size}" -L "ROOT-TEST" -t ext2 ) |
| 119 | if [[ -n "${block_groups}" ]]; then |
| 120 | mkfs_opts+=( -G "${block_groups}" ) |
| 121 | fi |
| 122 | |
| 123 | local mntdir=$(mktemp --tmpdir -d generate_ext2.XXXXXX) |
| 124 | trap 'cleanup "${mntdir}"; rm -f "${filename}"' INT TERM EXIT |
| 125 | |
| 126 | # Cleanup old image. |
| 127 | if [[ -e "${filename}" ]]; then |
| 128 | rm -f "${filename}" |
| 129 | fi |
| 130 | truncate --size="${size}" "${filename}" |
| 131 | |
| 132 | mkfs.ext2 "${mkfs_opts[@]}" "${filename}" |
| 133 | sudo mount "${filename}" "${mntdir}" -o loop |
| 134 | |
| 135 | case "${kind}" in |
| 136 | ue_settings) |
| 137 | add_files_ue_settings "${mntdir}" "${block_size}" |
| 138 | ;; |
| 139 | default) |
| 140 | add_files_default "${mntdir}" "${block_size}" |
| 141 | ;; |
| 142 | esac |
Alex Deymo | 2b19cfb | 2015-03-26 00:35:07 -0700 | [diff] [blame] | 143 | |
| 144 | cleanup "${mntdir}" |
| 145 | trap - INT TERM EXIT |
| 146 | } |
| 147 | |
| 148 | image_desc="${1:-}" |
| 149 | output_dir="${2:-}" |
| 150 | |
| 151 | if [[ ! -e "${image_desc}" || ! -d "${output_dir}" ]]; then |
| 152 | echo "Use: $0 <image_description.txt> <output_dir>" >&2 |
| 153 | exit 1 |
| 154 | fi |
| 155 | |
| 156 | args=( $(cat ${image_desc}) ) |
| 157 | dest_image="${output_dir}/$(basename ${image_desc} .txt).img" |
| 158 | generate_fs "${dest_image}" "${args[@]}" |