Files
docker-machine/commands/config.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

122 lines
3.3 KiB
Go

package commands
import (
"fmt"
"net/url"
"strings"
"github.com/codegangsta/cli"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/cert"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/state"
)
func cmdConfig(c *cli.Context) {
if len(c.Args()) != 1 {
log.Fatal(ErrExpectedOneMachine)
}
h := getFirstArgHost(c)
dockerHost, authOptions, err := runConnectionBoilerplate(h, c)
if err != nil {
log.Fatalf("Error running connection boilerplate: %s", err)
}
log.Debug(dockerHost)
fmt.Printf("--tlsverify --tlscacert=%q --tlscert=%q --tlskey=%q -H=%s",
authOptions.CaCertPath, authOptions.ClientCertPath, authOptions.ClientKeyPath, dockerHost)
}
func runConnectionBoilerplate(h *host.Host, c *cli.Context) (string, *auth.AuthOptions, error) {
hostState, err := h.Driver.GetState()
if err != nil {
// TODO: This is a common operation and should have a commonly
// defined error.
return "", &auth.AuthOptions{}, fmt.Errorf("Error trying to get host state: %s", err)
}
if hostState != state.Running {
return "", &auth.AuthOptions{}, fmt.Errorf("%s is not running. Please start it in order to use the connection settings.", h.Name)
}
dockerHost, err := h.Driver.GetURL()
if err != nil {
return "", &auth.AuthOptions{}, fmt.Errorf("Error getting driver URL: %s", err)
}
if c.Bool("swarm") {
var err error
dockerHost, err = parseSwarm(dockerHost, h)
if err != nil {
return "", &auth.AuthOptions{}, fmt.Errorf("Error parsing swarm: %s", err)
}
}
u, err := url.Parse(dockerHost)
if err != nil {
return "", &auth.AuthOptions{}, fmt.Errorf("Error parsing URL: %s", err)
}
authOptions := h.HostOptions.AuthOptions
if err := checkCert(u.Host, authOptions, c); err != nil {
return "", &auth.AuthOptions{}, fmt.Errorf("Error checking and/or regenerating the certs: %s", err)
}
return dockerHost, authOptions, nil
}
func checkCert(hostUrl string, authOptions *auth.AuthOptions, c *cli.Context) error {
valid, err := cert.ValidateCertificate(
hostUrl,
authOptions.CaCertPath,
authOptions.ServerCertPath,
authOptions.ServerKeyPath,
)
if err != nil {
return fmt.Errorf("Error attempting to validate the certficate: %s", err)
}
if !valid {
log.Errorf("Invalid certs detected; regenerating for %s", hostUrl)
if err := runActionWithContext("configureAuth", c); err != nil {
return fmt.Errorf("Error attempting to regenerate the certs: %s", err)
}
}
return nil
}
// TODO: This could use a unit test.
func parseSwarm(hostUrl string, h *host.Host) (string, error) {
swarmOptions := h.HostOptions.SwarmOptions
if !swarmOptions.Master {
return "", fmt.Errorf("Error: %s is not a swarm master. The --swarm flag is intended for use with swarm masters.", h.Name)
}
u, err := url.Parse(swarmOptions.Host)
if err != nil {
return "", fmt.Errorf("There was an error parsing the url: %s", err)
}
parts := strings.Split(u.Host, ":")
swarmPort := parts[1]
// get IP of machine to replace in case swarm host is 0.0.0.0
mUrl, err := url.Parse(hostUrl)
if err != nil {
return "", fmt.Errorf("There was an error parsing the url: %s", err)
}
mParts := strings.Split(mUrl.Host, ":")
machineIp := mParts[0]
hostUrl = fmt.Sprintf("tcp://%s:%s", machineIp, swarmPort)
return hostUrl, nil
}