Skip to main content
Jamf Nation, hosted by Jamf, is the largest Apple IT management community in the world. Dialog with your fellow IT professionals, gain insight about Apple device deployments, share best practices and bounce ideas off each other. Join the conversation.

Packaging Google Chrome breaks auto-updates

Hi Everyone,

I've recently packaged Google Chrome as a .pkg, and it deploys and works perfectly except that the automatic updates seem to fail. When I go to Chrome -> About Google Chrome , I get the "Updating Google Chrome" message for a moment then "Update failed (error: 12)". Following Google's instructions for resolving this error produces no results. The only thing that seems to fix it is a clean download and install off the .dmg direct from Google. Has anyone else experienced this before?

Thanks,

-Mike

Like Comment
Order by:
SOLVED Posted: 8/11/15 at 3:11 PM by mpermann

What are the permissions on the Google Chrome.app that you packaged?

Like
SOLVED Posted: 8/11/15 at 3:21 PM by michaelherrick

Actually, I got frustrated using Composer so I used pkgbuild following these instructions:

https://wiki.afp548.com/index.php/Guidelines_for_Mac_software_packaging#Google_Chrome

Like
SOLVED Posted: 8/11/15 at 3:33 PM by alexjdale

I see that same error with pkgbuild and Chrome, for what it's worth. I wasn't able to figure it out, even with permissions modifications after installing.

Like
SOLVED Posted: 8/11/15 at 6:13 PM by rtrouton

I'm going to put in an obligatory plug for AutoPkg, as it can handle building a working Chrome installer package for you:

http://autopkg.github.io/autopkg/

Other approaches for packaging drag-and-drop applications like Chrome include using Packages:

https://derflounder.wordpress.com/2014/05/02/building-simple-packages-with-packages/

I've also built a tool for creating installer packages from drag-and-drop applications:

https://github.com/rtrouton/Simple-Package-Creator

Like
SOLVED Posted: 8/13/15 at 8:52 AM by bvrooman

I fixed an issue with Chrome not updating by deploying a package along with the app that contains:

/Library/Google/Google Chrome Brand.plist
/Library/Google/GoogleSoftwareUpdate/*
/Library/LaunchAgents/com.google.keystone.agent.plist
/Library/LaunchDaemons/com.google.keystone.daemon.plist

I honestly don't recall what error I was seeing, but it may be worth making sure those files exist on your test machine when you try to update.

Like
SOLVED Posted: 8/13/15 at 10:16 AM by RobertHammen

@rtrouton I'm even seeing the same thing with packages built with AutoPkg, so... #ymmv

Like
SOLVED Posted: 8/14/15 at 8:15 PM by aporlebeke

I just did Normal Snapshot with Composer before installing Chrome, install Chrome, configure settings and set auto-update, set bookmarks, etc. and then take after snapshot. Worked like a charm.

Alternatively, I also tried installing Chrome, configure the settings, auto update, etc. and using the preinstalled software option in Composer and that worked as well.

My 2 cents ...

Like
SOLVED Posted: 8/14/15 at 9:13 PM by gregneagle

Depending on your POV disabling autoupdates for Chrome might be considered a feature and not a bug.

But what's happening here is that when a pkg installs Chrome it's being written to the /Applications folder with root as the owner of the application bundle. When a normal (non-root) user runs the app, they don't have the rights to modify it.

There are ways to install the Google Updater as root also so it can update Chrome if you want to, but I'd think you'd want your software management system (Casper) to manage your software and its updates...

Like
SOLVED Posted: 12/16/15 at 2:56 PM by nkalister

from the chrome installer script, I believe this is what Greg was referring to . . .

FixChromePerms () {
    if [ -e "/Applications/Google Chrome.app" ]; then
        chgrp -Rh admin /Applications/Google\ Chrome.app
        chmod -R "a+rX,ug+w,o-w" /Applications/Google\ Chrome.app
        find /Applications/Google\ Chrome.app -type l -exec chmod -h "a+rX,ug+w,o-w" {} +
        OS_VERSION=$(sw_vers -productVersion)
        OS_MAJOR=$(sed -Ene 's/^([0-9]+).*/\1/p' <<< ${OS_VERSION})
        OS_MINOR=$(sed -Ene 's/^([0-9]+)\.([0-9]+).*/\2/p' <<< ${OS_VERSION})
        QUARANTINE_ATTR=com.apple.quarantine
        if [ ${OS_MAJOR} -gt 10 ] ||
           ([ ${OS_MAJOR} -eq 10 ] && [ ${OS_MINOR} -ge 6 ]) ; then
          # On 10.6, xattr supports -r for recursive operation.
          xattr -d -r "${QUARANTINE_ATTR}" "${DEST}" >& /dev/null
        else
          # On earlier systems, xattr doesn't support -r, so run xattr via find.
          find "${DEST}" -exec xattr -d "${QUARANTINE_ATTR}" {} + >& /dev/null
        fi
    fi
}
Like
SOLVED Posted: 12/18/15 at 9:49 AM by Chris_Hafner

