Example #1
0
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()
Example #2
0
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()
Example #3
0
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.')
Example #4
0
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.')
Example #5
0
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)
Example #6
0
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)
Example #7
0
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))
Example #8
0
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))
Example #9
0
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))
Example #10
0
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))