diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs
index 107e72b188..a91405cb53 100644
--- a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs
+++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs
@@ -139,12 +139,14 @@ public void SetupTest(PlatformID platform = PlatformID.Win32NT)
}
[Test]
- [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1")]
+ [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", true)]
+ [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", false)]
[Platform(Exclude = "Unix,Linux,MacOsX")]
- public async Task PowershellExecutorExecutesTheCorrectWorkloadCommands(PlatformID platform, string platformSpecificPath, string command)
+ public async Task PowershellExecutorExecutesTheCorrectWorkloadCommands(PlatformID platform, string platformSpecificPath, string command, bool runElevated)
{
this.SetupTest(platform);
- this.fixture.Parameters["ScriptPath"] = command;
+ this.fixture.Parameters[nameof(PowershellExecutor.RunElevated)] = runElevated;
+ this.fixture.Parameters[nameof(PowershellExecutor.ScriptPath)] = command;
string fullCommand = $"{this.mockPackage.Path}{platformSpecificPath}\\{command} parameter1 parameter2";
diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PythonExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PythonExecutorTests.cs
index 3094d0dc8c..763939f7e4 100644
--- a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PythonExecutorTests.cs
+++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PythonExecutorTests.cs
@@ -139,22 +139,27 @@ public void SetupTest(PlatformID platform)
}
[Test]
- [TestCase(PlatformID.Win32NT, @"\win-x64\", @"genericScript.py", true, "python3")]
- [TestCase(PlatformID.Unix, @"/linux-x64/", @"genericScript.py", true, "python3")]
- [TestCase(PlatformID.Win32NT, @"\win-x64\", @"genericScript.py", false, "python")]
- [TestCase(PlatformID.Unix, @"/linux-x64/", @"genericScript.py", false, "python")]
- public async Task PythonExecutorExecutesTheCorrectWorkloadCommands(PlatformID platform, string platformSpecificPath, string command, bool usePython3, string pythonVersion)
+ [TestCase(PlatformID.Win32NT, @"\win-x64\", @"genericScript.py", true, "python3", true)]
+ [TestCase(PlatformID.Win32NT, @"\win-x64\", @"genericScript.py", true, "python3", false)]
+ [TestCase(PlatformID.Unix, @"/linux-x64/", @"genericScript.py", true, "python3", true)]
+ [TestCase(PlatformID.Unix, @"/linux-x64/", @"genericScript.py", true, "python3", false)]
+ [TestCase(PlatformID.Win32NT, @"\win-x64\", @"genericScript.py", false, "python", true)]
+ [TestCase(PlatformID.Win32NT, @"\win-x64\", @"genericScript.py", false, "python", false)]
+ [TestCase(PlatformID.Unix, @"/linux-x64/", @"genericScript.py", false, "python", true)]
+ [TestCase(PlatformID.Unix, @"/linux-x64/", @"genericScript.py", false, "python", false)]
+ public async Task PythonExecutorExecutesTheCorrectWorkloadCommands(PlatformID platform, string platformSpecificPath, string command, bool usePython3, string pythonVersion, bool runElevated)
{
this.SetupTest(platform);
- this.mockFixture.Parameters["ScriptPath"] = command;
- this.mockFixture.Parameters["UsePython3"] = usePython3;
+ this.mockFixture.Parameters[nameof(PythonExecutor.RunElevated)] = runElevated;
+ this.mockFixture.Parameters[nameof(PythonExecutor.ScriptPath)] = command;
+ this.mockFixture.Parameters[nameof(PythonExecutor.UsePython3)] = usePython3;
string fullCommand = $"{this.mockPackage.Path}{platformSpecificPath}{command} parameter1 parameter2";
using (TestPythonExecutor executor = new TestPythonExecutor(this.mockFixture))
{
bool commandExecuted = false;
- string expectedCommand = $"{pythonVersion} {fullCommand}";
+ string expectedCommand = $"{(PlatformID.Unix.Equals(platform) && runElevated ? "sudo" : string.Empty)} {pythonVersion} {fullCommand}".Trim();
this.mockFixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDirectory) =>
{
if (expectedCommand == $"{exe} {arguments}")
diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/ScriptExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/ScriptExecutorTests.cs
index d3ecda69f4..d47ffa30c1 100644
--- a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/ScriptExecutorTests.cs
+++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/ScriptExecutorTests.cs
@@ -176,17 +176,21 @@ public void ScriptExecutorThrowsOnInitializationWhenNoFileExistsAtExecutablePath
}
[Test]
- [TestCase(@"genericScript.bat", true)]
- [TestCase(@"..\..\..\subfolder1\genericScript.bat", true)]
- [TestCase(@"..\..\..\subfolder1\genericScript.bat", false)]
+ [TestCase(@"genericScript.bat", true, true)]
+ [TestCase(@"genericScript.bat", true, false)]
+ [TestCase(@"..\..\..\subfolder1\genericScript.bat", true, true)]
+ [TestCase(@"..\..\..\subfolder1\genericScript.bat", true, false)]
+ [TestCase(@"..\..\..\subfolder1\genericScript.bat", false, true)]
+ [TestCase(@"..\..\..\subfolder1\genericScript.bat", false, false)]
[Platform(Exclude = "Unix,Linux,MacOsX")]
- public async Task ScriptExecutorExecutesTheCorrectWorkloadCommandsInWindows(string command, bool packageAvailable)
+ public async Task ScriptExecutorExecutesTheCorrectWorkloadCommandsInWindows(string command, bool packageAvailable, bool runElevated)
{
this.SetupTest(PlatformID.Win32NT);
- this.mockFixture.Parameters["ScriptPath"] = command;
+ this.mockFixture.Parameters[nameof(ScriptExecutor.RunElevated)] = runElevated;
+ this.mockFixture.Parameters[nameof(ScriptExecutor.ScriptPath)] = command;
string platformSpecificPath = packageAvailable ? Path.Combine("win-x64") : string.Empty;
- this.mockFixture.Parameters["PackageName"] = packageAvailable ? "workloadPackage" : string.Empty;
+ this.mockFixture.Parameters[nameof(ScriptExecutor.PackageName)] = packageAvailable ? "workloadPackage" : string.Empty;
string workingDir = packageAvailable ? this.mockPackage.Path : this.mockFixture.PlatformSpecifics.CurrentDirectory;
using (TestScriptExecutor executor = new TestScriptExecutor(this.mockFixture))
@@ -225,16 +229,20 @@ await executor.ExecuteAsync(CancellationToken.None)
}
[Test]
- [TestCase(@"genericScript.sh", true)]
- [TestCase(@"../../../subfolder1/genericScript.sh", true)]
- [TestCase(@"../../../subfolder1/genericScript.sh", false)]
- public async Task ScriptExecutorExecutesTheCorrectWorkloadCommandsInUnix(string command, bool packageAvailable)
+ [TestCase(@"genericScript.sh", true, true)]
+ [TestCase(@"genericScript.sh", true, false)]
+ [TestCase(@"../../../subfolder1/genericScript.sh", true, true)]
+ [TestCase(@"../../../subfolder1/genericScript.sh", true, false)]
+ [TestCase(@"../../../subfolder1/genericScript.sh", false, true)]
+ [TestCase(@"../../../subfolder1/genericScript.sh", false, false)]
+ public async Task ScriptExecutorExecutesTheCorrectWorkloadCommandsInUnix(string command, bool packageAvailable, bool runElevated)
{
this.SetupTest(PlatformID.Unix);
- this.mockFixture.Parameters["ScriptPath"] = command;
+ this.mockFixture.Parameters[nameof(ScriptExecutor.RunElevated)] = runElevated;
+ this.mockFixture.Parameters[nameof(ScriptExecutor.ScriptPath)] = command;
string platformSpecificPath = packageAvailable ? Path.Combine("linux-x64") : string.Empty;
- this.mockFixture.Parameters["PackageName"] = packageAvailable ? "workloadPackage" : string.Empty;
+ this.mockFixture.Parameters[nameof(ScriptExecutor.PackageName)] = packageAvailable ? "workloadPackage" : string.Empty;
string workingDir = packageAvailable ? this.mockPackage.Path : this.mockFixture.PlatformSpecifics.CurrentDirectory;
using (TestScriptExecutor executor = new TestScriptExecutor(this.mockFixture))
@@ -249,7 +257,7 @@ public async Task ScriptExecutorExecutesTheCorrectWorkloadCommandsInUnix(string
unixStylePath = unixStylePath.Substring(unixStylePath.IndexOf(':') + 1); // Remove drive letter
}
- string expectedCommand = $"{unixStylePath} parameter1 parameter2";
+ string expectedCommand = $"{(runElevated ? "sudo" : string.Empty)} {unixStylePath} parameter1 parameter2".Trim();
this.mockFixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDirectory) =>
{
diff --git a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs
index 88b76ce882..bada79d781 100644
--- a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs
+++ b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs
@@ -41,7 +41,7 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel
.AddContext(nameof(command), command)
.AddContext(nameof(commandArguments), commandArguments);
- using (IProcessProxy process = await this.ExecuteCommandAsync(command, commandArguments, this.ExecutableDirectory, telemetryContext, cancellationToken, false))
+ using (IProcessProxy process = await this.ExecuteCommandAsync(command, commandArguments, this.ExecutableDirectory, telemetryContext, cancellationToken, this.RunElevated))
{
if (!cancellationToken.IsCancellationRequested)
{
diff --git a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PythonExecutor.cs b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PythonExecutor.cs
index e3c98a7e91..a4a2d1f82e 100644
--- a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PythonExecutor.cs
+++ b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PythonExecutor.cs
@@ -60,7 +60,7 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel
.AddContext(nameof(command), command)
.AddContext(nameof(commandArguments), commandArguments);
- using (IProcessProxy process = await this.ExecuteCommandAsync(command, commandArguments, this.ExecutableDirectory, telemetryContext, cancellationToken, false))
+ using (IProcessProxy process = await this.ExecuteCommandAsync(command, commandArguments, this.ExecutableDirectory, telemetryContext, cancellationToken, this.RunElevated))
{
if (!cancellationToken.IsCancellationRequested)
{
diff --git a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/ScriptExecutor.cs b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/ScriptExecutor.cs
index 72865fc019..e28a23138e 100644
--- a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/ScriptExecutor.cs
+++ b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/ScriptExecutor.cs
@@ -89,6 +89,23 @@ public string ToolName
}
}
+ ///
+ /// True if VC should create elevated process
+ /// to execute the script. Default = false.
+ ///
+ public bool RunElevated
+ {
+ get
+ {
+ return this.Parameters.GetValue(nameof(this.RunElevated), false);
+ }
+
+ set
+ {
+ this.Parameters[nameof(this.RunElevated)] = value;
+ }
+ }
+
///
/// The full path to the script executable.
///
@@ -153,7 +170,7 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel
.AddContext(nameof(command), command)
.AddContext(nameof(commandArguments), commandArguments);
- using (IProcessProxy process = await this.ExecuteCommandAsync(command, commandArguments, this.ExecutableDirectory, telemetryContext, cancellationToken, false))
+ using (IProcessProxy process = await this.ExecuteCommandAsync(command, commandArguments, this.ExecutableDirectory, telemetryContext, cancellationToken, this.RunElevated))
{
if (!cancellationToken.IsCancellationRequested)
{
diff --git a/src/VirtualClient/VirtualClient.Main/profiles/EXAMPLE-EXECUTE-SCRIPT.json b/src/VirtualClient/VirtualClient.Main/profiles/EXAMPLE-EXECUTE-SCRIPT.json
index 41f8317752..90cbea20fc 100644
--- a/src/VirtualClient/VirtualClient.Main/profiles/EXAMPLE-EXECUTE-SCRIPT.json
+++ b/src/VirtualClient/VirtualClient.Main/profiles/EXAMPLE-EXECUTE-SCRIPT.json
@@ -8,11 +8,12 @@
"Parameters": {
"CommandLine": "",
"ScriptPath": "relativePath\\script.sh",
- "LogPaths": "relativePath1\\file1;relativePath2\\subFolder1;*.txt",
- "ToolName": "",
- "PackageName": "exampleWorkload",
- "WorkloadPackage": "exampleworkload.1.1.0.zip",
- "FailFast": false
+ "LogPaths": "relativePath1\\file1;relativePath2\\subFolder1;*.txt",
+ "ToolName": "",
+ "PackageName": "exampleWorkload",
+ "WorkloadPackage": "exampleworkload.1.1.0.zip",
+ "FailFast": false,
+ "RunElevated": false
},
"Actions": [
{
@@ -24,7 +25,8 @@
"LogPaths": "$.Parameters.LogPaths",
"ToolName": "$.Parameters.ToolName",
"PackageName": "$.Parameters.PackageName",
- "FailFast": "$.Parameters.FailFast",
+ "FailFast": "$.Parameters.FailFast",
+ "RunElevated": "$.Parameters.RunElevated",
"Tags": "Test,VC,Script"
}
}