Here's +1 for @rtrouton posted methods. For what it's worth, I use composer and distribute as a .dmg.

Like
SOLVED Posted: 3/8/16 at 4:03 PM by milesleacy

Hey all,

I used autopkg to create my initial Chrome installer package. I have since used @hjuutilainen 's script to enable Chrome to automatically update.

After running the script, Chrome stopped offering to "set up updates for all users", and was able to successfully run an update check for a time.

Today, I encountered Chrome offering to "set up updates for all users" again. When I loaded the About page in Chrome, it was unable to check for updates, returning error 12. After trying the permissions fix @nkalister quoted above, the update check proceeded, but then returned error 11.

After clicking the button to "set up updates for all users" and authenticating, Chrome was able to update.

So, the question is, what happens when you let Chrome "set up updates for all users"? I captured changes during the process and I'm slogging through the list of changes. I'm wondering if anyone listening has already discovered the answer.

Like
SOLVED Posted: 3/16/16 at 12:04 PM by donmontalvo

+1 to @milesleacy's position.

Chrome has an embedded copy of Flash, and as everyone knows, Flash is updated every time you sneeze.

So disabling automatic updates to Flash might sound like a good idea.

But the truth is, when your company has it's next security audit and they (hopefully) raise a flag, you're going some 'splaining to do, Lucy.

Diaper policy...enable Chrome updates and keep it enabled. If your company/client tells you to disable, teach them why that's a terrible idea (and not recommended or supported by Google).

Don

Like
SOLVED Posted: 3/16/16 at 10:57 PM by milesleacy

@donmontalvo I have Chrome automatically updating.

Adobe Flash Installer is a restricted software item - kill, delete, message "Flash Player is a security and performance risk. If you need to view Flash content, you may use Google Chrome."

Like
SOLVED Posted: 3/17/16 at 1:35 PM by Chris_Hafner

@milesleacy What an interesting concept. Something tells me that I won't be able to pull that one off but...

Like
SOLVED Posted: 4/14/16 at 11:00 AM by Jeff-JAMF

See Ben Toms latest MacMule post on Google Chrome v50 - some significant OS version requirement changes

GOOGLE CHROME 50 OS REQUIREMENT CHANGES

Like
SOLVED Posted: 6/22/16 at 10:44 AM by mbezzo

Looks like there still isn't a solid answer for this? I've got a "normal" package (just places the chrome .app in /Applications) that we push out and it fails to update with error 12. I've ran both of the scripts mentioned here - the first doesn't change anything and hjuutilainen's makes the errors go away, but now chrome reports as being up to date but it isn't. (My package is a few months old so is installing version 45). Any ideas? Testing on 10.11.5 currently, so it's not the v50 OS requirements.

Thanks!

p.s. Anybody found anything like Joe Farage's FirefoxInstall.sh? LOVE that - no packaging, always get the latest version. :)

Like
SOLVED Posted: 6/22/16 at 10:50 AM by aporlebeke

@mbezzo We ran into this issue, but only when for when we initially packaged Chrome and User preferences into a DMG and set the file to Fill User Templates.

We're getting our 10.11.5 image ready and I've been able to deploy the latest version of Chrome (just the app) to /Applications and then run a one-time startup Python script to enable Auto Updates for all users without issue.

I can't seem to find where I acquired the script originally, but I've included it below.

