Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions cli/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"encoding/json"
"fmt"
"log"
"strings"
"time"

"github.com/docker/machine/drivers/virtualbox"
Expand Down Expand Up @@ -63,6 +64,40 @@ func StopHost(api libmachine.API) error {
return nil
}

type multiError struct {
Errors []error
}

func (m *multiError) Collect(err error) {
if err != nil {
m.Errors = append(m.Errors, err)
}
}

func (m multiError) ToError() error {
if len(m.Errors) == 0 {
return nil
}

errStrings := []string{}
for _, err := range m.Errors {
errStrings = append(errStrings, err.Error())
}
return fmt.Errorf(strings.Join(errStrings, "\n"))
}

// DeleteHost deletes the host VM.
func DeleteHost(api libmachine.API) error {
host, err := api.Load(constants.MachineName)
if err != nil {
return err
}
m := multiError{}
m.Collect(host.Driver.Remove())
m.Collect(api.Remove(constants.MachineName))
return m.ToError()
}

type sshAble interface {
RunSSHCommand(string) (string, error)
}
Expand Down
76 changes: 76 additions & 0 deletions cli/cluster/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cluster

import (
"fmt"
"strings"
"testing"

"github.com/docker/machine/libmachine/host"
Expand Down Expand Up @@ -156,4 +157,79 @@ func TestStopHost(t *testing.T) {
if s, _ := h.Driver.GetState(); s != state.Stopped {
t.Fatalf("Machine not stopped. Currently in state: %s", s)
}

}

func TestMultiError(t *testing.T) {
m := multiError{}

m.Collect(fmt.Errorf("Error 1"))
m.Collect(fmt.Errorf("Error 2"))

err := m.ToError()
expected := `Error 1
Error 2`
if err.Error() != expected {
t.Fatalf("%s != %s", err, expected)
}

m = multiError{}
if err := m.ToError(); err != nil {
t.Fatalf("Unexpected error: %s", err)
}
}

func TestDeleteHost(t *testing.T) {
api := &tests.MockAPI{}
createHost(api)

if err := DeleteHost(api); err != nil {
t.Fatalf("Unexpected error deleting host: %s", err)
}
}

func TestDeleteHostErrorDeletingVM(t *testing.T) {
api := &tests.MockAPI{}
h, _ := createHost(api)

d := &tests.MockDriver{RemoveError: true}

h.Driver = d

if err := DeleteHost(api); err == nil {
t.Fatal("Expected error deleting host.")
}
}

func TestDeleteHostErrorDeletingFiles(t *testing.T) {
api := &tests.MockAPI{RemoveError: true}
createHost(api)

if err := DeleteHost(api); err == nil {
t.Fatal("Expected error deleting host.")
}
}

func TestDeleteHostMultipleErrors(t *testing.T) {
api := &tests.MockAPI{
RemoveError: true,
}
h, _ := createHost(api)

d := &tests.MockDriver{RemoveError: true}

h.Driver = d

err := DeleteHost(api)

if err == nil {
t.Fatal("Expected error deleting host, didn't get one.")
}

expectedErrors := []string{"Error removing minikubeVM", "Error deleting machine"}
for _, expectedError := range expectedErrors {
if !strings.Contains(err.Error(), expectedError) {
t.Fatalf("Error %s expected to contain: %s. ", err)
}
}
}
48 changes: 48 additions & 0 deletions cli/cmd/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright © 2016 NAME HERE <EMAIL ADDRESS>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"fmt"
"os"

"github.com/docker/machine/libmachine"
"github.com/kubernetes/minikube/cli/cluster"
"github.com/kubernetes/minikube/cli/constants"
"github.com/spf13/cobra"
)

// deleteCmd represents the delete command
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Deletes a local kubernetes cluster.",
Long: `Deletes a local kubernetes cluster. This command deletes the VM, and removes all
associated files.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Deleting local Kubernetes cluster...")
api := libmachine.NewClient(constants.Minipath, constants.MakeMiniPath("certs"))
defer api.Close()

if err := cluster.DeleteHost(api); err != nil {
fmt.Println("Errors occurred deleting machine: ", err)
os.Exit(1)
}
fmt.Println("Machine deleted.")
},
}

func init() {
RootCmd.AddCommand(deleteCmd)
}
23 changes: 4 additions & 19 deletions cli/cmd/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,16 @@ import (
// stopCmd represents the stop command
var stopCmd = &cobra.Command{
Use: "stop",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Short: "Stops a running local kubernetes cluster.",
Long: `Stops a local kubernetes cluster running in Virtualbox. This command stops the VM
itself, leaving all files intact. The cluster can be started again with the "start" command.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Stopping local Kubernetes cluster...")
api := libmachine.NewClient(constants.Minipath, constants.MakeMiniPath("certs"))
defer api.Close()

if err := cluster.StopHost(api); err != nil {
fmt.Println("Error stopping machine: %s", err)
fmt.Println("Error stopping machine: ", err)
os.Exit(1)
}
fmt.Println("Machine stopped.")
Expand All @@ -48,15 +44,4 @@ to quickly create a Cobra application.`,

func init() {
RootCmd.AddCommand(stopCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// stopCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// stopCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}
5 changes: 5 additions & 0 deletions cli/tests/api_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
type MockAPI struct {
Hosts []*host.Host
CreateError bool
RemoveError bool
}

// Close closes the API.
Expand Down Expand Up @@ -77,6 +78,10 @@ func (api *MockAPI) Load(name string) (*host.Host, error) {

// Remove a host.
func (api *MockAPI) Remove(name string) error {
if api.RemoveError {
return fmt.Errorf("Error removing %s", name)
}

newHosts := []*host.Host{}

for _, host := range api.Hosts {
Expand Down
6 changes: 6 additions & 0 deletions cli/tests/driver_mock.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package tests

import (
"fmt"

"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/state"
Expand All @@ -10,6 +12,7 @@ import (
type MockDriver struct {
drivers.BaseDriver
CurrentState state.State
RemoveError bool
}

// Create creates a MockDriver instance
Expand Down Expand Up @@ -46,6 +49,9 @@ func (driver *MockDriver) Kill() error {

// Remove removes the machine
func (driver *MockDriver) Remove() error {
if driver.RemoveError {
return fmt.Errorf("Error deleting machine.")
}
return nil
}

Expand Down