| |
@@ -3,7 +3,6 @@
|
| |
# SPDX-License-Identifier: GPL-2.0+
|
| |
|
| |
import argparse
|
| |
- import datetime
|
| |
import getpass
|
| |
import logging
|
| |
import subprocess
|
| |
@@ -11,6 +10,7 @@
|
| |
|
| |
import koji
|
| |
import pkgdb2client
|
| |
+ import requests
|
| |
|
| |
|
| |
log = logging.getLogger(__name__)
|
| |
@@ -20,9 +20,13 @@
|
| |
PRODUCTION_PKGDB = "https://admin.fedoraproject.org/pkgdb"
|
| |
STAGING_PKGDB = "https://admin.stg.fedoraproject.org/pkgdb"
|
| |
|
| |
+ PRODUCTION_PDC = "https://pdc.fedoraproject.org"
|
| |
+ STAGING_PDC = "https://pdc.stg.fedoraproject.org"
|
| |
+
|
| |
# pkgdb default namespace
|
| |
DEFAULT_NS = "rpms"
|
| |
|
| |
+
|
| |
class SubjectSMTPHandler(logging.handlers.SMTPHandler):
|
| |
|
| |
subject_prefix = ""
|
| |
@@ -34,7 +38,6 @@
|
| |
return fmt.format(record, first_line=first_line)
|
| |
|
| |
|
| |
-
|
| |
class ReleaseMapper(object):
|
| |
BRANCHNAME = 0
|
| |
KOJI_TAG = 1
|
| |
@@ -124,54 +127,55 @@
|
| |
return unblocked
|
| |
|
| |
|
| |
- def get_retired_packages(branch="master", staging=False, namespace=DEFAULT_NS):
|
| |
- url = PRODUCTION_PKGDB if not staging else STAGING_PKGDB
|
| |
- pkgdb = pkgdb2client.PkgDB(url)
|
| |
-
|
| |
- try:
|
| |
- retiredresponse = pkgdb.get_packages(
|
| |
- branches=branch, page="all", status="Retired", namespace=namespace)
|
| |
- except pkgdb2client.PkgDBException as e:
|
| |
- if "No packages found for these parameters" not in str(e):
|
| |
- raise
|
| |
- return []
|
| |
+ def get_retired_packages(branch="master", staging=False, namespace=DEFAULT_NS,
|
| |
+ source='pkgdb'):
|
| |
+ retiredpkgs = []
|
| |
+ if source == 'pkgdb':
|
| |
+ url = PRODUCTION_PKGDB if not staging else STAGING_PKGDB
|
| |
+ pkgdb = pkgdb2client.PkgDB(url)
|
| |
+
|
| |
+ try:
|
| |
+ retiredresponse = pkgdb.get_packages(
|
| |
+ branches=branch, page="all", status="Retired",
|
| |
+ namespace=namespace)
|
| |
+ except pkgdb2client.PkgDBException as e:
|
| |
+ if "No packages found for these parameters" not in str(e):
|
| |
+ raise
|
| |
+ return []
|
| |
+
|
| |
+ retiredinfo = retiredresponse["packages"]
|
| |
+ retiredpkgs = [p["name"] for p in retiredinfo]
|
| |
+ elif source == 'pdc':
|
| |
+ # PDC uses singular names such as rpm and container
|
| |
+ if namespace.endswith('s'):
|
| |
+ content_type = namespace[:-1]
|
| |
+ else:
|
| |
+ content_type = namespace
|
| |
+ url = PRODUCTION_PDC if not staging else STAGING_PDC
|
| |
+ url = ('{0}/rest_api/v1/component-branches/?name={1}&type={2}'
|
| |
+ '&active=false&page_size=100'.format(url, branch, content_type))
|
| |
+ while True:
|
| |
+ rv = requests.get(url)
|
| |
+ if not rv.ok:
|
| |
+ raise RuntimeError('Failed getting the retired packages from '
|
| |
+ 'PDC. The response was: {0}'
|
| |
+ .format(rv.content))
|
| |
+
|
| |
+ rv_json = rv.json()
|
| |
+ for branch in rv_json['results']:
|
| |
+ retiredpkgs.append(branch['global_component'])
|
| |
+
|
| |
+ if rv_json['next']:
|
| |
+ url = rv_json['next']
|
| |
+ else:
|
| |
+ break
|
| |
+ else:
|
| |
+ raise RuntimeError('An invalid source of "{0}" was provided'
|
| |
+ .format(source))
|
| |
|
| |
- retiredinfo = retiredresponse["packages"]
|
| |
- retiredpkgs = [p["name"] for p in retiredinfo]
|
| |
return retiredpkgs
|
| |
|
| |
|
| |
- def pkgdb_retirement_status(package, branch="master", staging=False, namespace=DEFAULT_NS):
|
| |
- """ Returns retirement info for `package` in `branch`
|
| |
-
|
| |
- :returns: dict: retired: True - if retired, False if not, None if
|
| |
- there was an error, status_change: last status change as datetime object
|
| |
- """
|
| |
-
|
| |
- url = PRODUCTION_PKGDB if not staging else STAGING_PKGDB
|
| |
- pkgdb = pkgdb2client.PkgDB(url)
|
| |
- retired = None
|
| |
- status_change = None
|
| |
- try:
|
| |
- pkgdbresult = pkgdb.get_package(package, branches=branch, namespace=namespace)
|
| |
- if pkgdbresult["output"] == "ok":
|
| |
- for pkginfo in pkgdbresult["packages"]:
|
| |
- if pkginfo["package"]["name"] == package:
|
| |
- if pkginfo["status"] == "Retired":
|
| |
- retired = True
|
| |
- else:
|
| |
- retired = False
|
| |
- status_change = datetime.datetime.fromtimestamp(
|
| |
- pkginfo["status_change"])
|
| |
- break
|
| |
- except:
|
| |
- pass
|
| |
-
|
| |
- return dict(retired=retired, status_change=status_change)
|
| |
-
|
| |
-
|
| |
-
|
| |
-
|
| |
def run_koji(koji_params, staging=False):
|
| |
profile = PRODUCTION_KOJI_PROFILE if not staging else STAGING_KOJI_PROFILE
|
| |
koji_cmd = ["koji", "--profile", profile]
|
| |
@@ -219,14 +223,15 @@
|
| |
return errors
|
| |
|
| |
|
| |
- def block_all_retired(branches=RETIRING_BRANCHES, staging=False, namespace=DEFAULT_NS):
|
| |
+ def block_all_retired(branches=RETIRING_BRANCHES, staging=False,
|
| |
+ namespace=DEFAULT_NS, source='pkgdb'):
|
| |
for branch in branches:
|
| |
log.debug("Processing branch %s", branch)
|
| |
if staging and branch in PROD_ONLY_BRANCHES:
|
| |
log.warning('%s in namespace "%s" not handled in staging..' %
|
| |
(branch, namespace))
|
| |
continue
|
| |
- retired = get_retired_packages(branch, staging, namespace)
|
| |
+ retired = get_retired_packages(branch, staging, namespace, source)
|
| |
unblocked = []
|
| |
|
| |
# Check which packages are included in a tag but not blocked, this
|
| |
@@ -293,13 +298,16 @@
|
| |
help="Branch to retire specified packages on, default: %(default)s")
|
| |
parser.add_argument(
|
| |
"--staging", default=False, action="store_true",
|
| |
- help="Talk to staging services (pkgdb), instead of production")
|
| |
+ help="Talk to staging services (pkgdb/pdc), instead of production")
|
| |
parser.add_argument(
|
| |
"-p", "--profile", default="compose_koji",
|
| |
help="Koji profile to use, default: %(default)s")
|
| |
parser.add_argument(
|
| |
"--namespace", default=DEFAULT_NS,
|
| |
- help="pkgdb namespace to use, default: %(default)s")
|
| |
+ help="pkgdb/pdc namespace to use, default: %(default)s")
|
| |
+ parser.add_argument(
|
| |
+ "--source", default='pdc', choices=['pkgdb', 'pdc'],
|
| |
+ help="Source for retirement information, default: %(default)s")
|
| |
args = parser.parse_args()
|
| |
|
| |
setup_logging(args.debug)
|
| |
@@ -307,7 +315,8 @@
|
| |
PRODUCTION_KOJI_PROFILE = args.profile
|
| |
STAGING_KOJI_PROFILE = "stg"
|
| |
if not args.packages:
|
| |
- block_all_retired(staging=args.staging, namespace=args.namespace)
|
| |
+ block_all_retired(staging=args.staging, namespace=args.namespace,
|
| |
+ source=args.source)
|
| |
else:
|
| |
block_package(args.packages, args.branch, staging=args.staging,
|
| |
namespace=args.namespace)
|
| |
This PR is branched off of the branch used in PR #6861 (removes unused functions). It also has a separate commit that removes a function that isn't used anymore.
Please consider merging PR #6861 before reviewing this one.
This is part of the work for https://fedoraproject.org/wiki/Changes/ArbitraryBranching