-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathbuildDockerImages.pl
executable file
·345 lines (309 loc) · 13.9 KB
/
buildDockerImages.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
#!/usr/bin/perl
# Copyright 2017-2019 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
#
# Created by: Hal Rosenberg
#
# This builds and pushes the Docker images for Weathervane
#
package BuildDocker;
use strict;
use Getopt::Long;
use Term::ReadKey;
use Cwd qw(getcwd);
sub usage {
print "Usage: ./buildDockerImages.pl [options] [imageNames]\n";
print "This script builds the Weathervane docker images and pushes them to either\n";
print "a Docker Hub account or a private registry.\n";
print " Options:\n";
print " --help : Print this help and exit.\n";
print " --username: The username for the repository (Docker Hub account or private repository).\n";
print " This must be provided if --private is not used.\n";
print " For a private repository, this must be provided if a login is required\n";
print " to authenticate to the repository.\n";
print " --password: (optional) The password for the username (Docker Hub account or private repository).\n";
print " If username is specified and this is not provided, you will be prompted.\n";
print " --private : Use a private Docker registry \n";
print " --host : This is the hostname or IP address for the private registry.\n";
print " This must be provided if --private is used.\n";
print " --port : This is the port number for the private registry.\n";
print " This is only used with --private.\n";
print " --https_proxy : This is the url of the https proxy to use when accessing the internet.\n";
print " The proxy is currently only used for images that use curl in their Dockerfiles.\n";
print " If required by your proxy, the url should include the port, username, and password.\n";
print " --http_proxy : This is the url of the http proxy to use when accessing the internet.\n";
print " The proxy is currently only used for images that use curl in their Dockerfiles.\n";
print " If required by your proxy, the url should include the port, username, and password.\n";
# Command line argument to drive deletion of the docker images created
print " --deleteImages : This option drives deletion of the created docker images by this script";
print " This option when set to true will delete all the created images";
print " default value for this option is set to false";
print "If the list of image names is empty, then all images are built and pushed.\n";
}
my $help = '';
my $host= "";
my $port = 0;
my $username = "";
my $password = "";
my $private = '';
my $http_proxy = '';
my $https_proxy = '';
my $deleteImages = "false";
my $optionsSuccess = GetOptions('help' => \$help,
'host=s' => \$host,
'port=i' => \$port,
'username=s' => \$username,
'password=s' => \$password,
'private!' => \$private,
'http_proxy=s' => \$http_proxy,
'https_proxy=s' => \$https_proxy,
'deleteImages=s' => \$deleteImages
);
if (!$optionsSuccess) {
die "Error for command line options.\n";
}
my @imageNames = qw(baseos runharness auctiondatamanager auctionworkloaddriver auctionappserverwarmer cassandra nginx postgresql rabbitmq zookeeper tomcat auctionbidservice);
if ($#ARGV >= 0) {
@imageNames = @ARGV;
}
if ($help) {
usage();
exit;
}
sub runAndLog {
my ( $fileout, $cmd ) = @_;
print $fileout "COMMAND> $cmd\n";
open( CMD, "$cmd 2>&1 |" ) || die "Couldn't run command $cmd: $!\n";
while ( my $line = <CMD> ) {
print $fileout $line;
}
close CMD;
}
sub rewriteDockerfile {
my ( $dirName, $namespace, $version) = @_;
`mv $dirName/Dockerfile $dirName/Dockerfile.orig`;
open(my $filein, "$dirName/Dockerfile.orig") or die "Can't open file $dirName/Dockerfile.orig for reading: $!\n";
open(my $fileout, ">$dirName/Dockerfile") or die "Can't open file $dirName/Dockerfile for writing: $!\n";
while (my $inline = <$filein>) {
if ($inline =~ /^FROM/) {
print $fileout "FROM $namespace/weathervane-baseos:$version\n";
} else {
print $fileout $inline;
}
}
close $filein;
close $fileout
}
sub cleanupDockerfile {
my ( $dirName) = @_;
`mv $dirName/Dockerfile.orig $dirName/Dockerfile`;
}
sub buildImage {
my ($imageName, $buildArgsListRef, $fileout, $namespace, $version, $logFile) = @_;
if ($imageName ne "baseos") {
rewriteDockerfile("./dockerImages/$imageName", $namespace, $version);
}
my $buildArgs = "";
foreach my $buildArg (@$buildArgsListRef) {
$buildArgs .= " --build-arg $buildArg";
}
runAndLog($fileout, "docker build $buildArgs -t $namespace/weathervane-$imageName:$version ./dockerImages/$imageName");
my $exitValue;
$exitValue=$? >> 8;
if ($exitValue) {
print "Error: docker build failed with exitValue $exitValue, check $logFile.\n";
if ($imageName ne "baseos") {
cleanupDockerfile("./dockerImages/$imageName");
}
cleanupAfterBuild($fileout);
exit(-1);
}
runAndLog($fileout, "docker push $namespace/weathervane-$imageName:$version");
$exitValue=$? >> 8;
if ($exitValue) {
print "Error: docker push failed with exitValue $exitValue, check $logFile.\n";
if ($imageName ne "baseos") {
cleanupDockerfile("./dockerImages/$imageName");
}
cleanupAfterBuild($fileout);
exit(-1);
}
if ($imageName ne "baseos") {
cleanupDockerfile("./dockerImages/$imageName");
}
if ($deleteImages eq "true") {
print "Removing docker image for $namespace/weathervane-$imageName:$version (deleteImages true).\n";
runAndLog($fileout, "docker images | grep -E \"$namespace/weathervane-$imageName\\s+$version \" | awk '{print \$3}' | xargs -r docker rmi");
}
}
sub setupForBuild {
my ($fileout) = @_;
#nginx
runAndLog($fileout, "rm -rf ./dockerImages/nginx/html");
runAndLog($fileout, "mkdir ./dockerImages/nginx/html");
runAndLog($fileout, "cp ./dist/auctionWeb.zip ./dockerImages/nginx/html/");
runAndLog($fileout, "cd ./dockerImages/nginx/html; unzip auctionWeb.zip; rm -f auctionWeb.zip");
# appServerWarmer
runAndLog($fileout, "rm -f ./dockerImages/auctionappserverwarmer/auctionAppServerWarmer.jar");
runAndLog($fileout, "cp ./dist/auctionAppServerWarmer.jar ./dockerImages/auctionappserverwarmer/auctionAppServerWarmer.jar");
# tomcat
runAndLog($fileout, "rm -rf ./dockerImages/tomcat/apache-tomcat-auction1/webapps");
runAndLog($fileout, "mkdir ./dockerImages/tomcat/apache-tomcat-auction1/webapps");
runAndLog($fileout, "mkdir ./dockerImages/tomcat/apache-tomcat-auction1/webapps/auction");
runAndLog($fileout, "mkdir ./dockerImages/tomcat/apache-tomcat-auction1/webapps/auctionWeb");
runAndLog($fileout, "cp ./dist/auction.war ./dockerImages/tomcat/apache-tomcat-auction1/webapps/");
runAndLog($fileout, "cp ./dist/auctionWeb.war ./dockerImages/tomcat/apache-tomcat-auction1/webapps/");
runAndLog($fileout, "cp ./dist/auction.war ./dockerImages/tomcat/apache-tomcat-auction1/webapps/auction/");
runAndLog($fileout, "cd ./dockerImages/tomcat/apache-tomcat-auction1/webapps/auction; unzip auction.war; rm -f auction.war");
runAndLog($fileout, "cp ./dist/auctionWeb.war ./dockerImages/tomcat/apache-tomcat-auction1/webapps/auctionWeb/");
runAndLog($fileout, "cd ./dockerImages/tomcat/apache-tomcat-auction1/webapps/auctionWeb; unzip auctionWeb.war; rm -f auctionWeb.war");
# auctionBidService
runAndLog($fileout, "rm -rf ./dockerImages/auctionbidservice/apache-tomcat-bid/webapps");
runAndLog($fileout, "mkdir ./dockerImages/auctionbidservice/apache-tomcat-bid/webapps");
runAndLog($fileout, "mkdir ./dockerImages/auctionbidservice/apache-tomcat-bid/webapps/auction");
runAndLog($fileout, "cp ./dist/auctionBidService.war ./dockerImages/auctionbidservice/apache-tomcat-bid/webapps/auction.war");
runAndLog($fileout, "cp ./dist/auctionBidService.war ./dockerImages/auctionbidservice/apache-tomcat-bid/webapps/auction/auction.war");
runAndLog($fileout, "cd ./dockerImages/auctionbidservice/apache-tomcat-bid/webapps/auction; unzip auction.war; rm -f auction.war");
# workload driver
runAndLog($fileout, "rm -f ./dockerImages/auctionworkloaddriver/workloadDriver.jar");
runAndLog($fileout, "rm -rf ./dockerImages/auctionworkloaddriver/workloadDriverLibs");
runAndLog($fileout, "cp ./dist/workloadDriver.jar ./dockerImages/auctionworkloaddriver/workloadDriver.jar");
runAndLog($fileout, "cp -r ./dist/workloadDriverLibs ./dockerImages/auctionworkloaddriver/workloadDriverLibs");
# data manager
runAndLog($fileout, "rm -f ./dockerImages/auctiondatamanager/dbLoader.jar");
runAndLog($fileout, "rm -rf ./dockerImages/auctiondatamanager/dbLoaderLibs");
runAndLog($fileout, "cp ./dist/dbLoader.jar ./dockerImages/auctiondatamanager/dbLoader.jar");
runAndLog($fileout, "cp -r ./dist/dbLoaderLibs ./dockerImages/auctiondatamanager/dbLoaderLibs");
# run harness
runAndLog($fileout, "rm -rf ./dockerImages/runharness/runHarness");
runAndLog($fileout, "rm -rf ./dockerImages/runharness/configFiles");
runAndLog($fileout, "rm -rf ./dockerImages/runharness/workloadConfiguration");
runAndLog($fileout, "rm -f ./dockerImages/runharness/weathervane.pl");
runAndLog($fileout, "rm -f ./dockerImages/runharness/version.txt");
runAndLog($fileout, "cp ./version.txt ./dockerImages/runharness/version.txt");
runAndLog($fileout, "cp -r ./runHarness ./dockerImages/runharness/runHarness");
runAndLog($fileout, "cp ./weathervane.pl ./dockerImages/runharness/weathervane.pl");
runAndLog($fileout, "cp -r ./configFiles ./dockerImages/runharness/configFiles");
runAndLog($fileout, "cp -r ./workloadConfiguration ./dockerImages/runharness/workloadConfiguration");
}
sub cleanupAfterBuild {
my ($fileout) = @_;
runAndLog($fileout, "rm -rf ./dockerImages/nginx/html");
runAndLog($fileout, "rm -f ./dockerImages/auctionappserverwarmer/auctionAppServerWarmer.jar");
runAndLog($fileout, "rm -rf ./dockerImages/tomcat/apache-tomcat-auction1/webapps");
runAndLog($fileout, "rm -rf ./dockerImages/auctionBidService/apache-tomcat-bid/webapps");
runAndLog($fileout, "rm -f ./dockerImages/auctionworkloaddriver/workloadDriver.jar");
runAndLog($fileout, "rm -rf ./dockerImages/auctionworkloaddriver/workloadDriverLibs");
runAndLog($fileout, "rm -f ./dockerImages/auctiondatamanager/dbLoader.jar");
runAndLog($fileout, "rm -rf ./dockerImages/auctiondatamanager/dbLoaderLibs");
runAndLog($fileout, "rm -rf ./dockerImages/runharness/runHarness");
runAndLog($fileout, "rm -rf ./dockerImages/runharness/configFiles");
runAndLog($fileout, "rm -rf ./dockerImages/runharness/workloadConfiguration");
runAndLog($fileout, "rm -f ./dockerImages/runharness/weathervane.pl");
runAndLog($fileout, "rm -f ./dockerImages/runharness/version.txt");
}
my $namespace;
if ($private) {
if ($host eq "") {
print "When using a private repository, you must specify the host parameter.\n";
usage();
exit(-1);
}
$namespace = $host;
if ($port) {
$namespace .= ":$port";
}
} else {
if ($username eq "") {
print "When using Docker Hub, you must specify the username parameter.\n";
usage();
exit(-1);
}
$namespace = $username;
}
if (!(-e "./buildDockerImages.pl")) {
print "You must run in the weathervane directory with buildDockerImages.pl\n";
exit(-1);
}
my $cmdout;
my $fileout;
my $logFile = "buildDockerImages.log";
open( $fileout, ">$logFile" ) or die "Can't open file $logFile for writing: $!\n";
my $version = `cat version.txt`;
chomp($version);
# Build the executables if any of the images to be built
# require the executables
foreach my $imageName (@imageNames) {
my @needExecutableImageNames = qw(auctiondatamanager auctionworkloaddriver auctionappserverwarmer nginx tomcat auctionbidservice);
if (grep { $imageName eq $_ } @needExecutableImageNames) {
print "Building the executables.\n";
print $fileout "Building the executables.\n";
# Create a .gradle directory and map it into the container
# This will speed subsequent builds
my $cwd = getcwd();
`mkdir -p $cwd/.gradle`;
my $cmdString = "docker run --name weathervane-builder --rm "
. "-v $cwd/.gradle:/root/.gradle "
. "-v $cwd:/root/weathervane -w /root/weathervane "
. "--entrypoint /root/weathervane/gradlew openjdk:8 release";
runAndLog($fileout, $cmdString);
my $exitValue=$? >> 8;
if ($exitValue) {
print "Error: Building failed with exitValue $exitValue, check $logFile.\n";
exit(-1);
}
last;
}
}
# Get the latest executables into the appropriate directories for the Docker images
print "Setting up the Docker images.\n";
print $fileout "Setting up the Docker images.\n";
setupForBuild($fileout);
# Turn on auto flushing of output
BEGIN { $| = 1 }
if (!$private || $username) {
my $hostString = "Docker Hub";
if ($private) {
$hostString = $host;
}
if (!(length $password > 0)) {
Term::ReadKey::ReadMode('noecho');
print "Enter $hostString password for $username:";
$password = Term::ReadKey::ReadLine(0);
Term::ReadKey::ReadMode('restore');
print "\n";
$password =~ s/\R\z//; #get rid of new line
}
if (!(length $password > 0)) {
die "Error, no password input.\n";
}
print "Logging into $hostString\n";
print $fileout "Logging into $hostString\n";
my $cmd = "docker login -u=\'$username\' -p=$password $host";
my $response = `$cmd 2>&1`;
print $fileout "result: $response\n";
if ($response =~ /unauthorized/) {
print "Could not login to $hostString with the supplied username and password.\n";
cleanupAfterBuild($fileout);
exit(-1);
}
}
foreach my $imageName (@imageNames) {
$imageName = lc $imageName;
print "Building and pushing weathervane-$imageName image.\n";
print $fileout "Building and pushing weathervane-$imageName image.\n";
my @buildArgs;
if($http_proxy){
push @buildArgs, "http_proxy=$http_proxy";
}
if($https_proxy){
push @buildArgs, "https_proxy=$https_proxy";
}
buildImage($imageName, \@buildArgs, $fileout, $namespace, $version, $logFile);
}
# Clean up
print $fileout "Cleaning up.\n";
cleanupAfterBuild($fileout);
print "Done.\n";
print $fileout "Done.\n";
1;