Page MenuHomePhabricator

D10248.id24673.diff
No OneTemporary

D10248.id24673.diff

diff --git a/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php b/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php
--- a/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php
+++ b/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php
@@ -36,18 +36,44 @@
$argv = func_get_args();
- // This assumes there's a UNIX shell living at the other
- // end of the connection, which isn't the case for Windows machines.
- if ($this->getConfig('platform') !== 'windows') {
- $argv = $this->applyWorkingDirectoryToArgv($argv);
- }
+ if ($this->getConfig('platform') === 'windows') {
+ // Handle Windows by executing the command under PowerShell.
+ $command = id(new PhutilCommandString($argv))
+ ->setEscapingMode(PhutilCommandString::MODE_POWERSHELL);
- $full_command = call_user_func_array('csprintf', $argv);
+ $change_directory = '';
+ if ($this->getWorkingDirectory() !== null) {
+ $change_directory .= 'cd '.$this->getWorkingDirectory();
+ }
- if ($this->getConfig('platform') === 'windows') {
- // On Windows platforms we need to execute cmd.exe explicitly since
- // most commands are not really executables.
- $full_command = 'C:\\Windows\\system32\\cmd.exe /C '.$full_command;
+ $script = <<<EOF
+$change_directory
+$command
+if (\$LastExitCode -ne 0) {
+ exit \$LastExitCode
+}
+EOF;
+
+ // When Microsoft says "Unicode" they don't mean UTF-8.
+ $script = mb_convert_encoding($script, 'UTF-16LE');
+
+ $script = base64_encode($script);
+
+ $powershell =
+ 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
+ $powershell .=
+ ' -ExecutionPolicy Bypass'.
+ ' -NonInteractive'.
+ ' -InputFormat Text'.
+ ' -OutputFormat Text'.
+ ' -EncodedCommand '.$script;
+
+ $full_command = $powershell;
+ } else {
+ // Handle UNIX by executing under the native shell.
+ $argv = $this->applyWorkingDirectoryToArgv($argv);
+
+ $full_command = call_user_func_array('csprintf', $argv);
}
$command_timeout = '';
diff --git a/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php
@@ -3,6 +3,8 @@
final class HarbormasterCommandBuildStepImplementation
extends HarbormasterBuildStepImplementation {
+ private $platform;
+
public function getName() {
return pht('Run Command');
}
@@ -18,6 +20,18 @@
$this->formatSettingForDescription('hostartifact'));
}
+ public function escapeCommand($pattern, array $args) {
+ array_unshift($args, $pattern);
+
+ $mode = PhutilCommandString::MODE_DEFAULT;
+ if ($this->platform == 'windows') {
+ $mode = PhutilCommandString::MODE_POWERSHELL;
+ }
+
+ return id(new PhutilCommandString($args))
+ ->setEscapingMode($mode);
+ }
+
public function execute(
HarbormasterBuild $build,
HarbormasterBuildTarget $build_target) {
@@ -25,14 +39,18 @@
$settings = $this->getSettings();
$variables = $build_target->getVariables();
+ $artifact = $build->loadArtifact($settings['hostartifact']);
+
+ $lease = $artifact->loadDrydockLease();
+
+ $this->platform = $lease->getAttribute('platform');
+
$command = $this->mergeVariables(
- 'vcsprintf',
+ array($this, 'escapeCommand'),
$settings['command'],
$variables);
- $artifact = $build->loadArtifact($settings['hostartifact']);
-
- $lease = $artifact->loadDrydockLease();
+ $this->platform = null;
$interface = $lease->getInterface('command');
@@ -88,6 +106,9 @@
'name' => pht('Command'),
'type' => 'text',
'required' => true,
+ 'caption' => pht(
+ 'Under Windows, this is executed under PowerShell.'.
+ 'Under UNIX, this is executed using the user\'s shell.'),
),
'hostartifact' => array(
'name' => pht('Host'),

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 14, 2:59 AM (2 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
8973814
Default Alt Text
D10248.id24673.diff (4 KB)

Event Timeline