Skip to content

Commit ae4afb6

Browse files
authored
Merge pull request #157 from movabletype/multi_platform
Multi platform
2 parents f32360c + 0fb39d3 commit ae4afb6

43 files changed

Lines changed: 405 additions & 571 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,45 @@ Dockerfile to test MT.
1010
|image name|base image|Perl|PHP|MySQL|OpenSSL|End of Life|
1111
|-|-|-|-|-|-|-|
1212
|centos7|centos:7|5.16.3|*7.1.33*|*MariaDB 5.5.68*|1.0.2k|2024-06|
13-
|buster|debian:buster-slim|*5.28.1*|*7.3.31*|*MariaDB 10.3.39*|1.1.1n|2022-01|
1413
|bullseye|debian:bullseye-slim|*5.32.1*|*7.4.33*|*MariaDB 10.5.28*|1.1.1w|2024-08|
1514
|fedora35|fedora:35|*5.34.1*|*8.0.26*|8.0.31|1.1.1q|2022-12|
1615
|fedora37|fedora:37|*5.36.1*|*8.1.25*|*8.0.35*|3.0.9|2023-12|
17-
|fedora40|fedora:40|5.38.4|*8.2.29*|*MariaDB 10.11.11*|3.2.4|-|
16+
|fedora40|fedora:40|*5.38.4*|*8.2.29*|*MariaDB 10.11.11*|3.2.4|-|
1817
|fedora42|fedora:42|*5.40.3*|*8.4.16*|*9.5.0*|3.2.6|-|
1918
|fedora43|fedora:43|*5.42.0*|8.4.16|*8.4.7*|3.5.4|-|
20-
|cloud6 (\*1)|centos:7|*5.28.2*|*7.4.33*|*5.7.44*|1.0.2k|-|
2119
|cloud7 (\*1)|rockylinux/rockylinux:9|*5.38.2*|*8.3.29*|MariaDB 10.5.27|3.5.1|-|
2220

23-
\*1 These images are not used in the MT cloud, but the well-known modules should have the same version (except for those used only in tests).
21+
\*1 This image is not used in the MT cloud, but the well-known modules should have the same versions (except for those used only in tests).
22+
23+
## Environment list (multi platforms, suitable for mt-dev)
24+
25+
|image name|base image|Perl|PHP|MySQL|OpenSSL|End of Life|
26+
|-|-|-|-|-|-|-|
27+
|noble|ubuntu:noble|5.38.2|8.3.6|8.4.7|3.0.13|-|
28+
|plucky|ubuntu:plucky|5.40.1|8.4.5|8.4.7|3.4.1|-|
29+
|questing|ubuntu:questing|5.42.0|8.4.11|8.4.7|3.5.3|-|
2430

2531
## Environment list (only for manual testing)
2632

2733
|image name|base image|Perl|PHP|MySQL|OpenSSL|End of Life|
2834
|-|-|-|-|-|-|-|
35+
|buster (\*2)|debian:buster-slim|*5.28.1*|*7.3.31*|*MariaDB 10.3.39*|1.1.1n|2022-01|
2936
|centos6 (\*2)|centos:6|*5.10.1*|*5.3.3*|*5.1.73*|1.0.1e|2020-11|
3037
|centos8|centos:8|5.26.3|8.0.30|8.0.26|1.1.1k|2021-12|
31-
|fedora32 (\*2)|fedora:32|5.30.3|7.4.19|8.0.24|1.1.1k|2021-05|
3238
|fedora39 (\*2)|fedora:39|5.38.2|8.2.25|8.0.39|3.1.4|2024-11|
3339
|fedora41 (\*2)|fedora:41|5.40.3|8.3.27|8.4.7|3.2.6|-|
3440
|rawhide|fedora:rawhide|5.42.0|8.5.1|8.4.7|3.5.4|-|
3541
|rockylinux|rockylinux/rockylinux:9|5.32.1|8.1.34|8.0.44|3.5.1|-|
3642
|bookworm|debian:bookworm-slim|5.36.0|8.2.29|MariaDB 10.11.14|3.0.17|2028-06|
3743
|sid|debian:sid|5.40.1|8.4.16|MariaDB 11.8.5|3.5.4|-|
38-
|noble|ubuntu:noble|5.38.2|8.3.6|8.4.7|3.0.13|-|
3944
|amazonlinux|amazonlinux:2|5.16.3|7.4.33|MariaDB 5.5.68|1.0.2k|-|
40-
|amazonlinux2023 (\*4)|amazonlinux:2023|5.32.1|8.4.14|MariaDB 10.11.13|3.2.2|-|
45+
|amazonlinux2023|amazonlinux:2023|5.32.1|8.4.14|MariaDB 10.11.13|3.2.2|-|
4146
|postgresql|fedora:41|5.40.3|8.3.27|Postgres 16.11|3.2.6|-|
4247
|oracle (\*3)|oraclelinux:9-slim|5.32.1|8.3.29|MariaDB 10.5.29|3.5.1|-|
4348
|oracle8 (\*3)|oraclelinux:8-slim|5.26.3|8.2.30|MariaDB 10.3.39|1.1.1k|-|
4449

