-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Pedro Castillo <[email protected]>
- Loading branch information
Showing
8 changed files
with
198 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package docker | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
|
||
"golang.org/x/crypto/ssh" | ||
|
||
"github.com/govm-project/govm/internal" | ||
"github.com/govm-project/govm/pkg/homedir" | ||
"github.com/govm-project/govm/pkg/termutil" | ||
) | ||
|
||
func (e *Engine) SSHVM(namespace, id, user, key string, term *termutil.Terminal) error { | ||
container, err := e.docker.Inspect(id) | ||
if err != nil { | ||
fullName := internal.GenerateContainerName(namespace, id) | ||
container, err = e.docker.Inspect(fullName) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
ip := container.NetworkSettings.IPAddress | ||
keyPath := homedir.ExpandPath(key) | ||
|
||
privateKey, err := ioutil.ReadFile(keyPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
signer, err := ssh.ParsePrivateKey(privateKey) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
config := ssh.ClientConfig{ | ||
User: user, | ||
Auth: []ssh.AuthMethod{ | ||
ssh.PublicKeys(signer), | ||
}, | ||
HostKeyCallback: ssh.InsecureIgnoreHostKey(), | ||
} | ||
config.SetDefaults() | ||
|
||
conn, err := ssh.Dial("tcp", ip+":22", &config) | ||
if err != nil { | ||
return err | ||
} | ||
defer conn.Close() | ||
|
||
sess, err := conn.NewSession() | ||
if err != nil { | ||
return err | ||
} | ||
defer sess.Close() | ||
|
||
sess.Stdin = term.In() | ||
sess.Stdout = term.Out() | ||
sess.Stderr = term.Err() | ||
|
||
sz, err := term.GetWinsize() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = term.MakeRaw() | ||
if err != nil { | ||
return err | ||
} | ||
defer term.Restore() | ||
|
||
err = sess.RequestPty(os.Getenv("TERM"), int(sz.Height), int(sz.Width), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = sess.Shell() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// If our terminal window changes, signal the ssh connection | ||
stopch := make(chan struct{}) | ||
defer close(stopch) | ||
go func() { | ||
sigch := make(chan os.Signal) | ||
signal.Notify(sigch, syscall.SIGWINCH) | ||
defer signal.Stop(sigch) | ||
defer close(sigch) | ||
outer: | ||
for { | ||
select { | ||
case <-sigch: | ||
sz, err := term.GetWinsize() | ||
if err == nil { | ||
sess.WindowChange(int(sz.Height), int(sz.Width)) | ||
} | ||
case <-stopch: | ||
break outer | ||
} | ||
} | ||
}() | ||
|
||
return sess.Wait() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
package main | ||
package engines | ||
|
||
import ( | ||
"github.com/govm-project/govm/pkg/termutil" | ||
"github.com/govm-project/govm/vm" | ||
) | ||
|
||
// VMEngine stands as an abstraction for VMs management engines | ||
type VMEngine interface { | ||
Create(spec vm.Instance) (string, error) | ||
Start(namespace, id string) error | ||
Delete(namespace, id string) error | ||
List(namespace string, all bool) ([]vm.Instance, error) | ||
CreateVM(spec vm.Instance) (string, error) | ||
StartVM(namespace, id string) error | ||
DeleteVM(namespace, id string) error | ||
SSHVM(namespace, id, user, key string, term *termutil.Terminal) error | ||
ListVM(namespace string, all bool) ([]vm.Instance, error) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,7 @@ func New() (*cli.App, error) { | |
&removeCommand, | ||
&startCommand, | ||
&composeCommand, | ||
&sshCommand, | ||
}, | ||
}, nil | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,45 @@ | ||
package cli | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
|
||
"golang.org/x/crypto/ssh" | ||
"github.com/govm-project/govm/engines/docker" | ||
"github.com/govm-project/govm/pkg/termutil" | ||
cli "gopkg.in/urfave/cli.v2" | ||
) | ||
|
||
type password string | ||
|
||
func (p password) Password(user string) (password string, err error) { | ||
return string(p), nil | ||
} | ||
|
||
// TODO: Reduce cyclomatic complexity | ||
func getNewSSHConn(username, hostname, key string) { // nolint: gocyclo | ||
//var hostKey ssh.PublicKey | ||
|
||
privateKeyBytes, err := ioutil.ReadFile(key) | ||
if err != nil { | ||
log.Fatalf("Error on reading private key file: %v", err) | ||
} | ||
|
||
// Create the Signer for this private key. | ||
signer, err := ssh.ParsePrivateKey(privateKeyBytes) | ||
if err != nil { | ||
log.Fatalf("unable to parse private key: %v", err) | ||
} | ||
|
||
// Create client config | ||
config := &ssh.ClientConfig{ | ||
User: username, | ||
Auth: []ssh.AuthMethod{ | ||
//ssh.Password("password"), | ||
ssh.PublicKeys(signer), | ||
var sshCommand = cli.Command{ | ||
Name: "ssh", | ||
Usage: "ssh into a running VM", | ||
Flags: []cli.Flag{ | ||
&cli.StringFlag{ | ||
Name: "user", | ||
Aliases: []string{"u"}, | ||
Usage: "login as this username", | ||
}, | ||
//HostKeyCallback: ssh.FixedHostKey(hostKey), | ||
HostKeyCallback: ssh.InsecureIgnoreHostKey(), | ||
} | ||
config.SetDefaults() | ||
// Connect to ssh server | ||
conn, err := ssh.Dial("tcp", hostname+":22", config) | ||
if err != nil { | ||
log.Fatal("unable to connect: ", err) | ||
} | ||
defer func() { | ||
err := conn.Close() | ||
// TODO: Change to warning when log package is changed | ||
log.Println(err) | ||
}() | ||
|
||
// Create a session | ||
session, err := conn.NewSession() | ||
if err != nil { | ||
log.Fatal("unable to create session: ", err) | ||
} | ||
defer func() { | ||
err := session.Close() | ||
// TODO: Change to warning when log package is changed | ||
log.Println(err) | ||
}() | ||
|
||
// Set IO | ||
session.Stdout = os.Stdout | ||
session.Stderr = os.Stderr | ||
in, err := session.StdinPipe() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// Set up terminal modes | ||
modes := ssh.TerminalModes{ | ||
ssh.ECHO: 0, // disable echoing | ||
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud | ||
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud | ||
} | ||
|
||
// Request pseudo terminal | ||
if err := session.RequestPty("xterm", 80, 40, modes); err != nil { | ||
log.Fatalf("request for pseudo terminal failed: %s", err) | ||
} | ||
|
||
// Start remote shell | ||
if err := session.Shell(); err != nil { | ||
log.Fatalf("failed to start shell: %s", err) | ||
} | ||
|
||
// Accepting commands | ||
for { | ||
reader := bufio.NewReader(os.Stdin) | ||
str, err := reader.ReadString('\n') | ||
if err != nil { | ||
log.Println("Error reading command") | ||
&cli.StringFlag{ | ||
Name: "key", | ||
Aliases: []string{"k"}, | ||
Usage: "ssh private key file", | ||
Value: "~/.ssh/id_rsa", | ||
}, | ||
}, | ||
Action: func(c *cli.Context) error { | ||
if c.Args().Len() != 1 { | ||
return fmt.Errorf("VM name required") | ||
} | ||
_, err = fmt.Fprint(in, str) | ||
if err != nil { | ||
log.Println("Error reading command") | ||
name := c.Args().First() | ||
namespace := c.String("namespace") | ||
user := c.String("user") | ||
if user == "" { | ||
return fmt.Errorf("--user argument required") | ||
} | ||
} | ||
key := c.String("key") | ||
term := termutil.StdTerminal() | ||
|
||
engine := docker.Engine{} | ||
engine.Init() | ||
|
||
return engine.SSHVM(namespace, name, user, key, term) | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package types | ||
|
||
// Network represents a network for VMs | ||
type Network struct { | ||
ID string `yaml:"id" json:"id"` | ||
Subnet string `yaml:"subnet" json:"subnet"` | ||
DNS []string `yaml:"dns" json:"dns"` | ||
} |
Oops, something went wrong.