diff options
Diffstat (limited to 'chrome/tools')
-rw-r--r-- | chrome/tools/build/mac/FILES-official | 1 | ||||
-rwxr-xr-x | chrome/tools/build/mac/keystone_install.sh | 97 | ||||
-rwxr-xr-x | chrome/tools/build/mac/keystone_install_test.sh | 100 | ||||
-rwxr-xr-x | chrome/tools/build/mac/make_sign_sh | 28 | ||||
-rw-r--r-- | chrome/tools/build/mac/sign.sh.in | 45 |
5 files changed, 271 insertions, 0 deletions
diff --git a/chrome/tools/build/mac/FILES-official b/chrome/tools/build/mac/FILES-official index fd80032..2d3802c6 100644 --- a/chrome/tools/build/mac/FILES-official +++ b/chrome/tools/build/mac/FILES-official @@ -1 +1,2 @@ Google Chrome.app +Google Chrome Packaging diff --git a/chrome/tools/build/mac/keystone_install.sh b/chrome/tools/build/mac/keystone_install.sh new file mode 100755 index 0000000..173875a --- /dev/null +++ b/chrome/tools/build/mac/keystone_install.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Called by the Keystone system to update the installed application with a new +# version from a disk image. + +# Return values: +# 0 Happiness +# 1 Unknown failure +# 2 Basic sanity check destination failure (e.g. ticket points to nothing) +# 3 Cannot get version of currently installed Chrome +# 4 No permission to write in destination directory +# 5 rsync failed +# 6 Cannot get version or update URL of newly installed Chrome +# 7 Post-install Chrome has same version as pre-install Chrome +# 8 ksadmin failure +# 10 Basic sanity check source failure (e.g. no app on disk image) + +set -e + +# The argument should be the disk image path. Make sure it exists. +if [ $# -lt 1 ] || [ ! -d "${1}" ]; then + exit 10 +fi + +# Who we are. +APP_NAME="Google Chrome.app" +SRC="${1}/${APP_NAME}" + +# Sanity, make sure that there's something to copy from. +if [ ! -d "${SRC}" ]; then + exit 10 +fi + +# Figure out where we're going. +PRODUCT_ID=$(defaults read "${SRC}/Contents/Info" KSProductID || exit 3) +DEST=$(ksadmin -pP "${PRODUCT_ID}" | grep xc= | sed -E 's/.+path=(.+)>$/\1/g') + +# More sanity checking. +if [ -z "${SRC}" ] || [ -z "${DEST}" ] || [ ! -d $(dirname "${DEST}") ]; then + exit 2 +fi + +# Read old version to help confirm install happiness +OLD_VERSION=$(defaults read "${DEST}/Contents/Info" KSVersion || exit 3) + +# Make sure we have permission to write the destination +DEST_DIRECTORY=$(dirname "${DEST}") +if [ ! -w "${DEST_DIRECTORY}" ]; then + exit 4 +fi + +# This usage will preserve any changes the user made to the application name. +# TODO(jrg): this may choke a running Chrome.app; be smarter. +# Note: If the rsync fails we do not update the ticket version. +rsync -a --delete "${SRC}/" "${DEST}/" || exit 5 + +# Read the new values (e.g. version) +VERSION=$(defaults read "${DEST}/Contents/Info" KSVersion || exit 6) +URL=$(defaults read "${DEST}/Contents/Info" KSUpdateURL || exit 6) +# The channel ID is optional. Suppress stderr to prevent Keystone from seeing +# possible error output. +CHANNEL_ID=$(defaults read "${DEST}/Contents/Info" KSChannelID 2>/dev/null || \ + true) + +# Compare old and new versions. If they are equal we failed somewhere. +if [ "${OLD_VERSION}" = "${VERSION}" ]; then + exit 7 +fi + +# Notify LaunchServices. +/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister "${DEST}" + +# Notify Keystone. Older versions of Keystone don't recognize --tag. If the +# command with --tag fails, retry without it. In that case, Chrome will set +# the tag when it runs. +# TODO: The version of Keystone picking up --tag will also include support for +# --ksdamin-version. At that point, we can check to see if ksadmin honors the +# version check; if not, no --tag, if yes, do a case...esac on the version +# patterns for any support checks we need. +ksadmin --register \ + -P "${PRODUCT_ID}" \ + --version "${VERSION}" \ + --xcpath "${DEST}" \ + --url "${URL}" \ + --tag "${CHANNEL_ID}" || \ + ksadmin --register \ + -P "${PRODUCT_ID}" \ + --version "${VERSION}" \ + --xcpath "${DEST}" \ + --url "${URL}" || exit 8 + +# Great success! +exit 0 diff --git a/chrome/tools/build/mac/keystone_install_test.sh b/chrome/tools/build/mac/keystone_install_test.sh new file mode 100755 index 0000000..b72a9d4 --- /dev/null +++ b/chrome/tools/build/mac/keystone_install_test.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Test of the Mac Chrome installer. + + +# Where I am +DIR=$(dirname "${0}") + +# My installer to test +INSTALLER="${DIR}"/keystone_install.sh +if [ ! -f "${INSTALLER}" ]; then + echo "Can't find scripts." >& 2 + exit 1 +fi + +# What I test +APPNAME="Google Chrome.app" + +# Temp directory to be used as the disk image (source) +TEMPDIR=$(mktemp -d ${TMPDIR}/$(basename ${0}).XXXXXX) +PATH=$PATH:"${TEMPDIR}" + +# Clean up the temp directory +function cleanup_tempdir() { + chmod u+w "${TEMPDIR}" + rm -rf "${TEMPDIR}" +} + +# Run the installer and make sure it fails. +# If it succeeds, we fail. +# Arg0: string to print +function fail_installer() { + echo $1 + "${INSTALLER}" "${TEMPDIR}" >/dev/null 2>&1 + RETURN=$? + if [ $RETURN -eq 0 ]; then + echo "Did not fail (which is a failure)" >& 2 + cleanup_tempdir + exit 1 + else + echo "Returns $RETURN" + fi +} + +# Make sure installer works! +# Arg0: string to print +function pass_installer() { + echo $1 + "${INSTALLER}" "${TEMPDIR}" >/dev/null 2>&1 + RETURN=$? + if [ $RETURN -ne 0 ]; then + echo "FAILED; returned $RETURN but should have worked" >& 2 + cleanup_tempdir + exit 1 + else + echo "worked" + fi +} + +# Most of the setup for an install source and dest +function make_basic_src_and_dest() { + chmod ugo+w "${TEMPDIR}" + rm -rf "${TEMPDIR}" + mkdir -p "${TEMPDIR}/${APPNAME}/Contents" + defaults write "${TEMPDIR}/${APPNAME}/Contents/Info" \ + KSProductID "com.google.Chrome" + defaults write "${TEMPDIR}/${APPNAME}/Contents/Info" KSVersion 1 + DEST="${TEMPDIR}"/Dest.app + mkdir -p "${DEST}"/Contents + defaults write "${DEST}/Contents/Info" KSVersion 0 + cat >"${TEMPDIR}"/ksadmin <<EOF +#!/bin/sh +echo "echo xc=<blah path=$DEST>" +exit 0 +EOF + chmod u+x "${TEMPDIR}"/ksadmin +} + +fail_installer "No source anything" + +mkdir "${TEMPDIR}"/"${APPNAME}" +fail_installer "No source bundle" + +make_basic_src_and_dest +chmod ugo-w "${TEMPDIR}" +fail_installer "Writable dest directory" + +make_basic_src_and_dest +fail_installer "Was no KSUpdateURL in dest after copy" + +make_basic_src_and_dest +defaults write "${TEMPDIR}/${APPNAME}/Contents/Info" \ + KSUpdateURL "http://foo.bar" +pass_installer "ALL" + +cleanup_tempdir diff --git a/chrome/tools/build/mac/make_sign_sh b/chrome/tools/build/mac/make_sign_sh new file mode 100755 index 0000000..115882c --- /dev/null +++ b/chrome/tools/build/mac/make_sign_sh @@ -0,0 +1,28 @@ +#!/bin/sh + +# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This script creates sign.sh, the script that will be used to sign the +# application bundle and inner bundles. sign.sh is placed in the Packaging +# directory next to the .app bundle. The packaging system is expected to run +# sign.sh to sign everything. + +set -e + +if [ $# -ne 2 ] ; then + echo "usage: ${0} PACKAGING_DIR MAC_PRODUCT_NAME" >& 2 + exit 1 +fi + +PACKAGING_DIR="${1}" +MAC_PRODUCT_NAME="${2}" +SIGN_SH_IN_FILE="$(dirname "${0}")/sign.sh.in" +SIGN_SH_FILE="${PACKAGING_DIR}/sign.sh" + +mkdir -p "${PACKAGING_DIR}" +sed -e "s/@MAC_PRODUCT_NAME@/${MAC_PRODUCT_NAME}/g" \ + < "${SIGN_SH_IN_FILE}" \ + > "${SIGN_SH_FILE}" +chmod a+rx "${SIGN_SH_FILE}" diff --git a/chrome/tools/build/mac/sign.sh.in b/chrome/tools/build/mac/sign.sh.in new file mode 100644 index 0000000..41c8b58 --- /dev/null +++ b/chrome/tools/build/mac/sign.sh.in @@ -0,0 +1,45 @@ +#!/bin/sh + +# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Using codesign, sign the application. Inner components are signed as needed, +# then the outermost bundle is signed, and everything is verified. + +set -e + +if [ $# -ne 3 ] ; then + echo "usage: ${0} APP_PATH CODESIGN_KEYCHAIN CODESIGN_ID" >& 2 + exit 1 +fi + +APP_PATH="${1}" +CODESIGN_KEYCHAIN="${2}" +CODESIGN_ID="${3}" + +# An .app bundle to be signed can be signed directly. Signging a framework +# bundle requires that each version within be signed individually. +# http://developer.apple.com/mac/library/technotes/tn2007/tn2206.html#TNTAG13 + +BROWSER_APP="${APP_PATH}" +FRAMEWORK="${BROWSER_APP}/Contents/Frameworks/@MAC_PRODUCT_NAME@ Framework.framework/Versions/A" +HELPER_APP="${BROWSER_APP}/Contents/Resources/@MAC_PRODUCT_NAME@ Helper.app" + +echo "${0}: signing..." + +# Sign the outer .app last so that its seal includes the signed inner +# components. + +codesign -s "${CODESIGN_ID}" --keychain "${CODESIGN_KEYCHAIN}" "${FRAMEWORK}" +codesign -s "${CODESIGN_ID}" --keychain "${CODESIGN_KEYCHAIN}" "${HELPER_APP}" +codesign -s "${CODESIGN_ID}" --keychain "${CODESIGN_KEYCHAIN}" "${BROWSER_APP}" + +# Verify everything to ensure that signing the outer bundle didn't break an +# inner bundle. + +echo "${0}: verifying..." + +codesign -v "${FRAMEWORK}" +codesign -v "${HELPER_APP}" +codesign -v "${BROWSER_APP}" |