Skip to content

Commit b63940e

Browse files
committed
Add buildroot repo to non-dev Copr chroots
Signed-off-by: Nikola Forró <[email protected]>
1 parent 06b6550 commit b63940e

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

mcp_server/copr_tools.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import aiohttp
1111
import rpm
12-
from copr.v3 import BuildProxy, ProjectProxy
12+
from copr.v3 import BuildProxy, ProjectChrootProxy, ProjectProxy
1313
from fastmcp.exceptions import ToolError
1414
from pydantic import BaseModel, Field
1515

@@ -57,12 +57,10 @@ def read_header():
5757
return (COPR_ARCHES - exclude_arches) & exclusive_arches
5858

5959

60-
async def _branch_to_chroot(dist_git_branch: str) -> str:
60+
async def _branch_to_chroot(dist_git_branch: str, upcoming_z_streams: dict[str, str]) -> str:
6161
if not (m := re.match(r"^(?:c(\d+)s|rhel-(\d+)-main|rhel-(\d+)\.(\d+).*)$", dist_git_branch)):
6262
raise ValueError(f"Unsupported branch name: {dist_git_branch}")
6363
majorver, minorver = m.group(1) or m.group(2) or m.group(3), m.group(4)
64-
rhel_config = await load_rhel_config()
65-
upcoming_z_streams = rhel_config.get("upcoming_z_streams", {})
6664
# build Y-Streams and 0-day Z-Streams against the dev chroot
6765
if minorver is not None:
6866
if (ver := upcoming_z_streams.get(majorver)) and ver.startswith(
@@ -94,8 +92,10 @@ async def build_package(
9492
# build for x86_64 unless the package is exclusive to other arch(es),
9593
# in such case build for either of them
9694
build_arch = exclusive_arches.pop() if exclusive_arches else "x86_64"
95+
rhel_config = await load_rhel_config()
96+
upcoming_z_streams = rhel_config.get("upcoming_z_streams", {})
9797
try:
98-
chroot = (await _branch_to_chroot(dist_git_branch)) + f"-{build_arch}"
98+
chroot = (await _branch_to_chroot(dist_git_branch, upcoming_z_streams)) + f"-{build_arch}"
9999
except ValueError as e:
100100
raise ToolError(f"Failed to deduce Copr chroot: {e}") from e
101101
project_proxy = ProjectProxy({"username": copr_user, **COPR_CONFIG})
@@ -116,6 +116,34 @@ async def build_package(
116116
await asyncio.to_thread(project_proxy.edit, **kwargs)
117117
except Exception as e:
118118
raise ToolError(f"Failed to create or update Copr project: {e}") from e
119+
if not chroot.removesuffix(f"-{build_arch}").endswith(".dev"):
120+
# make sure the chroot has access to corresponding buildroot repository
121+
chroot_proxy = ProjectChrootProxy({"username": copr_user, **COPR_CONFIG})
122+
if not (internal_repos_host := rhel_config.get("internal_repos_host")):
123+
raise ToolError("Internal repos host not configured")
124+
buildroot_repo_url = urljoin(
125+
internal_repos_host,
126+
f"brewroot/repos/{dist_git_branch}-z-build/latest/{build_arch}",
127+
)
128+
try:
129+
chroot_config = await asyncio.to_thread(
130+
chroot_proxy.get,
131+
ownername=copr_user,
132+
projectname=jira_issue,
133+
chrootname=chroot,
134+
)
135+
if buildroot_repo_url not in chroot_config.additional_repos:
136+
await asyncio.to_thread(
137+
chroot_proxy.edit,
138+
ownername=copr_user,
139+
projectname=jira_issue,
140+
chrootname=chroot,
141+
additional_repos=sorted(
142+
set(chroot_config.additional_repos) | {buildroot_repo_url},
143+
),
144+
)
145+
except Exception as e:
146+
raise ToolError(f"Failed to update Copr chroot: {e}") from e
119147
build_proxy = BuildProxy({"username": copr_user, **COPR_CONFIG})
120148
try:
121149
build = await asyncio.to_thread(

mcp_server/tests/unit/test_copr.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import aiohttp
77
import pytest
8-
from copr.v3 import ProjectProxy, BuildProxy
8+
from copr.v3 import BuildProxy, ProjectChrootProxy, ProjectProxy
99
from fastmcp.exceptions import ToolError
1010
from flexmock import flexmock
1111

@@ -36,8 +36,10 @@ async def test_build_package(build_failure, exclusive_arch, dist_git_branch):
3636
srpm_path = Path("test.src.rpm")
3737
jira_issue = "RHEL-12345"
3838
suffix = "" if dist_git_branch == "rhel-10.0" else ".dev"
39-
chroot = f"rhel-10{suffix}-{exclusive_arch or 'x86_64'}"
39+
build_arch = exclusive_arch or "x86_64"
40+
chroot = f"rhel-10{suffix}-{build_arch}"
4041
existing_chroot = "rhel-9.dev-x86_64"
42+
internal_repos_host = "http://example.com"
4143

4244
async def init_kerberos_ticket():
4345
return f"{ownername}@EXAMPLE.COM"
@@ -46,6 +48,7 @@ async def load_rhel_config():
4648
return {
4749
"current_z_streams": {"10": "rhel-10.0.z"},
4850
"upcoming_z_streams": {"10": "rhel-10.1.z"},
51+
"internal_repos_host": internal_repos_host,
4952
}
5053

5154
async def _get_exclusive_arches(*_):
@@ -72,6 +75,19 @@ async def sleep(*_):
7275
).once()
7376
kwargs["chroots"] = sorted({existing_chroot} | {chroot})
7477
flexmock(ProjectProxy).should_receive("edit").with_args(**kwargs).once()
78+
flexmock(ProjectChrootProxy).should_receive("get").with_args(
79+
ownername=ownername,
80+
projectname=jira_issue,
81+
chrootname=chroot,
82+
).and_return(flexmock(additional_repos=[])).times(0 if suffix else 1)
83+
flexmock(ProjectChrootProxy).should_receive("edit").with_args(
84+
ownername=ownername,
85+
projectname=jira_issue,
86+
chrootname=chroot,
87+
additional_repos=[
88+
f"{internal_repos_host}/brewroot/repos/{dist_git_branch}-z-build/latest/{build_arch}",
89+
],
90+
).times(0 if suffix else 1)
7591
flexmock(BuildProxy).should_receive("create_from_file").with_args(
7692
ownername=ownername,
7793
projectname=jira_issue,

0 commit comments

Comments
 (0)