def RepairClient(): """Downloads and installs a new Simian client. Raises: RepairClientError: there was an error repairing this client. """ url = GetServerURL() logging.info('Fetching repair client from: %s/repair', url) # TODO(user): figure out a way to not specify filename, then add a version # check so if the downloaded client is the same version that is running the # repair will just abort. download_path = os.path.join( tempfile.mkdtemp(prefix='munki_repair_dmg_', dir='/tmp'), 'munkiclient.dmg') mount_path = tempfile.mkdtemp(prefix='munki_repair_client_', dir='/tmp') try: updatecheck.getResourceIfChangedAtomically('%s/repair' % url, download_path) except fetch.MunkiDownloadError as e: raise RepairClientError( u'MunkiDownloadError getting Munki client: %s' % e) return_code, unused_stdout, stderr = Exec([ '/usr/bin/hdiutil', 'attach', '-mountpoint', mount_path, '-nobrowse', '-readonly', download_path ]) logging.info('Mounted munki repair client dmg at %s.', mount_path) if return_code != 0: raise RepairClientError( 'Failed to attach repair client dmg with ret %s. ' 'Error: %s' % (return_code, stderr)) if not os.path.isdir(mount_path): raise RepairClientError('Mount path not found:' % mount_path) file_list = os.listdir(mount_path) for file_name in file_list: if re.match(r'^(munkitools.*|simian.*)\.pkg$', file_name): installer_file = os.path.join(mount_path, file_name) cmd = ['/usr/sbin/installer', '-pkg', installer_file, '-target', '/'] logging.info('Trying to install repair client with %s.', ' '.join(cmd)) return_code, unused_stdout, stderr = Exec(cmd) if return_code != 0: raise RepairClientError( 'Failed to install pkg with ret %s. Error: %s' % (return_code, stderr)) return_code, unused_stdout, unused_stderr = Exec( ['/usr/bin/hdiutil', 'detach', mount_path, '-force']) if return_code != 0: logging.warning('Could not detach %s!', mount_path) # If we've just repaired, kill any hung managedsofwareupdate instances, as # that may be the main reason we needed to repair in the first place. KillHungManagedSoftwareUpdate()
def RepairClient(): """Downloads and installs a new Simian client. Raises: RepairClientError: there was an error repairing this client. """ url = GetServerURL() logging.info('Fetching repair client from: %s/repair', url) # TODO(user): figure out a way to not specify filename, then add a version # check so if the downloaded client is the same version that is running the # repair will just abort. download_path = os.path.join( tempfile.mkdtemp(prefix='munki_repair_dmg_', dir='/tmp'), 'munkiclient.dmg') mount_path = tempfile.mkdtemp(prefix='munki_repair_client_', dir='/tmp') try: updatecheck.getResourceIfChangedAtomically('%s/repair' % url, download_path) except fetch.MunkiDownloadError as e: raise RepairClientError( u'MunkiDownloadError getting Munki client: %s' % e) return_code, unused_stdout, stderr = Exec( ['/usr/bin/hdiutil', 'attach', '-mountpoint', mount_path, '-nobrowse', '-readonly', download_path]) logging.info('Mounted munki repair client dmg at %s.', mount_path) if return_code != 0: raise RepairClientError('Failed to attach repair client dmg with ret %s. ' 'Error: %s' % (return_code, stderr)) if not os.path.isdir(mount_path): raise RepairClientError('Mount path not found:' % mount_path) file_list = os.listdir(mount_path) for file_name in file_list: if re.match(r'^(munkitools.*|simian.*)\.pkg$', file_name): installer_file = os.path.join(mount_path, file_name) cmd = ['/usr/sbin/installer', '-pkg', installer_file, '-target', '/'] logging.info('Trying to install repair client with %s.', ' '.join(cmd)) return_code, unused_stdout, stderr = Exec(cmd) if return_code != 0: raise RepairClientError( 'Failed to install pkg with ret %s. Error: %s' % (return_code, stderr)) return_code, unused_stdout, unused_stderr = Exec( ['/usr/bin/hdiutil', 'detach', mount_path, '-force']) if return_code != 0: logging.warning('Could not detach %s!', mount_path) # If we've just repaired, kill any hung managedsofwareupdate instances, as # that may be the main reason we needed to repair in the first place. KillHungManagedSoftwareUpdate()
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: updatecheck.getResourceIfChangedAtomically( '%s/applesus/' % url, APPLE_SUS_CATALOG) # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST) except (fetch.MunkiDownloadError, fpl.NSPropertyListSerializationException): logging.exception('MunkiDownloadError getting Apple SUS catalog.')
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: updatecheck.getResourceIfChangedAtomically('%s/applesus/' % url, APPLE_SUS_CATALOG) # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST) except (fetch.MunkiDownloadError, fpl.NSPropertyListSerializationException): logging.exception('MunkiDownloadError getting Apple SUS catalog.')
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: new = updatecheck.getResourceIfChangedAtomically( '%s/applesus/' % url, APPLE_SUS_CATALOG) except fetch.MunkiDownloadError: logging.exception('MunkiDownloadError getting Apple SUS catalog.') return if new: # SUS catalog changed, clear last check date to run softwareupdate soon. munkicommon.set_pref('LastAppleSoftwareUpdateCheck', None) try: sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) except fpl.NSPropertyListSerializationException: # plist may not exist, but will be created when softwareupdate is run, then # the next execution of of this code will set the CatalogURL. logging.exception('Failed to read Apple SoftwareUpdate plist.') return # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST)
def GetAppleSUSCatalog(): """Fetches an Apple Software Update Service catalog from the server.""" url = GetServerURL() try: new = updatecheck.getResourceIfChangedAtomically( '%s/applesus/' % url, APPLE_SUS_CATALOG) except fetch.MunkiDownloadError as e: logging.exception(u'MunkiDownloadError getting Apple SUS catalog: %s', e) return if new: # SUS catalog changed, clear last check date to run softwareupdate soon. munkicommon.set_pref('LastAppleSoftwareUpdateCheck', None) try: sus_catalog = fpl.readPlist(APPLE_SUS_PLIST) except fpl.NSPropertyListSerializationException: # plist may not exist, but will be created when softwareupdate is run, then # the next execution of of this code will set the CatalogURL. logging.exception('Failed to read Apple SoftwareUpdate plist.') return # Update the CatalogURL setting in com.apple.SoftwareUpdate.plist. sus_catalog['CatalogURL'] = urlparse.urljoin( 'file://localhost/', urllib.quote(APPLE_SUS_CATALOG)) fpl.writePlist(sus_catalog, APPLE_SUS_PLIST)
def RepairClient(): """Downloads and installs a new Simian client. Raises: RepairClientError: there was an error repairing this client. """ url = GetServerURL() # TODO(user): figure out a way to not specify filename, then add a version # check so if the downloaded client is the same version that is running the # repair will just abort. download = '/tmp/munkiclient.dmg' try: logging.info('Fetching repair client from: %s/repair', url) updatecheck.getResourceIfChangedAtomically('%s/repair' % url, download) except fetch.MunkiDownloadError, e: raise RepairClientError( 'MunkiDownloadError getting Munki client: %s' % str(e))
def RepairClient(): """Downloads and installs a new Simian client. Raises: RepairClientError: there was an error repairing this client. """ url = GetServerURL() # TODO(user): figure out a way to not specify filename, then add a version # check so if the downloaded client is the same version that is running the # repair will just abort. download = '/tmp/munkiclient.dmg' try: logging.info('Fetching repair client from: %s/repair', url) updatecheck.getResourceIfChangedAtomically('%s/repair' % url, download) except fetch.MunkiDownloadError, e: raise RepairClientError('MunkiDownloadError getting Munki client: %s' % str(e))
def RepairClient(): """Downloads and installs a new Simian client. Raises: RepairClientError: there was an error repairing this client. """ url = GetServerURL() logging.info('Fetching repair client from: %s/repair', url) # TODO(user): figure out a way to not specify filename, then add a version # check so if the downloaded client is the same version that is running the # repair will just abort. download_path = os.path.join( tempfile.mkdtemp(prefix='munki_repair_dmg_', dir='/tmp'), 'munkiclient.dmg') mount_path = tempfile.mkdtemp(prefix='munki_repair_client_', dir='/tmp') try: updatecheck.getResourceIfChangedAtomically('%s/repair' % url, download_path) except fetch.MunkiDownloadError, e: raise RepairClientError( 'MunkiDownloadError getting Munki client: %s' % str(e))