Add support for product icon downloads from Munki server

This commit is contained in:
Greg Neagle
2014-03-24 10:21:42 -07:00
parent 7562688f59
commit d343ede672
4 changed files with 87 additions and 8 deletions
@@ -354,19 +354,31 @@ class GenericItem(dict):
def getIcon(self):
'''Return name/relative path of image file to use for the icon'''
# first look for downloaded icons
icon_name = self.get('icon_name') or self['name']
if not os.path.splitext(icon_name)[1]:
icon_name += '.png'
icon_path = os.path.join(msulib.html_dir(), 'icons', icon_name)
if os.path.exists(icon_path):
return 'icons/' + icon_name
# didn't find one in the downloaded icons
# so create one if needed from a locally installed app
for key in ['icon_name', 'display_name', 'name']:
if key in self:
name = self[key]
icon_path = os.path.join(msulib.html_dir(), name + '.png')
icon_name = name
if not os.path.splitext(icon_name)[1]:
icon_name += '.png'
icon_path = os.path.join(msulib.html_dir(), icon_name)
if os.path.exists(icon_path) or msulib.convertIconToPNG(name, icon_path, 350):
return name + '.png'
return icon_name
else:
# use the Generic package icon
return 'static/Generic.png'
def unavailable_reason_text(self):
'''There are several reasons an item might be unavailable for install.
Return the relevent reason'''
Return the relevent reason'''
if ('licensed_seats_available' in self
and not self['licensed_seats_available']):
return NSLocalizedString(u'No licenses available',
@@ -247,6 +247,11 @@ def html_dir():
source_path = os.path.join(resourcesPath, 'WebResources')
link_path = os.path.join(_html_dir, 'static')
os.symlink(source_path, link_path)
# symlink the Managed Installs icons dir
managed_install_dir = munki.pref('ManagedInstallDir')
source_path = os.path.join(managed_install_dir, 'icons')
link_path = os.path.join(_html_dir, 'icons')
os.symlink(source_path, link_path)
return _html_dir
+2 -1
View File
@@ -139,11 +139,12 @@ def initMunkiDirs():
ManagedInstallDir = munkicommon.pref('ManagedInstallDir')
manifestsdir = os.path.join(ManagedInstallDir, 'manifests')
catalogsdir = os.path.join(ManagedInstallDir, 'catalogs')
iconsdir = os.path.join(ManagedInstallDir, 'icons')
cachedir = os.path.join(ManagedInstallDir, 'Cache')
logdir = os.path.join(ManagedInstallDir, 'Logs')
if not createDirsIfNeeded([ManagedInstallDir, manifestsdir, catalogsdir,
cachedir, logdir]):
iconsdir, cachedir, logdir]):
munkicommon.display_error('Could not create needed directories '
'in %s' % ManagedInstallDir)
return False
+65 -4
View File
@@ -2481,6 +2481,7 @@ class ManifestException(Exception):
manifest."""
pass
MANIFESTS = {}
def getmanifest(partialurl, suppress_errors=False):
"""Gets a manifest from the server.
@@ -2489,10 +2490,10 @@ def getmanifest(partialurl, suppress_errors=False):
string local path to the downloaded manifest.
"""
#global MANIFESTS
manifestbaseurl = munkicommon.pref('ManifestURL') or \
munkicommon.pref('SoftwareRepoURL') + '/manifests/'
if not manifestbaseurl.endswith('?') and \
not manifestbaseurl.endswith('/'):
manifestbaseurl = (munkicommon.pref('ManifestURL') or
munkicommon.pref('SoftwareRepoURL') + '/manifests/')
if (not manifestbaseurl.endswith('?') and
not manifestbaseurl.endswith('/')):
manifestbaseurl = manifestbaseurl + '/'
manifest_dir = os.path.join(munkicommon.pref('ManagedInstallDir'),
'manifests')
@@ -2708,6 +2709,59 @@ def getDownloadCachePath(destinationpathprefix, url):
destinationpathprefix, getInstallerItemBasename(url))
def download_icons(item_list):
'''Attempts to download icons (actually png files) for items in
item_list'''
icon_list = []
icon_base_url = (munkicommon.pref('IconURL') or
munkicommon.pref('SoftwareRepoURL') + '/icons/')
icon_base_url = icon_base_url.rstrip('/') + '/'
icon_dir = os.path.join(munkicommon.pref('ManagedInstallDir'), 'icons')
munkicommon.display_debug2('Icon base URL is: %s', icon_base_url)
for item in item_list:
icon_name = item.get('icon_name') or item['name']
if not os.path.splitext(icon_name)[1]:
icon_name += '.png'
icon_list.append(icon_name)
icon_url = icon_base_url + urllib2.quote(icon_name)
icon_path = os.path.join(icon_dir, icon_name)
icon_subdir = os.path.dirname(icon_path)
if not os.path.exists(icon_subdir):
try:
os.makedirs(icon_subdir, 0755)
except OSError, err:
munkicommon.display_error(
'Could not create %s' % icon_subdir)
continue
munkicommon.display_detail('Getting icon %s...', icon_name)
item_name = item.get('display_name') or item['name']
message = 'Getting icon for %s...' % item_name
try:
unused_value = getResourceIfChangedAtomically(
icon_url, icon_path, message=message)
except fetch.MunkiDownloadError, err:
munkicommon.display_warning(
'Could not retrieve icon %s from the server: %s',
icon_name, err)
# remove no-longer needed icons from the local directory
for (dirpath, dirnames, filenames) in os.walk(icon_dir, topdown=False):
for filename in filenames:
icon_path = os.path.join(dirpath, filename)
rel_path = icon_path[len(icon_dir):].lstrip('/')
if rel_path not in icon_list:
try:
os.unlink(icon_path)
except (IOError, OSError), err:
pass
if len(munkicommon.listdir(dirpath)) == 0:
# did we empty out this directory (or is it already empty)?
# if so, remove it
try:
os.rmdir(dirpath)
except (IOError, OSError), err:
pass
MACHINE = {}
CONDITIONS = {}
def check(client_id='', localmanifestpath=None):
@@ -2921,6 +2975,13 @@ def check(client_id='', localmanifestpath=None):
[item for item in installinfo['removals']
if item.get('installed')]
# download display icons for optional installs
# and active installs/removals
item_list = list(installinfo.get('optional_installs', []))
item_list.extend(installinfo['managed_installs'])
item_list.extend(installinfo['removals'])
download_icons(item_list)
# record the filtered lists
munkicommon.report['ItemsToInstall'] = installinfo['managed_installs']
munkicommon.report['ItemsToRemove'] = installinfo['removals']