Page MenuHomePhabricator

D10214.diff
No OneTemporary

D10214.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2752,6 +2752,7 @@
'UserQueryConduitAPIMethod' => 'applications/people/conduit/UserQueryConduitAPIMethod.php',
'UserRemoveStatusConduitAPIMethod' => 'applications/people/conduit/UserRemoveStatusConduitAPIMethod.php',
'UserWhoAmIConduitAPIMethod' => 'applications/people/conduit/UserWhoAmIConduitAPIMethod.php',
+ 'WindowsZeroConf' => 'applications/drydock/blueprint/windows/WindowsZeroConf.php',
),
'function' => array(
'_phabricator_time_format' => 'view/viewutils.php',
@@ -5731,5 +5732,6 @@
'UserQueryConduitAPIMethod' => 'UserConduitAPIMethod',
'UserRemoveStatusConduitAPIMethod' => 'UserConduitAPIMethod',
'UserWhoAmIConduitAPIMethod' => 'UserConduitAPIMethod',
+ 'WindowsZeroConf' => 'Phobject',
),
));
diff --git a/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php
--- a/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php
+++ b/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php
@@ -97,6 +97,13 @@
$i++;
}
+ if (!$this->getDetail('skip-ssh-setup-windows')) {
+ if ($this->getDetail('platform') === 'windows') {
+ $settings['UserData'] = id(new WindowsZeroConf())
+ ->getEncodedUserData($credential);
+ }
+ }
+
$result = $this->getAWSEC2Future()
->setRawAWSQuery(
'RunInstances',
@@ -229,7 +236,7 @@
'port' => $resource->getAttribute('port'),
'credential' => $resource->getAttribute('credential'),
'platform' => $resource->getAttribute('platform')));
- $ssh->setConnectTimeout(5);
+ $ssh->setConnectTimeout(60);
while (true) {
try {
@@ -473,6 +480,14 @@
'to instances so that Phabricator can SSH to them from the '.
'internet (instances are still only accessible by SSH key pairs)')
),
+ 'skip-ssh-setup-windows' => array(
+ 'name' => pht('Skip SSH setup on Windows'),
+ 'type' => 'bool',
+ 'caption' => pht(
+ 'If SSH is already configured on a Windows AMI, check this option. '.
+ 'By default, Phabricator will automatically install and configure '.
+ 'SSH on the Windows image.')
+ ),
'min-count' => array(
'name' => pht('Minimum Instances'),
'type' => 'int',
diff --git a/src/applications/drydock/blueprint/windows/WindowsZeroConf.php b/src/applications/drydock/blueprint/windows/WindowsZeroConf.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/blueprint/windows/WindowsZeroConf.php
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * Responsible for configuring and automatically installing SSH on Windows
+ * EC2 instances when they start.
+ */
+final class WindowsZeroConf extends Phobject {
+
+ public function getEncodedUserData(PassphraseCredential $credential) {
+ return base64_encode($this->getUserData($credential));
+ }
+
+ private function getUserData(PassphraseCredential $credential) {
+
+ $type = PassphraseCredentialType::getTypeByConstant(
+ $credential->getCredentialType());
+ if (!$type) {
+ throw new Exception(pht('Credential has invalid type "%s"!', $type));
+ }
+
+ if (!$type->hasPublicKey()) {
+ throw new Exception(pht('Credential has no public key!'));
+ }
+
+ $username = $credential->getUsername();
+ $publickey = $type->getPublicKey(
+ PhabricatorUser::getOmnipotentUser(),
+ $credential);
+ $publickey = trim($publickey);
+
+ $username = str_replace('"', '`"', $username);
+ $publickey = str_replace('"', '`"', $publickey);
+
+ return <<<EOF
+<powershell>
+\$username = "$username";
+\$publickey = "$publickey";
+
+# Download Cygwin64
+wget https://cygwin.com/setup-x86_64.exe `
+ -OutFile C:\setup-x86_64.exe
+
+# Run Cygwin64 install
+C:\setup-x86_64.exe -s http://mirrors.kernel.org/sourceware/cygwin/ -P openssh `
+ -q -a x86_64 -B -X -n -N -d
+
+# Wait for Cygwin install to finish
+while ((Get-Process setup-x86_64 -ErrorAction SilentlyContinue) -ne \$null) {
+ Write-Host "Waiting for Cygwin to finish installation..."
+ Sleep 5
+}
+
+# Setup SSHD
+\$env:PATH = \$env:PATH + ";c:\cygwin64\bin"
+C:\cygwin64\bin\chmod.exe +r /etc/passwd
+C:\cygwin64\bin\chmod.exe +r /etc/group
+C:\cygwin64\bin\chmod.exe a+x /var
+C:\cygwin64\bin\bash.exe -c "mkpasswd > /etc/passwd"
+C:\cygwin64\bin\bash.exe C:\cygwin64\bin\ssh-host-config -y -w SSHPRIV1@
+
+\$objOu = [ADSI]"WinNT://localhost"
+\$objUser = \$objOU.Create("User", \$username)
+\$objUser.setpassword("SSHPRIV1@")
+try {
+ \$objUser.SetInfo()
+} catch {
+ # User might have specified Administrator as the username, in which case
+ # we don't need to create the user.
+ echo "\$username already exists, not creating the user."
+}
+
+C:\cygwin64\bin\bash.exe -c "mkpasswd > /etc/passwd"
+
+if (!(Test-Path C:\cygwin64\home\\\$username\.ssh)) {
+ mkdir C:\cygwin64\home\\\$username\.ssh
+}
+
+\$keyline = "\$publickey Automatically Defined Key"
+
+Set-Content `
+ -Path C:\cygwin64\home\\\$username\.ssh\authorized_keys `
+ -Value \$keyline
+
+New-NetFirewallRule -DisplayName "SSHD" `
+ -Direction Inbound -Protocol TCP -LocalPort 22 -Action allow
+
+Set-Service sshd -StartupType Automatic
+
+\$sshd_config = Get-Content -Path C:\cygwin64\\etc\sshd_config
+\$sshd_config = \$sshd_config.Replace( `
+ "UsePrivilegeSeparation sandbox", `
+ "UsePrivilegeSeparation no")
+Set-Content -Path C:\cygwin64\\etc\sshd_config -Value \$sshd_config
+
+# Use cmd.exe as the initial prompt on SSH.
+\$passwd_config = Get-Content -Path C:\cygwin64\\etc\passwd
+\$passwd_config = \$passwd_config.Replace( `
+ "/bin/bash", `
+ "/cygdrive/c/Windows/system32/cmd.exe")
+Set-Content -Path C:\cygwin64\\etc\passwd -Value \$passwd_config
+
+Start-Service sshd
+
+</powershell>
+EOF;
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Mar 18 2025, 9:24 PM (4 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7588547
Default Alt Text
D10214.diff (5 KB)

Event Timeline