Files
docker-machine/drivers/generic/generic.go
Nathan LeClaire b5927f10c4 Make libmachine usable by outside world
- Clear out some cruft tightly coupling libmachine to filestore

- Comment out drivers other than virtualbox for now

- Change way too many things

- Mostly, break out the code to be more modular.

- Destroy all traces of "provider" in its current form.  It will be
brought back as something more sensible, instead of something which
overlaps in function with both Host and Store.

- Fix mis-managed config passthru

- Remove a few instances of state stored in env vars

- This should be explicitly communicated in Go-land, not through the
shell.

- Rename "store" module to "persist"

- This is done mostly to avoid confusion about the fact that a concrete
instance of a "Store" interface is oftentimes referred to as "store" in
the code.

- Rip out repetitive antipattern for getting store

- This replaces the previous repetive idiom for getting the cert info, and
consequently the store, with a much less repetitive idiom.

- Also, some redundant methods in commands.go for accessing hosts have
either been simplified or removed entirely.

- First steps towards fixing up tests

- Test progress continues

- Replace unit tests with integration tests

- MAKE ALL UNIT TESTS PASS YAY

- Add helper test files

- Don't write to disk in libmachine/host

- Heh.. coverage check strikes again

- Fix remove code

- Move cert code around

- Continued progress: simplify Driver

- Fixups and make creation work with new model

- Move drivers module inside of libmachine

- Move ssh module inside of libmachine

- Move state module to libmachine

- Move utils module to libmachine

- Move version module to libmachine

- Move log module to libmachine

- Modify some constructor methods around

- Change Travis build dep structure

- Boring gofmt fix

- Add version module

- Move NewHost to store

- Update some boring cert path infos to make API easier to use

- Fix up some issues around the new model

- Clean up some cert path stuff

- Don't use shady functions to get store path :D

- Continue artifact work

- Fix silly machines dir bug

- Continue fixing silly path issues

- Change up output of vbm a bit

- Continue work to make example go

- Change output a little more

- Last changes needed to make create finish properly

- Fix config.go to use libmachine

- Cut down code duplication and make both methods work with libmachine

- Add pluggable logging implementation

- Return error when machine already in desired state

- Update example to show log method

- Fix file:// bug

- Fix Swarm defaults

- Remove unused TLS settings from Engine and Swarm options

- Remove spurious error

- Correct bug detecting if migration was performed

- Fix compilation errors from tests

- Fix most of remaining test issues

- Fix final silly bug in tests

- Remove extraneous debug code

- Add -race to test command

- Appease the gofmt

- Appease the generate coverage

- Making executive decision to remove Travis coverage check

In the early days I thought this would be a good idea because it would
encourage people to write tests in case they added a new module.  Well,
in fact it has just turned into a giant nuisance and made refactoring
work like this even more difficult.

- Move Get to Load
- Move HostListItem code to CLI

Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
2015-09-23 12:30:15 -07:00

187 lines
3.7 KiB
Go

package generic
import (
"fmt"
"net"
"os"
"path/filepath"
"time"
"github.com/codegangsta/cli"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/mcnutils"
"github.com/docker/machine/libmachine/state"
)
type Driver struct {
*drivers.BaseDriver
SSHKey string
}
const (
defaultSSHUser = "root"
defaultSSHPort = 22
defaultTimeout = 1 * time.Second
)
var (
defaultSSHKey = filepath.Join(mcnutils.GetHomeDir(), ".ssh", "id_rsa")
)
func init() {
drivers.Register("generic", &drivers.RegisteredDriver{
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",
},
cli.StringFlag{
Name: "generic-ssh-user",
Usage: "SSH user",
Value: defaultSSHUser,
},
cli.StringFlag{
Name: "generic-ssh-key",
Usage: "SSH private key path",
Value: defaultSSHKey,
},
cli.IntFlag{
Name: "generic-ssh-port",
Usage: "SSH port",
Value: defaultSSHPort,
},
}
}
func NewDriver(hostName, storePath string) drivers.Driver {
return &Driver{
SSHKey: defaultSSHKey,
BaseDriver: &drivers.BaseDriver{
SSHUser: defaultSSHUser,
SSHPort: defaultSSHPort,
MachineName: hostName,
StorePath: storePath,
},
}
}
func (d *Driver) DriverName() string {
return "generic"
}
func (d *Driver) GetSSHHostname() (string, error) {
return d.GetIP()
}
func (d *Driver) GetSSHUsername() string {
return d.SSHUser
}
func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.IPAddress = flags.String("generic-ip-address")
d.SSHUser = flags.String("generic-ssh-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) PreCreateCheck() error {
return nil
}
func (d *Driver) Create() error {
log.Infof("Importing SSH key...")
if err := mcnutils.CopyFile(d.SSHKey, d.GetSSHKeyPath()); err != nil {
return fmt.Errorf("unable to copy ssh key: %s", err)
}
if err := os.Chmod(d.GetSSHKeyPath(), 0600); err != nil {
return err
}
log.Debugf("IP: %s", d.IPAddress)
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.DialTimeout("tcp", addr, defaultTimeout)
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...")
if _, err := drivers.RunSSHCommandFromDriver(d, "sudo shutdown -r now"); err != nil {
return err
}
return nil
}
func (d *Driver) Kill() error {
log.Debug("Killing...")
if _, err := drivers.RunSSHCommandFromDriver(d, "sudo shutdown -P now"); err != nil {
return err
}
return nil
}
func (d *Driver) publicSSHKeyPath() string {
return d.GetSSHKeyPath() + ".pub"
}