Posted on 08-11-2015 01:09 PM
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
Posted on 08-11-2015 01:11 PM
What are the permissions on the Google Chrome.app that you packaged?
Posted on 08-11-2015 01:21 PM
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
Posted on 08-11-2015 01:33 PM
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.
Posted on 08-11-2015 04:13 PM
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:
Posted on 08-13-2015 06:52 AM
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.
Posted on 08-13-2015 08:16 AM
@rtrouton I'm even seeing the same thing with packages built with AutoPkg, so... #ymmv
Posted on 08-14-2015 06:15 PM
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 ...
Posted on 08-14-2015 07:13 PM
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...
Posted on 12-16-2015 12:56 PM
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
}
Posted on 12-18-2015 07:49 AM
Here's +1 for @rtrouton posted methods. For what it's worth, I use composer and distribute as a .dmg.
Posted on 03-08-2016 02:03 PM
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.
Posted on 03-16-2016 10:04 AM
+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
Posted on 03-16-2016 08:57 PM
@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."
Posted on 03-17-2016 11:35 AM
@milesleacy What an interesting concept. Something tells me that I won't be able to pull that one off but...
Posted on 04-14-2016 09:00 AM
See Ben Toms latest MacMule post on Google Chrome v50 - some significant OS version requirement changes
Posted on 06-22-2016 08:44 AM
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. :)
Posted on 06-22-2016 08:50 AM
@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())
Posted on 06-22-2016 09:01 AM
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