Skip to content

Commit 61cdf49

Browse files
author
Konrad Kleine
committed
Update (base update)
[ghstack-poisoned]
1 parent 924a65e commit 61cdf49

2 files changed

Lines changed: 288 additions & 10 deletions

File tree

snapshot_manager/snapshot_manager/config.py

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,32 @@ class Config:
1111
chroot_pattern: str = r"^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)"
1212
"""Regular expression to select chroots from all chroots currently supported on Copr."""
1313

14+
chroots: list[str] = None
15+
"""A list of chroot names. To be filled automatically for you from the chroot_pattern. See util.augment_config_with_chroots()"""
16+
1417
packages: list[str] = dataclasses.field(
1518
default_factory=lambda: [
1619
"llvm",
1720
]
1821
)
1922
"""List of packages that are relevant to you."""
2023

21-
active_build_state_pattern: str = r"(running|waiting|pending|importing|starting)"
22-
"""Regular expression to select what states of a copr build are considered active."""
23-
2424
datetime: "datetime.datetime" = datetime.datetime.now()
2525
"""Datetime of today"""
2626

2727
build_strategy: str = "big-merge"
2828
"""The build strategy to use a by default."""
2929

3030
github_repo: str = "fedora-llvm-team/llvm-snapshots-test"
31-
"""Default github repo to use"""
31+
"""Default github repo to use for creating issues"""
32+
33+
package_clone_url: str = "https://src.fedoraproject.org/rpms/llvm.git"
34+
"""The package to clone from when creating RPMs"""
3235

33-
github_token_env: str = "GH_TEST_TOKEN"
36+
package_clone_ref: str = "rawhide"
37+
"""The git clone ref to use for creating the RPMs"""
38+
39+
github_token_env: str = "GITHUB_TOKEN"
3440
"""Default name of the environment variable which holds the github token"""
3541

3642
update_marker: str = "<!--UPDATES_FOLLOW_HERE-->"
@@ -42,6 +48,9 @@ class Config:
4248
creator_handle: str = "github-actions[bot]"
4349
"""The Github user that is expected to have created the daily issue (TODO(kwk): Improve documentation)"""
4450

51+
copr_target_project: str = "@fedora-llvm-team/llvm-snapshots"
52+
"""The Copr project that the daily snapshot will be converted to if all goes well"""
53+
4554
copr_ownername: str = "@fedora-llvm-team"
4655
"""The Copr owner name of the project to work with"""
4756

