repos

the soil's own key suffices, bootstrap stops demanding a fresh one from the host

6eca5b41 by Isaac Bythewood · 24 days ago

modified containers/webdev/bootstrap.ps1
@@ -95,6 +95,18 @@ function Fail   { param([string]$M) Write-Host "  [fail] $M" -ForegroundColor Refunction Should-Run { param([string]$Name) return (-not $Only) -or ($Only -eq $Name) }# ---------------------------------------------------------------------------# Does the bythewood-ssh volume already hold a usable home_key? On a machine# that's been set up before (or restored from B2), the deploy key already lives# in the volume, so we don't need a host-side copy at all. The volume may not# exist yet on a truly fresh machine — an inspect failure just means "absent".function Test-VolumeKey {    docker volume inspect bythewood-ssh 2>$null 1>$null    if ($LASTEXITCODE -ne 0) { return $false }    docker run --rm --volume "bythewood-ssh:/ssh:ro" $HelperImage `        sh -c "test -f /ssh/home_key" 2>$null 1>$null    return ($LASTEXITCODE -eq 0)}function Step-Prereqs {    Step-Banner "prereqs"    try {
@@ -104,17 +116,28 @@ function Step-Prereqs {        Fail "Docker Desktop is not running. Start it and re-run."    }    if (-not (Test-Path $HostKeyPath) -or -not (Test-Path $HostKeyPubPath)) {        Fail @"SSH key not found at $HostKeyPath (.pub).    # The host key is only needed to authenticate git against GitHub (cloning /    # pulling taproot). If it isn't on the host but the bythewood-ssh volume    # already has one, the clone helper borrows that and we never copy a fresh    # key in. Only a genuinely fresh machine — no host key AND empty volume —    # has nothing to authenticate with.    if ((Test-Path $HostKeyPath) -and (Test-Path $HostKeyPubPath)) {        Done "SSH key found at $HostKeyPath"        return    }    if (Test-VolumeKey) {        Skip "no host key, but home_key already in bythewood-ssh volume — using that"        return    }    Fail @"SSH key not found at $HostKeyPath (.pub), and none in the bythewood-ssh volume.Set up your keys first:    ssh-keygen -t ed25519 -f `"$HostKeyPath`" -C bythewood-webdevThen add the public key to GitHub:    Get-Content `"$HostKeyPubPath`" | clipPaste at https://github.com/settings/ssh/new(Or restore the bythewood-ssh volume from B2 with -Restore if you have a snapshot.)"@    }    Done "SSH key found at $HostKeyPath"}# ---------------------------------------------------------------------------
@@ -140,9 +163,13 @@ function Invoke-Helper-Clone {    # Dockerfile does `useradd dev` it gets UID 1001 (next available). Files    # created here as 1001 match dev inside webdev with no chown gymnastics.    #    # The host SSH key is bind-mounted read-only at /keys/home_key. Windows    # NTFS has no unix mode to copy, so it lands at 0777 which ssh refuses.    # We copy it into the helper user's $HOME and chmod 600 before invoking git.    # The deploy key is mounted read-only at /keys/home_key. Two sources: if the    # host has one, bind-mount that file directly; otherwise mount the    # bythewood-ssh volume (set up on a previous run) and read its key. Either    # way we copy it into the helper user's $HOME and chmod 600 before invoking    # git — Windows NTFS has no unix mode to carry over, so a bind-mounted host    # key lands at 0777, which ssh refuses, and the volume key is owned by uid    # 1001 which root in the helper can read but git wants at 600 anyway.    $gitOp = if ($Action -eq "clone") {        "git clone --branch $TaprootBranch $TaprootRepo /code/taproot"    } else {
@@ -162,11 +189,21 @@ chown -R 1001:1001 /home/devhelper /codesudo -u devhelper -E env GIT_SSH_COMMAND='ssh -i /home/devhelper/.ssh/home_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/tmp/known_hosts' sh -c '$gitOp'"@    docker run --rm `        --volume "${HostKeyPath}:/keys/home_key:ro" `        --volume "bythewood-code:/code" `        $HelperImage `        sh -c $script    # Key source: the host file when present, else the bythewood-ssh volume.    # Both expose the key to the helper at /keys/home_key (the volume mount    # lands it at /keys/home_key since the volume's root holds home_key).    $keyMount = if (Test-Path $HostKeyPath) {        @("--volume", "${HostKeyPath}:/keys/home_key:ro")    } else {        @("--volume", "bythewood-ssh:/keys:ro")    }    $dockerArgs = @("run", "--rm") + $keyMount + @(        "--volume", "bythewood-code:/code",        $HelperImage,        "sh", "-c", $script    )    docker @dockerArgs    if ($LASTEXITCODE -ne 0) { Fail "helper container failed during '$Action'" }}
@@ -262,18 +299,22 @@ function Step-Ssh {    if ($keyOk -and $pubOk) {        Skip "home_key already in volume"    } elseif (-not ((Test-Path $HostKeyPath) -and (Test-Path $HostKeyPubPath))) {        # Volume key is incomplete but there's no host key to copy from. Nothing        # to do here — the clone/pull already authenticated with whatever the        # volume had, so don't fail; just fall through to the perms fix-up.        Skip "no host key to copy; leaving volume's key as-is"    } else {        docker cp $HostKeyPath "${ContainerName}:/home/dev/.ssh/home_key" | Out-Null        docker cp $HostKeyPubPath "${ContainerName}:/home/dev/.ssh/home_key.pub" | Out-Null        Done "copied home_key + home_key.pub into bythewood-ssh volume"    }    # Always (re)apply ownership and perms. docker cp from Windows hosts loses    # mode info, and pre-existing keys from earlier manual setups may have been    # left at 0777, which ssh refuses ("unprotected private key file").    docker exec $ContainerName sudo chown dev:dev /home/dev/.ssh/home_key /home/dev/.ssh/home_key.pub | Out-Null    docker exec $ContainerName sudo chmod 600 /home/dev/.ssh/home_key | Out-Null    docker exec $ContainerName sudo chmod 644 /home/dev/.ssh/home_key.pub | Out-Null    # Always (re)apply ownership and perms on whatever key is present. docker cp    # from Windows hosts loses mode info, and pre-existing keys from earlier    # manual setups may have been left at 0777, which ssh refuses ("unprotected    # private key file"). Guarded with `-f` so a missing pub doesn't error.    docker exec $ContainerName sh -c 'cd /home/dev/.ssh && sudo chown dev:dev home_key home_key.pub 2>/dev/null; [ -f home_key ] && sudo chmod 600 home_key; [ -f home_key.pub ] && sudo chmod 644 home_key.pub' | Out-Null    Done "verified perms (key 600, pub 644)"}