From 7b2533575803cbbc1db15679a0fa2edc70ed317d Mon Sep 17 00:00:00 2001 From: "D. Paolella" Date: Thu, 6 Oct 2022 09:23:59 +0200 Subject: [PATCH] Rebase Dockerfiles according to release schedule # Conflicts: # doozerlib/distgit.py --- doozerlib/distgit.py | 17 ++++++++++---- doozerlib/release_schedule.py | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 doozerlib/release_schedule.py diff --git a/doozerlib/distgit.py b/doozerlib/distgit.py index 350f52123..0b7349976 100644 --- a/doozerlib/distgit.py +++ b/doozerlib/distgit.py @@ -11,10 +11,9 @@ import re import shutil import sys -import threading import time import traceback -from datetime import date +from datetime import date, datetime from multiprocessing import Event, Lock from typing import Dict, List, Optional, Tuple, Union @@ -35,6 +34,7 @@ from doozerlib.model import ListModel, Missing, Model from doozerlib.osbs2_builder import OSBS2Builder from doozerlib.pushd import Dir +from doozerlib.release_schedule import ReleaseSchedule from doozerlib.rpm_utils import parse_nvr from doozerlib.source_modifications import SourceModifierFactory from doozerlib.util import convert_remote_git_to_https, yellow_print @@ -430,6 +430,15 @@ def __init__(self, metadata, autoclone=True, self.logger: logging.Logger = metadata.logger self.source_modifier_factory = source_modifier_factory + # Check if we should try to match upstream + if self.runtime.group_config.canonical_builders_from_upstream == 'auto': + # canonical_builders_from_upstream set to 'auto': rebase according to release schedule + feature_freeze_date = ReleaseSchedule(self.runtime).get_ff_date() + self.should_match_upstream = datetime.now() < feature_freeze_date + else: + # canonical_builders_from_upstream set to either 'false' or 'true' + self.should_match_upstream = self.runtime.group_config.canonical_builders_from_upstream + def clone(self, distgits_root_dir, distgit_branch): super(ImageDistGitRepo, self).clone(distgits_root_dir, distgit_branch) self._read_master_data() @@ -1633,11 +1642,11 @@ def _mapped_image_for_assembly_build(self, parent_images, i): def _mapped_image_from_stream(self, image, original_parent, dfp): stream = self.runtime.resolve_stream(image.stream) - if not self.runtime.group_config.canonical_builders_from_upstream: + if not self.should_match_upstream: # Do typical stream resolution. return stream.image - # When canonical_builders_from_upstream flag is set, try to match upstream FROM + # canonical_builders_from_upstream flag is either True, or 'auto' and we are before feature freeze try: self.logger.debug('Retrieving image info for image %s', original_parent) cmd = f'oc image info {original_parent} -o json' diff --git a/doozerlib/release_schedule.py b/doozerlib/release_schedule.py new file mode 100644 index 000000000..e128c472b --- /dev/null +++ b/doozerlib/release_schedule.py @@ -0,0 +1,43 @@ +from datetime import datetime +import os + +import yaml + +from doozerlib import gitdata + + +class ReleaseSchedule: + """ + This class is a Singleton. Only at first object construction, it will clone ocp-release-schedule repo inside Doozer + working directory, parse and store yaml data related to the current OCP version + """ + + _instance = None + + def __new__(cls, runtime): + if cls._instance is None: + cls._instance = super(ReleaseSchedule, cls).__new__(cls) + cls.initialize(runtime) + return cls._instance + + @classmethod + def initialize(cls, runtime): + if 'GITLAB_TOKEN' not in os.environ: + raise RuntimeError('A GITLAB_TOKEN env var must be defined') + + # Clone ocp-release-schedule in doozer working dir + git_data = gitdata.GitData( + data_path=f'https://oauth2:{os.environ["GITLAB_TOKEN"]}@gitlab.cee.redhat.com/ocp-release-schedule/schedule.git', + clone_dir=runtime.working_dir + ) + + # Parse and store relevant yaml + major = runtime.group_config.vars['MAJOR'] + minor = runtime.group_config.vars['MINOR'] + config_file = f'{git_data.data_dir}/schedules/{major}.{minor}.yaml' + with open(config_file) as f: + cls._instance.schedule_data = yaml.safe_load(f.read()) + + def get_ff_date(self) -> datetime: + event = next(item for item in self.schedule_data['events'] if item["name"] == "feature-freeze") + return datetime.strptime(event['date'], '%Y-%m-%dT%H:00:00-00:00')