Exemple #1
0
def GenerateAppleSUSCatalog(
    os_version, track, datetime_=datetime.datetime, catalog_lock=None):
  """Generates an Apple SUS catalog for a given os_version and track.

  This function loads the untouched/raw Apple SUS catalog, removes any
  products/updates that are not approved for the given track, then saves
  a new catalog (plist/xml) to Datastore for client consumption.

  Args:
    os_version: str OS version to generate the catalog for.
    track: str track name to generate the catalog for.
    datetime_: datetime module; only used for stub during testing.
    catalog_lock: datastore_lock.DatastoreLock; If provided, the lock to release
                  upon completion of the operation.
  Returns:
    tuple, new models.AppleSUSCatalog object and plist.ApplePlist object. Or,
    if there is no "untouched" catalog for the os_version, then (None, None) is
    returned.
  """
  logging.info('Generating catalog: %s_%s', os_version, track)

  catalog_key = '%s_untouched' % os_version
  untouched_catalog_obj = models.AppleSUSCatalog.get_by_key_name(catalog_key)
  if not untouched_catalog_obj:
    logging.warning('Apple Update catalog does not exist: %s', catalog_key)
    if catalog_lock:
      catalog_lock.Release()
    return None, None
  untouched_catalog_plist = plist.ApplePlist(untouched_catalog_obj.plist)
  untouched_catalog_plist.Parse()

  approved_product_ids = set()
  products_query = models.AppleSUSProduct.AllActive().filter('tracks =', track)
  for product in products_query:
    approved_product_ids.add(product.product_id)

  product_ids = untouched_catalog_plist.get('Products', {}).keys()
  new_plist = untouched_catalog_plist
  for product_id in product_ids:
    if product_id not in approved_product_ids:
      del new_plist['Products'][product_id]

  catalog_plist_xml = new_plist.GetXml()

  # Save the catalog using a time-specific key for rollback purposes.
  now = datetime_.utcnow()
  now_str = now.strftime('%Y-%m-%d-%H-%M-%S')
  backup = models.AppleSUSCatalog(
      key_name='backup_%s_%s_%s' % (os_version, track, now_str))
  backup.plist = catalog_plist_xml
  backup.put()
  # Overwrite the catalog being served for this os_version/track pair.
  c = models.AppleSUSCatalog(key_name='%s_%s' % (os_version, track))
  c.plist = catalog_plist_xml
  c.put()

  if catalog_lock:
    catalog_lock.Release()

  return c, new_plist
Exemple #2
0
    def testProcessCatalogAndNotifyAdmins(self, generate_catalog_mock,
                                          log_mock, deprecate_products_mock,
                                          notify_mock):
        """Tests _ProcessCatalogAndNotifyAdmins()."""
        os_version = '10.7'
        mock_catalog = models.AppleSUSCatalog(plist='<plist></plist>')

        new_products = ['new1', 'new2']
        deprecated_products = ['old1', 'old2']

        deprecate_products_mock.return_value = deprecated_products

        with mock.patch.object(applesus.AppleSUSCatalogSync,
                               '_UpdateProductDataFromCatalog',
                               return_value=new_products):
            with mock.patch.object(applesus.plist, 'ApplePlist',
                                   autospec=True):
                self.catalog_sync._ProcessCatalogAndNotifyAdmins(
                    mock_catalog, os_version)

        generate_catalog_mock.assert_called_once_with(os_version,
                                                      applesus.common.UNSTABLE)

        notify_mock.assert_called_once_with(mock_catalog, new_products,
                                            deprecated_products)

        log_mock.assert_has_calls([
            mock.call(new_products, 'new for %s' % os_version),
            mock.call(deprecated_products, 'deprecated for %s' % os_version),
        ])
Exemple #3
0
def GenerateAppleSUSCatalog(os_version, track, _datetime=datetime.datetime):
    """Generates an Apple SUS catalog for a given os_version and track.

  This function loads the untouched/raw Apple SUS catalog, removes any
  products/updates that are not approved for the given track, then saves
  a new catalog (plist/xml) to Datastore for client consumption.

  Args:
    os_version: str OS version to generate the catalog for.
    track: str track name to generate the catalog for.
    _datetime: datetime module; only used for stub during testing.
  Returns:
    tuple, new models.AppleSUSCatalog object and plist.ApplePlist object.
  """
    logging.info('Generating catalog: %s_%s', os_version, track)
    approved_product_ids = {}
    products_query = models.AppleSUSProduct.all().filter('tracks =', track)
    for product in products_query:
        approved_product_ids[product.product_id] = True

    untouched_catalog_obj = models.AppleSUSCatalog.get_by_key_name(
        '%s_untouched' % os_version)
    untouched_catalog_plist = plist.ApplePlist(untouched_catalog_obj.plist)
    untouched_catalog_plist.Parse()

    product_ids = untouched_catalog_plist.get('Products', {}).keys()
    new_plist = untouched_catalog_plist
    for product_id in product_ids:
        if product_id not in approved_product_ids:
            del new_plist['Products'][product_id]

    catalog_plist_xml = new_plist.GetXml()

    # Save the catalog using a time-specific key for rollback purposes.
    now = _datetime.utcnow()
    now_str = now.strftime('%Y-%m-%d-%H-%M-%S')
    backup = models.AppleSUSCatalog(key_name='backup_%s_%s_%s' %
                                    (os_version, track, now_str))
    backup.plist = catalog_plist_xml
    backup.put()
    # Overwrite the catalog being served for this os_version/track pair.
    c = models.AppleSUSCatalog(key_name='%s_%s' % (os_version, track))
    c.plist = catalog_plist_xml
    c.put()
    return c, new_plist
Exemple #4
0
  def testSupplyClientIdAndTokenInUrl(self):
    testapp = webtest.TestApp(gae_app)

    plist = 'PLIST'
    models.AppleSUSCatalog(key_name='10.11_stable', plist=plist).put()

    headers = {
        applesus.MUNKI_CLIENT_ID_HEADER_KEY: 'track=stable|os_version=10.11'}

    ss = models.AuthSession(uuid='34')
    with mock.patch.object(gaeserver, 'DoMunkiAuth', return_value=ss):
      resp = testapp.post(
          '/applesus/', status=httplib.OK,
          headers=headers)
    resp = testapp.get('/applesus/%s' % resp.body, status=httplib.OK)
    self.assertEqual(plist, resp.body)