Allow `ssh/config` to accept string, or array of strings
[!NOTE] I made this PR rogue, in the sense that I forked and made a change that seems to have worked without discussing this change with anybody else first. I don't necessarily expect this to be merged. 🙂
On the topic of passing through
configI would like to use this option, so that I can embed aconfig/ssh_configwith my project and have Kamal use it, instead of having to modify my global~/.ssh/config.
There are the following changes in this PR:
- Actually pass
ssh/configthrough to the SSH options, so that the documentation is accurate. - Modify
run_over_ssh(shelling out to SSH) to actually use the config file if one is passed, ornoneiffalseis passed - Modify the validation to allow a path to a config file, in addition to the boolean
- Modify the documentation because, we don't actually support an array of files
Supporting a string path allows support for using an ssh_config-file in Kamal, similar to this:
Host web
HostName 8.8.8.8
User kamal
Host accessories
HostName 10.0.0.3
User kamal
ProxyJump web
... which then allows you to specify the hosts using the names, rather than IPs. The same file can also be used when SSHing in manually, using ssh -F ssh_config web.
This is reviewable commit-by-commit.
To do
- [ ] Main question: is this change wanted?
- [x] Add tests to ensure this keeps working.
FYI I force-pushed, because I added tests to each commit.
I've noticed that certain commands (e.g. app exec -i, logs -f) doesn't go through SSHKit, so this change isn't complete.
@Burgestrand any updates on this? I ran into this as well and very interested in getting this functionality added.
~~For now this got me far enough to notice there's more to it to get it to work for a few specific commands.~~
~~I don't know which parts need to change to get e.g. log following to respect this flag. I won't be working on this for at least a few weeks, but if you want to pick up where I left off absolutely feel free.~~
On top of that I would say this is still missing the blessing of the maintainers of Kamal, i.e. is this something they'd like to merge and ultimately support.
I would hope it is blessed by the maintainers because @jeremy linked this PR when I raised an issue abt the incorrect documentation related to ssh config.
Is the issue time or other resources? I don't have my ruby merit badge but I'd be willing to sponsor some hours if that's a motivator.
Is the issue time or other resources? [...]
Motivation and time expenditure! I've been experimenting with Kamal for future projects, but paid client work got in between and I'm not using Kamal for them in the near future 😊
Regardless, I had some time to think about the "interactive commands" problem in the car today and figured "how hard can it be?", so now this PR also has some adjustments so that e.g. kamal app logs --follow work properly.
In doing that work I noticed the ssh CLI doesn't accept more than one ssh_config through -F, so I opted to remove the array option as a minimum common supported option between SSH and SSHKit.
@djmb @Sija @jeremy
Any of you able to review these changes?
+1. Ended up here because the Kamal documentation says you can set ssh/config to a file path (or array of paths) to load specific configuration, but per the above comment this appears to be incorrect, and I'm getting the error:
ERROR (Kamal::ConfigurationError): ssh/config: should be a boolean
Initially, I tried overriding the ssh configuration on a per-role basis (as the documentation says "overwrite other settings from the root configuration") just to get something working, but that too seems unsupported. So into this PR I went...
Use Case
I need multiple servers/VMs that have the same IP address to be treated as separate servers (they have different TCP ports for their SSH daemon, behind some proxy -- I'm deploying to TensorDock and this can happen). This PR was close to making my specific use case possible, but:
Kamal::Configuration::Sshprovides sane defaults foruserandport, and they are always set within the#optionshashKamal::Commands::Base#run_over_sshspecifies (or in my case, overrides) theuserandportCLI arguments based on the aforementioned options hashKamal::Commander(which appears to be a singleton) sets the SSHKit'sssh_optionswith these also present, which overrides the settings for the Host if present in the config.
Solution
I've worked around this with additional changes by essentially ignoring/disabling the user and port settings from the config if the SSH config parameter is a string (i.e. it should be a path to an SSH configuration):
- [x] do not prefix the
hostwith theusername@or specify the port with the-pflag when running SSH commands - [x] do not include
userorportin the options hash, and thus thessh_configpassed to SSHKit
Another solution I thought of was supporting an explicit
nilforuserandportwithin the Kamal config, but I didn't want to update the validation logic just to get a working proof of concept.
I have not written tests (or even ran the existing ones yet) for that change, but so far so good. I may revisit the tests before I move to production, depending on the response here; if these semantics are something Kamal would be interested in adopting, let me know if I can help.
P.S. if there's another solution to my use-case that I'm missing and uses project-specific configuration, please let me know :mage: