mirror of https://github.com/docker/docs.git
Display driver in error without crashing
Signed-off-by: Jean-Laurent de Morlhon <jeanlaurent@morlhon.net>
This commit is contained in:
parent
d7d6ca205a
commit
f9f886f529
|
|
@ -18,12 +18,12 @@ func cmdActive(c CommandLine, api libmachine.API) error {
|
||||||
return errTooManyArguments
|
return errTooManyArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
hosts, err := persist.LoadAllHosts(api)
|
hosts, hostsInError, err := persist.LoadAllHosts(api)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting active host: %s", err)
|
return fmt.Errorf("Error getting active host: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
items := getHostListItems(hosts)
|
items := getHostListItems(hosts, hostsInError)
|
||||||
|
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
if item.Active {
|
if item.Active {
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,14 @@ func (c *contextCommandLine) Application() *cli.App {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runAction(actionName string, c CommandLine, api libmachine.API) error {
|
func runAction(actionName string, c CommandLine, api libmachine.API) error {
|
||||||
hosts, err := persist.LoadHosts(api, c.Args())
|
hosts, hostsInError := persist.LoadHosts(api, c.Args())
|
||||||
if err != nil {
|
|
||||||
return err
|
if len(hostsInError) > 0 {
|
||||||
|
errs := []error{}
|
||||||
|
for _, err := range hostsInError {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
return consolidateErrs(errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(hosts) == 0 {
|
if len(hosts) == 0 {
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func cmdLs(c CommandLine, api libmachine.API) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hostList, err := persist.LoadAllHosts(api)
|
hostList, hostInError, err := persist.LoadAllHosts(api)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ func cmdLs(c CommandLine, api libmachine.API) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items := getHostListItems(hostList)
|
items := getHostListItems(hostList, hostInError)
|
||||||
|
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
activeString := "-"
|
activeString := "-"
|
||||||
|
|
@ -283,7 +283,7 @@ func getHostState(h *host.Host, hostListItemsChan chan<- HostListItem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHostListItems(hostList []*host.Host) []HostListItem {
|
func getHostListItems(hostList []*host.Host, hostsInError map[string]error) []HostListItem {
|
||||||
hostListItems := []HostListItem{}
|
hostListItems := []HostListItem{}
|
||||||
hostListItemsChan := make(chan HostListItem)
|
hostListItemsChan := make(chan HostListItem)
|
||||||
|
|
||||||
|
|
@ -297,6 +297,15 @@ func getHostListItems(hostList []*host.Host) []HostListItem {
|
||||||
|
|
||||||
close(hostListItemsChan)
|
close(hostListItemsChan)
|
||||||
|
|
||||||
|
for name, err := range hostsInError {
|
||||||
|
itemInError := HostListItem{}
|
||||||
|
itemInError.Name = name
|
||||||
|
itemInError.DriverName = "not found"
|
||||||
|
itemInError.State = state.Error
|
||||||
|
itemInError.Error = err.Error()
|
||||||
|
hostListItems = append(hostListItems, itemInError)
|
||||||
|
}
|
||||||
|
|
||||||
sortHostListItemsByName(hostListItems)
|
sortHostListItemsByName(hostListItems)
|
||||||
return hostListItems
|
return hostListItems
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"errors"
|
||||||
"github.com/docker/machine/drivers/fakedriver"
|
"github.com/docker/machine/drivers/fakedriver"
|
||||||
"github.com/docker/machine/libmachine/host"
|
"github.com/docker/machine/libmachine/host"
|
||||||
"github.com/docker/machine/libmachine/state"
|
"github.com/docker/machine/libmachine/state"
|
||||||
|
|
@ -323,7 +324,7 @@ func TestGetHostListItems(t *testing.T) {
|
||||||
{"foo", state.Running, true, ""},
|
{"foo", state.Running, true, ""},
|
||||||
}
|
}
|
||||||
|
|
||||||
items := getHostListItems(hosts)
|
items := getHostListItems(hosts, map[string]error{})
|
||||||
|
|
||||||
for i := range expected {
|
for i := range expected {
|
||||||
assert.Equal(t, expected[i].name, items[i].Name)
|
assert.Equal(t, expected[i].name, items[i].Name)
|
||||||
|
|
@ -398,7 +399,7 @@ func TestGetHostListItemsEnvDockerHostUnset(t *testing.T) {
|
||||||
"baz": {state.Saved, false},
|
"baz": {state.Saved, false},
|
||||||
}
|
}
|
||||||
|
|
||||||
items := getHostListItems(hosts)
|
items := getHostListItems(hosts, map[string]error{})
|
||||||
|
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
expected := expected[item.Name]
|
expected := expected[item.Name]
|
||||||
|
|
@ -446,7 +447,7 @@ func TestGetHostStateTimeout(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
stateTimeoutDuration = 1 * time.Second
|
stateTimeoutDuration = 1 * time.Second
|
||||||
hostItems := getHostListItems(hosts)
|
hostItems := getHostListItems(hosts, map[string]error{})
|
||||||
hostItem := hostItems[0]
|
hostItem := hostItems[0]
|
||||||
|
|
||||||
assert.Equal(t, "foo", hostItem.Name)
|
assert.Equal(t, "foo", hostItem.Name)
|
||||||
|
|
@ -466,7 +467,7 @@ func TestGetHostStateError(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
hostItems := getHostListItems(hosts)
|
hostItems := getHostListItems(hosts, map[string]error{})
|
||||||
hostItem := hostItems[0]
|
hostItem := hostItems[0]
|
||||||
|
|
||||||
assert.Equal(t, "foo", hostItem.Name)
|
assert.Equal(t, "foo", hostItem.Name)
|
||||||
|
|
@ -476,3 +477,34 @@ func TestGetHostStateError(t *testing.T) {
|
||||||
assert.Equal(t, "Unable to get ip", hostItem.Error)
|
assert.Equal(t, "Unable to get ip", hostItem.Error)
|
||||||
assert.Nil(t, hostItem.SwarmOptions)
|
assert.Nil(t, hostItem.SwarmOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetSomeHostInEror(t *testing.T) {
|
||||||
|
hosts := []*host.Host{
|
||||||
|
{
|
||||||
|
Name: "foo",
|
||||||
|
Driver: &fakedriver.Driver{
|
||||||
|
MockState: state.Running,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
hostsInError := map[string]error{
|
||||||
|
"bar": errors.New("invalid memory address or nil pointer dereference"),
|
||||||
|
}
|
||||||
|
|
||||||
|
hostItems := getHostListItems(hosts, hostsInError)
|
||||||
|
assert.Equal(t, 2, len(hostItems))
|
||||||
|
|
||||||
|
hostItem := hostItems[0]
|
||||||
|
|
||||||
|
assert.Equal(t, "bar", hostItem.Name)
|
||||||
|
assert.Equal(t, state.Error, hostItem.State)
|
||||||
|
assert.Equal(t, "not found", hostItem.DriverName)
|
||||||
|
assert.Empty(t, hostItem.URL)
|
||||||
|
assert.Equal(t, "invalid memory address or nil pointer dereference", hostItem.Error)
|
||||||
|
assert.Nil(t, hostItem.SwarmOptions)
|
||||||
|
|
||||||
|
hostItem = hostItems[1]
|
||||||
|
|
||||||
|
assert.Equal(t, "foo", hostItem.Name)
|
||||||
|
assert.Equal(t, state.Running, hostItem.State)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package persist
|
package persist
|
||||||
|
|
||||||
import "github.com/docker/machine/libmachine/host"
|
import (
|
||||||
|
"github.com/docker/machine/libmachine/host"
|
||||||
|
)
|
||||||
|
|
||||||
type Store interface {
|
type Store interface {
|
||||||
// Exists returns whether a machine exists or not
|
// Exists returns whether a machine exists or not
|
||||||
|
|
@ -19,27 +21,27 @@ type Store interface {
|
||||||
Save(host *host.Host) error
|
Save(host *host.Host) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadHosts(s Store, hostNames []string) ([]*host.Host, error) {
|
func LoadHosts(s Store, hostNames []string) ([]*host.Host, map[string]error) {
|
||||||
loadedHosts := []*host.Host{}
|
loadedHosts := []*host.Host{}
|
||||||
|
errors := map[string]error{}
|
||||||
|
|
||||||
for _, hostName := range hostNames {
|
for _, hostName := range hostNames {
|
||||||
h, err := s.Load(hostName)
|
h, err := s.Load(hostName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: (nathanleclaire) Should these be bundled up
|
errors[hostName] = err
|
||||||
// into one error instead of exiting?
|
} else {
|
||||||
return nil, err
|
loadedHosts = append(loadedHosts, h)
|
||||||
}
|
}
|
||||||
loadedHosts = append(loadedHosts, h)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadedHosts, nil
|
return loadedHosts, errors
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadAllHosts(s Store) ([]*host.Host, error) {
|
func LoadAllHosts(s Store) ([]*host.Host, map[string]error, error) {
|
||||||
hostNames, err := s.List()
|
hostNames, err := s.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
loadedHosts, hostInError := LoadHosts(s, hostNames)
|
||||||
return LoadHosts(s, hostNames)
|
return loadedHosts, hostInError, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue