Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1573)

Side by Side Diff: scripts/image_signing/align_rootfs.sh

Issue 6079004: Preserves file system metadata between new build and latest shipping image. (Closed) Base URL: http://git.chromium.org/git/vboot_reference.git@master
Patch Set: Removed sudo from clean up trap. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | scripts/image_signing/common.sh » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/bin/bash
2
3 # Copyright (c) 2011 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 # Script to preserve the on-disk file layout of the specified image and
8 # the latest shipping image. This is accomplished by copying the new rootfs
9 # over a template rootfs (aka the latest shipping image) to preserve as much
10 # of the metadata from the shipping rootfs as possible. This will ensure
11 # minimal disk shuffling when applying the auto-update.
12 #
13 # Note: This script does not recompute the rootfs hash.
14
15 # Load common library. This should be the first executable line.
16 # The path to common.sh should be relative to your script's location.
17 . "$(dirname "$0")/common.sh"
18
19 load_shflags
20
21 # Flags.
22 DEFINE_string app_id "{87efface-864d-49a5-9bb3-4b050a7c227a}" \
23 "App ID to use when pinging the Omaha server for the latest version."
24 DEFINE_string channel "dev-channel" \
25 "Release channel of the build."
26 DEFINE_string hardware_id "IEC MARIO PONY 6101" \
27 "The Hardware ID of the latest shipping image to use as a template."
28 DEFINE_string image "" \
29 "The image that needs to be aligned to the latest shipping image."
30
31 IMAGE_SEARCH_STRING=
32 RELEASE_URL=
33 RELEASE_ALT_URL=
34
35 # Sets up environment variables specific to the board.
36 initialize() {
37 if [ "${FLAGS_hardware_id}" = "IEC MARIO PONY 6101" ]; then
38 IMAGE_SEARCH_STRING="*SSD_MP_SIGNED.bin"
39 RELEASE_URL="http://chromeos-images/chromeos-official/${FLAGS_channel}/x86-m ario"
40 RELEASE_ALT_URL="${RELEASE_URL}-rc"
41 else
42 die "Hardware ID \"${FLAGS_hardware_id}\" not supported"
43 fi
44 }
45
46 # Gets the latest shipping version for the specified Hardware ID by pinging
47 # the Omaha server. The latest shipping version is printed to stdout.
48 # The caller must use process substition when invoking this function so we
49 # use a simple trap for clean up instead of calling add_cleanup_action.
50 get_latest_shipping_version() {
51 info "Pinging Omaha for the latest shipping version."
52 local auserver_url="https://tools.google.com/service/update2"
53 local au_request_file=$(mktemp "/tmp/align_rootfs_au_request.XXXX")
54 trap "rm -f \"${au_request_file}\"" INT TERM EXIT
55 cat > "${au_request_file}" << EOF
56 <?xml version="1.0" encoding="UTF-8"?>
57 <o:gupdate xmlns:o="http://www.google.com/update2/request"
58 version="ChromeOSUpdateEngine-0.1.0.0"
59 updaterversion="ChromeOSUpdateEngine-0.1.0.0" protocol="2.0" ismachine="1">
60 <o:os version="Indy" platform="Chrome OS" sp="ForcedUpdate_i686"></o:os>
61 <o:app appid="${FLAGS_app_id}"
62 version="0.0.0.0" lang="en-US" track="${FLAGS_channel}"
63 hardware_class="${FLAGS_hardware_id}" delta_okay="true">
64 <o:updatecheck></o:updatecheck>
65 </o:app>
66 </o:gupdate>
67 EOF
68
69 wget -q --header="Content-Type: text/xml" \
70 --post-file="${au_request_file}" -O - ${auserver_url} |
71 sed 's/.*\(ChromeOSVersion="\)\([0-9\.]*\)"\(.*\)/\2/'
72 }
73
74 # Downloads the image from the specified |URL| using ${IMAGE_SEARCH_STRING} as
75 # a wildcard match and write the image to |OUTPUT_FILE|.
76 # Args: URL OUTPUT_FILE
77 download_image() {
78 # Since we don't know the exact name, we'll just download recursively based
79 # on a wildcard. Then we'll rename that download file to the desired output
80 # file. It's important that the IMAGE_SEARCH_STRING matches only one file.
81 local url=$1
82 local output_file=$2
83 local retcode=0
84
85 local download_dir=$(mktemp -d "/tmp/align_rootfs_download_dir.XXXX")
86 add_cleanup_action "sudo rm -rf \"${download_dir}\""
87
88 wget -A "${IMAGE_SEARCH_STRING}" --progress=bar -r -l1 -nd \
89 -P "${download_dir}" ${url} || retcode=$?
90 if [ ${retcode} -eq 0 ]; then
91 mv -f "${download_dir}"/* "${output_file}"
92 else
93 return ${retcode}
94 fi
95 }
96
97 # Retrieves the latest shipping image and saves it to |IMAGE|.
98 # Args: VERSION IMAGE
99 get_shipping_image() {
100 # The image may reside in one of two URLs. We don't know exactly which one
101 # so we'll have to try both.
102 local version=$1
103 local image=$2
104 local url="${RELEASE_URL}/${version}"
105 download_image "${url}" "${image}" || retcode=$?
106 if [ ${retcode} -gt 0 ]; then
107 url="${RELEASE_ALT_URL}/${version}"
108 download_image "${url}" "${image}"
109 fi
110 }
111
112 # Copies the rootfs from |SRC_IMAGE| to the |DST_ROOT_FS| and preserves as
113 # much of the file system metadata in |DST_ROOT_FS| as possible.
114 # Args: SRC_IMAGE DST_ROOT_FS
115 copy_root_fs() {
116 local src_image=$1
117 local dst_root_fs=$2
118
119 # Mount the src and dst rootfs.
120 local src_root_fs_dir=$(mktemp -d "/tmp/align_root_fs_src_mount_dir.XXXX")
121 add_cleanup_action "sudo rm -rf \"${src_root_fs_dir}\""
122 mount_image_partition_ro "${src_image}" 3 "${src_root_fs_dir}"
123 add_cleanup_action "sudo umount -d \"${src_root_fs_dir}\""
124
125 local dst_root_fs_dir=$(mktemp -d "/tmp/align_root_fs_dst_mount_dir.XXXX")
126 add_cleanup_action "sudo rm -rf \"${dst_root_fs_dir}\""
127 sudo mount -o loop "${dst_root_fs}" "${dst_root_fs_dir}" -o loop
128 add_cleanup_action "sudo umount -d \"${dst_root_fs_dir}\""
129
130 # Temporarily make immutable files on the dst rootfs mutable.
131 # We'll need to track these files in ${immutable_files} so we can make them
132 # mutable again.
133 local immutable_files=()
134 sudo find "${dst_root_fs_dir}" -xdev -type f |
135 while read -r file; do
136 immutable=$(sudo lsattr "${file}" | cut -d' ' -f1 | grep -q i ; echo $?)
137 if [ $immutable -eq 0 ]; then
138 immutable_files=("${immutable_files[@]}" "${file}")
139 sudo chattr -i "${file}"
140 fi
141 done
142
143 # Copy files from the src rootfs over top of dst rootfs.
144 # Use the --inplace flag to preserve as much of the file system metadata
145 # as possible.
146 sudo rsync -v -a -H -A -x --force --inplace --numeric-ids --delete \
147 "${src_root_fs_dir}"/ "${dst_root_fs_dir}"
148
149 # Make immutable files immutable again.
150 for file in ${immutable_files[*]} ; do
151 sudo chattr +i "${file}"
152 done
153
154 # Unmount the src and dst root fs so that we can replace the rootfs later.
155 perform_latest_cleanup_action
156 perform_latest_cleanup_action
157 perform_latest_cleanup_action
158 perform_latest_cleanup_action
159 }
160
161 # Zeroes the rootfs free space in the specified image.
162 # Args: IMAGE
163 zero_root_fs_free_space() {
164 local image=$1
165 local root_fs_dir=$(mktemp -d "/tmp/align_rootfs_zero_free_space_dir.XXXX")
166 add_cleanup_action "sudo rm -rf \"${root_fs_dir}\""
167 mount_image_partition "${image}" 3 "${root_fs_dir}"
168 add_cleanup_action "sudo umount -d \"${root_fs_dir}\""
169
170 info "Zeroing free space in rootfs"
171 sudo dd if=/dev/zero of="${root_fs_dir}/filler" oflag=sync bs=4096 || true
172 sudo rm -f "${root_fs_dir}/filler"
173 sudo sync
174
175 perform_latest_cleanup_action
176 perform_latest_cleanup_action
177 }
178
179 main() {
180 # Parse command line.
181 FLAGS "$@" || exit 1
182 eval set -- "${FLAGS_ARGV}"
183
184 # Only now can we die on error. shflags functions leak non-zero error codes,
185 # so will die prematurely if 'set -e' is specified before now.
186 set -e
187
188 # Make sure we have the required parameters.
189 if [ -z "${FLAGS_image}" ]; then
190 die "--image is required."
191 fi
192
193 if [ ! -f "${FLAGS_image}" ]; then
194 die "Cannot find the specified image."
195 fi
196
197 # Initialize some variables specific to the board.
198 initialize
199
200 # Download the latest shipping image.
201 local latest_shipping_version=$(get_latest_shipping_version)
202 local latest_shipping_image=$(mktemp "/tmp/align_rootfs_shipping_image.XXXX")
203 add_cleanup_action "sudo rm -f \"${latest_shipping_image}\""
204 info "Downloading image (${latest_shipping_version})"
205 get_shipping_image "${latest_shipping_version}" "${latest_shipping_image}"
206
207 # Make sure the two rootfs are the same size.
208 # If they are not, then there is nothing for us to do.
209 # Note: Exit with a zero code so we do not break the build workflow.
210 local shipping_root_fs_size=$(partsize "${latest_shipping_image}" 3)
211 local new_root_fs_size=$(partsize "${FLAGS_image}" 3)
212 if [ ${shipping_root_fs_size} -ne ${new_root_fs_size} ]; then
213 warn "The latest shipping rootfs and the new rootfs are not the same size."
214 exit 0
215 fi
216
217 # Extract the rootfs from the shipping image and use this as a template
218 # for the new image.
219 temp_root_fs=$(mktemp "/tmp/align_rootfs_temp_rootfs.XXXX")
220 add_cleanup_action "sudo rm -f \"${temp_root_fs}\""
221 info "Extracting rootfs from shipping image"
222 extract_image_partition "${latest_shipping_image}" 3 "${temp_root_fs}"
223 enable_rw_mount "${temp_root_fs}"
224
225 # Perform actual copy of the two root file systems.
226 info "Copying rootfs"
227 copy_root_fs "${FLAGS_image}" "${temp_root_fs}"
228
229 # Replace the rootfs in the new image with the aligned version.
230 info "Replacing rootfs"
231 replace_image_partition "${FLAGS_image}" 3 "${temp_root_fs}"
232
233 # Zero rootfs free space.
234 zero_root_fs_free_space "${FLAGS_image}"
235 }
236
237 main "$@"
OLDNEW
« no previous file with comments | « no previous file | scripts/image_signing/common.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698