Have working minikube addons command w/ enable, disable, delete. Also
updated docs.pull/639/head
parent
d8e1f20751
commit
2d2b484a22
|
@ -26,7 +26,7 @@ _testmain.go
|
|||
/out
|
||||
/_gopath
|
||||
|
||||
/pkg/minikube/cluster/assets.go
|
||||
/pkg/minikube/assets/assets.go
|
||||
/minikube
|
||||
|
||||
.DS_Store
|
||||
|
|
16
Makefile
16
Makefile
|
@ -59,13 +59,13 @@ else
|
|||
docker run -w /go/src/$(REPOPATH) -e IN_DOCKER=1 -v $(shell pwd):/go/src/$(REPOPATH) $(BUILD_IMAGE) make out/localkube
|
||||
endif
|
||||
|
||||
out/minikube-darwin-amd64: $(GOPATH)/src/$(ORG) pkg/minikube/cluster/assets.go $(shell $(MINIKUBEFILES))
|
||||
out/minikube-darwin-amd64: $(GOPATH)/src/$(ORG) pkg/minikube/assets/assets.go $(shell $(MINIKUBEFILES))
|
||||
CGO_ENABLED=0 GOARCH=amd64 GOOS=darwin go build --installsuffix cgo -ldflags="$(MINIKUBE_LDFLAGS) $(K8S_VERSION_LDFLAGS)" -a -o $(BUILD_DIR)/minikube-darwin-amd64 ./cmd/minikube
|
||||
|
||||
out/minikube-linux-amd64: $(GOPATH)/src/$(ORG) pkg/minikube/cluster/assets.go $(shell $(MINIKUBEFILES))
|
||||
out/minikube-linux-amd64: $(GOPATH)/src/$(ORG) pkg/minikube/assets/assets.go $(shell $(MINIKUBEFILES))
|
||||
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build --installsuffix cgo -ldflags="$(MINIKUBE_LDFLAGS) $(K8S_VERSION_LDFLAGS)" -a -o $(BUILD_DIR)/minikube-linux-amd64 ./cmd/minikube
|
||||
|
||||
out/minikube-windows-amd64.exe: $(GOPATH)/src/$(ORG) pkg/minikube/cluster/assets.go $(shell $(MINIKUBEFILES))
|
||||
out/minikube-windows-amd64.exe: $(GOPATH)/src/$(ORG) pkg/minikube/assets/assets.go $(shell $(MINIKUBEFILES))
|
||||
CGO_ENABLED=0 GOARCH=amd64 GOOS=windows go build --installsuffix cgo -ldflags="$(MINIKUBE_LDFLAGS) $(K8S_VERSION_LDFLAGS)" -a -o $(BUILD_DIR)/minikube-windows-amd64.exe ./cmd/minikube
|
||||
|
||||
localkube-image: out/localkube
|
||||
|
@ -79,11 +79,11 @@ integration: out/minikube
|
|||
go test -v $(REPOPATH)/test/integration --tags=integration
|
||||
|
||||
.PHONY: test
|
||||
test: $(GOPATH)/src/$(ORG) pkg/minikube/cluster/assets.go
|
||||
test: $(GOPATH)/src/$(ORG) pkg/minikube/assets/assets.go
|
||||
./test.sh
|
||||
|
||||
pkg/minikube/cluster/assets.go: out/localkube $(GOPATH)/bin/go-bindata deploy/iso/addon-manager.yaml deploy/addons/dashboard-rc.yaml deploy/addons/dashboard-svc.yaml
|
||||
$(GOPATH)/bin/go-bindata -nomemcopy -o pkg/minikube/cluster/assets.go -pkg cluster ./out/localkube deploy/iso/addon-manager.yaml deploy/addons/dashboard-rc.yaml deploy/addons/dashboard-svc.yaml
|
||||
pkg/minikube/assets/assets.go: out/localkube $(GOPATH)/bin/go-bindata deploy/iso/addon-manager.yaml deploy/addons/dashboard-rc.yaml deploy/addons/dashboard-svc.yaml
|
||||
$(GOPATH)/bin/go-bindata -nomemcopy -o pkg/minikube/assets/assets.go -pkg assets ./out/localkube deploy/iso/addon-manager.yaml deploy/addons/dashboard-rc.yaml deploy/addons/dashboard-svc.yaml
|
||||
|
||||
$(GOPATH)/bin/go-bindata: $(GOPATH)/src/$(ORG)
|
||||
GOBIN=$(GOPATH)/bin go get github.com/jteeuwen/go-bindata/...
|
||||
|
@ -103,12 +103,12 @@ checksum:
|
|||
clean:
|
||||
rm -rf $(GOPATH)
|
||||
rm -rf $(BUILD_DIR)
|
||||
rm -f pkg/minikube/cluster/assets.go
|
||||
rm -f pkg/minikube/assets/assets.go
|
||||
|
||||
.PHONY: gendocs
|
||||
gendocs: docs/minikube.md
|
||||
|
||||
docs/minikube.md: $(GOPATH)/src/$(ORG) $(shell find cmd) $(shell find pkg/minikube/constants) pkg/minikube/cluster/assets.go
|
||||
docs/minikube.md: $(GOPATH)/src/$(ORG) $(shell find cmd) $(shell find pkg/minikube/constants) pkg/minikube/assets/assets.go
|
||||
cd $(GOPATH)/src/$(REPOPATH) && go run -ldflags="$(K8S_VERSION_LDFLAGS) $(MINIKUBE_LDFLAGS)" -tags gendocs gen_help_text.go
|
||||
|
||||
out/minikube_$(DEB_VERSION).deb: out/minikube-linux-amd64
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 config
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var AddonsCmd = &cobra.Command{
|
||||
Use: "addons SUBCOMMAND [flags]",
|
||||
Short: "Modify minikube's kubernetes addons",
|
||||
Long: `addons modifies minikube addons files using subcommands like "minikube addons enable heapster"`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
|
@ -34,11 +34,10 @@ type configFile interface {
|
|||
}
|
||||
|
||||
type setFn func(string, string) error
|
||||
type MinikubeConfig map[string]interface{}
|
||||
|
||||
type Setting struct {
|
||||
name string
|
||||
set func(MinikubeConfig, string, string) error
|
||||
set func(config.MinikubeConfig, string, string) error
|
||||
validations []setFn
|
||||
callbacks []setFn
|
||||
}
|
||||
|
@ -109,6 +108,18 @@ var settings = []Setting{
|
|||
name: config.WantReportErrorPrompt,
|
||||
set: SetBool,
|
||||
},
|
||||
{
|
||||
name: "dashboard",
|
||||
set: SetBool,
|
||||
validations: []setFn{IsValidAddon},
|
||||
callbacks: []setFn{EnableOrDisableAddon},
|
||||
},
|
||||
{
|
||||
name: "addon-manager",
|
||||
set: SetBool,
|
||||
validations: []setFn{IsValidAddon},
|
||||
callbacks: []setFn{EnableOrDisableAddon},
|
||||
},
|
||||
}
|
||||
|
||||
var ConfigCmd = &cobra.Command{
|
||||
|
@ -129,25 +140,8 @@ func configurableFields() string {
|
|||
return strings.Join(fields, "\n")
|
||||
}
|
||||
|
||||
// ReadConfig reads in the JSON minikube config
|
||||
func ReadConfig() (MinikubeConfig, error) {
|
||||
f, err := os.Open(constants.ConfigFile)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return make(map[string]interface{}), nil
|
||||
}
|
||||
return nil, fmt.Errorf("Could not open file %s: %s", constants.ConfigFile, err)
|
||||
}
|
||||
m, err := decode(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not decode config %s: %s", constants.ConfigFile, err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// WriteConfig writes a minikube config to the JSON file
|
||||
func WriteConfig(m MinikubeConfig) error {
|
||||
func WriteConfig(m config.MinikubeConfig) error {
|
||||
f, err := os.Create(constants.ConfigFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not open file %s: %s", constants.ConfigFile, err)
|
||||
|
@ -160,13 +154,7 @@ func WriteConfig(m MinikubeConfig) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func decode(r io.Reader) (MinikubeConfig, error) {
|
||||
var data MinikubeConfig
|
||||
err := json.NewDecoder(r).Decode(&data)
|
||||
return data, err
|
||||
}
|
||||
|
||||
func encode(w io.Writer, m MinikubeConfig) error {
|
||||
func encode(w io.Writer, m config.MinikubeConfig) error {
|
||||
b, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -18,7 +18,6 @@ package config
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -58,16 +57,6 @@ var configTestCases = []configTestCase{
|
|||
},
|
||||
}
|
||||
|
||||
func TestReadConfig(t *testing.T) {
|
||||
for _, tt := range configTestCases {
|
||||
r := bytes.NewBufferString(tt.data)
|
||||
config, err := decode(r)
|
||||
if reflect.DeepEqual(config, tt.config) || err != nil {
|
||||
t.Errorf("Did not read config correctly,\n\n wanted %+v, \n\n got %+v", tt.config, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteConfig(t *testing.T) {
|
||||
var b bytes.Buffer
|
||||
for _, tt := range configTestCases {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var addonsDisableCmd = &cobra.Command{
|
||||
Use: "disable ADDON_NAME",
|
||||
Short: "Disables the addon w/ADDON_NAME within minikube (example: minikube addons disable dashboard). For a list of available addons use: minikube addons list ",
|
||||
Long: "Disables the addon w/ADDON_NAME within minikube (example: minikube addons disable dashboard). For a list of available addons use: minikube addons list ",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintln(os.Stderr, "usage: minikube addons disable ADDON_NAME")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
addon := args[0]
|
||||
err := Set(addon, "false")
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stdout, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Fprintln(os.Stdout, fmt.Sprintf("%s was successfully disabled", addon))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
AddonsCmd.AddCommand(addonsDisableCmd)
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/sshutil"
|
||||
"k8s.io/minikube/pkg/minikube/tests"
|
||||
)
|
||||
|
||||
func TestDisableUnknownAddon(t *testing.T) {
|
||||
if err := Set("InvalidAddon", "false"); err == nil {
|
||||
t.Fatalf("Disable did not return error for unknown addon")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisableValidAddonNoVM(t *testing.T) {
|
||||
tempDir := tests.MakeTempDir()
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
addonName := "dashboard"
|
||||
expected := "false"
|
||||
if err := Set(addonName, expected); err != nil {
|
||||
//check that setting was changed in temp dir
|
||||
conf, _ := ioutil.ReadFile(filepath.Join(tempDir, "config", "config.json"))
|
||||
strConf := string(conf)
|
||||
if !strings.Contains(strConf, addonName) {
|
||||
t.Fatalf("Expected %s, in %s after running disable", addonName, strConf)
|
||||
}
|
||||
if !strings.Contains(strConf, expected) {
|
||||
t.Fatalf("Expected %s, in %s after running disable", expected, strConf)
|
||||
}
|
||||
//check that nothing was transferred?
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Fatalf("Disable returned error for known addon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteAddonViaDriver(t *testing.T) {
|
||||
s, _ := tests.NewSSHServer()
|
||||
port, err := s.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("Error starting ssh server: %s", err)
|
||||
}
|
||||
|
||||
d := &tests.MockDriver{
|
||||
Port: port,
|
||||
BaseDriver: drivers.BaseDriver{
|
||||
IPAddress: "127.0.0.1",
|
||||
SSHKeyPath: "",
|
||||
},
|
||||
}
|
||||
|
||||
dashboard := assets.Addons["dashboard"]
|
||||
if err := deleteAddonViaDriver(dashboard, d); err != nil {
|
||||
t.Fatalf("Unexpected error %s deleting addon", err)
|
||||
}
|
||||
// check command(s) were run
|
||||
for _, addon := range dashboard.Assets {
|
||||
expected, _ := ioutil.ReadFile(addon.GetAssetName())
|
||||
if _, ok := s.Commands[sshutil.GetDeleteFileCommand(addon)]; !ok {
|
||||
t.Fatalf("Error: Expected delete addon ssh command to be run: %s.", expected)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var addonsEnableCmd = &cobra.Command{
|
||||
Use: "enable ADDON_NAME",
|
||||
Short: "Enables the addon w/ADDON_NAME within minikube (example: minikube addons enable dashboard). For a list of available addons use: minikube addons list ",
|
||||
Long: "Enables the addon w/ADDON_NAME within minikube (example: minikube addons enable dashboard). For a list of available addons use: minikube addons list ",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 1 {
|
||||
fmt.Fprintln(os.Stderr, "usage: minikube addons enable ADDON_NAME")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
addon := args[0]
|
||||
err := Set(addon, "true")
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stdout, err)
|
||||
}
|
||||
fmt.Fprintln(os.Stdout, fmt.Sprintf("%s was successfully enabled", addon))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
AddonsCmd.AddCommand(addonsEnableCmd)
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/tests"
|
||||
)
|
||||
|
||||
func TestEnableUnknownAddon(t *testing.T) {
|
||||
if err := Set("InvalidAddon", "false"); err == nil {
|
||||
t.Fatalf("Enable did not return error for unknown addon")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnableValidAddonNoVM(t *testing.T) {
|
||||
tempDir := tests.MakeTempDir()
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
addonName := "dashboard"
|
||||
expected := "true"
|
||||
if err := Set(addonName, expected); err != nil {
|
||||
//check that setting was changed in temp dir
|
||||
conf, _ := ioutil.ReadFile(filepath.Join(tempDir, "config", "config.json"))
|
||||
strConf := string(conf)
|
||||
if !strings.Contains(strConf, addonName) {
|
||||
t.Fatalf("Expected %s, in %s after running enable", addonName, strConf)
|
||||
}
|
||||
if !strings.Contains(strConf, expected) {
|
||||
t.Fatalf("Expected %s, in %s after running enable", expected, strConf)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Fatalf("Enable returned error for known addon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransferAddonViaDriver(t *testing.T) {
|
||||
s, _ := tests.NewSSHServer()
|
||||
port, err := s.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("Error starting ssh server: %s", err)
|
||||
}
|
||||
|
||||
d := &tests.MockDriver{
|
||||
Port: port,
|
||||
BaseDriver: drivers.BaseDriver{
|
||||
IPAddress: "127.0.0.1",
|
||||
SSHKeyPath: "",
|
||||
},
|
||||
}
|
||||
|
||||
dashboard := assets.Addons["dashboard"]
|
||||
if err := transferAddonViaDriver(dashboard, d); err != nil {
|
||||
t.Fatalf("Unexpected error %s transferring addon", err)
|
||||
}
|
||||
// check contents
|
||||
for _, addon := range dashboard.Assets {
|
||||
expected, _ := ioutil.ReadFile(addon.GetAssetName())
|
||||
transferred := s.Transfers.Bytes()
|
||||
//test that custom addons are transferred properly
|
||||
if !bytes.Contains(transferred, expected) {
|
||||
t.Fatalf("Expected transfers to contain addon with content: %s. It was: %s", expected, transferred)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -33,7 +35,7 @@ var configGetCmd = &cobra.Command{
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
val, err := get(args[0])
|
||||
val, err := config.Get(args[0])
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stdout, err)
|
||||
}
|
||||
|
@ -46,11 +48,3 @@ var configGetCmd = &cobra.Command{
|
|||
func init() {
|
||||
ConfigCmd.AddCommand(configGetCmd)
|
||||
}
|
||||
|
||||
func get(name string) (string, error) {
|
||||
m, err := ReadConfig()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%v", m[name]), nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
)
|
||||
|
||||
var listFormat string
|
||||
|
||||
type ListTemplate struct {
|
||||
AddonName string
|
||||
AddonStatus string
|
||||
}
|
||||
|
||||
var addonsListCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "Lists all available minikube addons as well as there current status (enabled/disabled)",
|
||||
Long: "Lists all available minikube addons as well as there current status (enabled/disabled)",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 0 {
|
||||
fmt.Fprintln(os.Stderr, "usage: minikube addons list")
|
||||
os.Exit(1)
|
||||
}
|
||||
err := list()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
AddonsCmd.Flags().StringVar(&listFormat, "format", constants.DefaultListFormat,
|
||||
`Go template format string for the addon list output. The format for Go templates can be found here: https://golang.org/pkg/text/template/
|
||||
For the list of accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd/addon#ListTemplate`)
|
||||
AddonsCmd.AddCommand(addonsListCmd)
|
||||
}
|
||||
|
||||
func stringFromStatus(addonStatus bool) string {
|
||||
if addonStatus {
|
||||
return "enabled"
|
||||
}
|
||||
return "disabled"
|
||||
}
|
||||
|
||||
func list() error {
|
||||
for addonName, addonBundle := range assets.Addons {
|
||||
addonStatus, err := addonBundle.IsEnabled()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl, err := template.New("list").Parse(listFormat)
|
||||
if err != nil {
|
||||
glog.Errorln("Error creating list template:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
listTmplt := ListTemplate{addonName, stringFromStatus(addonStatus)}
|
||||
err = tmpl.Execute(os.Stdout, listTmplt)
|
||||
if err != nil {
|
||||
glog.Errorln("Error executing list template:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -20,6 +20,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
pkgConfig "k8s.io/minikube/pkg/minikube/config"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -57,7 +59,7 @@ func Set(name string, value string) error {
|
|||
}
|
||||
|
||||
// Set the value
|
||||
config, err := ReadConfig()
|
||||
config, err := pkgConfig.ReadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
pkgConfig "k8s.io/minikube/pkg/minikube/config"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -44,7 +46,7 @@ func init() {
|
|||
}
|
||||
|
||||
func unset(name string) error {
|
||||
m, err := ReadConfig()
|
||||
m, err := pkgConfig.ReadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -19,6 +19,15 @@ package config
|
|||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/machine/libmachine"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/cluster"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/minikube/sshutil"
|
||||
)
|
||||
|
||||
// Runs all the validation or callback functions and collects errors
|
||||
|
@ -47,12 +56,12 @@ func findSetting(name string) (Setting, error) {
|
|||
|
||||
// Set Functions
|
||||
|
||||
func SetString(m MinikubeConfig, name string, val string) error {
|
||||
func SetString(m config.MinikubeConfig, name string, val string) error {
|
||||
m[name] = val
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetInt(m MinikubeConfig, name string, val string) error {
|
||||
func SetInt(m config.MinikubeConfig, name string, val string) error {
|
||||
i, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -61,7 +70,7 @@ func SetInt(m MinikubeConfig, name string, val string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func SetBool(m MinikubeConfig, name string, val string) error {
|
||||
func SetBool(m config.MinikubeConfig, name string, val string) error {
|
||||
b, err := strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -69,3 +78,51 @@ func SetBool(m MinikubeConfig, name string, val string) error {
|
|||
m[name] = b
|
||||
return nil
|
||||
}
|
||||
|
||||
func EnableOrDisableAddon(name string, val string) error {
|
||||
enable, err := strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
errors.Wrapf(err, "error attempted to parse enabled/disable value addon %s", name)
|
||||
}
|
||||
api := libmachine.NewClient(constants.Minipath, constants.MakeMiniPath("certs"))
|
||||
defer api.Close()
|
||||
cluster.EnsureMinikubeRunningOrExit(api, 0)
|
||||
|
||||
addon, _ := assets.Addons[name] // validation done prior
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
host, err := cluster.CheckIfApiExistsAndLoad(api)
|
||||
if enable {
|
||||
if err = transferAddonViaDriver(addon, host.Driver); err != nil {
|
||||
return errors.Wrapf(err, "Error transferring addon %s to VM", name)
|
||||
}
|
||||
} else {
|
||||
if err = deleteAddonViaDriver(addon, host.Driver); err != nil {
|
||||
return errors.Wrapf(err, "Error deleteing addon %s from VM", name)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteAddonViaDriver(addon *assets.Addon, d drivers.Driver) error {
|
||||
client, err := sshutil.NewSSHClient(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := sshutil.DeleteAddon(addon, client); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func transferAddonViaDriver(addon *assets.Addon, d drivers.Driver) error {
|
||||
client, err := sshutil.NewSSHClient(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := sshutil.TransferAddon(addon, client); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -16,9 +16,13 @@ limitations under the License.
|
|||
|
||||
package config
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
var minikubeConfig = MinikubeConfig{
|
||||
pkgConfig "k8s.io/minikube/pkg/minikube/config"
|
||||
)
|
||||
|
||||
var minikubeConfig = pkgConfig.MinikubeConfig{
|
||||
"vm-driver": "kvm",
|
||||
"cpus": 12,
|
||||
"show-libmachine-logs": true,
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"strconv"
|
||||
|
||||
units "github.com/docker/go-units"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
)
|
||||
|
||||
|
@ -74,3 +76,10 @@ func IsValidPath(name string, path string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsValidAddon(name string, val string) error {
|
||||
if _, ok := assets.Addons[name]; ok {
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("Cannot enable/disable invalid addon %s", name)
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ var dashboardCmd = &cobra.Command{
|
|||
api := libmachine.NewClient(constants.Minipath, constants.MakeMiniPath("certs"))
|
||||
defer api.Close()
|
||||
|
||||
cluster.EnsureMinikubeRunningOrExit(api)
|
||||
cluster.EnsureMinikubeRunningOrExit(api, 1)
|
||||
namespace := "kube-system"
|
||||
service := "kubernetes-dashboard"
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ func setFlagsUsingViper() {
|
|||
func init() {
|
||||
RootCmd.PersistentFlags().Bool(showLibmachineLogs, false, "Whether or not to show logs from libmachine.")
|
||||
RootCmd.AddCommand(configCmd.ConfigCmd)
|
||||
RootCmd.AddCommand(configCmd.AddonsCmd)
|
||||
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
|
||||
viper.BindPFlags(RootCmd.PersistentFlags())
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
|
|
@ -55,7 +55,7 @@ var serviceCmd = &cobra.Command{
|
|||
api := libmachine.NewClient(constants.Minipath, constants.MakeMiniPath("certs"))
|
||||
defer api.Close()
|
||||
|
||||
cluster.EnsureMinikubeRunningOrExit(api)
|
||||
cluster.EnsureMinikubeRunningOrExit(api, 1)
|
||||
if err := util.RetryAfter(20, func() error { return CheckService(namespace, service) }, 6*time.Second); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Could not find finalized endpoint being pointed to by %s: %s", service, err)
|
||||
cmdUtil.MaybeReportErrorAndExit(err)
|
||||
|
|
|
@ -75,6 +75,6 @@ var statusCmd = &cobra.Command{
|
|||
func init() {
|
||||
statusCmd.Flags().StringVar(&statusFormat, "format", constants.DefaultStatusFormat,
|
||||
`Go template format string for the status output. The format for Go templates can be found here: https://golang.org/pkg/text/template/
|
||||
For the list accessible variables for the template, see the struct values here:https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status`)
|
||||
For the list accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status`)
|
||||
RootCmd.AddCommand(statusCmd)
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ Minikube is a CLI tool that provisions and manages single-node Kubernetes cluste
|
|||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [minikube addons](minikube_addons.md) - Modify minikube's kubernetes addons
|
||||
* [minikube config](minikube_config.md) - Modify minikube config
|
||||
* [minikube dashboard](minikube_dashboard.md) - Opens/displays the kubernetes dashboard URL for your local cluster
|
||||
* [minikube delete](minikube_delete.md) - Deletes a local kubernetes cluster.
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
## minikube addons
|
||||
|
||||
Modify minikube's kubernetes addons
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
addons modifies minikube addons files using subcommands like "minikube addons enable heapster"
|
||||
|
||||
```
|
||||
minikube addons SUBCOMMAND [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--format string Go template format string for the addon list output. The format for Go templates can be found here: https://golang.org/pkg/text/template/
|
||||
For the list of accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd/addon#ListTemplate (default "- {{.AddonName}}: {{.AddonStatus}}\n")
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--alsologtostderr log to standard error as well as files
|
||||
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
|
||||
--log_dir string If non-empty, write log files in this directory
|
||||
--logtostderr log to standard error instead of files
|
||||
--show-libmachine-logs Whether or not to show logs from libmachine.
|
||||
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
|
||||
-v, --v Level log level for V logs
|
||||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [minikube](minikube.md) - Minikube is a tool for managing local Kubernetes clusters.
|
||||
* [minikube addons disable](minikube_addons_disable.md) - Disables the addon w/ADDON_NAME within minikube (example: minikube addons disable dashboard). For a list of available addons use: minikube addons list
|
||||
* [minikube addons enable](minikube_addons_enable.md) - Enables the addon w/ADDON_NAME within minikube (example: minikube addons enable dashboard). For a list of available addons use: minikube addons list
|
||||
* [minikube addons list](minikube_addons_list.md) - Lists all available minikube addons as well as there current status (enabled/disabled)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
## minikube addons disable
|
||||
|
||||
Disables the addon w/ADDON_NAME within minikube (example: minikube addons disable dashboard). For a list of available addons use: minikube addons list
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Disables the addon w/ADDON_NAME within minikube (example: minikube addons disable dashboard). For a list of available addons use: minikube addons list
|
||||
|
||||
```
|
||||
minikube addons disable ADDON_NAME
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--alsologtostderr log to standard error as well as files
|
||||
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
|
||||
--log_dir string If non-empty, write log files in this directory
|
||||
--logtostderr log to standard error instead of files
|
||||
--show-libmachine-logs Whether or not to show logs from libmachine.
|
||||
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
|
||||
-v, --v Level log level for V logs
|
||||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [minikube addons](minikube_addons.md) - Modify minikube's kubernetes addons
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
## minikube addons enable
|
||||
|
||||
Enables the addon w/ADDON_NAME within minikube (example: minikube addons enable dashboard). For a list of available addons use: minikube addons list
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Enables the addon w/ADDON_NAME within minikube (example: minikube addons enable dashboard). For a list of available addons use: minikube addons list
|
||||
|
||||
```
|
||||
minikube addons enable ADDON_NAME
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--alsologtostderr log to standard error as well as files
|
||||
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
|
||||
--log_dir string If non-empty, write log files in this directory
|
||||
--logtostderr log to standard error instead of files
|
||||
--show-libmachine-logs Whether or not to show logs from libmachine.
|
||||
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
|
||||
-v, --v Level log level for V logs
|
||||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [minikube addons](minikube_addons.md) - Modify minikube's kubernetes addons
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
## minikube addons list
|
||||
|
||||
Lists all available minikube addons as well as there current status (enabled/disabled)
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Lists all available minikube addons as well as there current status (enabled/disabled)
|
||||
|
||||
```
|
||||
minikube addons list
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--alsologtostderr log to standard error as well as files
|
||||
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
|
||||
--log_dir string If non-empty, write log files in this directory
|
||||
--logtostderr log to standard error instead of files
|
||||
--show-libmachine-logs Whether or not to show logs from libmachine.
|
||||
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
|
||||
-v, --v Level log level for V logs
|
||||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [minikube addons](minikube_addons.md) - Modify minikube's kubernetes addons
|
||||
|
|
@ -21,6 +21,8 @@ Configurable fields:
|
|||
* ReminderWaitPeriodInHours
|
||||
* WantReportError
|
||||
* WantReportErrorPrompt
|
||||
* dashboard
|
||||
* addon-manager
|
||||
|
||||
```
|
||||
minikube config SUBCOMMAND [flags]
|
||||
|
|
|
@ -15,7 +15,7 @@ minikube status
|
|||
|
||||
```
|
||||
--format string Go template format string for the status output. The format for Go templates can be found here: https://golang.org/pkg/text/template/
|
||||
For the list accessible variables for the template, see the struct values here:https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status (default "minikubeVM: {{.MinikubeStatus}}\nlocalkube: {{.LocalkubeStatus}}\n")
|
||||
For the list accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status (default "minikubeVM: {{.MinikubeStatus}}\nlocalkube: {{.LocalkubeStatus}}\n")
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 assets
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
type Addon struct {
|
||||
Assets []*MemoryAsset
|
||||
enabled bool
|
||||
addonName string
|
||||
}
|
||||
|
||||
func NewAddon(assets []*MemoryAsset, enabled bool, addonName string) *Addon {
|
||||
a := &Addon{
|
||||
Assets: assets,
|
||||
enabled: enabled,
|
||||
addonName: addonName,
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Addon) IsEnabled() (bool, error) {
|
||||
addonStatusText, err := config.Get(a.addonName)
|
||||
if err == nil {
|
||||
addonStatus, err := strconv.ParseBool(addonStatusText)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return addonStatus, nil
|
||||
}
|
||||
return a.enabled, nil
|
||||
}
|
||||
|
||||
var Addons = map[string]*Addon{
|
||||
"addon-manager": NewAddon([]*MemoryAsset{
|
||||
NewMemoryAsset(
|
||||
"deploy/iso/addon-manager.yaml",
|
||||
"/etc/kubernetes/manifests/",
|
||||
"addon-manager.yaml",
|
||||
"0640"),
|
||||
}, true, "addon-manager"),
|
||||
"dashboard": NewAddon([]*MemoryAsset{
|
||||
NewMemoryAsset(
|
||||
"deploy/addons/dashboard-rc.yaml",
|
||||
constants.AddonsPath,
|
||||
"dashboard-rc.yaml",
|
||||
"0640"),
|
||||
NewMemoryAsset(
|
||||
"deploy/addons/dashboard-svc.yaml",
|
||||
constants.AddonsPath,
|
||||
"dashboard-svc.yaml",
|
||||
"0640"),
|
||||
}, true, "dashboard"),
|
||||
}
|
||||
|
||||
func AddMinikubeAddonsDirToAssets(assetList *[]CopyableFile) {
|
||||
// loop over .minikube/addons and add them to assets
|
||||
searchDir := constants.MakeMiniPath("addons")
|
||||
err := filepath.Walk(searchDir, func(addonFile string, f os.FileInfo, err error) error {
|
||||
isDir, err := util.IsDirectory(addonFile)
|
||||
if err == nil && !isDir {
|
||||
f, err := NewFileAsset(addonFile, constants.AddonsPath, filepath.Base(addonFile), "0640")
|
||||
if err == nil {
|
||||
*assetList = append(*assetList, f)
|
||||
}
|
||||
} else if err != nil {
|
||||
glog.Infoln("Error encountered while walking .minikube/addons: ", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
glog.Infoln("Error encountered while walking .minikube/addons: ", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 assets
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type CopyableFile interface {
|
||||
io.Reader
|
||||
GetLength() int
|
||||
GetAssetName() string
|
||||
GetTargetDir() string
|
||||
GetTargetName() string
|
||||
GetPermissions() string
|
||||
}
|
||||
|
||||
type BaseAsset struct {
|
||||
data []byte
|
||||
reader io.Reader
|
||||
Length int
|
||||
AssetName string
|
||||
TargetDir string
|
||||
TargetName string
|
||||
Permissions string
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetAssetName() string {
|
||||
return b.AssetName
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetTargetDir() string {
|
||||
return b.TargetDir
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetTargetName() string {
|
||||
return b.TargetName
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetPermissions() string {
|
||||
return b.Permissions
|
||||
}
|
||||
|
||||
type FileAsset struct {
|
||||
BaseAsset
|
||||
}
|
||||
|
||||
func NewFileAsset(assetName, targetDir, targetName, permissions string) (*FileAsset, error) {
|
||||
f := &FileAsset{
|
||||
BaseAsset{
|
||||
AssetName: assetName,
|
||||
TargetDir: targetDir,
|
||||
TargetName: targetName,
|
||||
Permissions: permissions,
|
||||
},
|
||||
}
|
||||
file, err := os.Open(f.AssetName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error opening file asset: %s", f.AssetName)
|
||||
}
|
||||
f.reader = file
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (f *FileAsset) GetLength() int {
|
||||
file, err := os.Open(f.AssetName)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
fi, err := file.Stat()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int(fi.Size())
|
||||
}
|
||||
|
||||
func (f *FileAsset) Read(p []byte) (int, error) {
|
||||
if f.reader == nil {
|
||||
return 0, errors.New("Error attempting FileAsset.Read, FileAsset.reader uninitialized")
|
||||
}
|
||||
return f.reader.Read(p)
|
||||
}
|
||||
|
||||
type MemoryAsset struct {
|
||||
BaseAsset
|
||||
}
|
||||
|
||||
func NewMemoryAsset(assetName, targetDir, targetName, permissions string) *MemoryAsset {
|
||||
m := &MemoryAsset{
|
||||
BaseAsset{
|
||||
AssetName: assetName,
|
||||
TargetDir: targetDir,
|
||||
TargetName: targetName,
|
||||
Permissions: permissions,
|
||||
},
|
||||
}
|
||||
m.loadData()
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *MemoryAsset) loadData() error {
|
||||
contents, err := Asset(m.AssetName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.data = contents
|
||||
m.Length = len(contents)
|
||||
m.reader = bytes.NewReader(m.data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MemoryAsset) GetLength() int {
|
||||
return m.Length
|
||||
}
|
||||
|
||||
func (m *MemoryAsset) Read(p []byte) (int, error) {
|
||||
return m.reader.Read(p)
|
||||
}
|
|
@ -23,7 +23,6 @@ import (
|
|||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
|
@ -44,6 +43,7 @@ import (
|
|||
kubeApi "k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/minikube/sshutil"
|
||||
"k8s.io/minikube/pkg/util"
|
||||
|
@ -151,7 +151,7 @@ func GetHostStatus(api libmachine.API) (string, error) {
|
|||
|
||||
// GetLocalkubeStatus gets the status of localkube from the host VM.
|
||||
func GetLocalkubeStatus(api libmachine.API) (string, error) {
|
||||
host, err := checkIfApiExistsAndLoad(api)
|
||||
host, err := CheckIfApiExistsAndLoad(api)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -215,136 +215,6 @@ func StartCluster(h sshAble, kubernetesConfig KubernetesConfig) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type CopyableFile interface {
|
||||
io.Reader
|
||||
GetLength() int
|
||||
GetAssetName() string
|
||||
GetTargetDir() string
|
||||
GetTargetName() string
|
||||
GetPermissions() string
|
||||
}
|
||||
|
||||
type BaseAsset struct {
|
||||
data []byte
|
||||
reader io.Reader
|
||||
Length int
|
||||
AssetName string
|
||||
TargetDir string
|
||||
TargetName string
|
||||
Permissions string
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetAssetName() string {
|
||||
return b.AssetName
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetTargetDir() string {
|
||||
return b.TargetDir
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetTargetName() string {
|
||||
return b.TargetName
|
||||
}
|
||||
|
||||
func (b *BaseAsset) GetPermissions() string {
|
||||
return b.Permissions
|
||||
}
|
||||
|
||||
type FileAsset struct {
|
||||
BaseAsset
|
||||
}
|
||||
|
||||
func NewFileAsset(assetName, targetDir, targetName, permissions string) (*FileAsset, error) {
|
||||
f := &FileAsset{
|
||||
BaseAsset{
|
||||
AssetName: assetName,
|
||||
TargetDir: targetDir,
|
||||
TargetName: targetName,
|
||||
Permissions: permissions,
|
||||
},
|
||||
}
|
||||
file, err := os.Open(f.AssetName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error opening file asset: %s", f.AssetName)
|
||||
}
|
||||
f.reader = file
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (f *FileAsset) GetLength() int {
|
||||
file, err := os.Open(f.AssetName)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
fi, err := file.Stat()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int(fi.Size())
|
||||
}
|
||||
|
||||
func (f *FileAsset) Read(p []byte) (int, error) {
|
||||
if f.reader == nil {
|
||||
return 0, errors.New("Error attempting FileAsset.Read, FileAsset.reader uninitialized")
|
||||
}
|
||||
return f.reader.Read(p)
|
||||
}
|
||||
|
||||
type MemoryAsset struct {
|
||||
BaseAsset
|
||||
}
|
||||
|
||||
func NewMemoryAsset(assetName, targetDir, targetName, permissions string) *MemoryAsset {
|
||||
m := &MemoryAsset{
|
||||
BaseAsset{
|
||||
AssetName: assetName,
|
||||
TargetDir: targetDir,
|
||||
TargetName: targetName,
|
||||
Permissions: permissions,
|
||||
},
|
||||
}
|
||||
m.loadData()
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *MemoryAsset) loadData() error {
|
||||
contents, err := Asset(m.AssetName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.data = contents
|
||||
m.Length = len(contents)
|
||||
m.reader = bytes.NewReader(m.data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MemoryAsset) GetLength() int {
|
||||
return m.Length
|
||||
}
|
||||
|
||||
func (m *MemoryAsset) Read(p []byte) (int, error) {
|
||||
return m.reader.Read(p)
|
||||
}
|
||||
|
||||
var memoryAssets = []CopyableFile{
|
||||
NewMemoryAsset(
|
||||
"deploy/iso/addon-manager.yaml",
|
||||
"/etc/kubernetes/manifests/",
|
||||
"addon-manager.yaml",
|
||||
"0640"),
|
||||
NewMemoryAsset(
|
||||
"deploy/addons/dashboard-rc.yaml",
|
||||
"/etc/kubernetes/addons/",
|
||||
"dashboard-rc.yaml",
|
||||
"0640"),
|
||||
NewMemoryAsset(
|
||||
"deploy/addons/dashboard-svc.yaml",
|
||||
"/etc/kubernetes/addons/",
|
||||
"dashboard-svc.yaml",
|
||||
"0640"),
|
||||
}
|
||||
|
||||
func UpdateCluster(h sshAble, d drivers.Driver, config KubernetesConfig) error {
|
||||
client, err := sshutil.NewSSHClient(d)
|
||||
if err != nil {
|
||||
|
@ -362,17 +232,23 @@ func UpdateCluster(h sshAble, d drivers.Driver, config KubernetesConfig) error {
|
|||
return errors.Wrap(err, "Error updating localkube from asset")
|
||||
}
|
||||
}
|
||||
fileAssets := []CopyableFile{}
|
||||
addMinikubeAddonsDirToAssets(&fileAssets)
|
||||
fileAssets := []assets.CopyableFile{}
|
||||
assets.AddMinikubeAddonsDirToAssets(&fileAssets)
|
||||
// merge files to copy
|
||||
var copyableFiles []CopyableFile
|
||||
copyableFiles = append(copyableFiles, memoryAssets...)
|
||||
var copyableFiles []assets.CopyableFile
|
||||
for _, addonBundle := range assets.Addons {
|
||||
if isEnabled, err := addonBundle.IsEnabled(); err == nil && isEnabled {
|
||||
for _, addon := range addonBundle.Assets {
|
||||
copyableFiles = append(copyableFiles, addon)
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
copyableFiles = append(copyableFiles, fileAssets...)
|
||||
// transfer files to vm
|
||||
for _, copyableFile := range copyableFiles {
|
||||
if err := sshutil.Transfer(copyableFile, copyableFile.GetLength(),
|
||||
copyableFile.GetTargetDir(), copyableFile.GetTargetName(),
|
||||
copyableFile.GetPermissions(), client); err != nil {
|
||||
if err := sshutil.TransferFile(copyableFile, client); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -588,7 +464,7 @@ func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
|
|||
|
||||
// GetHostDockerEnv gets the necessary docker env variables to allow the use of docker through minikube's vm
|
||||
func GetHostDockerEnv(api libmachine.API) (map[string]string, error) {
|
||||
host, err := checkIfApiExistsAndLoad(api)
|
||||
host, err := CheckIfApiExistsAndLoad(api)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error checking that api exists and loading it")
|
||||
}
|
||||
|
@ -611,7 +487,7 @@ func GetHostDockerEnv(api libmachine.API) (map[string]string, error) {
|
|||
|
||||
// GetHostLogs gets the localkube logs of the host VM.
|
||||
func GetHostLogs(api libmachine.API) (string, error) {
|
||||
host, err := checkIfApiExistsAndLoad(api)
|
||||
host, err := CheckIfApiExistsAndLoad(api)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Error checking that api exists and loading it")
|
||||
}
|
||||
|
@ -622,7 +498,7 @@ func GetHostLogs(api libmachine.API) (string, error) {
|
|||
return s, nil
|
||||
}
|
||||
|
||||
func checkIfApiExistsAndLoad(api libmachine.API) (*host.Host, error) {
|
||||
func CheckIfApiExistsAndLoad(api libmachine.API) (*host.Host, error) {
|
||||
exists, err := api.Exists(constants.MachineName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error checking that api exists for: ", constants.MachineName)
|
||||
|
@ -639,7 +515,7 @@ func checkIfApiExistsAndLoad(api libmachine.API) (*host.Host, error) {
|
|||
}
|
||||
|
||||
func CreateSSHShell(api libmachine.API, args []string) error {
|
||||
host, err := checkIfApiExistsAndLoad(api)
|
||||
host, err := CheckIfApiExistsAndLoad(api)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error checking if api exist and loading it")
|
||||
}
|
||||
|
@ -661,7 +537,7 @@ func CreateSSHShell(api libmachine.API, args []string) error {
|
|||
}
|
||||
|
||||
func GetServiceURL(api libmachine.API, namespace, service string) (string, error) {
|
||||
host, err := checkIfApiExistsAndLoad(api)
|
||||
host, err := CheckIfApiExistsAndLoad(api)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Error checking if api exist and loading it")
|
||||
}
|
||||
|
@ -745,7 +621,7 @@ func GetKubernetesEndpointsWithNamespace(namespace string) (endpointGetter, erro
|
|||
|
||||
// EnsureMinikubeRunningOrExit checks that minikube has a status available and that
|
||||
// that the status is `Running`, otherwise it will exit
|
||||
func EnsureMinikubeRunningOrExit(api libmachine.API) {
|
||||
func EnsureMinikubeRunningOrExit(api libmachine.API, exitStatus int) {
|
||||
s, err := GetHostStatus(api)
|
||||
if err != nil {
|
||||
glog.Errorln("Error getting machine status:", err)
|
||||
|
@ -753,26 +629,6 @@ func EnsureMinikubeRunningOrExit(api libmachine.API) {
|
|||
}
|
||||
if s != state.Running.String() {
|
||||
fmt.Fprintln(os.Stdout, "minikube is not currently running so the service cannot be accessed")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func addMinikubeAddonsDirToAssets(assetList *[]CopyableFile) {
|
||||
// loop over .minikube/addons and add them to assets
|
||||
searchDir := constants.MakeMiniPath("addons")
|
||||
err := filepath.Walk(searchDir, func(addonFile string, f os.FileInfo, err error) error {
|
||||
isDir, err := util.IsDirectory(addonFile)
|
||||
if err == nil && !isDir {
|
||||
f, err := NewFileAsset(addonFile, "/etc/kubernetes/addons", filepath.Base(addonFile), "0640")
|
||||
if err == nil {
|
||||
*assetList = append(*assetList, f)
|
||||
}
|
||||
} else if err != nil {
|
||||
glog.Infoln("Error encountered while walking .minikube/addons: ", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
glog.Infoln("Error encountered while walking .minikube/addons: ", err)
|
||||
os.Exit(exitStatus)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/minikube/tests"
|
||||
)
|
||||
|
@ -568,16 +569,21 @@ func TestUpdateDefault(t *testing.T) {
|
|||
}
|
||||
transferred := s.Transfers.Bytes()
|
||||
|
||||
//test that kube-add memoryAssets are transferred properly
|
||||
for _, a := range memoryAssets {
|
||||
contents, _ := Asset(a.GetAssetName())
|
||||
if !bytes.Contains(transferred, contents) {
|
||||
t.Fatalf("File not copied. Expected transfers to contain: %s. It was: %s", contents, transferred)
|
||||
for _, addonBundle := range assets.Addons {
|
||||
if isEnabled, err := addonBundle.IsEnabled(); err == nil && isEnabled {
|
||||
for _, addon := range addonBundle.Assets {
|
||||
contents, _ := assets.Asset(addon.GetAssetName())
|
||||
if !bytes.Contains(transferred, contents) {
|
||||
t.Fatalf("File not copied. Expected transfers to contain: %s. It was: %s", contents, transferred)
|
||||
}
|
||||
}
|
||||
} else if err != nil {
|
||||
t.Fatalf("File not copied. Unexpected error while attempting to check transferred addons: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
//test that localkube is transferred properly
|
||||
contents, _ := Asset("out/localkube")
|
||||
contents, _ := assets.Asset("out/localkube")
|
||||
if !bytes.Contains(transferred, contents) {
|
||||
t.Fatalf("File not copied. Expected transfers to contain: %s. It was: %s", contents, transferred)
|
||||
}
|
||||
|
|
|
@ -28,13 +28,14 @@ import (
|
|||
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/minikube/sshutil"
|
||||
"k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
func updateLocalkubeFromAsset(client *ssh.Client) error {
|
||||
contents, err := Asset("out/localkube")
|
||||
contents, err := assets.Asset("out/localkube")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error loading asset out/localkube")
|
||||
}
|
||||
|
|
|
@ -16,9 +16,68 @@ limitations under the License.
|
|||
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
)
|
||||
|
||||
const (
|
||||
WantUpdateNotification = "WantUpdateNotification"
|
||||
ReminderWaitPeriodInHours = "ReminderWaitPeriodInHours"
|
||||
WantReportError = "WantReportError"
|
||||
WantReportErrorPrompt = "WantReportErrorPrompt"
|
||||
)
|
||||
|
||||
type configFile interface {
|
||||
io.ReadWriter
|
||||
}
|
||||
|
||||
type setFn func(string, string) error
|
||||
type MinikubeConfig map[string]interface{}
|
||||
|
||||
type Setting struct {
|
||||
name string
|
||||
set func(MinikubeConfig, string, string) error
|
||||
validations []setFn
|
||||
callbacks []setFn
|
||||
}
|
||||
|
||||
func Get(name string) (string, error) {
|
||||
m, err := ReadConfig()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if val, ok := m[name]; ok {
|
||||
return fmt.Sprintf("%v", val), nil
|
||||
} else {
|
||||
return "", errors.New("specified key could not be found in config")
|
||||
}
|
||||
}
|
||||
|
||||
// ReadConfig reads in the JSON minikube config
|
||||
func ReadConfig() (MinikubeConfig, error) {
|
||||
f, err := os.Open(constants.ConfigFile)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return make(map[string]interface{}), nil
|
||||
}
|
||||
return nil, fmt.Errorf("Could not open file %s: %s", constants.ConfigFile, err)
|
||||
}
|
||||
m, err := decode(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not decode config %s: %s", constants.ConfigFile, err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func decode(r io.Reader) (MinikubeConfig, error) {
|
||||
var data MinikubeConfig
|
||||
err := json.NewDecoder(r).Decode(&data)
|
||||
return data, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type configTestCase struct {
|
||||
data string
|
||||
config map[string]interface{}
|
||||
}
|
||||
|
||||
var configTestCases = []configTestCase{
|
||||
{
|
||||
data: `{
|
||||
"memory": 2
|
||||
}`,
|
||||
config: map[string]interface{}{
|
||||
"memory": 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
data: `{
|
||||
"ReminderWaitPeriodInHours": 99,
|
||||
"cpus": 4,
|
||||
"disk-size": "20g",
|
||||
"log_dir": "/etc/hosts",
|
||||
"show-libmachine-logs": true,
|
||||
"v": 5,
|
||||
"vm-driver": "kvm"
|
||||
}`,
|
||||
config: map[string]interface{}{
|
||||
"vm-driver": "kvm",
|
||||
"cpus": 4,
|
||||
"disk-size": "20g",
|
||||
"v": 5,
|
||||
"show-libmachine-logs": true,
|
||||
"log_dir": "/etc/hosts",
|
||||
"ReminderWaitPeriodInHours": 99,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestReadConfig(t *testing.T) {
|
||||
for _, tt := range configTestCases {
|
||||
r := bytes.NewBufferString(tt.data)
|
||||
config, err := decode(r)
|
||||
if reflect.DeepEqual(config, tt.config) || err != nil {
|
||||
t.Errorf("Did not read config correctly,\n\n wanted %+v, \n\n got %+v", tt.config, config)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@ const (
|
|||
DefaultVMDriver = "virtualbox"
|
||||
DefaultStatusFormat = "minikubeVM: {{.MinikubeStatus}}\n" +
|
||||
"localkube: {{.LocalkubeStatus}}\n"
|
||||
DefaultListFormat = "- {{.AddonName}}: {{.AddonStatus}}\n"
|
||||
GithubMinikubeReleasesURL = "https://storage.googleapis.com/minikube/releases.json"
|
||||
KubernetesVersionGCSURL = "https://storage.googleapis.com/minikube/k8s_releases.json"
|
||||
)
|
||||
|
@ -87,3 +88,5 @@ var LocalkubeLinuxFilename = "localkube-linux-amd64"
|
|||
const DockerAPIVersion = "1.23"
|
||||
|
||||
const ReportingURL = "https://clouderrorreporting.googleapis.com/v1beta1/projects/k8s-minikube/events:report?key=AIzaSyACUwzG0dEPcl-eOgpDKnyKoUFgHdfoFuA"
|
||||
|
||||
const AddonsPath = "/etc/kubernetes/addons"
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
machinessh "github.com/docker/machine/libmachine/ssh"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"k8s.io/minikube/pkg/minikube/assets"
|
||||
)
|
||||
|
||||
// SSHSession provides methods for running commands on a host.
|
||||
|
@ -61,6 +62,42 @@ func NewSSHClient(d drivers.Driver) (*ssh.Client, error) {
|
|||
return client, nil
|
||||
}
|
||||
|
||||
func DeleteAddon(a *assets.Addon, client *ssh.Client) error {
|
||||
var err error
|
||||
if enabled, err := a.IsEnabled(); err != nil {
|
||||
return errors.Wrapf(err, "error attempting to transfer addon")
|
||||
} else if enabled {
|
||||
return errors.Errorf("Error, attempted to removed enabled addon")
|
||||
}
|
||||
for _, f := range a.Assets {
|
||||
if err := DeleteFile(f, client); err != nil {
|
||||
err = errors.Wrap(err, "")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func TransferAddon(a *assets.Addon, client *ssh.Client) error {
|
||||
var err error
|
||||
if enabled, err := a.IsEnabled(); err != nil {
|
||||
return errors.Wrapf(err, "error attempting to transfer addon")
|
||||
} else if !enabled {
|
||||
return errors.Errorf("Error, attempted to transfer disabled addon")
|
||||
}
|
||||
for _, f := range a.Assets {
|
||||
if err := TransferFile(f, client); err != nil {
|
||||
errors.Wrap(err, "")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func TransferFile(f assets.CopyableFile, client *ssh.Client) error {
|
||||
return Transfer(f, f.GetLength(),
|
||||
f.GetTargetDir(), f.GetTargetName(),
|
||||
f.GetPermissions(), client)
|
||||
}
|
||||
|
||||
// Transfer uses an SSH session to copy a file to the remote machine.
|
||||
func Transfer(reader io.Reader, readerLen int, remotedir, filename string, perm string, c *ssh.Client) error {
|
||||
// Delete the old file first. This makes sure permissions get reset.
|
||||
|
@ -137,3 +174,11 @@ func newSSHHost(d drivers.Driver) (*sshHost, error) {
|
|||
Username: d.GetSSHUsername(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func DeleteFile(f assets.CopyableFile, client *ssh.Client) error {
|
||||
return RunCommand(client, GetDeleteFileCommand(f))
|
||||
}
|
||||
|
||||
func GetDeleteFileCommand(f assets.CopyableFile) string {
|
||||
return fmt.Sprintf("sudo rm %s", filepath.Join(f.GetTargetDir(), f.GetTargetName()))
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ type SSHServer struct {
|
|||
Connected bool
|
||||
Transfers *bytes.Buffer
|
||||
HadASessionRequested bool
|
||||
CommandToOutput map[string]string
|
||||
// CommandsToOutput can be used to mock what the SSHServer returns for a given command
|
||||
CommandToOutput map[string]string
|
||||
}
|
||||
|
||||
// NewSSHServer returns a NewSSHServer instance, ready for use.
|
||||
|
|
Loading…
Reference in New Issue