Add tip to "Automatically install or update dotfiles when ssh'ing into a remote machine"
parent
7e99cee0de
commit
3497688ab9
1 changed files with 46 additions and 2 deletions
|
@ -1,2 +1,46 @@
|
|||
**How can I have different groups of tasks for different hosts with different configurations?**
|
||||
## How can I have different groups of tasks for different hosts with different configurations?
|
||||
|
||||
See [here](https://github.com/anishathalye/dotbot/pull/11#issuecomment-73082152) for information on using machine-specific configs.
|
||||
|
||||
## Automatically install or update dotfiles when ssh'ing into a remote machine (or: let my dotfiles follow me)
|
||||
|
||||
In your local `~/.ssh/config`:
|
||||
|
||||
```
|
||||
Host some.remote.host.example.com
|
||||
PermitLocalCommand yes
|
||||
# Unfortunately ssh does not support line breaks in config files
|
||||
LocalCommand ssh -o PermitLocalCommand=no %n "which git >/dev/null && ([[ -d ~/dotfiles ]] && (echo "Updating dotfiles on %h ..." && cd ~/dotfiles && git pull -q && ./install >/dev/null) || (echo "Installing dotfiles on %h ..." && git clone -q https://github.com/MYNAMESPACE/dotfiles && ./dotfiles/install >/dev/null))"
|
||||
```
|
||||
|
||||
Relevant part broken down for readability:
|
||||
|
||||
```bash
|
||||
LocalCommand ssh -o PermitLocalCommand=no %n "which git >/dev/null && ([[ -d ~/dotfiles ]] && \
|
||||
(echo "Updating dotfiles on %h ..." && cd ~/dotfiles && git pull -q && ./install >/dev/null) || \
|
||||
(echo "Installing dotfiles on %h ..." && git clone -q https://github.com/MYNAMESPACE/dotfiles && ./dotfiles/install >/dev/null))"
|
||||
```
|
||||
|
||||
The main attraction here is the clever use of `LocalCommand`:
|
||||
|
||||
> `LocalCommand` Specifies a command to execute on the *local* machine after successfully connecting to the server.
|
||||
|
||||
We use `LocalCommand` to run a *second* SSH session to connect to the same remote machine and execute the defined command line in that SSH session. So what happens is this:
|
||||
|
||||
1. Initiate SSH connection to remote machine (`ssh user@some.remote.host.example.com`)
|
||||
2. If the connection is successful (including authentication) then `LocalCommand` is executed
|
||||
3. The `LocalCommand` initiates a second SSH connection to the same remote machine and executes the command line specified. This commandline updates or installes the dotfiles.
|
||||
|
||||
The second SSH connection sets `-o PermitLocalCommand=no` so that *no local command* is executed for that SSH connection. Without this setting each SSH connection would initiate another SSH connection, which would initiate another SSH connection, ad infinitum. Wo don't want that.
|
||||
4. When the command line of the second SSH connection is finished then the `LocalCommand` is finished
|
||||
5. The initial SSH session is finally established and the remote shell becomes available
|
||||
|
||||
The command line is in Bash syntax so adapt it if you use a different shell.
|
||||
|
||||
First we check if `git` is even available (if it is not then nothing more will happen). Then, if there is a `dotfiles` directory in the user's home we `cd` into it, run `git pull` and `install`, thus updating the local dotfiles repository and installing any new or changed files or symlinks.
|
||||
|
||||
If there isn't a `dotfiles` repository in the user's home we do a fresh installation by cloning the dotfiles repo from Github and running the `install` command.
|
||||
|
||||
Obviously this `LocalCommand` is executed every time you connect to the remote machine so it will take a few seconds before your remote shell becomes available.
|
||||
|
||||
This works best if you use public key authentication (or GSSAPI/Kerberos authentication) so SSH doesn't ask for a password when logging in. If you do use password authentication then you will need to enter your password once for each of the two SSH connections.
|
Loading…
Reference in a new issue