generate.pl: overhaul to support building slim images

Do a long-needed overhaul of this script allow building of `slim`
variants:

- Make the base image configurable through a new `builds` setting.
- Rename the `64bit` image to `main`, as bit-ness no longer applies as
  we already build on multiple architectures.
- Rename `Releases.yaml` to the more general `config.yml`, allowing it
  to contain the supported image variants and Configure options.
- Run through perltidy 💄

The `slim` variants installs the minimum build-deps needed to build
Perl, and removes them after (save for make and netbase, to retain being
able to install CPAN modules through cpanm.)
This commit is contained in:
Zak B. Elep 2018-08-04 19:50:13 +08:00
parent b4032ceb63
commit 0cb4fc3643
2 changed files with 143 additions and 65 deletions

View file

@ -1,39 +1,48 @@
---
builds:
- main
- slim
options:
common: "-Duseshrplib -Dvendorprefix=/usr/local"
threaded: "-Dusethreads"
releases: releases:
- version: 5.8.9 - version: 5.8.9
sha256: 1097fbcd48ceccb2bc735d119c9db399a02a8ab9f7dc53e29e47e6a8d0d72e79 sha256: 1097fbcd48ceccb2bc735d119c9db399a02a8ab9f7dc53e29e47e6a8d0d72e79
extra_flags: "-A ccflags=-fwrapv" extra_flags: "-A ccflags=-fwrapv"
test_parallel: no test_parallel: no
buildpack_deps: jessie debian_release: jessie
- version: 5.10.1 - version: 5.10.1
sha256: 9385f2c8c2ca8b1dc4a7c31903f1f8dc8f2ba867dc2a9e5c93012ed6b564e826 sha256: 9385f2c8c2ca8b1dc4a7c31903f1f8dc8f2ba867dc2a9e5c93012ed6b564e826
extra_flags: "-A ccflags=-fwrapv" extra_flags: "-A ccflags=-fwrapv"
test_parallel: no test_parallel: no
buildpack_deps: jessie debian_release: jessie
- version: 5.12.5 - version: 5.12.5
sha256: 10749417fd3010aae320a34181ad4cd6a4855c1fc63403b87fa4d630b18e966c sha256: 10749417fd3010aae320a34181ad4cd6a4855c1fc63403b87fa4d630b18e966c
extra_flags: "-A ccflags=-fwrapv" extra_flags: "-A ccflags=-fwrapv"
test_parallel: no test_parallel: no
buildpack_deps: jessie debian_release: jessie
- version: 5.14.4 - version: 5.14.4
sha256: eece8c2b0d491bf6f746bd1f4f1bb7ce26f6b98e91c54690c617d7af38964745 sha256: eece8c2b0d491bf6f746bd1f4f1bb7ce26f6b98e91c54690c617d7af38964745
extra_flags: "-A ccflags=-fwrapv" extra_flags: "-A ccflags=-fwrapv"
test_parallel: no test_parallel: no
buildpack_deps: jessie debian_release: jessie
- version: 5.16.3 - version: 5.16.3
sha256: bb7bc735e6813b177dcfccd480defcde7eddefa173b5967eac11babd1bfa98e8 sha256: bb7bc735e6813b177dcfccd480defcde7eddefa173b5967eac11babd1bfa98e8
extra_flags: "-A ccflags=-fwrapv" extra_flags: "-A ccflags=-fwrapv"
test_parallel: no test_parallel: no
buildpack_deps: jessie debian_release: jessie
- version: 5.18.4 - version: 5.18.4
sha256: 1fb4d27b75cd244e849f253320260efe1750641aaff4a18ce0d67556ff1b96a5 sha256: 1fb4d27b75cd244e849f253320260efe1750641aaff4a18ce0d67556ff1b96a5
extra_flags: "-A ccflags=-fwrapv" extra_flags: "-A ccflags=-fwrapv"
test_parallel: no test_parallel: no
buildpack_deps: jessie debian_release: jessie
- version: 5.20.3 - version: 5.20.3
sha256: 1b40068166c242e34a536836286e70b78410602a80615143301e52aa2901493b sha256: 1b40068166c242e34a536836286e70b78410602a80615143301e52aa2901493b

View file

