/// <summary> /// Process a single dataset and fetch the info about it. /// </summary> protected override void ProcessRecord() { var trimmedDSName = DatasetName.Trim(); if (_resultsCache.Value[trimmedDSName] is PSGRIDDatasetInfo cHit) { WriteObject(cHit); } else { // Setup for verbosity if we need it. var listener = new PSListener(this); Trace.Listeners.Add(listener); try { // Where are we going to be doing query on - we need a machine. var sm = JobParser.GetSubmissionMachine(); // Get the remove environment configured if it needs to be if (_connection == null) { _connection = new SSHConnection(sm.MachineName, sm.UserName); _connection .Apply(() => DisplayStatus("Setting up ATLAS")) .setupATLAS() .Apply(() => DisplayStatus("Setting up Rucio")) .setupRucio(_gridCredentials.Username) .Apply(() => DisplayStatus("Acquiring GRID credentials")) .VomsProxyInit("atlas", failNow: () => Stopping); } // Great - get the info on this dataset. var fileInfo = _connection .Apply(() => DisplayStatus($"Checking for info on {trimmedDSName}.")) .FileInfoFromGRID(trimmedDSName, failNow: () => Stopping); // Next, build the resulting thingy. var r = new PSGRIDDatasetInfo() { DatasetName = trimmedDSName, nFiles = fileInfo.Count, TotalSizeMB = (int)fileInfo.Sum(fi => fi.size), FileInfo = fileInfo.ToArray() }; _resultsCache.Value[trimmedDSName] = r; using (var pp = listener.PauseListening()) { WriteObject(r); } } finally { Trace.Listeners.Remove(listener); } } }
/// <summary> /// Create the connection, and setup the appropriate stuff for using AMI. /// </summary> /// <returns></returns> private SSHConnection GetConnection() { if (_connection != null) { return(_connection); } // Establish the connection var sm = JobParser.GetSubmissionMachine(); var connection = new SSHConnection(sm.MachineName, sm.UserName); // Setup for using ami. connection.Apply(() => DisplayStatus("Setting up ATLAS")) .setupATLAS() .Apply(() => DisplayStatus("Setting up pyAMI")) .ExecuteLinuxCommand("lsetup pyami") .Apply(() => DisplayStatus("Acquiring GRID credentials")) .VomsProxyInit("atlas", failNow: () => Stopping); // And the connection is now ready for use! _connection = connection; return(_connection); }
/// <summary> /// Load up the job requested. Fail, obviously, if we can't. /// </summary> protected override void ProcessRecord() { // Setup for verbosity if we need it. var listener = new PSListener(this); Trace.Listeners.Add(listener); try { // Get the job var job = JobParser.FindJob(JobName, JobVersion); // Get the expected resulting dataset name. Since this will be a personal // dataset, we need to get the GRID info. var originalDatasetName = DatasetName.Trim(); string resultDatasetName = job.ResultingDataSetName(originalDatasetName, _gridCredentials, JobIteration); // See if there is already a job defined that will produce this var pandaJob = (resultDatasetName + "/").FindPandaJobWithTaskName(useCacheIfPossible: !DoNotUsePandaTaskCache.IsPresent); if (pandaJob == null) { // Where are we going to be doing the submission on? var sm = JobParser.GetSubmissionMachine(); // Get the remove environment configured if it needs to be var firstJob = false; if (_connection == null) { firstJob = true; _connection = new SSHConnection(sm.MachineName, sm.UserName); _connection .Apply(() => DisplayStatus("Setting up ATLAS")) .setupATLAS(dumpOnly: WhatIf.IsPresent) .Apply(() => DisplayStatus("Setting up Rucio")) .setupRucio(_gridCredentials.Username, dumpOnly: WhatIf.IsPresent) .Apply(() => DisplayStatus("Acquiring GRID credentials")) .VomsProxyInit("atlas", failNow: () => Stopping, dumpOnly: WhatIf.IsPresent); } // Check to see if the original dataset exists. We will use the location known as Local for doing the // setup, I suppose. var files = _connection .Apply(() => DisplayStatus("Checking dataset exists on the GRID")) .FilelistFromGRID(originalDatasetName, failNow: () => Stopping, dumpOnly: WhatIf.IsPresent); if (files.Length == 0 && !WhatIf.IsPresent) { throw new ArgumentException($"Dataset '{originalDatasetName}' has zero files - won't submit a job against it!"); } // Submit the job _connection .SubmitJobAsync(job, originalDatasetName, resultDatasetName, DisplayStatus, failNow: () => Stopping, sameJobAsLastTime: !firstJob, dumpOnly: WhatIf.IsPresent) .WaitAndUnwrapException(); // Try to find the job again if requested. The submission can take a very long time to show up in // big panda, so skip unless requested. if (WaitForPandaRegistration) { var pandJobResult = Policy .Handle <InvalidOperationException>() .WaitAndRetryForever(nthRetry => TimeSpan.FromMinutes(1), (e, ts) => { WriteWarning($"Failed to find the submitted panda job on bigpanda: {e.Message}. Will wait one minute and try again."); }) .ExecuteAndCapture(() => FindPandaJobForDS(resultDatasetName)); if (pandJobResult.Outcome != OutcomeType.Successful) { throw pandJobResult.FinalException; } pandaJob = pandJobResult.Result; } } // Return a helper obj that contains the info about this job that can be used by other commands. if (pandaJob != null) { var r = new AtlasPandaTaskID() { ID = pandaJob.jeditaskid, Name = pandaJob.taskname }; using (var pp = listener.PauseListening()) { WriteObject(r); } } } finally { Trace.Listeners.Remove(listener); } }