#!/usr/bin/env perl # # $Id: //guest/daniel_kionka/bootstrap/bin/build-bootstrap.pl#5 $ # # Copyright (c) 2005-2006 Daniel P. Kionka; all rights reserved # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Originally written by Daniel P. Kionka while contracting for CiraNova. # http://www.ciranova.com/ # # # build-bootstrap.pl - simple utility for starting builds # # This utility solves the chicken-and-egg problem of how to check out and start # the script that checks out the source including the script that starts the # build. The solution is a generic utility to check out and start any source # based on a config file. The general rules are: # # 1. You have a p4 client where you can p4 sync all files. # 2. You have a script that will do the entire build. # 3. You specify the client and script names in a config file. # use strict; use warnings; use File::Spec; # # variables # # constants my $debug = 1; my @rcRequired = qw(P4CLIENT START LOG ROOT); my $logP4Change = "p4-change.log"; my $logP4Client = "p4-client.log"; my $p4SyncErr = "p4-sync-err.log"; my $p4SyncOut = "p4-sync-out.log"; my $startErr = "start-err.log"; my $startOut = "start-out.log"; my $p4exeDefault = "/opt/perforce/p4"; my $p4ExeDefaultDir = "/opt/perforce"; my $p4portDefault = "public.perforce.com:1666"; # global hashes with config file values and p4 client info my (%rc, %client); # other globals my $errorFlag = 0; # # functions # sub debugPrint(@) { print @_, "\n" if ($debug); } sub errorPrint(@) { print STDERR @_, "\n"; } sub mySystem($) { my ($cmd) = @_; if ($errorFlag != 0) { errorPrint("skipping system after error: $cmd"); return; } debugPrint("system: $cmd"); my $err = system($cmd); if ($err != 0) { $errorFlag++; errorPrint("system command failed: $cmd"); } return $err; } sub renameOld($) { my ($file) = @_; debugPrint("renaming: $file"); my $fold = "$file.old"; if (-r $fold) { mySystem("rm -rf $fold"); } rename($file, "$fold"); } # # read the bootstrap config file (START, LOG, etc) # sub readRC($) { my ($rcfile) = @_; my ($line); open(RC, '<', $rcfile) || die "open $rcfile"; while (defined($line = )) { chomp $line; $line =~ s/\s*#.*//; next if (! $line); my ($key, $val) = ($line =~ m/^(\S+)\s*=\s*(.*)/); debugPrint("key=$key,val=$val"); if (defined($val)) { $rc{$key} = $val; $ENV{$key} = $val if ($key =~ m/^P4/); # export P$ variables } } close RC; if (! defined($rc{ROOT})) { foreach my $line (`p4 client -o $rc{P4CLIENT}`) { $rc{ROOT} = $1 if ($line =~ m/^Root:\s+(.*)/); } die "rc{ROOT} undefined" if (! defined($rc{ROOT})); chomp $rc{ROOT}; } foreach $line (@rcRequired) { # maybe we should look at environment vars first die "missing RC line: $line" if (! defined($rc{$line})); } } # # mainline # my ($rcfile) = @ARGV; # 1. setup and sanity checks mySystem("p4 set"); if ($errorFlag) { # append default p4 dir to path $errorFlag = 0; # no real error yet my @PATH = File::Spec->path(); push(@PATH, $p4ExeDefaultDir); $ENV{PATH} = catdir(@PATH); } $ENV{P4PORT} = $p4portDefault if (! exists($ENV{P4PORT})); mySystem("p4 set"); die "Can not run p4" if ($errorFlag); # 2. read config file readRC($rcfile); # 3. rename source directory renameOld($rc{ROOT}); # 4. set up log directory mkdir($rc{ROOT}); chdir($rc{ROOT}) || die "Can not chdir $rc{ROOT}"; delete($ENV{PWD}); # PWD confuses p4 mySystem("mkdir -p $rc{LOG}"); # 5. p4 commands: sync -f, get p4 change# mySystem("p4 -c $rc{P4CLIENT} sync -f " . "1> $rc{LOG}/$p4SyncOut 2> $rc{LOG}/$p4SyncErr"); my $change = `p4 -c $rc{P4CLIENT} changes -m 1 ...#have`; chomp($change); debugPrint("change: $change"); $change =~ s/Change (\d+) .*/$1/; die "No p4 change" if (! $change); $ENV{BBS_CHANGE} = $change; # save p4 info for build scripts mySystem("echo $change > $rc{LOG}/$logP4Change"); mySystem("echo $rc{P4CLIENT} > $rc{LOG}/$logP4Client"); # 6. run start mySystem("$rc{START} > $rc{LOG}/$startErr 2> $rc{LOG}/$startOut"); # 7. wrapup print "$0: ", ($errorFlag == 0) ? "Succeeded" : "Failed", "\n"; sleep(2); # finish print before ending ssh exit($errorFlag);