ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/JSOC/proj/util/scripts/prodbuild.pl
Revision: 1.2
Committed: Wed Jul 31 23:44:27 2013 UTC (10 years, 1 month ago) by arta
Content type: text/plain
Branch: MAIN
CVS Tags: Ver_8-8, Ver_8-11, Ver_8-2, Ver_8-10, Ver_8-1, Ver_8-6, Ver_LATEST, Ver_8-4, Ver_9-41, Ver_8-3, Ver_8-5, Ver_8-12, Ver_8-7, Ver_9-5, Ver_9-4, Ver_9-3, Ver_9-2, Ver_9-1, Ver_9-0, HEAD
Changes since 1.1: +1 -1 lines
Log Message:
Update the exe path for ActiveState updates.

File Contents

# Content
1 #!/home/jsoc/bin/linux_x86_64/activeperl
2
3 # This script maintains the 'production' set of JSOC binaries, which are located in
4 # /home/jsoc/cvs/Development/JSOC/bin. It works as follows:
5 #
6 # 1. It runs "make MACH='waystation_<arch>' <target1> <target2> ..." This will create binary files in
7 # /home/jsoc/cvs/Development/JSOC/_waystation_<arch>. There will be links created from
8 # /home/jsoc/cvs/Development/JSOC/bin/waystation_<arch> and
9 # /home/jsoc/cvs/Development/JSOC/lib/waystation_<arch> to the just-created binaries.
10 # 2. It then follows all these links to identify all the newly created files. Each of these files
11 # is going to replace a file in /home/jsoc/cvs/Development/JSOC/_<arch>. However, these original
12 # files may be in use, so each is first moved to a "save" directory, which is named
13 # /home/jsoc/cvs/Development/JSOC/_<arch>_YYYYMMDDHHMMSS. This save directory
14 # must be created every time this script is run. At regular intervals, these save directories
15 # must be deleted (a one-day retention time is good). Each original file is first moved to the save
16 # directory, then its replacement (in /home/jsoc/cvs/Development/JSOC/_waystation_<arch>)
17 # is moved into place in the production directory, /home/jsoc/cvs/Development/JSOC/_<arch>.
18 # 3. The links to the files in /home/jsoc/cvs/Development/JSOC/_waystation_<arch> will now be dead.
19 # This script therefore deletes those links.
20 # 4. /home/jsoc/cvs/Development/JSOC/waystation_<arch> is now the repository for all the object and dependency files.
21 # make will use these files when it builds binaries, so we must maintain this directory.
22
23 use strict;
24 use warnings;
25 use Cwd qw(getcwd realpath chdir);
26 use File::Spec;
27 use File::stat;
28 use IO::Dir;
29 use Data::Dumper;
30 use FindBin qw($Bin);
31 use lib "$Bin/../../../base/libs/perl";
32 use drmsLocks;
33 use drmsArgs;
34 use drmsRunProg;
35
36 # Required arguments
37 use constant kArgMods => "mods"; # modules to build (comma-separated list)
38 use constant kArgFiles => "files"; # source files to first update (comma-separated list)
39
40 # Optional arguments
41 # If clean is specified, then the required arguments above are ignored. In this case, the $bindir is cleaned,
42 # just like 'make clean' will do. And $builddir is cleaned too.
43 use constant kArgClean => "clean"; # clean $bindir (i.e., _linux_x86_64) AND $builddir (i.e., _waystation_$bindir)
44 use constant kArgBinDir => "bindir"; # _waystation_<value> is the directory where the binaries are saved
45 # (defaults to _waystation_$JSOC_MACHINE)
46
47 # Lockfile
48 use constant kLockFile => "/home/jsoc/locks/prodbuildlck.txt";
49 use constant kJSOCtreeRoot => "JSOC";
50
51 # Return values
52 use constant kRetSuccess => 0;
53 use constant kRetNoLock => 1;
54 use constant kRetInvalidArgs => 2;
55 use constant kRetDlSource => 3;
56 use constant kRetInvalidWD => 4;
57 use constant kRetConfigure => 5;
58 use constant kRetMake => 6;
59 use constant kRetMove => 7;
60 use constant kRetDelLinks => 8;
61
62 my($rv);
63 my($argsinH);
64 my($optsinH);
65 my($lock);
66 my($args);
67 my($opts);
68 my(@mods);
69 my($bindir);
70 my($cmd);
71 my($basetime);
72 my(@srcdirs);
73 my($wdir); # working dir (which must be a JSOC root directory)
74 my(@relspecs);
75 my($specstr);
76 my($usewaystation);
77 my($builddir);
78 my($clean);
79
80 $rv = &kRetSuccess;
81
82 # Required arguments
83 $argsinH =
84 {
85 &kArgMods => 's',
86 &kArgFiles => 's',
87 };
88
89 $optsinH =
90 {
91 &kArgClean => 'noval',
92 &kArgBinDir => 's'
93 };
94
95 # Lock this script
96 $lock = new drmsNetLocks(&kLockFile);
97
98 if (defined($lock))
99 {
100 $rv = &kRetSuccess;
101
102 $basetime = time();
103
104 $opts = new drmsArgs($optsinH, 0);
105
106 $clean = 0;
107 if (defined($opts))
108 {
109 $clean = $opts->Get(&kArgClean);
110 }
111 else
112 {
113 $clean = 0;
114 }
115
116 if ($clean)
117 {
118 $bindir = $opts->Get(&kArgBinDir);
119 if (!defined($bindir))
120 {
121 $bindir = $ENV{JSOC_MACHINE};
122 }
123
124 if (!defined($bindir))
125 {
126 print STDERR "Binary directory not specified.\n";
127 $rv = &kRetInvalidArgs;
128 }
129 else
130 {
131 $cmd = "make 'MACH=$bindir' clean";
132 print "running $cmd\n";
133
134 if (drmsSysRun::RunCmd($cmd) != 0)
135 {
136 print STDERR "Unable to clean $bindir.\n";
137 $rv = &kRetMake;
138 }
139 else
140 {
141 $builddir = "waystation_$bindir";
142 $cmd = "make 'MACH=$builddir' clean";
143 print "runnning $cmd\n";
144
145 if (drmsSysRun::RunCmd($cmd) != 0)
146 {
147 print STDERR "Unable to clean $builddir.\n";
148 $rv = &kRetMake;
149 }
150 }
151 }
152 }
153 else
154 {
155 $args = new drmsArgs($argsinH, 1);
156
157 if (!defined($args))
158 {
159 $rv = &kRetInvalidArgs;
160 }
161 else
162 {
163 # kArgMods must be defined (otherwise new drmsArgs would have failed).
164 @mods = split(qr(,), $args->Get(&kArgMods));
165 @relspecs = split(qr(,), $args->Get(&kArgFiles));
166 $bindir = $opts->Get(&kArgBinDir);
167 if (!defined($bindir))
168 {
169 $bindir = $ENV{JSOC_MACHINE};
170 }
171
172 if (!defined($bindir))
173 {
174 print STDERR "Binary directory not specified.\n";
175 $rv = &kRetInvalidArgs;
176 }
177 }
178
179 if ($rv == &kRetSuccess)
180 {
181 $wdir = getcwd();
182
183 # Make sure that the current directory is a JSOC-tree root.
184 # I'm probably going to regret this, but to ensure that the working directory is the root of
185 # a JSOC tree, let's consider this a valid tree if it contains base/jsoc_version.h. Let's not
186 # count of the current directory being "JSOC" (even though this is a requirement, I know
187 # Rick renames his tree root directory to DRMS).
188 if (!(-f "$wdir/base/jsoc_version.h"))
189 {
190 print STDERR "The current directory is the root of a valid JSOC source-code tree.\n";
191 $rv = kRetInvalidWD;
192 }
193 }
194
195 if ($rv == &kRetSuccess)
196 {
197
198 # Update source files.
199 $specstr = join(',', @relspecs);
200
201 $cmd = "/home/jsoc/dlsource.pl -o update -s $specstr";
202 if (drmsSysRun::RunCmd($cmd) != 0)
203 {
204 print STDERR "Unable to update source files.\n";
205 $rv = &kRetDlSource;
206 }
207 }
208
209 # Build modules.
210 if ($rv == &kRetSuccess)
211 {
212 my($targetstr);
213
214 $targetstr = join(' ', @mods);
215
216 # Run configure, just to be sure (but this assurance, which is necessary, will trigger a
217 # rebuild of pretty much all binaries since it, in essence, updates the timestamps on all
218 # headers. I need to make the configure script smarter so that it doesn't re-create
219 # all header links. Instead it should simply make a link to a header if the link does
220 # not already exist).
221 $cmd = "./configure";
222 if (drmsSysRun::RunCmd($cmd) != 0)
223 {
224 print STDERR "'configure' falied to run properly.\n";
225 $rv = &kRetConfigure;
226 }
227
228 # Run make. If the $bindir already exists, then we need to build in waystation_$bindir, and
229 # then copy the resulting binaries back to $bindir. But if $bindir does NOT exist, then
230 # we simply build in $bindir.
231
232 if ($rv == &kRetSuccess)
233 {
234 print "bindir is $bindir\n";
235 if (-d "_$bindir")
236 {
237 $usewaystation = 1;
238 $builddir = "waystation_$bindir";
239 }
240 else
241 {
242 $usewaystation = 0;
243 $builddir = $bindir;
244 }
245 }
246
247 if ($rv == &kRetSuccess)
248 {
249 $cmd = "make 'MACH=$builddir' $targetstr";
250 print "runnning $cmd\n";
251
252 if (drmsSysRun::RunCmd($cmd) != 0)
253 {
254 print STDERR "Unable to update source files.\n";
255 $rv = &kRetMake;
256 }
257 }
258 }
259
260 exit;
261
262 # Move the old binaries to a save location, and move the new binaries into locations vacated by
263 # the old binaries.
264 if ($rv == &kRetSuccess)
265 {
266 # $basetime is the time (number of secs since the epoch) when the script started running.
267 # For each binary that was created by this script, the binary that will be replaced
268 # by this new binary needs to be MOVED into a save directory. Then, the new binary
269 # needs to be MOVED into the production tree.
270
271 # Binaries whose timestamps are newer than $basetime are considered binaries that
272 # were created by this script.
273 push(@srcdirs, "$wdir/bin/waystation_$bindir");
274
275 if (MoveFiles($basetime, \@srcdirs) != 0)
276 {
277 print STDERR "Unable to move newly created binaries into place.\n";
278 $rv = &kRetMove;
279 }
280
281 if ($rv == &kRetSuccess)
282 {
283 # Remove the links from bin/$builddir to _$builddir.
284 if (RemoveLinks() != 0)
285 {
286 print STDERR "Unable to remove dead links.\n";
287 $rv = &kRetDelLinks;
288 }
289 }
290 }
291 }
292 }
293 else
294 {
295 print STDERR "This script is already running; bailing out.\n";
296 $rv = &kRetNoLock;
297 }
298
299 exit $rv;
300
301
302 sub FormSpecs
303 {
304 my($wdir) = $_[0];
305 my($spec) = $_[1];
306 my($fspec);
307 my(@rv) = ();
308
309 $fspec = File::Spec->catfile($wdir, $spec);
310
311 if (-e $fspec)
312 {
313 # Strip off the JSOC root prefix.
314 if ($fspec =~ /.+\/JSOC\/(.+)/) # 'greedy' algorithm
315 {
316 push(@rv, $1);
317 }
318 }
319 else
320 {
321 print STDERR "Warning: Invalid file specification '$spec'; skipping.\n";
322 }
323
324 return @rv;
325 }
326
327 sub FilterFile
328 {
329 my($afile) = shift;
330
331 if ($afile !~ /^\.$/ && $afile !~ /^\.\.$/ && $afile !~ /\.o\.d$/ && $afile !~ /\.o$/)
332 {
333 return $afile;
334 }
335 else
336 {
337 return ();
338 }
339 }
340
341 sub GetNewFiles
342 {
343 my($basetime) = shift;
344 my($dir) = shift;
345 my(@files) = @_;
346
347 my($timestamp);
348 my($tinfo);
349 my(@newfiles);
350 my($realfile);
351
352 @files = map(FilterFile($_), @files);
353
354 foreach my $afile (@files)
355 {
356 # Resolve links
357 $realfile = realpath("$dir/$afile");
358
359 # Now skip files that were not just created.
360 $tinfo = stat($realfile);
361
362 if (!$tinfo)
363 {
364 print STDERR "Unable to stat file $realfile.\n";
365 next;
366 }
367
368 $timestamp = $tinfo->mtime;
369 if ($timestamp < $basetime)
370 {
371 next;
372 }
373
374 if (-f $realfile)
375 {
376 # Not a subdirectory.
377 push(@newfiles, $realfile);
378 }
379 elsif (-d $realfile)
380 {
381 # A subdirectory.
382 my(@dirfiles);
383
384 tie(my(%dirH), "IO::Dir", "$realfile");
385 @dirfiles = keys(%dirH);
386 push(@newfiles, GetNewFiles($basetime, "$realfile", @dirfiles));
387 untie(%dirH);
388 }
389 else
390 {
391 print STDERR "Invalid file type, file $realfile.\n";
392 }
393 }
394
395 return @newfiles;
396 }
397
398 sub GetOldFile
399 {
400 my($afile) = shift;
401 my($oldfile);
402
403 if ($afile =~ /\/_waystation_\S+\//)
404 {
405 $oldfile = $afile;
406 $oldfile =~ s/_waystation//;
407 return $oldfile;
408 }
409 else
410 {
411 print STDERR "Unsupported source file $afile\n";
412 return "";
413 }
414 }
415
416 # Move newly built files from the _waystation_<arch> directory to the _<arch> directory.
417 # First, move the to-be-replaced files in the _<arch> directory to the save directory.
418 sub MoveFiles
419 {
420 my($basetime) = $_[0];
421 my($srcdirsR) = $_[1];
422
423 my($rv) = 1;
424 my($savedir);
425 my(%tree);
426 my(@allfiles);
427 my(@newfiles);
428 my(@oldfiles);
429 my($srcfile);
430 my($tgtfile);
431 my($timestamp);
432
433 # Collect a list of binary files that were created during the build phase.
434 foreach my $dir (@$srcdirsR)
435 {
436 if (-d $dir)
437 {
438 tie(%tree, "IO::Dir", $dir);
439
440 # @allfiles contains base file names (not paths).
441 @allfiles = keys(%tree);
442 # @newfiles contains full paths.
443 push(@newfiles, GetNewFiles($basetime, $dir, @allfiles));
444 untie(%tree);
445 }
446 else
447 {
448 print STDERR "Binary directory $dir does not exist.\n";
449 last;
450 }
451 }
452
453 # Find the original files that these new files will replace
454 foreach $srcfile (@newfiles)
455 {
456 $tgtfile = GetOldFile($srcfile);
457 print "new file $srcfile, old file $tgtfile\n";
458
459 # Move old file to save directory.
460 # ART
461 }
462
463
464 # for now, print new files
465 exit;
466
467
468 # Must create link from JSOC/bin/$bindir to each binary installed, and from JSOC/lib/$bindir to each
469 # library installed.
470 return $rv;
471 }