#!/usr/bin/python
# encoding: utf-8
"""
chrome-enable-autoupdates.py

This script enables system wide automatic updates for Google Chrome.
It should work for Chrome versions 18 and later. No configuration needed
as this is originally intended as a munki postinstall script.

Created by Hannes Juutilainen, hjuutilainen@mac.com

History:

2015-09-25, Niklas Blomdalen - Modifications to include old KeystoneRegistration installation (python version) 2014-11-20, Hannes Juutilainen - Modifications for Chrome 39 2012-08-31, Hannes Juutilainen - Added --force flag to keystoneInstall as suggested by Riley Shott 2012-05-29, Hannes Juutilainen - Added more error checking 2012-05-25, Hannes Juutilainen - Added some error checking in main 2012-05-24, Hannes Juutilainen - First version """ import sys import os import getopt import subprocess import plistlib chromePath = "/Applications/Google Chrome.app" infoPlistPath = os.path.realpath(os.path.join(chromePath, 'Contents/Info.plist')) brandPath = "/Library/Google/Google Chrome Brand.plist" brandKey = "KSBrandID" tagPath = infoPlistPath tagKey = "KSChannelID" versionPath = infoPlistPath versionKey = "KSVersion" class Usage(Exception): def __init__(self, msg): self.msg = msg def chromeIsInstalled(): """Check if Chrome is installed""" if os.path.exists(chromePath): return True else: return False def chromeVersion(): """Returns Chrome version""" infoPlist = plistlib.readPlist(infoPlistPath) bundleShortVersion = infoPlist["CFBundleShortVersionString"] return bundleShortVersion def chromeKSUpdateURL(): """Returns KSUpdateURL from Chrome Info.plist""" infoPlist = plistlib.readPlist(infoPlistPath) KSUpdateURL = infoPlist["KSUpdateURL"] return KSUpdateURL def chromeKSProductID(): """Returns KSProductID from Chrome Info.plist""" infoPlist = plistlib.readPlist(infoPlistPath) KSProductID = infoPlist["KSProductID"] return KSProductID def keystoneRegistrationFrameworkPath(): """Returns KeystoneRegistration.framework path""" keystoneRegistration = os.path.join(chromePath, 'Contents/Versions') keystoneRegistration = os.path.join(keystoneRegistration, chromeVersion()) keystoneRegistration = os.path.join(keystoneRegistration, 'Google Chrome Framework.framework') keystoneRegistration = os.path.join(keystoneRegistration, 'Frameworks/KeystoneRegistration.framework') return keystoneRegistration def keystoneInstall(): """Install the current Keystone""" installScript = os.path.join(keystoneRegistrationFrameworkPath(), 'Resources/ksinstall') if not os.path.exists(installScript): installScript = os.path.join(keystoneRegistrationFrameworkPath(), 'Resources/install.py') keystonePayload = os.path.join(keystoneRegistrationFrameworkPath(), 'Resources/Keystone.tbz') if os.path.exists(installScript) and os.path.exists(keystonePayload): retcode = subprocess.call([installScript, '--install', keystonePayload, '--force']) if retcode == 0: return True else: return False else: print >> sys.stderr, "Error: KeystoneRegistration.framework not found" return False def removeChromeFromKeystone(): """Removes Chrome from Keystone""" ksadmin = "/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksadmin" ksadminProcess = [ ksadmin, '--delete', '--productid', chromeKSProductID()] retcode = subprocess.call(ksadminProcess) if retcode == 0: return True else: return False def registerChromeWithKeystone(): """Registers Chrome with Keystone""" ksadmin = "/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksadmin" if os.path.exists(ksadmin): ksadminProcess = [ksadmin, '--register', '--preserve-tttoken', '--productid', chromeKSProductID(), '--version', chromeVersion(), '--xcpath', chromePath, '--url', chromeKSUpdateURL(), '--tag-path', tagPath, '--tag-key', tagKey, '--brand-path', brandPath, '--brand-key', brandKey, '--version-path', versionPath, '--version-key', versionKey] retcode = subprocess.call(ksadminProcess) if retcode == 0: return True else: return False else: print >> sys.stderr, "Error: %s doesn't exist" % ksadmin return False def main(argv=None): if argv is None: argv = sys.argv try: # Check for root if os.geteuid() != 0: print >> sys.stderr, "This script must be run as root" return 1 if not chromeIsInstalled(): print >> sys.stderr, "Error: Chrome is not installed on this computer" return 1 if keystoneInstall(): print "Keystone installed" else: print >> sys.stderr, "Error: Keystone install failed" return 1 if registerChromeWithKeystone(): print "Registered Chrome with Keystone" return 0 else: print >> sys.stderr, "Error: Failed to register Chrome with Keystone" return 1 except Usage, err: print >>sys.stderr, err.msg print >>sys.stderr, "for help use --help" return 2 if __name__ == "__main__": sys.exit(main())
Like
SOLVED Posted: 6/22/16 at 11:01 AM by mbezzo

Thanks @aporlebeke That's the script I'm using where I'm seeing the "Chrome is up to date" when it isn't. So, it fixed one issue but presents another! This is such a pain to test too, because if I create a new package, or say use autopkg, the newly packaged version is completely updated, so can't actually test to see if it does properly update! :)

Thanks,
Matt

Like