mirror of
https://github.com/munki/munki.git
synced 2026-05-03 02:40:32 -05:00
s/forced_(un)install/unattended_(un)install/g
s/only_forced/only_unattended/g Change forced_* pkginfo key names to more accurately describe what's happening, since they're not "forced" in the true sense of the word. Admins should include both forced_* and unattended_* keys in their pkginfos while migrating to client releases after this change, to ensure both old and new clients have desired pkg push agressiveness :( git-svn-id: http://munki.googlecode.com/svn/trunk@1098 a4e17f2e-e282-11dd-95e1-755cbddbdd66
This commit is contained in:
@@ -135,16 +135,16 @@ def initMunkiDirs():
|
||||
return True
|
||||
|
||||
|
||||
def doInstallTasks(only_forced=False):
|
||||
def doInstallTasks(only_unattended=False):
|
||||
"""Perform our installation/removal tasks.
|
||||
|
||||
Args:
|
||||
only_forced: Boolean. If True, only do forced installs/removals.
|
||||
only_unattended: Boolean. If True, only do unattended_(un)install items.
|
||||
|
||||
Returns:
|
||||
Boolean. True if a restart is required, False otherwise.
|
||||
"""
|
||||
if not only_forced:
|
||||
if not only_unattended:
|
||||
# first, clear the last notified date
|
||||
# so we can get notified of new changes after this round
|
||||
# of installs
|
||||
@@ -161,7 +161,7 @@ def doInstallTasks(only_forced=False):
|
||||
if munkiUpdatesAvailable():
|
||||
# install munki updates
|
||||
try:
|
||||
need_to_restart = installer.run(only_forced=only_forced)
|
||||
need_to_restart = installer.run(only_unattended=only_unattended)
|
||||
except:
|
||||
munkicommon.display_error(
|
||||
'Unexpected error in munkilib.installer:')
|
||||
@@ -171,11 +171,11 @@ def doInstallTasks(only_forced=False):
|
||||
|
||||
# clear any Apple update info since it may no longer
|
||||
# be relevant
|
||||
if not only_forced:
|
||||
if not only_unattended:
|
||||
appleupdates.clearAppleUpdateInfo()
|
||||
elif ((munkicommon.pref('InstallAppleSoftwareUpdates') or
|
||||
munkicommon.pref('AppleSoftwareUpdatesOnly'))
|
||||
and not only_forced):
|
||||
and not only_unattended):
|
||||
# are we supposed to handle Apple Software Updates?
|
||||
try:
|
||||
need_to_restart = appleupdates.installAppleUpdates()
|
||||
@@ -627,11 +627,11 @@ def main():
|
||||
munkicommon.log('Skipping auto install because system is '
|
||||
'not idle (keyboard or mouse activity).')
|
||||
else: # there are GUI users
|
||||
doInstallTasks(only_forced=True)
|
||||
doInstallTasks(only_unattended=True)
|
||||
# it's possible that we no longer have any available updates
|
||||
# so we need to check InstallInfo.plist again
|
||||
# however Apple Updates have not been affected by the forced
|
||||
# install tasks (so that check is still valid).
|
||||
# however Apple Updates have not been affected by the
|
||||
# unattended install tasks (so that check is still valid).
|
||||
if appleupdatesavailable or munkiUpdatesAvailable():
|
||||
consoleuser = munkicommon.getconsoleuser()
|
||||
if consoleuser == u'loginwindow':
|
||||
|
||||
@@ -621,8 +621,8 @@ def main():
|
||||
matchingpkginfo.get('installer_item_location')):
|
||||
options.subdirectory = os.path.dirname(
|
||||
matchingpkginfo['installer_item_location'])
|
||||
for key in ['forced_install',
|
||||
'forced_uninstall',
|
||||
for key in ['unattended_install',
|
||||
'unattended_uninstall',
|
||||
'requires',
|
||||
'update_for']:
|
||||
if key in matchingpkginfo:
|
||||
|
||||
@@ -463,7 +463,7 @@ def itemPrereqsInSkippedItems(item, skipped_items):
|
||||
munkicommon.display_debug1(
|
||||
'Checking for skipped prerequisites for %s-%s'
|
||||
% (item['name'], item.get('version_to_install')))
|
||||
|
||||
|
||||
# get list of prerequisites for this item
|
||||
prerequisites = item.get('requires', [])
|
||||
prerequisites.extend(item.get('update_for', []))
|
||||
@@ -473,7 +473,7 @@ def itemPrereqsInSkippedItems(item, skipped_items):
|
||||
% (item['name'], item.get('version_to_install')))
|
||||
return []
|
||||
munkicommon.display_debug1('Prerequisites: %s' % ", ".join(prerequisites))
|
||||
|
||||
|
||||
# build a dictionary of names and versions of skipped items
|
||||
skipped_item_dict = {}
|
||||
for skipped_item in skipped_items:
|
||||
@@ -484,7 +484,7 @@ def itemPrereqsInSkippedItems(item, skipped_items):
|
||||
munkicommon.display_debug1('Adding skipped item: %s-%s'
|
||||
% (skipped_item['name'], normalized_version))
|
||||
skipped_item_dict[skipped_item['name']].append(normalized_version)
|
||||
|
||||
|
||||
# now check prereqs against the skipped items
|
||||
matched_prereqs = []
|
||||
for prereq in prerequisites:
|
||||
@@ -501,7 +501,8 @@ def itemPrereqsInSkippedItems(item, skipped_items):
|
||||
return matched_prereqs
|
||||
|
||||
|
||||
def installWithInfo(dirpath, installlist, only_forced=False, applesus=False):
|
||||
def installWithInfo(
|
||||
dirpath, installlist, only_unattended=False, applesus=False):
|
||||
"""
|
||||
Uses the installlist to install items in the
|
||||
correct order.
|
||||
@@ -511,17 +512,17 @@ def installWithInfo(dirpath, installlist, only_forced=False, applesus=False):
|
||||
skipped_installs = []
|
||||
for item in installlist:
|
||||
itemindex = itemindex + 1
|
||||
if only_forced:
|
||||
if not item.get('forced_install'):
|
||||
if only_unattended:
|
||||
if not item.get('unattended_install'):
|
||||
skipped_installs.append(item)
|
||||
munkicommon.display_detail(
|
||||
('Skipping install of %s because it\'s not flagged for '
|
||||
'forced_install.') % item['name'])
|
||||
('Skipping install of %s because it\'s not unattended.'
|
||||
% item['name'])
|
||||
continue
|
||||
elif blockingApplicationsRunning(item):
|
||||
skipped_installs.append(item)
|
||||
munkicommon.display_detail(
|
||||
'Skipping forced/background install of %s because '
|
||||
'Skipping unattended install of %s because '
|
||||
'blocking application(s) running.'
|
||||
% item['name'])
|
||||
continue
|
||||
@@ -531,18 +532,18 @@ def installWithInfo(dirpath, installlist, only_forced=False, applesus=False):
|
||||
# need to skip this too
|
||||
skipped_installs.append(item)
|
||||
munkicommon.display_detail(
|
||||
'Skipping forced/background install of %s because these '
|
||||
'Skipping unattended install of %s because these '
|
||||
'prerequisites were skipped: %s'
|
||||
% (item['name'], ", ".join(skipped_prereqs)))
|
||||
continue
|
||||
|
||||
|
||||
if munkicommon.stopRequested():
|
||||
return restartflag, skipped_installs
|
||||
|
||||
|
||||
retcode = 0
|
||||
if 'preinstall_script' in item:
|
||||
retcode = runEmbeddedScript('preinstall_script', item)
|
||||
|
||||
|
||||
if retcode == 0 and 'installer_item' in item:
|
||||
display_name = item.get('display_name') or item.get('name')
|
||||
version_to_install = item.get('version_to_install','')
|
||||
@@ -563,7 +564,7 @@ def installWithInfo(dirpath, installlist, only_forced=False, applesus=False):
|
||||
munkicommon.display_error("Installer item %s was not found." %
|
||||
item["installer_item"])
|
||||
return restartflag, skipped_installs
|
||||
|
||||
|
||||
installer_type = item.get("installer_type","")
|
||||
if installer_type.startswith("Adobe"):
|
||||
retcode = adobeutils.doAdobeInstall(item)
|
||||
@@ -654,7 +655,7 @@ def installWithInfo(dirpath, installlist, only_forced=False, applesus=False):
|
||||
suppressBundleRelocation)
|
||||
if needtorestart:
|
||||
restartflag = True
|
||||
|
||||
|
||||
if retcode == 0 and 'postinstall_script' in item:
|
||||
# only run embedded postinstall script if the install did not
|
||||
# return a failure code
|
||||
@@ -760,7 +761,7 @@ def writefile(stringdata, path):
|
||||
def runEmbeddedScript(scriptname, pkginfo_item):
|
||||
'''Runs a script embedded in the pkginfo.
|
||||
Returns the result code.'''
|
||||
|
||||
|
||||
# get the script text from the pkginfo
|
||||
script_text = pkginfo_item.get(scriptname)
|
||||
itemname = pkginfo_item.get('name')
|
||||
@@ -768,7 +769,7 @@ def runEmbeddedScript(scriptname, pkginfo_item):
|
||||
munkicommon.display_error(
|
||||
'Missing script %s for %s' % (scriptname, itemname))
|
||||
return -1
|
||||
|
||||
|
||||
# write the script to a temp file
|
||||
scriptpath = os.path.join(munkicommon.tmpdir, scriptname)
|
||||
if writefile(script_text, scriptpath):
|
||||
@@ -776,18 +777,18 @@ def runEmbeddedScript(scriptname, pkginfo_item):
|
||||
retcode = subprocess.call(cmd)
|
||||
if retcode:
|
||||
munkicommon.display_error(
|
||||
'Error setting script mode in %s for %s'
|
||||
'Error setting script mode in %s for %s'
|
||||
% (scriptname, itemname))
|
||||
return -1
|
||||
else:
|
||||
munkicommon.display_error(
|
||||
'Cannot write script %s for %s' % (scriptname, itemname))
|
||||
return -1
|
||||
|
||||
|
||||
# now run the script
|
||||
return runScript(itemname, scriptpath, scriptname)
|
||||
|
||||
|
||||
|
||||
|
||||
def runScript(itemname, path, scriptname):
|
||||
'''Runs a script, Returns return code.'''
|
||||
if munkicommon.munkistatusoutput:
|
||||
@@ -835,14 +836,14 @@ def skippedItemsThatRequireThisItem(item, skipped_items):
|
||||
the current item. Returns a list of matches.'''
|
||||
munkicommon.display_debug1(
|
||||
'Checking for skipped items that require %s' % item['name'])
|
||||
|
||||
|
||||
matched_skipped_items = []
|
||||
for skipped_item in skipped_items:
|
||||
# get list of prerequisites for this skipped_item
|
||||
prerequisites = skipped_item.get('requires', [])
|
||||
prerequisites.extend(skipped_item.get('update_for', []))
|
||||
munkicommon.display_debug1(
|
||||
'%s has these prerequisites: %s'
|
||||
'%s has these prerequisites: %s'
|
||||
% (skipped_item['name'], ', '.join(prerequisites)))
|
||||
for prereq in prerequisites:
|
||||
(prereq_name, unused_version) = updatecheck.nameAndVersion(prereq)
|
||||
@@ -851,23 +852,23 @@ def skippedItemsThatRequireThisItem(item, skipped_items):
|
||||
return matched_skipped_items
|
||||
|
||||
|
||||
def processRemovals(removallist, only_forced=False):
|
||||
def processRemovals(removallist, only_unattended=False):
|
||||
'''processes removals from the removal list'''
|
||||
restartFlag = False
|
||||
index = 0
|
||||
skipped_removals = []
|
||||
for item in removallist:
|
||||
if only_forced:
|
||||
if not item.get('forced_uninstall'):
|
||||
if only_unattended:
|
||||
if not item.get('unattended_uninstall'):
|
||||
skipped_removals.append(item)
|
||||
munkicommon.display_detail(
|
||||
('Skipping removal of %s because it\'s not flagged for '
|
||||
'forced_uninstall') % item['name'])
|
||||
('Skipping removal of %s because it\'s not unattended.'
|
||||
% item['name'])
|
||||
continue
|
||||
elif blockingApplicationsRunning(item):
|
||||
skipped_removals.append(item)
|
||||
munkicommon.display_detail(
|
||||
'Skipping forced/background removal of %s because '
|
||||
'Skipping unattended removal of %s because '
|
||||
'blocking application(s) running.' % item['name'])
|
||||
continue
|
||||
dependent_skipped_items = skippedItemsThatRequireThisItem(
|
||||
@@ -876,11 +877,11 @@ def processRemovals(removallist, only_forced=False):
|
||||
# need to skip this too
|
||||
skipped_removals.append(item)
|
||||
munkicommon.display_detail(
|
||||
'Skipping forced/background removal of %s because these '
|
||||
'Skipping unattended removal of %s because these '
|
||||
'skipped items required it: %s'
|
||||
% (item['name'], ", ".join(dependent_skipped_items)))
|
||||
continue
|
||||
|
||||
|
||||
if munkicommon.stopRequested():
|
||||
return restartFlag
|
||||
if not item.get('installed'):
|
||||
@@ -1028,19 +1029,19 @@ def blockingApplicationsRunning(pkginfoitem):
|
||||
return False
|
||||
|
||||
|
||||
def run(only_forced=False):
|
||||
def run(only_unattended=False):
|
||||
"""Runs the install/removal session.
|
||||
|
||||
Args:
|
||||
only_forced: Boolean. If True, only do forced installs/removals.
|
||||
only_unattended: Boolean. If True, only do unattended_(un)install pkgs.
|
||||
"""
|
||||
managedinstallbase = munkicommon.pref('ManagedInstallDir')
|
||||
installdir = os.path.join(managedinstallbase , 'Cache')
|
||||
|
||||
removals_need_restart = installs_need_restart = False
|
||||
|
||||
if only_forced:
|
||||
munkicommon.log("### Beginning forced installer session ###")
|
||||
if only_unattended:
|
||||
munkicommon.log("### Beginning unattended installer session ###")
|
||||
else:
|
||||
munkicommon.log("### Beginning managed installer session ###")
|
||||
|
||||
@@ -1081,8 +1082,8 @@ def run(only_forced=False):
|
||||
munkistatus.percent(-1)
|
||||
munkicommon.log("Processing removals")
|
||||
(removals_need_restart,
|
||||
skipped_removals) = processRemovals(removallist,
|
||||
only_forced=only_forced)
|
||||
skipped_removals) = processRemovals(
|
||||
removallist, only_unattended=only_unattended)
|
||||
# if any removals were skipped, record them for later
|
||||
installinfo['removals'] = skipped_removals
|
||||
|
||||
@@ -1105,13 +1106,14 @@ def run(only_forced=False):
|
||||
munkistatus.percent(-1)
|
||||
munkicommon.log("Processing installs")
|
||||
(installs_need_restart,
|
||||
skipped_installs) = installWithInfo(installdir,
|
||||
installlist,
|
||||
only_forced=only_forced)
|
||||
skipped_installs) = installWithInfo(
|
||||
installdir,
|
||||
installlist,
|
||||
only_unattended=only_unattended)
|
||||
# if any installs were skipped record them for later
|
||||
installinfo['managed_installs'] = skipped_installs
|
||||
|
||||
if (only_forced and
|
||||
if (only_unattended and
|
||||
installinfo['managed_installs'] or installinfo['removals']):
|
||||
# need to write the installinfo back out minus the stuff we
|
||||
# actually installed
|
||||
@@ -1123,11 +1125,11 @@ def run(only_forced=False):
|
||||
"Could not write to %s" % installinfopath)
|
||||
|
||||
else:
|
||||
if not only_forced: # no need to log that no forced found.
|
||||
if not only_unattended: # no need to log that no unattended pkgs found.
|
||||
munkicommon.log("No %s found." % installinfo)
|
||||
|
||||
if only_forced:
|
||||
munkicommon.log("### End forced installer session ###")
|
||||
if only_unattended:
|
||||
munkicommon.log("### End unattended installer session ###")
|
||||
else:
|
||||
munkicommon.log("### End managed installer session ###")
|
||||
|
||||
|
||||
@@ -647,7 +647,7 @@ class CurlDownloadError(MunkiDownloadError):
|
||||
class PackageVerificationError(MunkiDownloadError):
|
||||
"""Download failed because it could not be verified"""
|
||||
pass
|
||||
|
||||
|
||||
class FileCopyError(MunkiDownloadError):
|
||||
"""Download failed because of file copy errors."""
|
||||
pass
|
||||
@@ -679,7 +679,7 @@ def download_installeritem(item_pl, installinfo, uninstalling=False):
|
||||
if not downloadbaseurl.endswith('/'):
|
||||
downloadbaseurl = downloadbaseurl + '/'
|
||||
pkgurl = downloadbaseurl + urllib2.quote(location)
|
||||
|
||||
|
||||
pkgname = getInstallerItemBasename(location)
|
||||
munkicommon.display_debug2('Download base URL is: %s' % downloadbaseurl)
|
||||
munkicommon.display_debug2('Package name is: %s' % pkgname)
|
||||
@@ -1509,16 +1509,16 @@ def processInstall(manifestitem, cataloglist, installinfo):
|
||||
iteminfo['version_to_install'] = item_pl.get(
|
||||
'version','UNKNOWN')
|
||||
|
||||
# we will ignore the forced_install key
|
||||
# if the item needs a restart or logout...
|
||||
if item_pl.get('forced_install'):
|
||||
# we will ignore the unattended_install key if the item needs a
|
||||
# restart or logout...
|
||||
if item_pl.get('unattended_install'):
|
||||
if item_pl.get('RestartAction'):
|
||||
munkicommon.display_warning(
|
||||
'Ignoring forced_install key for %s '
|
||||
'Ignoring unattended_install key for %s '
|
||||
'because RestartAction is %s.'
|
||||
% (item_pl['name'], item_pl.get('RestartAction')))
|
||||
else:
|
||||
iteminfo['forced_install'] = True
|
||||
iteminfo['unattended_install'] = True
|
||||
|
||||
# optional keys
|
||||
optional_keys = ['suppress_bundle_relocation',
|
||||
@@ -1841,17 +1841,17 @@ def processRemoval(manifestitem, cataloglist, installinfo):
|
||||
iteminfo['display_name'] = uninstall_item.get('display_name', '')
|
||||
iteminfo['description'] = 'Will be removed.'
|
||||
|
||||
# we will ignore the forced_install and forced_uninstall key if
|
||||
# the item needs a restart or logout...
|
||||
if uninstall_item.get('forced_uninstall'):
|
||||
# we will ignore the unattended_uninstall key if the item needs a restart
|
||||
# or logout...
|
||||
if uninstall_item.get('unattended_uninstall'):
|
||||
if uninstall_item.get('RestartAction'):
|
||||
munkicommon.display_warning(
|
||||
'Ignoring forced_uninstall key for %s '
|
||||
'Ignoring unattended_uninstall key for %s '
|
||||
'because RestartAction is %s.'
|
||||
% (uninstall_item['name'],
|
||||
uninstall_item.get('RestartAction')))
|
||||
else:
|
||||
iteminfo['forced_uninstall'] = True
|
||||
iteminfo['unattended_uninstall'] = True
|
||||
|
||||
# some keys we'll copy if they exist
|
||||
optionalKeys = ['blocking_applications',
|
||||
@@ -2507,7 +2507,7 @@ def getResourceIfChangedAtomically(url, destinationpath,
|
||||
message=None, resume=False):
|
||||
"""Gets file from a URL, checking first to see if it has changed on the
|
||||
server.
|
||||
|
||||
|
||||
Supported schemes are http, https, file.
|
||||
|
||||
Returns True if a new download was required; False if the
|
||||
@@ -2573,7 +2573,7 @@ def getFileIfChangedAtomically(path, destinationpath):
|
||||
shutil.copy2(path, tmp_destinationpath)
|
||||
except IOError, e:
|
||||
raise FileCopyError('Copy IOError: %s' % str(e))
|
||||
|
||||
|
||||
# rename temp destination to final destination
|
||||
try:
|
||||
os.rename(tmp_destinationpath, destinationpath)
|
||||
@@ -2803,7 +2803,7 @@ def check(client_id='', localmanifestpath=None):
|
||||
'managed_installs')
|
||||
available_optional_installs = [item['name']
|
||||
for item in installinfo.get('optional_installs',[])]
|
||||
# filter the list, removing any items not in the current list
|
||||
# filter the list, removing any items not in the current list
|
||||
# of available self-serve installs
|
||||
selfserveinstalls = [item for item in selfserveinstalls
|
||||
if item in available_optional_installs]
|
||||
@@ -2835,7 +2835,7 @@ def check(client_id='', localmanifestpath=None):
|
||||
for item in installinfo['managed_installs']
|
||||
if item.get('installed') == False and
|
||||
not item.get('installer_item')]
|
||||
# filter removals to get items already removed
|
||||
# filter removals to get items already removed
|
||||
# (or never installed)
|
||||
removed_items = [item.get('name','')
|
||||
for item in installinfo['removals']
|
||||
@@ -2885,7 +2885,7 @@ def check(client_id='', localmanifestpath=None):
|
||||
# record the filtered lists
|
||||
munkicommon.report['ItemsToInstall'] = installinfo['managed_installs']
|
||||
munkicommon.report['ItemsToRemove'] = installinfo['removals']
|
||||
|
||||
|
||||
# clean up catalogs directory
|
||||
cleanUpCatalogs()
|
||||
|
||||
@@ -2917,7 +2917,7 @@ def check(client_id='', localmanifestpath=None):
|
||||
# that need to be installed but are missing
|
||||
# the installer_item; these might be partial
|
||||
# downloads. So if we have no problem items, it's
|
||||
# OK to get rid of any partial downloads hanging
|
||||
# OK to get rid of any partial downloads hanging
|
||||
# around.
|
||||
os.unlink(os.path.join(cachedir, item))
|
||||
elif item not in cache_list:
|
||||
|
||||
Reference in New Issue
Block a user