Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/bin/bash | 1 #!/bin/bash |
| 2 | 2 |
| 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 # Script to generate a factory install partition set and miniomaha.conf | 7 # Script to generate a factory install partition set and miniomaha.conf |
| 8 # file from a release image and a factory image. This creates a server | 8 # file from a release image and a factory image. This creates a server |
| 9 # configuration that can be installed using a factory install shim. | 9 # configuration that can be installed using a factory install shim. |
| 10 # | 10 # |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 "If set, include the firmware shellball into the server configuration" | 32 "If set, include the firmware shellball into the server configuration" |
| 33 DEFINE_string release "" \ | 33 DEFINE_string release "" \ |
| 34 "Directory and file containing release image: /path/chromiumos_image.bin" | 34 "Directory and file containing release image: /path/chromiumos_image.bin" |
| 35 DEFINE_string subfolder "" \ | 35 DEFINE_string subfolder "" \ |
| 36 "If set, the name of the subfolder to put the payload items inside" | 36 "If set, the name of the subfolder to put the payload items inside" |
| 37 | 37 |
| 38 # Parse command line | 38 # Parse command line |
| 39 FLAGS "$@" || exit 1 | 39 FLAGS "$@" || exit 1 |
| 40 eval set -- "${FLAGS_ARGV}" | 40 eval set -- "${FLAGS_ARGV}" |
| 41 | 41 |
| 42 if [ ! -f "${FLAGS_release}" ] ; then | 42 if [ ! -f "${FLAGS_release}" ]; then |
| 43 echo "Cannot find image file ${FLAGS_release}" | 43 echo "Cannot find image file ${FLAGS_release}" |
| 44 exit 1 | 44 exit 1 |
| 45 fi | 45 fi |
| 46 | 46 |
| 47 if [ ! -f "${FLAGS_factory}" ] ; then | 47 if [ ! -f "${FLAGS_factory}" ]; then |
| 48 echo "Cannot find image file ${FLAGS_factory}" | 48 echo "Cannot find image file ${FLAGS_factory}" |
| 49 exit 1 | 49 exit 1 |
| 50 fi | 50 fi |
| 51 | 51 |
| 52 if [ ! -z "${FLAGS_firmware_updater}" ] && \ | 52 if [ -n "${FLAGS_firmware_updater}" ] && |
| 53 [ ! -f "${FLAGS_firmware_updater}" ] ; then | 53 [ ! -f "${FLAGS_firmware_updater}" ]; then |
| 54 echo "Cannot find firmware file ${FLAGS_firmware_updater}" | 54 echo "Cannot find firmware file ${FLAGS_firmware_updater}" |
| 55 exit 1 | 55 exit 1 |
| 56 fi | 56 fi |
| 57 | 57 |
| 58 # Convert args to paths. Need eval to un-quote the string so that shell | 58 # Convert args to paths. Need eval to un-quote the string so that shell |
| 59 # chars like ~ are processed; just doing FOO=`readlink -f ${FOO}` won't work. | 59 # chars like ~ are processed; just doing FOO=`readlink -f ${FOO}` won't work. |
| 60 OMAHA_DIR=${SRC_ROOT}/platform/dev | 60 OMAHA_DIR="${SRC_ROOT}/platform/dev" |
| 61 OMAHA_DATA_DIR=${OMAHA_DIR}/static/ | 61 OMAHA_CONF="${OMAHA_DIR}/miniomaha.conf" |
| 62 OMAHA_DATA_DIR="${OMAHA_DIR}/static/" | |
| 62 | 63 |
| 63 # Note: The subfolder flag can only append configs. That means you will need | 64 # Note: The subfolder flag can only append configs. That means you will need |
| 64 # to have unique board IDs for every time you run. If you delete miniomaha.conf | 65 # to have unique board IDs for every time you run. If you delete miniomaha.conf |
| 65 # you can still use this flag and it will start fresh. | 66 # you can still use this flag and it will start fresh. |
| 66 if [ -n "${FLAGS_subfolder}" ] ; then | 67 if [ -n "${FLAGS_subfolder}" ]; then |
| 67 OMAHA_DATA_DIR=${OMAHA_DIR}/static/${FLAGS_subfolder}/ | 68 OMAHA_DATA_DIR="${OMAHA_DIR}/static/${FLAGS_subfolder}/" |
| 68 fi | 69 fi |
| 69 | 70 |
| 70 if [ ${INSIDE_CHROOT} -eq 0 ]; then | 71 if [ ${INSIDE_CHROOT} -eq 0 ]; then |
| 71 echo "Caching sudo authentication" | 72 echo "Caching sudo authentication" |
| 72 sudo -v | 73 sudo -v |
| 73 echo "Done" | 74 echo "Done" |
| 74 fi | 75 fi |
| 75 | 76 |
| 76 # Use this image as the source image to copy | 77 # Use this image as the source image to copy |
| 77 RELEASE_DIR=`dirname ${FLAGS_release}` | 78 RELEASE_DIR="$(dirname "${FLAGS_release}")" |
| 78 FACTORY_DIR=`dirname ${FLAGS_factory}` | 79 FACTORY_DIR="$(dirname "${FLAGS_factory}")" |
| 79 RELEASE_IMAGE=`basename ${FLAGS_release}` | 80 RELEASE_IMAGE="$(basename "${FLAGS_release}")" |
| 80 FACTORY_IMAGE=`basename ${FLAGS_factory}` | 81 FACTORY_IMAGE="$(basename "${FLAGS_factory}")" |
| 81 | 82 |
| 82 | 83 |
| 83 prepare_omaha() { | 84 prepare_omaha() { |
| 84 sudo rm -rf ${OMAHA_DATA_DIR}/rootfs-test.gz | 85 sudo rm -rf "${OMAHA_DATA_DIR}/rootfs-test.gz" |
| 85 sudo rm -rf ${OMAHA_DATA_DIR}/rootfs-release.gz | 86 sudo rm -rf "${OMAHA_DATA_DIR}/rootfs-release.gz" |
| 86 rm -rf ${OMAHA_DATA_DIR}/efi.gz | 87 rm -rf "${OMAHA_DATA_DIR}/efi.gz" |
| 87 rm -rf ${OMAHA_DATA_DIR}/oem.gz | 88 rm -rf "${OMAHA_DATA_DIR}/oem.gz" |
| 88 rm -rf ${OMAHA_DATA_DIR}/state.gz | 89 rm -rf "${OMAHA_DATA_DIR}/state.gz" |
| 89 if [ ! -f "${OMAHA_DATA_DIR}" ] ; then | 90 if [ ! -d "${OMAHA_DATA_DIR}" ]; then |
| 90 mkdir -p ${OMAHA_DATA_DIR} | 91 mkdir -p "${OMAHA_DATA_DIR}" |
| 91 fi | 92 fi |
| 92 } | 93 } |
| 93 | 94 |
| 94 prepare_dir() { | 95 prepare_dir() { |
| 95 sudo rm -rf rootfs-test.gz | 96 sudo rm -rf rootfs-test.gz |
| 96 sudo rm -rf rootfs-release.gz | 97 sudo rm -rf rootfs-release.gz |
| 97 rm -rf efi.gz | 98 rm -rf efi.gz |
| 98 rm -rf oem.gz | 99 rm -rf oem.gz |
| 99 rm -rf state.gz | 100 rm -rf state.gz |
| 100 } | 101 } |
| 101 | 102 |
| 102 compress_and_hash_memento_image() { | 103 compress_and_hash_memento_image() { |
| 103 local input_file="$1" | 104 local input_file="$1" |
| 104 | 105 |
| 105 if has_part_tools; then | 106 if [ -n "${IMAGE_IS_UNPACKED}" ]; then |
| 107 sudo "${SCRIPTS_DIR}/mk_memento_images.sh" part_2 part_3 | | |
| 108 grep hash | | |
| 109 awk '{print $4}' | |
| 110 else | |
| 106 sudo "${SCRIPTS_DIR}/mk_memento_images.sh" "$input_file" 2 3 | | 111 sudo "${SCRIPTS_DIR}/mk_memento_images.sh" "$input_file" 2 3 | |
| 107 grep hash | | 112 grep hash | |
| 108 awk '{print $4}' | 113 awk '{print $4}' |
| 109 else | |
| 110 sudo "${SCRIPTS_DIR}/mk_memento_images.sh" part_2 part_3 | | |
| 111 grep hash | | |
| 112 awk '{print $4}' | |
| 113 fi | 114 fi |
| 114 } | 115 } |
| 115 | 116 |
| 116 compress_and_hash_file() { | 117 compress_and_hash_file() { |
| 117 local input_file="$1" | 118 local input_file="$1" |
| 118 local output_file="$2" | 119 local output_file="$2" |
| 119 | 120 |
| 120 if [ -z "$input_file" ]; then | 121 if [ -z "$input_file" ]; then |
| 121 # Runs as a pipe processor | 122 # Runs as a pipe processor |
| 122 gzip_compress -c -9 | | 123 image_gzip_compress -c -9 | |
| 123 tee "$output_file" | | 124 tee "$output_file" | |
| 124 openssl sha1 -binary | | 125 openssl sha1 -binary | |
| 125 openssl base64 | 126 openssl base64 |
| 126 else | 127 else |
| 127 gzip_compress -c -9 "$input_file" | | 128 image_gzip_compress -c -9 "$input_file" | |
| 128 tee "$output_file" | | 129 tee "$output_file" | |
| 129 openssl sha1 -binary | | 130 openssl sha1 -binary | |
| 130 openssl base64 | 131 openssl base64 |
| 131 fi | 132 fi |
| 132 } | 133 } |
| 133 | 134 |
| 134 compress_and_hash_partition() { | 135 compress_and_hash_partition() { |
| 135 local input_file="$1" | 136 local input_file="$1" |
| 136 local part_num="$2" | 137 local part_num="$2" |
| 137 local output_file="$3" | 138 local output_file="$3" |
| 138 | 139 |
| 139 if has_part_tools; then | 140 if [ -n "${IMAGE_IS_UNPACKED}" ]; then |
| 140 dump_partition "$input_file" "$part_num" | | 141 compress_and_hash_file "part_$part_num" "$output_file" |
| 142 else | |
| 143 image_dump_partition "$input_file" "$part_num" | | |
| 141 compress_and_hash_file "" "$output_file" | 144 compress_and_hash_file "" "$output_file" |
| 142 else | |
| 143 compress_and_hash_file "part_$part_num" "$output_file" | |
| 144 fi | 145 fi |
| 145 } | 146 } |
| 146 | 147 |
| 147 # Clean up stale config and data files. | 148 # Clean up stale config and data files. |
| 148 prepare_omaha | 149 prepare_omaha |
| 149 | 150 |
| 151 # Decide if we should unpack partition | |
| 152 if image_has_part_tools; then | |
| 153 IMAGE_IS_UNPACKED= | |
| 154 else | |
| 155 #TODO(hungte) Currently we run unpack_partitions.sh if part_tools are not | |
| 156 # found. If the format of unpack_partitions.sh is reliable, we can prevent | |
| 157 # creating temporary files. See image_part_offset for more information. | |
| 158 echo "WARNING: cannot find partition tools. Using unpack_partitions.sh." >&2 | |
| 159 IMAGE_IS_UNPACKED=1 | |
| 160 fi | |
| 161 | |
| 150 # Get the release image. | 162 # Get the release image. |
| 151 pushd ${RELEASE_DIR} > /dev/null | 163 pushd "${RELEASE_DIR}" >/dev/null |
| 152 echo "Generating omaha release image from ${FLAGS_release}" | 164 echo "Generating omaha release image from ${FLAGS_release}" |
| 153 echo "Generating omaha factory image from ${FLAGS_factory}" | 165 echo "Generating omaha factory image from ${FLAGS_factory}" |
| 154 echo "Output omaha image to ${OMAHA_DATA_DIR}" | 166 echo "Output omaha image to ${OMAHA_DATA_DIR}" |
| 155 echo "Output omaha config to ${OMAHA_DIR}/miniomaha.conf" | 167 echo "Output omaha config to ${OMAHA_CONF}" |
| 156 | 168 |
| 157 prepare_dir | 169 prepare_dir |
| 158 | 170 |
| 159 if ! has_part_tools; then | 171 if [ -n "${IMAGE_IS_UNPACKED}" ]; then |
| 160 #TODO(hungte) we can still avoid running unpack_partitions.sh | |
| 161 # by $(cat unpack_partitions.sh | grep Label | sed "s/#//" | grep ${name}" | | |
| 162 # awk '{ print $1}') to fetch offset/size. | |
| 163 echo "Unpacking image ${RELEASE_IMAGE} ..." >&2 | 172 echo "Unpacking image ${RELEASE_IMAGE} ..." >&2 |
| 164 sudo ./unpack_partitions.sh "${RELEASE_IMAGE}" 2>/dev/null | 173 sudo ./unpack_partitions.sh "${RELEASE_IMAGE}" 2>/dev/null |
| 165 fi | 174 fi |
| 166 | 175 |
| 167 release_hash="$(compress_and_hash_memento_image "${RELEASE_IMAGE}")" | 176 release_hash="$(compress_and_hash_memento_image "${RELEASE_IMAGE}")" |
| 168 sudo chmod a+rw update.gz | 177 sudo chmod a+rw update.gz |
| 169 mv update.gz rootfs-release.gz | 178 mv update.gz rootfs-release.gz |
| 170 mv rootfs-release.gz ${OMAHA_DATA_DIR} | 179 mv rootfs-release.gz "${OMAHA_DATA_DIR}" |
| 171 echo "release: ${release_hash}" | 180 echo "release: ${release_hash}" |
| 172 | 181 |
| 173 oem_hash="$(compress_and_hash_partition "${RELEASE_IMAGE}" 8 "oem.gz")" | 182 oem_hash="$(compress_and_hash_partition "${RELEASE_IMAGE}" 8 "oem.gz")" |
| 174 mv oem.gz ${OMAHA_DATA_DIR} | 183 mv oem.gz "${OMAHA_DATA_DIR}" |
| 175 echo "oem: ${oem_hash}" | 184 echo "oem: ${oem_hash}" |
| 176 | 185 |
| 177 efi_hash="$(compress_and_hash_partition "${RELEASE_IMAGE}" 12 "efi.gz")" | 186 efi_hash="$(compress_and_hash_partition "${RELEASE_IMAGE}" 12 "efi.gz")" |
| 178 mv efi.gz ${OMAHA_DATA_DIR} | 187 mv efi.gz "${OMAHA_DATA_DIR}" |
| 179 echo "efi: ${efi_hash}" | 188 echo "efi: ${efi_hash}" |
| 180 | 189 |
| 181 popd > /dev/null | 190 popd >/dev/null |
| 182 | 191 |
| 183 # Go to retrieve the factory test image. | 192 # Go to retrieve the factory test image. |
| 184 pushd ${FACTORY_DIR} > /dev/null | 193 pushd "${FACTORY_DIR}" >/dev/null |
| 185 prepare_dir | 194 prepare_dir |
| 186 | 195 |
| 187 if ! has_part_tools; then | 196 if [ -n "${IMAGE_IS_UNPACKED}" ]; then |
| 188 echo "Unpacking image ${FACTORY_IMAGE} ..." >&2 | 197 echo "Unpacking image ${FACTORY_IMAGE} ..." >&2 |
| 189 sudo ./unpack_partitions.sh "${FACTORY_IMAGE}" 2>/dev/null | 198 sudo ./unpack_partitions.sh "${FACTORY_IMAGE}" 2>/dev/null |
| 190 fi | 199 fi |
| 191 | 200 |
| 192 test_hash="$(compress_and_hash_memento_image "${FACTORY_IMAGE}")" | 201 test_hash="$(compress_and_hash_memento_image "${FACTORY_IMAGE}")" |
| 193 sudo chmod a+rw update.gz | 202 sudo chmod a+rw update.gz |
| 194 mv update.gz rootfs-test.gz | 203 mv update.gz rootfs-test.gz |
| 195 mv rootfs-test.gz ${OMAHA_DATA_DIR} | 204 mv rootfs-test.gz "${OMAHA_DATA_DIR}" |
| 196 echo "test: ${test_hash}" | 205 echo "test: ${test_hash}" |
| 197 | 206 |
| 198 state_hash="$(compress_and_hash_partition "${FACTORY_IMAGE}" 1 "state.gz")" | 207 state_hash="$(compress_and_hash_partition "${FACTORY_IMAGE}" 1 "state.gz")" |
| 199 mv state.gz ${OMAHA_DATA_DIR} | 208 mv state.gz "${OMAHA_DATA_DIR}" |
| 200 echo "state: ${state_hash}" | 209 echo "state: ${state_hash}" |
| 201 | 210 |
| 202 popd > /dev/null | 211 popd >/dev/null |
| 203 | 212 |
| 204 if [ ! -z ${FLAGS_firmware_updater} ] ; then | 213 if [ -n "${FLAGS_firmware_updater}" ]; then |
| 205 SHELLBALL="${FLAGS_firmware_updater}" | 214 SHELLBALL="${FLAGS_firmware_updater}" |
| 206 if [ ! -f "$SHELLBALL" ]; then | 215 if [ ! -f "$SHELLBALL" ]; then |
| 207 echo "Failed to find firmware updater: $SHELLBALL." | 216 echo "Failed to find firmware updater: $SHELLBALL." |
| 208 exit 1 | 217 exit 1 |
| 209 fi | 218 fi |
| 210 | 219 |
| 211 firmware_hash="$(compress_and_hash_file "$SHELLBALL" "firmware.gz")" | 220 firmware_hash="$(compress_and_hash_file "$SHELLBALL" "firmware.gz")" |
| 212 mv firmware.gz ${OMAHA_DATA_DIR} | 221 mv firmware.gz "${OMAHA_DATA_DIR}" |
| 213 echo "firmware: ${firmware_hash}" | 222 echo "firmware: ${firmware_hash}" |
| 214 fi | 223 fi |
| 215 | 224 |
| 216 # If the file does exist and we are using the subfolder flag we are going to | 225 # If the file does exist and we are using the subfolder flag we are going to |
| 217 # append another config. | 226 # append another config. |
| 218 if [ -n "${FLAGS_subfolder}" ] && \ | 227 if [ -n "${FLAGS_subfolder}" ] && |
| 219 [ -f "${OMAHA_DIR}"/miniomaha.conf"" ] ; then | 228 [ -f "${OMAHA_CONF}" ]; then |
| 220 # Remove the ']' from the last line of the file so we can add another config. | 229 # Remove the ']' from the last line of the file so we can add another config. |
| 221 while [ -s "${OMAHA_DIR}/miniomaha.conf" ]; do | 230 while [ -s "${OMAHA_CONF}" ]; do |
| 222 # If the last line is null | 231 # If the last line is null |
| 223 if [ -z "$(tail -1 "${OMAHA_DIR}/miniomaha.conf")" ]; then | 232 if [ -z "$(tail -1 "${OMAHA_CONF}")" ]; then |
| 224 sed -i '$d' "${OMAHA_DIR}/miniomaha.conf" | 233 sed -i '$d' "${OMAHA_CONF}" |
| 225 elif [ "$(tail -1 "${OMAHA_DIR}/miniomaha.conf")" != ']' ]; then | 234 elif [ "$(tail -1 "${OMAHA_CONF}")" != ']' ]; then |
| 226 sed -i '$d' "${OMAHA_DIR}/miniomaha.conf" | 235 sed -i '$d' "${OMAHA_CONF}" |
| 227 else | 236 else |
| 228 break | 237 break |
| 229 fi | 238 fi |
| 230 done | 239 done |
| 231 | 240 |
| 232 # Remove the last ] | 241 # Remove the last ] |
| 233 if [ "$(tail -1 "${OMAHA_DIR}/miniomaha.conf")" = ']' ]; then | 242 if [ "$(tail -1 "${OMAHA_CONF}")" = ']' ]; then |
| 234 sed -i '$d' "${OMAHA_DIR}/miniomaha.conf" | 243 sed -i '$d' "${OMAHA_CONF}" |
| 235 fi | 244 fi |
| 236 | 245 |
| 237 # If the file is empty, create it from scratch | 246 # If the file is empty, create it from scratch |
| 238 if [ ! -s "${OMAHA_DIR}/miniomaha.conf" ]; then | 247 if [ ! -s "${OMAHA_CONF}" ]; then |
| 239 echo "config = [" > "${OMAHA_DIR}/miniomaha.conf" | 248 echo "config = [" >"${OMAHA_CONF}" |
| 240 fi | 249 fi |
| 241 else | 250 else |
| 242 echo "config = [" > "${OMAHA_DIR}/miniomaha.conf" | 251 echo "config = [" >"${OMAHA_CONF}" |
| 243 fi | 252 fi |
| 244 | 253 |
| 245 if [ -n "${FLAGS_subfolder}" ] ; then | 254 if [ -n "${FLAGS_subfolder}" ]; then |
| 246 subfolder="${FLAGS_subfolder}/" | 255 subfolder="${FLAGS_subfolder}/" |
| 247 fi | 256 fi |
| 248 | 257 |
| 249 echo -n "{ | 258 echo -n "{ |
| 250 'qual_ids': set([\"${FLAGS_board}\"]), | 259 'qual_ids': set([\"${FLAGS_board}\"]), |
| 251 'factory_image': '"${subfolder}"rootfs-test.gz', | 260 'factory_image': '${subfolder}rootfs-test.gz', |
| 252 'factory_checksum': '${test_hash}', | 261 'factory_checksum': '${test_hash}', |
| 253 'release_image': '"${subfolder}"rootfs-release.gz', | 262 'release_image': '${subfolder}rootfs-release.gz', |
| 254 'release_checksum': '${release_hash}', | 263 'release_checksum': '${release_hash}', |
| 255 'oempartitionimg_image': '"${subfolder}"oem.gz', | 264 'oempartitionimg_image': '${subfolder}oem.gz', |
| 256 'oempartitionimg_checksum': '${oem_hash}', | 265 'oempartitionimg_checksum': '${oem_hash}', |
| 257 'efipartitionimg_image': '"${subfolder}"efi.gz', | 266 'efipartitionimg_image': '${subfolder}efi.gz', |
| 258 'efipartitionimg_checksum': '${efi_hash}', | 267 'efipartitionimg_checksum': '${efi_hash}', |
| 259 'stateimg_image': '"${subfolder}"state.gz', | 268 'stateimg_image': '${subfolder}state.gz', |
| 260 'stateimg_checksum': '${state_hash}'," >> ${OMAHA_DIR}/miniomaha.conf | 269 'stateimg_checksum': '${state_hash}'," >>"${OMAHA_CONF}" |
| 261 | 270 |
| 262 if [ ! -z "${FLAGS_firmware_updater}" ] ; then | 271 if [ -n "${FLAGS_firmware_updater}" ] ; then |
| 263 echo -n " | 272 echo -n " |
| 264 'firmware_image': '"${subfolder}"firmware.gz', | 273 'firmware_image': '${subfolder}firmware.gz', |
| 265 'firmware_checksum': '${firmware_hash}'," >> ${OMAHA_DIR}/miniomaha.conf | 274 'firmware_checksum': '${firmware_hash}'," >>"${OMAHA_CONF}" |
| 266 fi | 275 fi |
| 267 | 276 |
| 268 echo -n " | 277 echo -n " |
| 269 }, | 278 }, |
| 270 ] | 279 ] |
| 271 " >> ${OMAHA_DIR}/miniomaha.conf | 280 " >>"${OMAHA_CONF}" |
| 272 | 281 |
| 273 echo "The miniomaha server lives in src/platform/dev" | 282 echo "The miniomaha server lives in src/platform/dev |
|
Tom Wai-Hong Tam
2010/11/18 04:25:50
Better to add a period at the end.
Hung-Te
2010/11/18 05:49:31
Done.
| |
| 274 echo "to validate the configutarion, run:" | 283 To validate the configutarion, run: |
| 275 echo " python2.6 devserver.py --factory_config miniomaha.conf \ | 284 python devserver.py --factory_config miniomaha.conf --validate_factory_config |
|
Nick Sanders
2010/11/18 05:12:08
not all pythons can work, it needs 2.5+
Hung-Te
2010/11/18 05:49:31
I thought version check should be done inside the
Nick Sanders
2010/11/18 06:18:35
Agree that the check should be in devserver.py, bu
| |
| 276 --validate_factory_config" | 285 To run the server: |
| 277 echo "To run the server:" | 286 python devserver.py --factory_config miniomaha.conf" |
| 278 echo " python2.6 devserver.py --factory_config miniomaha.conf" | |
| OLD | NEW |