Skip to content

Commit a5f3d96

Browse files
bintars
1 parent 80c4e27 commit a5f3d96

4 files changed

Lines changed: 241 additions & 16 deletions

File tree

configuration/builders/definitions/foundry/builders.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,32 @@ def foundry_scheduler_name(mariadb_version):
3939
version = package_config["version"]
4040
package = f"{ops}-{version}"
4141
package_type = package_config["type"]
42-
sequence_fn = _SEQUENCE_BY_PACKAGE_TYPE[package_type]
43-
repo_file = _REPO_FILE_BY_PACKAGE_TYPE[package_type]
4442
for arch in package_config["arch"]:
45-
# Server autobake builder that publishes MariaDB-devel/libmariadb-dev
46-
# for this platform, e.g. "amd64-debian-12-deb-autobake" -- see
47-
# BUILDERS_AUTOBAKE in constants.py.
48-
autobake_builder = f"{arch}-{package_config['os_info_key']}-{package_type}-autobake"
49-
repo_file_url = (
50-
f"{_DEVEL_REPO_ARTIFACTS_URL}/%(prop:tarbuildnum)s/{autobake_builder}/{repo_file}"
51-
)
43+
if package_type == "bintar":
44+
# Bintar builds link against a MariaDB server bintar (see
45+
# autobake.bintar) instead of installing -devel packages from an
46+
# autobake builder's repo, so there's no repo_file_url to build.
47+
sequence = autobake.bintar(
48+
docker_config(image=f"{ops}{version}"),
49+
package_config["ci_bintar_builder"],
50+
)
51+
else:
52+
sequence_fn = _SEQUENCE_BY_PACKAGE_TYPE[package_type]
53+
repo_file = _REPO_FILE_BY_PACKAGE_TYPE[package_type]
54+
# Server autobake builder that publishes
55+
# MariaDB-devel/libmariadb-dev for this platform, e.g.
56+
# "amd64-debian-12-deb-autobake" -- see BUILDERS_AUTOBAKE in
57+
# constants.py.
58+
autobake_builder = (
59+
f"{arch}-{package_config['os_info_key']}-{package_type}-autobake"
60+
)
61+
repo_file_url = (
62+
f"{_DEVEL_REPO_ARTIFACTS_URL}/%(prop:tarbuildnum)s/{autobake_builder}/{repo_file}"
63+
)
64+
sequence = sequence_fn(docker_config(image=f"{ops}{version}"), repo_file_url)
5265
builder = GenericBuilder(
5366
name=f"foundry-{arch}-{ops}-{version}",
54-
sequences=[
55-
sequence_fn(docker_config(image=f"{ops}{version}"), repo_file_url)
56-
],
67+
sequences=[sequence],
5768
)
5869
FOUNDRY_BUILDERS_BY_ARCH.setdefault(arch, []).append(builder)
5970
FOUNDRY_BUILDERS_BY_PACKAGE.setdefault(package, []).append(builder)

configuration/builders/definitions/foundry/foundry.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,21 @@ packages:
9090
type: rpm
9191
os_info_key: opensuse-1600
9292
arch: [amd64]
93+
# Bintar builds: the plugin is built against a MariaDB server bintar
94+
# (fetched from ci_bintar_builder on ci.mariadb.org, same tarbuildnum)
95+
# instead of installed -devel packages -- see autobake.bintar. Only one
96+
# image builds bintars per MariaDB version range: centos7 up to 11.4,
97+
# almalinux8 from 11.8 on (see mariadb_versions below).
98+
- ops: centos
99+
version: "7-bintar"
100+
type: bintar
101+
ci_bintar_builder: amd64-centos-7-bintar
102+
arch: [amd64]
103+
- ops: almalinux
104+
version: "8-bintar"
105+
type: bintar
106+
ci_bintar_builder: amd64-almalinux-8-bintar
107+
arch: [amd64]
93108

