add generic driver

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett 2015-01-25 23:37:17 -05:00
parent fdc8538de4
commit 7fc50f3de3
2 changed files with 266 additions and 0 deletions

View File

@ -17,6 +17,7 @@ import (
_ "github.com/docker/machine/drivers/azure"
_ "github.com/docker/machine/drivers/digitalocean"
_ "github.com/docker/machine/drivers/exoscale"
_ "github.com/docker/machine/drivers/generic"
_ "github.com/docker/machine/drivers/google"
_ "github.com/docker/machine/drivers/hyperv"
_ "github.com/docker/machine/drivers/none"

265
drivers/generic/generic.go Normal file
View File

@ -0,0 +1,265 @@
package generic
import (
"fmt"
"net"
"os"
"os/exec"
"path/filepath"
log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
"github.com/docker/machine/drivers"
"github.com/docker/machine/ssh"
"github.com/docker/machine/state"
"github.com/docker/machine/utils"
)
const (
dockerConfigDir = "/etc/docker"
)
type Driver struct {
MachineName string
IPAddress string
User string
SSHKey string
SSHPort int
CaCertPath string
PrivateKeyPath string
DriverKeyPath string
storePath string
}
func init() {
drivers.Register("generic", &drivers.RegisteredDriver{
New: NewDriver,
GetCreateFlags: GetCreateFlags,
})
}
// GetCreateFlags registers the flags this driver adds to
// "docker hosts create"
func GetCreateFlags() []cli.Flag {
return []cli.Flag{
cli.StringFlag{
Name: "generic-ip-address",
Usage: "IP Address of machine",
Value: "",
},
cli.StringFlag{
Name: "generic-user",
Usage: "User to use for machine",
Value: "root",
},
cli.StringFlag{
Name: "generic-ssh-key",
Usage: "SSH private key path",
Value: "",
},
cli.IntFlag{
Name: "generic-ssh-port",
Usage: "SSH port",
Value: 22,
},
}
}
func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) {
return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil
}
func (d *Driver) DriverName() string {
return "generic"
}
func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.IPAddress = flags.String("generic-ip-address")
d.User = flags.String("generic-user")
d.SSHKey = flags.String("generic-ssh-key")
d.SSHPort = flags.Int("generic-ssh-port")
if d.IPAddress == "" {
return fmt.Errorf("generic driver requires the --generic-ip-address option")
}
if d.SSHKey == "" {
return fmt.Errorf("generic driver requires the --generic-ssh-key option")
}
return nil
}
func (d *Driver) Create() error {
log.Infof("Copying SSH key...")
if err := utils.CopyFile(d.SSHKey, d.sshKeyPath()); err != nil {
return fmt.Errorf("unable to copy ssh key: %s", err)
}
if err := os.Chmod(d.sshKeyPath(), 0600); err != nil {
return err
}
log.Infof("Waiting for SSH...")
if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.IPAddress, 22)); err != nil {
return err
}
log.Info("Configuring machine...")
log.Debugf("Setting hostname: %s", d.MachineName)
cmd, err := d.GetSSHCommand(fmt.Sprintf(
"echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname",
d.MachineName,
d.MachineName,
d.MachineName,
))
if err != nil {
return err
}
if err := cmd.Run(); err != nil {
return err
}
log.Debug("Installing Docker")
cmd, err = d.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl get.docker.io | sudo sh -; fi")
if err != nil {
return err
}
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (d *Driver) GetURL() (string, error) {
ip, err := d.GetIP()
if err != nil {
return "", err
}
return fmt.Sprintf("tcp://%s:2376", ip), nil
}
func (d *Driver) GetIP() (string, error) {
if d.IPAddress == "" {
return "", fmt.Errorf("IP address is not set")
}
return d.IPAddress, nil
}
func (d *Driver) GetState() (state.State, error) {
addr := fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort)
_, err := net.Dial("tcp", addr)
var st state.State
if err != nil {
st = state.Stopped
} else {
st = state.Running
}
return st, nil
}
func (d *Driver) Start() error {
return fmt.Errorf("generic driver does not support start")
}
func (d *Driver) Stop() error {
return fmt.Errorf("generic driver does not support stop")
}
func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
log.Debug("Restarting...")
cmd, err := d.GetSSHCommand("sudo shutdown -r now")
if err != nil {
return err
}
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (d *Driver) Kill() error {
log.Debug("Killing...")
cmd, err := d.GetSSHCommand("sudo shutdown -P now")
if err != nil {
return err
}
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (d *Driver) StartDocker() error {
log.Debug("Starting Docker...")
cmd, err := d.GetSSHCommand("sudo service docker start")
if err != nil {
return err
}
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (d *Driver) StopDocker() error {
log.Debug("Stopping Docker...")
cmd, err := d.GetSSHCommand("sudo service docker stop")
if err != nil {
return err
}
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (d *Driver) GetDockerConfigDir() string {
return dockerConfigDir
}
func (d *Driver) Upgrade() error {
sshCmd, err := d.GetSSHCommand("apt-get update && apt-get install lxc-docker")
if err != nil {
return err
}
sshCmd.Stdin = os.Stdin
sshCmd.Stdout = os.Stdout
sshCmd.Stderr = os.Stderr
if err := sshCmd.Run(); err != nil {
return fmt.Errorf("%s", err)
}
return nil
}
func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) {
return ssh.GetSSHCommand(d.IPAddress, d.SSHPort, d.User, d.sshKeyPath(), args...), nil
}
func (d *Driver) sshKeyPath() string {
return filepath.Join(d.storePath, "id_rsa")
}
func (d *Driver) publicSSHKeyPath() string {
return d.sshKeyPath() + ".pub"
}