Merge pull request #2732 from dgageot/better-logs

Improve Start/Stop/Kill/Restart lifecycle/logs
This commit is contained in:
David Gageot 2016-01-04 16:24:55 +01:00
commit e143c68cf9
15 changed files with 224 additions and 358 deletions

View File

@ -612,11 +612,7 @@ func (d *Driver) Start() error {
return err
}
if err := d.waitForInstance(); err != nil {
return err
}
return nil
return d.waitForInstance()
}
func (d *Driver) Stop() error {
@ -627,20 +623,6 @@ func (d *Driver) Stop() error {
return err
}
func (d *Driver) Remove() error {
if err := d.terminate(); err != nil {
return fmt.Errorf("unable to terminate instance: %s", err)
}
// remove keypair
if err := d.deleteKeyPair(); err != nil {
return fmt.Errorf("unable to remove key pair: %s", err)
}
return nil
}
func (d *Driver) Restart() error {
_, err := d.getClient().RebootInstances(&ec2.RebootInstancesInput{
InstanceIds: []*string{&d.InstanceId},
@ -656,6 +638,19 @@ func (d *Driver) Kill() error {
return err
}
func (d *Driver) Remove() error {
if err := d.terminate(); err != nil {
return fmt.Errorf("unable to terminate instance: %s", err)
}
// remove keypair
if err := d.deleteKeyPair(); err != nil {
return fmt.Errorf("unable to remove key pair: %s", err)
}
return nil
}
func (d *Driver) getClient() *ec2.EC2 {
config := aws.NewConfig()
config = config.WithRegion(d.Region)

View File

@ -13,7 +13,6 @@ import (
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/mcnutils"
"github.com/docker/machine/libmachine/ssh"
"github.com/docker/machine/libmachine/state"
)
@ -286,8 +285,6 @@ func (d *Driver) Start() error {
return nil
}
log.Debugf("starting %s", d.MachineName)
if err := vmClient.StartRole(d.MachineName, d.MachineName, d.MachineName); err != nil {
return err
}
@ -302,15 +299,6 @@ func (d *Driver) Stop() error {
return err
}
if vmState, err := d.GetState(); err != nil {
return err
} else if vmState == state.Stopped {
log.Infof("Host is already stopped")
return nil
}
log.Debugf("stopping %s", d.MachineName)
if err := vmClient.ShutdownRole(d.MachineName, d.MachineName, d.MachineName); err != nil {
return err
}
@ -319,69 +307,38 @@ func (d *Driver) Stop() error {
return nil
}
func (d *Driver) Restart() error {
if err := d.setUserSubscription(); err != nil {
return err
}
if err := vmClient.RestartRole(d.MachineName, d.MachineName, d.MachineName); err != nil {
return err
}
var err error
d.IPAddress, err = d.GetIP()
return err
}
func (d *Driver) Kill() error {
return d.Stop()
}
func (d *Driver) Remove() error {
if err := d.setUserSubscription(); err != nil {
return err
}
if available, _, err := vmClient.CheckHostedServiceNameAvailability(d.MachineName); err != nil {
return err
} else if available {
return nil
}
log.Debugf("removing %s", d.MachineName)
return vmClient.DeleteHostedService(d.MachineName)
}
func (d *Driver) Restart() error {
err := d.setUserSubscription()
if err != nil {
return err
}
if vmState, err := d.GetState(); err != nil {
return err
} else if vmState == state.Stopped {
return errors.New("Host is already stopped, use start command to run it")
}
log.Debugf("restarting %s", d.MachineName)
if err := vmClient.RestartRole(d.MachineName, d.MachineName, d.MachineName); err != nil {
return err
}
d.IPAddress, err = d.GetIP()
return err
}
func (d *Driver) Kill() error {
if err := d.setUserSubscription(); err != nil {
return err
}
if vmState, err := d.GetState(); err != nil {
return err
} else if vmState == state.Stopped {
log.Infof("Host is already stopped")
return nil
}
log.Debugf("killing %s", d.MachineName)
if err := vmClient.ShutdownRole(d.MachineName, d.MachineName, d.MachineName); err != nil {
return err
}
d.IPAddress = ""
return nil
}
func generateVMName() string {
randomID := mcnutils.TruncateID(mcnutils.GenerateRandomID())
return fmt.Sprintf("docker-host-%s", randomID)
}
func (d *Driver) setUserSubscription() error {
if d.PublishSettingsFilePath != "" {
return azure.ImportPublishSettingsFile(d.PublishSettingsFilePath)

View File

@ -288,6 +288,16 @@ func (d *Driver) Stop() error {
return err
}
func (d *Driver) Restart() error {
_, _, err := d.getClient().DropletActions.Reboot(d.DropletID)
return err
}
func (d *Driver) Kill() error {
_, _, err := d.getClient().DropletActions.PowerOff(d.DropletID)
return err
}
func (d *Driver) Remove() error {
client := d.getClient()
if resp, err := client.Keys.DeleteByID(d.SSHKeyID); err != nil {
@ -307,16 +317,6 @@ func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
_, _, err := d.getClient().DropletActions.Reboot(d.DropletID)
return err
}
func (d *Driver) Kill() error {
_, _, err := d.getClient().DropletActions.PowerOff(d.DropletID)
return err
}
func (d *Driver) getClient() *godo.Client {
token := &oauth2.Token{AccessToken: d.AccessToken}
tokenSource := oauth2.StaticTokenSource(token)

View File

@ -320,45 +320,40 @@ func (d *Driver) Create() error {
}
func (d *Driver) Start() error {
vmstate, err := d.GetState()
if err != nil {
return err
}
if vmstate == state.Running || vmstate == state.Starting {
log.Infof("Host is already running or starting")
return nil
}
client := egoscale.NewClient(d.URL, d.APIKey, d.APISecretKey)
svmresp, err := client.StartVirtualMachine(d.ID)
if err != nil {
return err
}
if err = d.waitForJob(client, svmresp); err != nil {
return err
}
return nil
return d.waitForJob(client, svmresp)
}
func (d *Driver) Stop() error {
vmstate, err := d.GetState()
if err != nil {
return err
}
if vmstate == state.Stopped {
log.Infof("Host is already stopped")
return nil
}
client := egoscale.NewClient(d.URL, d.APIKey, d.APISecretKey)
svmresp, err := client.StopVirtualMachine(d.ID)
if err != nil {
return err
}
if err = d.waitForJob(client, svmresp); err != nil {
return d.waitForJob(client, svmresp)
}
func (d *Driver) Restart() error {
client := egoscale.NewClient(d.URL, d.APIKey, d.APISecretKey)
svmresp, err := client.RebootVirtualMachine(d.ID)
if err != nil {
return err
}
return nil
return d.waitForJob(client, svmresp)
}
func (d *Driver) Kill() error {
return d.Stop()
}
func (d *Driver) Remove() error {
@ -380,31 +375,6 @@ func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
vmstate, err := d.GetState()
if err != nil {
return err
}
if vmstate == state.Stopped {
return fmt.Errorf("Host is stopped, use start command to start it")
}
client := egoscale.NewClient(d.URL, d.APIKey, d.APISecretKey)
svmresp, err := client.RebootVirtualMachine(d.ID)
if err != nil {
return err
}
if err = d.waitForJob(client, svmresp); err != nil {
return err
}
return nil
}
func (d *Driver) Kill() error {
return d.Stop()
}
func (d *Driver) jobIsDone(client *egoscale.Client, jobid string) (bool, error) {
resp, err := client.PollAsyncJob(jobid)
if err != nil {

View File

@ -80,10 +80,6 @@ func (d *Driver) Create() error {
return nil
}
func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Start() error {
d.MockState = state.Running
return nil
@ -104,6 +100,10 @@ func (d *Driver) Kill() error {
return nil
}
func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Upgrade() error {
return nil
}

View File

@ -159,12 +159,7 @@ func (d *Driver) Stop() error {
return errors.New("generic driver does not support stop")
}
func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
log.Debug("Restarting...")
_, err := drivers.RunSSHCommandFromDriver(d, "sudo shutdown -r now")
return err
}
@ -172,3 +167,7 @@ func (d *Driver) Restart() error {
func (d *Driver) Kill() error {
return errors.New("generic driver does not support kill")
}
func (d *Driver) Remove() error {
return nil
}

View File

@ -340,7 +340,6 @@ func (c *ComputeUtil) deleteInstance() error {
// stopInstance stops the instance.
func (c *ComputeUtil) stopInstance() error {
log.Infof("Stopping instance.")
op, err := c.service.Instances.Stop(c.project, c.zone, c.instanceName).Do()
if err != nil {
return err
@ -352,7 +351,6 @@ func (c *ComputeUtil) stopInstance() error {
// startInstance starts the instance.
func (c *ComputeUtil) startInstance() error {
log.Infof("Starting instance.")
op, err := c.service.Instances.Start(c.project, c.zone, c.instanceName).Do()
if err != nil {
return err

View File

@ -316,6 +316,15 @@ func (d *Driver) Stop() error {
return nil
}
// Restart restarts a machine which is known to be running.
func (d *Driver) Restart() error {
if err := d.Stop(); err != nil {
return err
}
return d.Start()
}
// Kill stops an existing GCE instance.
func (d *Driver) Kill() error {
return d.Stop()
@ -339,12 +348,3 @@ func (d *Driver) Remove() error {
}
return c.deleteDisk()
}
// Restart restarts a machine which is known to be running.
func (d *Driver) Restart() error {
if err := d.Stop(); err != nil {
return err
}
return d.Start()
}

View File

@ -383,26 +383,31 @@ func (d *Driver) Create() error {
}
func (d *Driver) Start() error {
log.Debug("Starting OpenStack instance...", map[string]string{"MachineId": d.MachineId})
if err := d.initCompute(); err != nil {
return err
}
if err := d.client.StartInstance(d); err != nil {
return err
}
return nil
return d.client.StartInstance(d)
}
func (d *Driver) Stop() error {
log.Debug("Stopping OpenStack instance...", map[string]string{"MachineId": d.MachineId})
if err := d.initCompute(); err != nil {
return err
}
if err := d.client.StopInstance(d); err != nil {
return d.client.StopInstance(d)
}
func (d *Driver) Restart() error {
if err := d.initCompute(); err != nil {
return err
}
return nil
return d.client.RestartInstance(d)
}
func (d *Driver) Kill() error {
return d.Stop()
}
func (d *Driver) Remove() error {
@ -422,21 +427,6 @@ func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
log.Info("Restarting OpenStack instance...", map[string]string{"MachineId": d.MachineId})
if err := d.initCompute(); err != nil {
return err
}
if err := d.client.RestartInstance(d); err != nil {
return err
}
return nil
}
func (d *Driver) Kill() error {
return d.Stop()
}
const (
errorMandatoryEnvOrOption string = "%s must be specified either using the environment variable %s or the CLI option %s"
errorMandatoryOption string = "%s must be specified using the CLI option %s"

View File

@ -454,10 +454,6 @@ func (d *Driver) publicSSHKeyPath() string {
return d.GetSSHKeyPath() + ".pub"
}
func (d *Driver) Kill() error {
return d.getClient().VirtualGuest().PowerOff(d.Id)
}
func (d *Driver) Remove() error {
log.Infof("Canceling SoftLayer instance %d...", d.Id)
var err error
@ -479,12 +475,19 @@ func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
return d.getClient().VirtualGuest().Reboot(d.Id)
}
func (d *Driver) Start() error {
return d.getClient().VirtualGuest().PowerOn(d.Id)
}
func (d *Driver) Stop() error {
return d.getClient().VirtualGuest().PowerOff(d.Id)
}
func (d *Driver) Restart() error {
return d.getClient().VirtualGuest().Reboot(d.Id)
}
func (d *Driver) Kill() error {
return d.Stop()
}

View File

@ -479,7 +479,6 @@ func (d *Driver) Start() error {
if err := d.vbm("startvm", d.MachineName, "--type", "headless"); err != nil {
return err
}
log.Infof("Starting VM...")
case state.Paused:
if err := d.vbm("controlvm", d.MachineName, "resume", "--type", "headless"); err != nil {
return err
@ -502,23 +501,6 @@ func (d *Driver) Start() error {
return d.waitForIP()
}
func (d *Driver) waitForIP() error {
// Wait for SSH over NAT to be available before returning to user
if err := drivers.WaitForSSH(d); err != nil {
return err
}
// Bail if we don't get an IP from DHCP after a given number of seconds.
if err := mcnutils.WaitForSpecific(d.hostOnlyIPAvailable, 5, 4*time.Second); err != nil {
return err
}
var err error
d.IPAddress, err = d.GetIP()
return err
}
func (d *Driver) Stop() error {
currentState, err := d.GetState()
if err != nil {
@ -546,13 +528,44 @@ func (d *Driver) Stop() error {
break
}
}
log.Infof("Stopping VM...")
d.IPAddress = ""
return nil
}
// Restart restarts a machine which is known to be running.
func (d *Driver) Restart() error {
if err := d.vbm("controlvm", d.MachineName, "reset"); err != nil {
return err
}
d.IPAddress = ""
return d.waitForIP()
}
func (d *Driver) Kill() error {
return d.vbm("controlvm", d.MachineName, "poweroff")
}
func (d *Driver) waitForIP() error {
// Wait for SSH over NAT to be available before returning to user
if err := drivers.WaitForSSH(d); err != nil {
return err
}
// Bail if we don't get an IP from DHCP after a given number of seconds.
if err := mcnutils.WaitForSpecific(d.hostOnlyIPAvailable, 5, 4*time.Second); err != nil {
return err
}
var err error
d.IPAddress, err = d.GetIP()
return err
}
func (d *Driver) Remove() error {
s, err := d.GetState()
if err != nil {
@ -576,22 +589,6 @@ func (d *Driver) Remove() error {
return d.vbm("unregistervm", "--delete", d.MachineName)
}
// Restart restarts a machine which is known to be running.
func (d *Driver) Restart() error {
log.Infof("Restarting VM...")
if err := d.vbm("controlvm", d.MachineName, "reset"); err != nil {
return err
}
d.IPAddress = ""
return d.waitForIP()
}
func (d *Driver) Kill() error {
return d.vbm("controlvm", d.MachineName, "poweroff")
}
func (d *Driver) GetState() (state.State, error) {
stdout, stderr, err := d.vbmOutErr("showvminfo", d.MachineName,
"--machinereadable")

View File

@ -374,7 +374,6 @@ func (d *Driver) Create() error {
}
func (d *Driver) Start() error {
log.Infof("Starting %s...", d.MachineName)
vmrun("start", d.vmxPath(), "nogui")
// Do not execute the rest of boot2docker specific configuration, exit here
@ -406,13 +405,21 @@ func (d *Driver) Start() error {
}
func (d *Driver) Stop() error {
log.Infof("Gracefully shutting down %s...", d.MachineName)
vmrun("stop", d.vmxPath(), "nogui")
return nil
_, _, err := vmrun("stop", d.vmxPath(), "nogui")
return err
}
func (d *Driver) Restart() error {
_, _, err := vmrun("reset", d.vmxPath(), "nogui")
return err
}
func (d *Driver) Kill() error {
_, _, err := vmrun("stop", d.vmxPath(), "hard nogui")
return err
}
func (d *Driver) Remove() error {
s, _ := d.GetState()
if s == state.Running {
if err := d.Kill(); err != nil {
@ -424,18 +431,6 @@ func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
log.Infof("Gracefully restarting %s...", d.MachineName)
vmrun("reset", d.vmxPath(), "nogui")
return nil
}
func (d *Driver) Kill() error {
log.Infof("Forcibly halting %s...", d.MachineName)
vmrun("stop", d.vmxPath(), "hard nogui")
return nil
}
func (d *Driver) Upgrade() error {
return fmt.Errorf("VMware Fusion does not currently support the upgrade operation")
}

View File

@ -204,7 +204,6 @@ func (d *Driver) GetIP() (string, error) {
}
func (d *Driver) GetState() (state.State, error) {
p, err := govcloudair.NewClient()
if err != nil {
return state.Error, err
@ -238,11 +237,9 @@ func (d *Driver) GetState() (state.State, error) {
return state.Stopped, nil
}
return state.None, nil
}
func (d *Driver) Create() error {
key, err := d.createSSHKey()
if err != nil {
return err
@ -452,7 +449,6 @@ func (d *Driver) Remove() error {
}
func (d *Driver) Start() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
@ -496,7 +492,6 @@ func (d *Driver) Start() error {
}
func (d *Driver) Stop() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
@ -514,13 +509,6 @@ func (d *Driver) Stop() error {
return err
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
if status == "POWERED_ON" {
log.Infof("Shutting down %s...", d.MachineName)
task, err := vapp.Shutdown()
if err != nil {
return err
@ -529,8 +517,6 @@ func (d *Driver) Stop() error {
return err
}
}
if err = p.Disconnect(); err != nil {
return err
}
@ -541,7 +527,6 @@ func (d *Driver) Stop() error {
}
func (d *Driver) Restart() error {
p, err := govcloudair.NewClient()
if err != nil {
return err
@ -559,14 +544,6 @@ func (d *Driver) Restart() error {
return err
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
if status == "POWERED_ON" {
// If it's powered on, restart the machine
log.Infof("Restarting %s...", d.MachineName)
task, err := vapp.Reset()
if err != nil {
return err
@ -575,19 +552,6 @@ func (d *Driver) Restart() error {
return err
}
} else {
// If it's not powered on, start it.
log.Infof("Docker host %s is powered off, powering it back on...", d.MachineName)
task, err := vapp.PowerOn()
if err != nil {
return err
}
if err = task.WaitTaskCompletion(); err != nil {
return err
}
}
if err = p.Disconnect(); err != nil {
return err
}
@ -614,13 +578,6 @@ func (d *Driver) Kill() error {
return err
}
status, err := vapp.GetStatus()
if err != nil {
return err
}
if status == "POWERED_ON" {
log.Infof("Stopping %s...", d.MachineName)
task, err := vapp.PowerOff()
if err != nil {
return err
@ -629,8 +586,6 @@ func (d *Driver) Kill() error {
return err
}
}
if err = p.Disconnect(); err != nil {
return err
}

View File

@ -563,7 +563,7 @@ func (d *Driver) Start() error {
if err != nil {
return err
}
log.Infof("Powering on VM...")
task, err := vm.PowerOn(ctx)
if err != nil {
return err
@ -595,7 +595,7 @@ func (d *Driver) Stop() error {
if err != nil {
return err
}
log.Infof("Powering off VM...")
if err := vm.ShutdownGuest(ctx); err != nil {
return err
}
@ -605,6 +605,67 @@ func (d *Driver) Stop() error {
return nil
}
func (d *Driver) Restart() error {
if err := d.Stop(); err != nil {
return err
}
// Check for 120 seconds for the machine to stop
for i := 1; i <= 60; i++ {
machineState, err := d.GetState()
if err != nil {
return err
}
if machineState == state.Running {
log.Debugf("Not there yet %d/%d", i, 60)
time.Sleep(2 * time.Second)
continue
}
if machineState == state.Stopped {
break
}
}
machineState, err := d.GetState()
// If the VM is still running after 120 seconds just kill it.
if machineState == state.Running {
if err = d.Kill(); err != nil {
return fmt.Errorf("can't stop VM: %s", err)
}
}
return d.Start()
}
func (d *Driver) Kill() error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c, err := d.vsphereLogin(ctx)
if err != nil {
return err
}
vm, err := d.fetchVM(c, ctx, d.MachineName)
if err != nil {
return err
}
task, err := vm.PowerOff(ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(ctx, nil)
if err != nil {
return err
}
d.IPAddress = ""
return nil
}
func (d *Driver) Remove() error {
machineState, err := d.GetState()
if err != nil {
@ -670,66 +731,6 @@ func (d *Driver) Remove() error {
return nil
}
func (d *Driver) Restart() error {
if err := d.Stop(); err != nil {
return err
}
// Check for 120 seconds for the machine to stop
for i := 1; i <= 60; i++ {
machineState, err := d.GetState()
if err != nil {
return err
}
if machineState == state.Running {
log.Debugf("Not there yet %d/%d", i, 60)
time.Sleep(2 * time.Second)
continue
}
if machineState == state.Stopped {
break
}
}
machineState, err := d.GetState()
// If the VM is still running after 120 seconds just kill it.
if machineState == state.Running {
if err = d.Kill(); err != nil {
return fmt.Errorf("can't stop VM: %s", err)
}
}
return d.Start()
}
func (d *Driver) Kill() error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c, err := d.vsphereLogin(ctx)
if err != nil {
return err
}
vm, err := d.fetchVM(c, ctx, d.MachineName)
if err != nil {
return err
}
log.Infof("Powering off VM forcibly...")
task, err := vm.PowerOff(ctx)
if err != nil {
return err
}
_, err = task.WaitForResult(ctx, nil)
if err != nil {
return err
}
d.IPAddress = ""
return nil
}
func (d *Driver) Upgrade() error {
return fmt.Errorf("upgrade is not supported for vsphere driver at this moment")
}

View File

@ -89,6 +89,7 @@ func (h *Host) runActionForState(action func() error, desiredState state.State)
}
func (h *Host) Start() error {
log.Infof("Starting %q...", h.Name)
if err := h.runActionForState(h.Driver.Start, state.Running); err != nil {
return err
}
@ -98,6 +99,7 @@ func (h *Host) Start() error {
}
func (h *Host) Stop() error {
log.Infof("Stopping %q...", h.Name)
if err := h.runActionForState(h.Driver.Stop, state.Stopped); err != nil {
return err
}
@ -107,6 +109,7 @@ func (h *Host) Stop() error {
}
func (h *Host) Kill() error {
log.Infof("Killing %q...", h.Name)
if err := h.runActionForState(h.Driver.Kill, state.Stopped); err != nil {
return err
}
@ -116,15 +119,18 @@ func (h *Host) Kill() error {
}
func (h *Host) Restart() error {
log.Infof("Restarting %q...", h.Name)
if drivers.MachineInState(h.Driver, state.Stopped)() {
return h.Start()
}
if drivers.MachineInState(h.Driver, state.Running)() {
if err := h.Driver.Restart(); err != nil {
return err
}
return mcnutils.WaitFor(drivers.MachineInState(h.Driver, state.Running))
}
return nil
}