Skip to content

Commit a2c0198

Browse files
authored
Generates TLS certificates dynamically in CI (#505)
close #500
1 parent 6fcb24c commit a2c0198

16 files changed

Lines changed: 302 additions & 225 deletions

File tree

.drone.star

Lines changed: 101 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ def _find_package_b2_command(source_dir, generator):
7575
'--generator="{}" '.format(generator)
7676

7777

78+
def _make_entrypoint(db):
79+
if db.startswith('mysql:'):
80+
# MySQL generic. Sanitize UNIX socket permissions and launch the server with the adequate TLS files
81+
res = "chown -R mysql:mysql /var/run/mysqld && /usr/local/bin/docker-entrypoint.sh mysqld " + \
82+
"--ssl-ca=/tls/ca-cert.pem " + \
83+
"--ssl-cert=/tls/server-cert.pem " + \
84+
"--ssl-key=/tls/server-key.pem "
85+
if db.startswith('mysql:8.'):
86+
# v8.x needs this flag to enable mysql_native_password
87+
res += "--mysql-native-password=ON"
88+
else:
89+
# MariaDB changed the default socket path, so we provide it explicitly
90+
res = "chown -R mysql:mysql /var/run/mysqld && /usr/local/bin/docker-entrypoint.sh mariadbd " + \
91+
"--ssl-ca=/tls/ca-cert.pem " + \
92+
"--ssl-cert=/tls/server-cert.pem " + \
93+
"--ssl-key=/tls/server-key.pem " + \
94+
"--socket=/var/run/mysqld/mysqld.sock"
95+
96+
return res
97+
98+
7899
def _pipeline(
79100
name,
80101
image,
@@ -85,6 +106,20 @@ def _pipeline(
85106
disable_aslr=False
86107
):
87108
steps = []
109+
110+
# Volumes, common to all steps
111+
volumes = [
112+
{
113+
"name": "mysql-socket",
114+
"path": "/var/run/mysqld"
115+
},
116+
{
117+
"name": "tls-certificates",
118+
"path": "/tls"
119+
}
120+
] if db != None else []
121+
122+
# Disable ASLR
88123
if disable_aslr:
89124
steps.append({
90125
"name": "Disable ASLR",
@@ -93,15 +128,60 @@ def _pipeline(
93128
"privileged": True,
94129
"commands": ["echo 0 | tee /proc/sys/kernel/randomize_va_space"]
95130
})
131+
132+
# Set up the database and certificates
133+
cert_dir = "C:\\\\ssl\\\\" if os == "windows" else "/tls/"
134+
if os == "windows":
135+
# Generate certificates
136+
steps.append({
137+
"name": "Generate certificates",
138+
"image": image,
139+
"pull": "if-not-exists",
140+
"commands": [
141+
"python tools/ci/gen-certificates.py {}".format(cert_dir)
142+
]
143+
})
144+
145+
elif db != None:
146+
# Generate certificates
147+
steps.append({
148+
"name": "Generate certificates",
149+
"image": image,
150+
"pull": "if-not-exists",
151+
"volumes": volumes,
152+
"commands": [
153+
"python tools/ci/gen-certificates.py {}".format(cert_dir)
154+
]
155+
})
156+
157+
# Database step
158+
steps.append({
159+
"name": "mysql",
160+
"image": db,
161+
"pull": "if-not-exists",
162+
"detach": True,
163+
"environment": {
164+
"MYSQL_ALLOW_EMPTY_PASSWORD": "1",
165+
"MYSQL_ROOT_PASSWORD": ""
166+
},
167+
"entrypoint": [
168+
"/bin/bash",
169+
"-c",
170+
_make_entrypoint(db)
171+
],
172+
"volumes": volumes
173+
})
174+
175+
# Run the build
96176
steps.append({
97177
"name": "Build and run",
98178
"image": image,
99179
"pull": "if-not-exists",
100180
"privileged": arch == "arm64", # TSAN tests fail otherwise (personality syscall)
101-
"volumes":[{
102-
"name": "mysql-socket",
103-
"path": "/var/run/mysqld"
104-
}] if db != None else [],
181+
"volumes": volumes,
182+
"environment": {
183+
"BOOST_MYSQL_CA_CERTIFICATE": cert_dir + "ca-cert.pem"
184+
},
105185
"commands": [command]
106186
})
107187

@@ -119,18 +199,16 @@ def _pipeline(
119199
},
120200
"node": {},
121201
"steps": steps,
122-
"services": [{
123-
"name": "mysql",
124-
"image": "ghcr.io/anarthal/cpp-ci-containers/{}".format(db),
125-
"volumes": [{
202+
"volumes": [
203+
{
126204
"name": "mysql-socket",
127-
"path": "/var/run/mysqld"
128-
}]
129-
}] if db != None else [],
130-
"volumes": [{
131-
"name": "mysql-socket",
132-
"temp": {}
133-
}] if db != None else []
205+
"temp": {}
206+
},
207+
{
208+
"name": "tls-certificates",
209+
"temp": {}
210+
}
211+
]
134212
}
135213

136214

@@ -149,7 +227,7 @@ def linux_b2(
149227
valgrind=0,
150228
arch='amd64',
151229
fail_if_no_openssl=1,
152-
db='mysql-8_4_1:1',
230+
db='mysql:8.4.1',
153231
):
154232
command = _b2_command(
155233
source_dir='$(pwd)',
@@ -201,7 +279,7 @@ def windows_b2(
201279
def linux_cmake(
202280
name,
203281
image,
204-
db='mysql-8_4_1:1',
282+
db='mysql:8.4.1',
205283
build_shared_libs=0,
206284
cmake_build_type='Debug',
207285
cxxstd='20',
@@ -270,7 +348,7 @@ def bench(name):
270348
'--server-host=mysql ' + \
271349
'--connection-pool-iters=1 ' + \
272350
'--protocol-iters=1 '
273-
return _pipeline(name=name, image=_image('build-bench:1'), os='linux', command=command, db='mysql-8_4_1:1')
351+
return _pipeline(name=name, image=_image('build-bench:1'), os='linux', command=command, db='mysql:8.4.1')
274352

275353

276354
def docs(name):
@@ -286,8 +364,8 @@ def docs(name):
286364
def main(ctx):
287365
return [
288366
# CMake Linux
289-
linux_cmake('Linux CMake MySQL 5.x', _image('build-gcc14:1'), db='mysql-5_7_41:1', build_shared_libs=0),
290-
linux_cmake('Linux CMake MariaDB', _image('build-gcc14:1'), db='mariadb-11_4_2:1', build_shared_libs=1),
367+
linux_cmake('Linux CMake MySQL 5.x', _image('build-gcc14:1'), db='mysql:5.7.41', build_shared_libs=0),
368+
linux_cmake('Linux CMake MariaDB', _image('build-gcc14:1'), db='mariadb:11.4.2', build_shared_libs=1),
291369
linux_cmake('Linux CMake cmake 3.8', _image('build-cmake3_8:3'), cxxstd='11', install_test=0),
292370
linux_cmake('Linux CMake gcc Release', _image('build-gcc14:1'), cmake_build_type='Release'),
293371
linux_cmake('Linux CMake gcc MinSizeRel', _image('build-gcc14:1'), cmake_build_type='MinSizeRel'),
@@ -311,14 +389,14 @@ def main(ctx):
311389
# Ubuntu 24.04: gcc13, clang 18
312390
linux_b2('Linux B2 clang-4', _image('build-clang4:1'), toolset='clang-4', cxxstd='14'),
313391
linux_b2('Linux B2 clang-5-honly-dbg', _image('build-clang5:1'), toolset='clang-5', cxxstd='14', separate_compilation=0),
314-
linux_b2('Linux B2 clang-6', _image('build-clang5:1'), toolset='clang-5', cxxstd='14'),
392+
linux_b2('Linux B2 clang-6', _image('build-clang6:1'), toolset='clang-6', cxxstd='14'),
315393
linux_b2('Linux B2 clang-7', _image('build-clang7:2'), toolset='clang-7', cxxstd='14,17'),
316394
linux_b2('Linux B2 clang-8', _image('build-clang8:2'), toolset='clang-8', cxxstd='14', variant='debug', address_sanitizer=1, undefined_sanitizer=1),
317395
linux_b2('Linux B2 clang-9', _image('build-clang9:2'), toolset='clang-9', cxxstd='17', variant='release'),
318396
linux_b2('Linux B2 clang-10', _image('build-clang10:2'), toolset='clang-10', cxxstd='17,20', variant='debug'),
319397
linux_b2('Linux B2 clang-11', _image('build-clang11:2'), toolset='clang-11', cxxstd='20'),
320398
linux_b2('Linux B2 clang-12', _image('build-clang12:2'), toolset='clang-12', cxxstd='20', variant='debug', stdlib='libc++', address_sanitizer=1, undefined_sanitizer=1),
321-
linux_b2('Linux B2 clang-13', _image('build-clang13:1'), toolset='clang-13', cxxstd='20', db='mysql-9_4_0:1'),
399+
linux_b2('Linux B2 clang-13', _image('build-clang13:1'), toolset='clang-13', cxxstd='20', db='mysql:9.4.0'),
322400
linux_b2('Linux B2 clang-14', _image('build-clang14:1'), toolset='clang-14', cxxstd='20', variant='debug'),
323401
linux_b2('Linux B2 clang-15', _image('build-clang15:1'), toolset='clang-15', cxxstd='20', variant='debug'),
324402
linux_b2('Linux B2 clang-16', _image('build-clang16:1'), toolset='clang-16', cxxstd='20', variant='debug', address_sanitizer=1, undefined_sanitizer=1),
@@ -338,7 +416,7 @@ def main(ctx):
338416
linux_b2('Linux B2 gcc-10', _image('build-gcc10:1'), toolset='gcc-10', cxxstd='17'),
339417
linux_b2('Linux B2 gcc-11', _image('build-gcc11:1'), toolset='gcc-11', cxxstd='20'),
340418
linux_b2('Linux B2 gcc-12', _image('build-gcc12:1'), toolset='gcc-12', cxxstd='20,23', variant='debug'),
341-
linux_b2('Linux B2 gcc-13', _image('build-gcc13:1'), toolset='gcc-13', cxxstd='20', db='mysql-9_4_0:1'),
419+
linux_b2('Linux B2 gcc-13', _image('build-gcc13:1'), toolset='gcc-13', cxxstd='20', db='mysql:9.4.0'),
342420
linux_b2('Linux B2 gcc-14', _image('build-gcc14:1'), toolset='gcc-14', cxxstd='23'),
343421
linux_b2('Linux B2 gcc-15', _image('build-gcc15:1'), toolset='gcc-15', cxxstd='23'),
344422
linux_b2('Linux B2 gcc-sanit', _image('build-gcc14:1'), toolset='gcc-14', cxxstd='23', variant='debug', address_sanitizer=1, undefined_sanitizer=1),

.github/workflows/build-code.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ name: Build
1010
on:
1111
push:
1212
branches: [develop, master]
13-
tags: ['*']
13+
tags: ["*"]
1414
pull_request:
1515
workflow_dispatch:
1616

17-
1817
jobs:
1918
osx:
2019
runs-on: macos-latest
2120
steps:
22-
- uses: actions/checkout@v4
21+
- uses: actions/checkout@v6
2322
- run: |
2423
unlink /usr/local/bin/python || echo "/usr/local/bin/python not found"
2524
ln -s /usr/local/bin/python3 /usr/local/bin/python

.github/workflows/coverage.yml

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,26 @@ on:
1717
jobs:
1818
coverage:
1919
runs-on: ubuntu-latest
20-
container:
21-
image: ghcr.io/anarthal/cpp-ci-containers/build-gcc14-lcov:1
22-
volumes:
23-
- /var/run/mysqld:/var/run/mysqld
24-
services:
25-
mysql:
26-
image: ghcr.io/anarthal/cpp-ci-containers/mysql-8_4_1:1
27-
ports:
28-
- 3306:3306
29-
volumes:
30-
- /var/run/mysqld:/var/run/mysqld
3120
steps:
3221
- name: Fetch code
33-
uses: actions/checkout@v4
22+
uses: actions/checkout@v6
23+
24+
- name: Generate certificates
25+
run: python tools/ci/gen-certificates.py /tmp/mysql-tls
26+
27+
- name: Start containers
28+
uses: hoverkraft-tech/compose-action@v2.6.0
29+
with:
30+
compose-file: ./tools/ci/docker-compose.yml
31+
env:
32+
BUILDER_IMAGE: ghcr.io/anarthal/cpp-ci-containers/build-gcc14-lcov:1
3433

3534
- name: Build code
3635
run: |
37-
python tools/ci/main.py \
38-
--source-dir=$(pwd) \
36+
docker exec builder python /boost-mysql/tools/ci/main.py \
37+
--source-dir=/boost-mysql \
3938
b2 \
40-
--server-host=mysql \
39+
--server-host=localhost \
4140
--toolset=gcc \
4241
--cxxstd=20 \
4342
--variant=debug \
@@ -47,29 +46,29 @@ jobs:
4746
- name: Generate coverage reports
4847
shell: bash
4948
run: |
50-
cd ~/boost-root/bin.v2
51-
lcov \
49+
docker exec builder lcov \
5250
--rc branch_coverage=0 \
5351
--rc geninfo_unexecuted_blocks=1 \
5452
--ignore-errors mismatch \
5553
--gcov-tool gcov-14 \
56-
--directory . \
54+
--directory /root/boost-root/bin.v2 \
5755
--capture \
5856
--output-file all.info
59-
lcov \
57+
docker exec builder lcov \
6058
--rc branch_coverage=0 \
6159
--output-file coverage.info \
6260
--extract all.info '*/boost/mysql*'
63-
sed "s|^SF:$HOME/boost-root/|SF:include/|g" coverage.info > $GITHUB_WORKSPACE/coverage.info
61+
docker exec builder sed -i "s|^SF:/root/boost-root/|SF:include/|g" coverage.info
62+
docker exec builder mv coverage.info /boost-mysql/coverage.info
6463
6564
- name: Upload coverage reports
66-
uses: codecov/codecov-action@v4
65+
uses: codecov/codecov-action@v6
6766
with:
6867
verbose: true
6968
fail_ci_if_error: true
7069
token: ${{ secrets.CODECOV_TOKEN }}
7170
plugins: noop # Don't run gcov again, codecov doesn't know about the filtering we perform
72-
file: coverage.info
71+
files: coverage.info
7372
disable_search: true # Don't upload unwanted files
7473
disable_file_fixes: true # Default fixes make reports unusable
7574

.github/workflows/fuzz.yml

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ name: fuzz
1010
on:
1111
push:
1212
branches: [develop, master]
13-
tags: ['*']
13+
tags: ["*"]
1414
pull_request:
1515
workflow_dispatch:
1616
schedule:
@@ -19,43 +19,46 @@ on:
1919
jobs:
2020
fuzz:
2121
runs-on: ubuntu-latest
22-
container:
23-
image: ghcr.io/anarthal/cpp-ci-containers/build-clang18:1
24-
volumes:
25-
- /var/run/mysqld:/var/run/mysqld
26-
services:
27-
mysql:
28-
image: ghcr.io/anarthal/cpp-ci-containers/mysql-8_4_1:1
29-
ports:
30-
- 3306:3306
31-
volumes:
32-
- /var/run/mysqld:/var/run/mysqld
3322
steps:
3423
- name: Fetch code
35-
uses: actions/checkout@v4
24+
uses: actions/checkout@v6
25+
26+
- name: Generate certificates
27+
run: python tools/ci/gen-certificates.py /tmp/mysql-tls
28+
29+
- name: Start containers
30+
uses: hoverkraft-tech/compose-action@v2.6.0
31+
with:
32+
compose-file: ./tools/ci/docker-compose.yml
33+
env:
34+
BUILDER_IMAGE: ghcr.io/anarthal/cpp-ci-containers/build-clang18:1
3635

3736
- name: Restore corpus
38-
uses: actions/cache@v4
37+
uses: actions/cache@v5
3938
with:
4039
path: /tmp/corpus.tar.gz
4140
key: corpus-${{ github.run_id }}
4241
restore-keys: corpus-
43-
42+
4443
# Note: this will take care of using the corpus and updating it
4544
- name: Build and run the fuzzer
4645
run: |
47-
python tools/ci/main.py \
48-
--source-dir=$(pwd) \
49-
fuzz \
50-
--server-host=mysql
46+
docker exec builder python /boost-mysql/tools/ci/main.py \
47+
--source-dir=/boost-mysql \
48+
fuzz
49+
50+
- name: Copy crashes from container
51+
if: always()
52+
run: |
53+
docker exec builder bash -c 'cp /root/boost-root/crash-* /root/boost-root/leak-* /root/boost-root/timeout-* /boost-mysql/ || true'
5154
5255
- name: Archive any crashes as an artifact
53-
uses: actions/upload-artifact@v4
56+
uses: actions/upload-artifact@v7
5457
if: always()
5558
with:
5659
name: crashes
5760
path: |
58-
~/boost-root/crash-*
59-
~/boost-root/leak-*
60-
~/boost-root/timeout-*
61+
crash-*
62+
leak-*
63+
timeout-*
6164
if-no-files-found: ignore

0 commit comments

Comments
 (0)