mirror of https://github.com/docker/docs.git
Add docker-machine provision command
Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
This commit is contained in:
parent
248596da8a
commit
01c7556e3a
|
|
@ -240,6 +240,11 @@ var Commands = []cli.Command{
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "provision",
|
||||
Usage: "Re-provision existing machines",
|
||||
Action: runCommand(cmdProvision),
|
||||
},
|
||||
{
|
||||
Name: "regenerate-certs",
|
||||
Usage: "Regenerate TLS Certificates for a machine",
|
||||
|
|
@ -355,6 +360,7 @@ func machineCommand(actionName string, host *host.Host, errorChan chan<- error)
|
|||
"kill": host.Kill,
|
||||
"upgrade": host.Upgrade,
|
||||
"ip": printIP(host),
|
||||
"provision": host.Provision,
|
||||
}
|
||||
|
||||
log.Debugf("command=%s machine=%s", actionName, host.Name)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package commands
|
||||
|
||||
import "github.com/docker/machine/libmachine"
|
||||
|
||||
func cmdProvision(c CommandLine, api libmachine.API) error {
|
||||
return runAction("provision", c, api)
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/machine/commands/commandstest"
|
||||
"github.com/docker/machine/drivers/fakedriver"
|
||||
"github.com/docker/machine/libmachine"
|
||||
"github.com/docker/machine/libmachine/auth"
|
||||
"github.com/docker/machine/libmachine/engine"
|
||||
"github.com/docker/machine/libmachine/host"
|
||||
"github.com/docker/machine/libmachine/libmachinetest"
|
||||
"github.com/docker/machine/libmachine/provision"
|
||||
"github.com/docker/machine/libmachine/provision/provisiontest"
|
||||
"github.com/docker/machine/libmachine/swarm"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCmdProvision(t *testing.T) {
|
||||
testCases := []struct {
|
||||
commandLine CommandLine
|
||||
api libmachine.API
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
commandLine: &commandstest.FakeCommandLine{
|
||||
CliArgs: []string{"foo", "bar"},
|
||||
},
|
||||
api: &libmachinetest.FakeAPI{
|
||||
Hosts: []*host.Host{
|
||||
{
|
||||
Name: "foo",
|
||||
Driver: &fakedriver.Driver{},
|
||||
HostOptions: &host.Options{
|
||||
EngineOptions: &engine.Options{},
|
||||
AuthOptions: &auth.Options{},
|
||||
SwarmOptions: &swarm.Options{},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "bar",
|
||||
Driver: &fakedriver.Driver{},
|
||||
HostOptions: &host.Options{
|
||||
EngineOptions: &engine.Options{},
|
||||
AuthOptions: &auth.Options{},
|
||||
SwarmOptions: &swarm.Options{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
provision.SetDetector(&provisiontest.FakeDetector{
|
||||
Provisioner: provisiontest.NewFakeProvisioner(nil),
|
||||
})
|
||||
|
||||
// fakeprovisioner always returns "true" for compatible host, so we
|
||||
// just need to register it.
|
||||
provision.Register("fakeprovisioner", &provision.RegisteredProvisioner{
|
||||
New: provisiontest.NewFakeProvisioner,
|
||||
})
|
||||
|
||||
for _, tc := range testCases {
|
||||
assert.Equal(t, tc.expectedErr, cmdProvision(tc.commandLine, tc.api))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<!--[metadata]>
|
||||
+++
|
||||
title = "provision"
|
||||
description = "Re-run provisioning on a created machine."
|
||||
keywords = ["machine, provision, subcommand"]
|
||||
[menu.main]
|
||||
parent="smn_machine_subcmds"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# provision
|
||||
|
||||
Re-run provisioning on a created machine.
|
||||
|
||||
Sometimes it may be helpful to re-run Machine's provisioning process on a
|
||||
created machine. Reasons for doing so may include a failure during the original
|
||||
provisioning process, or a drift from the desired system state (including the
|
||||
originally specified Swarm or Engine configuration).
|
||||
|
||||
Usage is `docker-machine provision [name]`. Multiple names may be specified.
|
||||
|
||||
$ docker-machine provision foo bar
|
||||
Copying certs to the local machine directory...
|
||||
Copying certs to the remote machine...
|
||||
Setting Docker configuration on the remote daemon...
|
||||
|
||||
The Machine provisioning process will:
|
||||
|
||||
1. Set the hostname on the instance to the name Machine addresses it by (e.g.
|
||||
`default`).
|
||||
2. Install Docker if it is not present already.
|
||||
3. Generate a set of certificates (usually with the default, self-signed CA) and
|
||||
configure the daemon to accept connections over TLS.
|
||||
4. Copy the generated certificates to the server and local config directory.
|
||||
5. Configure the Docker Engine according to the options specified at create
|
||||
time.
|
||||
6. Configure and activate Swarm if applicable.
|
||||
|
|
@ -192,3 +192,12 @@ func (h *Host) ConfigureAuth() error {
|
|||
// Call provision to re-provision the certs properly.
|
||||
return provisioner.Provision(swarm.Options{}, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions)
|
||||
}
|
||||
|
||||
func (h *Host) Provision() error {
|
||||
provisioner, err := provision.DetectProvisioner(h.Driver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,26 @@ import (
|
|||
"github.com/docker/machine/libmachine/swarm"
|
||||
)
|
||||
|
||||
var provisioners = make(map[string]*RegisteredProvisioner)
|
||||
var (
|
||||
provisioners = make(map[string]*RegisteredProvisioner)
|
||||
detector Detector = &StandardDetector{}
|
||||
)
|
||||
|
||||
type SSHCommander interface {
|
||||
// Short-hand for accessing an SSH command from the driver.
|
||||
SSHCommand(args string) (string, error)
|
||||
}
|
||||
|
||||
type Detector interface {
|
||||
DetectProvisioner(d drivers.Driver) (Provisioner, error)
|
||||
}
|
||||
|
||||
type StandardDetector struct{}
|
||||
|
||||
func SetDetector(newDetector Detector) {
|
||||
detector = newDetector
|
||||
}
|
||||
|
||||
// Provisioner defines distribution specific actions
|
||||
type Provisioner interface {
|
||||
fmt.Stringer
|
||||
|
|
@ -77,6 +90,10 @@ func Register(name string, p *RegisteredProvisioner) {
|
|||
}
|
||||
|
||||
func DetectProvisioner(d drivers.Driver) (Provisioner, error) {
|
||||
return detector.DetectProvisioner(d)
|
||||
}
|
||||
|
||||
func (detector StandardDetector) DetectProvisioner(d drivers.Driver) (Provisioner, error) {
|
||||
log.Info("Detecting the provisioner...")
|
||||
|
||||
osReleaseOut, err := drivers.RunSSHCommandFromDriver(d, "cat /etc/os-release")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
package provisiontest
|
||||
|
||||
import (
|
||||
"github.com/docker/machine/libmachine/auth"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/docker/machine/libmachine/engine"
|
||||
"github.com/docker/machine/libmachine/provision"
|
||||
"github.com/docker/machine/libmachine/provision/pkgaction"
|
||||
"github.com/docker/machine/libmachine/provision/serviceaction"
|
||||
"github.com/docker/machine/libmachine/swarm"
|
||||
)
|
||||
|
||||
type FakeDetector struct {
|
||||
provision.Provisioner
|
||||
}
|
||||
|
||||
func (fd *FakeDetector) DetectProvisioner(d drivers.Driver) (provision.Provisioner, error) {
|
||||
return fd.Provisioner, nil
|
||||
}
|
||||
|
||||
type FakeProvisioner struct{}
|
||||
|
||||
func NewFakeProvisioner(d drivers.Driver) provision.Provisioner {
|
||||
return &FakeProvisioner{}
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) SSHCommand(args string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) String() string {
|
||||
return "fakeprovisioner"
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) GenerateDockerOptions(dockerPort int) (*provision.DockerOptions, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) GetDockerOptionsDir() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) GetAuthOptions() auth.Options {
|
||||
return auth.Options{}
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) Package(name string, action pkgaction.PackageAction) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) Hostname() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) SetHostname(hostname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) CompatibleWithHost() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) Service(name string, action serviceaction.ServiceAction) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) GetDriver() drivers.Driver {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fp *FakeProvisioner) SetOsReleaseInfo(info *provision.OsRelease) {}
|
||||
|
||||
func (fp *FakeProvisioner) GetOsReleaseInfo() (*provision.OsRelease, error) {
|
||||
return nil, nil
|
||||
}
|
||||
Loading…
Reference in New Issue