mirror of
https://git.centos.org/centos/centpkg.git
synced 2025-02-23 08:12:55 +00:00
Require --rhel-target
This commit is contained in:
parent
0271c67c5a
commit
1e7ef8239a
2 changed files with 300 additions and 3 deletions
|
@ -23,7 +23,11 @@ import centpkg.utils
|
|||
from pyrpkg.cli import cliClient
|
||||
from pyrpkg import rpkgError
|
||||
from six.moves.urllib_parse import urlparse
|
||||
import six.moves.configparser as ConfigParser
|
||||
|
||||
import json
|
||||
import koji
|
||||
import os
|
||||
|
||||
_DEFAULT_API_BASE_URL = 'https://gitlab.com'
|
||||
|
||||
|
@ -126,6 +130,122 @@ class centpkgClient(cliClient):
|
|||
msg = "Remote with name '{0}' already exists."
|
||||
self.log.info(msg.format(remote_name))
|
||||
|
||||
# Overloaded build
|
||||
def register_build(self):
|
||||
# Do all the work from the super class
|
||||
super(centpkgClient, self).register_build()
|
||||
build_parser = self.subparsers.choices['build']
|
||||
build_parser.formatter_class = argparse.RawDescriptionHelpFormatter
|
||||
build_parser.description = textwrap.dedent('''
|
||||
{0}
|
||||
|
||||
centpkg now sets the rhel metadata with --rhel-target.
|
||||
* exception - This will build for the current in-development Y-stream release.
|
||||
It is equivalent to passing latest when not in the Blocker and Exception Phase.
|
||||
* zstream - If pre-GA of a y-stream release, this will build for 0day.
|
||||
If post-GA of a Y-stream release, this will build for the Z-stream of that release.
|
||||
* latest - This will always build for the next Y-stream release
|
||||
|
||||
'''.format('\n'.join(textwrap.wrap(build_parser.description))))
|
||||
|
||||
# Now add our additional option
|
||||
build_parser.add_argument(
|
||||
'--rhel-target',
|
||||
choices=['exception', 'zstream', 'latest'],
|
||||
default='latest',
|
||||
help='Set the rhel-target metadata')
|
||||
|
||||
# Overloaded _build
|
||||
def _build(self, sets=None):
|
||||
|
||||
# Only run if we have internal configuraions, or scratch
|
||||
internal_config_file = "/etc/rpkg/centpkg_internal.conf"
|
||||
if os.path.exists(internal_config_file):
|
||||
# Get our internal only variables
|
||||
cfg = ConfigParser.SafeConfigParser()
|
||||
cfg.read(internal_config_file)
|
||||
pp_api_url = config_get_safely(cfg, "centpkg.internal", 'pp_api_url')
|
||||
gitbz_query_url = config_get_safely(cfg, "centpkg.internal", 'gitbz_query_url')
|
||||
rhel_dist_git = config_get_safely(cfg, "centpkg.internal", 'rhel_dist_git')
|
||||
|
||||
# Find out divergent branch and stabalization
|
||||
stream_version = self.cmd.target.split('-')[0]
|
||||
rhel_version = centpkg.utils.stream_mapping(stream_version)
|
||||
active_y, in_stabilization = centpkg.utils.determine_active_y_version(rhel_version, pp_api_url)
|
||||
divergent_branch = centpkg.utils.does_divergent_branch_exist(
|
||||
self.cmd.repo_name,
|
||||
rhel_version,
|
||||
rhel_dist_git,
|
||||
pp_api_url,
|
||||
"rpms")
|
||||
|
||||
# Good to know
|
||||
if divergent_branch :
|
||||
print("divergent_branch: TRUE")
|
||||
else:
|
||||
print("divergent_branch: FALSE")
|
||||
if in_stabilization :
|
||||
print("in_stabilization: TRUE")
|
||||
else:
|
||||
print("in_stabilization: FALSE")
|
||||
|
||||
# Update args.custom_user_metadata
|
||||
if hasattr(self.args, 'custom_user_metadata') and self.args.custom_user_metadata:
|
||||
try:
|
||||
temp_custom_user_metadata = json.loads(self.args.custom_user_metadata)
|
||||
# Use ValueError instead of json.JSONDecodeError for Python 2 and 3 compatibility
|
||||
except ValueError as e:
|
||||
self.parser.error("--custom-user-metadata is not valid JSON: %s" % e)
|
||||
if not isinstance(temp_custom_user_metadata, dict):
|
||||
self.parser.error("--custom-user-metadata must be a JSON object")
|
||||
if hasattr(self.args, 'rhel_target') and self.args.rhel_target:
|
||||
temp_custom_user_metadata["rhel-target"] = self.args.rhel_target
|
||||
else:
|
||||
if divergent_branch and not in_stabilization :
|
||||
temp_custom_user_metadata["rhel-target"] = "latest"
|
||||
elif not divergent_branch and not in_stabilization :
|
||||
temp_custom_user_metadata["rhel-target"] = "zstream"
|
||||
else:
|
||||
print("We are currently in Stabalization mode")
|
||||
print("You must either set the rhel-target (--rhel-target)")
|
||||
print("or branch for the previous version.")
|
||||
print("Exiting")
|
||||
raise SystemExit
|
||||
self.args.custom_user_metadata = json.dumps(temp_custom_user_metadata)
|
||||
else:
|
||||
if hasattr(self.args, 'rhel_target') and self.args.rhel_target:
|
||||
temp_custom_user_metadata = {"rhel-target": self.args.rhel_target}
|
||||
self.args.custom_user_metadata = json.dumps(temp_custom_user_metadata)
|
||||
else:
|
||||
if divergent_branch and not in_stabilization :
|
||||
self.args.custom_user_metadata = '{"rhel-target": "latest"}'
|
||||
elif not divergent_branch and not in_stabilization :
|
||||
self.args.custom_user_metadata = '{"rhel-target": "zstream"}'
|
||||
else:
|
||||
print("We are currently in Stabalization mode")
|
||||
print("You must either set the rhel-target (--rhel-target)")
|
||||
print("or branch for the previous version.")
|
||||
print("Exiting")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
# Good to know, but take out for final cut
|
||||
print('Metadata: %r', self.args.custom_user_metadata)
|
||||
|
||||
# Purposely fail during testing so we do not have so many builds
|
||||
#self.args.custom_user_metadata = json.loads(self.args.custom_user_metadata)
|
||||
|
||||
else:
|
||||
if not self.args.scratch:
|
||||
print("NO SCRATCH BUILD")
|
||||
print("Only scratch builds are allowed without internal configurations")
|
||||
print("Exiting")
|
||||
raise SystemExit
|
||||
|
||||
# Proceed with build
|
||||
return super(centpkgClient, self)._build(sets)
|
||||
|
||||
|
||||
def register_request_gated_side_tag(self):
|
||||
"""Register command line parser for subcommand request-gated-side-tag"""
|
||||
parser = self.subparsers.add_parser(
|
||||
|
|
|
@ -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 @@ def get_repo_name(name, org='rpms'):
|
|||
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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue