Chromium Code Reviews| 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 |