#6857 Get the update-critpath script ready to talk to PDC.
Merged 6 years ago by mohanboddu. Opened 6 years ago by ralph.
ralph/releng update-critpath-pdc  into  master

@@ -13,7 +13,7 @@ 

  Description

  ===========

  

- Packagedb has information about which packages are critpath and which are not.

+ PDC has information about which packages are critpath and which are not.

  A script that reads the yum repodata (critpath group in comps, and the package

  dependencies) is used to generate this.  Since package dependencies change,

  this list should be updated periodically.
@@ -48,16 +48,16 @@ 

  

          ./critpath.py --srpm -o critpath.txt branched

  

- #. Run the update script to add that to the pkgdb:

+ #. Run the update script to add that to PDC:

  

     ::

  

          ./update-critpath --user toshio f18 critpath.txt

  

     The username is your fas username.  You must be in cvsadmin to be able to

-    change this.  The release is given in pkgdb format (f17, f18, devel, etc).

+    change this.  The branch is the name of the dist-git branch.

     critpath.txt is the file that the output of critpath.py went into.  The

-    script will prompt for your FAS password to verify your identity with the

-    pkgdb.

+    script needs a PDC token to talk to the server, configured in /etc/pdc.d/.

+    See the PDC SOP for more info.

  

  .. _releng git repository: https://pagure.io/releng

file modified
+96 -102
@@ -1,15 +1,12 @@ 

  # -*- coding: utf-8 -*-

- 

- """

- # update_critpath - a commandline frontend for updating the critpath

- #

+ # vi: ft=python

  # Copyright (C) 2014 Red Hat Inc

  # Copyright (C) 2014 Pierre-Yves Chibon, Chaoyi Zha, Toshio Kuratomi,

  #                    Bill Nottingham

  # Authors: Pierre-Yves Chibon <pingou@pingoured.fr>

-            Chaoyi Zha <summermontreal@gmail.com>

-            Bill Nottingham <notting@fedoraproject.org>

-            Toshio Kuratomi <toshio@fedoraproject.org>

+ #          Chaoyi Zha <summermontreal@gmail.com>

+ #          Bill Nottingham <notting@fedoraproject.org>

+ #          Toshio Kuratomi <toshio@fedoraproject.org>

  #

  # This program is free software; you can redistribute it and/or modify

  # it under the terms of the GNU General Public License as published by
@@ -17,68 +14,50 @@ 

  # your option) any later version.

  # See http://www.gnu.org/copyleft/gpl.html  for the full text of the

  # license.

- #

- # Critpath updating SOP:

- # http://fedoraproject.org/wiki/Update_Critpath_SOP

- #

- # How to use:

- #  $ python update-critpath <critpath.txt> <branch>

- # for example

- #  $ python update-critpath critpath.txt f20

- #

+ """ update_critpath - a commandline frontend for updating the critpath

+ 

+ Critpath updating SOP: https://docs.pagure.org/releng/sop_update_critpath.html

+ 

+ How to use:

+  $ python update-critpath <critpath.txt> <branch>

+ for example

