private void HandleNewFile(FileInfo fi) { try { bool success = false; while (!success) { try { using (TextReader tr = new StreamReader(fi.FullName)) { lock (IncomingQueueLock) { incoming.Enqueue(XMLSerializable.FromXML <AutomationMessage>(tr.ReadToEnd())); } } success = true; } catch (IOException) { //eat it } catch (System.UnauthorizedAccessException) { //eat it } } if (success && fi.Exists) { fi.Delete(); } } catch (Exception ex) { EventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error); //invalid file, rename it try { fi.MoveTo(fi.FullName + ".bad"); } catch (Exception ex2) { EventLog.WriteEntry(ex2.ToString(), EventLogEntryType.Error); //eat it } } lock (ExecuteLock) { Monitor.PulseAll(ExecuteLock); } }
public static Job FromXML(string xmlPath) { return(XMLSerializable.FromXMLFile <Job>(xmlPath)); }
public static ConfigurationType FromXML(string xmlPath) { return(XMLSerializable.FromXMLFile <ConfigurationType>(xmlPath)); }
public static Sequence FromXML(string xmlPath) { return(XMLSerializable.FromXMLFile <Sequence>(xmlPath)); }
public static Package FromXML(string xmlPath) { return(XMLSerializable.FromXMLFile <Package>(xmlPath)); }
public static JobCollection FromXML(string xmlPath) { return(XMLSerializable.FromXMLFile <JobCollection>(xmlPath)); }
public static ISO FromXML(string xmlPath) { return(XMLSerializable.FromXMLFile <ISO>(xmlPath)); }
//void queue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e) //{ // //TODO catch MessageQueueException // MessageQueue mq = (MessageQueue)sender; // Message m = mq.EndReceive(e.AsyncResult); // lock (IncomingQueueLock) // { // incoming.Enqueue(e.Message); // } // lock (ExecuteLock) // { // Monitor.PulseAll(ExecuteLock); // } // mq.BeginReceive(); //} protected override void OnStart(string[] args) { #region Load VM Configs FileInfo vmConfigFile = new FileInfo(Path.Combine(AppConfig.ExecutingDir.FullName, "vm_list.txt")); if (vmConfigFile.Exists) { using (TextReader tr = new StreamReader(vmConfigFile.FullName)) { while (true) { string line = tr.ReadLine(); if (line == null) { break; } string[] parts = line.Split(','); if (parts.Length != 4) { //skip the line continue; } string config = parts[0].Trim(); string path = parts[1].Trim(); VirtualMachine vm = new VirtualMachine(parts[2].Trim(), parts[3].Trim(), vmHost.GetVMConnectionFromPath(path)); vmMap[config] = vm; } } } #endregion #region Test Configuration //first check connection to ESX/vSphere try { vmHost.Login(); } catch (System.Web.Services.Protocols.SoapException ex) { EventLog.WriteEntry("Error while logging in. Exception: " + Environment.NewLine + ex.ToString() + Environment.NewLine + ex.Detail.OuterXml, EventLogEntryType.Error); throw; } catch (System.Net.WebException ex) { EventLog.WriteEntry("Error while logging in. Exception: " + Environment.NewLine + ex.ToString() + Environment.NewLine + ex.Status, EventLogEntryType.Error); throw; } catch (Exception ex) { EventLog.WriteEntry("Error while logging in. Exception: " + Environment.NewLine + ex.ToString(), EventLogEntryType.Error); throw; } //now check each VM foreach (VirtualMachine vm in vmMap.Values) { if (!vm.HasValidConnection) { EventLog.WriteEntry("Error: Could not find VM \"" + vm.Identifier + "\"", EventLogEntryType.Warning); } } #endregion #region Load Jobs DirectoryInfo import = new DirectoryInfo(Path.Combine(AppConfig.ExecutingDir.FullName, "jobs")); if (import.Exists) { foreach (FileInfo jobFile in import.GetFiles("*.job")) { try { Job j = null; using (TextReader tr = new StreamReader(jobFile.FullName)) { j = XMLSerializable.FromXML <Job>(tr.ReadToEnd()); } FileInfo jobStatusFile = new FileInfo(Path.Combine(import.FullName, j.JobID + ".sta")); JobStatus js = null; using (TextReader tr = new StreamReader(jobStatusFile.FullName)) { js = XMLSerializable.FromXML <JobStatus>(tr.ReadToEnd()); } jobs[j] = js; } catch (Exception ex) { EventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error); continue; } } import.Delete(true); } #endregion #region Handle Messages //look for existing files (messages) FileInfo[] existingFiles = AppConfig.Inbox.GetFiles("*.xml"); //start looking for new files StartWatchingDir(); //handle existing files (messages) foreach (FileInfo fi in existingFiles) { HandleNewFile(fi); } #endregion //start worker loops mainLoopRunning = true; if (!mainLoop.IsAlive) { mainLoop.Start(); } jobLoopRunning = true; if (!jobLoop.IsAlive) { jobLoop.Start(); } //Set up background thread to periodically check jobs Thread backgroundChecker = new Thread(new ThreadStart(delegate { try { while (mainLoopRunning) { CheckJobs(); Thread.Sleep(TimeSpan.FromMinutes(1)); } } catch (ThreadAbortException) { } //eat it })); backgroundChecker.IsBackground = true; backgroundChecker.Start(); EventLog.WriteEntry("JobManagerService started successfully."); }
public void Run() { try { FileInfo mapNetBatchFile = new FileInfo(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "map.bat")); //if the network drive is disconected, then we will be unable to get to the server inbox, in which case we should try to remap if (!AppConfig.ServerInbox.Exists && mapNetBatchFile.Exists) { using (System.Diagnostics.Process p = new System.Diagnostics.Process()) { p.StartInfo.WorkingDirectory = mapNetBatchFile.Directory.FullName; p.StartInfo.FileName = mapNetBatchFile.Name; p.StartInfo.CreateNoWindow = true; p.StartInfo.UseShellExecute = true; p.Start(); p.WaitForExit(); } } int packageToRun = 0; JobResult result = new JobResult(); result.Completed = true; //string sendQueueName = @"FormatName:DIRECT=OS:hammerbuildvm\Private$\jobmanager"; //string sendQueueName = @"FormatName:DIRECT=OS:ryanadams2\Private$\test2"; //jci.LogString("Connecting to Job Manager receive queue (" + sendQueueName + ")"); MessageSendRecieve msr = new MessageSendRecieve(AppConfig.ServerInbox, AppConfig.ServerOutbox); //jci.LogString("Permission = " + msr.RemoteMessageQueue.AccessMode.ToString()); //look for an existing job to run/continue before getting a new job from the server FileInfo jobXML = new FileInfo(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "job.xml")); if (jobXML.Exists) { using (TextReader tr = new StreamReader(jobXML.FullName)) { j = XMLSerializable.FromXML <Job>(tr.ReadToEnd()); if (j.Properties.ContainsKey("PackageToRun")) { packageToRun = Int32.Parse(j.Properties["PackageToRun"]); } } try { //rename the job file so the next run doesn't automatically use it. The job.xml file will be put back //as part of jci.StartupOnNextRun if it is meant to be continued after a restart string lastFile = jobXML.FullName + ".old"; if (File.Exists(lastFile)) { File.Delete(lastFile); } File.Move(jobXML.FullName, lastFile); } catch (Exception ex) { //if the delete fails lets log it, but it isn't critical so let's eat the exception LogString("Could not delete existing job.xml file: " + ex.ToString()); } //look for an existing JobResult to pull in FileInfo jobResultXML = new FileInfo(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml")); if (jobResultXML.Exists) { try { using (TextReader tr = new StreamReader(jobResultXML.FullName)) { result = XMLSerializable.FromXML <JobResult>(tr.ReadToEnd()); } } catch (Exception ex) { //log, but eat it LogString(ex.ToString()); } } } else { LogString("Requesting Jobs from Job Manager"); string messageID = msr.RequestJob(); LogString("Sent request with message id: " + messageID); LogString("Waiting for Job response from Job Manager"); j = msr.WaitForJob(messageID, DEFAULT_JOB_WAIT); if (j == null) { LogString("No Jobs Available"); return; } try { LogString("Found Job: " + j.JobID); if (baseDir.Exists) { baseDir.Delete(true); //TODO wait for files to be deleted? } baseDir.Create(); List <string> keys = new List <string>(j.ISOs.Keys); foreach (string isoName in keys) { FileInfo isoPath = new FileInfo(j.ISOs[isoName]); string destPath = Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, isoPath.Name); LogString("Copying ISO from \"" + isoPath.Directory.FullName + "\" to \"" + destPath + "\""); isoPath.CopyTo(destPath); j.ISOs[isoName] = destPath; } if (j.Properties == null) { j.Properties = new SerializableDictionary <string, string>(); } } catch (Exception ex) { LogString(ex.ToString()); result.Completed = false; ExecutionResult er = new ExecutionResult(ex.ToString(), null); result.ExecutionResults.Add(er); Logger.Instance.Pause(); result.Logs.Add(FileData.FromFile(new FileInfo(Logger.Instance.FileName))); Logger.Instance.Resume(); LogString("Sending Job Result"); msr.ReportJobStatus(new JobCompleted(j, result)); LogString("Job Result Sent"); return; } } if (j.Packages.Count == 0) { Logger.Instance.Pause(); result.Logs.Add(FileData.FromFile(new FileInfo(Logger.Instance.FileName))); Logger.Instance.Resume(); } while (packageToRun < j.Packages.Count) { runningPackageDir = new DirectoryInfo(Path.Combine(baseDir.FullName, packageToRun.ToString())); ExecutablePackage ep = j.Packages[packageToRun]; runningPackage = ep; ExecutionResult er = new ExecutionResult(); try { if (!ep.ContentDirectory.ToLower().Equals(runningPackageDir.FullName.ToLower())) { if (runningPackageDir.Exists) { runningPackageDir.Delete(true); } runningPackageDir.Create(); LogString("Copying data from \"" + ep.ContentDirectory + "\" to \"" + runningPackageDir.FullName + "\""); DirectoryData.FromDirectory(new DirectoryInfo(ep.ContentDirectory)).DumpContentsToDir(runningPackageDir); ep.ContentDirectory = runningPackageDir.FullName; } LogString("Loading external test DLL: " + ep.JobRunnerDLLName + " , " + ep.JobRunnerClassName); JobRunner jr = LoadJobRunner(ep.JobRunnerClassName, Path.Combine(runningPackageDir.FullName, ep.JobRunnerDLLName)); LogString("Executing Execute() method on external DLL"); er = jr.Execute(this); } catch (Exception ex) { LogString(ex.ToString()); result.Completed = false; er = new ExecutionResult(ex.ToString(), null); } Logger.Instance.Pause(); result.Logs.Add(FileData.FromFile(new FileInfo(Logger.Instance.FileName))); Logger.Instance.Resume(); if (er != null) { result.ExecutionResults.Add(er); } //lets save the current job result using (TextWriter tw = new StreamWriter(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml"), false)) { tw.Write(result.ToXML()); } if (er == null) { //The automation is likely not finished, the computer is likely going to reboot and //we want this execution to continue after reboot so we should exit now instead of going to the next package. //the executable package should have already called startuponnextrun return; } if (!er.Success) { //stop on first error break; } packageToRun++; j.Properties["PackageToRun"] = packageToRun.ToString(); if (er.Success && er.RestartAfter) { StartupOnNextRun(); LogString("Restarting ..."); system.Shutdown(true); return; } } LogString("Sending Job Result"); msr.ReportJobStatus(new JobCompleted(j, result)); LogString("Job Result Sent"); //cleanup if (File.Exists(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml"))) { File.Delete(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml")); } if (ShutdownOnCompletion) { LogString("Shuting Down ..."); system.Shutdown(false); //so, lets exit the program System.Windows.Forms.Application.Exit(); } } catch (ThreadAbortException) { //eat it, get out right away. Program is exiting or user has stopped automation return; } catch (Exception e) { LogString("Exception in thread: " + e.ToString()); return; } }