Skip to content

Commit 8688be4

Browse files
authored
Merge pull request #1325 from AkihiroSuda/split-show-ssh
Split show_ssh.go (no substantial code change)
2 parents 6bb9005 + 1650b33 commit 8688be4

File tree

2 files changed

+96
-62
lines changed

2 files changed

+96
-62
lines changed

cmd/limactl/show_ssh.go

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package main
33
import (
44
"errors"
55
"fmt"
6-
"io"
76
"os"
87
"strings"
98

@@ -12,20 +11,6 @@ import (
1211
"github.com/spf13/cobra"
1312
)
1413

15-
const (
16-
showSSHFormatCmd = "cmd"
17-
showSSHFormatArgs = "args"
18-
showSSHFormatOptions = "options"
19-
showSSHFormatConfig = "config"
20-
// TODO: consider supporting "url" format (ssh://USER@HOSTNAME:PORT)
21-
22-
// TODO: consider supporting "json" format
23-
// It is unclear whether we can just map ssh "config" into JSON, as "config" has duplicated keys.
24-
// (JSON supports duplicated keys too, but not all JSON implementations expect JSON with duplicated keys)
25-
)
26-
27-
var showSSHFormats = []string{showSSHFormatCmd, showSSHFormatArgs, showSSHFormatOptions, showSSHFormatConfig}
28-
2914
const showSSHExample = `
3015
"cmd" format (default): Full ssh command line.
3116
$ limactl show-ssh --format=cmd default
@@ -62,9 +47,9 @@ func newShowSSHCommand() *cobra.Command {
6247
SilenceErrors: true,
6348
}
6449

65-
shellCmd.Flags().StringP("format", "f", showSSHFormatCmd, "Format: "+strings.Join(showSSHFormats, ", "))
50+
shellCmd.Flags().StringP("format", "f", sshutil.FormatCmd, "Format: "+strings.Join(sshutil.Formats, ", "))
6651
_ = shellCmd.RegisterFlagCompletionFunc("format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
67-
return showSSHFormats, cobra.ShellCompDirectiveNoFileComp
52+
return sshutil.Formats, cobra.ShellCompDirectiveNoFileComp
6853
})
6954
return shellCmd
7055
}
@@ -93,51 +78,7 @@ func showSSHAction(cmd *cobra.Command, args []string) error {
9378
}
9479
opts = append(opts, "Hostname=127.0.0.1")
9580
opts = append(opts, fmt.Sprintf("Port=%d", inst.SSHLocalPort))
96-
return formatSSH(w, instName, format, opts)
97-
}
98-
99-
func quoteOption(o string) string {
100-
// make sure the shell doesn't swallow quotes in option values
101-
if strings.ContainsRune(o, '"') {
102-
o = "'" + o + "'"
103-
}
104-
return o
105-
}
106-
107-
func formatSSH(w io.Writer, instName, format string, opts []string) error {
108-
fakeHostname := "lima-" + instName // corresponds to the default guest hostname
109-
switch format {
110-
case showSSHFormatCmd:
111-
args := []string{"ssh"}
112-
for _, o := range opts {
113-
args = append(args, "-o", quoteOption(o))
114-
}
115-
args = append(args, fakeHostname)
116-
// the args are similar to `limactl shell` but not exactly same. (e.g., lacks -t)
117-
fmt.Fprintln(w, strings.Join(args, " ")) // no need to use shellescape.QuoteCommand
118-
case showSSHFormatArgs:
119-
var args []string
120-
for _, o := range opts {
121-
args = append(args, "-o", quoteOption(o))
122-
}
123-
fmt.Fprintln(w, strings.Join(args, " ")) // no need to use shellescape.QuoteCommand
124-
case showSSHFormatOptions:
125-
for _, o := range opts {
126-
fmt.Fprintln(w, o)
127-
}
128-
case showSSHFormatConfig:
129-
fmt.Fprintf(w, "Host %s\n", fakeHostname)
130-
for _, o := range opts {
131-
kv := strings.SplitN(o, "=", 2)
132-
if len(kv) != 2 {
133-
return fmt.Errorf("unexpected option %q", o)
134-
}
135-
fmt.Fprintf(w, " %s %s\n", kv[0], kv[1])
136-
}
137-
default:
138-
return fmt.Errorf("unknown format: %q", format)
139-
}
140-
return nil
81+
return sshutil.Format(w, instName, format, opts)
14182
}
14283

14384
func showSSHBashComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

pkg/sshutil/format.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package sshutil
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"strings"
7+
)
8+
9+
// FormatT specifies the format type.
10+
type FormatT = string
11+
12+
const (
13+
// FormatCmd prints the full ssh command line.
14+
//
15+
// ssh -o IdentityFile="/Users/example/.lima/_config/user" -o User=example -o Hostname=127.0.0.1 -o Port=60022 lima-default
16+
FormatCmd = FormatT("cmd")
17+
18+
// FormatArgs is similar to FormatCmd but omits "ssh" and the destination address
19+
//
20+
// -o IdentityFile="/Users/example/.lima/_config/user" -o User=example -o Hostname=127.0.0.1 -o Port=60022
21+
FormatArgs = FormatT("args")
22+
23+
// FormatOptions prints the ssh option key value pairs.
24+
//
25+
// IdentityFile="/Users/example/.lima/_config/user"
26+
// User=example
27+
// Hostname=127.0.0.1
28+
// Port=60022
29+
FormatOptions = FormatT("options")
30+
31+
// FormatConfig uses the ~/.ssh/config format
32+
//
33+
// Host lima-default
34+
// IdentityFile "/Users/example/.lima/_config/user "
35+
// User example
36+
// Hostname 127.0.0.1
37+
// Port 60022
38+
FormatConfig = FormatT("config")
39+
40+
// TODO: consider supporting "url" format (ssh://USER@HOSTNAME:PORT)
41+
//
42+
// TODO: consider supporting "json" format
43+
// It is unclear whether we can just map ssh "config" into JSON, as "config" has duplicated keys.
44+
// (JSON supports duplicated keys too, but not all JSON implementations expect JSON with duplicated keys)
45+
)
46+
47+
// Formats is the list of the supported formats.
48+
var Formats = []FormatT{FormatCmd, FormatArgs, FormatOptions, FormatConfig}
49+
50+
func quoteOption(o string) string {
51+
// make sure the shell doesn't swallow quotes in option values
52+
if strings.ContainsRune(o, '"') {
53+
o = "'" + o + "'"
54+
}
55+
return o
56+
}
57+
58+
// Format formats the ssh options.
59+
func Format(w io.Writer, instName string, format FormatT, opts []string) error {
60+
fakeHostname := "lima-" + instName // corresponds to the default guest hostname
61+
switch format {
62+
case FormatCmd:
63+
args := []string{"ssh"}
64+
for _, o := range opts {
65+
args = append(args, "-o", quoteOption(o))
66+
}
67+
args = append(args, fakeHostname)
68+
// the args are similar to `limactl shell` but not exactly same. (e.g., lacks -t)
69+
fmt.Fprintln(w, strings.Join(args, " ")) // no need to use shellescape.QuoteCommand
70+
case FormatArgs:
71+
var args []string
72+
for _, o := range opts {
73+
args = append(args, "-o", quoteOption(o))
74+
}
75+
fmt.Fprintln(w, strings.Join(args, " ")) // no need to use shellescape.QuoteCommand
76+
case FormatOptions:
77+
for _, o := range opts {
78+
fmt.Fprintln(w, o)
79+
}
80+
case FormatConfig:
81+
fmt.Fprintf(w, "Host %s\n", fakeHostname)
82+
for _, o := range opts {
83+
kv := strings.SplitN(o, "=", 2)
84+
if len(kv) != 2 {
85+
return fmt.Errorf("unexpected option %q", o)
86+
}
87+
fmt.Fprintf(w, " %s %s\n", kv[0], kv[1])
88+
}
89+
default:
90+
return fmt.Errorf("unknown format: %q", format)
91+
}
92+
return nil
93+
}

0 commit comments

Comments
 (0)