+  $ python update-critpath critpath.txt f20

  """

  

- from pkgdb2client import PkgDB, PkgDBException

- import pkgdb2client

  import argparse

+ import json

  import logging

+ import sys

+ 

+ import pdc_client

+ import dogpile.cache

+ 

  

+ # Here, 'fedora' is the name of the production instance, configured in

+ # /etc/pdc.d/.  See the PDC SOP for more information on authenticating.

+ pdc = pdc_client.PDCClient('fedora')

  

- pkgdbclient = PkgDB('https://admin.fedoraproject.org/pkgdb',

-                     login_callback=pkgdb2client.ask_password)

+ # This is an on-disk cache to avoid hitting PDC over and over.

+ cache_filename = "/var/tmp/pdc-branch-cache.dbm"

+ def key_generator(ns, fn, **kw):

+     return lambda **kwargs: "%r_%r|%r" % (ns, fn.__name__, json.dumps(kwargs))

+ cache = dogpile.cache.make_region(function_key_generator=key_generator)

  

  # Initial simple logging stuff

  logging.basicConfig()

- PKGDBLOG = logging.getLogger("pkgdb2client")

  LOG = logging.getLogger("update_critpath")

  

  

- def _get_active_branch(packagename=None):

-     ''' Return a list of the active branch for a specific package or simply

-     all the active branches if no package is specified.

-     '''

-     LOG.debug("Retrieving all the active branches")

-     branches = []

-     if packagename:

-         output = pkgdbclient.get_package(packagename)

-         for pkg in output['packages']:

-             if pkg['collection']['status'] != 'EOL':

-                 branches.append(pkg['collection']['branchname'])

-     else:

-         output = pkgdbclient.get_collections(

-             clt_status=['Active', 'Under Development'])

-         for collect in output['collections']:

-             if collect['status'] == 'EOL':

-                 continue

-             branches.append(collect['branchname'])

-     return branches

- 

- 

  def setup_parser():

      '''

      Set up argparse

      '''

      parser = argparse.ArgumentParser(prog="update_critpath")

      # General connection options

-     parser.add_argument('--user', dest="username",

-                         help="FAS username")

-     parser.add_argument('--password', dest="password",

-                         help="FAS password (if not provided, will be asked "

-                         "later)")

      parser.add_argument('--debug', action='store_true',

                          help="Outputs bunches of debugging info")

      parser.add_argument('--test', action='store_true',

-                         help="Uses a test instance instead of the real pkgdb.")

+                         help="Uses the stg instance instead of the real pdc.")

  

      parser.add_argument(

          'branch', default='master',
@@ -90,61 +69,72 @@ 

      return parser

  

  

- def list_critpath(branches):

-     ''' Return the list of packages flagged as critpatch in the specified

-     branches.

+ def list_critpath(branch):

+     ''' Return the set of packages flagged as critpatch in the specified

+     branch.

  

-     :arg branches: one or more branches used to restrict the list of packages

-         returned.

-     :type branches: str or list

-     :return: a list of package names

-     :rtype: list

+     :arg branch: branch used to restrict the list of packages returned.

+     :type branch: str

+     :return: a set of package names with PDC branch IDs

+     :rtype: set

      '''

-     if isinstance(branches, basestring):

-         branches = [branches]

+     if not isinstance(branch, basestring):

+         raise TypeError('branch *must* be a string')

  

-     args = {

-         'branches': branches,

-         'format': 'json',

-     }

-     output = pkgdbclient.handle_api_call('/critpath', params=args)

+     LOG.debug("Retrieving existing critpath list from PDC.")

+     args = { 'name': branch, 'type': 'rpm', 'critical_path': True }

+     results = pdc.get_paged(pdc['component-branches'], **args)

  

      pkgs = set()

-     if output:

-         for branch in branches:

-             if branch in output['pkgs']:

-                 pkgs.update(output['pkgs'][branch])

+     for result in results:

+         pkgs.add("{id}:{global_component}".format(**result))

+     LOG.debug("Done retrieving existing critpath list from PDC.")

+     return pkgs

+ 

+ 

+ def prepend_pdc_branch_ids(global_components, branch):

+     LOG.debug("Finding PDC branch IDs for supplied critpath list."

+               "  (See cache in %s)" % cache_filename)

+     pkgs = set()

+     endpoint = pdc['component-branches']

  

+     @cache.cache_on_arguments()

+     def _get_pdc_branch_id(**args):

+         results = list(pdc.get_paged(endpoint, **args))

+         assert len(results) == 1

+         return results[0]

+ 

+     for i, component in enumerate(global_components):

+         args = {'name': branch, 'type': 'rpm', 'global_component': component}

+         result = _get_pdc_branch_id(**args)

+ 

+         pkgs.add("{id}:{global_component}".format(**result))

+     LOG.debug("Done finding PDC branch IDs for supplied critpath list.")

      return pkgs

  

  

  def update_critpath(current_critpath, new_critpath, branch):

-     ''' Change critpath status of packages in PkgDB

+     ''' Change critpath status of packages in PDC

  

      :arg current_critpath: a set listing all the packages that currently have

          the critpath package

      '''

-     # Remove the critpath flag to the package that should not have it

  

+     # Remove the critpath flag from packages which do not have it, but should.

      new_no = current_critpath - new_critpath

-     if new_no:

-         try:

-             pkgdbclient.update_critpath(new_no, branch, False)

-         except PkgDBException, err:

-             LOG.debug('PkgDBException')

-             print '{0}'.format(err)

-     else:

-         print 'No packages to which the critpath flag should be removed'

+     LOG.debug('%i packages need critpath removed.' % len(new_no))

+     for item in new_no:

+         idx, name = item.split(':', 1)

+         LOG.debug('  Sending PATCH for %s, (idx: %s)' % (name, idx))

+         pdc['component-branches'][idx + '/'] += dict(critical_path=False)

  

+     # Add the critpath flag to packages which should have it, but do not.

      new_yes = new_critpath - current_critpath

-     if new_yes:

-         try:

-             pkgdbclient.update_critpath(new_yes, branch, True)

-         except PkgDBException, err:

-             LOG.debug('PkgDBException')

-             print '{0}'.format(err)

-     else:

-         print 'No packages to which the critpath flag should be added'

+     LOG.debug('%i packages need critpath added.' % len(new_yes))

+     for item in new_yes:

+         idx, name = item.split(':', 1)

+         LOG.debug('  Sending PATCH for %s, (idx: %s)' % (name, idx))

+         pdc['component-branches'][idx + '/'] += dict(critical_path=True)

  

  

  def main():
@@ -160,41 +150,45 @@ 

  

      if arg.debug:

          LOG.setLevel(logging.DEBUG)

-         PKGDBLOG.setLevel(logging.DEBUG)

  

      if arg.test:

-         global pkgdbclient

-         print "Testing environment"

-         pkgdbclient = PkgDB(

-             'https://admin.stg.fedoraproject.org/pkgdb',

-             login_callback=pkgdb2client.ask_password,

-             insecure=True)

+         global pdc

+         LOG.info("Using staging environment")

+         pdc = pdc_client.PDCClient('staging')

  

-     return_code = 0

  

-     if arg.password:

-         pkgdbclient.password = arg.password

-     if arg.username:

-         pkgdbclient.username = arg.username

+     LOG.debug("Using pdc branch cache %r" % cache_filename)

+     cache.configure(

+         "dogpile.cache.dbm",

+         expiration_time=-1,  # Never!!

+         arguments={"filename": cache_filename}

+     )

+ 

+     return_code = 0

  

-     current_critpath = list_critpath(arg.branch)

      new_critpath = []

+     LOG.debug("Reading supplied %r" % arg.txtlist)

      with open(arg.txtlist) as f:

          for line in f.readlines():

              new_critpath.append(line.strip())

  

+     # At this point, the new_critpath list contains only package names.  We

+     # need to enrich that with the IDs of the branch mappings from PDC

+     new_critpath = prepend_pdc_branch_ids(new_critpath, arg.branch)

+ 

+     current_critpath = list_critpath(arg.branch)

+ 

      try:

          update_critpath(set(current_critpath), set(new_critpath), arg.branch)

      except KeyboardInterrupt:

-         print "\nInterrupted by user."

+         LOG.info("\nInterrupted by user.")

          return_code = 1

      except Exception, err:

-         print 'Error: {0}'.format(err)

-         logging.exception("Generic error catched:")

+         LOG.exception("Caught generic error")

          return_code = 2

  

      return return_code

  

  

  if __name__ == '__main__':

-     main()

+     sys.exit(main())

Arbitrary branching pieces are falling into place now.

Can I get a reviewer on this one?

This should be just a single branch, not one or more.

1 new commit added

  • Fix docstring typo.
6 years ago

Pull-Request has been merged by mohanboddu

6 years ago