diff --git a/docs/changelog.rst b/docs/changelog.rst index aa2144bb5..9050259b0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -43,6 +43,14 @@ The :doc:`ssh kitten ` is redesigned with powerful new features: Detailed list of changes ------------------------------------- +0.30.1 [future] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- ssh kitten: Fix a regression in 0.28.0 that caused using ``--kitten`` to + override :file:`ssh.conf` not inheriting settings from :file:`ssh.conf` + (:iss:`6639`) + + 0.30.0 [2023-09-18] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/kittens/ssh.rst b/docs/kittens/ssh.rst index ae664511b..e969de1ff 100644 --- a/docs/kittens/ssh.rst +++ b/docs/kittens/ssh.rst @@ -82,10 +82,10 @@ Additionally, you can pass config options on the command line: kitty +kitten ssh --kitten interpreter=python servername The :code:`--kitten` argument can be specified multiple times, with directives -from :file:`ssh.conf`. These are merged with :file:`ssh.conf` as if they were -appended to the end of that file. They apply only to the host being SSHed to by -this invocation, so any :opt:`hostname ` directives are -ignored. +from :file:`ssh.conf`. These override the final options used for the matched host, as if they +had been appended to the end of the matching section for that host in +:file:`ssh.conf`. They apply only to the host being SSHed to by this invocation, +so any :opt:`hostname ` directives are ignored. .. warning:: diff --git a/kittens/ssh/config.go b/kittens/ssh/config.go index 96b5d8242..4d4b21067 100644 --- a/kittens/ssh/config.go +++ b/kittens/ssh/config.go @@ -391,9 +391,20 @@ func (self *ConfigSet) line_handler(key, val string) error { func load_config(hostname_to_match string, username_to_match string, overrides []string, paths ...string) (*Config, []config.ConfigLine, error) { ans := &ConfigSet{all_configs: []*Config{NewConfig()}} p := config.ConfigParser{LineHandler: ans.line_handler} - err := p.LoadConfig("ssh.conf", paths, overrides) + err := p.LoadConfig("ssh.conf", paths, nil) if err != nil { return nil, nil, err } - return config_for_hostname(hostname_to_match, username_to_match, ans), p.BadLines(), nil + final_conf := config_for_hostname(hostname_to_match, username_to_match, ans) + bad_lines := p.BadLines() + if len(overrides) > 0 { + h := final_conf.Hostname + override_parser := config.ConfigParser{LineHandler: final_conf.Parse} + if err = override_parser.ParseOverrides(overrides...); err != nil { + return nil, nil, err + } + bad_lines = append(bad_lines, override_parser.BadLines()...) + final_conf.Hostname = h + } + return final_conf, bad_lines, nil } diff --git a/kittens/ssh/config_test.go b/kittens/ssh/config_test.go index b12a5eb29..4d782afd9 100644 --- a/kittens/ssh/config_test.go +++ b/kittens/ssh/config_test.go @@ -24,11 +24,14 @@ func TestSSHConfigParsing(t *testing.T) { hostname := "unmatched" username := "" conf := "" + overrides := []string{} for_python := false cf := filepath.Join(tdir, "ssh.conf") rt := func(expected_env ...string) { - os.WriteFile(cf, []byte(conf), 0o600) - c, bad_lines, err := load_config(hostname, username, nil, cf) + if err := os.WriteFile(cf, []byte(conf), 0o600); err != nil { + t.Fatal(err) + } + c, bad_lines, err := load_config(hostname, username, overrides, cf) if err != nil { t.Fatal(err) } @@ -52,6 +55,10 @@ func TestSSHConfigParsing(t *testing.T) { rt() conf = "env a=b" rt(`export 'a'="b"`) + conf = "env a=b" + overrides = []string{"env=c=d"} + rt(`export 'a'="b"`, `export 'c'="d"`) + overrides = nil conf = "env a=\\" rt(`export 'a'="\\"`) diff --git a/kittens/ssh/main.go b/kittens/ssh/main.go index a245dded1..8d3ab5ee6 100644 --- a/kittens/ssh/main.go +++ b/kittens/ssh/main.go @@ -115,9 +115,6 @@ func parse_kitten_args(found_extra_args []string, username, hostname_for_match s } } } - if len(overrides) > 0 { - overrides = append([]string{"hostname " + username + "@" + hostname_for_match}, overrides...) - } return }