94109
# Supported MariaDB versions: which packages get built for each, and the
95110
# tarbuildnum of the server CI build to install MariaDB-devel/libmariadb-dev
@@ -111,6 +126,7 @@ mariadb_versions:
111126
- debian-12
112127
- ubuntu-22.04
113128
- ubuntu-24.04
129+
- centos-7-bintar
114130
# "11.8":
115131
# tarbuildnum: 0
116132
# packages:
@@ -128,3 +144,4 @@ mariadb_versions:
128144
# - sles-1507
129145
# - sles-1600
130146
# - opensuse-1600
147+
# - almalinux-8-bintar

configuration/builders/sequences/foundry/autobake.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
from configuration.steps.commands.download import GitInitFromCommit
1010
from configuration.steps.commands.foundry import (
1111
BuildPlugin,
12+
DownloadServerBintar,
13+
ExtractPluginBintarIntoServerBintar,
1214
InstallBuiltPackages,
1315
RunPluginMTRSuite,
16+
RunPluginMTRSuiteFromBintar,
1417
)
1518
from configuration.steps.commands.packages import (
1619
InstallDEBPackages,
@@ -179,3 +182,58 @@ def rpm(config: DockerConfig, repo_file_url: str):
179182
)
180183
)
181184
return sequence
185+
186+
187+
_SERVER_BINTAR_PROP = "%(prop:server_bintar_dir)s"
188+
189+
190+
def bintar(config: DockerConfig, ci_bintar_builder: str):
191+
# Bintar images (centos7, almalinux8) have no autobake builder of their
192+
# own to install -devel packages from -- instead, the plugin is built
193+
# against a matching MariaDB server bintar (published by ci_bintar_builder
194+
# on production CI, e.g. "amd64-centos-7-bintar") via -DCMAKE_PREFIX_PATH.
195+
# Testing then means unpacking the plugin's own bintar into that same
196+
# server bintar tree and running its bundled ./mtr, rather than
197+
# installing MariaDB-server/MariaDB-test as system packages.
198+
sequence = BuildSequence()
199+
sequence.add_step(_clone_foundry_step(config))
200+
sequence.add_step(_capture_foundry_revision_step(config))
201+
sequence.add_step(
202+
InContainer(
203+
PropFromShellStep(
204+
command=DownloadServerBintar(ci_bintar_builder),
205+
property="server_bintar_dir",
206+
),
207+
docker_environment=config,
208+
)
209+
)
210+
sequence.add_step(
211+
InContainer(
212+
ShellStep(
213+
command=BuildPlugin(cmake_prefix_path=_SERVER_BINTAR_PROP),
214+
env_vars=_MARIADB_VERSION_ENV,
215+
),
216+
docker_environment=config,
217+
)
218+
)
219+
sequence.add_step(_save_packages_step(config, "mariadb-plugin-*.tar.gz"))
220+
sequence.add_step(
221+
InContainer(
222+
PropFromShellStep(
223+
command=ExtractPluginBintarIntoServerBintar(_SERVER_BINTAR_PROP),
224+
property="plugin_suites",
225+
),
226+
docker_environment=config,
227+
)
228+
)
229+
sequence.add_step(
230+
InContainer(
231+
ShellStep(
232+
command=RunPluginMTRSuiteFromBintar(
233+
_SERVER_BINTAR_PROP, "%(prop:plugin_suites)s"
234+
)
235+
),
236+
docker_environment=config,
237+
)
238+
)
239+
return sequence

configuration/steps/commands/foundry.py

Lines changed: 143 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,36 @@
55

66