@@ -80,11 +89,6 @@ def copr_projectname(self) -> str:
8089
"""
8190
return self.copr_project_tpl.replace("YYYYMMDD", self.yyyymmdd)
8291

83-
@property
84-
def copr_project(self) -> str:
85-
"""Returns the owner/project string for the current date."""
86-
return f"{self.config.copr_ownername}/{self.config.copr_projectname}"
87-
8892
@property
8993
def copr_monitor_url(self) -> str:
9094
"""Takes the copr_monitor_tpl and replaces the YYYYMMDD placeholder (if any) with a date.
@@ -113,3 +117,78 @@ def yyyymmdd(self) -> str:
113117
'20240229'
114118
"""
115119
return self.datetime.strftime("%Y%m%d")
120+
121+
def to_github_dict(self) -> dict:
122+
"""Returns a subset of config entries to be used in a github workflow matrix.
123+
124+
The keys in this dict are accessed from github workflow files using the "matrix." object.
125+
For example the maintainer handle will be accessed as `${{ matrix.maintainer_handle }}`.
126+
127+
Examples:
128+
129+
>>> import pprint
130+
>>> pprint.pprint(Config(build_strategy="mybuildstrategy",
131+
... copr_target_project="@mycoprgroup/mycoprproject",
132+
... package_clone_url="https://src.fedoraproject.org/rpms/mypackage.git",
133+
... package_clone_ref="mainbranch",
134+
... maintainer_handle="fakeperson",
135+
... copr_project_tpl="SomeProjectTemplate-YYYYMMDD",
136+
... copr_monitor_tpl="https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate-YYYYMMDD/monitor/",
137+
... chroot_pattern="^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)",
138+
... chroots=["fedora-rawhide-x86_64", "rhel-9-ppc64le"]
139+
... ).to_github_dict())
140+
{'chroot_pattern': '^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)',
141+
'chroots': 'fedora-rawhide-x86_64 rhel-9-ppc64le',
142+
'clone_ref': 'mainbranch',
143+
'clone_url': 'https://src.fedoraproject.org/rpms/mypackage.git',
144+
'copr_monitor_tpl': 'https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate-YYYYMMDD/monitor/',
145+
'copr_ownername': '@fedora-llvm-team',
146+
'copr_project_tpl': 'SomeProjectTemplate-YYYYMMDD',
147+
'copr_target_project': '@mycoprgroup/mycoprproject',
148+
'maintainer_handle': 'fakeperson',
149+
'name': 'mybuildstrategy'}
150+
"""
151+
return {
152+
"name": self.build_strategy,
153+
"copr_target_project": self.copr_target_project,
154+
"clone_url": self.package_clone_url,
155+
"clone_ref": self.package_clone_ref,
156+
"maintainer_handle": self.maintainer_handle,
157+
"copr_ownername": self.copr_ownername,
158+
"copr_project_tpl": self.copr_project_tpl,
159+
"copr_monitor_tpl": self.copr_monitor_tpl,
160+
"chroot_pattern": self.chroot_pattern,
161+
"chroots": " ".join(self.chroots),
162+
}
163+
164+
165+
def build_config_map() -> dict[str, Config]:
166+
"""Builds a dictionary for each supported build strategy with the name of the build strategy as key.
167+
168+
Returns:
169+
dict: The config map with build strategies as keys and config objects as values.
170+
"""
171+
configs = [
172+
Config(
173+
build_strategy="big-merge",
174+
copr_target_project="@fedora-llvm-team/llvm-snapshots",
175+
package_clone_url="https://src.fedoraproject.org/rpms/llvm.git",
176+
package_clone_ref="rawhide",
177+
maintainer_handle="tuliom",
178+
copr_project_tpl="llvm-snapshots-big-merge-YYYYMMDD",
179+
copr_monitor_tpl="https://copr.fedorainfracloud.org/coprs/g/fedora-llvm-team/llvm-snapshots-big-merge-YYYYMMDD/monitor/",
180+
chroot_pattern="^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)",
181+
),
182+
Config(
183+
build_strategy="pgo",
184+
copr_target_project="@fedora-llvm-team/llvm-snapshots-pgo",
185+
package_clone_url="https://src.fedoraproject.org/forks/kkleine/rpms/llvm.git",
186+
package_clone_ref="pgo",
187+
maintainer_handle="kwk",
188+
copr_project_tpl="llvm-snapshots-pgo-YYYYMMDD",
189+
copr_monitor_tpl="https://copr.fedorainfracloud.org/coprs/g/fedora-llvm-team/llvm-snapshots-pgo-YYYYMMDD/monitor/",
190+
chroot_pattern="(fedora-41)",
191+
),
192+
]
193+
194+
return {config.build_strategy: config for config in configs}

snapshot_manager/snapshot_manager/util.py

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import datetime
66
import functools
7+
import json
78
import logging
89
import os
910
import pathlib
@@ -14,6 +15,7 @@
1415
import regex
1516
import requests
1617

18+
import snapshot_manager.config as config
1719
import snapshot_manager.file_access as file_access
1820

1921

@@ -474,3 +476,200 @@ def get_release_for_yyyymmdd(yyyymmdd: str) -> str:
474476
logging.info(f"Getting URL {url}")
475477
response = requests.get(url)
476478
return response.text.strip()
479+
480+
481+
def filter_chroots(chroots: list[str], pattern: str) -> list[str]:
482+
"""Return a sorted list of chroots filtered by the given pattern.
483+
484+
Args:
485+
chroots (list[str]): As list of chroots to filter
486+
pattern (str, optional): Regular expression e.g. `r"^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)"`
487+
488+
Returns:
489+
list[str]: List of filtered and sorted chroots.
490+
491+
Examples:
492+
493+
>>> chroots = ["rhel-7-x86_64", "rhel-9-s390x", "fedora-rawhide-x86_64", "centos-stream-10-ppc64le"]
494+
>>> filter_chroots(chroots=chroots, pattern=r"^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)")
495+
['fedora-rawhide-x86_64', 'rhel-9-s390x']
496+
"""
497+
res: list[str] = []
498+
for chroot in chroots:
499+
if re.match(pattern=pattern, string=chroot) != None:
500+
res.append(chroot)
501+
res.sort()
502+
return res
503+
504+
505+
def sanitize_chroots(chroots: list[str]) -> list[str]:
506+
"""Removes all s390x fedora chroots but rawhide and the highest
507+
numbered version in the given list
508+
509+
Args:
510+
chroots (list[str]): A list of chroots
511+
512+
Returns:
513+
list[str]: The sanitized list of chroots
514+
515+
Example:
516+
517+
>>> chroots = ["fedora-40-aarch64", "fedora-40-s390x",
518+
... "fedora-41-s390x", "fedora-41-ppc64le",
519+
... "fedora-42-aarch64", "fedora-42-s390x",
520+
... "fedora-rawhide-x86_64", "fedora-rawhide-s390x",
521+
... "rhel-8-aarch64", "rhel-8-s390x",
522+
... "rhel-8-x86_64", "rhel-9-aarch64",
523+
... "rhel-9-s390x", "rhel-9-x86_64"]
524+
>>> expected = ['fedora-40-aarch64', 'fedora-41-ppc64le',
525+
... 'fedora-42-aarch64', 'fedora-42-s390x',
526+
... 'fedora-rawhide-x86_64', 'fedora-rawhide-s390x',
527+
... 'rhel-8-aarch64', 'rhel-8-s390x',
528+
... 'rhel-8-x86_64', 'rhel-9-aarch64',
529+
... 'rhel-9-s390x', 'rhel-9-x86_64']
530+
>>> actual = sanitize_chroots(chroots)
531+
>>> actual == expected
532+
True
533+
"""
534+
chroots = [expect_chroot(chroot) for chroot in chroots]
535+
removals = filter_chroots(chroots, r"^fedora-[0-9]+-s390x")
536+
max = 0
537+
for chroot in removals:
538+
ver = int(chroot_version(chroot))
539+
if ver > max:
540+
max = ver
541+
for chroot in removals:
542+
if max != int(chroot_version(chroot)):
543+
chroots.remove(chroot)
544+
return chroots
545+
546+
547+
def augment_config_with_chroots(config: config.Config, all_chroots: list[str]) -> None:
548+
"""Augments the config in place with chroots from the given chroot pattern.
549+
550+
Args:
551+
config (config.Config) A config object
552+
all_chroots (list[str]): A list of all possible chroots currently supported on Copr
553+
554+
Example:
555+
556+
>>> strategy = "foo"
557+
>>> all_chroots = ["fedora-rawhide-x86_64", "rhel-9-ppc64le", "fedora-42-x86_64"]
558+
>>> config = config.Config(build_strategy=strategy, chroot_pattern=r"fedora-.*")
559+
>>> augment_config_with_chroots(config=config, all_chroots=all_chroots)
560+
>>> config.chroots
561+
['fedora-42-x86_64', 'fedora-rawhide-x86_64']
562+
"""
563+
chroots = filter_chroots(chroots=all_chroots, pattern=config.chroot_pattern)
564+
config.chroots = sanitize_chroots(chroots=chroots)
565+
566+
567+
def augment_config_map_with_chroots(
568+
config_map: dict[str, config.Config], all_chroots: list[str]
569+
) -> None:
570+
"""Augments the config_map in place with chroots from the given chroot pattern.
571+
572+
Args:
573+
config_map (dict[str, config.Config]) A config map as returned by config.build_config_map()
574+
all_chroots (list[str]): A list of all possible chroots currently supported on Copr
575+
576+
Example:
577+
578+
>>> all_chroots = ["fedora-rawhide-x86_64", "rhel-9-ppc64le", "fedora-42-x86_64"]
579+
>>> config_map = dict()
580+
>>> config_map["foo"] = config.Config(build_strategy="foo", chroot_pattern=r"fedora-.*")
581+
>>> config_map["bar"] = config.Config(build_strategy="bar", chroot_pattern=r"rhel-.*")
582+
>>> augment_config_map_with_chroots(config_map=config_map, all_chroots=all_chroots)
583+
>>> config_map["foo"].chroots
584+
['fedora-42-x86_64', 'fedora-rawhide-x86_64']
585+
>>> config_map["bar"].chroots
586+
['rhel-9-ppc64le']
587+
"""
588+
for strategy in config_map:
589+
augment_config_with_chroots(
590+
config=config_map[strategy], all_chroots=all_chroots
591+
)
592+
593+
594+
def serialize_config_map_to_github_matrix(
595+
strategy: str,
596+
config_map: dict[str, config.Config],
597+
lookback_days: list[int] | None = None,
598+
) -> str:
599+
"""Returns a serialized JSON github workflow matrix.
600+
601+
See https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow.
602+
603+
Args:
604+
strategy (str): Which strategy to output for for ("" or "all" will include all strategies from the `config_map`)
605+
config_map (dict[str, Config]): A config map to serialize
606+
lookback_days (list[int], optional): Integer array for how many days to look back (0 means just today)
607+
608+
Returns:
609+
str: A github workflow matrix dictionary as JSON
610+
611+
Example:
612+
613+
>>> strategy = "foo"
614+
>>> config_map = dict()
615+
>>> config_map["mybuildstrategy"] = config.Config(build_strategy="mybuildstrategy",
616+
... copr_target_project="@mycoprgroup/mycoprproject",
617+
... package_clone_url="https://src.fedoraproject.org/rpms/mypackage.git",
618+
... package_clone_ref="mainbranch",
619+
... maintainer_handle="fakeperson",
620+
... copr_project_tpl="SomeProjectTemplate-YYYYMMDD",
621+
... copr_monitor_tpl="https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate-YYYYMMDD/monitor/",
622+
... chroot_pattern="^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)",
623+
... chroots=["fedora-rawhide-x86_64", "rhel-9-ppc64le"]
624+
... )
625+
>>> config_map["mybuildstrategy2"] = config.Config(build_strategy="mybuildstrategy2",
626+
... copr_target_project="@mycoprgroup2/mycoprproject2",
627+
... package_clone_url="https://src.fedoraproject.org/rpms/mypackage2.git",
628+
... package_clone_ref="mainbranch2",
629+
... maintainer_handle="fakeperson2",
630+
... copr_project_tpl="SomeProjectTemplate2-YYYYMMDD",
631+
... copr_monitor_tpl="https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate2-YYYYMMDD/monitor/",
632+
... chroot_pattern="rhel-[8,9]",
633+
... chroots=["rhel-9-ppc64le"]
634+
... )
635+
>>> s = serialize_config_map_to_github_matrix(strategy="all", config_map=config_map, lookback_days=[0,1,2,3])
636+
>>> obj = json.loads(s)
637+
>>> import pprint
638+
>>> pprint.pprint(obj)
639+
{'include': [{'chroot_pattern': '^(fedora-(rawhide|[0-9]+)|rhel-[8,9]-)',
640+
'chroots': 'fedora-rawhide-x86_64 rhel-9-ppc64le',
641+
'clone_ref': 'mainbranch',
642+
'clone_url': 'https://src.fedoraproject.org/rpms/mypackage.git',
643+
'copr_monitor_tpl': 'https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate-YYYYMMDD/monitor/',
644+
'copr_ownername': '@fedora-llvm-team',
645+
'copr_project_tpl': 'SomeProjectTemplate-YYYYMMDD',
646+
'copr_target_project': '@mycoprgroup/mycoprproject',
647+
'maintainer_handle': 'fakeperson',
648+
'name': 'mybuildstrategy'},
649+
{'chroot_pattern': 'rhel-[8,9]',
650+
'chroots': 'rhel-9-ppc64le',
651+
'clone_ref': 'mainbranch2',
652+
'clone_url': 'https://src.fedoraproject.org/rpms/mypackage2.git',
653+
'copr_monitor_tpl': 'https://copr.fedorainfracloud.org/coprs/g/mycoprgroup/SomeProjectTemplate2-YYYYMMDD/monitor/',
654+
'copr_ownername': '@fedora-llvm-team',
655+
'copr_project_tpl': 'SomeProjectTemplate2-YYYYMMDD',
656+
'copr_target_project': '@mycoprgroup2/mycoprproject2',
657+
'maintainer_handle': 'fakeperson2',
658+
'name': 'mybuildstrategy2'}],
659+
'name': ['mybuildstrategy', 'mybuildstrategy2'],
660+
'today_minus_n_days': [0, 1, 2, 3]}
661+
"""
662+
res = {
663+
"name": [],
664+
"include": [],
665+
}
666+
667+
if lookback_days is not None:
668+
res["today_minus_n_days"] = lookback_days
669+
670+
for strat in config_map:
671+
if strategy in ("all", "", strat):
672+
res["include"].append(config_map[strat].to_github_dict())
673+
res["name"].append(strat)
674+
675+
return json.dumps(res)

0 commit comments

Comments
 (0)