@@ -12,6 +12,54 @@ import (
1212 "github.com/coreos/fleet/ssh"
1313)
1414
15+ // SSH opens an interactive shell to a machine in the cluster
16+ func (c * FleetClient ) SSH (name string ) (err error ) {
17+ var sshClient * ssh.SSHForwardingClient
18+
19+ timeout := time .Duration (Flags .SSHTimeout * 1000 ) * time .Millisecond
20+
21+ ms , err := machineState (name )
22+ if err != nil {
23+ return err
24+ }
25+
26+ // If name isn't a machine ID, try it as a unit instead
27+ if ms == nil {
28+ units , err := c .Units (name )
29+
30+ if err != nil {
31+ return err
32+ }
33+
34+ machID , err := findUnit (units [0 ])
35+
36+ if err != nil {
37+ return err
38+ }
39+
40+ ms , err = machineState (machID )
41+
42+ if err != nil || ms == nil {
43+ return err
44+ }
45+ }
46+
47+ addr := ms .PublicIP
48+
49+ if tun := getTunnelFlag (); tun != "" {
50+ sshClient , err = ssh .NewTunnelledSSHClient ("core" , tun , addr , getChecker (), false , timeout )
51+ } else {
52+ sshClient , err = ssh .NewSSHClient ("core" , addr , getChecker (), false , timeout )
53+ }
54+ if err != nil {
55+ return err
56+ }
57+
58+ defer sshClient .Close ()
59+ err = ssh .Shell (sshClient )
60+ return err
61+ }
62+
1563// runCommand will attempt to run a command on a given machine. It will attempt
1664// to SSH to the machine if it is identified as being remote.
1765func runCommand (cmd string , machID string ) (retcode int ) {
@@ -76,6 +124,24 @@ func runRemoteCommand(cmd string, addr string, timeout time.Duration) (exit int,
76124 return
77125}
78126
127+ // findUnits returns the machine ID of a running unit
128+ func findUnit (name string ) (machID string , err error ) {
129+ u , err := cAPI .Unit (name )
130+ if err != nil {
131+ return "" , fmt .Errorf ("Error retrieving Unit %s: %v" , name , err )
132+ }
133+ if suToGlobal (* u ) {
134+ return "" , fmt .Errorf ("Unable to connect to global unit %s.\n " , name )
135+ }
136+ if u == nil {
137+ return "" , fmt .Errorf ("Unit %s does not exist.\n " , name )
138+ } else if u .CurrentState == "" {
139+ return "" , fmt .Errorf ("Unit %s does not appear to be running.\n " , name )
140+ }
141+
142+ return u .MachineID , nil
143+ }
144+
79145func machineState (machID string ) (* machine.MachineState , error ) {
80146 machines , err := cAPI .Machines ()
81147 if err != nil {
0 commit comments