77
class BuildPlugin(Command):
8-
# package_type: "RPM" or "DEB" -- the -D flag run.cmake expects.
9-
def __init__(self, package_type: str, workdir: PurePath = PurePath(".")):
8+
# Pass package_type ("RPM" or "DEB") for the -D flag run.cmake expects,
9+
# or cmake_prefix_path (exclusive of package_type) to instead link
10+
# against an unpacked MariaDB server bintar via -DCMAKE_PREFIX_PATH --
11+
# omitting -DRPM/-DDEB entirely is what makes run.cmake produce a plain
12+
# bintar tarball for the plugin instead of a package.
13+
def __init__(
14+
self,
15+
package_type: str = None,
16+
cmake_prefix_path: str = None,
17+
workdir: PurePath = PurePath("."),
18+
):
19+
assert (package_type is None) != (cmake_prefix_path is None), (
20+
"BuildPlugin takes exactly one of package_type or cmake_prefix_path"
21+
)
1022
self.package_type = package_type
11-
super().__init__(name=f"Build plugin ({package_type})", workdir=workdir)
23+
self.cmake_prefix_path = cmake_prefix_path
24+
super().__init__(
25+
name=f"Build plugin ({package_type or 'bintar'})", workdir=workdir
26+
)
1227

1328
def as_cmd_arg(self) -> list[str]:
29+
cmake_define = (
30+
f"-DCMAKE_PREFIX_PATH={self.cmake_prefix_path} "
31+
if self.cmake_prefix_path
32+
else f"-D{self.package_type}=1 "
33+
)
1434
return [
1535
"bash",
1636
"-exc",
17-
util.Interpolate(f"cmake -D{self.package_type}=1 -P run.cmake %(prop:plugin)s"),
37+
util.Interpolate(f"cmake {cmake_define}-P run.cmake %(prop:plugin)s"),
1838
]
1939

2040

@@ -53,6 +73,87 @@ def as_cmd_arg(self) -> list[str]:
5373
return ["bash", "-exc", f"set -euo pipefail\n{script}"]
5474

5575

