update ps1 to prompt change to different hostname
This commit is contained in:
1 parent
2e8e3faff0
commit
3485cae164
1 file changed
+103
-3
+103
-3
@@ -6,6 +6,11 @@
|
|||||||
for the passphrase every time, and signs Gitea's key-verification token.
|
for the passphrase every time, and signs Gitea's key-verification token.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
|
The script asks which SSH host to set up. The first time the answer is
|
||||||
|
blank; after that it offers the host you used last, so press Enter to keep
|
||||||
|
it or type another one to add a second server. You can type a bare host
|
||||||
|
(git.example.com), host:port, or paste an SSH clone URL.
|
||||||
|
|
||||||
Safe to re-run: an existing key is reused (unless -Force), a key already in
|
Safe to re-run: an existing key is reused (unless -Force), a key already in
|
||||||
the agent is not added again, and an existing Host entry in ~/.ssh/config
|
the agent is not added again, and an existing Host entry in ~/.ssh/config
|
||||||
is never modified.
|
is never modified.
|
||||||
@@ -21,7 +26,8 @@
|
|||||||
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1
|
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1 -Comment "you@example.com"
|
# Skip the host prompt.
|
||||||
|
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1 -HostName git.example.com -Port 2222
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
# Verify the key later: click Verify next to it in Gitea and pass the token it shows.
|
# Verify the key later: click Verify next to it in Gitea and pass the token it shows.
|
||||||
@@ -32,12 +38,14 @@
|
|||||||
#>
|
#>
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
# Host to add to ~/.ssh/config and test against. Use -HostName "" to skip both.
|
# SSH host for Git. If omitted, the script asks and remembers the answer.
|
||||||
[string]$HostName = "tea.lenrui.net",
|
# Use -HostName "" to skip the ~/.ssh/config entry and the connection test.
|
||||||
|
[string]$HostName,
|
||||||
|
|
||||||
# SSH user for the host (Gitea, GitHub and GitLab all use "git").
|
# SSH user for the host (Gitea, GitHub and GitLab all use "git").
|
||||||
[string]$User = "git",
|
[string]$User = "git",
|
||||||
|
|
||||||
|
# SSH port. Defaults to 22, or to the port typed as host:port at the prompt.
|
||||||
[ValidateRange(1, 65535)]
|
[ValidateRange(1, 65535)]
|
||||||
[int]$Port = 22,
|
[int]$Port = 22,
|
||||||
|
|
||||||
@@ -70,6 +78,55 @@ function Stop-Setup([string]$Message) {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Turns what the user typed into a host name and an optional port. Accepts a
|
||||||
|
# bare host, host:port, git@host, git@host:owner/repo.git, or
|
||||||
|
# ssh://git@host:port/owner/repo.git. Returns $null if it isn't usable.
|
||||||
|
function ConvertTo-SshTarget([string]$Text) {
|
||||||
|
$t = "$Text".Trim()
|
||||||
|
$t = $t -replace '^[A-Za-z][A-Za-z0-9+.-]*://', '' # ssh:// or https://
|
||||||
|
$t = $t -replace '^[^@/]*@', '' # git@
|
||||||
|
$t = ($t -split '/')[0] # any path
|
||||||
|
$p = $null
|
||||||
|
if ($t -match '^(.+):(\d+)$') {
|
||||||
|
if ($Matches[2].Length -gt 5) { return $null }
|
||||||
|
$t = $Matches[1]
|
||||||
|
$p = [int]$Matches[2]
|
||||||
|
if ($p -lt 1 -or $p -gt 65535) { return $null }
|
||||||
|
} elseif ($t.Contains(':')) {
|
||||||
|
$t = $t.Substring(0, $t.IndexOf(':')) # host:owner/repo.git
|
||||||
|
}
|
||||||
|
if ($t -notmatch '^[A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?$') { return $null }
|
||||||
|
return [pscustomobject]@{ HostName = $t.ToLowerInvariant(); Port = $p }
|
||||||
|
}
|
||||||
|
|
||||||
|
# The last host used is kept in a small file in your user profile.
|
||||||
|
$stateDir = if ($env:APPDATA) { Join-Path $env:APPDATA 'git-ssh-setup' } else { Join-Path $HOME '.git-ssh-setup' }
|
||||||
|
$stateFile = Join-Path $stateDir 'last-host.json'
|
||||||
|
|
||||||
|
function Read-LastHost {
|
||||||
|
try {
|
||||||
|
if (Test-Path $stateFile) {
|
||||||
|
$saved = Get-Content -Path $stateFile -Raw | ConvertFrom-Json
|
||||||
|
if ($saved.HostName) {
|
||||||
|
$savedPort = 22
|
||||||
|
if ($saved.Port) { $savedPort = [int]$saved.Port }
|
||||||
|
return [pscustomobject]@{ HostName = [string]$saved.HostName; Port = $savedPort }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch { }
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Save-LastHost([string]$Name, [int]$PortNumber) {
|
||||||
|
try {
|
||||||
|
New-Item -ItemType Directory -Path $stateDir -Force | Out-Null
|
||||||
|
$json = [pscustomobject]@{ HostName = $Name; Port = $PortNumber } | ConvertTo-Json
|
||||||
|
[IO.File]::WriteAllText($stateFile, $json, (New-Object Text.UTF8Encoding($false)))
|
||||||
|
} catch {
|
||||||
|
Write-Note "Couldn't remember the host for next time: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Signs $Text exactly as given and returns the armored signature, or $null if
|
# Signs $Text exactly as given and returns the armored signature, or $null if
|
||||||
# ssh-keygen failed. The text is written to a file with no trailing newline and
|
# ssh-keygen failed. The text is written to a file with no trailing newline and
|
||||||
# no BOM: piping it into ssh-keygen from PowerShell would add a newline and
|
# no BOM: piping it into ssh-keygen from PowerShell would add a newline and
|
||||||
@@ -96,6 +153,49 @@ if ($Token -and $Token -notmatch '^[0-9a-fA-F]+$') {
|
|||||||
Stop-Setup "-Token should be just the hex string from Gitea's Token box."
|
Stop-Setup "-Token should be just the hex string from Gitea's Token box."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# --- 0. SSH host -------------------------------------------------------------
|
||||||
|
$target = $null
|
||||||
|
if ($PSBoundParameters.ContainsKey('HostName')) {
|
||||||
|
if ($HostName) {
|
||||||
|
$target = ConvertTo-SshTarget $HostName
|
||||||
|
if (-not $target) { Stop-Setup "'$HostName' isn't a host name the script can use." }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Step "Choosing the SSH host"
|
||||||
|
$last = Read-LastHost
|
||||||
|
$suggested = ''
|
||||||
|
if ($last) {
|
||||||
|
$suggested = $last.HostName
|
||||||
|
if ($last.Port -ne 22) { $suggested = "$($last.HostName):$($last.Port)" }
|
||||||
|
Write-Host " Press Enter to keep the last host, or type a different one."
|
||||||
|
} else {
|
||||||
|
Write-Host " Type the host name from your SSH clone URL, e.g. git.example.com"
|
||||||
|
Write-Host " (add :port if the server doesn't use 22)."
|
||||||
|
}
|
||||||
|
while ($true) {
|
||||||
|
$label = if ($suggested) { " SSH host [$suggested]" } else { " SSH host" }
|
||||||
|
$answer = "$(Read-Host $label)".Trim()
|
||||||
|
if (-not $answer) {
|
||||||
|
if ($suggested) { $answer = $suggested } else { Write-Note "A host name is needed."; continue }
|
||||||
|
}
|
||||||
|
$target = ConvertTo-SshTarget $answer
|
||||||
|
if ($target) {
|
||||||
|
if ($answer -match '^https?://') {
|
||||||
|
Write-Note "That was a web address. Make sure '$($target.HostName)' is the host in your SSH"
|
||||||
|
Write-Note "clone URL; a site behind Cloudflare's proxy won't accept SSH."
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Write-Note "'$answer' doesn't look like a host name. Try something like git.example.com or git.example.com:2222"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($target) {
|
||||||
|
$HostName = $target.HostName
|
||||||
|
if ($target.Port -and -not $PSBoundParameters.ContainsKey('Port')) { $Port = $target.Port }
|
||||||
|
Save-LastHost $HostName $Port
|
||||||
|
Write-Ok "Using $User@${HostName}, port $Port"
|
||||||
|
}
|
||||||
|
|
||||||
$openSshDir = Join-Path $env:WINDIR 'System32\OpenSSH'
|
$openSshDir = Join-Path $env:WINDIR 'System32\OpenSSH'
|
||||||
$sshExe = Join-Path $openSshDir 'ssh.exe'
|
$sshExe = Join-Path $openSshDir 'ssh.exe'
|
||||||
$keygenExe = Join-Path $openSshDir 'ssh-keygen.exe'
|
$keygenExe = Join-Path $openSshDir 'ssh-keygen.exe'
|
||||||
|
|||||||
Reference in new issue
Block a user