855 lines
23 KiB
JavaScript
855 lines
23 KiB
JavaScript
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1995
|
||
|
//
|
||
|
// File: autostart.js
|
||
|
//
|
||
|
// Contents: A script which will connect to a Build Manager machine and
|
||
|
// start a build. This can be used to start builds automatically
|
||
|
// with the task scheduler or by scripts.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
var RemoteObj = null;
|
||
|
|
||
|
var DEFAULT_IDENTITY_BM = "BuildManager";
|
||
|
var DEFAULT_IDENTITY_BUILDER = "Build";
|
||
|
var strBldMgr;
|
||
|
var strBldMgrIdentity = DEFAULT_IDENTITY_BM;
|
||
|
var strConfigURL = null;
|
||
|
var strEnviroURL = null;
|
||
|
|
||
|
var strConfigXML;
|
||
|
var strEnviroXML;
|
||
|
var strTimeStamp;
|
||
|
|
||
|
var fForceRestart = false;
|
||
|
var fCreateMachines = false;
|
||
|
var fUpdateBinaries = false;
|
||
|
var fSetTimeStamp = false;
|
||
|
var fTryAgain = true;
|
||
|
|
||
|
var aMachines = new Array();
|
||
|
|
||
|
// Capture variables
|
||
|
var fCaptureLogsFromMachine;
|
||
|
var fCaptureLogs;
|
||
|
var strCaptureLogDir;
|
||
|
var strCaptureLogMan;
|
||
|
var strCaptureLogManIdentity;
|
||
|
var g_FSObj;
|
||
|
|
||
|
var vRet = 0;
|
||
|
//
|
||
|
// First, parse command line arguments
|
||
|
//
|
||
|
Error.prototype.toString = Error_ToString;
|
||
|
ParseArguments(WScript.Arguments);
|
||
|
|
||
|
if (fUpdateBinaries)
|
||
|
{
|
||
|
vRet = DoBinariesUpdate();
|
||
|
}
|
||
|
else if (fCaptureLogs)
|
||
|
{
|
||
|
g_FSObj = new ActiveXObject("Scripting.FileSystemObject"); // Parse input Parameter List
|
||
|
if (fCaptureLogsFromMachine)
|
||
|
vRet = CaptureLogsManager(strCaptureLogDir, strCaptureLogMan, strCaptureLogManIdentity);
|
||
|
else
|
||
|
vRet = CaptureLogsEnviro(strCaptureLogDir);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vRet = AutoStart();
|
||
|
}
|
||
|
|
||
|
WScript.Quit(vRet);
|
||
|
|
||
|
function ParseArguments(Arguments)
|
||
|
{
|
||
|
var strArg;
|
||
|
var chArg0;
|
||
|
var chArg1;
|
||
|
var argn;
|
||
|
|
||
|
for(argn = 0; argn < Arguments.length; argn++)
|
||
|
{
|
||
|
strArg = Arguments(argn);
|
||
|
chArg0 = strArg.charAt(0);
|
||
|
chArg1 = strArg.toLowerCase().slice(1);
|
||
|
|
||
|
if (chArg0 != '-' && chArg0 != '/')
|
||
|
{
|
||
|
if (!strConfigURL)
|
||
|
strConfigURL = Arguments(argn);
|
||
|
else if (!strEnviroURL )
|
||
|
strEnviroURL = Arguments(argn);
|
||
|
else
|
||
|
Usage(1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch(chArg1)
|
||
|
{
|
||
|
case 'f':
|
||
|
fForceRestart = true;
|
||
|
break;
|
||
|
case 'u':
|
||
|
fUpdateBinaries = true;
|
||
|
fCreateMachines = true;
|
||
|
break;
|
||
|
case 't':
|
||
|
fSetTimeStamp = true;
|
||
|
argn++;
|
||
|
if (argn < Arguments.length)
|
||
|
strTimeStamp = Arguments(argn);
|
||
|
else
|
||
|
Usage(1);
|
||
|
break;
|
||
|
case 'log':
|
||
|
fCaptureLogs = true;
|
||
|
argn++;
|
||
|
if (argn < Arguments.length)
|
||
|
strCaptureLogDir = Arguments(argn);
|
||
|
else
|
||
|
Usage(2);
|
||
|
fCreateMachines = true;
|
||
|
break;
|
||
|
case 'logman':
|
||
|
fCaptureLogsFromMachine = true;
|
||
|
argn++;
|
||
|
if (argn < Arguments.length)
|
||
|
strCaptureLogMan = Arguments(argn);
|
||
|
else
|
||
|
Usage(3);
|
||
|
argn++;
|
||
|
if (argn < Arguments.length)
|
||
|
strCaptureLogManIdentity = Arguments(argn);
|
||
|
else
|
||
|
Usage(4);
|
||
|
break;
|
||
|
default:
|
||
|
Usage(5);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Insist that the config and enviro templates are supplied.
|
||
|
if (!fCaptureLogsFromMachine && (!strConfigURL || !strEnviroURL))
|
||
|
{
|
||
|
if (!fCaptureLogs)
|
||
|
{
|
||
|
WScript.Echo('!fCaptureLogsFromMachine' + !fCaptureLogsFromMachine);
|
||
|
WScript.Echo('!strConfigURL' + !strConfigURL);
|
||
|
WScript.Echo('!strEnviroURL' + !strEnviroURL);
|
||
|
Usage(6);
|
||
|
}
|
||
|
}
|
||
|
if (fCaptureLogsFromMachine && !fCaptureLogs)
|
||
|
Usage(7);
|
||
|
}
|
||
|
|
||
|
function AutoStart()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
var ret;
|
||
|
var err = new Error();
|
||
|
var PublicData;
|
||
|
|
||
|
LoadEnvironmentTemplate();
|
||
|
LoadConfigTemplate();
|
||
|
|
||
|
try
|
||
|
{
|
||
|
var objOD = new ActiveXObject('MTScript.ObjectDaemon', strBldMgr)
|
||
|
RemoteObj = objOD.OpenInterface(strBldMgrIdentity, 'MTScript.Remote', true);
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
if (strBldMgr && strBldMgr.length > 0)
|
||
|
err.description = 'Sorry. Could not connect to machine "' + strBldMgr + '\\' + strBldMgrIdentity + '"';
|
||
|
else
|
||
|
err.description = 'Sorry. Could not connect to the local machine.';
|
||
|
|
||
|
err.description += '\n\tVerify that the machine is available and that mtscript.exe\n\tis running on the machine.';
|
||
|
|
||
|
err.details = ex.description;
|
||
|
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
PublicData = RemoteObj.Exec('getpublic', 'root');
|
||
|
PublicData = eval(PublicData);
|
||
|
|
||
|
CommonVersionCheck("$DROPVERSION: V(2463.0 ) F(autostart.js )$", PublicData);
|
||
|
|
||
|
// Check the current mode of the machine. If it's idle, then switch it
|
||
|
// into master or standalone mode and get it going.
|
||
|
if (PublicData.strMode != 'idle')
|
||
|
{
|
||
|
if (fForceRestart)
|
||
|
{
|
||
|
WScript.Echo('The machine is not idle. Forcing a restart...');
|
||
|
|
||
|
ret = RemoteObj.Exec('setmode', 'idle');
|
||
|
|
||
|
WScript.Sleep(5000);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WScript.Echo('The machine is not idle. Use -f to force a restart.');
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while (!StartBuild() && fTryAgain)
|
||
|
{
|
||
|
ret = RemoteObj.Exec('setmode', 'idle');
|
||
|
|
||
|
WScript.Sleep(5000);
|
||
|
|
||
|
fTryAgain = false;
|
||
|
}
|
||
|
|
||
|
WScript.Echo('Build started successfully.');
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
WScript.Echo('An error occurred starting the build:');
|
||
|
WScript.Echo('\t' + ex);
|
||
|
WScript.Echo('');
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
function MachineInfo()
|
||
|
{
|
||
|
this.strName = '';
|
||
|
this.strEnlistment = '';
|
||
|
this.fPostBuild = false;
|
||
|
}
|
||
|
|
||
|
function StartBuild()
|
||
|
{
|
||
|
var ret = 'ok';
|
||
|
var err = new Error();
|
||
|
|
||
|
if (fSetTimeStamp)
|
||
|
{
|
||
|
ret = RemoteObj.Exec('setstringmap', "%today%=" + strTimeStamp);
|
||
|
}
|
||
|
|
||
|
if (ret == 'ok')
|
||
|
{
|
||
|
ret = RemoteObj.Exec('setconfig', strConfigXML);
|
||
|
|
||
|
if (ret == 'ok')
|
||
|
{
|
||
|
ret = RemoteObj.Exec('setenv', strEnviroXML);
|
||
|
|
||
|
if (ret == 'ok')
|
||
|
{
|
||
|
ret = RemoteObj.Exec('setmode', 'master');
|
||
|
|
||
|
if (ret == 'ok')
|
||
|
{
|
||
|
ret = RemoteObj.Exec('start', '');
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
err.description = 'An error occurred loading the environment template';
|
||
|
}
|
||
|
else if (ret == 'alreadyset')
|
||
|
{
|
||
|
// The machine is busy. Reset it if necessary.
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
err.description = 'An error occurred loading the build template';
|
||
|
}
|
||
|
else
|
||
|
err.description = 'An error occurred setting the timestamp.';
|
||
|
|
||
|
if (ret != 'ok')
|
||
|
{
|
||
|
if (!err.description)
|
||
|
err.description = 'A failure occurred communicating with the machine.';
|
||
|
|
||
|
err.details = ret;
|
||
|
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function LoadEnvironmentTemplate()
|
||
|
{
|
||
|
var xml = new ActiveXObject('Microsoft.XMLDOM');
|
||
|
var err = new Error();
|
||
|
var node;
|
||
|
|
||
|
fStandaloneMode = false;
|
||
|
|
||
|
xml.async = false;
|
||
|
// It's unlikely they have the schema file available for this template,
|
||
|
// so we turn off schema validation right now. The script engine will
|
||
|
// validate it when we start the build.
|
||
|
xml.validateOnParse = false;
|
||
|
xml.resolveExternals = false;
|
||
|
|
||
|
if (!xml.load(strEnviroURL) || !xml.documentElement)
|
||
|
{
|
||
|
err.description = 'Error loading the environment template ' + strEnviroURL;
|
||
|
err.details = xml.parseError.reason;
|
||
|
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
node = xml.documentElement.selectSingleNode('BuildManager');
|
||
|
|
||
|
if (!node)
|
||
|
{
|
||
|
err.description = 'Invalid environment template file (BuildManager tag missing): ' + strEnviroURL;
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
strBldMgr = node.getAttribute("Name");
|
||
|
strBldMgrIdentity = node.getAttribute("Identity");
|
||
|
|
||
|
if (!strBldMgr)
|
||
|
{
|
||
|
err.description = 'Invalid environment template file (BuildManager tag badly formatted): ' + strEnviroURL;
|
||
|
throw(err);
|
||
|
}
|
||
|
if (!strBldMgrIdentity)
|
||
|
strBldMgrIdentity = DEFAULT_IDENTITY_BM;
|
||
|
|
||
|
if (strBldMgr.toLowerCase() == '%localmachine%' ||
|
||
|
strBldMgr.toLowerCase() == '%remotemachine%')
|
||
|
{
|
||
|
err.description = 'Sorry, cannot use the local machine or remote machine templates from this script';
|
||
|
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
strEnviroXML = 'XML: ' + xml.xml;
|
||
|
|
||
|
if (fCreateMachines)
|
||
|
{
|
||
|
var node;
|
||
|
var strPostBuild;
|
||
|
var nodelist;
|
||
|
var objMach;
|
||
|
|
||
|
// Build the list of machines so we can copy the binaries from each
|
||
|
// one.
|
||
|
|
||
|
strPostBuild = node.getAttribute("PostBuildMachine");
|
||
|
|
||
|
nodelist = xml.documentElement.selectNodes('Machine');
|
||
|
|
||
|
for (node = nodelist.nextNode();
|
||
|
node;
|
||
|
node = nodelist.nextNode())
|
||
|
{
|
||
|
objMach = new MachineInfo();
|
||
|
|
||
|
objMach.strName = node.getAttribute("Name");
|
||
|
objMach.strEnlistment = node.getAttribute("Enlistment");
|
||
|
objMach.Identity = node.getAttribute("Identity");
|
||
|
if (!objMach.Identity || objMach.Identity == '')
|
||
|
objMach.Identity = DEFAULT_IDENTITY_BUILDER;
|
||
|
|
||
|
if (objMach.strName.toLowerCase() == strPostBuild.toLowerCase())
|
||
|
{
|
||
|
objMach.fPostBuild = true;
|
||
|
}
|
||
|
|
||
|
aMachines[aMachines.length] = objMach;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function LoadConfigTemplate()
|
||
|
{
|
||
|
var xml = new ActiveXObject('Microsoft.XMLDOM');
|
||
|
var err = new Error();
|
||
|
|
||
|
xml.async = false;
|
||
|
// It's unlikely they have the schema file available for this template,
|
||
|
// so we turn off schema validation right now. The script engine will
|
||
|
// validate it when we start the build.
|
||
|
xml.validateOnParse = false;
|
||
|
xml.resolveExternals = false;
|
||
|
|
||
|
if (!xml.load(strConfigURL) || !xml.documentElement)
|
||
|
{
|
||
|
err.description = 'Error loading the config template ' + strConfigURL;
|
||
|
err.details = xml.parseError.reason;
|
||
|
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
strConfigXML = 'XML: ' + xml.xml;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function GetBinariesUNC(mach)
|
||
|
{
|
||
|
var strUNC;
|
||
|
|
||
|
strUNC = '\\\\' + mach.strName + '\\';
|
||
|
|
||
|
try
|
||
|
{
|
||
|
var objOD = new ActiveXObject('MTScript.ObjectDaemon', mach.strName)
|
||
|
RemoteObj = objOD.OpenInterface(mach.Identity, 'MTScript.Remote', true);
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
err.description = 'Sorry. Could not connect to machine "' + mach.strName + '"';
|
||
|
|
||
|
err.description += '\n\tVerify that the machine is available and that mtscript.exe\n\tis running on the machine.';
|
||
|
|
||
|
err.details = ex.description;
|
||
|
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
strUNC += eval(RemoteObj.Exec('getpublic', 'PrivateData.aEnlistmentInfo[0].hEnvObj["_nttree"]'));
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
err.description = 'Machine ' + mach.strName + '\\' + mach.Identity + ' is not in the correct state. ';
|
||
|
err.description += 'The binaries location cannot be determined. (Was the machine reset?)';
|
||
|
|
||
|
err.details = ex.description;
|
||
|
|
||
|
throw(err);
|
||
|
}
|
||
|
|
||
|
strUNC = strUNC.replace(/\:/ig, '$');
|
||
|
|
||
|
return strUNC;
|
||
|
}
|
||
|
|
||
|
function DoBinariesUpdate()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
LoadEnvironmentTemplate();
|
||
|
LoadConfigTemplate();
|
||
|
|
||
|
// The postbuild machine must always be the first machine listed
|
||
|
var i;
|
||
|
|
||
|
for (i = 0; i < aMachines.length; i++)
|
||
|
{
|
||
|
if (aMachines[i].fPostBuild)
|
||
|
{
|
||
|
WScript.Echo(aMachines[i].strName + "\\" + aMachines[i].Identity + " " + GetBinariesUNC(aMachines[i]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < aMachines.length; i++)
|
||
|
{
|
||
|
if (!aMachines[i].fPostBuild)
|
||
|
{
|
||
|
WScript.Echo(aMachines[i].strName + "\\" + aMachines[i].Identity + " " + GetBinariesUNC(aMachines[i]));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
WScript.Echo('An error occurred during update binaries:');
|
||
|
WScript.Echo('\t' + ex);
|
||
|
WScript.Echo('');
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
function Error_ToString()
|
||
|
{
|
||
|
var i;
|
||
|
var str = 'Exception(';
|
||
|
|
||
|
/*
|
||
|
Only some error messages get filled in for "ex".
|
||
|
Specifically the text for disk full never seems
|
||
|
to get set by functions such as CreateTextFile().
|
||
|
|
||
|
|
||
|
*/
|
||
|
if (this.number != null && this.description == "")
|
||
|
{
|
||
|
switch(this.number)
|
||
|
{
|
||
|
case -2147024784:
|
||
|
this.description = "There is not enough space on the disk.";
|
||
|
break;
|
||
|
case -2147024894:
|
||
|
this.description = "The system cannot find the file specified.";
|
||
|
break;
|
||
|
case -2147023585:
|
||
|
this.description = "There are currently no logon servers available to service the logon request.";
|
||
|
break;
|
||
|
case -2147023170:
|
||
|
this.description = "The remote procedure call failed.";
|
||
|
break;
|
||
|
case -2147024837:
|
||
|
this.description = "An unexpected network error occurred";
|
||
|
break;
|
||
|
case -2147024890:
|
||
|
this.description = "The handle is invalid.";
|
||
|
break;
|
||
|
default:
|
||
|
this.description = "Error text not set for (" + this.number + ")";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
for(i in this)
|
||
|
{
|
||
|
str += i + ": " + this[i] + " ";
|
||
|
}
|
||
|
return str + ")";
|
||
|
}
|
||
|
|
||
|
// MyEval(expr)
|
||
|
// evaluating uneval'ed objects creates a bunch of junk local variables.
|
||
|
// by putting the eval call in a little subroutine, we avoid keeping those
|
||
|
// locals around.
|
||
|
function MyEval(expr)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
return eval(expr);
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
throw ex;
|
||
|
}
|
||
|
}
|
||
|
// CopyFileNoThrow(strSrc, strDst)
|
||
|
// Wrap the FSObj.CopyFile call to prevent it from
|
||
|
// throwing its errors.
|
||
|
function CopyFileNoThrow(strSrc, strDst)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
g_FSObj.CopyFile(strSrc, strDst, true);
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
WScript.Echo("Copy failed from " + strSrc + " to " + strDst + " " + ex);
|
||
|
return ex;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
// CreateFolderNoThrow(strSrc, strDst)
|
||
|
// Wrap the FSObj.MakeFolder call to prevent it from
|
||
|
// throwing its errors.
|
||
|
function CreateFolderNoThrow(strName)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
g_FSObj.CreateFolder(strName);
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
return ex;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
// DirScanNoThrow(strDir)
|
||
|
// Wrap the FSObj.Directory scan functionality to prevent it from
|
||
|
// throwing its errors.
|
||
|
function DirScanNoThrow(strDir)
|
||
|
{
|
||
|
var aFiles = new Array();
|
||
|
try
|
||
|
{
|
||
|
var folder;
|
||
|
var fc;
|
||
|
|
||
|
folder = g_FSObj.GetFolder(strDir);
|
||
|
fc = new Enumerator(folder.files);
|
||
|
for (; !fc.atEnd(); fc.moveNext())
|
||
|
{
|
||
|
aFiles[aFiles.length] = fc.item().Name; // fc.item() returns entire path, fc.item().Name is just the filename
|
||
|
}
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
aFiles.ex = ex;
|
||
|
}
|
||
|
return aFiles;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// CopyDirectory
|
||
|
// Do a non-recursive directory copy.
|
||
|
//
|
||
|
function CopyDirectory(strSrcDir, strDestDir)
|
||
|
{
|
||
|
var ret = true;
|
||
|
var ex;
|
||
|
var aFiles;
|
||
|
var strFileName = '';
|
||
|
var i;
|
||
|
|
||
|
WScript.Echo("Copy from " + strSrcDir + " to " + strDestDir);
|
||
|
aFiles = DirScanNoThrow(strSrcDir);
|
||
|
if (aFiles.ex)
|
||
|
{
|
||
|
WScript.Echo('Could not dirscan ' + strSrcDir + ', ex=' + ex);
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(i = 0; i < aFiles.length; ++i)
|
||
|
{
|
||
|
strFileName = aFiles[i];
|
||
|
ex = CopyFileNoThrow(
|
||
|
strSrcDir + '\\' + strFileName,
|
||
|
strDestDir + '\\' + strFileName);
|
||
|
|
||
|
if (ex)
|
||
|
{
|
||
|
WScript.Echo("\t FAILED: " + strFileName);
|
||
|
ret = false;
|
||
|
}
|
||
|
else
|
||
|
WScript.Echo("\t COPIED: " + strFileName);
|
||
|
}
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// CopyMTScriptLog()
|
||
|
// Copy the highest numbers "mtscript" log file
|
||
|
// from the specified machine.
|
||
|
//
|
||
|
function CopyMTScriptLog(strMachineName, strIdentity, strDestDir)
|
||
|
{
|
||
|
var nLargestIndex = 0;
|
||
|
var aReResult;
|
||
|
var re = new RegExp('^' + strMachineName + '_' + strIdentity + '_MTS.([0-9]+).log$', 'i'); // match files "BUILDCON2_MTScript.051.log"
|
||
|
var ex;
|
||
|
var aFiles;
|
||
|
var strFileName = '';
|
||
|
var i;
|
||
|
var strSrcDir = '\\\\' + strMachineName + "\\bc_build_logs";
|
||
|
|
||
|
aFiles = DirScanNoThrow(strSrcDir);
|
||
|
if (aFiles.ex)
|
||
|
WScript.Echo('Could not dirscan ' + strSrcDir + ', ex=' + ex );
|
||
|
else
|
||
|
{
|
||
|
for(i = 0; i < aFiles.length; ++i)
|
||
|
{
|
||
|
aReResult = re.exec(aFiles[i]);
|
||
|
if (aReResult && Number(aReResult[1]) > nLargestIndex)
|
||
|
{
|
||
|
nLargestIndex = Number(aReResult[1]);
|
||
|
strFileName = aFiles[i];
|
||
|
}
|
||
|
}
|
||
|
if (strFileName == '')
|
||
|
WScript.Echo("No MTSCRIPT log files on " + strMachineName);
|
||
|
else
|
||
|
{
|
||
|
WScript.Echo("Copy from " + strSrcDir + '\\' + strFileName + " to " + strDestDir + '\\' + g_FSObj.GetFilename(strFileName));
|
||
|
ex = CopyFileNoThrow(strSrcDir + '\\' + strFileName, strDestDir + '\\' + g_FSObj.GetFilename(strFileName));
|
||
|
if (ex)
|
||
|
{
|
||
|
WScript.Echo("Failed " + ex);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// CopyLogFiles()
|
||
|
// Copy the build log files from the given machines.
|
||
|
//
|
||
|
function CopyLogFiles(strDestDir, strBuildManagerName, strBuildManagerIdentity, aMachines)
|
||
|
{
|
||
|
var i;
|
||
|
var strDest;
|
||
|
|
||
|
CreateFolderNoThrow(strDestDir);
|
||
|
CopyMTScriptLog(strBuildManagerName, strBuildManagerIdentity, strDestDir);
|
||
|
for( i = 0; i < aMachines.length; ++i)
|
||
|
{
|
||
|
CopyMTScriptLog(aMachines[i].strName, aMachines[i].Identity, strDestDir);
|
||
|
}
|
||
|
/*
|
||
|
Note: The following code tries to guess the filenames of the build log files.
|
||
|
The "real" information can be had from the PublicData of the build manager.
|
||
|
PublicData.aBuild[0].aDepot[ x ].aTask[ y ].strLogPath
|
||
|
PublicData.aBuild[0].aDepot[ x ].aTask[ y ].strErrLogPath
|
||
|
|
||
|
Of course, that would require that the build manager is still alive and well.
|
||
|
*/
|
||
|
for( i = 0; i < aMachines.length; ++i)
|
||
|
{
|
||
|
strDest = strDestDir + "\\" + aMachines[i].strName;
|
||
|
CreateFolderNoThrow(strDest);
|
||
|
|
||
|
strDest += '\\' + aMachines[i].Identity;
|
||
|
CreateFolderNoThrow(strDest);
|
||
|
|
||
|
CopyDirectory("\\\\" + aMachines[i].strName + "\\bc_build_logs\\build_logs\\" + aMachines[i].Identity,
|
||
|
strDestDir + "\\" + aMachines[i].strName + '\\' + aMachines[i].Identity);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// CaptureLogsManager()
|
||
|
// Connect to the given build manager
|
||
|
// and query it for its list of build machines,
|
||
|
// The copy the MTSCRIPT and build log files from
|
||
|
// each of those machines.
|
||
|
//
|
||
|
function CaptureLogsManager(strLogDir, strMachineName, strIdentity)
|
||
|
{
|
||
|
var strMode;
|
||
|
var obj;
|
||
|
try
|
||
|
{
|
||
|
WScript.Echo("Attempting connection to " + strMachineName + "\\" + strIdentity);
|
||
|
obj = new ActiveXObject('MTScript.Proxy');
|
||
|
WScript.Echo("Now connecting");
|
||
|
obj.ConnectToMTScript(strMachineName, strIdentity, false);
|
||
|
|
||
|
strMode = obj.Exec('getpublic', 'PublicData.strMode');
|
||
|
strMode = MyEval(strMode);
|
||
|
if (strMode == 'idle')
|
||
|
{
|
||
|
WScript.Echo(strMachineName + "\\" + strIdentity + " is currently idle");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
aMachines = obj.Exec('getpublic', 'PrivateData.objEnviron.Machine');
|
||
|
aMachines = MyEval(aMachines);
|
||
|
for( i = 0; i < aMachines.length; ++i)
|
||
|
{
|
||
|
aMachines[i].strName = aMachines[i].Name;
|
||
|
if (!aMachines[i].Identity || aMachines[i].Identity == '')
|
||
|
aMachines[i].Identity = DEFAULT_IDENTITY_BUILDER;
|
||
|
}
|
||
|
CopyLogFiles(strLogDir, strMachineName, strIdentity, aMachines);
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
WScript.Echo("CaptureLogsManager '" + strMachineName + "\\" + strIdentity + "' failed, ex=" + ex);
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// CaptureLogsEnviro()
|
||
|
// Read the supplied environment template
|
||
|
// and copy the MTSCRIPT and build logs
|
||
|
// from each of the specifed build machines.
|
||
|
//
|
||
|
function CaptureLogsEnviro(strLogDir)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
var ret;
|
||
|
if (!strEnviroURL && strConfigURL)
|
||
|
{
|
||
|
strEnviroURL = strConfigURL;
|
||
|
strConfigURL = null;
|
||
|
}
|
||
|
LoadEnvironmentTemplate();
|
||
|
|
||
|
ret = CopyLogFiles(strLogDir, strBldMgr, strBldMgrIdentity, aMachines);
|
||
|
}
|
||
|
catch(ex)
|
||
|
{
|
||
|
WScript.Echo('An error occurred capturing log files:');
|
||
|
WScript.Echo('\t ex=' + ex);
|
||
|
WScript.Echo('');
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
CommonVersionCheck(strLocalVersion, PublicData)
|
||
|
|
||
|
Ensure that this script and the remote script are running the same version.
|
||
|
A copy of this function exists in:
|
||
|
autostart.js
|
||
|
bldcon.hta
|
||
|
utils.js
|
||
|
*/
|
||
|
function CommonVersionCheck(strLocalVersion, PublicData)
|
||
|
{
|
||
|
var err = new Error();
|
||
|
var reBuildNum = new RegExp("V\\(([#0-9. ]+)\\)");
|
||
|
var aLocal = reBuildNum.exec(strLocalVersion);
|
||
|
var aPublicBuildNum;
|
||
|
|
||
|
if (!PublicData.strDataVersion)
|
||
|
{
|
||
|
err.description = "autostart version mismatch";
|
||
|
err.details = "Build Manager does not have a version string";
|
||
|
throw err;
|
||
|
}
|
||
|
aPublicBuildNum = reBuildNum.exec(PublicData.strDataVersion);
|
||
|
if (!aLocal || !aPublicBuildNum)
|
||
|
{
|
||
|
err.description = "Invalid version format";
|
||
|
err.details = "UI Version: " + strLocalVersion + ", Build Manager Version: " + PublicData.strDataVersion;
|
||
|
throw err;
|
||
|
}
|
||
|
|
||
|
if (aLocal[1] != aPublicBuildNum[1])
|
||
|
{
|
||
|
err.description = "Version mismatch";
|
||
|
err.details = "UI Version: " + strLocalVersion + ", Build Manager Version: " + PublicData.strDataVersion;
|
||
|
throw err;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function Usage(x)
|
||
|
{
|
||
|
WScript.Echo('');
|
||
|
WScript.Echo('Usage: bcauto [-f] [-u] [-t] <config> <enviro>');
|
||
|
WScript.Echo('');
|
||
|
WScript.Echo(' -f : If the machine is busy, terminate the build and restart.');
|
||
|
WScript.Echo(' -u : Update: Recombine all the binaries from each of the build');
|
||
|
WScript.Echo(' machines after taking incremental fixes so that postbuild');
|
||
|
WScript.Echo(' can be run again.');
|
||
|
WScript.Echo(' -t <timestamp> : Use timestamp (e.g. 2001/12/15:12:00)');
|
||
|
WScript.Echo(' -log dir : Capture log files to specified directory');
|
||
|
WScript.Echo(' -logman machine identity : Query "machine" with "identity" for list of');
|
||
|
WScript.Echo(' build machines instead of template files.');
|
||
|
WScript.Echo(' ("machine" must be a build manager)');
|
||
|
WScript.Echo(' config : URL or path for the build template.');
|
||
|
WScript.Echo(' enviro : URL or path for the environment template.');
|
||
|
WScript.Echo('');
|
||
|
WScript.Quit(1);
|
||
|
}
|