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

Side by Side Diff: chrome/installer/mac/keystone_install.sh

Issue 124813002: Make the update installer fail when attempting to install a 64-bit update on a 32-bit-only system (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | no next file » | 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 -p 1 #!/bin/bash -p
2 2
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2012 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 # usage: keystone_install.sh update_dmg_mount_point 7 # usage: keystone_install.sh update_dmg_mount_point
8 # 8 #
9 # Called by the Keystone system to update the installed application with a new 9 # Called by the Keystone system to update the installed application with a new
10 # version from a disk image. 10 # version from a disk image.
(...skipping 13 matching lines...) Expand all
24 # 4 Update driven by user ticket when a system ticket is also present 24 # 4 Update driven by user ticket when a system ticket is also present
25 # 5 Could not prepare existing installed version to receive update 25 # 5 Could not prepare existing installed version to receive update
26 # 6 Patch sanity check failure 26 # 6 Patch sanity check failure
27 # 7 rsync failed (could not copy new versioned directory to Versions) 27 # 7 rsync failed (could not copy new versioned directory to Versions)
28 # 8 rsync failed (could not update outer .app bundle) 28 # 8 rsync failed (could not update outer .app bundle)
29 # 9 Could not get the version, update URL, or channel after update 29 # 9 Could not get the version, update URL, or channel after update
30 # 10 Updated application does not have the version number from the update 30 # 10 Updated application does not have the version number from the update
31 # 11 ksadmin failure 31 # 11 ksadmin failure
32 # 12 dirpatcher failed for versioned directory 32 # 12 dirpatcher failed for versioned directory
33 # 13 dirpatcher failed for outer .app bundle 33 # 13 dirpatcher failed for outer .app bundle
34 # 14 The update is incompatible with the system
Nico 2014/01/06 05:32:14 Since that other patch mentioned something in chro
34 # 35 #
35 # The following exit codes can be used to convey special meaning to Keystone. 36 # The following exit codes can be used to convey special meaning to Keystone.
36 # KeystoneRegistration will present these codes to Chrome as "success." 37 # KeystoneRegistration will present these codes to Chrome as "success."
37 # 66 (unused) success, request reboot 38 # 66 (unused) success, request reboot
38 # 77 (unused) try installation again later 39 # 77 (unused) try installation again later
39 40
40 set -eu 41 set -eu
41 42
42 # http://b/2290916: Keystone runs the installation with a restrictive PATH 43 # http://b/2290916: Keystone runs the installation with a restrictive PATH
43 # that only includes the directory containing ksadmin, /bin, and /usr/bin. It 44 # that only includes the directory containing ksadmin, /bin, and /usr/bin. It
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 # This function exists because the update process delivers new copies of 488 # This function exists because the update process delivers new copies of
488 # Info.plist files to the disk behind cfprefsd's back, and if cfprefsd becomes 489 # Info.plist files to the disk behind cfprefsd's back, and if cfprefsd becomes
489 # aware of the original version of the file for any reason (such as this 490 # aware of the original version of the file for any reason (such as this
490 # script reading values from it via "defaults read"), the new version of the 491 # script reading values from it via "defaults read"), the new version of the
491 # file will not be immediately effective or visible via cfprefsd after the 492 # file will not be immediately effective or visible via cfprefsd after the
492 # update is applied. 493 # update is applied.
493 infoplist_read() { 494 infoplist_read() {
494 __CFPREFERENCES_AVOID_DAEMON=1 defaults read "${@}" 495 __CFPREFERENCES_AVOID_DAEMON=1 defaults read "${@}"
495 } 496 }
496 497
498 # Adjust the tag to contain the -32bit tag suffix. This is intended to be used
499 # as a last resort, if sanity checks show that a non-32-bit update is about to
500 # be applied to a 32-bit-only system. If this happens, it means that the
501 # server delivered a non-32-bit update to a 32-bit-only system, most likely
502 # because the tag was never updated to include the -32bit tag suffix.
503 #
504 # This mechanism takes a heavy-handed approach, clearing --tag-path and
505 # --tag-key so that the channel identity will no longer follow the installed
506 # application. However, it's expected that once -32bit is added to the tag,
507 # the server will deliver a 32-bit update (possibly the final 32-bit version),
508 # and once installed, that update will restore the --tag-path and --tag-key.
509 # In any event, channel identity in this case may be moot, if 32-bit builds
510 # are no longer being produced.
511 #
512 # This provides some resilience in the update system for old 32-bit-only
513 # systems that aren't used during the window between when the -32bit tag
514 # suffix begins being used and 32-bit releases end.
515 mark_32_bit_only_system() {
516 local product_id="${1}"
517
518 # This step isn't critical.
519 local set_e=
520 if [[ "${-}" =~ e ]]; then
521 set_e="y"
522 set +e
523 fi
524
525 note "marking 32-bit-only system"
526
527 if ! ksadmin_supports_tagpath_tagkey; then
528 note "couldn't mark 32-bit-only system, no ksadmin support"
529 if [[ -n "${set_e}" ]]; then
530 set -e
531 fi
532 return 0
533 fi
534
535 local current_tag="$(ksadmin --productid "${product_id}" --print-tag)"
536 note "current_tag = ${current_tag}"
537
538 if grep -Eq -- '-32bit(-|$)' <<< "${current_tag}"; then
539 note "current tag already has -32bit"
540 if [[ -n "${set_e}" ]]; then
541 set -e
542 fi
543 return 0
544 fi
545
546 # This clears any other tag suffix, but that shouldn't be a problem. The
547 # only other currently-defined tag suffix component is -full, but -full and
548 # -32bit were introduced at the same time, so if -full appears, whatever set
549 # it would have already had enough knowledge to set -32bit as well, and this
550 # codepath wouldn't be entered.
551 local current_channel="$(sed -e 's/-.*//' <<< "${current_tag}")"
552 local new_tag="${current_channel}-32bit"
553 note "new_tag = ${new_tag}"
554
555 # Using ksadmin without --register only updates specified values in the
556 # ticket, without changing other existing values. Giving empty values for
557 # --tag-path and --tag-key clears those fields.
558 if ! ksadmin --productid "${product_id}" \
559 --tag "${new_tag}" --tag-path '' --tag-key ''; then
560 err "ksadmin failed to mark 32-bit-only system"
561 else
562 note "marked 32-bit-only system"
563 fi
564
565 # Go back to how things were.
566 if [[ -n "${set_e}" ]]; then
567 set -e
568 fi
569 }
570
497 # When a patch update fails because the old installed copy doesn't match the 571 # When a patch update fails because the old installed copy doesn't match the
498 # expected state, mark_failed_patch_update updates the Keystone ticket by 572 # expected state, mark_failed_patch_update updates the Keystone ticket by
499 # adding "-full" to the tag. The server will see this on a subsequent update 573 # adding "-full" to the tag. The server will see this on a subsequent update
500 # attempt and will provide a full update (as opposed to a patch) to the 574 # attempt and will provide a full update (as opposed to a patch) to the
501 # client. 575 # client.
502 # 576 #
503 # Even if mark_failed_patch_update fails to modify the tag, the user will 577 # Even if mark_failed_patch_update fails to modify the tag, the user will
504 # eventually be updated. Patch updates are only provided for successive 578 # eventually be updated. Patch updates are only provided for successive
505 # releases on a particular channel, to update version o to version o+1. If a 579 # releases on a particular channel, to update version o to version o+1. If a
506 # patch update fails in this case, eventually version o+2 will be released, 580 # patch update fails in this case, eventually version o+2 will be released,
507 # and no patch update will exist to update o to o+2, so the server will 581 # and no patch update will exist to update o to o+2, so the server will
508 # provide a full update package. 582 # provide a full update package.
509 mark_failed_patch_update() { 583 mark_failed_patch_update() {
510 local product_id="${1}" 584 local product_id="${1}"
511 local want_full_installer_path="${2}" 585 local want_full_installer_path="${2}"
512 local old_ks_plist="${3}" 586 local old_ks_plist="${3}"
513 local old_version_app="${4}" 587 local old_version_app="${4}"
514 local system_ticket="${5}" 588 local system_ticket="${5}"
515 589
516 set +e 590 # This step isn't critical.
591 local set_e=
592 if [[ "${-}" =~ e ]]; then
593 set_e="y"
594 set +e
595 fi
517 596
518 note "marking failed patch update" 597 note "marking failed patch update"
519 598
520 local channel 599 local channel
521 channel="$(infoplist_read "${old_ks_plist}" "${KS_CHANNEL_KEY}" 2> /dev/null)" 600 channel="$(infoplist_read "${old_ks_plist}" "${KS_CHANNEL_KEY}" 2> /dev/null)"
522 601
523 local tag="${channel}" 602 local tag="${channel}"
524 local tag_key="${KS_CHANNEL_KEY}" 603 local tag_key="${KS_CHANNEL_KEY}"
525 if has_32_bit_only_cpu; then 604 if has_32_bit_only_cpu; then
526 tag="${tag}-32bit" 605 tag="${tag}-32bit"
527 tag_key="${tag_key}-32bit" 606 tag_key="${tag_key}-32bit"
528 fi 607 fi
529 608
530 tag="${tag}-full" 609 tag="${tag}-full"
531 tag_key="${tag_key}-full" 610 tag_key="${tag_key}-full"
532 611
533 note "tag = ${tag}" 612 note "tag = ${tag}"
534 note "tag_key = ${tag_key}" 613 note "tag_key = ${tag_key}"
535 614
536 # ${old_ks_plist}, used for --tag-path, is the Info.plist for the old 615 # ${old_ks_plist}, used for --tag-path, is the Info.plist for the old
537 # version of Chrome. It may not contain the keys for the "-full" tag suffix. 616 # version of Chrome. It may not contain the keys for the "-full" tag suffix.
538 # If it doesn't, just bail out without marking the patch update as failed. 617 # If it doesn't, just bail out without marking the patch update as failed.
539 local read_tag="$(infoplist_read "${old_ks_plist}" "${tag_key}" 2> /dev/null)" 618 local read_tag="$(infoplist_read "${old_ks_plist}" "${tag_key}" 2> /dev/null)"
540 note "read_tag = ${read_tag}" 619 note "read_tag = ${read_tag}"
541 if [[ -z "${read_tag}" ]]; then 620 if [[ -z "${read_tag}" ]]; then
542 note "couldn't mark failed patch update" 621 note "couldn't mark failed patch update"
622 if [[ -n "${set_e}" ]]; then
623 set -e
624 fi
543 return 0 625 return 0
544 fi 626 fi
545 627
546 # Chrome can't easily read its Keystone ticket prior to registration, and 628 # Chrome can't easily read its Keystone ticket prior to registration, and
547 # when Chrome registers with Keystone, it obliterates old tag values in its 629 # when Chrome registers with Keystone, it obliterates old tag values in its
548 # ticket. Therefore, an alternative mechanism is provided to signal to 630 # ticket. Therefore, an alternative mechanism is provided to signal to
549 # Chrome that a full installer is desired. If the .want_full_installer file 631 # Chrome that a full installer is desired. If the .want_full_installer file
550 # is present and it contains Chrome's current version number, Chrome will 632 # is present and it contains Chrome's current version number, Chrome will
551 # include "-full" in its tag when it registers with Keystone. This allows 633 # include "-full" in its tag when it registers with Keystone. This allows
552 # "-full" to persist in the tag even after Chrome is relaunched, which on a 634 # "-full" to persist in the tag even after Chrome is relaunched, which on a
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 if ksadmin_supports_tagpath_tagkey; then 670 if ksadmin_supports_tagpath_tagkey; then
589 ksadmin_args+=( 671 ksadmin_args+=(
590 --tag-path "${old_ks_plist_path}" 672 --tag-path "${old_ks_plist_path}"
591 --tag-key "${tag_key}" 673 --tag-key "${tag_key}"
592 ) 674 )
593 fi 675 fi
594 676
595 note "ksadmin_args = ${ksadmin_args[*]}" 677 note "ksadmin_args = ${ksadmin_args[*]}"
596 678
597 if ! ksadmin "${ksadmin_args[@]}"; then 679 if ! ksadmin "${ksadmin_args[@]}"; then
598 err "ksadmin failed" 680 err "ksadmin failed to mark failed patch update"
681 else
682 note "marked failed patch update"
599 fi 683 fi
600 684
601 note "marked failed patch update" 685 # Go back to how things were.
602 686 if [[ -n "${set_e}" ]]; then
603 set -e 687 set -e
688 fi
604 } 689 }
605 690
606 usage() { 691 usage() {
607 echo "usage: ${ME} update_dmg_mount_point" >& 2 692 echo "usage: ${ME} update_dmg_mount_point" >& 2
608 } 693 }
609 694
610 main() { 695 main() {
611 local update_dmg_mount_point="${1}" 696 local update_dmg_mount_point="${1}"
612 697
613 # Early steps are critical. Don't continue past any failure. 698 # Early steps are critical. Don't continue past any failure.
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 # Collect the installed application's brand code, it will be used later. It 1028 # Collect the installed application's brand code, it will be used later. It
944 # is not an error for the installed application to not have a brand code. 1029 # is not an error for the installed application to not have a brand code.
945 local old_ks_plist="${installed_app_plist}" 1030 local old_ks_plist="${installed_app_plist}"
946 note "old_ks_plist = ${old_ks_plist}" 1031 note "old_ks_plist = ${old_ks_plist}"
947 local old_brand 1032 local old_brand
948 old_brand="$(infoplist_read "${old_ks_plist}" \ 1033 old_brand="$(infoplist_read "${old_ks_plist}" \
949 "${KS_BRAND_KEY}" 2> /dev/null || 1034 "${KS_BRAND_KEY}" 2> /dev/null ||
950 true)" 1035 true)"
951 note "old_brand = ${old_brand}" 1036 note "old_brand = ${old_brand}"
952 1037
1038 if has_32_bit_only_cpu; then
1039 # On a 32-bit-only system, make sure that the update contains 32-bit code.
1040 note "system is 32-bit-only"
1041
1042 local test_binary
1043 if [[ -z "${is_patch}" ]]; then
1044 # For a full installer, the framework is available, so check it for
1045 # 32-bit code.
1046 local old_framework_dir="${old_versioned_dir}/${FRAMEWORK_DIR}"
1047 test_binary="${old_framework_dir}/${FRAMEWORK_NAME}"
1048 else
1049 # No application code is guaranteed to be available at this point for a
1050 # patch updater, but goobspatch is built alongside and will have the
1051 # same bitness of the product that this updater will install, so it's a
1052 # reasonable proxy.
1053 test_binary="${patch_dir}/goobspatch"
1054 fi
1055 note "test_binary = ${test_binary}"
1056
1057 if ! file "${test_binary}" | grep -q 'i386$'; then
1058 err "can't install non-32-bit update on 32-bit-only system"
1059 mark_32_bit_only_system "${product_id}"
1060 exit 14
1061 else
1062 note "update will run on a 32-bit-only system"
1063 fi
1064 fi
1065
953 ensure_writable_symlinks_recursive "${installed_app}" 1066 ensure_writable_symlinks_recursive "${installed_app}"
954 1067
955 # By copying to ${installed_app}, the existing application name will be 1068 # By copying to ${installed_app}, the existing application name will be
956 # preserved, if the user has renamed the application on disk. Respecting 1069 # preserved, if the user has renamed the application on disk. Respecting
957 # the user's changes is friendly. 1070 # the user's changes is friendly.
958 1071
959 # Make sure that ${installed_versions_dir} exists, so that it can receive 1072 # Make sure that ${installed_versions_dir} exists, so that it can receive
960 # the versioned directory. It may not exist if updating from an older 1073 # the versioned directory. It may not exist if updating from an older
961 # version that did not use the versioned layout on disk. Later, during the 1074 # version that did not use the versioned layout on disk. Later, during the
962 # rsync to copy the application directory, the mode bits and timestamp on 1075 # rsync to copy the application directory, the mode bits and timestamp on
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 1663
1551 # Check "less than" instead of "not equal to" in case Keystone ever changes to 1664 # Check "less than" instead of "not equal to" in case Keystone ever changes to
1552 # pass more arguments. 1665 # pass more arguments.
1553 if [[ ${#} -lt 1 ]]; then 1666 if [[ ${#} -lt 1 ]]; then
1554 usage 1667 usage
1555 exit 2 1668 exit 2
1556 fi 1669 fi
1557 1670
1558 main "${@}" 1671 main "${@}"
1559 exit ${?} 1672 exit ${?}
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698