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

Side by Side Diff: chrome/tools/build/mac/keystone_install.sh

Issue 365004: When updating on a user ticket, check for system tickets (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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 | chrome/tools/build/mac/keystone_install_test.sh » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/bin/bash 1 #!/bin/bash
2 2
3 # Copyright (c) 2009 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2009 The Chromium 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 # Called by the Keystone system to update the installed application with a new 7 # Called by the Keystone system to update the installed application with a new
8 # version from a disk image. 8 # version from a disk image.
9 9
10 # Return values: 10 # Return values:
11 # 0 Happiness 11 # 0 Happiness
12 # 1 Unknown failure 12 # 1 Unknown failure
13 # 2 Basic sanity check destination failure (e.g. ticket points to nothing) 13 # 2 Basic sanity check source failure (e.g. no app on disk image)
14 # 3 Could not prepare existing installed version to receive update 14 # 3 Basic sanity check destination failure (e.g. ticket points to nothing)
15 # 4 rsync failed (could not assure presence of Versions directory) 15 # 4 Update driven by user ticket when a system ticket is also present
16 # 5 rsync failed (could not copy new versioned directory to Versions) 16 # 5 Could not prepare existing installed version to receive update
17 # 6 rsync failed (could not update outer .app bundle) 17 # 6 rsync failed (could not assure presence of Versions directory)
18 # 7 Could not get the version, update URL, or channel after update 18 # 7 rsync failed (could not copy new versioned directory to Versions)
19 # 8 Updated application does not have the version number from the update 19 # 8 rsync failed (could not update outer .app bundle)
20 # 9 ksadmin failure 20 # 9 Could not get the version, update URL, or channel after update
21 # 10 Basic sanity check source failure (e.g. no app on disk image) 21 # 10 Updated application does not have the version number from the update
22 # 11 ksadmin failure
22 23
23 set -e 24 set -e
24 25
25 # Returns 0 (true) if the parameter exists, is a symbolic link, and appears 26 # Returns 0 (true) if the parameter exists, is a symbolic link, and appears
26 # writable on the basis of its POSIX permissions. This is used to determine 27 # writable on the basis of its POSIX permissions. This is used to determine
27 # writeability like test's -w primary, but -w resolves symbolic links and this 28 # writeability like test's -w primary, but -w resolves symbolic links and this
28 # function does not. 29 # function does not.
29 function is_writable_symlink() { 30 function is_writable_symlink() {
30 SYMLINK=${1} 31 SYMLINK=${1}
31 LINKMODE=$(stat -f %Sp "${SYMLINK}" 2> /dev/null || true) 32 LINKMODE=$(stat -f %Sp "${SYMLINK}" 2> /dev/null || true)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 chmod -h 755 "${TEMPLINK}" && \ 111 chmod -h 755 "${TEMPLINK}" && \
111 mv -f "${TEMPLINK}" "${SYMLINKDIR}") || true 112 mv -f "${TEMPLINK}" "${SYMLINKDIR}") || true
112 rm -rf "${TEMPLINKDIR}" 113 rm -rf "${TEMPLINKDIR}"
113 fi 114 fi
114 115
115 return 0 116 return 0
116 } 117 }
117 118
118 # The argument should be the disk image path. Make sure it exists. 119 # The argument should be the disk image path. Make sure it exists.
119 if [ $# -lt 1 ] || [ ! -d "${1}" ]; then 120 if [ $# -lt 1 ] || [ ! -d "${1}" ]; then
120 exit 10 121 exit 2
121 fi 122 fi
122 123
123 # Who we are. 124 # Who we are.
124 PRODUCT_NAME="Google Chrome" 125 PRODUCT_NAME="Google Chrome"
125 APP_DIR="${PRODUCT_NAME}.app" 126 APP_DIR="${PRODUCT_NAME}.app"
126 FRAMEWORK_NAME="${PRODUCT_NAME} Framework" 127 FRAMEWORK_NAME="${PRODUCT_NAME} Framework"
127 FRAMEWORK_DIR="${FRAMEWORK_NAME}.framework" 128 FRAMEWORK_DIR="${FRAMEWORK_NAME}.framework"
128 SRC="${1}/${APP_DIR}" 129 SRC="${1}/${APP_DIR}"
129 130
130 # Make sure that there's something to copy from, and that it's an absolute 131 # Make sure that there's something to copy from, and that it's an absolute
131 # path. 132 # path.
132 if [ -z "${SRC}" ] || [ "${SRC:0:1}" != "/" ] || [ ! -d "${SRC}" ] ; then 133 if [ -z "${SRC}" ] || [ "${SRC:0:1}" != "/" ] || [ ! -d "${SRC}" ] ; then
133 exit 10 134 exit 2
134 fi 135 fi
135 136
136 # Figure out where we're going. Determine the application version to be 137 # Figure out where we're going. Determine the application version to be
137 # installed, use that to locate the framework, and then look inside the 138 # installed, use that to locate the framework, and then look inside the
138 # framework for the Keystone product ID. 139 # framework for the Keystone product ID.
139 APP_VERSION_KEY="CFBundleShortVersionString" 140 APP_VERSION_KEY="CFBundleShortVersionString"
140 UPD_VERSION_APP=$(defaults read "${SRC}/Contents/Info" "${APP_VERSION_KEY}" || 141 UPD_VERSION_APP=$(defaults read "${SRC}/Contents/Info" "${APP_VERSION_KEY}" ||
141 exit 10) 142 exit 2)
142 UPD_KS_PLIST="${SRC}/Contents/Versions/${UPD_VERSION_APP}/${FRAMEWORK_DIR}/Resou rces/Info" 143 UPD_KS_PLIST="${SRC}/Contents/Versions/${UPD_VERSION_APP}/${FRAMEWORK_DIR}/Resou rces/Info"
143 KS_VERSION_KEY="KSVersion" 144 KS_VERSION_KEY="KSVersion"
144 UPD_VERSION_KS=$(defaults read "${UPD_KS_PLIST}" "${KS_VERSION_KEY}" || exit 10) 145 UPD_VERSION_KS=$(defaults read "${UPD_KS_PLIST}" "${KS_VERSION_KEY}" || exit 2)
145 PRODUCT_ID=$(defaults read "${UPD_KS_PLIST}" KSProductID || exit 10) 146 PRODUCT_ID=$(defaults read "${UPD_KS_PLIST}" KSProductID || exit 2)
146 if [ -z "${UPD_VERSION_KS}" ] || [ -z "${PRODUCT_ID}" ] ; then 147 if [ -z "${UPD_VERSION_KS}" ] || [ -z "${PRODUCT_ID}" ] ; then
147 exit 2 148 exit 3
148 fi 149 fi
149 DEST=$(ksadmin -pP "${PRODUCT_ID}" | 150 DEST=$(ksadmin -pP "${PRODUCT_ID}" |
150 sed -Ene \ 151 sed -Ene \
151 's%^[[:space:]]+xc=<KSPathExistenceChecker:.* path=(/.+)>$%\1%p') 152 's%^[[:space:]]+xc=<KSPathExistenceChecker:.* path=(/.+)>$%\1%p')
152 153
153 # More sanity checking. 154 # More sanity checking.
154 if [ -z "${DEST}" ] || [ ! -d "${DEST}" ]; then 155 if [ -z "${DEST}" ] || [ ! -d "${DEST}" ]; then
155 exit 2 156 exit 3
157 fi
158
159 # If this script is not running as root, it's being driven by a user ticket.
160 # If a system ticket is also present, there's a potential for the two to
161 # collide. Both ticket types might be present if another user on the system
162 # promoted the ticket to system: the other user could not have removed this
163 # user's user ticket. Handle that case here by deleting the user ticket and
164 # exiting early with a discrete exit status.
165 #
166 # Current versions of ksadmin will exit 1 (false) when asked to print tickets
167 # and given a specific product ID to print. Older versions of ksadmin would
168 # exit 0 (true), but those same versions did not support -S (meaning to check
169 # the system ticket store) and would exit 1 (false) with this invocation due
170 # to not understanding the question. Therefore, the usage here will only
171 # delete the existing user ticket when running as non-root with access to a
172 # sufficiently recent ksadmin. Older ksadmins are tolerated: the update will
173 # likely fail for another reason and the user ticket will hang around until
174 # something is eventually able to remove it.
175 if [ ${EUID} -ne 0 ] &&
176 ksadmin -S --print-tickets -P "${PRODUCT_ID}" >& /dev/null ; then
177 ksadmin --delete -P "${PRODUCT_ID}" || true
178 exit 4
156 fi 179 fi
157 180
158 # Figure out what the existing version is using for its versioned directory. 181 # Figure out what the existing version is using for its versioned directory.
159 # This will be used later, to avoid removing the currently-installed version's 182 # This will be used later, to avoid removing the currently-installed version's
160 # versioned directory in case anything is still using it. 183 # versioned directory in case anything is still using it.
161 OLD_VERSION_APP=$(defaults read "${DEST}/Contents/Info" "${APP_VERSION_KEY}" || 184 OLD_VERSION_APP=$(defaults read "${DEST}/Contents/Info" "${APP_VERSION_KEY}" ||
162 true) 185 true)
163 OLD_VERSIONED_DIR="${DEST}/Contents/Versions/${OLD_VERSION_APP}" 186 OLD_VERSIONED_DIR="${DEST}/Contents/Versions/${OLD_VERSION_APP}"
164 187
165 # See if the timestamp of what's currently on disk is newer than the update's 188 # See if the timestamp of what's currently on disk is newer than the update's
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 # directory, otherwise, this directory would be the only one in the entire 265 # directory, otherwise, this directory would be the only one in the entire
243 # update exempt from getting its permissions copied over. A simple mkdir 266 # update exempt from getting its permissions copied over. A simple mkdir
244 # wouldn't copy mode bits. This is done even if ${DEST}/Contents/Versions 267 # wouldn't copy mode bits. This is done even if ${DEST}/Contents/Versions
245 # already does exist to ensure that the mode bits come from the update. 268 # already does exist to ensure that the mode bits come from the update.
246 # 269 #
247 # ${DEST} is guaranteed to exist at this point, but ${DEST}/Contents may not 270 # ${DEST} is guaranteed to exist at this point, but ${DEST}/Contents may not
248 # if things are severely broken or if this update is actually an initial 271 # if things are severely broken or if this update is actually an initial
249 # installation from a Keystone skeleton bootstrap. The mkdir creates 272 # installation from a Keystone skeleton bootstrap. The mkdir creates
250 # ${DEST}/Contents if it doesn't exist; its mode bits will be fixed up in a 273 # ${DEST}/Contents if it doesn't exist; its mode bits will be fixed up in a
251 # subsequent rsync. 274 # subsequent rsync.
252 mkdir -p "${DEST}/Contents" || exit 3 275 mkdir -p "${DEST}/Contents" || exit 5
253 rsync ${RSYNC_FLAGS} --exclude "*" "${SRC}/Contents/Versions/" \ 276 rsync ${RSYNC_FLAGS} --exclude "*" "${SRC}/Contents/Versions/" \
254 "${DEST}/Contents/Versions" || exit 4 277 "${DEST}/Contents/Versions" || exit 6
255 278
256 # Copy the versioned directory. The new versioned directory will have a 279 # Copy the versioned directory. The new versioned directory will have a
257 # different name than any existing one, so this won't harm anything already 280 # different name than any existing one, so this won't harm anything already
258 # present in Contents/Versions, including the versioned directory being used 281 # present in Contents/Versions, including the versioned directory being used
259 # by any running processes. If this step is interrupted, there will be an 282 # by any running processes. If this step is interrupted, there will be an
260 # incomplete versioned directory left behind, but it won't interfere with 283 # incomplete versioned directory left behind, but it won't interfere with
261 # anything, and it will be replaced or removed during a future update attempt. 284 # anything, and it will be replaced or removed during a future update attempt.
262 NEW_VERSIONED_DIR="${DEST}/Contents/Versions/${UPD_VERSION_APP}" 285 NEW_VERSIONED_DIR="${DEST}/Contents/Versions/${UPD_VERSION_APP}"
263 rsync ${RSYNC_FLAGS} --delete-before \ 286 rsync ${RSYNC_FLAGS} --delete-before \
264 "${SRC}/Contents/Versions/${UPD_VERSION_APP}/" \ 287 "${SRC}/Contents/Versions/${UPD_VERSION_APP}/" \
265 "${NEW_VERSIONED_DIR}" || exit 5 288 "${NEW_VERSIONED_DIR}" || exit 7
266 289
267 # Copy the unversioned files into place, leaving everything in 290 # Copy the unversioned files into place, leaving everything in
268 # Contents/Versions alone. If this step is interrupted, the application will 291 # Contents/Versions alone. If this step is interrupted, the application will
269 # at least remain in a usable state, although it may not pass signature 292 # at least remain in a usable state, although it may not pass signature
270 # validation. Depending on when this step is interrupted, the application 293 # validation. Depending on when this step is interrupted, the application
271 # will either launch the old or the new version. The critical point is when 294 # will either launch the old or the new version. The critical point is when
272 # the main executable is replaced. There isn't very much to copy in this step, 295 # the main executable is replaced. There isn't very much to copy in this step,
273 # because most of the application is in the versioned directory. This step 296 # because most of the application is in the versioned directory. This step
274 # only accounts for around 50 files, most of which are small localized 297 # only accounts for around 50 files, most of which are small localized
275 # InfoPlist.strings files. 298 # InfoPlist.strings files.
276 rsync ${RSYNC_FLAGS} --delete-after --exclude /Contents/Versions \ 299 rsync ${RSYNC_FLAGS} --delete-after --exclude /Contents/Versions \
277 "${SRC}/" "${DEST}" || exit 6 300 "${SRC}/" "${DEST}" || exit 8
278 301
279 # If necessary, touch the outermost .app so that it appears to the outside 302 # If necessary, touch the outermost .app so that it appears to the outside
280 # world that something was done to the bundle. This will cause LaunchServices 303 # world that something was done to the bundle. This will cause LaunchServices
281 # to invalidate the information it has cached about the bundle even if 304 # to invalidate the information it has cached about the bundle even if
282 # lsregister does not run. This is not done if rsync already updated the 305 # lsregister does not run. This is not done if rsync already updated the
283 # timestamp to something newer than what had been on disk. This is not 306 # timestamp to something newer than what had been on disk. This is not
284 # considered a critical step, and if it fails, this script will not exit. 307 # considered a critical step, and if it fails, this script will not exit.
285 if [ -n "${NEEDS_TOUCH}" ] ; then 308 if [ -n "${NEEDS_TOUCH}" ] ; then
286 touch -cf "${DEST}" || true 309 touch -cf "${DEST}" || true
287 fi 310 fi
288 311
289 # Read the new values (e.g. version). Get the installed application version 312 # Read the new values (e.g. version). Get the installed application version
290 # to get the path to the framework, where the Keystone keys are stored. 313 # to get the path to the framework, where the Keystone keys are stored.
291 NEW_VERSION_APP=$(defaults read "${DEST}/Contents/Info" "${APP_VERSION_KEY}" || 314 NEW_VERSION_APP=$(defaults read "${DEST}/Contents/Info" "${APP_VERSION_KEY}" ||
292 exit 7) 315 exit 9)
293 NEW_KS_PLIST="${DEST}/Contents/Versions/${NEW_VERSION_APP}/${FRAMEWORK_DIR}/Reso urces/Info" 316 NEW_KS_PLIST="${DEST}/Contents/Versions/${NEW_VERSION_APP}/${FRAMEWORK_DIR}/Reso urces/Info"
294 NEW_VERSION_KS=$(defaults read "${NEW_KS_PLIST}" "${KS_VERSION_KEY}" || exit 7) 317 NEW_VERSION_KS=$(defaults read "${NEW_KS_PLIST}" "${KS_VERSION_KEY}" || exit 9)
295 URL=$(defaults read "${NEW_KS_PLIST}" KSUpdateURL || exit 7) 318 URL=$(defaults read "${NEW_KS_PLIST}" KSUpdateURL || exit 9)
296 # The channel ID is optional. Suppress stderr to prevent Keystone from seeing 319 # The channel ID is optional. Suppress stderr to prevent Keystone from seeing
297 # possible error output. 320 # possible error output.
298 CHANNEL_ID=$(defaults read "${NEW_KS_PLIST}" KSChannelID 2>/dev/null || true) 321 CHANNEL_ID=$(defaults read "${NEW_KS_PLIST}" KSChannelID 2>/dev/null || true)
299 322
300 # Make sure that the update was successful by comparing the version found in 323 # Make sure that the update was successful by comparing the version found in
301 # the update with the version now on disk. 324 # the update with the version now on disk.
302 if [ "${NEW_VERSION_KS}" != "${UPD_VERSION_KS}" ]; then 325 if [ "${NEW_VERSION_KS}" != "${UPD_VERSION_KS}" ]; then
303 exit 8 326 exit 10
304 fi 327 fi
305 328
306 # Notify LaunchServices. This is not considered a critical step, and 329 # Notify LaunchServices. This is not considered a critical step, and
307 # lsregister's exit codes shouldn't be confused with this script's own. 330 # lsregister's exit codes shouldn't be confused with this script's own.
308 /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.fram ework/Support/lsregister "${DEST}" || true 331 /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.fram ework/Support/lsregister "${DEST}" || true
309 332
310 # Notify Keystone. 333 # Notify Keystone.
311 KSADMIN_VERSION=$(ksadmin --ksadmin-version || true) 334 KSADMIN_VERSION=$(ksadmin --ksadmin-version || true)
312 if [ -n "${KSADMIN_VERSION}" ] ; then 335 if [ -n "${KSADMIN_VERSION}" ] ; then
313 # If ksadmin recognizes --ksadmin-version, it will recognize --tag. 336 # If ksadmin recognizes --ksadmin-version, it will recognize --tag.
314 ksadmin --register \ 337 ksadmin --register \
315 -P "${PRODUCT_ID}" \ 338 -P "${PRODUCT_ID}" \
316 --version "${NEW_VERSION_KS}" \ 339 --version "${NEW_VERSION_KS}" \
317 --xcpath "${DEST}" \ 340 --xcpath "${DEST}" \
318 --url "${URL}" \ 341 --url "${URL}" \
319 --tag "${CHANNEL_ID}" || exit 9 342 --tag "${CHANNEL_ID}" || exit 11
320 else 343 else
321 # Older versions of ksadmin don't recognize --tag. The application will 344 # Older versions of ksadmin don't recognize --tag. The application will
322 # set the tag when it runs. 345 # set the tag when it runs.
323 ksadmin --register \ 346 ksadmin --register \
324 -P "${PRODUCT_ID}" \ 347 -P "${PRODUCT_ID}" \
325 --version "${NEW_VERSION_KS}" \ 348 --version "${NEW_VERSION_KS}" \
326 --xcpath "${DEST}" \ 349 --xcpath "${DEST}" \
327 --url "${URL}" || exit 9 350 --url "${URL}" || exit 11
328 fi 351 fi
329 352
330 # The remaining steps are not considered critical. 353 # The remaining steps are not considered critical.
331 set +e 354 set +e
332 355
333 # Try to clean up old versions that are not in use. The strategy is to keep 356 # Try to clean up old versions that are not in use. The strategy is to keep
334 # the versioned directory corresponding to the update just applied 357 # the versioned directory corresponding to the update just applied
335 # (obviously) and the version that was just replaced, and to use ps and lsof 358 # (obviously) and the version that was just replaced, and to use ps and lsof
336 # to see if it looks like any processes are currently using any other old 359 # to see if it looks like any processes are currently using any other old
337 # directories. Directories not in use are removed. Old versioned directories 360 # directories. Directories not in use are removed. Old versioned directories
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 ([ ${OS_MAJOR} -eq 10 ] && [ ${OS_MINOR} -ge 6 ]) ; then 497 ([ ${OS_MAJOR} -eq 10 ] && [ ${OS_MINOR} -ge 6 ]) ; then
475 # On 10.6, xattr supports -r for recursive operation. 498 # On 10.6, xattr supports -r for recursive operation.
476 xattr -d -r "${QUARANTINE_ATTR}" "${DEST}" >& /dev/null 499 xattr -d -r "${QUARANTINE_ATTR}" "${DEST}" >& /dev/null
477 else 500 else
478 # On earlier systems, xattr doesn't support -r, so run xattr via find. 501 # On earlier systems, xattr doesn't support -r, so run xattr via find.
479 find "${DEST}" -exec xattr -d "${QUARANTINE_ATTR}" {} + >& /dev/null 502 find "${DEST}" -exec xattr -d "${QUARANTINE_ATTR}" {} + >& /dev/null
480 fi 503 fi
481 504
482 # Great success! 505 # Great success!
483 exit 0 506 exit 0
OLDNEW
« no previous file with comments | « no previous file | chrome/tools/build/mac/keystone_install_test.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698