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