| |
@@ -10,16 +10,22 @@
|
| |
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
|
| |
# the full text of the license.
|
| |
|
| |
- import re
|
| |
- import json
|
| |
-
|
| |
import git
|
| |
+ import json
|
| |
+ import logging
|
| |
+ import os
|
| |
+ import pytz
|
| |
+ import re
|
| |
import requests
|
| |
+ import sys
|
| |
+ from datetime import date, datetime
|
| |
from pyrpkg import rpkgError
|
| |
from requests.exceptions import ConnectionError
|
| |
from six.moves.configparser import NoOptionError, NoSectionError
|
| |
from six.moves.urllib.parse import quote_plus, urlparse
|
| |
|
| |
+ import git as gitpython
|
| |
+
|
| |
dist_git_config = None
|
| |
|
| |
def do_fork(logger, base_url, token, repo_name, namespace, cli_name):
|
| |
@@ -255,3 +261,174 @@
|
| |
repo_name = get_canonical_repo_name(dist_git_config, name)
|
| |
|
| |
return '%s/%s' % (org, repo_name)
|
| |
+
|
| |
+ def stream_mapping(csname):
|
| |
+ """
|
| |
+ Given a CentOS Stream name, map it to the corresponding RHEL name.
|
| |
+
|
| |
+ Parameters
|
| |
+ ----------
|
| |
+ csname: str
|
| |
+ The CentOS Stream name.
|
| |
+
|
| |
+ Returns
|
| |
+ -------
|
| |
+ str
|
| |
+ Correspoinding RHEL name.
|
| |
+ """
|
| |
+ if csname == "c8s" or csname == "cs8" :
|
| |
+ return "rhel-8"
|
| |
+ if csname == "c9s" or csname == "cs9" :
|
| |
+ return "rhel-9"
|
| |
+ if csname == "c10s" or csname == "cs10" :
|
| |
+ return "rhel-10"
|
| |
+ if csname == "c11s" or csname == "cs11" :
|
| |
+ return "rhel-11"
|
| |
+ return None
|
| |
+
|
| |
+ def does_divergent_branch_exist(repo_name, rhel_version, rhel_dist_git, pp_api_url, namespace):
|
| |
+ logger = logging.getLogger(__name__)
|
| |
+
|
| |
+ # Determine if the Y-1 branch exists for this repo
|
| |
+
|
| |
+ # Look up the Y-1 branch name
|
| |
+ divergent_branch = determine_divergent_branch(
|
| |
+ rhel_version,
|
| |
+ pp_api_url,
|
| |
+ namespace,
|
| |
+ )
|
| |
+ logger.debug("Divergent branch: {}".format(divergent_branch))
|
| |
+
|
| |
+ g = gitpython.cmd.Git()
|
| |
+ try:
|
| |
+ g.ls_remote(
|
| |
+ "--exit-code",
|
| |
+ os.path.join(rhel_dist_git, namespace, repo_name),
|
| |
+ divergent_branch,
|
| |
+ )
|
| |
+ branch_exists = True
|
| |
+ except gitpython.GitCommandError as e:
|
| |
+ t, v, tb = sys.exc_info()
|
| |
+ # `git ls-remote --exit-code` returns "2" if it cannot find the ref
|
| |
+ if e.status == 2:
|
| |
+ branch_exists = False
|
| |
+ else:
|
| |
+ raise
|
| |
+ return branch_exists
|
| |
+
|
| |
+ def determine_divergent_branch(rhel_version, pp_api_url, namespace):
|
| |
+ logger = logging.getLogger(__name__)
|
| |
+
|
| |
+ # Query the "package pages" API for the current active Y-stream release
|
| |
+ # Phase 230 is "Planning / Development / Testing" (AKA DeveTestDoc)
|
| |
+ request_params = {
|
| |
+ "phase": 230,
|
| |
+ "product__shortname": "rhel",
|
| |
+ "relgroup__shortname": rhel_version,
|
| |
+ "format": "json",
|
| |
+ }
|
| |
+
|
| |
+ res = requests.get(
|
| |
+ os.path.join(pp_api_url, "latest", "releases"),
|
| |
+ params=request_params,
|
| |
+ timeout=60,
|
| |
+ )
|
| |
+ res.raise_for_status()
|
| |
+ payload = json.loads(res.text)
|
| |
+ logger.debug(
|
| |
+ "Response from PP API: {}".format(json.dumps(payload, indent=2))
|
| |
+ )
|
| |
+ if len(payload) < 1:
|
| |
+ raise RuntimeError("Received zero potential release matches)")
|
| |
+
|
| |
+ active_y_version = -1
|
| |
+ for entry in payload:
|
| |
+ shortname = entry["shortname"]
|
| |
+
|
| |
+ # The shortname is in the form rhel-9-1.0
|
| |
+ # Extract the active Y-stream version
|
| |
+ m = re.search("(?<={}-)\d+(?=\.0)".format(rhel_version), shortname)
|
| |
+ if not m:
|
| |
+ raise RuntimeError(
|
| |
+ "Could not determine active Y-stream version from shortname"
|
| |
+ )
|
| |
+ y_version = int(m.group(0))
|
| |
+ if y_version > active_y_version:
|
| |
+ active_y_version = y_version
|
| |
+
|
| |
+ # The divergent branch is Y-1
|
| |
+ return "{}.{}.0".format(rhel_version, active_y_version - 1)
|
| |
+
|
| |
+ def _datesplit(isodate):
|
| |
+ date_string_tuple = isodate.split('-')
|
| |
+ return [ int(x) for x in date_string_tuple ]
|
| |
+
|
| |
+
|
| |
+ def determine_active_y_version(rhel_version, pp_api_url):
|
| |
+ """
|
| |
+ Returns: A 2-tuple of the active Y-stream version(int) and whether we are
|
| |
+ in the Exception Phase(bool)
|
| |
+ """
|
| |
+ logger = logging.getLogger(__name__)
|
| |
+
|
| |
+ # Query the "package pages" API for the current active Y-stream release
|
| |
+ # Phase 230 is "Planning / Development / Testing" (AKA DeveTestDoc)
|
| |
+ request_params = {
|
| |
+ "phase": 230,
|
| |
+ "product__shortname": "rhel",
|
| |
+ "relgroup__shortname": rhel_version,
|
| |
+ "format": "json",
|
| |
+ }
|
| |
+
|
| |
+ res = requests.get(
|
| |
+ os.path.join(pp_api_url, "latest", "releases"),
|
| |
+ params=request_params,
|
| |
+ timeout=60,
|
| |
+ )
|
| |
+ res.raise_for_status()
|
| |
+ payload = json.loads(res.text)
|
| |
+ logger.debug(
|
| |
+ "Response from PP API: {}".format(json.dumps(payload, indent=2))
|
| |
+ )
|
| |
+ if len(payload) < 1:
|
| |
+ raise RuntimeError("Received zero potential release matches)")
|
| |
+
|
| |
+ release_id = -1
|
| |
+ active_y_version = -1
|
| |
+ for entry in payload:
|
| |
+ shortname = entry["shortname"]
|
| |
+
|
| |
+ # The shortname is in the form rhel-9-1.0
|
| |
+ # Extract the active Y-stream version
|
| |
+ m = re.search("(?<={}-)\d+(?=\.0)".format(rhel_version), shortname)
|
| |
+ if not m:
|
| |
+ raise RuntimeError(
|
| |
+ "Could not determine active Y-stream version from shortname"
|
| |
+ )
|
| |
+ y_version = int(m.group(0))
|
| |
+ if y_version > active_y_version:
|
| |
+ active_y_version = y_version
|
| |
+ release_id = entry["id"]
|
| |
+
|
| |
+ # Now look up whether we are in the Exception Phase for this Y-stream release
|
| |
+ request_params = {
|
| |
+ "name__regex": "Exception Phase",
|
| |
+ "format": "json",
|
| |
+ }
|
| |
+ res = requests.get(os.path.join(pp_api_url, "latest", "releases", str(release_id), "schedule-tasks"), params=request_params)
|
| |
+ res.raise_for_status()
|
| |
+ payload = json.loads(res.text)
|
| |
+
|
| |
+ # This lookup *must* return exactly one value or the Product Pages are
|
| |
+ # wrong and must be fixed.
|
| |
+ assert len(payload) == 1
|
| |
+
|
| |
+ # Determine if this Y-stream release is in the exception phase
|
| |
+ today = datetime.now(tz=pytz.utc).date()
|
| |
+ exception_start_date = date(*_datesplit(payload[0]["date_start"]))
|
| |
+ in_exception_phase = today >= exception_start_date
|
| |
+
|
| |
+ logger.debug("Active Y-stream: {}, Enforcing: {}".format(active_y_version, in_exception_phase))
|
| |
+
|
| |
+ return active_y_version, in_exception_phase
|
| |
+
|
| |
For Y Z builds we need to have the proper metadata sent to koji when a build happens.
This adds the --rhel-target option, and makes sure the proper metadata get's passed along.
Signed-off-by: Troy Dawson tdawson@redhat.com