OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 ${?} |
OLD | NEW |