VM setup: shell detection, dedicated GitHub key, in-script sign-ins, Remote Control service - #28
Merged
Merged
Conversation
- Write the env block to the login shell's rc file (zsh or bash, from the passwd entry), plus the other shell's rc only if it already exists - Generate ~/.ssh/id_ed25519_github instead of the default key and wire it to github.com via a managed ~/.ssh/config block; keep the old key as a fallback until ssh -T confirms GitHub accepts the new one - Fall back to ssh.github.com:443 when port 22 is blocked
…alth check - Split into an interactive phase (prereqs, git, gh + SSH key, Claude install + claude auth login) and a fully unattended phase - Sign in to Claude Code with claude auth login --claudeai when needed - Optional always-on claude remote-control systemd user service with lingering, Restart=always, and pre-accepted workspace trust - End-of-run health check replaces the manual verification steps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-ups to #26 for
Bash/AI/Claude/claude-code-vm-setup.sh: login-shell detection, a dedicated GitHub SSH key, and making it a "run once, walk away, connect from Desktop" script (in-script sign-ins, two-phase run, always-on Remote Control, end-of-run health check).Detect the login shell (zsh vs bash)
Previously
~/.bashrcwas always treated as primary, and~/.zshrcwas created whenever zsh happened to be installed, so a zsh user was told tosource ~/.bashrc.getent passwd), falling back to$SHELL. That's more reliable than$SHELL, which can be inherited, and the script itself always runs under bash.~/.bashrc, since Ubuntu's skel always creates it. bash users no longer get an unwanted~/.zshrc.~/.bashrcis still set up.source …hint and a new Shell line in the generatedCLAUDE.mdreflect the detected shell.Dedicated GitHub SSH key
~/.ssh/id_ed25519_github(override withGITHUB_SSH_KEY) instead of creating or reusing the default~/.ssh/id_ed25519, so it can be revoked on its own and is never offered to other hosts.Host github.comblock in~/.ssh/config(IdentitiesOnly yes, file mode 600).gh auth loginnow uses--skip-ssh-key -s admin:public_key, so gh doesn't upload whichever key it finds first. The dedicated key is uploaded explicitly instead, with agh auth refreshfor the scope if an existing login lacks it.ssh -Tusing only that key, which works whether or not gh is authenticated.ssh.github.com:443(withHostKeyAlias github.com) and writes the block for whichever endpoint is reachable.Host github.comentry the user already wrote is left alone, with a warning saying whichIdentityFileto point it at.Sign in to Claude Code in the script
claude auth status --json(.loggedIn); if not signed in and a terminal is attached, runsclaude auth login --claudeai.--claudeaibecause Remote Control only works with a subscription login.CLAUDE_EMAILpre-fills the sign-in page. New prompt/env:CLAUDE_LOGIN.Two phases: interaction first, then unattended
gh auth login, Claude Code install + sign-in.gh auth logininterrupted about 5 minutes in, partway through the apt installs.Always-on Remote Control (systemd user service)
REMOTE_CONTROL_SERVICE: writes~/.config/systemd/user/claude-remote-control.servicerunningclaude remote-control --name <hostname>in the project dir (extra flags viaREMOTE_CONTROL_ARGS, e.g.--spawn worktree). Also runsloginctl enable-linger, so it starts at boot without a login session.Restart=always/RestartSec=60: covers server mode exiting after about 10 minutes offline, and also means the service comes up by itself within a minute ofclaude auth loginif you weren't signed in yet.~/.claude.json, because a headless server can't answer the trust dialog.Health check instead of "go check X" steps
~/.ssh/config(i.e. exactly what git uses);claude-sync.sh doctor; Remote Control service actually staying up; Docker daemon;/var/run/reboot-required.Test plan
ubuntu:24.04container (zsh user, no TTY): phases in the right order; Claude sign-in skipped with a warning; linger enabled; unit enabled from~/.config/systemd/user;--namecorrectly quoted; project dir trusted in~/.claude.json; with no sign-in the service sits inactivating (auto-restart); health check reports sign-in ✘ and Remote Control "starts once you sign in"; exit 0systemd-analyze --user verifyclaude auth login) listed once; failure count correctclaude auth loginnot exercised (need a real Pro/Max login)shellcheckcleandetect_shellunit cases: zsh ± existing.bashrc, bash ± existing.zshrc, fishubuntu:24.04as a zsh login user: block in.zshrc+.bashrc, one block each; interactive zsh gets PATH/aliases/claudeand lands in~/project; summary sayssource ~/.zshrcSETUP_GITHUB=y, no TTY: dedicated key generated then reused, host keys pinned,~/.ssh/configblock written (600), no default key created, exit 0ssh.github.com:443~/.ssh/configwriter: fallback line present while unregistered and removed after registration; existing user hosts preserved; user-ownedHost github.comdetected (multi-pattern, case-insensitive) and left alone;HostName github.comunder another host not mistaken for onegh auth login/gh auth refreshupload path not exercised (needs a real GitHub login)