Windows-Server-2003/tools/bcdazzle.js

383 lines
12 KiB
JavaScript

/*
Dazzle.js:
Usage:
Dazzle.js [-e env_templ.xml] [-man buildmanager Identity] [-m macros_file]
Get a list of machines
For each machine
create an alias for each depot on the machine, except root.
BC1 jporkka1\bldcon1 _x86 _fre _x86fre _postbuild _root _inetsrv
BC2 jporkka1\bldcon2 _x86 _fre _x86fre _ds _sdktools
BC3 jporkka1\bldcon3 _x86 _fre _x86fre _termsrv
*/
var DEFAULT_IDENTITY_BM = "BuildManager";
var DEFAULT_IDENTITY_BUILDER = "Build";
Error.prototype.toString = Error_ToString;
var g_FSObj = new ActiveXObject("Scripting.FileSystemObject"); // Parse input Parameter List
var g_aBuildManagers = new Array();
var g_aServersFiles = new Array();
var g_aMacrosFiles = new Array();
var g_hMacrosWritten = new Object();
ParseArguments(WScript.Arguments);
main();
WScript.Quit(0);
function main()
{
var PrivateData;
var objFile;
var objMacroFile;
var i;
var strMacroFileName;
var strFileName;
var strCmdLine;
for(i = 0; i < g_aBuildManagers.length; ++i)
{
WScript.Echo("Build manager: " + g_aBuildManagers[i].strMachine + "\\" + g_aBuildManagers[i].strMachineIdentity);
PrivateData = GetEnvironment(g_aBuildManagers[i].strMachine, g_aBuildManagers[i].strMachineIdentity);
if (PrivateData)
{
strFileName = CreateConfigFileName("Servers", g_aBuildManagers[i].strMachine, g_aBuildManagers[i].strMachineIdentity);
g_aServersFiles[g_aServersFiles.length] = strFileName;
objFile = g_FSObj.CreateTextFile(strFileName, true);
objFile.WriteLine("######################################################");
objFile.WriteLine("# Servers for build manager: " + g_aBuildManagers[i].strMachine + "\\" + g_aBuildManagers[i].strMachineIdentity);
if (!strMacroFileName)
{
strMacroFileName = CreateConfigFileName("Macros", g_aBuildManagers[i].strMachine, g_aBuildManagers[i].strMachineIdentity);
objMacroFile = g_FSObj.CreateTextFile(strMacroFileName, true);
WriteMacro(objMacroFile, 'root', null);
WriteMacro(objMacroFile, 'postbuild', null);
}
WriteServerInfo(objFile, objMacroFile, PrivateData);
objFile.Close();
}
}
strCmdLine = "BCDazzle.exe ";
if (objMacroFile)
{
objMacroFile.Close();
strCmdLine += " -m " + strMacroFileName;
}
if (g_aServersFiles.length)
strCmdLine += " -s " + g_aServersFiles.join(" -s ");
if (g_aMacrosFiles.length)
strCmdLine += " -m " + g_aMacrosFiles.join(" -m ");
var objShell;
objShell = WScript.CreateObject( "WScript.Shell" )
WScript.Echo("Running " + strCmdLine);
objShell.Run(strCmdLine, 1);
}
// macro com ( _com ) "CD /d %sdxroot%\\com\n"
function WriteMacro(objMacroFile, strDepotName, strDepotPath)
{
if (!g_hMacrosWritten[strDepotName])
{
g_hMacrosWritten[strDepotName] = true;
objMacroFile.WriteLine('macro '
+ strDepotName
+ ' ( _' + strDepotName
+ ' ) "cd /d %sdxroot%'
+ (strDepotPath ? '\\\\' + strDepotPath : '')
+ '\\n"');
}
}
function CreateConfigFileName(strName, strMachine, strMachineIdentity)
{
var strResult =
g_FSObj.GetSpecialFolder(2)
+ "\\"
+ strName
+ "_"
+ strMachine
+ "_"
+ strMachineIdentity
+ ".txt";
return strResult;
}
function ParseArguments(Arguments)
{
var strArg;
var chArg0;
var chArg1;
var argn;
var objBM;
for(argn = 0; argn < Arguments.length; argn++)
{
strArg = Arguments(argn);
chArg0 = strArg.charAt(0);
chArg1 = strArg.toLowerCase().slice(1);
if (chArg0 != '-' && chArg0 != '/')
Usage(1);
else
{
switch(chArg1)
{
case 'e':
if (argn + 1 < Arguments.length)
objBM = LoadEnvironmentTemplate(Arguments(argn + 1));
else
Usage(2);
if (!objBM)
Usage(3);
g_aBuildManagers[g_aBuildManagers.length] = objBM;
argn++;
break;
case 'man':
objBM = new Object;
if (argn + 2 < Arguments.length)
{
objBM.strMachine = Arguments(argn + 1);
objBM.strMachineIdentity = Arguments(argn + 2);
}
else
Usage(4);
g_aBuildManagers[g_aBuildManagers.length] = objBM;
argn += 2;
break;
case 'm':
if (argn + 1 < Arguments.length)
g_aMacrosFiles[g_aMacrosFiles.length] = Arguments(argn + 1);
else
Usage(5);
argn++;
break;
default:
Usage(4);
break;
}
}
}
}
// 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;
}
}
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 + ")";
}
function WriteServerInfo(objFile, objMacroFile, PrivateData)
{
var i;
var j;
var strLine;
var aMachines = PrivateData.objEnviron.Machine;
var strDepotName;
for(i = 0; i < aMachines.length; ++i)
{
strLine = aMachines[i].Name
+ " "
+ aMachines[i].Name + "\\BldCon_" + aMachines[i].Identity
+ " _" + PrivateData.objConfig.Options.BuildType
+ " _" + PrivateData.objConfig.Options.Platform;
if (PrivateData.objConfig.Options.Aliases)
strLine += " " + PrivateData.objConfig.Options.Aliases;
if (aMachines[i].Aliases)
strLine += " " + aMachines[i].Aliases;
if (aMachines[i].Name == PrivateData.objEnviron.BuildManager.PostBuildMachine)
strLine += " _root _postbuild";
for(j = 0; j < aMachines[i].Depot.length; ++j)
{
strDepotName = aMachines[i].Depot[j].toLowerCase();
if (strDepotName != 'root')
{
strLine += " _" + strDepotName;
WriteMacro(objMacroFile, strDepotName, strDepotName);
}
}
objFile.WriteLine(strLine);
}
}
function GetEnvironment(strMachineName, strIdentity)
{
var strMode;
var obj;
var PrivateData = new Object();
try
{
WScript.Echo("Attempting connection to " + strMachineName + "\\" + strIdentity);
obj = new ActiveXObject('MTScript.Proxy');
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 null;
}
PrivateData.objConfig = obj.Exec('getpublic', 'PrivateData.objConfig');
PrivateData.objConfig = MyEval(PrivateData.objConfig);
PrivateData.objEnviron = obj.Exec('getpublic', 'PrivateData.objEnviron');
PrivateData.objEnviron = MyEval(PrivateData.objEnviron);
var result;
WScript.Echo("Starting Remote Razzle Windows...");
result = obj.Exec('remote','');
WScript.Echo("Remote result is " + result);
return PrivateData;
}
catch(ex)
{
WScript.Echo("CaptureLogsManager '" + strMachineName + "\\" + strIdentity + "' failed, ex=" + ex);
}
return null;
}
function LoadEnvironmentTemplate(strEnviroURL)
{
var xml = new ActiveXObject('Microsoft.XMLDOM');
var err = new Error();
var node;
var objBM = new Object();
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);
}
objBM.strMachine = node.getAttribute("Name");
objBM.strMachineIdentity = node.getAttribute("Identity");
if (!objBM.strMachine)
{
err.description = 'Invalid environment template file (BuildManager tag badly formatted): ' + strEnviroURL;
throw(err);
}
if (!objBM.strMachineIdentity)
objBM.strMachineIdentity = DEFAULT_IDENTITY_BM;
if (objBM.strMachine.toLowerCase() == '%localmachine%' ||
objBM.strMachine.toLowerCase() == '%remotemachine%')
{
err.description = 'Sorry, cannot use the local machine or remote machine templates from this script';
throw(err);
}
return objBM;
}
function Usage(x)
{
WScript.Echo('');
WScript.Echo('Usage: dazzle [-e env_template.xml] [-man bldmgr identity] [-m macros]');
WScript.Echo('');
WScript.Echo(' -e env_template.xml : Use the specific environment template to find the build machines');
WScript.Echo(' -man bldmgr identity : Query "bldmgr" with "identity" for list of');
WScript.Echo(' build machines instead of template files.');
WScript.Echo(' -m macros.txt : Load the macros file.');
WScript.Echo('');
WScript.Echo(' You may specify multiple -e, -man and -m options.');
WScript.Echo('');
WScript.Quit(1);
}