76+
class DownloadServerBintar(Command):
77+
# Foundry bintar plugin builds link against a matching MariaDB server
78+
# bintar instead of installed -devel packages. ci_builder is the
79+
# production buildbot builder on ci.mariadb.org that publishes it for
80+
# this OS (e.g. "amd64-centos-7-bintar") -- the exact tarball filename
81+
# varies by version/build, so it's discovered from the directory
82+
# listing rather than assumed. Emits the extracted directory's absolute
83+
# path on stdout, for capture into a property (e.g. via
84+
# PropFromShellStep) and use as BuildPlugin's cmake_prefix_path.
85+
def __init__(self, ci_builder: str, workdir: PurePath = PurePath(".")):
86+
self.ci_builder = ci_builder
87+
super().__init__(name="Download server bintar", workdir=workdir)
88+
89+
def as_cmd_arg(self) -> list[str]:
90+
return [
91+
"bash",
92+
"-exc",
93+
util.Interpolate(
94+
f"""
95+
set -euo pipefail
96+
97+
base_url="https://ci.mariadb.org/%(prop:tarbuildnum)s/{self.ci_builder}"
98+
filename=$(curl -fsSL "$base_url/" | grep -oE 'href="mariadb-[^"]*-linux[^"]*\\.tar\\.gz"' | head -1 | sed -E 's/^href="(.*)"$/\\1/')
99+
if [ -z "$filename" ]; then
100+
echo "Could not find a server bintar under $base_url" >&2
101+
exit 1
102+
fi
103+
104+
mkdir -p /home/buildbot/bintar
105+
curl -fsSL "$base_url/$filename" -o "/home/buildbot/bintar/$filename"
106+
tar -xzf "/home/buildbot/bintar/$filename" -C /home/buildbot/bintar
107+
108+
dirname=$(tar -tzf "/home/buildbot/bintar/$filename" | head -1 | cut -d/ -f1)
109+
echo "/home/buildbot/bintar/$dirname"
110+
"""
111+
),
112+
]
113+
114+
115+
class ExtractPluginBintarIntoServerBintar(Command):
116+
# The plugin's own MTR suite is only visible to MTR once its bintar is
117+
# unpacked directly into the server bintar tree it was built against --
118+
# --strip-components=1 drops the plugin tarball's own top-level
119+
# directory so its plugin/<name>/ contents land alongside the server
120+
# bintar's own plugin/, mysql-test/, etc.
121+
#
122+
# The server bintar ships its own bundled plugin suites (rocksdb,
123+
# columnstore, ...) under that same plugin/*/*/suite.pm layout, so once
124+
# extraction is done there's no way to tell "ours" apart from those by
125+
# just re-scanning the merged tree. Emit the suite name(s) contributed
126+
# by *this* plugin's tarball -- read off its own listing, before it gets
127+
# merged in -- on stdout, for capture into a property (e.g. via
128+
# PropFromShellStep) and use as RunPluginMTRSuiteFromBintar's suites arg.
129+
def __init__(self, server_bintar_dir: str, workdir: PurePath = PurePath(".")):
130+
self.server_bintar_dir = server_bintar_dir
131+
super().__init__(
132+
name="Extract plugin bintar into server bintar", workdir=workdir
133+
)
134+
135+
def as_cmd_arg(self) -> list[str]:
136+
return [
137+
"bash",
138+
"-exc",
139+
util.Interpolate(
140+
f"""
141+
set -euo pipefail
142+
143+
suites=""
144+
for f in ./mariadb-plugin-*.tar.gz; do
145+
tar -xf "$f" -C "{self.server_bintar_dir}" --strip-components=1
146+
for name in $(tar -tzf "$f" | grep -oE '^[^/]+/plugin/[^/]+/[^/]+/suite\\.pm$' | awk -F/ '{{print $4}}' || true); do
147+
suites="$suites,$name"
148+
done
149+
done
150+
suites=$(echo "$suites" | sed 's/^,//')
151+
echo "$suites"
152+
"""
153+
),
154+
]
155+
156+
56157
class RunPluginMTRSuite(Command):
57158
# MARIADB_ADD_PLUGIN's INSTALL_MYSQL_TEST (cmake/plugin.cmake) installs
58159
# a plugin's mysql-test suite(s) under <mtr_base_dir>/plugin/<X>/<name>/,
@@ -111,3 +212,41 @@ def as_cmd_arg(self) -> list[str]:
111212
"""
112213
),
113214
]
215+
216+
217+
class RunPluginMTRSuiteFromBintar(Command):
218+
# Runs the suite(s) contributed by the plugin we just built and unpacked
219+
# into a server bintar tree. Unlike RunPluginMTRSuite, suites isn't
220+
# (re)discovered here -- the server bintar bundles its own plugin
221+
# suites (rocksdb, columnstore, ...) under the same plugin/*/*/suite.pm
222+
# layout, so re-scanning the merged tree can't tell those apart from
223+
# ours. Instead suites comes straight from
224+
# ExtractPluginBintarIntoServerBintar, which read it off the plugin's
225+
# own tarball listing before merging. mariadb-test-run.pl (wrapped by
226+
# ./mtr) lives at a known path inside the tree, so there's no package
227+
# manager to query either.
228+
def __init__(
229+
self, server_bintar_dir: str, suites: str, workdir: PurePath = PurePath(".")
230+
):
231+
self.server_bintar_dir = server_bintar_dir
232+
self.suites = suites
233+
super().__init__(name="Run plugin MTR suite", workdir=workdir)
234+
235+
def as_cmd_arg(self) -> list[str]:
236+
return [
237+
"bash",
238+
"-exc",
239+
util.Interpolate(
240+
f"""
241+
set -euo pipefail
242+
243+
suites="{self.suites}"
244+
if [ -z "$suites" ]; then
245+
echo "No MTR suite found for plugin %(prop:plugin)s -- skipping"
246+
exit 0
247+
fi
248+
249+
cd "{self.server_bintar_dir}/mariadb-test" && ./mtr --force --max-test-fail=20 --suite="$suites"
250+
"""
251+
),
252+
]

0 commit comments

Comments
 (0)