ultravisor 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/launch.json +11 -0
- package/.claude/ultravisor-dev-config.json +3 -0
- package/.ultravisor.json +426 -0
- package/docs/README.md +63 -0
- package/package.json +12 -8
- package/source/Ultravisor.cjs +22 -3
- package/source/cli/Ultravisor-CLIProgram.cjs +35 -23
- package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +29 -18
- package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +62 -19
- package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +27 -15
- package/source/config/Ultravisor-Default-Command-Configuration.cjs +5 -3
- package/source/services/Ultravisor-ExecutionEngine.cjs +1039 -0
- package/source/services/Ultravisor-ExecutionManifest.cjs +399 -0
- package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
- package/source/services/Ultravisor-Hypervisor.cjs +38 -83
- package/source/services/Ultravisor-StateManager.cjs +241 -0
- package/source/services/Ultravisor-TaskTypeRegistry.cjs +143 -0
- package/source/services/tasks/Ultravisor-TaskType-Base.cjs +105 -0
- package/source/services/tasks/control/Ultravisor-TaskType-IfConditional.cjs +148 -0
- package/source/services/tasks/control/Ultravisor-TaskType-LaunchOperation.cjs +187 -0
- package/source/services/tasks/control/Ultravisor-TaskType-SplitExecute.cjs +184 -0
- package/source/services/tasks/data/Ultravisor-TaskType-ReplaceString.cjs +82 -0
- package/source/services/tasks/data/Ultravisor-TaskType-SetValues.cjs +81 -0
- package/source/services/tasks/data/Ultravisor-TaskType-StringAppender.cjs +101 -0
- package/source/services/tasks/file-io/Ultravisor-TaskType-ReadFile.cjs +103 -0
- package/source/services/tasks/file-io/Ultravisor-TaskType-WriteFile.cjs +117 -0
- package/source/services/tasks/interaction/Ultravisor-TaskType-ErrorMessage.cjs +54 -0
- package/source/services/tasks/interaction/Ultravisor-TaskType-ValueInput.cjs +62 -0
- package/source/web_server/Ultravisor-API-Server.cjs +237 -124
- package/test/Ultravisor_browser_tests.js +2226 -0
- package/test/Ultravisor_tests.js +1143 -5830
- package/webinterface/css/ultravisor.css +23 -0
- package/webinterface/package.json +6 -3
- package/webinterface/source/Pict-Application-Ultravisor.js +93 -73
- package/webinterface/source/cards/FlowCard-CSVTransform.js +43 -0
- package/webinterface/source/cards/FlowCard-Command.js +86 -0
- package/webinterface/source/cards/FlowCard-ComprehensionIntersect.js +40 -0
- package/webinterface/source/cards/FlowCard-Conditional.js +87 -0
- package/webinterface/source/cards/FlowCard-CopyFile.js +55 -0
- package/webinterface/source/cards/FlowCard-End.js +29 -0
- package/webinterface/source/cards/FlowCard-GetJSON.js +55 -0
- package/webinterface/source/cards/FlowCard-GetText.js +54 -0
- package/webinterface/source/cards/FlowCard-Histogram.js +176 -0
- package/webinterface/source/cards/FlowCard-LaunchOperation.js +82 -0
- package/webinterface/source/cards/FlowCard-ListFiles.js +55 -0
- package/webinterface/source/cards/FlowCard-MeadowCount.js +44 -0
- package/webinterface/source/cards/FlowCard-MeadowCreate.js +44 -0
- package/webinterface/source/cards/FlowCard-MeadowDelete.js +45 -0
- package/webinterface/source/cards/FlowCard-MeadowRead.js +46 -0
- package/webinterface/source/cards/FlowCard-MeadowReads.js +46 -0
- package/webinterface/source/cards/FlowCard-MeadowUpdate.js +44 -0
- package/webinterface/source/cards/FlowCard-ParseCSV.js +85 -0
- package/webinterface/source/cards/FlowCard-ReadJSON.js +54 -0
- package/webinterface/source/cards/FlowCard-ReadText.js +54 -0
- package/webinterface/source/cards/FlowCard-RestRequest.js +59 -0
- package/webinterface/source/cards/FlowCard-SendJSON.js +57 -0
- package/webinterface/source/cards/FlowCard-Solver.js +77 -0
- package/webinterface/source/cards/FlowCard-Start.js +29 -0
- package/webinterface/source/cards/FlowCard-TemplateString.js +77 -0
- package/webinterface/source/cards/FlowCard-WriteJSON.js +54 -0
- package/webinterface/source/cards/FlowCard-WriteText.js +54 -0
- package/webinterface/source/data/ExampleFlow-CSVPipeline.js +231 -0
- package/webinterface/source/data/ExampleFlow-FileProcessor.js +315 -0
- package/webinterface/source/data/ExampleFlow-MeadowPipeline.js +328 -0
- package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +8 -8
- package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +6 -6
- package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +436 -0
- package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +45 -43
- package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +34 -89
- package/webinterface/source/views/PictView-Ultravisor-OperationList.js +128 -13
- package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
- package/webinterface/source/views/PictView-Ultravisor-Schedule.js +18 -53
- package/webinterface/source/views/PictView-Ultravisor-TimingView.js +27 -14
- package/webinterface/source/views/PictView-Ultravisor-TopBar.js +2 -1
- package/.babelrc +0 -6
- package/.browserslistrc +0 -1
- package/.browserslistrc-BACKUP +0 -1
- package/.gulpfile-quackage-config.json +0 -7
- package/.gulpfile-quackage.js +0 -2
- package/debug/Harness.js +0 -5
- package/source/services/Ultravisor-Operation-Manifest.cjs +0 -160
- package/source/services/Ultravisor-Operation.cjs +0 -200
- package/source/services/Ultravisor-Task.cjs +0 -349
- package/source/services/events/Ultravisor-Hypervisor-Event-Solver.cjs +0 -11
- package/source/services/tasks/Ultravisor-Task-Base.cjs +0 -264
- package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +0 -188
- package/source/services/tasks/Ultravisor-Task-Command.cjs +0 -65
- package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +0 -190
- package/source/services/tasks/Ultravisor-Task-Conditional.cjs +0 -104
- package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +0 -72
- package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +0 -336
- package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +0 -143
- package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +0 -146
- package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +0 -158
- package/source/services/tasks/Ultravisor-Task-Request.cjs +0 -56
- package/source/services/tasks/Ultravisor-Task-Solver.cjs +0 -89
- package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +0 -93
- package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +0 -127
- package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +0 -119
- package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +0 -109
- package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +0 -112
- package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +0 -499
- package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +0 -150
- package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +0 -110
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +0 -89
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +0 -87
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +0 -67
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +0 -66
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +0 -69
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +0 -95
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +0 -96
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +0 -99
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +0 -102
- package/webinterface/.babelrc +0 -6
- package/webinterface/.browserslistrc +0 -1
- package/webinterface/.browserslistrc-BACKUP +0 -1
- package/webinterface/.gulpfile-quackage-config.json +0 -7
- package/webinterface/.gulpfile-quackage.js +0 -2
- package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
- package/webinterface/source/views/PictView-Ultravisor-TaskList.js +0 -248
- /package/docs/{cover.md → _cover.md} +0 -0
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
const libPictService = require(`pict-serviceproviderbase`);
|
|
2
|
-
|
|
3
|
-
const libFS = require('fs');
|
|
4
|
-
const libPath = require('path');
|
|
5
|
-
|
|
6
|
-
class UltravisorOperationManifest extends libPictService
|
|
7
|
-
{
|
|
8
|
-
constructor(pPict, pOptions, pServiceHash)
|
|
9
|
-
{
|
|
10
|
-
super(pPict, pOptions, pServiceHash);
|
|
11
|
-
|
|
12
|
-
// In-memory store of recent operation manifests
|
|
13
|
-
this._Manifests = {};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
createManifest(pOperationDefinition)
|
|
17
|
-
{
|
|
18
|
-
let tmpManifest = {
|
|
19
|
-
GUIDOperation: pOperationDefinition.GUIDOperation,
|
|
20
|
-
Name: pOperationDefinition.Name || pOperationDefinition.GUIDOperation,
|
|
21
|
-
StartTime: new Date().toISOString(),
|
|
22
|
-
StopTime: null,
|
|
23
|
-
Status: 'Running',
|
|
24
|
-
Success: false,
|
|
25
|
-
TaskResults: [],
|
|
26
|
-
Summary: '',
|
|
27
|
-
Log: []
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
tmpManifest.Log.push(`Operation ${tmpManifest.GUIDOperation} started at ${tmpManifest.StartTime}`);
|
|
31
|
-
|
|
32
|
-
// Store it keyed by a run ID
|
|
33
|
-
let tmpRunGUID = `${tmpManifest.GUIDOperation}-${Date.now()}`;
|
|
34
|
-
tmpManifest.GUIDRun = tmpRunGUID;
|
|
35
|
-
this._Manifests[tmpRunGUID] = tmpManifest;
|
|
36
|
-
|
|
37
|
-
return tmpManifest;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
addTaskResult(pManifest, pTaskResult)
|
|
41
|
-
{
|
|
42
|
-
if (!pManifest || !pTaskResult)
|
|
43
|
-
{
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
pManifest.TaskResults.push(pTaskResult);
|
|
47
|
-
pManifest.Log.push(`Task ${pTaskResult.GUIDTask} completed with status: ${pTaskResult.Status}`);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
finalizeManifest(pManifest, pStagingPath)
|
|
51
|
-
{
|
|
52
|
-
if (!pManifest)
|
|
53
|
-
{
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
pManifest.StopTime = new Date().toISOString();
|
|
57
|
-
|
|
58
|
-
// Determine overall success from task results
|
|
59
|
-
let tmpAllSucceeded = true;
|
|
60
|
-
for (let i = 0; i < pManifest.TaskResults.length; i++)
|
|
61
|
-
{
|
|
62
|
-
if (!pManifest.TaskResults[i].Success)
|
|
63
|
-
{
|
|
64
|
-
tmpAllSucceeded = false;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
pManifest.Success = tmpAllSucceeded;
|
|
69
|
-
pManifest.Status = tmpAllSucceeded ? 'Complete' : 'Error';
|
|
70
|
-
|
|
71
|
-
// Compute elapsed time from ISO timestamps
|
|
72
|
-
let tmpElapsedMs = new Date(pManifest.StopTime).getTime() - new Date(pManifest.StartTime).getTime();
|
|
73
|
-
if (!pManifest.ElapsedMs)
|
|
74
|
-
{
|
|
75
|
-
pManifest.ElapsedMs = tmpElapsedMs;
|
|
76
|
-
}
|
|
77
|
-
if (!pManifest.ElapsedFormatted)
|
|
78
|
-
{
|
|
79
|
-
pManifest.ElapsedFormatted = this.fable.ProgressTime.formatTimeDuration(tmpElapsedMs);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
pManifest.Summary = `Operation ${pManifest.GUIDOperation} ${pManifest.Status}: ${pManifest.TaskResults.length} task(s) executed in ${pManifest.ElapsedFormatted}.`;
|
|
83
|
-
pManifest.Log.push(pManifest.Summary);
|
|
84
|
-
|
|
85
|
-
// Write the manifest JSON to the staging folder
|
|
86
|
-
if (pStagingPath && typeof(pStagingPath) === 'string' && pStagingPath.length > 0)
|
|
87
|
-
{
|
|
88
|
-
try
|
|
89
|
-
{
|
|
90
|
-
if (!libFS.existsSync(pStagingPath))
|
|
91
|
-
{
|
|
92
|
-
libFS.mkdirSync(pStagingPath, { recursive: true });
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let tmpManifestFileName = `Manifest_${pManifest.GUIDOperation}.json`;
|
|
96
|
-
let tmpManifestFilePath = libPath.resolve(pStagingPath, tmpManifestFileName);
|
|
97
|
-
let tmpContent = JSON.stringify(pManifest, null, 4);
|
|
98
|
-
libFS.writeFileSync(tmpManifestFilePath, tmpContent, 'utf8');
|
|
99
|
-
|
|
100
|
-
pManifest.ManifestFilePath = tmpManifestFilePath;
|
|
101
|
-
pManifest.Log.push(`Manifest written to ${tmpManifestFilePath}`);
|
|
102
|
-
}
|
|
103
|
-
catch (pError)
|
|
104
|
-
{
|
|
105
|
-
pManifest.Log.push(`Error writing manifest file: ${pError.message}`);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return pManifest;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Create and store a manifest for a standalone task execution result.
|
|
114
|
-
*/
|
|
115
|
-
createTaskManifest(pTaskResult)
|
|
116
|
-
{
|
|
117
|
-
if (!pTaskResult)
|
|
118
|
-
{
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
let tmpRunGUID = `Task-${pTaskResult.GUIDTask}-${Date.now()}`;
|
|
123
|
-
|
|
124
|
-
let tmpManifest = {
|
|
125
|
-
GUIDRun: tmpRunGUID,
|
|
126
|
-
GUIDOperation: null,
|
|
127
|
-
GUIDTask: pTaskResult.GUIDTask,
|
|
128
|
-
Name: pTaskResult.Name || pTaskResult.GUIDTask,
|
|
129
|
-
StartTime: pTaskResult.StartTime || new Date().toISOString(),
|
|
130
|
-
StopTime: pTaskResult.StopTime || new Date().toISOString(),
|
|
131
|
-
Status: pTaskResult.Status || 'Unknown',
|
|
132
|
-
Success: pTaskResult.Success || false,
|
|
133
|
-
TaskResults: [pTaskResult],
|
|
134
|
-
Summary: `Task ${pTaskResult.GUIDTask} ${pTaskResult.Status}: standalone execution.`,
|
|
135
|
-
Log: pTaskResult.Log || []
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
this._Manifests[tmpRunGUID] = tmpManifest;
|
|
139
|
-
|
|
140
|
-
return tmpManifest;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
getManifest(pRunGUID)
|
|
144
|
-
{
|
|
145
|
-
return this._Manifests[pRunGUID] || null;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
getManifestList()
|
|
149
|
-
{
|
|
150
|
-
let tmpManifests = [];
|
|
151
|
-
let tmpKeys = Object.keys(this._Manifests);
|
|
152
|
-
for (let i = 0; i < tmpKeys.length; i++)
|
|
153
|
-
{
|
|
154
|
-
tmpManifests.push(this._Manifests[tmpKeys[i]]);
|
|
155
|
-
}
|
|
156
|
-
return tmpManifests;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
module.exports = UltravisorOperationManifest;
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
const libPictService = require(`pict-serviceproviderbase`);
|
|
2
|
-
|
|
3
|
-
const libFS = require('fs');
|
|
4
|
-
const libPath = require('path');
|
|
5
|
-
|
|
6
|
-
class UltravisorOperation extends libPictService
|
|
7
|
-
{
|
|
8
|
-
constructor(pPict, pOptions, pServiceHash)
|
|
9
|
-
{
|
|
10
|
-
super(pPict, pOptions, pServiceHash);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Resolve the base staging root folder.
|
|
15
|
-
*
|
|
16
|
-
* Priority:
|
|
17
|
-
* 1. UltravisorStagingRoot from ProgramConfiguration
|
|
18
|
-
* 2. ./dist/ultravisor_staging (relative to cwd)
|
|
19
|
-
*
|
|
20
|
-
* @returns {string} Absolute path to the staging root.
|
|
21
|
-
*/
|
|
22
|
-
resolveStagingRoot()
|
|
23
|
-
{
|
|
24
|
-
return (this.fable?.ProgramConfiguration?.UltravisorStagingRoot)
|
|
25
|
-
|| libPath.resolve(process.cwd(), 'dist', 'ultravisor_staging');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Generate a timestamp suffix for unique folder naming.
|
|
30
|
-
*
|
|
31
|
-
* Format: YYYY-MM-DD-HH-MM-SS-MS_SALT
|
|
32
|
-
* where SALT is a random two-digit number (00–99).
|
|
33
|
-
*
|
|
34
|
-
* @returns {string} The formatted timestamp suffix.
|
|
35
|
-
*/
|
|
36
|
-
generateOperationTimestamp()
|
|
37
|
-
{
|
|
38
|
-
let tmpNow = new Date();
|
|
39
|
-
let tmpYear = tmpNow.getFullYear();
|
|
40
|
-
let tmpMonth = String(tmpNow.getMonth() + 1).padStart(2, '0');
|
|
41
|
-
let tmpDay = String(tmpNow.getDate()).padStart(2, '0');
|
|
42
|
-
let tmpHours = String(tmpNow.getHours()).padStart(2, '0');
|
|
43
|
-
let tmpMinutes = String(tmpNow.getMinutes()).padStart(2, '0');
|
|
44
|
-
let tmpSeconds = String(tmpNow.getSeconds()).padStart(2, '0');
|
|
45
|
-
let tmpMilliseconds = String(tmpNow.getMilliseconds()).padStart(3, '0');
|
|
46
|
-
let tmpSalt = String(Math.floor(Math.random() * 100)).padStart(2, '0');
|
|
47
|
-
|
|
48
|
-
return `${tmpYear}-${tmpMonth}-${tmpDay}-${tmpHours}-${tmpMinutes}-${tmpSeconds}-${tmpMilliseconds}_${tmpSalt}`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Build and ensure the per-operation staging folder exists.
|
|
53
|
-
*
|
|
54
|
-
* Creates: {StagingRoot}/{GUIDOperation}-{Timestamp}_{Salt}/
|
|
55
|
-
*
|
|
56
|
-
* @param {string} pGUIDOperation - The operation GUID.
|
|
57
|
-
* @returns {string} Absolute path to the operation staging folder.
|
|
58
|
-
*/
|
|
59
|
-
ensureOperationStagingFolder(pGUIDOperation)
|
|
60
|
-
{
|
|
61
|
-
let tmpStagingRoot = this.resolveStagingRoot();
|
|
62
|
-
let tmpTimestamp = this.generateOperationTimestamp();
|
|
63
|
-
let tmpFolderName = `${pGUIDOperation}-${tmpTimestamp}`;
|
|
64
|
-
let tmpOperationStagingPath = libPath.resolve(tmpStagingRoot, tmpFolderName);
|
|
65
|
-
|
|
66
|
-
if (!libFS.existsSync(tmpOperationStagingPath))
|
|
67
|
-
{
|
|
68
|
-
libFS.mkdirSync(tmpOperationStagingPath, { recursive: true });
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return tmpOperationStagingPath;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Execute an operation (a set of tasks run in sequence).
|
|
76
|
-
*
|
|
77
|
-
* @param {object} pOperationDefinition - The operation definition from state.
|
|
78
|
-
* @param {function} fCallback - Callback with (pError, pManifest).
|
|
79
|
-
*/
|
|
80
|
-
executeOperation(pOperationDefinition, fCallback)
|
|
81
|
-
{
|
|
82
|
-
if (typeof(pOperationDefinition) !== 'object' || pOperationDefinition === null)
|
|
83
|
-
{
|
|
84
|
-
return fCallback(new Error(`Ultravisor Operation: executeOperation requires a valid operation definition.`));
|
|
85
|
-
}
|
|
86
|
-
if (!pOperationDefinition.GUIDOperation)
|
|
87
|
-
{
|
|
88
|
-
return fCallback(new Error(`Ultravisor Operation: executeOperation requires GUIDOperation.`));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let tmpManifestService = this.fable['Ultravisor-Operation-Manifest'];
|
|
92
|
-
let tmpTaskService = this.fable['Ultravisor-Task'];
|
|
93
|
-
let tmpStateService = this.fable['Ultravisor-Hypervisor-State'];
|
|
94
|
-
|
|
95
|
-
// Create the per-operation staging folder
|
|
96
|
-
let tmpStagingPath = pOperationDefinition.StagingPath || '';
|
|
97
|
-
|
|
98
|
-
if (!tmpStagingPath || tmpStagingPath.length === 0)
|
|
99
|
-
{
|
|
100
|
-
tmpStagingPath = this.ensureOperationStagingFolder(pOperationDefinition.GUIDOperation);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let tmpManifest = tmpManifestService.createManifest(pOperationDefinition);
|
|
104
|
-
tmpManifest.StagingPath = tmpStagingPath;
|
|
105
|
-
|
|
106
|
-
// Gather the task GUIDs for this operation
|
|
107
|
-
let tmpTaskGUIDs = pOperationDefinition.Tasks || [];
|
|
108
|
-
if (!Array.isArray(tmpTaskGUIDs) || tmpTaskGUIDs.length === 0)
|
|
109
|
-
{
|
|
110
|
-
tmpManifest.Log.push(`Operation has no tasks to execute.`);
|
|
111
|
-
tmpManifestService.finalizeManifest(tmpManifest, tmpStagingPath);
|
|
112
|
-
return fCallback(null, tmpManifest);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
let tmpContext = {
|
|
116
|
-
GlobalState: pOperationDefinition.GlobalState || {},
|
|
117
|
-
NodeState: pOperationDefinition.NodeState || {},
|
|
118
|
-
StagingPath: tmpStagingPath
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
// Expose GlobalState via AppData so that fable services
|
|
122
|
-
// (e.g. ExpressionParser) can resolve addresses against it.
|
|
123
|
-
if (!this.fable.AppData || typeof(this.fable.AppData) !== 'object')
|
|
124
|
-
{
|
|
125
|
-
this.fable.AppData = {};
|
|
126
|
-
}
|
|
127
|
-
this.fable.AppData.GlobalState = tmpContext.GlobalState;
|
|
128
|
-
|
|
129
|
-
this.log.info(`Ultravisor Operation: executing operation ${pOperationDefinition.GUIDOperation} with ${tmpTaskGUIDs.length} task(s).`);
|
|
130
|
-
|
|
131
|
-
// Set up progress tracking for the operation
|
|
132
|
-
let tmpProgressTrackerSet = this.fable.instantiateServiceProviderIfNotExists('ProgressTrackerSet');
|
|
133
|
-
let tmpProgressTrackerHash = `Op-${tmpManifest.GUIDRun}`;
|
|
134
|
-
tmpProgressTrackerSet.createProgressTracker(tmpProgressTrackerHash, tmpTaskGUIDs.length);
|
|
135
|
-
tmpProgressTrackerSet.startProgressTracker(tmpProgressTrackerHash);
|
|
136
|
-
|
|
137
|
-
// Execute tasks in sequence using anticipate
|
|
138
|
-
let tmpAnticipate = this.fable.newAnticipate();
|
|
139
|
-
|
|
140
|
-
for (let i = 0; i < tmpTaskGUIDs.length; i++)
|
|
141
|
-
{
|
|
142
|
-
let tmpTaskGUID = tmpTaskGUIDs[i];
|
|
143
|
-
|
|
144
|
-
tmpAnticipate.anticipate(
|
|
145
|
-
function (fNext)
|
|
146
|
-
{
|
|
147
|
-
tmpStateService.getTask(tmpTaskGUID,
|
|
148
|
-
(pError, pTaskDefinition) =>
|
|
149
|
-
{
|
|
150
|
-
if (pError)
|
|
151
|
-
{
|
|
152
|
-
tmpManifest.Log.push(`Could not find task ${tmpTaskGUID}: ${pError.message}`);
|
|
153
|
-
tmpProgressTrackerSet.incrementProgressTracker(tmpProgressTrackerHash);
|
|
154
|
-
return fNext();
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
tmpTaskService.executeTask(pTaskDefinition, tmpContext,
|
|
158
|
-
(pTaskError, pTaskResult) =>
|
|
159
|
-
{
|
|
160
|
-
if (pTaskError)
|
|
161
|
-
{
|
|
162
|
-
tmpManifest.Log.push(`Error executing task ${tmpTaskGUID}: ${pTaskError.message}`);
|
|
163
|
-
tmpProgressTrackerSet.incrementProgressTracker(tmpProgressTrackerHash);
|
|
164
|
-
return fNext();
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
tmpManifestService.addTaskResult(tmpManifest, pTaskResult);
|
|
168
|
-
tmpProgressTrackerSet.incrementProgressTracker(tmpProgressTrackerHash);
|
|
169
|
-
tmpProgressTrackerSet.logProgressTrackerStatus(tmpProgressTrackerHash);
|
|
170
|
-
return fNext();
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
tmpAnticipate.wait(
|
|
177
|
-
(pError) =>
|
|
178
|
-
{
|
|
179
|
-
if (pError)
|
|
180
|
-
{
|
|
181
|
-
tmpManifest.Log.push(`Error during operation execution: ${pError.message}`);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
tmpProgressTrackerSet.endProgressTracker(tmpProgressTrackerHash);
|
|
185
|
-
let tmpTrackerData = tmpProgressTrackerSet.getProgressTrackerData(tmpProgressTrackerHash);
|
|
186
|
-
tmpManifest.ElapsedMs = tmpTrackerData.ElapsedTime;
|
|
187
|
-
tmpManifest.ElapsedFormatted = this.fable.ProgressTime.formatTimeDuration(tmpTrackerData.ElapsedTime);
|
|
188
|
-
tmpManifest.AverageTaskMs = tmpTrackerData.AverageOperationTime;
|
|
189
|
-
tmpManifest.Log.push(tmpProgressTrackerSet.getProgressTrackerStatusString(tmpProgressTrackerHash));
|
|
190
|
-
|
|
191
|
-
tmpManifestService.finalizeManifest(tmpManifest, tmpStagingPath);
|
|
192
|
-
|
|
193
|
-
this.log.info(`Ultravisor Operation: operation ${pOperationDefinition.GUIDOperation} completed in ${tmpManifest.ElapsedFormatted}. Status: ${tmpManifest.Status}`);
|
|
194
|
-
|
|
195
|
-
return fCallback(null, tmpManifest);
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
module.exports = UltravisorOperation;
|
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
const libPictService = require(`pict-serviceproviderbase`);
|
|
2
|
-
|
|
3
|
-
const _TaskTypes = {
|
|
4
|
-
'command': require('./tasks/Ultravisor-Task-Command.cjs'),
|
|
5
|
-
'request': require('./tasks/Ultravisor-Task-Request.cjs'),
|
|
6
|
-
'conditional': require('./tasks/Ultravisor-Task-Conditional.cjs'),
|
|
7
|
-
'solver': require('./tasks/Ultravisor-Task-Solver.cjs'),
|
|
8
|
-
'linematch': require('./tasks/Ultravisor-Task-LineMatch.cjs'),
|
|
9
|
-
|
|
10
|
-
'listfiles': require('./tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs'),
|
|
11
|
-
'readjson': require('./tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs'),
|
|
12
|
-
'writejson': require('./tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs'),
|
|
13
|
-
'readtext': require('./tasks/stagingfiles/Ultravisor-Task-ReadText.cjs'),
|
|
14
|
-
'writetext': require('./tasks/stagingfiles/Ultravisor-Task-WriteText.cjs'),
|
|
15
|
-
'readxml': require('./tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs'),
|
|
16
|
-
'writexml': require('./tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs'),
|
|
17
|
-
'readbinary': require('./tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs'),
|
|
18
|
-
'writebinary': require('./tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs'),
|
|
19
|
-
'copyfile': require('./tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs'),
|
|
20
|
-
|
|
21
|
-
'getjson': require('./tasks/rest/Ultravisor-Task-GetJSON.cjs'),
|
|
22
|
-
'getbinary': require('./tasks/rest/Ultravisor-Task-GetBinary.cjs'),
|
|
23
|
-
'gettext': require('./tasks/rest/Ultravisor-Task-GetText.cjs'),
|
|
24
|
-
'getxml': require('./tasks/rest/Ultravisor-Task-GetXML.cjs'),
|
|
25
|
-
'sendjson': require('./tasks/rest/Ultravisor-Task-SendJSON.cjs'),
|
|
26
|
-
'restrequest': require('./tasks/rest/Ultravisor-Task-RestRequest.cjs'),
|
|
27
|
-
|
|
28
|
-
'generatepagedoperation': require('./tasks/Ultravisor-Task-GeneratePagedOperation.cjs'),
|
|
29
|
-
|
|
30
|
-
'collectvalues': require('./tasks/Ultravisor-Task-CollectValues.cjs'),
|
|
31
|
-
'commandeach': require('./tasks/Ultravisor-Task-CommandEach.cjs'),
|
|
32
|
-
|
|
33
|
-
'datewindow': require('./tasks/Ultravisor-Task-DateWindow.cjs'),
|
|
34
|
-
'templatestring': require('./tasks/Ultravisor-Task-TemplateString.cjs'),
|
|
35
|
-
|
|
36
|
-
'launchoperation': require('./tasks/Ultravisor-Task-LaunchOperation.cjs'),
|
|
37
|
-
'launchtask': require('./tasks/Ultravisor-Task-LaunchTask.cjs'),
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
class UltravisorTask extends libPictService
|
|
41
|
-
{
|
|
42
|
-
constructor(pPict, pOptions, pServiceHash)
|
|
43
|
-
{
|
|
44
|
-
super(pPict, pOptions, pServiceHash);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Execute a task based on its type, then run any subsequent task sets.
|
|
49
|
-
*
|
|
50
|
-
* Subsequent task sets are optional arrays of task GUIDs on the task
|
|
51
|
-
* definition. They run in order after the core task completes:
|
|
52
|
-
*
|
|
53
|
-
* onBefore -- runs before the core task executes
|
|
54
|
-
* onCompletion -- runs after the core task succeeds (Status === 'Complete')
|
|
55
|
-
* onSubsequent -- runs after the core task regardless of outcome
|
|
56
|
-
* onFailure -- runs after the core task when Success is false
|
|
57
|
-
* onError -- runs after the core task when Status is 'Error'
|
|
58
|
-
*
|
|
59
|
-
* Each set is an array of task GUIDs executed sequentially.
|
|
60
|
-
*
|
|
61
|
-
* @param {object} pTaskDefinition - The task definition object from state.
|
|
62
|
-
* @param {object} pContext - Execution context (GlobalState, NodeState, StagingPath).
|
|
63
|
-
* @param {function} fCallback - Callback with (pError, pManifestEntry).
|
|
64
|
-
*/
|
|
65
|
-
executeTask(pTaskDefinition, pContext, fCallback)
|
|
66
|
-
{
|
|
67
|
-
if (typeof(pTaskDefinition) !== 'object' || pTaskDefinition === null)
|
|
68
|
-
{
|
|
69
|
-
return fCallback(new Error(`Ultravisor Task: executeTask requires a valid task definition object.`));
|
|
70
|
-
}
|
|
71
|
-
if (!pTaskDefinition.GUIDTask)
|
|
72
|
-
{
|
|
73
|
-
return fCallback(new Error(`Ultravisor Task: executeTask requires the task definition to have a GUIDTask.`));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
let tmpManifestEntry = {
|
|
77
|
-
GUIDTask: pTaskDefinition.GUIDTask,
|
|
78
|
-
Name: pTaskDefinition.Name || pTaskDefinition.GUIDTask,
|
|
79
|
-
Type: pTaskDefinition.Type || 'Command',
|
|
80
|
-
StartTime: new Date().toISOString(),
|
|
81
|
-
StopTime: null,
|
|
82
|
-
Status: 'Running',
|
|
83
|
-
Success: false,
|
|
84
|
-
Output: null,
|
|
85
|
-
Log: [],
|
|
86
|
-
SubsequentResults: {}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
tmpManifestEntry.Log.push(`Task ${tmpManifestEntry.GUIDTask} started at ${tmpManifestEntry.StartTime}`);
|
|
90
|
-
|
|
91
|
-
// Set up per-task progress timing
|
|
92
|
-
let tmpProgressTrackerSet = this.fable.instantiateServiceProviderIfNotExists('ProgressTrackerSet');
|
|
93
|
-
let tmpTaskTimerHash = `Task-${pTaskDefinition.GUIDTask}-${Date.now()}`;
|
|
94
|
-
tmpProgressTrackerSet.createProgressTracker(tmpTaskTimerHash, 1);
|
|
95
|
-
tmpProgressTrackerSet.startProgressTracker(tmpTaskTimerHash);
|
|
96
|
-
|
|
97
|
-
// Ensure GlobalState is accessible via AppData for fable services
|
|
98
|
-
if (!pContext.GlobalState || typeof(pContext.GlobalState) !== 'object')
|
|
99
|
-
{
|
|
100
|
-
pContext.GlobalState = {};
|
|
101
|
-
}
|
|
102
|
-
if (!this.fable.AppData || typeof(this.fable.AppData) !== 'object')
|
|
103
|
-
{
|
|
104
|
-
this.fable.AppData = {};
|
|
105
|
-
}
|
|
106
|
-
this.fable.AppData.GlobalState = pContext.GlobalState;
|
|
107
|
-
|
|
108
|
-
// --- onBefore ---
|
|
109
|
-
this.executeSubsequentSet(pTaskDefinition, 'onBefore', pContext, tmpManifestEntry,
|
|
110
|
-
(pBeforeError) =>
|
|
111
|
-
{
|
|
112
|
-
if (pBeforeError)
|
|
113
|
-
{
|
|
114
|
-
tmpManifestEntry.Log.push(`Error in onBefore: ${pBeforeError.message}`);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// --- Core task execution ---
|
|
118
|
-
this.executeCoreTask(pTaskDefinition, pContext, tmpManifestEntry,
|
|
119
|
-
(pCoreError) =>
|
|
120
|
-
{
|
|
121
|
-
if (pCoreError)
|
|
122
|
-
{
|
|
123
|
-
tmpManifestEntry.Log.push(`Core task error: ${pCoreError.message}`);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// --- Determine which subsequent sets to run ---
|
|
127
|
-
let tmpSubsequentPhases = [];
|
|
128
|
-
|
|
129
|
-
// onCompletion: only when core task succeeded
|
|
130
|
-
if (tmpManifestEntry.Status === 'Complete' && tmpManifestEntry.Success)
|
|
131
|
-
{
|
|
132
|
-
tmpSubsequentPhases.push('onCompletion');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// onFailure: when the task did not succeed
|
|
136
|
-
if (!tmpManifestEntry.Success)
|
|
137
|
-
{
|
|
138
|
-
tmpSubsequentPhases.push('onFailure');
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// onError: specifically when Status is 'Error'
|
|
142
|
-
if (tmpManifestEntry.Status === 'Error')
|
|
143
|
-
{
|
|
144
|
-
tmpSubsequentPhases.push('onError');
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// onSubsequent: always runs after core task
|
|
148
|
-
tmpSubsequentPhases.push('onSubsequent');
|
|
149
|
-
|
|
150
|
-
this.executeSubsequentPhases(pTaskDefinition, tmpSubsequentPhases, pContext, tmpManifestEntry,
|
|
151
|
-
() =>
|
|
152
|
-
{
|
|
153
|
-
// Record task timing
|
|
154
|
-
tmpProgressTrackerSet.endProgressTracker(tmpTaskTimerHash);
|
|
155
|
-
let tmpTrackerData = tmpProgressTrackerSet.getProgressTrackerData(tmpTaskTimerHash);
|
|
156
|
-
tmpManifestEntry.ElapsedMs = tmpTrackerData.ElapsedTime;
|
|
157
|
-
tmpManifestEntry.ElapsedFormatted = this.fable.ProgressTime.formatTimeDuration(tmpTrackerData.ElapsedTime);
|
|
158
|
-
tmpManifestEntry.Log.push(`Task ${tmpManifestEntry.Name} completed in ${tmpManifestEntry.ElapsedFormatted}`);
|
|
159
|
-
this.log.info(`Ultravisor Task: ${tmpManifestEntry.Name} [${tmpManifestEntry.Status}] completed in ${tmpManifestEntry.ElapsedFormatted}`);
|
|
160
|
-
return fCallback(null, tmpManifestEntry);
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Execute the core task logic by dispatching to the appropriate task type service.
|
|
168
|
-
*/
|
|
169
|
-
executeCoreTask(pTaskDefinition, pContext, pManifestEntry, fCallback)
|
|
170
|
-
{
|
|
171
|
-
let tmpType = (pTaskDefinition.Type || 'Command').toLowerCase();
|
|
172
|
-
|
|
173
|
-
let tmpTaskTypeClass = _TaskTypes[tmpType];
|
|
174
|
-
|
|
175
|
-
if (!tmpTaskTypeClass)
|
|
176
|
-
{
|
|
177
|
-
pManifestEntry.StopTime = new Date().toISOString();
|
|
178
|
-
pManifestEntry.Status = 'Unsupported';
|
|
179
|
-
pManifestEntry.Log.push(`Task type "${pTaskDefinition.Type}" is not yet implemented.`);
|
|
180
|
-
return fCallback(null);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
let tmpTaskTypeInstance = new tmpTaskTypeClass(this.fable);
|
|
184
|
-
tmpTaskTypeInstance.execute(pTaskDefinition, pContext, pManifestEntry,
|
|
185
|
-
() => { return fCallback(null); });
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Execute a list of subsequent phases in order.
|
|
190
|
-
*
|
|
191
|
-
* @param {object} pTaskDefinition - The parent task definition.
|
|
192
|
-
* @param {array} pPhases - Array of phase names to execute in order.
|
|
193
|
-
* @param {object} pContext - Execution context.
|
|
194
|
-
* @param {object} pManifestEntry - The parent manifest entry.
|
|
195
|
-
* @param {function} fCallback - Callback when all phases are done.
|
|
196
|
-
*/
|
|
197
|
-
executeSubsequentPhases(pTaskDefinition, pPhases, pContext, pManifestEntry, fCallback)
|
|
198
|
-
{
|
|
199
|
-
if (!Array.isArray(pPhases) || pPhases.length === 0)
|
|
200
|
-
{
|
|
201
|
-
return fCallback();
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
let tmpPhaseIndex = 0;
|
|
205
|
-
|
|
206
|
-
let fRunNextPhase = () =>
|
|
207
|
-
{
|
|
208
|
-
if (tmpPhaseIndex >= pPhases.length)
|
|
209
|
-
{
|
|
210
|
-
return fCallback();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
let tmpPhaseName = pPhases[tmpPhaseIndex];
|
|
214
|
-
tmpPhaseIndex++;
|
|
215
|
-
|
|
216
|
-
this.executeSubsequentSet(pTaskDefinition, tmpPhaseName, pContext, pManifestEntry,
|
|
217
|
-
() =>
|
|
218
|
-
{
|
|
219
|
-
fRunNextPhase();
|
|
220
|
-
});
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
fRunNextPhase();
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Execute a single subsequent task set by name (e.g. "onBefore",
|
|
228
|
-
* "onCompletion").
|
|
229
|
-
*
|
|
230
|
-
* The set is an array of task GUIDs on the task definition keyed by
|
|
231
|
-
* pSetName. Each GUID is looked up from state and executed sequentially.
|
|
232
|
-
* Results are stored in pManifestEntry.SubsequentResults[pSetName].
|
|
233
|
-
*
|
|
234
|
-
* @param {object} pTaskDefinition - The parent task definition.
|
|
235
|
-
* @param {string} pSetName - The subsequent set name.
|
|
236
|
-
* @param {object} pContext - Execution context.
|
|
237
|
-
* @param {object} pManifestEntry - The parent manifest entry.
|
|
238
|
-
* @param {function} fCallback - Callback when done.
|
|
239
|
-
*/
|
|
240
|
-
executeSubsequentSet(pTaskDefinition, pSetName, pContext, pManifestEntry, fCallback)
|
|
241
|
-
{
|
|
242
|
-
let tmpTaskGUIDs = pTaskDefinition[pSetName];
|
|
243
|
-
|
|
244
|
-
if (!Array.isArray(tmpTaskGUIDs) || tmpTaskGUIDs.length === 0)
|
|
245
|
-
{
|
|
246
|
-
return fCallback();
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
pManifestEntry.Log.push(`Executing subsequent set "${pSetName}" with ${tmpTaskGUIDs.length} task(s).`);
|
|
250
|
-
pManifestEntry.SubsequentResults[pSetName] = [];
|
|
251
|
-
|
|
252
|
-
let tmpStateService = this.fable['Ultravisor-Hypervisor-State'];
|
|
253
|
-
let tmpIndex = 0;
|
|
254
|
-
|
|
255
|
-
let fRunNext = () =>
|
|
256
|
-
{
|
|
257
|
-
if (tmpIndex >= tmpTaskGUIDs.length)
|
|
258
|
-
{
|
|
259
|
-
pManifestEntry.Log.push(`Subsequent set "${pSetName}" complete.`);
|
|
260
|
-
return fCallback();
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
let tmpGUID = tmpTaskGUIDs[tmpIndex];
|
|
264
|
-
tmpIndex++;
|
|
265
|
-
|
|
266
|
-
tmpStateService.getTask(tmpGUID,
|
|
267
|
-
(pError, pSubTaskDefinition) =>
|
|
268
|
-
{
|
|
269
|
-
if (pError)
|
|
270
|
-
{
|
|
271
|
-
pManifestEntry.Log.push(`${pSetName}: could not find task ${tmpGUID}: ${pError.message}`);
|
|
272
|
-
pManifestEntry.SubsequentResults[pSetName].push(
|
|
273
|
-
{
|
|
274
|
-
GUIDTask: tmpGUID,
|
|
275
|
-
Status: 'Error',
|
|
276
|
-
Success: false,
|
|
277
|
-
Log: [`Task not found: ${pError.message}`]
|
|
278
|
-
});
|
|
279
|
-
return fRunNext();
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Execute the subsequent task (without its own subsequent
|
|
283
|
-
// chains to avoid infinite recursion)
|
|
284
|
-
this.executeCoreTaskStandalone(pSubTaskDefinition, pContext,
|
|
285
|
-
(pExecError, pResult) =>
|
|
286
|
-
{
|
|
287
|
-
if (pExecError)
|
|
288
|
-
{
|
|
289
|
-
pManifestEntry.Log.push(`${pSetName}: error executing task ${tmpGUID}: ${pExecError.message}`);
|
|
290
|
-
pManifestEntry.SubsequentResults[pSetName].push(
|
|
291
|
-
{
|
|
292
|
-
GUIDTask: tmpGUID,
|
|
293
|
-
Status: 'Error',
|
|
294
|
-
Success: false,
|
|
295
|
-
Log: [`Execution error: ${pExecError.message}`]
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
else
|
|
299
|
-
{
|
|
300
|
-
pManifestEntry.Log.push(`${pSetName}: task ${tmpGUID} completed with status: ${pResult.Status}`);
|
|
301
|
-
pManifestEntry.SubsequentResults[pSetName].push(pResult);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return fRunNext();
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
fRunNext();
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Execute a task as a standalone core task (no subsequent chains).
|
|
314
|
-
* Used for subsequent tasks to avoid recursive subsequent execution.
|
|
315
|
-
*/
|
|
316
|
-
executeCoreTaskStandalone(pTaskDefinition, pContext, fCallback)
|
|
317
|
-
{
|
|
318
|
-
if (typeof(pTaskDefinition) !== 'object' || pTaskDefinition === null)
|
|
319
|
-
{
|
|
320
|
-
return fCallback(new Error(`Invalid task definition.`));
|
|
321
|
-
}
|
|
322
|
-
if (!pTaskDefinition.GUIDTask)
|
|
323
|
-
{
|
|
324
|
-
return fCallback(new Error(`Task definition missing GUIDTask.`));
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
let tmpManifestEntry = {
|
|
328
|
-
GUIDTask: pTaskDefinition.GUIDTask,
|
|
329
|
-
Name: pTaskDefinition.Name || pTaskDefinition.GUIDTask,
|
|
330
|
-
Type: pTaskDefinition.Type || 'Command',
|
|
331
|
-
StartTime: new Date().toISOString(),
|
|
332
|
-
StopTime: null,
|
|
333
|
-
Status: 'Running',
|
|
334
|
-
Success: false,
|
|
335
|
-
Output: null,
|
|
336
|
-
Log: []
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
tmpManifestEntry.Log.push(`Task ${tmpManifestEntry.GUIDTask} started at ${tmpManifestEntry.StartTime}`);
|
|
340
|
-
|
|
341
|
-
this.executeCoreTask(pTaskDefinition, pContext, tmpManifestEntry,
|
|
342
|
-
(pError) =>
|
|
343
|
-
{
|
|
344
|
-
return fCallback(null, tmpManifestEntry);
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
module.exports = UltravisorTask;
|