@ -9,23 +9,68 @@ use LWP::Simple;
sub die_with_sample { sub die_with_sample {
die <<EOF; die <<EOF;
The Releases.yaml file must look roughly like: The config.yml file must look roughly like:
---
builds:
- main
- slim
options:
common: "-Duseshrplib -Dvendorprefix=/usr/local"
threaded: "-Dusethreads"
releases: releases:
- version: 5.20.0 - version: 5.20.0
sha256: asdasdadas sha256: asdasdadas
Where version is the version number of Perl and sha256 is the SHA256 of Where "version" is the version number of Perl and "sha256" is the SHA256
the tar.bz2 file. of the Perl distribution tarball.
If needed or desired, extra_flags: can be added, which will be passed If needed or desired, extra_flags: can be added, which will be passed
verbatim to Configure. verbatim to Configure.
Run "perldoc ./generate.pl" to read the complete documentation.
EOF EOF
} }
my $yaml = do { my $docker_slim_run_install = <<'EOF';
open my $fh, "<", "Releases.yaml" or die "Couldn't open releases"; apt-get update \
&& apt-get install -y --no-install-recommends \
bzip2 \
ca-certificates \
# cpio \
curl \
dpkg-dev \
# file \
gcc \
# g++ \
# libbz2-dev \
# libdb-dev \
libc6-dev \
# libgdbm-dev \
# liblzma-dev \
make \
netbase \
patch \
# procps \
# zlib1g-dev \
xz-utils
EOF
chomp $docker_slim_run_install;
my $docker_slim_run_purge = <<'EOF';
savedPackages="make netbase" \
&& apt-mark auto '.*' > /dev/null \
&& apt-mark manual $savedPackages \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -fr /var/cache/apt/* /var/lib/apt/lists/*
EOF
chomp $docker_slim_run_purge;
my $config = do {
open my $fh, '<', 'config.yml' or die "Couldn't open config";
local $/; local $/;
Load <$fh>; Load <$fh>;
}; };
@ -35,15 +80,7 @@ my $template = do {
<DATA>; <DATA>;
}; };
my $common = join " ", qw{ my %builds;
-Duseshrplib
-Dvendorprefix=/usr/local
};
my %builds = (
"64bit" => "$common",
"64bit,threaded" => "-Dusethreads $common",
);
# sha256 taken from http://www.cpan.org/authors/id/M/MI/MIYAGAWA/CHECKSUMS # sha256 taken from http://www.cpan.org/authors/id/M/MI/MIYAGAWA/CHECKSUMS
my %cpanm = ( my %cpanm = (
@ -52,15 +89,21 @@ my %cpanm = (
sha256 => "9b60767fe40752ef7a9d3f13f19060a63389a5c23acc3e9827e19b75500f81f3", sha256 => "9b60767fe40752ef7a9d3f13f19060a63389a5c23acc3e9827e19b75500f81f3",
); );
die_with_sample unless defined $yaml->{releases}; die_with_sample unless defined $config->{releases};
die_with_sample unless ref $yaml->{releases} eq "ARRAY"; die_with_sample unless ref $config->{releases} eq "ARRAY";
if (!-d "downloads") { if (!-d "downloads") {
mkdir "downloads" or die "Couldn't create a downloads directory"; mkdir "downloads" or die "Couldn't create a downloads directory";
} }
for my $release (@{$yaml->{releases}}) { for my $build (@{$config->{builds}}) {
do { die_with_sample unless $release->{$_}} for (qw(version sha256)); $builds{$build} = $config->{options}{common};
$builds{"$build,threaded"} = "@{$config->{options}}{qw/threaded common/}";
}
for my $release (@{$config->{releases}}) {
do { die_with_sample unless $release->{$_} }
for (qw(version sha256));
die "Bad version: $release->{version}" unless $release->{version} =~ /\A5\.\d+\.\d+\Z/; die "Bad version: $release->{version}" unless $release->{version} =~ /\A5\.\d+\.\d+\Z/;
@ -68,10 +111,10 @@ for my $release (@{$yaml->{releases}}) {
$release->{type} ||= 'bz2'; $release->{type} ||= 'bz2';
my $file = "perl-$release->{version}.tar.$release->{type}"; my $file = "perl-$release->{version}.tar.$release->{type}";
my $url = "https://www.cpan.org/src/5.0/$file"; my $url = "https://www.cpan.org/src/5.0/$file";
if (-f "downloads/$file" && if (-f "downloads/$file" && `sha256sum downloads/$file` =~ /^\Q$release->{sha256}\E\s+\Qdownloads\/$file\E/) {
`sha256sum downloads/$file` =~ /^\Q$release->{sha256}\E\s+\Qdownloads\/$file\E/) {
print "Skipping download of $file, already current\n"; print "Skipping download of $file, already current\n";
} else { }
else {
print "Downloading $url\n"; print "Downloading $url\n";
getstore($url, "downloads/$file"); getstore($url, "downloads/$file");
} }
@ -95,20 +138,37 @@ for my $release (@{$yaml->{releases}}) {
die "Couldn't create a Devel::PatchPerl patch for $release->{version}" if $? != 0; die "Couldn't create a Devel::PatchPerl patch for $release->{version}" if $? != 0;
} }
for my $build (keys %builds) {
$release->{url} = $url; $release->{url} = $url;
$release->{extra_flags} = "" unless defined $release->{extra_flags};
$release->{_tag} = $release->{buildpack_deps} || "stretch";
$release->{"cpanm_dist_$_"} = $cpanm{$_} for keys %cpanm; $release->{"cpanm_dist_$_"} = $cpanm{$_} for keys %cpanm;
for my $config (keys %builds) { $release->{extra_flags} ||= '';
$release->{debian_release} ||= 'stretch';
if ($build =~ /main/) {
$release->{image} = 'buildpack-deps';
$release->{tag} = $release->{debian_release};
}
else {
$release->{image} = 'debian';
$release->{tag} = "@{[ $release->{debian_release} ]}-slim";
}
my $output = $template; my $output = $template;
$output =~ s/\{\{$_\}\}/$release->{$_}/mg $output =~ s/\{\{$_\}\}/$release->{$_}/mg
for (qw(version pause extra_flags sha256 type url _tag cpanm_dist_name cpanm_dist_url cpanm_dist_sha256)); for (qw(version pause extra_flags sha256 type url image tag cpanm_dist_name cpanm_dist_url cpanm_dist_sha256));
$output =~ s/\{\{args\}\}/$builds{$config}/mg; $output =~ s/\{\{args\}\}/$builds{$build}/mg;
my $dir = sprintf "%i.%03i.%03i-%s", if ($build =~ /slim/) {
($release->{version} =~ /(\d+)\.(\d+)\.(\d+)/), $output =~ s/\{\{docker_slim_run_install\}\}/$docker_slim_run_install/mg;
$config; $output =~ s/\{\{docker_slim_run_purge\}\}/$docker_slim_run_purge/mg;
}
else {
$output =~ s/\{\{docker_slim_run_install\}\}/true/mg;
$output =~ s/\{\{docker_slim_run_purge\}\}/true/mg;
}
my $dir = sprintf "%i.%03i.%03i-%s", ($release->{version} =~ /(\d+)\.(\d+)\.(\d+)/), $build;
mkdir $dir unless -d $dir; mkdir $dir unless -d $dir;
@ -120,9 +180,11 @@ for my $release (@{$yaml->{releases}}) {
if (defined $release->{test_parallel} && $release->{test_parallel} eq "no") { if (defined $release->{test_parallel} && $release->{test_parallel} eq "no") {
$output =~ s/\{\{test\}\}/make test_harness/; $output =~ s/\{\{test\}\}/make test_harness/;
} elsif (!defined $release->{test_parallel} || $release->{test_parallel} eq "yes") { }
elsif (!defined $release->{test_parallel} || $release->{test_parallel} eq "yes") {
$output =~ s/\{\{test\}\}/TEST_JOBS=\$(nproc) make test_harness/; $output =~ s/\{\{test\}\}/TEST_JOBS=\$(nproc) make test_harness/;
} else { }
else {
die "test_parallel was provided for $release->{version} but is invalid; should be 'yes' or 'no'\n"; die "test_parallel was provided for $release->{version} but is invalid; should be 'yes' or 'no'\n";
} }
@ -136,17 +198,18 @@ for my $release (@{$yaml->{releases}}) {
=head1 NAME =head1 NAME
generate.pl generate.pl - generate Dockerfiles for Perl
=head1 SYNOPSIS =head1 SYNOPSIS
generate.pl is a little helper script to reinitalize the Dockerfiles from a YAML file. cd /path/to/docker-perl
./generate.pl
=head1 DESCRIPTION =head1 DESCRIPTION
generate.pl is meant to be run from the actual repo directory, with a Releases.yaml file generate.pl is meant to be run from the actual repo directory, with a
correctly configured. It starts with a 'releases' key, which contains a list of releases, config.yml file correctly configured. It contains with a 'releases'
each with the following keys: key, which contains a list of releases, each with the following keys:
=over 4 =over 4
@ -160,23 +223,27 @@ The actual perl version, such as B<5.20.1>.
=item sha256 =item sha256
The SHA-256 of the C<.tar.bz2> file for that release. The SHA-256 of the tarball for that release.
=back
=item OPTIONAL =item OPTIONAL
=over 4 =over 4
=item buildpack_deps =item debian_release
The Docker L<buildpack-deps|https://hub.docker.com/_/buildpack-deps> The Docker image tag which this Perl would build on, common to both the
image tag which this Perl would build on. L<https://hub.docker.com/_/buildpack-deps|buildpack-deps> and
L<https://hub.docker.com/_/debian|debian> Docker images.
Defaults: C<stretch> Defaults: C<stretch> for C<main> builds, C<stretch-slim> for C<slim>
builds.
=item extra_flags =item extra_flags
Additional text to pass to C<Configure>. At the moment, this is necessary for Additional text to pass to C<Configure>. At the moment, this is
5.18.x so that it can get the C<-fwrapv> flag. necessary for 5.18.x so that it can get the C<-fwrapv> flag.
Default: C<""> Default: C<"">
@ -195,13 +262,14 @@ Default: C<yes>
=cut =cut
__DATA__ __DATA__
FROM buildpack-deps:{{_tag}} FROM {{image}}:{{tag}}
LABEL maintainer="Peter Martini <PeterCMartini@GMail.com>, Zak B. Elep <zakame@cpan.org>" LABEL maintainer="Peter Martini <PeterCMartini@GMail.com>, Zak B. Elep <zakame@cpan.org>"
COPY *.patch /usr/src/perl/ COPY *.patch /usr/src/perl/
WORKDIR /usr/src/perl WORKDIR /usr/src/perl
RUN curl -SL {{url}} -o perl-{{version}}.tar.{{type}} \ RUN {{docker_slim_run_install}} \
&& curl -SL {{url}} -o perl-{{version}}.tar.{{type}} \
&& echo '{{sha256}} *perl-{{version}}.tar.{{type}}' | sha256sum -c - \ && echo '{{sha256}} *perl-{{version}}.tar.{{type}}' | sha256sum -c - \
&& tar --strip-components=1 -xaf perl-{{version}}.tar.{{type}} -C /usr/src/perl \ && tar --strip-components=1 -xaf perl-{{version}}.tar.{{type}} -C /usr/src/perl \
&& rm perl-{{version}}.tar.{{type}} \ && rm perl-{{version}}.tar.{{type}} \
@ -217,6 +285,7 @@ RUN curl -SL {{url}} -o perl-{{version}}.tar.{{type}} \
&& curl -LO {{cpanm_dist_url}} \ && curl -LO {{cpanm_dist_url}} \
&& echo '{{cpanm_dist_sha256}} *{{cpanm_dist_name}}.tar.gz' | sha256sum -c - \ && echo '{{cpanm_dist_sha256}} *{{cpanm_dist_name}}.tar.gz' | sha256sum -c - \
&& tar -xzf {{cpanm_dist_name}}.tar.gz && cd {{cpanm_dist_name}} && perl bin/cpanm . && cd /root \ && tar -xzf {{cpanm_dist_name}}.tar.gz && cd {{cpanm_dist_name}} && perl bin/cpanm . && cd /root \
&& {{docker_slim_run_purge}} \
&& rm -fr ./cpanm /root/.cpanm /usr/src/perl /usr/src/{{cpanm_dist_name}}* /tmp/* && rm -fr ./cpanm /root/.cpanm /usr/src/perl /usr/src/{{cpanm_dist_name}}* /tmp/*
WORKDIR /root WORKDIR /root