4550
\*2 These images were used to test older versions of MT.
4651
\*3 with DBD::Oracle 1.80 + OracleInstantClient 26
47-
\*4 This image currently lacks php-dom, thus phpunit
4852

4953
## Special images
5054

@@ -60,8 +64,32 @@ Dockerfile to test MT.
6064
$ perl bin/update_dockerfile.pl
6165
$ perl bin/build_all.pl (with or without --no-cache)
6266
$ perl bin/check_all.pl
67+
$ perl bin/test_workflows.pl
6368
$ perl bin/test_readme.pl
64-
$ perl bin/push_all.pl
69+
$ perl bin/build_all.pl --push
6570
6671
then, make a pull request, review, and merge it to mirror the uploaded images.
6772
```
73+
74+
## Multi-platform build
75+
76+
See https://docs.docker.com/build/building/multi-platform/ for details.
77+
If you do not use Docker Build Cloud, then prepare a remote environment with
78+
a different architecture from your local environment. You'll need to add your
79+
remote USER to the docker group and make sure remote dockerd is running.
80+
Create your builder. The following uses local amd64 and remote arm64, but
81+
you may do differently.
82+
83+
```
84+
$ docker buildx create --name my_builder --node amd64 --platform linux/amd64
85+
$ docker buildx create --name my_builder --append --node arm64 --platform linux/arm64 ssh://USER@HOST
86+
```
87+
88+
Then specify your builder to build. Only a few images support multi-platform build right now.
89+
90+
```
91+
$ perl bin/build_all.pl --builder my_builder
92+
$ perl bin/build_all.pl --builder my_builder --push
93+
94+
push_all.pl doesn't work well for multi-platform images.
95+
```

amazonlinux/docker-entrypoint.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22
set -e
33

4+
45
mysql_install_db --user=mysql --skip-name-resolve --force >/dev/null
56

67
bash -c "cd /usr; mysqld_safe --user=mysql --datadir=/var/lib/mysql &"

amazonlinux2023/docker-entrypoint.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22
set -e
33

4+
45
mysql_install_db --user=mysql --skip-name-resolve --force >/dev/null
56

67
bash -c "cd /usr; mysqld_safe --user=mysql --datadir=/var/lib/mysql &"

bin/build_all.pl

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,18 @@
88
use Mojo::File qw/path/;
99

1010
GetOptions(
11+
'builder=s' => \my $builder,
12+
'push' => \my $push,
1113
'no_cache|no-cache' => \my $no_cache,
1214
'workers=i' => \my $workers,
1315
'errored|errored_only|errored-only' => \my $errored_only,
1416
);
1517

1618
my %aliases = qw(
17-
fedora fedora32
18-
1919
perl-5.16 centos7
20-
perl-5.28 buster
21-
perl-5.30 fedora32
22-
perl-5.32 bullseye
23-
perl-5.34 fedora35
24-
perl-5.36 fedora37
25-
perl-5.38 fedora39
26-
perl-5.40 fedora41
27-
perl-5.42 fedora43
20+
perl-5.38 noble
21+
perl-5.40 plucky
22+
perl-5.42 questing
2823
2924
php-7.3 buster
3025
php-7.4 fedora32
@@ -36,6 +31,8 @@
3631
);
3732
my %aliases_rev;
3833

34+
my %multi_platform = map {$_ => 1} qw( noble plucky questing );
35+
3936
while (my ($alias, $name) = each %aliases) {
4037
$aliases_rev{$name} ||= [];
4138
push @{ $aliases_rev{$name} }, $alias;
@@ -55,10 +52,34 @@
5552
}
5653
my $dockerfile = path("$name/Dockerfile")->slurp;
5754
my ($from) = $dockerfile =~ /^FROM (\S+)/;
58-
system("docker pull $from");
59-
system("docker build $name $tags" . ($no_cache ? " --no-cache" : "") . " 2>&1 | tee log/build_$name.log");
55+
system("docker pull $from") if $no_cache;
56+
if ($builder && $multi_platform{$name}) {
57+
system("docker buildx build --builder $builder --platform linux/amd64,linux/arm64 $name $tags --output=type=image" . ($no_cache ? " --no-cache" : "") . ($push ? " --push" : "") . " 2>&1 | tee log/build_$name.log");
58+
} else {
59+
if ($push) {
60+
if ($multi_platform{$name}) {
61+
say "$name requires multi-platform build to push";
62+
} else {
63+
my $id = `docker images movabletype/test:$name --no-trunc --format '{{.ID}}'`;
64+
chomp $id;
65+
die "Image not found: $name" unless $id;
66+
67+
say "$name : $id";
68+
69+
my @tags = map { s/ .*//r }
70+
grep { /$id/ }
71+
split /\n/, `docker images -f 'reference=movabletype/test:*' --no-trunc --format '{{.Tag}} {{.ID}}'`;
72+
73+
for my $tag (@tags) {
74+
system("docker push movabletype/test:$tag");
75+
}
76+
}
77+
} else {
78+
system("docker build $name $tags" . ($no_cache ? " --no-cache" : "") . " 2>&1 | tee log/build_$name.log");
79+
}
80+
}
6081
my $log = path("log/build_$name.log")->slurp;
61-
if ($log =~ m!(naming to docker.io/movabletype/test:$name (\S+ )?done|Successfully built)!) {
82+
if ($log =~ m!(naming to docker.io/movabletype/test:$name (\S+ )?done|Successfully built|exporting manifest list .* done)!) {
6283
if ($log =~ /No package (.+) available/) {
6384
rename "log/build_$name.log" => "log/build_warn_$name.log";
6485
} else {

bin/check_all.pl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
next if (my $conf = $dockerfile->slurp) =~ /EXPOSE/;
2727
my $id = substr(md5_hex($conf), 0, 7);
2828
diag "testing $name";
29-
my $res = eval { !system("docker run -it --rm -v\$PWD:/mt -w /mt --entrypoint '' movabletype/test:$name bash -c 'TEST_IMAGE=$name prove -lv bin/checker.t' 2>&1 | tee log/check_$name.log"); };
29+
my $res = eval { !system("docker run -it --rm -v\$PWD:/mt -w /mt --entrypoint '' movabletype/test:$name bash -c 'source ~/.bash_profile; TEST_IMAGE=$name prove -lv bin/checker.t' 2>&1 | tee log/check_$name.log"); };
3030
my ($has_ok, $has_fail, $has_todo) = (0, 0, 0);
3131
if ($res) {
3232
my $log = path("log/check_$name.log")->slurp;
@@ -78,6 +78,6 @@
7878
$message = colored(['red'], $message) if $fail || !$ok;
7979
diag $message;
8080
}
81-
diag $_ for @errors;
81+
diag colored([/# TODO/ ? 'yellow' : 'red'], $_) for @errors;
8282

8383
system('docker system prune -f');

bin/checker.t

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ ok !grep(/\.(?:cpanm|perl-cpm)/, @files), "$image_name: no cpanm|cpm directories
3636
my $entrypoint_is_executed;
3737
if (-e '/docker-entrypoint.sh' && $image_name !~ /chromedriver/) {
3838
my $entrypoint_sh = do { open my $fh, '<', '/docker-entrypoint.sh'; local $/; <$fh> };
39-
if ($entrypoint_sh =~ /mysql/ && $image_name !~ /(?:fedora23|postgresql)/) {
39+
if ($entrypoint_sh =~ /mysql/ && $image_name !~ /(?:postgresql)/) {
4040
my $entrypoint = `/docker-entrypoint.sh`;
4141
note $entrypoint;
4242
$entrypoint_is_executed = 1;
@@ -116,7 +116,7 @@ ok $imagemagick_supports{png}, "$image_name: ImageMagick supports PNG";
116116
ok $imagemagick_supports{jpeg}, "$image_name: ImageMagick supports JPEG";
117117
ok $imagemagick_supports{bmp}, "$image_name: ImageMagick supports BMP";
118118
SKIP: {
119-
local $TODO = 'WebP may not be supported' if $image_name =~ /^(?:amazonlinux|bionic|centos6|centos7|jessie|oracle|stretch|trusty)$/;
119+
local $TODO = 'WebP may not be supported' if $image_name =~ /^(?:amazonlinux|centos7|oracle)$/;
120120
ok $imagemagick_supports{webp}, "$image_name: ImageMagick supports WebP";
121121
}
122122
SKIP: {
@@ -131,19 +131,13 @@ ok $graphicsmagick_supports{gif}, "$image_name: GraphicsMagick supports GIF";
131131
ok $graphicsmagick_supports{png}, "$image_name: GraphicsMagick supports PNG";
132132
ok $graphicsmagick_supports{jpeg}, "$image_name: GraphicsMagick supports JPEG";
133133
ok $graphicsmagick_supports{bmp}, "$image_name: GraphicsMagick supports BMP";
134-
SKIP: {
135-
local $TODO = 'WebP may not be supported' if $image_name =~ /centos6|jessie|trusty/;
136-
ok $graphicsmagick_supports{webp}, "$image_name: GraphicsMagick supports WebP";
137-
}
134+
ok $graphicsmagick_supports{webp}, "$image_name: GraphicsMagick supports WebP";
138135
SKIP: {
139136
local $TODO = 'AVIF may not be supported';
140137
ok $graphicsmagick_supports{avif}, "$image_name: GraphicsMagick supports AVIF";
141138
}
142-
SKIP: {
143-
local $TODO = 'may be 8' if $image_name =~ /centos6|jessie|trusty/;
144-
my $graphicsmagick_depth = Graphics::Magick->new->Get('depth');
145-
is $graphicsmagick_depth => '16', "$image_name: GraphicsMagick Quantum Depth: Q$graphicsmagick_depth";
146-
}
139+
my $graphicsmagick_depth = Graphics::Magick->new->Get('depth');
140+
is $graphicsmagick_depth => '16', "$image_name: GraphicsMagick Quantum Depth: Q$graphicsmagick_depth";
147141
my ($has_identify) = `which identify`;
148142
ok $has_identify, "has identify";
149143
my ($has_convert) = `which convert`;
@@ -167,18 +161,12 @@ if ($image_name eq 'postgresql') {
167161
ok $phpinfo =~ /PDO drivers => .*?mysql/, "$image_name: PHP has PDO mysql driver";
168162
}
169163
ok $phpinfo =~ /GD Support => enabled/, "$image_name: PHP has GD";
170-
SKIP: {
171-
local $TODO = 'php for CentOS6 does not support DOM/XML' if $image_name =~ /centos6/;
172-
ok $phpinfo =~ /DOM.XML => enabled/, "$image_name: PHP has DOM/XML";
173-
}
164+
ok $phpinfo =~ /DOM.XML => enabled/, "$image_name: PHP has DOM/XML";
174165
ok $phpinfo =~ /GIF Read Support => enabled/, "$image_name: PHP supports GIF read";
175166
ok $phpinfo =~ /GIF Create Support => enabled/, "$image_name: PHP supports GIF create";
176167
ok $phpinfo =~ /JPEG Support => enabled/, "$image_name: PHP supports JPEG";
177168
ok $phpinfo =~ /PNG Support => enabled/, "$image_name: PHP supports PNG";
178-
SKIP: {
179-
local $TODO = 'php for CentOS6 does not support WebP' if $image_name =~ /centos6/;
180-
ok $phpinfo =~ /WebP Support => enabled/, "$image_name: PHP supports WebP";
181-
}
169+
ok $phpinfo =~ /WebP Support => enabled/, "$image_name: PHP supports WebP";
182170
SKIP: {
183171
local $TODO = 'Memcache may not be supported' if $image_name =~ /amazonlinux|oracle|centos8/;
184172
ok $phpinfo =~ /memcache support => enabled/, "$image_name: PHP supports memcache";
@@ -284,11 +272,8 @@ ok $mailpit, "$image_name: has mailpit $mailpit";
284272

285273
my (@icc_profiles) = (`find /usr/share | grep '.icc\$'` // '') =~ /(\w+\.icc)$/gm;
286274
my $srgb = grep /\bsRGB\.icc$/i, @icc_profiles;
287-
SKIP: {
288-
local $TODO = 'CentOS 6 has no icc profile packages' if $image_name =~ /centos6/;
289-
ok @icc_profiles, "$image_name: has " . join(",", @icc_profiles);
290-
ok $srgb, "$image_name: has sRGB.icc";
291-
}
275+
ok @icc_profiles, "$image_name: has " . join(",", @icc_profiles);
276+
ok $srgb, "$image_name: has sRGB.icc";
292277

293278
if ($image_name =~ /oracle/) {
294279
my ($sqlplus_version) = (`sqlplus -v`) =~ /^Version (\d+\.\d+)/m;

bin/push_all.pl

Lines changed: 0 additions & 25 deletions
This file was deleted.

bin/test_readme.pl

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,23 @@
22
use warnings;
33
use Test::More;
44
use Mojo::File qw/path/;
5-
use Data::Dump qw/dump/;
5+
use YAML;
66

77
my %mapping;
8+
my $phase;
89
for my $line (split /\n/, path('README.md')->slurp) {
10+
if ($line =~ /^## .*for CI/) {
11+
$phase = 'ci';
12+
}
13+
if ($line =~ /^## .*multi platforms/) {
14+
$phase = 'multi';
15+
}
16+
if ($line =~ /^## .*manual testing/) {
17+
$phase = 'manual';
18+
}
19+
if ($line =~ /^## Special images/) {
20+
$phase = 'special';
21+
}
922
next unless $line =~ /^\|/;
1023
next if $line =~ /^\|(?:\-|image name)/;
1124
$line =~ s/(^\|)|(\|$)//g;
@@ -18,12 +31,19 @@
1831
$mapping{$image} = { map { split / /, $_ } @extra };
1932
} else {
2033
my ($perl, $php, $mysql, $openssl) = @rest;
34+
my $ci = $phase eq 'ci' ? 1 : $image =~ /\(\\2\)/ ? 2 : 0;
2135
$image =~ s/ .+$//;
2236
$mapping{$image} = { perl => $perl, php => $php, mysql => $mysql, openssl => $openssl };
37+
$mapping{$image}{ci} = $ci if $ci;
2338
}
2439
$mapping{$image}{base} = $base;
2540
}
2641

42+
my $used = {};
43+
if (-e './tmp/used_images.yml') {
44+
$used = YAML::LoadFile('./tmp/used_images.yml');
45+
}
46+
2747
for my $image (sort keys %mapping) {
2848
my $logfile = "log/check_$image.log";
2949
if (!-f $logfile) {
@@ -41,11 +61,26 @@
4161
is $from => $mapping{$image}{$key} => "$image has correct $key";
4262
next;
4363
}
64+
if ($key eq 'ci') {
65+
if ($mapping{$image}{ci} == 1) {
66+
ok $used->{$image}{develop}, "$image is used in workflow files";
67+
}
68+
if ($mapping{$image}{ci} == 2) {
69+
ok $used->{$image} && !$used->{$image}{develop}, "$image is previously used in workflow files";
70+
}
71+
next;
72+
}
4473
my $wanted = $key;
4574
$wanted = '(?:mysql|mariadb|postgresql)' if $key eq 'mysql';
4675
my ($version) = $log =~ /$wanted exists \((.+?)\)/i;
4776
is $version => $mapping{$image}{$key} => "$image has correct $key";
4877
}
4978
}
5079

80+
for my $image (sort keys %$used) {
81+
next if $mapping{$image}{ci};
82+
next if $image =~ /addons8|chromiumdriver/;
83+
fail "$image is no longer used in workflow files";
84+
}
85+
5186
done_testing;

0 commit comments

Comments
 (0)