Merge branch 'master' of github.com:kubernetes/minikube into localization-poc
commit
03ebb0e0f5
|
@ -5,6 +5,8 @@ sudo: required
|
|||
go:
|
||||
- 1.x
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install -y libvirt-dev
|
||||
install:
|
||||
- echo "Don't run anything."
|
||||
script:
|
||||
|
|
20
Makefile
20
Makefile
|
@ -219,9 +219,25 @@ fmt:
|
|||
vet:
|
||||
@go vet $(SOURCE_PACKAGES)
|
||||
|
||||
# Once v1.16.1+ is released, replace with
|
||||
# curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh \
|
||||
# | bash -s -- -b out/linters v1.16.0
|
||||
|
||||
out/linters/golangci-lint:
|
||||
mkdir -p out/linters \
|
||||
&& cd out/linters \
|
||||
&& test -f go.mod || go mod init linters \
|
||||
&& go get -u github.com/golangci/golangci-lint/cmd/golangci-lint@692dacb773b703162c091c2d8c59f9cd2d6801db >/dev/null
|
||||
cp -f $(GOPATH)/bin/golangci-lint out/linters/golangci-lint
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
@golint -set_exit_status $(SOURCE_PACKAGES)
|
||||
lint: pkg/minikube/assets/assets.go out/linters/golangci-lint
|
||||
./out/linters/golangci-lint run \
|
||||
--deadline 4m \
|
||||
--build-tags "${MINIKUBE_INTEGRATION_BUILD_TAGS}" \
|
||||
--enable goimports,gocritic,golint,gocyclo,interfacer,misspell,nakedret,stylecheck,unconvert,unparam \
|
||||
--exclude 'variable on range scope.*in function literal|ifElseChain' \
|
||||
./...
|
||||
|
||||
.PHONY: reportcard
|
||||
reportcard:
|
||||
|
|
|
@ -56,16 +56,16 @@ For the list of accessible variables for the template, see the struct values her
|
|||
cacheCmd.AddCommand(listCacheCmd)
|
||||
}
|
||||
|
||||
// cacheList returns a formatted list of images found within the local cache
|
||||
func cacheList(images []string) error {
|
||||
for _, image := range images {
|
||||
tmpl, err := template.New("list").Parse(cacheListFormat)
|
||||
if err != nil {
|
||||
exit.WithError("Unable to parse template", err)
|
||||
return err
|
||||
}
|
||||
listTmplt := CacheListTemplate{image}
|
||||
err = tmpl.Execute(os.Stdout, listTmplt)
|
||||
if err != nil {
|
||||
exit.WithError("Unable to process template", err)
|
||||
if err := tmpl.Execute(os.Stdout, listTmplt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package config
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -26,6 +27,8 @@ var AddonsCmd = &cobra.Command{
|
|||
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()
|
||||
if err := cmd.Help(); err != nil {
|
||||
glog.Errorf("help: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
|
@ -261,7 +262,9 @@ var ConfigCmd = &cobra.Command{
|
|||
Long: `config modifies minikube config files using subcommands like "minikube config set vm-driver kvm"
|
||||
Configurable fields: ` + "\n\n" + configurableFields(),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
if err := cmd.Help(); err != nil {
|
||||
glog.Errorf("help: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -344,12 +347,12 @@ func DeleteFromConfigMap(name string, images []string) 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)
|
||||
return fmt.Errorf("create %s: %s", constants.ConfigFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
err = encode(f, m)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error encoding config %s: %s", constants.ConfigFile, err)
|
||||
return fmt.Errorf("encode %s: %s", constants.ConfigFile, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -95,9 +95,9 @@ You can add one by annotating a service with the label %s:%s`, key, addonName)
|
|||
}
|
||||
for i := range serviceList.Items {
|
||||
svc := serviceList.Items[i].ObjectMeta.Name
|
||||
service.WaitAndMaybeOpenService(api, namespace, svc, addonsURLTemplate,
|
||||
addonsURLMode, https, wait, interval)
|
||||
|
||||
if err := service.WaitAndMaybeOpenService(api, namespace, svc, addonsURLTemplate, addonsURLMode, https, wait, interval); err != nil {
|
||||
exit.WithCode(exit.Unavailable, "Wait failed: %v", err)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"k8s.io/minikube/pkg/minikube/console"
|
||||
)
|
||||
|
@ -42,15 +43,13 @@ func AskForYesNoConfirmation(s string, posResponses, negResponses []string) bool
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
response = strings.ToLower(strings.TrimSpace(response))
|
||||
|
||||
if containsString(posResponses, response) {
|
||||
switch r := strings.ToLower(strings.TrimSpace(response)); {
|
||||
case containsString(posResponses, r):
|
||||
return true
|
||||
} else if containsString(negResponses, response) {
|
||||
case containsString(negResponses, r):
|
||||
return false
|
||||
} else {
|
||||
default:
|
||||
console.Err("Please type yes or no:")
|
||||
return AskForYesNoConfirmation(s, posResponses, negResponses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +111,7 @@ func concealableAskForStaticValue(readWriter io.ReadWriter, promptString string,
|
|||
response = strings.TrimSpace(response)
|
||||
if len(response) == 0 {
|
||||
console.Warning("Please enter a value:")
|
||||
return concealableAskForStaticValue(readWriter, promptString, hidden)
|
||||
continue
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
@ -126,7 +125,11 @@ func AskForPasswordValue(s string) string {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer terminal.Restore(stdInFd, oldState)
|
||||
defer func() {
|
||||
if err := terminal.Restore(stdInFd, oldState); err != nil {
|
||||
glog.Errorf("terminal restore failed: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
result, err := concealableAskForStaticValue(os.Stdin, s, true)
|
||||
if err != nil {
|
||||
|
|
|
@ -54,7 +54,7 @@ func findSetting(name string) (Setting, error) {
|
|||
return s, nil
|
||||
}
|
||||
}
|
||||
return Setting{}, fmt.Errorf("Property name %s not found", name)
|
||||
return Setting{}, fmt.Errorf("property name %q not found", name)
|
||||
}
|
||||
|
||||
// Set Functions
|
||||
|
|
|
@ -33,6 +33,16 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/cruntime"
|
||||
)
|
||||
|
||||
// containerdOnlyMsg is the message shown when a containerd-only addon is enabled
|
||||
const containerdOnlyAddonMsg = `
|
||||
This addon can only be enabled with the containerd runtime backend. To enable this backend, please first stop minikube with:
|
||||
|
||||
minikube stop
|
||||
|
||||
and then start minikube again with the following flags:
|
||||
|
||||
minikube start --container-runtime=containerd --docker-opt containerd=/var/run/containerd/containerd.sock`
|
||||
|
||||
// IsValidDriver checks if a driver is supported
|
||||
func IsValidDriver(string, driver string) error {
|
||||
for _, d := range constants.SupportedVMDrivers {
|
||||
|
@ -40,7 +50,7 @@ func IsValidDriver(string, driver string) error {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("Driver %s is not supported", driver)
|
||||
return fmt.Errorf("driver %q is not supported", driver)
|
||||
}
|
||||
|
||||
// RequiresRestartMsg returns the "requires restart" message
|
||||
|
@ -53,7 +63,7 @@ func RequiresRestartMsg(string, string) error {
|
|||
func IsValidDiskSize(name string, disksize string) error {
|
||||
_, err := units.FromHumanSize(disksize)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Not valid disk size: %v", err)
|
||||
return fmt.Errorf("invalid disk size: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -117,7 +127,7 @@ func IsPositive(name string, val string) error {
|
|||
func IsValidCIDR(name string, cidr string) error {
|
||||
_, _, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error parsing CIDR: %v", err)
|
||||
return fmt.Errorf("invalid CIDR: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -151,16 +161,7 @@ func IsContainerdRuntime(_, _ string) error {
|
|||
}
|
||||
_, ok := r.(*cruntime.Containerd)
|
||||
if !ok {
|
||||
return fmt.Errorf(`This addon can only be enabled with the containerd runtime backend.
|
||||
|
||||
To enable this backend, please first stop minikube with:
|
||||
|
||||
minikube stop
|
||||
|
||||
and then start minikube again with the following flags:
|
||||
|
||||
minikube start --container-runtime=containerd --docker-opt containerd=/var/run/containerd/containerd.sock`)
|
||||
return fmt.Errorf(containerdOnlyAddonMsg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -377,7 +377,9 @@ var dockerEnvCmd = &cobra.Command{
|
|||
}
|
||||
}
|
||||
|
||||
executeTemplateStdout(shellCfg)
|
||||
if err := executeTemplateStdout(shellCfg); err != nil {
|
||||
exit.WithError("Error executing template", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,9 @@ var RootCmd = &cobra.Command{
|
|||
|
||||
logDir := pflag.Lookup("log_dir")
|
||||
if !logDir.Changed {
|
||||
logDir.Value.Set(constants.MakeMiniPath("logs"))
|
||||
if err := logDir.Value.Set(constants.MakeMiniPath("logs")); err != nil {
|
||||
exit.WithError("logdir set failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
if enableUpdateNotification {
|
||||
|
@ -116,7 +118,9 @@ func setFlagsUsingViper() {
|
|||
}
|
||||
// Viper will give precedence first to calls to the Set command,
|
||||
// then to values from the config.yml
|
||||
a.Value.Set(viper.GetString(a.Name))
|
||||
if err := a.Value.Set(viper.GetString(a.Name)); err != nil {
|
||||
exit.WithError(fmt.Sprintf("failed to set value for %q", a.Name), err)
|
||||
}
|
||||
a.Changed = true
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +133,9 @@ func init() {
|
|||
RootCmd.AddCommand(configCmd.AddonsCmd)
|
||||
RootCmd.AddCommand(configCmd.ProfileCmd)
|
||||
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
|
||||
viper.BindPFlags(RootCmd.PersistentFlags())
|
||||
if err := viper.BindPFlags(RootCmd.PersistentFlags()); err != nil {
|
||||
exit.WithError("Unable to bind flags", err)
|
||||
}
|
||||
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
|
@ -176,7 +182,7 @@ func GetClusterBootstrapper(api libmachine.API, bootstrapperName string) (bootst
|
|||
return nil, errors.Wrap(err, "getting kubeadm bootstrapper")
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown bootstrapper: %s", bootstrapperName)
|
||||
return nil, fmt.Errorf("unknown bootstrapper: %s", bootstrapperName)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -145,37 +146,43 @@ func getEnvVarName(name string) string {
|
|||
return constants.MinikubeEnvPrefix + "_" + strings.ToUpper(name)
|
||||
}
|
||||
|
||||
func setValues(t *testing.T, tt configTest) {
|
||||
func setValues(tt configTest) error {
|
||||
if tt.FlagValue != "" {
|
||||
pflag.Set(tt.Name, tt.FlagValue)
|
||||
if err := pflag.Set(tt.Name, tt.FlagValue); err != nil {
|
||||
return errors.Wrap(err, "flag set")
|
||||
}
|
||||
}
|
||||
if tt.EnvValue != "" {
|
||||
s := strings.Replace(getEnvVarName(tt.Name), "-", "_", -1)
|
||||
os.Setenv(s, tt.EnvValue)
|
||||
}
|
||||
if tt.ConfigValue != "" {
|
||||
err := initTestConfig(tt.ConfigValue)
|
||||
if err != nil {
|
||||
t.Fatalf("Config %s not read correctly: %v", tt.ConfigValue, err)
|
||||
if err := initTestConfig(tt.ConfigValue); err != nil {
|
||||
return errors.Wrapf(err, "Config %s not read correctly", tt.ConfigValue)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func unsetValues(tt configTest) {
|
||||
var f = pflag.Lookup(tt.Name)
|
||||
f.Value.Set(f.DefValue)
|
||||
func unsetValues(name string) error {
|
||||
f := pflag.Lookup(name)
|
||||
if err := f.Value.Set(f.DefValue); err != nil {
|
||||
return errors.Wrapf(err, "set(%s)", f.DefValue)
|
||||
}
|
||||
f.Changed = false
|
||||
|
||||
os.Unsetenv(getEnvVarName(tt.Name))
|
||||
|
||||
os.Unsetenv(getEnvVarName(name))
|
||||
viper.Reset()
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestViperAndFlags(t *testing.T) {
|
||||
restore := hideEnv(t)
|
||||
defer restore(t)
|
||||
for _, tt := range configTests {
|
||||
setValues(t, tt)
|
||||
err := setValues(tt)
|
||||
if err != nil {
|
||||
t.Fatalf("setValues: %v", err)
|
||||
}
|
||||
setupViper()
|
||||
f := pflag.Lookup(tt.Name)
|
||||
if f == nil {
|
||||
|
@ -185,6 +192,9 @@ func TestViperAndFlags(t *testing.T) {
|
|||
if actual != tt.ExpectedValue {
|
||||
t.Errorf("pflag.Value(%s) => %s, wanted %s [%+v]", tt.Name, actual, tt.ExpectedValue, tt)
|
||||
}
|
||||
unsetValues(tt)
|
||||
// Some flag validation may not accept their default value, such as log_at_backtrace :(
|
||||
if err := unsetValues(tt.Name); err != nil {
|
||||
t.Logf("unsetValues(%s) failed: %v", tt.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/api/core/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
"k8s.io/minikube/pkg/minikube/console"
|
||||
"k8s.io/minikube/pkg/minikube/exit"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
|
@ -69,6 +69,6 @@ var serviceListCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
func init() {
|
||||
serviceListCmd.Flags().StringVarP(&serviceListNamespace, "namespace", "n", v1.NamespaceAll, "The services namespace")
|
||||
serviceListCmd.Flags().StringVarP(&serviceListNamespace, "namespace", "n", core.NamespaceAll, "The services namespace")
|
||||
serviceCmd.AddCommand(serviceListCmd)
|
||||
}
|
||||
|
|
|
@ -153,7 +153,9 @@ func init() {
|
|||
startCmd.Flags().Bool(gpu, false, "Enable experimental NVIDIA GPU support in minikube (works only with kvm2 driver on Linux)")
|
||||
startCmd.Flags().Bool(hidden, false, "Hide the hypervisor signature from the guest in minikube (works only with kvm2 driver on Linux)")
|
||||
startCmd.Flags().Bool(noVTXCheck, false, "Disable checking for the availability of hardware virtualization before the vm is started (virtualbox)")
|
||||
viper.BindPFlags(startCmd.Flags())
|
||||
if err := viper.BindPFlags(startCmd.Flags()); err != nil {
|
||||
exit.WithError("unable to bind flags", err)
|
||||
}
|
||||
RootCmd.AddCommand(startCmd)
|
||||
}
|
||||
|
||||
|
@ -232,7 +234,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
exit.WithError("Failed to get command runner", err)
|
||||
}
|
||||
|
||||
cr := configureRuntimes(host, runner, k8sVersion)
|
||||
cr := configureRuntimes(runner, k8sVersion)
|
||||
|
||||
// prepareHostEnvironment uses the downloaded images, so we need to wait for background task completion.
|
||||
waitCacheImages(&cacheGroup)
|
||||
|
@ -277,7 +279,7 @@ func selectImageRepository(mirrorCountry string, k8sVersion string) (bool, strin
|
|||
|
||||
if mirrorCountry != "" {
|
||||
localRepos, ok := constants.ImageRepositories[mirrorCountry]
|
||||
if !ok || len(localRepos) <= 0 {
|
||||
if !ok || len(localRepos) == 0 {
|
||||
return false, "", fmt.Errorf("invalid image mirror country code: %s", mirrorCountry)
|
||||
}
|
||||
|
||||
|
@ -504,7 +506,7 @@ func startHost(api libmachine.API, mc cfg.MachineConfig) (*host.Host, bool) {
|
|||
start := func() (err error) {
|
||||
host, err = cluster.StartHost(api, mc)
|
||||
if err != nil {
|
||||
glog.Infof("StartHost: %v", err)
|
||||
glog.Errorf("StartHost: %v", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -617,7 +619,7 @@ func updateKubeConfig(h *host.Host, c *cfg.Config) *pkgutil.KubeConfigSetup {
|
|||
}
|
||||
|
||||
// configureRuntimes does what needs to happen to get a runtime going.
|
||||
func configureRuntimes(h *host.Host, runner bootstrapper.CommandRunner, k8sVersion string) cruntime.Manager {
|
||||
func configureRuntimes(runner cruntime.CommandRunner, k8sVersion string) cruntime.Manager {
|
||||
config := cruntime.Config{Type: viper.GetString(containerRuntime), Runner: runner}
|
||||
cr, err := cruntime.New(config)
|
||||
if err != nil {
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/cluster"
|
||||
pkg_config "k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/console"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/minikube/exit"
|
||||
"k8s.io/minikube/pkg/minikube/machine"
|
||||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
|
@ -69,6 +70,12 @@ itself, leaving all files intact. The cluster can be started again with the "sta
|
|||
if err := cmdUtil.KillMountProcess(); err != nil {
|
||||
console.OutStyle("warning", "Unable to kill mount process: %s", err)
|
||||
}
|
||||
|
||||
machineName := pkg_config.GetMachineName()
|
||||
err = pkgutil.UnsetCurrentContext(constants.KubeconfigPath, machineName)
|
||||
if err != nil {
|
||||
exit.WithError("update config", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@ func main() {
|
|||
|
||||
func validateSchema(schemaPathString string, docPathString string) {
|
||||
schemaPath, _ := filepath.Abs(schemaPathString)
|
||||
schemaUri := "file://" + schemaPath
|
||||
schemaLoader := gojsonschema.NewReferenceLoader(schemaUri)
|
||||
schemaSrc := "file://" + schemaPath
|
||||
schemaLoader := gojsonschema.NewReferenceLoader(schemaSrc)
|
||||
|
||||
docPath, _ := filepath.Abs(docPathString)
|
||||
docUri := "file://" + docPath
|
||||
docLoader := gojsonschema.NewReferenceLoader(docUri)
|
||||
docSrc := "file://" + docPath
|
||||
docLoader := gojsonschema.NewReferenceLoader(docSrc)
|
||||
|
||||
result, err := gojsonschema.Validate(schemaLoader, docLoader)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Using Minikube with an HTTP Proxy
|
||||
# minikube: Using HTTP/HTTPS proxies
|
||||
|
||||
minikube requires access to the internet via HTTP, HTTPS, and DNS protocols. If a HTTP proxy is required to access the internet, you may need to pass the proxy connection information to both minikube and Docker using environment variables:
|
||||
|
||||
|
@ -23,8 +23,7 @@ export HTTP_PROXY=http://<proxy hostname:port>
|
|||
export HTTPS_PROXY=https://<proxy hostname:port>
|
||||
export NO_PROXY=localhost,127.0.0.1,10.96.0.0/12,192.168.99.0/24,192.168.39.0/24
|
||||
|
||||
minikube start --docker-env=HTTP_PROXY=$HTTP_PROXY --docker-env HTTPS_PROXY=$HTTPS_PROXY \
|
||||
--docker-env NO_PROXY=$NO_PROXY
|
||||
minikube start
|
||||
```
|
||||
|
||||
To make the exported variables permanent, consider adding the declarations to ~/.bashrc or wherever your user-set environment variables are stored.
|
||||
|
@ -36,12 +35,23 @@ set HTTP_PROXY=http://<proxy hostname:port>
|
|||
set HTTPS_PROXY=https://<proxy hostname:port>
|
||||
set NO_PROXY=localhost,127.0.0.1,10.96.0.0/12,192.168.99.1/24,192.168.39.0/24
|
||||
|
||||
minikube start --docker-env=HTTP_PROXY=$HTTP_PROXY --docker-env HTTPS_PROXY=$HTTPS_PROXY \
|
||||
--docker-env NO_PROXY=$NO_PROXY
|
||||
minikube start
|
||||
```
|
||||
|
||||
To set these environment variables permanently, consider adding these to your [system settings](https://support.microsoft.com/en-au/help/310519/how-to-manage-environment-variables-in-windows-xp) or using [setx](https://stackoverflow.com/questions/5898131/set-a-persistent-environment-variable-from-cmd-exe)
|
||||
|
||||
## Configuring Docker to use a proxy
|
||||
|
||||
As of v1.0, minikube automatically configures the Docker instance inside of the VM to use the proxy environment variables, unless you have specified a `--docker-env` override. If you need to manually configure Docker for a set of proxies, use:
|
||||
|
||||
|
||||
```shell
|
||||
minikube start \
|
||||
--docker-env=HTTP_PROXY=$HTTP_PROXY \
|
||||
--docker-env HTTPS_PROXY=$HTTPS_PROXY \
|
||||
--docker-env NO_PROXY=$NO_PROXY
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### unable to cache ISO... connection refused
|
||||
|
@ -84,6 +94,10 @@ Ask your IT department for the appropriate PEM file, and add it to:
|
|||
|
||||
Then run `minikube delete` and `minikube start`.
|
||||
|
||||
## downloading binaries: proxyconnect tcp: tls: oversized record received with length 20527
|
||||
|
||||
Your need to set a correct `HTTPS_PROXY` value.
|
||||
|
||||
## Additional Information
|
||||
|
||||
* [Configure Docker to use a proxy server](https://docs.docker.com/network/proxy/)
|
||||
|
|
|
@ -11,7 +11,7 @@ As of v1.0, `minikube start` is offline compatible out of the box. Here are some
|
|||
* `~/.minikube/cache` - Top-level folder
|
||||
* `~/.minikube/cache/iso` - VM ISO image. Typically updated once per major minikube release.
|
||||
* `~/.minikube/cache/images` - Docker images used by Kubernetes.
|
||||
* `~/.minikube/<version>` - Kubernetes binaries, such as `kubeadm` and `kubelet`
|
||||
* `~/.minikube/cache/<version>` - Kubernetes binaries, such as `kubeadm` and `kubelet`
|
||||
|
||||
## Sharing the minikube cache
|
||||
|
||||
|
|
|
@ -10,6 +10,12 @@ The `none` driver allows advanced minikube users to skip VM creation, allowing m
|
|||
|
||||
The `none` driver supports releases of Debian, Ubuntu, and Fedora that are less than 2 years old. In practice, any systemd-based modern distribution is likely to work, and we will accept pull requests which improve compatibility with other systems.
|
||||
|
||||
## Example: basic usage
|
||||
|
||||
`sudo minikube start`
|
||||
|
||||
NOTE: The none driver requires minikube to be run as root, until [#3760](https://github.com/kubernetes/minikube/issues/3760) can be addressed.
|
||||
|
||||
## Example: Using minikube for continuous integration testing
|
||||
|
||||
Most continuous integration environments are already running inside a VM, and may not supported nested virtualization. The `none` driver was designed for this use case. Here is an example, that runs minikube from a non-root user, and ensures that the latest stable kubectl is installed:
|
||||
|
@ -96,6 +102,7 @@ Some environment variables may be useful for using the `none` driver:
|
|||
|
||||
## Known Issues
|
||||
|
||||
* `systemctl` is required. [#2704](https://github.com/kubernetes/minikube/issues/2704)
|
||||
* `-p` (profiles) are unsupported: It is not possible to run more than one `--vm-driver=none` instance
|
||||
* Many `minikube` commands are not supported, such as: `dashboard`, `mount`, `ssh`
|
||||
* minikube with the `none` driver has a confusing permissions model, as some commands need to be run as root ("start"), and others by a regular user ("dashboard")
|
||||
|
|
2
go.mod
2
go.mod
|
@ -41,6 +41,7 @@ require (
|
|||
github.com/johanneswuerbach/nfsexports v0.0.0-20181204082207-1aa528dcb345
|
||||
github.com/json-iterator/go v1.1.5 // indirect
|
||||
github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/libvirt/libvirt-go v3.4.0+incompatible
|
||||
github.com/machine-drivers/docker-machine-driver-vmware v0.1.1
|
||||
github.com/magiconair/properties v0.0.0-20160816085511-61b492c03cf4 // indirect
|
||||
|
@ -88,6 +89,7 @@ require (
|
|||
golang.org/x/text v0.3.2
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d // indirect
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.6 // indirect
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
|
||||
gopkg.in/inf.v0 v0.9.0 // indirect
|
||||
|
|
9
go.sum
9
go.sum
|
@ -90,6 +90,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi
|
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169 h1:YUrU1/jxRqnt0PSrKj1Uj/wEjk/fjnE80QFfi2Zlj7Q=
|
||||
github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169/go.mod h1:glhvuHOU9Hy7/8PwwdtnarXqLagOX0b/TbZx2zLMqEg=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/libvirt/libvirt-go v3.4.0+incompatible h1:Cpyalgj1x8JIeTlL6SDYZBo7j8nY3+5XHqmi8DaunCk=
|
||||
github.com/libvirt/libvirt-go v3.4.0+incompatible/go.mod h1:34zsnB4iGeOv7Byj6qotuW8Ya4v4Tr43ttjz/F0wjLE=
|
||||
github.com/machine-drivers/docker-machine-driver-vmware v0.1.1 h1:+E1IKKk+6kaQrCPg6edJZ/zISZijuZTPnzy6RE4C/Ho=
|
||||
|
@ -163,6 +168,7 @@ github.com/spf13/viper v1.0.0 h1:RUA/ghS2i64rlnn4ydTfblY8Og8QzcPtCcHvgMn+w/I=
|
|||
github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
@ -217,8 +223,9 @@ google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO50
|
|||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.6 h1:YQye4a1JysUfXYB6VihDfxb4lxOAei0xS44yN+srOew=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.6/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
|
|
|
@ -25,9 +25,15 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
os.MkdirAll("./out/docs", os.FileMode(0755))
|
||||
if err := os.MkdirAll("./out/docs", os.FileMode(0755)); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
cmd.RootCmd.DisableAutoGenTag = true
|
||||
doc.GenMarkdownTree(cmd.RootCmd, "./out/docs")
|
||||
if err := doc.GenMarkdownTree(cmd.RootCmd, "./out/docs"); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
f, err := os.Create("./out/docs/bash-completion")
|
||||
if err != nil {
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -56,21 +58,29 @@ func main() {
|
|||
re = regexp.MustCompile(`var NewestKubernetesVersion = .*`)
|
||||
f = re.ReplaceAllString(f, "var NewestKubernetesVersion = \""+v+"\"")
|
||||
|
||||
ioutil.WriteFile(constantsFile, []byte(f), mode)
|
||||
if err := ioutil.WriteFile(constantsFile, []byte(f), mode); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
testData := "../../pkg/minikube/bootstrapper/kubeadm/testdata"
|
||||
|
||||
err = filepath.Walk(testData, func(path string, info os.FileInfo, err error) error {
|
||||
if strings.HasSuffix(path, "default.yaml") {
|
||||
cf, err = ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
// Keep going if this errors out
|
||||
fmt.Println(err)
|
||||
}
|
||||
re = regexp.MustCompile(`kubernetesVersion: .*`)
|
||||
cf = []byte(re.ReplaceAllString(string(cf), "kubernetesVersion: "+v))
|
||||
ioutil.WriteFile(path, cf, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
if !strings.HasSuffix(path, "default.yaml") {
|
||||
return nil
|
||||
}
|
||||
cf, err = ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
re = regexp.MustCompile(`kubernetesVersion: .*`)
|
||||
cf = []byte(re.ReplaceAllString(string(cf), "kubernetesVersion: "+v))
|
||||
return ioutil.WriteFile(path, cf, info.Mode())
|
||||
})
|
||||
if err != nil {
|
||||
glog.Errorf("Walk failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ func printPullRequests() {
|
|||
}
|
||||
|
||||
func getClient() *github.Client {
|
||||
if len(token) <= 0 {
|
||||
if len(token) == 0 {
|
||||
return github.NewClient(nil)
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package drivers
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -51,25 +52,27 @@ func (d *CommonDriver) SetConfigFromFlags(flags drivers.DriverOptions) error {
|
|||
func createRawDiskImage(sshKeyPath, diskPath string, diskSizeMb int) error {
|
||||
tarBuf, err := mcnutils.MakeDiskImage(sshKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "make disk image")
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(diskPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "open")
|
||||
}
|
||||
defer file.Close()
|
||||
file.Seek(0, os.SEEK_SET)
|
||||
if _, err := file.Seek(0, io.SeekStart); err != nil {
|
||||
return errors.Wrap(err, "seek")
|
||||
}
|
||||
|
||||
if _, err := file.Write(tarBuf.Bytes()); err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "write tar")
|
||||
}
|
||||
if err := file.Close(); err != nil {
|
||||
return errors.Wrapf(err, "closing file %s", diskPath)
|
||||
}
|
||||
|
||||
if err := os.Truncate(diskPath, int64(diskSizeMb*1000000)); err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "truncate")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -91,37 +94,45 @@ func Restart(d drivers.Driver) error {
|
|||
|
||||
// MakeDiskImage makes a boot2docker VM disk image.
|
||||
func MakeDiskImage(d *drivers.BaseDriver, boot2dockerURL string, diskSize int) error {
|
||||
//TODO(r2d4): rewrite this, not using b2dutils
|
||||
b2dutils := mcnutils.NewB2dUtils(d.StorePath)
|
||||
if err := b2dutils.CopyIsoToMachineDir(boot2dockerURL, d.MachineName); err != nil {
|
||||
return errors.Wrap(err, "Error copying ISO to machine dir")
|
||||
glog.Infof("Making disk image using store path: %s", d.StorePath)
|
||||
b2 := mcnutils.NewB2dUtils(d.StorePath)
|
||||
if err := b2.CopyIsoToMachineDir(boot2dockerURL, d.MachineName); err != nil {
|
||||
return errors.Wrap(err, "copy iso to machine dir")
|
||||
}
|
||||
|
||||
glog.Info("Creating ssh key...")
|
||||
if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
|
||||
return err
|
||||
keyPath := d.GetSSHKeyPath()
|
||||
glog.Infof("Creating ssh key: %s...", keyPath)
|
||||
if err := ssh.GenerateSSHKey(keyPath); err != nil {
|
||||
return errors.Wrap(err, "generate ssh key")
|
||||
}
|
||||
|
||||
glog.Info("Creating raw disk image...")
|
||||
diskPath := GetDiskPath(d)
|
||||
glog.Infof("Creating raw disk image: %s...", diskPath)
|
||||
if _, err := os.Stat(diskPath); os.IsNotExist(err) {
|
||||
if err := createRawDiskImage(publicSSHKeyPath(d), diskPath, diskSize); err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "createRawDiskImage(%s)", diskPath)
|
||||
}
|
||||
if err := fixPermissions(d.ResolveStorePath(".")); err != nil {
|
||||
return err
|
||||
machPath := d.ResolveStorePath(".")
|
||||
if err := fixPermissions(machPath); err != nil {
|
||||
return errors.Wrapf(err, "fixing permissions on %s", machPath)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fixPermissions(path string) error {
|
||||
os.Chown(path, syscall.Getuid(), syscall.Getegid())
|
||||
files, _ := ioutil.ReadDir(path)
|
||||
glog.Infof("Fixing permissions on %s ...", path)
|
||||
if err := os.Chown(path, syscall.Getuid(), syscall.Getegid()); err != nil {
|
||||
return errors.Wrap(err, "chown dir")
|
||||
}
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read dir")
|
||||
}
|
||||
for _, f := range files {
|
||||
fp := filepath.Join(path, f.Name())
|
||||
if err := os.Chown(fp, syscall.Getuid(), syscall.Getegid()); err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "chown file")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -30,7 +30,9 @@ func Test_createDiskImage(t *testing.T) {
|
|||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
sshPath := filepath.Join(tmpdir, "ssh")
|
||||
ioutil.WriteFile(sshPath, []byte("mysshkey"), 0644)
|
||||
if err := ioutil.WriteFile(sshPath, []byte("mysshkey"), 0644); err != nil {
|
||||
t.Fatalf("writefile: %v", err)
|
||||
}
|
||||
diskPath := filepath.Join(tmpdir, "disk")
|
||||
|
||||
sizeInMb := 100
|
||||
|
|
|
@ -36,10 +36,11 @@ import (
|
|||
"github.com/docker/machine/libmachine/log"
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/johanneswuerbach/nfsexports"
|
||||
"github.com/mitchellh/go-ps"
|
||||
"github.com/moby/hyperkit/go"
|
||||
ps "github.com/mitchellh/go-ps"
|
||||
hyperkit "github.com/moby/hyperkit/go"
|
||||
"github.com/pkg/errors"
|
||||
pkgdrivers "k8s.io/minikube/pkg/drivers"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
|
|
@ -19,7 +19,6 @@ package hyperkit
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
|
@ -29,10 +28,10 @@ import (
|
|||
// ExtractFile extracts a file from an ISO
|
||||
func ExtractFile(isoPath, srcPath, destPath string) error {
|
||||
iso, err := os.Open(isoPath)
|
||||
defer iso.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer iso.Close()
|
||||
|
||||
r, err := iso9660.NewReader(iso)
|
||||
if err != nil {
|
||||
|
@ -45,36 +44,15 @@ func ExtractFile(isoPath, srcPath, destPath string) error {
|
|||
}
|
||||
|
||||
dst, err := os.Create(destPath)
|
||||
defer dst.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
_, err = io.Copy(dst, f.Sys().(io.Reader))
|
||||
return err
|
||||
}
|
||||
|
||||
func readFile(isoPath, srcPath string) (string, error) {
|
||||
iso, err := os.Open(isoPath)
|
||||
defer iso.Close()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
r, err := iso9660.NewReader(iso)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f, err := findFile(r, srcPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
contents, err := ioutil.ReadAll(f.Sys().(io.Reader))
|
||||
return string(contents), err
|
||||
}
|
||||
|
||||
func findFile(r *iso9660.Reader, path string) (os.FileInfo, error) {
|
||||
// Look through the ISO for a file with a matching path.
|
||||
for f, err := r.Next(); err != io.EOF; f, err = r.Next() {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build darwin
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
@ -38,6 +40,10 @@ const (
|
|||
SharedNetAddrKey = "Shared_Net_Address"
|
||||
)
|
||||
|
||||
var (
|
||||
leadingZeroRegexp = regexp.MustCompile(`0([A-Fa-f0-9](:|$))`)
|
||||
)
|
||||
|
||||
// DHCPEntry holds a parsed DNS entry
|
||||
type DHCPEntry struct {
|
||||
Name string
|
||||
|
@ -118,10 +124,7 @@ func parseDHCPdLeasesFile(file io.Reader) ([]DHCPEntry, error) {
|
|||
|
||||
// trimMacAddress trimming "0" of the ten's digit
|
||||
func trimMacAddress(rawUUID string) string {
|
||||
re := regexp.MustCompile(`0([A-Fa-f0-9](:|$))`)
|
||||
mac := re.ReplaceAllString(rawUUID, "$1")
|
||||
|
||||
return mac
|
||||
return leadingZeroRegexp.ReplaceAllString(rawUUID, "$1")
|
||||
}
|
||||
|
||||
// GetNetAddr gets the network address for vmnet
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build darwin
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
@ -52,10 +54,14 @@ func Test_getIpAddressFromFile(t *testing.T) {
|
|||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
dhcpFile := filepath.Join(tmpdir, "dhcp")
|
||||
ioutil.WriteFile(dhcpFile, validLeases, 0644)
|
||||
if err := ioutil.WriteFile(dhcpFile, validLeases, 0644); err != nil {
|
||||
t.Fatalf("writefile: %v", err)
|
||||
}
|
||||
|
||||
invalidFile := filepath.Join(tmpdir, "invalid")
|
||||
ioutil.WriteFile(invalidFile, []byte("foo"), 0644)
|
||||
if err := ioutil.WriteFile(invalidFile, []byte("foo"), 0644); err != nil {
|
||||
t.Fatalf("writefile: %v", err)
|
||||
}
|
||||
|
||||
type args struct {
|
||||
mac string
|
||||
|
|
|
@ -22,6 +22,6 @@ import (
|
|||
vmnet "github.com/zchee/go-vmnet"
|
||||
)
|
||||
|
||||
func GetMACAddressFromUUID(UUID string) (string, error) {
|
||||
return vmnet.GetMACAddressFromUUID(UUID)
|
||||
func GetMACAddressFromUUID(id string) (string, error) {
|
||||
return vmnet.GetMACAddressFromUUID(id)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
@ -121,7 +123,7 @@ func randomMAC() (net.HardwareAddr, error) {
|
|||
// The second LSB of the first octet
|
||||
// 0 for universally administered addresses
|
||||
// 1 for locally administered addresses
|
||||
buf[0] = buf[0] & 0xfc
|
||||
buf[0] &= 0xfc
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
|
@ -149,11 +151,14 @@ func getConnection() (*libvirt.Connect, error) {
|
|||
}
|
||||
|
||||
func closeDomain(dom *libvirt.Domain, conn *libvirt.Connect) error {
|
||||
dom.Free()
|
||||
if res, _ := conn.Close(); res != 0 {
|
||||
return fmt.Errorf("Error closing connection CloseConnection() == %d, expected 0", res)
|
||||
if err := dom.Free(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
res, err := conn.Close()
|
||||
if res != 0 {
|
||||
return fmt.Errorf("CloseConnection() == %d, expected 0", res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Driver) createDomain() (*libvirt.Domain, error) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
@ -20,6 +22,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
|
@ -140,18 +143,27 @@ func (d *Driver) GetURL() (string, error) {
|
|||
}
|
||||
|
||||
// GetState returns the state that the host is in (running, stopped, etc)
|
||||
func (d *Driver) GetState() (state.State, error) {
|
||||
func (d *Driver) GetState() (st state.State, err error) {
|
||||
dom, conn, err := d.getDomain()
|
||||
if err != nil {
|
||||
return state.None, errors.Wrap(err, "getting connection")
|
||||
}
|
||||
defer closeDomain(dom, conn)
|
||||
defer func() {
|
||||
if ferr := closeDomain(dom, conn); ferr != nil {
|
||||
err = ferr
|
||||
}
|
||||
}()
|
||||
|
||||
libvirtState, _, err := dom.GetState() // state, reason, error
|
||||
lvs, _, err := dom.GetState() // state, reason, error
|
||||
if err != nil {
|
||||
return state.None, errors.Wrap(err, "getting domain state")
|
||||
}
|
||||
st = machineState(lvs)
|
||||
return // st, err
|
||||
}
|
||||
|
||||
// machineState converts libvirt state to libmachine state
|
||||
func machineState(lvs libvirt.DomainState) state.State {
|
||||
// Possible States:
|
||||
//
|
||||
// VIR_DOMAIN_NOSTATE no state
|
||||
|
@ -164,23 +176,23 @@ func (d *Driver) GetState() (state.State, error) {
|
|||
// VIR_DOMAIN_PMSUSPENDED the domain is suspended by guest power management
|
||||
// VIR_DOMAIN_LAST this enum value will increase over time as new events are added to the libvirt API. It reflects the last state supported by this version of the libvirt API.
|
||||
|
||||
switch libvirtState {
|
||||
switch lvs {
|
||||
// DOMAIN_SHUTDOWN technically means the VM is still running, but in the
|
||||
// process of being shutdown, so we return state.Running
|
||||
case libvirt.DOMAIN_RUNNING, libvirt.DOMAIN_SHUTDOWN:
|
||||
return state.Running, nil
|
||||
return state.Running
|
||||
case libvirt.DOMAIN_BLOCKED, libvirt.DOMAIN_CRASHED:
|
||||
return state.Error, nil
|
||||
return state.Error
|
||||
case libvirt.DOMAIN_PAUSED:
|
||||
return state.Paused, nil
|
||||
return state.Paused
|
||||
case libvirt.DOMAIN_SHUTOFF:
|
||||
return state.Stopped, nil
|
||||
return state.Stopped
|
||||
case libvirt.DOMAIN_PMSUSPENDED:
|
||||
return state.Saved, nil
|
||||
return state.Saved
|
||||
case libvirt.DOMAIN_NOSTATE:
|
||||
return state.None, nil
|
||||
return state.None
|
||||
default:
|
||||
return state.None, nil
|
||||
return state.None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,13 +224,16 @@ func (d *Driver) DriverName() string {
|
|||
}
|
||||
|
||||
// Kill stops a host forcefully, including any containers that we are managing.
|
||||
func (d *Driver) Kill() error {
|
||||
func (d *Driver) Kill() (err error) {
|
||||
dom, conn, err := d.getDomain()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting connection")
|
||||
}
|
||||
defer closeDomain(dom, conn)
|
||||
|
||||
defer func() {
|
||||
if ferr := closeDomain(dom, conn); ferr != nil {
|
||||
err = ferr
|
||||
}
|
||||
}()
|
||||
return dom.Destroy()
|
||||
}
|
||||
|
||||
|
@ -228,11 +243,11 @@ func (d *Driver) Restart() error {
|
|||
}
|
||||
|
||||
// Start a host
|
||||
func (d *Driver) Start() error {
|
||||
func (d *Driver) Start() (err error) {
|
||||
// if somebody/something deleted the network in the meantime,
|
||||
// we might need to recreate it. It's (nearly) a noop if the network exists.
|
||||
log.Info("Creating network...")
|
||||
err := d.createNetwork()
|
||||
err = d.createNetwork()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating network")
|
||||
}
|
||||
|
@ -249,7 +264,11 @@ func (d *Driver) Start() error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "getting connection")
|
||||
}
|
||||
defer closeDomain(dom, conn)
|
||||
defer func() {
|
||||
if ferr := closeDomain(dom, conn); ferr != nil {
|
||||
err = ferr
|
||||
}
|
||||
}()
|
||||
|
||||
log.Info("Creating domain...")
|
||||
if err := dom.Create(); err != nil {
|
||||
|
@ -289,10 +308,11 @@ func (d *Driver) Start() error {
|
|||
}
|
||||
|
||||
// Create a host using the driver's config
|
||||
func (d *Driver) Create() error {
|
||||
log.Info("Creating machine...")
|
||||
log.Info("Creating network...")
|
||||
err := d.createNetwork()
|
||||
func (d *Driver) Create() (err error) {
|
||||
log.Info("Creating KVM machine...")
|
||||
defer log.Infof("KVM machine creation complete!")
|
||||
|
||||
err = d.createNetwork()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating network")
|
||||
}
|
||||
|
@ -304,42 +324,64 @@ func (d *Driver) Create() error {
|
|||
}
|
||||
}
|
||||
|
||||
log.Info("Setting up minikube home directory...")
|
||||
if err := os.MkdirAll(d.ResolveStorePath("."), 0755); err != nil {
|
||||
return errors.Wrap(err, "Error making store path directory")
|
||||
store := d.ResolveStorePath(".")
|
||||
log.Infof("Setting up store path in %s ...", store)
|
||||
// 0755 because it must be accessible by libvirt/qemu across a variety of configs
|
||||
if err := os.MkdirAll(store, 0755); err != nil {
|
||||
return errors.Wrap(err, "creating store")
|
||||
}
|
||||
|
||||
for dir := d.ResolveStorePath("."); dir != "/"; dir = filepath.Dir(dir) {
|
||||
info, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mode := info.Mode()
|
||||
if mode&0011 != 1 {
|
||||
log.Debugf("Setting executable bit set on %s", dir)
|
||||
mode |= 0011
|
||||
os.Chmod(dir, mode)
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Building disk image...")
|
||||
log.Infof("Building disk image from %s", d.Boot2DockerURL)
|
||||
if err = pkgdrivers.MakeDiskImage(d.BaseDriver, d.Boot2DockerURL, d.DiskSize); err != nil {
|
||||
return errors.Wrap(err, "Error creating disk")
|
||||
}
|
||||
|
||||
if err := ensureDirPermissions(store); err != nil {
|
||||
log.Errorf("unable to ensure permissions on %s: %v", store, err)
|
||||
}
|
||||
|
||||
log.Info("Creating domain...")
|
||||
dom, err := d.createDomain()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating domain")
|
||||
}
|
||||
defer dom.Free()
|
||||
|
||||
log.Debug("Finished creating machine, now starting machine...")
|
||||
defer func() {
|
||||
if ferr := dom.Free(); ferr != nil {
|
||||
err = ferr
|
||||
}
|
||||
}()
|
||||
return d.Start()
|
||||
}
|
||||
|
||||
// ensureDirPermissions ensures that libvirt has access to access the image store directory
|
||||
func ensureDirPermissions(store string) error {
|
||||
// traverse upwards from /home/user/.minikube/machines to ensure
|
||||
// that libvirt/qemu has execute access
|
||||
for dir := store; dir != "/"; dir = filepath.Dir(dir) {
|
||||
log.Debugf("Checking permissions on dir: %s", dir)
|
||||
s, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
owner := int(s.Sys().(*syscall.Stat_t).Uid)
|
||||
if owner != os.Geteuid() {
|
||||
log.Debugf("Skipping %s - not owner", dir)
|
||||
continue
|
||||
}
|
||||
mode := s.Mode()
|
||||
if mode&0011 != 1 {
|
||||
log.Infof("Setting executable bit set on %s (perms=%s)", dir, mode)
|
||||
mode |= 0011
|
||||
if err := os.Chmod(dir, mode); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop a host gracefully
|
||||
func (d *Driver) Stop() error {
|
||||
func (d *Driver) Stop() (err error) {
|
||||
d.IPAddress = ""
|
||||
s, err := d.GetState()
|
||||
if err != nil {
|
||||
|
@ -348,7 +390,11 @@ func (d *Driver) Stop() error {
|
|||
|
||||
if s != state.Stopped {
|
||||
dom, conn, err := d.getDomain()
|
||||
defer closeDomain(dom, conn)
|
||||
defer func() {
|
||||
if ferr := closeDomain(dom, conn); ferr != nil {
|
||||
err = ferr
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting connection")
|
||||
}
|
||||
|
@ -372,7 +418,7 @@ func (d *Driver) Stop() error {
|
|||
|
||||
}
|
||||
|
||||
return fmt.Errorf("Could not stop VM, current state %s", s.String())
|
||||
return fmt.Errorf("unable to stop vm, current state %q", s.String())
|
||||
}
|
||||
|
||||
// Remove a host
|
||||
|
@ -400,8 +446,12 @@ func (d *Driver) Remove() error {
|
|||
}
|
||||
if dom != nil {
|
||||
log.Infof("Domain %s exists, removing...", d.MachineName)
|
||||
dom.Destroy()
|
||||
dom.Undefine()
|
||||
if err := dom.Destroy(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := dom.Undefine(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
@ -320,7 +322,7 @@ func (d *Driver) lookupIPFromLeasesFile() (string, error) {
|
|||
// ExpiryTime MAC IP Hostname ExtendedMAC
|
||||
entry := strings.Split(lease, " ")
|
||||
if len(entry) != 5 {
|
||||
return "", fmt.Errorf("Malformed leases entry: %s", entry)
|
||||
return "", fmt.Errorf("malformed leases entry: %s", entry)
|
||||
}
|
||||
if entry[1] == d.PrivateMAC {
|
||||
ipAddress = entry[2]
|
||||
|
|
|
@ -341,7 +341,10 @@ func AddMinikubeDirAssets(assets *[]CopyableFile) error {
|
|||
// of files to be copied to the vm. If vmpath is left blank, the files will be
|
||||
// transferred to the location according to their relative minikube folder path.
|
||||
func addMinikubeDirToAssets(basedir, vmpath string, assets *[]CopyableFile) error {
|
||||
err := filepath.Walk(basedir, func(hostpath string, info os.FileInfo, err error) error {
|
||||
return filepath.Walk(basedir, func(hostpath string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
isDir, err := util.IsDirectory(hostpath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "checking if %s is directory", hostpath)
|
||||
|
@ -373,10 +376,6 @@ func addMinikubeDirToAssets(basedir, vmpath string, assets *[]CopyableFile) erro
|
|||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "walking filepath")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateTemplateData generates template data for template assets
|
||||
|
|
|
@ -41,12 +41,11 @@ func TestAddMinikubeDirAssets(t *testing.T) {
|
|||
tests := []struct {
|
||||
description string
|
||||
baseDir string
|
||||
vmPath string
|
||||
files []struct {
|
||||
relativePath string
|
||||
expectedPath string
|
||||
}
|
||||
vmPath string
|
||||
expectedCfg string
|
||||
}{
|
||||
{
|
||||
description: "relative path assets",
|
||||
|
@ -113,7 +112,7 @@ func TestAddMinikubeDirAssets(t *testing.T) {
|
|||
|
||||
testDirs = append(testDirs, testDir)
|
||||
testFileBaseDir := filepath.Join(testDir, test.baseDir)
|
||||
want := make(map[string]string, 0)
|
||||
want := make(map[string]string)
|
||||
for _, fileDef := range test.files {
|
||||
err := func() error {
|
||||
path := filepath.Join(testFileBaseDir, fileDef.relativePath)
|
||||
|
@ -146,7 +145,7 @@ func TestAddMinikubeDirAssets(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
got := make(map[string]string, 0)
|
||||
got := make(map[string]string)
|
||||
for _, actualFile := range actualFiles {
|
||||
got[actualFile.GetAssetName()] = actualFile.GetTargetDir()
|
||||
}
|
||||
|
|
|
@ -40,9 +40,6 @@ type CopyableFile interface {
|
|||
|
||||
// BaseAsset is the base asset class
|
||||
type BaseAsset struct {
|
||||
data []byte
|
||||
reader io.Reader
|
||||
Length int
|
||||
AssetName string
|
||||
TargetDir string
|
||||
TargetName string
|
||||
|
@ -72,6 +69,7 @@ func (b *BaseAsset) GetPermissions() string {
|
|||
// FileAsset is an asset using a file
|
||||
type FileAsset struct {
|
||||
BaseAsset
|
||||
reader io.Reader
|
||||
}
|
||||
|
||||
// NewMemoryAssetTarget creates a new MemoryAsset, with target
|
||||
|
@ -80,31 +78,25 @@ func NewMemoryAssetTarget(d []byte, targetPath, permissions string) *MemoryAsset
|
|||
}
|
||||
|
||||
// NewFileAsset creates a new FileAsset
|
||||
func NewFileAsset(assetName, targetDir, targetName, permissions string) (*FileAsset, error) {
|
||||
f := &FileAsset{
|
||||
BaseAsset{
|
||||
AssetName: assetName,
|
||||
func NewFileAsset(path, targetDir, targetName, permissions string) (*FileAsset, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error opening file asset: %s", path)
|
||||
}
|
||||
return &FileAsset{
|
||||
BaseAsset: BaseAsset{
|
||||
AssetName: path,
|
||||
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
|
||||
reader: f,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetLength returns the file length, or 0 (on error)
|
||||
func (f *FileAsset) GetLength() int {
|
||||
file, err := os.Open(f.AssetName)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
fi, err := file.Stat()
|
||||
func (f *FileAsset) GetLength() (flen int) {
|
||||
fi, err := os.Stat(f.AssetName)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
@ -121,11 +113,13 @@ func (f *FileAsset) Read(p []byte) (int, error) {
|
|||
// MemoryAsset is a memory-based asset
|
||||
type MemoryAsset struct {
|
||||
BaseAsset
|
||||
reader io.Reader
|
||||
length int
|
||||
}
|
||||
|
||||
// GetLength returns length
|
||||
func (m *MemoryAsset) GetLength() int {
|
||||
return m.Length
|
||||
return m.length
|
||||
}
|
||||
|
||||
// Read reads the asset
|
||||
|
@ -135,24 +129,23 @@ func (m *MemoryAsset) Read(p []byte) (int, error) {
|
|||
|
||||
// NewMemoryAsset creates a new MemoryAsset
|
||||
func NewMemoryAsset(d []byte, targetDir, targetName, permissions string) *MemoryAsset {
|
||||
m := &MemoryAsset{
|
||||
BaseAsset{
|
||||
return &MemoryAsset{
|
||||
BaseAsset: BaseAsset{
|
||||
TargetDir: targetDir,
|
||||
TargetName: targetName,
|
||||
Permissions: permissions,
|
||||
},
|
||||
reader: bytes.NewReader(d),
|
||||
length: len(d),
|
||||
}
|
||||
|
||||
m.data = d
|
||||
m.Length = len(m.data)
|
||||
m.reader = bytes.NewReader(m.data)
|
||||
return m
|
||||
}
|
||||
|
||||
// BinAsset is a bindata (binary data) asset
|
||||
type BinAsset struct {
|
||||
BaseAsset
|
||||
reader io.Reader
|
||||
template *template.Template
|
||||
length int
|
||||
}
|
||||
|
||||
// MustBinAsset creates a new BinAsset, or panics if invalid
|
||||
|
@ -205,11 +198,10 @@ func (m *BinAsset) loadData(isTemplate bool) error {
|
|||
m.template = tpl
|
||||
}
|
||||
|
||||
m.data = contents
|
||||
m.Length = len(contents)
|
||||
m.reader = bytes.NewReader(m.data)
|
||||
glog.Infof("Created asset %s with %d bytes", m.AssetName, m.Length)
|
||||
if m.Length == 0 {
|
||||
m.length = len(contents)
|
||||
m.reader = bytes.NewReader(contents)
|
||||
glog.Infof("Created asset %s with %d bytes", m.AssetName, m.length)
|
||||
if m.length == 0 {
|
||||
return fmt.Errorf("%s is an empty asset", m.AssetName)
|
||||
}
|
||||
return nil
|
||||
|
@ -237,12 +229,12 @@ func (m *BinAsset) Evaluate(data interface{}) (*MemoryAsset, error) {
|
|||
|
||||
// GetLength returns length
|
||||
func (m *BinAsset) GetLength() int {
|
||||
return m.Length
|
||||
return m.length
|
||||
}
|
||||
|
||||
// Read reads the asset
|
||||
func (m *BinAsset) Read(p []byte) (int, error) {
|
||||
if m.Length == 0 {
|
||||
if m.GetLength() == 0 {
|
||||
return 0, fmt.Errorf("attempted read from a 0 length asset")
|
||||
}
|
||||
return m.reader.Read(p)
|
||||
|
|
|
@ -25,11 +25,10 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
clientv1 "k8s.io/api/core/v1"
|
||||
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1beta1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
|
@ -52,7 +51,7 @@ func unmarkMaster() error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "getting core client")
|
||||
}
|
||||
n, err := client.Nodes().Get(master, v1.GetOptions{})
|
||||
n, err := client.Nodes().Get(master, meta.GetOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "getting node %s", master)
|
||||
}
|
||||
|
@ -62,7 +61,7 @@ func unmarkMaster() error {
|
|||
return errors.Wrap(err, "json marshalling data before patch")
|
||||
}
|
||||
|
||||
newTaints := []clientv1.Taint{}
|
||||
newTaints := []core.Taint{}
|
||||
for _, taint := range n.Spec.Taints {
|
||||
if taint.Key == masterTaint {
|
||||
continue
|
||||
|
@ -77,13 +76,13 @@ func unmarkMaster() error {
|
|||
return errors.Wrapf(err, "json marshalling data after patch")
|
||||
}
|
||||
|
||||
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, clientv1.Node{})
|
||||
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, core.Node{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating strategic patch")
|
||||
}
|
||||
|
||||
if _, err := client.Nodes().Patch(n.Name, types.StrategicMergePatchType, patchBytes); err != nil {
|
||||
if apierrs.IsConflict(err) {
|
||||
if apierr.IsConflict(err) {
|
||||
return errors.Wrap(err, "strategic patch conflict")
|
||||
}
|
||||
return errors.Wrap(err, "applying strategic patch")
|
||||
|
@ -100,24 +99,24 @@ func elevateKubeSystemPrivileges() error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "getting clientset")
|
||||
}
|
||||
clusterRoleBinding := &rbacv1beta1.ClusterRoleBinding{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
clusterRoleBinding := &rbac.ClusterRoleBinding{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: rbacName,
|
||||
},
|
||||
Subjects: []rbacv1beta1.Subject{
|
||||
Subjects: []rbac.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "default",
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1beta1.RoleRef{
|
||||
RoleRef: rbac.RoleRef{
|
||||
Kind: "ClusterRole",
|
||||
Name: "cluster-admin",
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := client.RbacV1beta1().ClusterRoleBindings().Get(rbacName, metav1.GetOptions{}); err == nil {
|
||||
if _, err := client.RbacV1beta1().ClusterRoleBindings().Get(rbacName, meta.GetOptions{}); err == nil {
|
||||
glog.Infof("Role binding %s already exists. Skipping creation.", rbacName)
|
||||
return nil
|
||||
}
|
||||
|
@ -167,7 +166,7 @@ func updateKubeProxyConfigMap(k8s config.KubernetesConfig) error {
|
|||
return errors.Wrap(err, "kube-proxy not running")
|
||||
}
|
||||
|
||||
cfgMap, err := client.CoreV1().ConfigMaps("kube-system").Get("kube-proxy", metav1.GetOptions{})
|
||||
cfgMap, err := client.CoreV1().ConfigMaps("kube-system").Get("kube-proxy", meta.GetOptions{})
|
||||
if err != nil {
|
||||
return &util.RetriableError{Err: errors.Wrap(err, "getting kube-proxy configmap")}
|
||||
}
|
||||
|
@ -206,7 +205,7 @@ func updateKubeProxyConfigMap(k8s config.KubernetesConfig) error {
|
|||
return &util.RetriableError{Err: errors.Wrap(err, "updating configmap")}
|
||||
}
|
||||
|
||||
pods, err := client.CoreV1().Pods("kube-system").List(metav1.ListOptions{
|
||||
pods, err := client.CoreV1().Pods("kube-system").List(meta.ListOptions{
|
||||
LabelSelector: "k8s-app=kube-proxy",
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -214,7 +213,7 @@ func updateKubeProxyConfigMap(k8s config.KubernetesConfig) error {
|
|||
}
|
||||
for _, pod := range pods.Items {
|
||||
// Retriable, as known to fail with: pods "<name>" not found
|
||||
if err := client.CoreV1().Pods(pod.Namespace).Delete(pod.Name, &metav1.DeleteOptions{}); err != nil {
|
||||
if err := client.CoreV1().Pods(pod.Namespace).Delete(pod.Name, &meta.DeleteOptions{}); err != nil {
|
||||
return &util.RetriableError{Err: errors.Wrapf(err, "deleting pod %+v", pod)}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ func NewComponentExtraArgs(opts util.ExtraOptionSlice, version semver.Version, f
|
|||
var kubeadmExtraArgs []ComponentExtraArgs
|
||||
for _, extraOpt := range opts {
|
||||
if _, ok := componentToKubeadmConfigKey[extraOpt.Component]; !ok {
|
||||
return nil, fmt.Errorf("Unknown component %s. Valid components and kubeadm config are %v", componentToKubeadmConfigKey, componentToKubeadmConfigKey)
|
||||
return nil, fmt.Errorf("unknown component %q. valid components are: %v", componentToKubeadmConfigKey, componentToKubeadmConfigKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ func ParseFeatureArgs(featureGates string) (map[string]bool, string, error) {
|
|||
// feature gates for kubeadm
|
||||
func Supports(featureName string) bool {
|
||||
for k := range features.InitFeatureGates {
|
||||
if featureName == string(k) {
|
||||
if featureName == k {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ func DefaultOptionsForComponentAndVersion(component string, version semver.Versi
|
|||
if opts.Option.Component == component {
|
||||
if VersionIsBetween(version, opts.GreaterThanOrEqual, opts.LessThanOrEqual) {
|
||||
if val, ok := versionedOpts[opts.Option.Key]; ok {
|
||||
return nil, fmt.Errorf("Flag %s=%s already set %s=%s", opts.Option.Key, opts.Option.Value, opts.Option.Key, val)
|
||||
return nil, fmt.Errorf("flag %s=%q already set %s=%q", opts.Option.Key, opts.Option.Value, opts.Option.Key, val)
|
||||
}
|
||||
versionedOpts[opts.Option.Key] = opts.Option.Value
|
||||
}
|
||||
|
|
|
@ -44,15 +44,13 @@ import (
|
|||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultVirtualboxNicType = "virtio"
|
||||
)
|
||||
|
||||
//This init function is used to set the logtostderr variable to false so that INFO level log info does not clutter the CLI
|
||||
//INFO lvl logging is displayed due to the kubernetes api calling flag.Set("logtostderr", "true") in its init()
|
||||
//see: https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/util/logs/logs.go#L32-L34
|
||||
func init() {
|
||||
flag.Set("logtostderr", "false")
|
||||
if err := flag.Set("logtostderr", "false"); err != nil {
|
||||
exit.WithError("unable to set logtostderr", err)
|
||||
}
|
||||
|
||||
// Setting the default client to native gives much better performance.
|
||||
ssh.SetDefaultClient(ssh.Native)
|
||||
|
@ -72,7 +70,7 @@ func CacheISO(config cfg.MachineConfig) error {
|
|||
func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error) {
|
||||
exists, err := api.Exists(cfg.GetMachineName())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "machine name: %s", cfg.GetMachineName())
|
||||
return nil, errors.Wrapf(err, "exists: %s", cfg.GetMachineName())
|
||||
}
|
||||
if !exists {
|
||||
glog.Infoln("Machine does not exist... provisioning new machine")
|
||||
|
@ -258,7 +256,7 @@ func engineOptions(config cfg.MachineConfig) *engine.Options {
|
|||
return &o
|
||||
}
|
||||
|
||||
func preCreateHost(config *cfg.MachineConfig) error {
|
||||
func preCreateHost(config *cfg.MachineConfig) {
|
||||
switch config.VMDriver {
|
||||
case "kvm":
|
||||
if viper.GetBool(cfg.ShowDriverDeprecationNotification) {
|
||||
|
@ -282,16 +280,10 @@ To disable this message, run [minikube config set WantShowDriverDeprecationNotif
|
|||
To disable this message, run [minikube config set WantShowDriverDeprecationNotification false]`)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error) {
|
||||
err := preCreateHost(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
preCreateHost(&config)
|
||||
console.OutStyle("starting-vm", "Creating %s VM (CPUs=%d, Memory=%dMB, Disk=%dMB) ...", config.VMDriver, config.CPUs, config.Memory, config.DiskSize)
|
||||
def, err := registry.Driver(config.VMDriver)
|
||||
if err != nil {
|
||||
|
@ -380,6 +372,16 @@ func GetVMHostIP(host *host.Host) (net.IP, error) {
|
|||
return ip, nil
|
||||
case "xhyve", "hyperkit":
|
||||
return net.ParseIP("192.168.64.1"), nil
|
||||
case "vmware":
|
||||
vmIPString, err := host.Driver.GetIP()
|
||||
if err != nil {
|
||||
return []byte{}, errors.Wrap(err, "Error getting VM IP address")
|
||||
}
|
||||
vmIP := net.ParseIP(vmIPString).To4()
|
||||
if vmIP == nil {
|
||||
return []byte{}, errors.Wrap(err, "Error converting VM IP address to IPv4 address")
|
||||
}
|
||||
return net.IPv4(vmIP[0], vmIP[1], vmIP[2], byte(1)), nil
|
||||
default:
|
||||
return []byte{}, errors.New("Error, attempted to get host ip address for unsupported driver")
|
||||
}
|
||||
|
|
|
@ -214,7 +214,11 @@ func TestStopHostError(t *testing.T) {
|
|||
|
||||
func TestStopHost(t *testing.T) {
|
||||
api := tests.NewMockAPI()
|
||||
h, _ := createHost(api, defaultMachineConfig)
|
||||
h, err := createHost(api, defaultMachineConfig)
|
||||
if err != nil {
|
||||
t.Errorf("createHost failed: %v", err)
|
||||
}
|
||||
|
||||
if err := StopHost(api); err != nil {
|
||||
t.Fatal("An error should be thrown when stopping non-existing machine.")
|
||||
}
|
||||
|
@ -225,7 +229,9 @@ func TestStopHost(t *testing.T) {
|
|||
|
||||
func TestDeleteHost(t *testing.T) {
|
||||
api := tests.NewMockAPI()
|
||||
createHost(api, defaultMachineConfig)
|
||||
if _, err := createHost(api, defaultMachineConfig); err != nil {
|
||||
t.Errorf("createHost failed: %v", err)
|
||||
}
|
||||
|
||||
if err := DeleteHost(api); err != nil {
|
||||
t.Fatalf("Unexpected error deleting host: %v", err)
|
||||
|
@ -234,7 +240,10 @@ func TestDeleteHost(t *testing.T) {
|
|||
|
||||
func TestDeleteHostErrorDeletingVM(t *testing.T) {
|
||||
api := tests.NewMockAPI()
|
||||
h, _ := createHost(api, defaultMachineConfig)
|
||||
h, err := createHost(api, defaultMachineConfig)
|
||||
if err != nil {
|
||||
t.Errorf("createHost failed: %v", err)
|
||||
}
|
||||
|
||||
d := &tests.MockDriver{RemoveError: true}
|
||||
|
||||
|
@ -248,7 +257,9 @@ func TestDeleteHostErrorDeletingVM(t *testing.T) {
|
|||
func TestDeleteHostErrorDeletingFiles(t *testing.T) {
|
||||
api := tests.NewMockAPI()
|
||||
api.RemoveError = true
|
||||
createHost(api, defaultMachineConfig)
|
||||
if _, err := createHost(api, defaultMachineConfig); err != nil {
|
||||
t.Errorf("createHost failed: %v", err)
|
||||
}
|
||||
|
||||
if err := DeleteHost(api); err == nil {
|
||||
t.Fatal("Expected error deleting host.")
|
||||
|
@ -270,10 +281,15 @@ func TestGetHostStatus(t *testing.T) {
|
|||
|
||||
checkState(state.None.String())
|
||||
|
||||
createHost(api, defaultMachineConfig)
|
||||
if _, err := createHost(api, defaultMachineConfig); err != nil {
|
||||
t.Errorf("createHost failed: %v", err)
|
||||
}
|
||||
|
||||
checkState(state.Running.String())
|
||||
|
||||
StopHost(api)
|
||||
if err := StopHost(api); err != nil {
|
||||
t.Errorf("StopHost failed: %v", err)
|
||||
}
|
||||
checkState(state.Stopped.String())
|
||||
}
|
||||
|
||||
|
|
|
@ -76,13 +76,13 @@ func ReadConfig() (MinikubeConfig, error) {
|
|||
if os.IsNotExist(err) {
|
||||
return make(map[string]interface{}), nil
|
||||
}
|
||||
return nil, fmt.Errorf("Could not open file %s: %v", constants.ConfigFile, err)
|
||||
return nil, fmt.Errorf("open %s: %v", constants.ConfigFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
m, err := decode(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not decode config %s: %v", constants.ConfigFile, err)
|
||||
return nil, fmt.Errorf("decode %s: %v", constants.ConfigFile, err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
|
|
|
@ -18,7 +18,6 @@ limitations under the License.
|
|||
package console
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
|
@ -65,99 +64,86 @@ func HasStyle(style string) bool {
|
|||
}
|
||||
|
||||
// OutStyle writes a stylized and formatted message to stdout
|
||||
func OutStyle(style, format string, a ...interface{}) error {
|
||||
func OutStyle(style, format string, a ...interface{}) {
|
||||
outStyled, err := applyStyle(style, useColor, format, a...)
|
||||
if err != nil {
|
||||
glog.Errorf("applyStyle(%s): %v", style, err)
|
||||
if oerr := OutLn(format, a...); oerr != nil {
|
||||
glog.Errorf("Out failed: %v", oerr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// escape any outstanding '%' signs so that they don't get interpreted
|
||||
// as a formatting directive down the line
|
||||
outStyled = strings.Replace(outStyled, "%", "%%", -1)
|
||||
|
||||
return Out(outStyled)
|
||||
Out(outStyled)
|
||||
}
|
||||
|
||||
// Out writes a basic formatted string to stdout
|
||||
func Out(format string, a ...interface{}) error {
|
||||
func Out(format string, a ...interface{}) {
|
||||
p := message.NewPrinter(preferredLanguage)
|
||||
if outFile == nil {
|
||||
if err := PrintToConsole(os.Stdout, "(stdout unset)"+format, a...); err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("no out file has been set")
|
||||
glog.Errorf("no output file has been set")
|
||||
return
|
||||
}
|
||||
_, err := p.Fprintf(outFile, format, a...)
|
||||
if err != nil {
|
||||
glog.Errorf("Fprintf failed: %v", err)
|
||||
}
|
||||
return PrintToConsole(outFile, format, a...)
|
||||
}
|
||||
|
||||
// OutLn writes a basic formatted string with a newline to stdout
|
||||
func OutLn(format string, a ...interface{}) error {
|
||||
return Out(format+"\n", a...)
|
||||
func OutLn(format string, a ...interface{}) {
|
||||
Out(format+"\n", a...)
|
||||
}
|
||||
|
||||
// ErrStyle writes a stylized and formatted error message to stderr
|
||||
func ErrStyle(style, format string, a ...interface{}) error {
|
||||
func ErrStyle(style, format string, a ...interface{}) {
|
||||
format, err := applyStyle(style, useColor, format, a...)
|
||||
if err != nil {
|
||||
glog.Errorf("applyStyle(%s): %v", style, err)
|
||||
if oerr := ErrLn(format, a...); oerr != nil {
|
||||
glog.Errorf("Err(%s) failed: %v", format, oerr)
|
||||
}
|
||||
return err
|
||||
ErrLn(format, a...)
|
||||
}
|
||||
|
||||
// escape any outstanding '%' signs so that they don't get interpreted
|
||||
// as a formatting directive down the line
|
||||
format = strings.Replace(format, "%", "%%", -1)
|
||||
|
||||
return Err(format)
|
||||
Err(format)
|
||||
}
|
||||
|
||||
// Err writes a basic formatted string to stderr
|
||||
func Err(format string, a ...interface{}) error {
|
||||
func Err(format string, a ...interface{}) {
|
||||
p := message.NewPrinter(preferredLanguage)
|
||||
if errFile == nil {
|
||||
if err := PrintToConsole(os.Stderr, "(stderr unset)"+format, a...); err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("no error file has been set")
|
||||
glog.Errorf("no error file has been set")
|
||||
return
|
||||
}
|
||||
_, err := p.Fprintf(errFile, format, a...)
|
||||
if err != nil {
|
||||
glog.Errorf("Fprint failed: %v", err)
|
||||
}
|
||||
return PrintToConsole(errFile, format, a...)
|
||||
}
|
||||
|
||||
// PrintToConsole writes a formatted string to the supplied writer
|
||||
func PrintToConsole(file fdWriter, format string, a ...interface{}) error {
|
||||
p := message.NewPrinter(translate.GetPreferredLanguage())
|
||||
format = translate.Translate(format)
|
||||
_, err := p.Fprintf(file, format, a...)
|
||||
return err
|
||||
}
|
||||
|
||||
// ErrLn writes a basic formatted string with a newline to stderr
|
||||
func ErrLn(format string, a ...interface{}) error {
|
||||
return Err(format+"\n", a...)
|
||||
func ErrLn(format string, a ...interface{}) {
|
||||
Err(format+"\n", a...)
|
||||
}
|
||||
|
||||
// Success is a shortcut for writing a styled success message to stdout
|
||||
func Success(format string, a ...interface{}) error {
|
||||
return OutStyle("success", format, a...)
|
||||
func Success(format string, a ...interface{}) {
|
||||
OutStyle("success", format, a...)
|
||||
}
|
||||
|
||||
// Fatal is a shortcut for writing a styled fatal message to stderr
|
||||
func Fatal(format string, a ...interface{}) error {
|
||||
return ErrStyle("fatal", format, a...)
|
||||
func Fatal(format string, a ...interface{}) {
|
||||
ErrStyle("fatal", format, a...)
|
||||
}
|
||||
|
||||
// Warning is a shortcut for writing a styled warning message to stderr
|
||||
func Warning(format string, a ...interface{}) error {
|
||||
return ErrStyle("warning", format, a...)
|
||||
func Warning(format string, a ...interface{}) {
|
||||
ErrStyle("warning", format, a...)
|
||||
}
|
||||
|
||||
// Failure is a shortcut for writing a styled failure message to stderr
|
||||
func Failure(format string, a ...interface{}) error {
|
||||
return ErrStyle("failure", format, a...)
|
||||
func Failure(format string, a ...interface{}) {
|
||||
ErrStyle("failure", format, a...)
|
||||
}
|
||||
|
||||
// SetOutFile configures which writer standard output goes to.
|
||||
|
|
|
@ -72,9 +72,7 @@ func TestOutStyle(t *testing.T) {
|
|||
os.Setenv(OverrideEnv, strconv.FormatBool(override))
|
||||
f := newFakeFile()
|
||||
SetOutFile(f)
|
||||
if err := OutStyle(tc.style, tc.message, tc.params...); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
OutStyle(tc.style, tc.message, tc.params...)
|
||||
got := f.String()
|
||||
want := tc.wantASCII
|
||||
if override {
|
||||
|
@ -113,9 +111,7 @@ func TestOut(t *testing.T) {
|
|||
f := newFakeFile()
|
||||
SetOutFile(f)
|
||||
ErrLn("unrelated message")
|
||||
if err := Out(tc.format, tc.arg); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
Out(tc.format, tc.arg)
|
||||
got := f.String()
|
||||
if got != tc.want {
|
||||
t.Errorf("Out(%s, %s) = %q, want %q", tc.format, tc.arg, got, tc.want)
|
||||
|
@ -128,10 +124,7 @@ func TestErr(t *testing.T) {
|
|||
os.Setenv(OverrideEnv, "0")
|
||||
f := newFakeFile()
|
||||
SetErrFile(f)
|
||||
if err := Err("xyz123 %s\n", "%s%%%d"); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
|
||||
Err("xyz123 %s\n", "%s%%%d")
|
||||
OutLn("unrelated message")
|
||||
got := f.String()
|
||||
want := "xyz123 %s%%%d\n"
|
||||
|
@ -145,9 +138,7 @@ func TestErrStyle(t *testing.T) {
|
|||
os.Setenv(OverrideEnv, "1")
|
||||
f := newFakeFile()
|
||||
SetErrFile(f)
|
||||
if err := ErrStyle("fatal", "error: %s", "%s%%%d"); err != nil {
|
||||
t.Errorf("unexpected error: %q", err)
|
||||
}
|
||||
ErrStyle("fatal", "error: %s", "%s%%%d")
|
||||
got := f.String()
|
||||
want := "💣 error: %s%%%d\n"
|
||||
if got != want {
|
||||
|
|
|
@ -53,11 +53,10 @@ func GetMinipath() string {
|
|||
|
||||
// ArchTag returns the archtag for images
|
||||
func ArchTag(hasTag bool) string {
|
||||
if runtime.GOARCH == "amd64" && hasTag == false {
|
||||
if runtime.GOARCH == "amd64" && !hasTag {
|
||||
return ":"
|
||||
} else {
|
||||
return "-" + runtime.GOARCH + ":"
|
||||
}
|
||||
return "-" + runtime.GOARCH + ":"
|
||||
}
|
||||
|
||||
// SupportedVMDrivers is a list of supported drivers on all platforms. Currently
|
||||
|
|
|
@ -149,7 +149,7 @@ func (f *FakeRunner) Run(cmd string) error {
|
|||
}
|
||||
|
||||
// docker is a fake implementation of docker
|
||||
func (f *FakeRunner) docker(args []string, root bool) (string, error) {
|
||||
func (f *FakeRunner) docker(args []string, _ bool) (string, error) {
|
||||
switch cmd := args[0]; cmd {
|
||||
case "ps":
|
||||
// ps -a --filter="name=apiserver" --format="{{.ID}}"
|
||||
|
@ -194,25 +194,23 @@ func (f *FakeRunner) docker(args []string, root bool) (string, error) {
|
|||
}
|
||||
|
||||
// crio is a fake implementation of crio
|
||||
func (f *FakeRunner) crio(args []string, root bool) (string, error) {
|
||||
switch cmd := args[0]; cmd {
|
||||
case "--version":
|
||||
func (f *FakeRunner) crio(args []string, _ bool) (string, error) {
|
||||
if args[0] == "--version" {
|
||||
return "crio version 1.13.0", nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// containerd is a fake implementation of containerd
|
||||
func (f *FakeRunner) containerd(args []string, root bool) (string, error) {
|
||||
switch cmd := args[0]; cmd {
|
||||
case "--version":
|
||||
func (f *FakeRunner) containerd(args []string, _ bool) (string, error) {
|
||||
if args[0] == "--version" {
|
||||
return "containerd github.com/containerd/containerd v1.2.0 c4446665cb9c30056f4998ed953e6d4ff22c7c39", nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// crictl is a fake implementation of crictl
|
||||
func (f *FakeRunner) crictl(args []string, root bool) (string, error) {
|
||||
func (f *FakeRunner) crictl(args []string, _ bool) (string, error) {
|
||||
switch cmd := args[0]; cmd {
|
||||
case "ps":
|
||||
// crictl ps -a --name=apiserver --state=Running --quiet
|
||||
|
@ -461,7 +459,9 @@ func TestContainerFunctions(t *testing.T) {
|
|||
}
|
||||
|
||||
// Stop the containers and assert that they have disappeared
|
||||
cr.StopContainers(got)
|
||||
if err := cr.StopContainers(got); err != nil {
|
||||
t.Fatalf("stop failed: %v", err)
|
||||
}
|
||||
got, err = cr.ListContainers("apiserver")
|
||||
if err != nil {
|
||||
t.Fatalf("ListContainers: %v", err)
|
||||
|
@ -482,7 +482,9 @@ func TestContainerFunctions(t *testing.T) {
|
|||
}
|
||||
|
||||
// Kill the containers and assert that they have disappeared
|
||||
cr.KillContainers(got)
|
||||
if err := cr.KillContainers(got); err != nil {
|
||||
t.Errorf("KillContainers: %v", err)
|
||||
}
|
||||
got, err = cr.ListContainers("")
|
||||
if err != nil {
|
||||
t.Fatalf("ListContainers: %v", err)
|
||||
|
|
|
@ -19,6 +19,8 @@ limitations under the License.
|
|||
package hyperkit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/pborman/uuid"
|
||||
"k8s.io/minikube/pkg/drivers/hyperkit"
|
||||
|
@ -28,11 +30,13 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: "hyperkit",
|
||||
Builtin: false,
|
||||
ConfigCreator: createHyperkitHost,
|
||||
})
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createHyperkitHost(config cfg.MachineConfig) interface{} {
|
||||
|
|
|
@ -29,11 +29,13 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: "kvm",
|
||||
Builtin: false,
|
||||
ConfigCreator: createKVMHost,
|
||||
})
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// Delete this once the following PR is merged:
|
||||
|
|
|
@ -29,11 +29,13 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: "kvm2",
|
||||
Builtin: false,
|
||||
ConfigCreator: createKVM2Host,
|
||||
})
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register failed: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// Delete this once the following PR is merged:
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
@ -19,6 +17,8 @@ limitations under the License.
|
|||
package none
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"k8s.io/minikube/pkg/drivers/none"
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
|
@ -27,14 +27,16 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: "none",
|
||||
Builtin: true,
|
||||
ConfigCreator: createNoneHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return none.NewDriver(none.Config{})
|
||||
},
|
||||
})
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register failed: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// createNoneHost creates a none Driver from a MachineConfig
|
||||
|
|
|
@ -19,6 +19,8 @@ limitations under the License.
|
|||
package parallels
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
parallels "github.com/Parallels/docker-machine-parallels"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
|
@ -27,7 +29,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
err := registry.Register(registry.DriverDef{
|
||||
Name: "parallels",
|
||||
Builtin: true,
|
||||
ConfigCreator: createParallelsHost,
|
||||
|
@ -35,6 +37,10 @@ func init() {
|
|||
return parallels.NewDriver("", "")
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to register: %v", err))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createParallelsHost(config cfg.MachineConfig) interface{} {
|
||||
|
|
|
@ -17,6 +17,8 @@ limitations under the License.
|
|||
package virtualbox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/machine/drivers/virtualbox"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
|
@ -27,7 +29,7 @@ import (
|
|||
const defaultVirtualboxNicType = "virtio"
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
err := registry.Register(registry.DriverDef{
|
||||
Name: "virtualbox",
|
||||
Builtin: true,
|
||||
ConfigCreator: createVirtualboxHost,
|
||||
|
@ -35,6 +37,9 @@ func init() {
|
|||
return virtualbox.NewDriver("", "")
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createVirtualboxHost(config cfg.MachineConfig) interface{} {
|
||||
|
@ -43,7 +48,7 @@ func createVirtualboxHost(config cfg.MachineConfig) interface{} {
|
|||
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
|
||||
d.Memory = config.Memory
|
||||
d.CPU = config.CPUs
|
||||
d.DiskSize = int(config.DiskSize)
|
||||
d.DiskSize = config.DiskSize
|
||||
d.HostOnlyCIDR = config.HostOnlyCIDR
|
||||
d.NoShare = config.DisableDriverMounts
|
||||
d.NoVTXCheck = config.NoVTXCheck
|
||||
|
|
|
@ -17,6 +17,8 @@ limitations under the License.
|
|||
package vmware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
vmwcfg "github.com/machine-drivers/docker-machine-driver-vmware/pkg/drivers/vmware/config"
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
|
@ -24,11 +26,14 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
err := registry.Register(registry.DriverDef{
|
||||
Name: "vmware",
|
||||
Builtin: false,
|
||||
ConfigCreator: createVMwareHost,
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createVMwareHost(config cfg.MachineConfig) interface{} {
|
||||
|
|
|
@ -19,6 +19,8 @@ limitations under the License.
|
|||
package vmwarefusion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/machine/drivers/vmwarefusion"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
|
@ -27,14 +29,16 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: "vmwarefusion",
|
||||
Builtin: true,
|
||||
ConfigCreator: createVMwareFusionHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return vmwarefusion.NewDriver("", "")
|
||||
},
|
||||
})
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createVMwareFusionHost(config cfg.MachineConfig) interface{} {
|
||||
|
|
|
@ -34,7 +34,7 @@ https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#xhyve-driver
|
|||
`
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: "xhyve",
|
||||
Builtin: false,
|
||||
ConfigCreator: createXhyveHost,
|
||||
|
@ -43,7 +43,9 @@ func init() {
|
|||
os.Exit(1)
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
type xhyveDriver struct {
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
)
|
||||
|
||||
// rootCauseRe is a regular expression that matches known failure root causes
|
||||
var rootCauseRe = regexp.MustCompile(`^error: |eviction manager: pods.* evicted|unknown flag: --|forbidden.*no providers available|eviction manager:.*evicted`)
|
||||
var rootCauseRe = regexp.MustCompile(`^error: |eviction manager: pods.* evicted|unknown flag: --|forbidden.*no providers available|eviction manager:.*evicted|tls: bad certificate`)
|
||||
|
||||
// ignoreRe is a regular expression that matches spurious errors to not surface
|
||||
var ignoreCauseRe = regexp.MustCompile("error: no objects passed to apply")
|
||||
|
|
|
@ -34,6 +34,7 @@ func TestIsProblem(t *testing.T) {
|
|||
{"apiserver-admission #3524", true, "error: unknown flag: --GenericServerRunOptions.AdmissionControl"},
|
||||
{"no-providers-available #3818", true, ` kubelet.go:1662] Failed creating a mirror pod for "kube-apiserver-minikube_kube-system(c7d572aebd3d33b17fa78ae6395b6d0a)": pods "kube-apiserver-minikube" is forbidden: no providers available to validate pod request`},
|
||||
{"no-objects-passed-to-apply #4010", false, "error: no objects passed to apply"},
|
||||
{"bad-certificate #4251", true, "log.go:172] http: TLS handshake error from 127.0.0.1:49200: remote error: tls: bad certificate"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
|
|
@ -133,12 +133,8 @@ func CacheAndLoadImages(images []string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmdRunner, err := bootstrapper.NewSSHRunner(client), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return LoadImages(cmdRunner, images, constants.ImageCacheDir)
|
||||
runner := bootstrapper.NewSSHRunner(client)
|
||||
return LoadImages(runner, images, constants.ImageCacheDir)
|
||||
}
|
||||
|
||||
// # ParseReference cannot have a : in the directory path
|
||||
|
@ -276,7 +272,7 @@ func cleanImageCacheDir() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func getDstPath(image, dst string) (string, error) {
|
||||
func getDstPath(dst string) (string, error) {
|
||||
if runtime.GOOS == "windows" && hasWindowsDriveLetter(dst) {
|
||||
// ParseReference does not support a Windows drive letter.
|
||||
// Therefore, will replace the drive letter to a volume name.
|
||||
|
@ -302,7 +298,9 @@ func CacheImage(image, dst string) error {
|
|||
defer func() {
|
||||
log.SetOutput(os.Stdout)
|
||||
var buf bytes.Buffer
|
||||
io.Copy(&buf, r)
|
||||
if _, err := io.Copy(&buf, r); err != nil {
|
||||
glog.Errorf("output copy failed: %v", err)
|
||||
}
|
||||
glog.Infof(buf.String())
|
||||
}()
|
||||
|
||||
|
@ -311,7 +309,7 @@ func CacheImage(image, dst string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
dstPath, err := getDstPath(image, dst)
|
||||
dstPath, err := getDstPath(dst)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting destination path")
|
||||
}
|
||||
|
|
|
@ -63,7 +63,9 @@ func MaybePrintUpdateText(output io.Writer, url string, lastUpdatePath string) {
|
|||
return
|
||||
}
|
||||
if localVersion.Compare(latestVersion) < 0 {
|
||||
writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC())
|
||||
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC()); err != nil {
|
||||
glog.Errorf("write time failed: %v", err)
|
||||
}
|
||||
fmt.Fprintf(output, `There is a newer version of minikube available (%s%s). Download it here:
|
||||
%s%s
|
||||
|
||||
|
|
|
@ -54,13 +54,19 @@ func TestShouldCheckURL(t *testing.T) {
|
|||
|
||||
// test that update notifications get triggered if it has been longer than 24 hours
|
||||
viper.Set(config.ReminderWaitPeriodInHours, 24)
|
||||
writeTimeToFile(lastUpdateCheckFilePath, time.Time{}) //time.Time{} returns time -> January 1, year 1, 00:00:00.000000000 UTC.
|
||||
|
||||
//time.Time{} returns time -> January 1, year 1, 00:00:00.000000000 UTC.
|
||||
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Time{}); err != nil {
|
||||
t.Errorf("write failed: %v", err)
|
||||
}
|
||||
if !shouldCheckURLVersion(lastUpdateCheckFilePath) {
|
||||
t.Fatalf("shouldCheckURLVersion returned false even though longer than 24 hours since last update")
|
||||
}
|
||||
|
||||
// test that update notifications do not get triggered if it has been less than 24 hours
|
||||
writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC())
|
||||
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC()); err != nil {
|
||||
t.Errorf("write failed: %v", err)
|
||||
}
|
||||
if shouldCheckURLVersion(lastUpdateCheckFilePath) {
|
||||
t.Fatalf("shouldCheckURLVersion returned true even though less than 24 hours since last update")
|
||||
}
|
||||
|
@ -78,7 +84,11 @@ func (h *URLHandlerCorrect) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
fmt.Fprintf(w, string(b))
|
||||
_, err = fmt.Fprint(w, string(b))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetLatestVersionFromURLCorrect(t *testing.T) {
|
||||
|
|
|
@ -25,6 +25,12 @@ func re(s string) *regexp.Regexp {
|
|||
|
||||
// vmProblems are VM related problems
|
||||
var vmProblems = map[string]match{
|
||||
"HYPERKIT_NO_IP": {
|
||||
Regexp: re(`IP address never found in dhcp leases file Temporary Error: Could not find an IP address for`),
|
||||
Advice: "Install the latest minikube hyperkit driver, and run 'minikube delete'",
|
||||
URL: "https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperkit-driver",
|
||||
Issues: []int{1926, 4206},
|
||||
},
|
||||
"VBOX_NOT_FOUND": {
|
||||
Regexp: re(`VBoxManage not found. Make sure VirtualBox is installed and VBoxManage is in the path`),
|
||||
Advice: "Install VirtualBox, ensure that VBoxManage is executable and in path, or select an alternative value for --vm-driver",
|
||||
|
@ -67,7 +73,7 @@ var vmProblems = map[string]match{
|
|||
"VBOX_HOST_ADAPTER": {
|
||||
Regexp: re(`The host-only adapter we just created is not visible`),
|
||||
Advice: "Reboot to complete VirtualBox installation, and verify that VirtualBox is not blocked by your system",
|
||||
Issues: []int{3614},
|
||||
Issues: []int{3614, 4222},
|
||||
URL: "https://stackoverflow.com/questions/52277019/how-to-fix-vm-issue-with-minikube-start",
|
||||
},
|
||||
"VBOX_KERNEL_MODULE_NOT_LOADED": {
|
||||
|
@ -80,10 +86,16 @@ var vmProblems = map[string]match{
|
|||
Advice: "Please install the minikube kvm2 VM driver, or select an alternative --vm-driver",
|
||||
URL: "https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#kvm2-driver",
|
||||
},
|
||||
"KVM2_NO_IP": {
|
||||
"KVM2_RESTART_NO_IP": {
|
||||
Regexp: re(`Error starting stopped host: Machine didn't return an IP after 120 seconds`),
|
||||
Advice: "The KVM driver is unable to resurrect this old VM. Please run `minikube delete` to delete it and try again.",
|
||||
Issues: []int{3901, 3566, 3434},
|
||||
Issues: []int{3901, 3434},
|
||||
},
|
||||
"KVM2_START_NO_IP": {
|
||||
Regexp: re(`Error in driver during machine creation: Machine didn't return an IP after 120 seconds`),
|
||||
Advice: "The KVM driver is not providing an IP address to the VM. Try checking your libvirt configuration and/or opening an issue",
|
||||
URL: "https://fedoraproject.org/wiki/How_to_debug_Virtualization_problems#Networking",
|
||||
Issues: []int{4249, 3566},
|
||||
},
|
||||
"KVM2_NETWORK_DEFINE_XML": {
|
||||
Regexp: re(`not supported by the connection driver: virNetworkDefineXML`),
|
||||
|
@ -91,10 +103,11 @@ var vmProblems = map[string]match{
|
|||
URL: "https://forums.gentoo.org/viewtopic-t-981692-start-0.html",
|
||||
Issues: []int{4195},
|
||||
},
|
||||
"VM_DOES_NOT_EXIST": {
|
||||
Regexp: re(`Error getting state for host: machine does not exist`),
|
||||
Advice: "Your system no longer knows about the VM previously created by minikube. Run 'minikube delete' to reset your local state.",
|
||||
Issues: []int{3864},
|
||||
"KVM_UNAVAILABLE": {
|
||||
Regexp: re(`invalid argument: could not find capabilities for domaintype=kvm`),
|
||||
Advice: "Your host does not support KVM virtualization. Ensure that qemu-kvm is installed, and run 'virt-host-validate' to debug the problem",
|
||||
URL: "http://mikko.repolainen.fi/documents/virtualization-with-kvm",
|
||||
Issues: []int{2991},
|
||||
},
|
||||
"VM_BOOT_FAILED_HYPERV_ENABLED": {
|
||||
Regexp: re(`VirtualBox won't boot a 64bits VM when Hyper-V is activated`),
|
||||
|
@ -106,6 +119,21 @@ var vmProblems = map[string]match{
|
|||
Advice: "Configure an external network switch following the official documentation, then add `--hyperv-virtual-switch=<switch-name>` to `minikube start`",
|
||||
URL: "https://docs.docker.com/machine/drivers/hyper-v/",
|
||||
},
|
||||
"HOST_CIDR_CONFLICT": {
|
||||
Regexp: re(`host-only cidr conflicts with the network address of a host interface`),
|
||||
Advice: "Specify an alternate --host-only-cidr value, such as 172.16.0.1/24",
|
||||
Issues: []int{3594},
|
||||
},
|
||||
"OOM_KILL_SSH": {
|
||||
Regexp: re(`Process exited with status 137 from signal KILL`),
|
||||
Advice: "Disable dynamic memory in your VM manager, or pass in a larger --memory value",
|
||||
Issues: []int{1766},
|
||||
},
|
||||
"OOM_KILL_SCP": {
|
||||
Regexp: re(`An existing connection was forcibly closed by the remote host`),
|
||||
Advice: "Disable dynamic memory in your VM manager, or pass in a larger --memory value",
|
||||
Issues: []int{1766},
|
||||
},
|
||||
}
|
||||
|
||||
// proxyDoc is the URL to proxy documentation
|
||||
|
@ -132,10 +160,10 @@ var netProblems = map[string]match{
|
|||
Issues: []int{3846},
|
||||
},
|
||||
"DOWNLOAD_TLS_OVERSIZED": {
|
||||
Regexp: re(`failed to download.*tls: oversized record received with length`),
|
||||
Advice: "A firewall is interfering with minikube's ability to make outgoing HTTPS requests. You may need to configure minikube to use a proxy.",
|
||||
Regexp: re(`tls: oversized record received with length`),
|
||||
Advice: "A firewall is interfering with minikube's ability to make outgoing HTTPS requests. You may need to change the value of the HTTPS_PROXY environment variable.",
|
||||
URL: proxyDoc,
|
||||
Issues: []int{3857, 3759},
|
||||
Issues: []int{3857, 3759, 4252},
|
||||
},
|
||||
"ISO_DOWNLOAD_FAILED": {
|
||||
Regexp: re(`iso: failed to download`),
|
||||
|
@ -181,6 +209,11 @@ var deployProblems = map[string]match{
|
|||
Regexp: re(`strconv.ParseUint: parsing "": invalid syntax`),
|
||||
Advice: "Check that your --kubernetes-version has a leading 'v'. For example: 'v1.1.14'",
|
||||
},
|
||||
"APISERVER_TIMEOUT": {
|
||||
Regexp: re(`wait: waiting for component=kube-apiserver: timed out waiting for the condition`),
|
||||
Advice: "Run 'minikube delete'. If the problem persists, check your proxy or firewall configuration",
|
||||
Issues: []int{4202, 3836, 4221},
|
||||
},
|
||||
}
|
||||
|
||||
// osProblems are operating-system specific issues
|
||||
|
@ -190,6 +223,12 @@ var osProblems = map[string]match{
|
|||
Advice: "Run minikube from the C: drive.",
|
||||
Issues: []int{1574},
|
||||
},
|
||||
"SYSTEMCTL_EXIT_1": {
|
||||
Regexp: re(`Failed to enable container runtime: .*sudo systemctl start docker: exit status 1`),
|
||||
Advice: "If using the none driver, ensure that systemctl is installed",
|
||||
URL: "https://github.com/kubernetes/minikube/blob/master/docs/vmdriver-none.md",
|
||||
Issues: []int{2704},
|
||||
},
|
||||
}
|
||||
|
||||
// stateProblems are issues relating to local state
|
||||
|
|
|
@ -29,6 +29,8 @@ func TestFromError(t *testing.T) {
|
|||
err string
|
||||
}{
|
||||
{0, "", "", "this is just a lame error message with no matches."},
|
||||
{2991, "", "KVM_UNAVAILABLE", "Unable to start VM: create: Error creating machine: Error in driver during machine creation: creating domain: Error defining domain xml:\n\n: virError(Code=8, Domain=44, Message='invalid argument: could not find capabilities for domaintype=kvm ')"},
|
||||
{3594, "", "HOST_CIDR_CONFLICT", "Error starting host: Error starting stopped host: Error setting up host only network on machine start: host-only cidr conflicts with the network address of a host interface."},
|
||||
{3614, "", "VBOX_HOST_ADAPTER", "Error starting host: Error starting stopped host: Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue"},
|
||||
{3784, "", "VBOX_NOT_FOUND", "create: precreate: VBoxManage not found. Make sure VirtualBox is installed and VBoxManage is in the path"},
|
||||
{3849, "", "IP_NOT_FOUND", "bootstrapper: Error creating new ssh host from driver: Error getting ssh host name for driver: IP not found"},
|
||||
|
@ -38,6 +40,9 @@ VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component MachineWrap,
|
|||
{3922, "", "ISO_DOWNLOAD_FAILED", `unable to cache ISO: https://storage.googleapis.com/minikube/iso/minikube-v0.35.0.iso: failed to download: failed to download to temp file: download failed: 5 error(s) occurred:
|
||||
* Temporary download error: Get https://storage.googleapis.com/minikube/iso/minikube-v0.35.0.iso: dial tcp 216.58.207.144:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.`},
|
||||
{4107, "darwin", "VBOX_BLOCKED", "Result Code: NS_ERROR_FAILURE (0x80004005)"},
|
||||
{4202, "", "APISERVER_TIMEOUT", "Error restarting cluster: wait: waiting for component=kube-apiserver: timed out waiting for the condition"},
|
||||
{4252, "", "DOWNLOAD_TLS_OVERSIZED", "Failed to update cluster: downloading binaries: downloading kubeadm: Error downloading kubeadm v1.14.1: failed to download: failed to download to temp file: download failed: 5 error(s) occurred:\n\nTemporary download error: Get https://storage.googleapis.com/kubernetes-release/release/v1.14.1/bin/linux/amd64/kubeadm: proxyconnect tcp: tls: oversized record received with length 20527"},
|
||||
{4222, "", "VBOX_HOST_ADAPTER", "Unable to start VM: create: creating: Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.want, func(t *testing.T) {
|
||||
|
|
|
@ -29,11 +29,11 @@ import (
|
|||
"github.com/pkg/browser"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/minikube/pkg/minikube/cluster"
|
||||
|
@ -45,7 +45,7 @@ import (
|
|||
|
||||
// K8sClient represents a kubernetes client
|
||||
type K8sClient interface {
|
||||
GetCoreClient() (corev1.CoreV1Interface, error)
|
||||
GetCoreClient() (typed_core.CoreV1Interface, error)
|
||||
GetClientset(timeout time.Duration) (*kubernetes.Clientset, error)
|
||||
}
|
||||
|
||||
|
@ -60,12 +60,12 @@ func init() {
|
|||
}
|
||||
|
||||
// GetCoreClient returns a core client
|
||||
func (k *K8sClientGetter) GetCoreClient() (corev1.CoreV1Interface, error) {
|
||||
func (k *K8sClientGetter) GetCoreClient() (typed_core.CoreV1Interface, error) {
|
||||
client, err := k.GetClientset(constants.DefaultK8sClientTimeout)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting clientset")
|
||||
}
|
||||
return client.Core(), nil
|
||||
return client.CoreV1(), nil
|
||||
}
|
||||
|
||||
// GetClientset returns a clientset
|
||||
|
@ -81,12 +81,12 @@ func (*K8sClientGetter) GetClientset(timeout time.Duration) (*kubernetes.Clients
|
|||
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
|
||||
clientConfig, err := kubeConfig.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating kubeConfig: %v", err)
|
||||
return nil, fmt.Errorf("kubeConfig: %v", err)
|
||||
}
|
||||
clientConfig.Timeout = timeout
|
||||
client, err := kubernetes.NewForConfig(clientConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()")
|
||||
return nil, errors.Wrap(err, "client from config")
|
||||
}
|
||||
|
||||
return client, nil
|
||||
|
@ -122,7 +122,7 @@ func GetServiceURLs(api libmachine.API, namespace string, t *template.Template)
|
|||
|
||||
serviceInterface := client.Services(namespace)
|
||||
|
||||
svcs, err := serviceInterface.List(metav1.ListOptions{})
|
||||
svcs, err := serviceInterface.List(meta.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -160,24 +160,24 @@ func GetServiceURLsForService(api libmachine.API, namespace, service string, t *
|
|||
return printURLsForService(client, ip, service, namespace, t)
|
||||
}
|
||||
|
||||
func printURLsForService(c corev1.CoreV1Interface, ip, service, namespace string, t *template.Template) ([]string, error) {
|
||||
func printURLsForService(c typed_core.CoreV1Interface, ip, service, namespace string, t *template.Template) ([]string, error) {
|
||||
if t == nil {
|
||||
return nil, errors.New("Error, attempted to generate service url with nil --format template")
|
||||
}
|
||||
|
||||
s := c.Services(namespace)
|
||||
svc, err := s.Get(service, metav1.GetOptions{})
|
||||
svc, err := s.Get(service, meta.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "service '%s' could not be found running", service)
|
||||
}
|
||||
|
||||
e := c.Endpoints(namespace)
|
||||
endpoints, err := e.Get(service, metav1.GetOptions{})
|
||||
endpoints, err := e.Get(service, meta.GetOptions{})
|
||||
m := make(map[int32]string)
|
||||
if err == nil && endpoints != nil && len(endpoints.Subsets) > 0 {
|
||||
for _, ept := range endpoints.Subsets {
|
||||
for _, p := range ept.Ports {
|
||||
m[int32(p.Port)] = p.Name
|
||||
m[p.Port] = p.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ func CheckService(namespace string, service string) error {
|
|||
return errors.Wrap(err, "Error getting kubernetes client")
|
||||
}
|
||||
|
||||
svc, err := client.Services(namespace).Get(service, metav1.GetOptions{})
|
||||
svc, err := client.Services(namespace).Get(service, meta.GetOptions{})
|
||||
if err != nil {
|
||||
return &util.RetriableError{
|
||||
Err: errors.Wrapf(err, "Error getting service %s", service),
|
||||
|
@ -258,30 +258,28 @@ func WaitAndMaybeOpenService(api libmachine.API, namespace string, service strin
|
|||
console.OutLn(urlString)
|
||||
} else {
|
||||
console.OutStyle("celebrate", "Opening kubernetes service %s/%s in default browser...", namespace, service)
|
||||
browser.OpenURL(urlString)
|
||||
if err := browser.OpenURL(urlString); err != nil {
|
||||
console.Err("browser failed to open url: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetServiceListByLabel returns a ServiceList by label
|
||||
func GetServiceListByLabel(namespace string, key string, value string) (*v1.ServiceList, error) {
|
||||
func GetServiceListByLabel(namespace string, key string, value string) (*core.ServiceList, error) {
|
||||
client, err := K8s.GetCoreClient()
|
||||
if err != nil {
|
||||
return &v1.ServiceList{}, &util.RetriableError{Err: err}
|
||||
return &core.ServiceList{}, &util.RetriableError{Err: err}
|
||||
}
|
||||
services := client.Services(namespace)
|
||||
if err != nil {
|
||||
return &v1.ServiceList{}, &util.RetriableError{Err: err}
|
||||
}
|
||||
return getServiceListFromServicesByLabel(services, key, value)
|
||||
return getServiceListFromServicesByLabel(client.Services(namespace), key, value)
|
||||
}
|
||||
|
||||
func getServiceListFromServicesByLabel(services corev1.ServiceInterface, key string, value string) (*v1.ServiceList, error) {
|
||||
func getServiceListFromServicesByLabel(services typed_core.ServiceInterface, key string, value string) (*core.ServiceList, error) {
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{key: value}))
|
||||
serviceList, err := services.List(metav1.ListOptions{LabelSelector: selector.String()})
|
||||
serviceList, err := services.List(meta.ListOptions{LabelSelector: selector.String()})
|
||||
if err != nil {
|
||||
return &v1.ServiceList{}, &util.RetriableError{Err: err}
|
||||
return &core.ServiceList{}, &util.RetriableError{Err: err}
|
||||
}
|
||||
|
||||
return serviceList, nil
|
||||
|
@ -294,11 +292,7 @@ func CreateSecret(namespace, name string, dataValues map[string]string, labels m
|
|||
return &util.RetriableError{Err: err}
|
||||
}
|
||||
secrets := client.Secrets(namespace)
|
||||
if err != nil {
|
||||
return &util.RetriableError{Err: err}
|
||||
}
|
||||
|
||||
secret, _ := secrets.Get(name, metav1.GetOptions{})
|
||||
secret, _ := secrets.Get(name, meta.GetOptions{})
|
||||
|
||||
// Delete existing secret
|
||||
if len(secret.Name) > 0 {
|
||||
|
@ -315,13 +309,13 @@ func CreateSecret(namespace, name string, dataValues map[string]string, labels m
|
|||
}
|
||||
|
||||
// Create Secret
|
||||
secretObj := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
secretObj := &core.Secret{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
},
|
||||
Data: data,
|
||||
Type: v1.SecretTypeOpaque,
|
||||
Type: core.SecretTypeOpaque,
|
||||
}
|
||||
|
||||
_, err = secrets.Create(secretObj)
|
||||
|
@ -340,11 +334,7 @@ func DeleteSecret(namespace, name string) error {
|
|||
}
|
||||
|
||||
secrets := client.Secrets(namespace)
|
||||
if err != nil {
|
||||
return &util.RetriableError{Err: err}
|
||||
}
|
||||
|
||||
err = secrets.Delete(name, &metav1.DeleteOptions{})
|
||||
err = secrets.Delete(name, &meta.DeleteOptions{})
|
||||
if err != nil {
|
||||
return &util.RetriableError{Err: err}
|
||||
}
|
||||
|
|
|
@ -22,26 +22,27 @@ import (
|
|||
"testing"
|
||||
"text/template"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine"
|
||||
"github.com/docker/machine/libmachine/host"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/kubernetes/typed/core/v1/fake"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/tests"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MockClientGetter struct {
|
||||
servicesMap map[string]corev1.ServiceInterface
|
||||
endpointsMap map[string]corev1.EndpointsInterface
|
||||
servicesMap map[string]typed_core.ServiceInterface
|
||||
endpointsMap map[string]typed_core.EndpointsInterface
|
||||
}
|
||||
|
||||
func (m *MockClientGetter) GetCoreClient() (corev1.CoreV1Interface, error) {
|
||||
func (m *MockClientGetter) GetCoreClient() (typed_core.CoreV1Interface, error) {
|
||||
return &MockCoreClient{
|
||||
servicesMap: m.servicesMap,
|
||||
endpointsMap: m.endpointsMap,
|
||||
|
@ -54,24 +55,24 @@ func (m *MockClientGetter) GetClientset(timeout time.Duration) (*kubernetes.Clie
|
|||
|
||||
type MockCoreClient struct {
|
||||
fake.FakeCoreV1
|
||||
servicesMap map[string]corev1.ServiceInterface
|
||||
endpointsMap map[string]corev1.EndpointsInterface
|
||||
servicesMap map[string]typed_core.ServiceInterface
|
||||
endpointsMap map[string]typed_core.EndpointsInterface
|
||||
}
|
||||
|
||||
var serviceNamespaces = map[string]corev1.ServiceInterface{
|
||||
var serviceNamespaces = map[string]typed_core.ServiceInterface{
|
||||
"default": defaultNamespaceServiceInterface,
|
||||
}
|
||||
|
||||
var defaultNamespaceServiceInterface = &MockServiceInterface{
|
||||
ServiceList: &v1.ServiceList{
|
||||
Items: []v1.Service{
|
||||
ServiceList: &core.ServiceList{
|
||||
Items: []core.Service{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "mock-dashboard",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Ports: []v1.ServicePort{
|
||||
Spec: core.ServiceSpec{
|
||||
Ports: []core.ServicePort{
|
||||
{
|
||||
NodePort: int32(1111),
|
||||
TargetPort: intstr.IntOrString{
|
||||
|
@ -88,44 +89,44 @@ var defaultNamespaceServiceInterface = &MockServiceInterface{
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "mock-dashboard-no-ports",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Ports: []v1.ServicePort{},
|
||||
Spec: core.ServiceSpec{
|
||||
Ports: []core.ServicePort{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var endpointNamespaces = map[string]corev1.EndpointsInterface{
|
||||
var endpointNamespaces = map[string]typed_core.EndpointsInterface{
|
||||
"default": defaultNamespaceEndpointInterface,
|
||||
}
|
||||
|
||||
var defaultNamespaceEndpointInterface = &MockEndpointsInterface{}
|
||||
|
||||
func (m *MockCoreClient) Endpoints(namespace string) corev1.EndpointsInterface {
|
||||
func (m *MockCoreClient) Endpoints(namespace string) typed_core.EndpointsInterface {
|
||||
return m.endpointsMap[namespace]
|
||||
}
|
||||
|
||||
func (m *MockCoreClient) Services(namespace string) corev1.ServiceInterface {
|
||||
func (m *MockCoreClient) Services(namespace string) typed_core.ServiceInterface {
|
||||
return m.servicesMap[namespace]
|
||||
}
|
||||
|
||||
type MockEndpointsInterface struct {
|
||||
fake.FakeEndpoints
|
||||
Endpoints *v1.Endpoints
|
||||
Endpoints *core.Endpoints
|
||||
}
|
||||
|
||||
var endpointMap = map[string]*v1.Endpoints{
|
||||
var endpointMap = map[string]*core.Endpoints{
|
||||
"no-subsets": {},
|
||||
"not-ready": {
|
||||
Subsets: []v1.EndpointSubset{
|
||||
Subsets: []core.EndpointSubset{
|
||||
{
|
||||
Addresses: []v1.EndpointAddress{},
|
||||
NotReadyAddresses: []v1.EndpointAddress{
|
||||
Addresses: []core.EndpointAddress{},
|
||||
NotReadyAddresses: []core.EndpointAddress{
|
||||
{IP: "1.1.1.1"},
|
||||
{IP: "2.2.2.2"},
|
||||
},
|
||||
|
@ -133,21 +134,21 @@ var endpointMap = map[string]*v1.Endpoints{
|
|||
},
|
||||
},
|
||||
"one-ready": {
|
||||
Subsets: []v1.EndpointSubset{
|
||||
Subsets: []core.EndpointSubset{
|
||||
{
|
||||
Addresses: []v1.EndpointAddress{
|
||||
Addresses: []core.EndpointAddress{
|
||||
{IP: "1.1.1.1"},
|
||||
},
|
||||
NotReadyAddresses: []v1.EndpointAddress{
|
||||
NotReadyAddresses: []core.EndpointAddress{
|
||||
{IP: "2.2.2.2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"mock-dashboard": {
|
||||
Subsets: []v1.EndpointSubset{
|
||||
Subsets: []core.EndpointSubset{
|
||||
{
|
||||
Ports: []v1.EndpointPort{
|
||||
Ports: []core.EndpointPort{
|
||||
{
|
||||
Name: "port1",
|
||||
Port: int32(11111),
|
||||
|
@ -162,7 +163,7 @@ var endpointMap = map[string]*v1.Endpoints{
|
|||
},
|
||||
}
|
||||
|
||||
func (e MockEndpointsInterface) Get(name string, _ metav1.GetOptions) (*v1.Endpoints, error) {
|
||||
func (e MockEndpointsInterface) Get(name string, _ meta.GetOptions) (*core.Endpoints, error) {
|
||||
endpoint, ok := endpointMap[name]
|
||||
if !ok {
|
||||
return nil, errors.New("Endpoint not found")
|
||||
|
@ -172,12 +173,12 @@ func (e MockEndpointsInterface) Get(name string, _ metav1.GetOptions) (*v1.Endpo
|
|||
|
||||
type MockServiceInterface struct {
|
||||
fake.FakeServices
|
||||
ServiceList *v1.ServiceList
|
||||
ServiceList *core.ServiceList
|
||||
}
|
||||
|
||||
func (s MockServiceInterface) List(opts metav1.ListOptions) (*v1.ServiceList, error) {
|
||||
serviceList := &v1.ServiceList{
|
||||
Items: []v1.Service{},
|
||||
func (s MockServiceInterface) List(opts meta.ListOptions) (*core.ServiceList, error) {
|
||||
serviceList := &core.ServiceList{
|
||||
Items: []core.Service{},
|
||||
}
|
||||
if opts.LabelSelector != "" {
|
||||
keyValArr := strings.Split(opts.LabelSelector, "=")
|
||||
|
@ -194,7 +195,7 @@ func (s MockServiceInterface) List(opts metav1.ListOptions) (*v1.ServiceList, er
|
|||
return s.ServiceList, nil
|
||||
}
|
||||
|
||||
func (s MockServiceInterface) Get(name string, _ metav1.GetOptions) (*v1.Service, error) {
|
||||
func (s MockServiceInterface) Get(name string, _ meta.GetOptions) (*core.Service, error) {
|
||||
for _, svc := range s.ServiceList.Items {
|
||||
if svc.ObjectMeta.Name == name {
|
||||
return &svc, nil
|
||||
|
@ -205,10 +206,10 @@ func (s MockServiceInterface) Get(name string, _ metav1.GetOptions) (*v1.Service
|
|||
}
|
||||
|
||||
func TestGetServiceListFromServicesByLabel(t *testing.T) {
|
||||
serviceList := &v1.ServiceList{
|
||||
Items: []v1.Service{
|
||||
serviceList := &core.ServiceList{
|
||||
Items: []core.Service{
|
||||
{
|
||||
Spec: v1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
|
|
|
@ -44,10 +44,10 @@ func TestNewSSHClient(t *testing.T) {
|
|||
|
||||
cmd := "foo"
|
||||
sess, err := c.NewSession()
|
||||
defer sess.Close()
|
||||
if err != nil {
|
||||
t.Fatal("Error creating new session for ssh client")
|
||||
}
|
||||
defer sess.Close()
|
||||
|
||||
if err := sess.Run(cmd); err != nil {
|
||||
t.Fatalf("Error running command: %s", cmd)
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/api/storage/v1"
|
||||
v1 "k8s.io/api/storage/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
|
@ -31,7 +31,7 @@ func annotateDefaultStorageClass(client *kubernetes.Clientset, class *v1.Storage
|
|||
isDefault := strconv.FormatBool(enable)
|
||||
|
||||
metav1.SetMetaDataAnnotation(&class.ObjectMeta, "storageclass.beta.kubernetes.io/is-default-class", isDefault)
|
||||
_, err := client.Storage().StorageClasses().Update(class)
|
||||
_, err := client.StorageV1().StorageClasses().Update(class)
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ func DisableDefaultStorageClass(class string) error {
|
|||
return errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()")
|
||||
}
|
||||
|
||||
sc, err := client.Storage().StorageClasses().Get(class, metav1.GetOptions{})
|
||||
sc, err := client.StorageV1().StorageClasses().Get(class, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Error getting storage class %s", class)
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ func SetDefaultStorageClass(name string) error {
|
|||
return errors.Wrap(err, "Error creating new client from kubeConfig.ClientConfig()")
|
||||
}
|
||||
|
||||
scList, err := client.Storage().StorageClasses().List(metav1.ListOptions{})
|
||||
scList, err := client.StorageV1().StorageClasses().List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error listing StorageClasses")
|
||||
}
|
||||
|
|
|
@ -110,12 +110,16 @@ func (s *SSHServer) Start() (int, error) {
|
|||
glog.Infoln("Got Req: ", req.Type)
|
||||
// Store anything that comes in over stdin.
|
||||
go func() {
|
||||
io.Copy(s.Transfers, channel)
|
||||
if _, err := io.Copy(s.Transfers, channel); err != nil {
|
||||
panic(fmt.Sprintf("copy failed: %v", err))
|
||||
}
|
||||
channel.Close()
|
||||
}()
|
||||
switch req.Type {
|
||||
case "exec":
|
||||
req.Reply(true, nil)
|
||||
if err := req.Reply(true, nil); err != nil {
|
||||
panic(fmt.Sprintf("reply failed: %v", err))
|
||||
}
|
||||
|
||||
// Note: string(req.Payload) adds additional characters to start of input.
|
||||
var cmd execRequest
|
||||
|
@ -127,14 +131,26 @@ func (s *SSHServer) Start() (int, error) {
|
|||
|
||||
// Write specified command output as mocked ssh output
|
||||
if val, err := s.GetCommandToOutput(cmd.Command); err == nil {
|
||||
channel.Write([]byte(val))
|
||||
if _, err := channel.Write([]byte(val)); err != nil {
|
||||
glog.Errorf("Write failed: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if _, err := channel.SendRequest("exit-status", false, []byte{0, 0, 0, 0}); err != nil {
|
||||
glog.Errorf("SendRequest failed: %v", err)
|
||||
return
|
||||
}
|
||||
channel.SendRequest("exit-status", false, []byte{0, 0, 0, 0})
|
||||
|
||||
case "pty-req":
|
||||
req.Reply(true, nil)
|
||||
if err := req.Reply(true, nil); err != nil {
|
||||
glog.Errorf("Reply failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
channel.SendRequest("exit-status", false, []byte{0, 0, 0, 0})
|
||||
if _, err := channel.SendRequest("exit-status", false, []byte{0, 0, 0, 0}); err != nil {
|
||||
glog.Errorf("SendRequest failed: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8s_types "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
|
@ -39,26 +39,22 @@ type patchConverter interface {
|
|||
|
||||
//loadBalancerEmulator is the main struct for emulating the loadbalancer behavior. it sets the ingress to the cluster IP
|
||||
type loadBalancerEmulator struct {
|
||||
coreV1Client v1.CoreV1Interface
|
||||
coreV1Client typed_core.CoreV1Interface
|
||||
requestSender requestSender
|
||||
patchConverter patchConverter
|
||||
}
|
||||
|
||||
func (l *loadBalancerEmulator) PatchServices() ([]string, error) {
|
||||
return l.applyOnLBServices(func(restClient rest.Interface, svc core_v1.Service) ([]byte, error) {
|
||||
return l.updateService(restClient, svc)
|
||||
})
|
||||
return l.applyOnLBServices(l.updateService)
|
||||
}
|
||||
|
||||
func (l *loadBalancerEmulator) Cleanup() ([]string, error) {
|
||||
return l.applyOnLBServices(func(restClient rest.Interface, svc core_v1.Service) ([]byte, error) {
|
||||
return l.cleanupService(restClient, svc)
|
||||
})
|
||||
return l.applyOnLBServices(l.cleanupService)
|
||||
}
|
||||
|
||||
func (l *loadBalancerEmulator) applyOnLBServices(action func(restClient rest.Interface, svc core_v1.Service) ([]byte, error)) ([]string, error) {
|
||||
func (l *loadBalancerEmulator) applyOnLBServices(action func(restClient rest.Interface, svc core.Service) ([]byte, error)) ([]string, error) {
|
||||
services := l.coreV1Client.Services("")
|
||||
serviceList, err := services.List(metav1.ListOptions{})
|
||||
serviceList, err := services.List(meta.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -83,7 +79,7 @@ func (l *loadBalancerEmulator) applyOnLBServices(action func(restClient rest.Int
|
|||
}
|
||||
return managedServices, nil
|
||||
}
|
||||
func (l *loadBalancerEmulator) updateService(restClient rest.Interface, svc core_v1.Service) ([]byte, error) {
|
||||
func (l *loadBalancerEmulator) updateService(restClient rest.Interface, svc core.Service) ([]byte, error) {
|
||||
clusterIP := svc.Spec.ClusterIP
|
||||
ingresses := svc.Status.LoadBalancer.Ingress
|
||||
if len(ingresses) == 1 && ingresses[0].IP == clusterIP {
|
||||
|
@ -92,7 +88,7 @@ func (l *loadBalancerEmulator) updateService(restClient rest.Interface, svc core
|
|||
glog.V(3).Infof("[%s] setting ClusterIP as the LoadBalancer Ingress", svc.Name)
|
||||
jsonPatch := fmt.Sprintf(`[{"op": "add", "path": "/status/loadBalancer/ingress", "value": [ { "ip": "%s" } ] }]`, clusterIP)
|
||||
patch := &Patch{
|
||||
Type: k8s_types.JSONPatchType,
|
||||
Type: types.JSONPatchType,
|
||||
ResourceName: svc.Name,
|
||||
NameSpaceSet: true,
|
||||
NameSpace: svc.Namespace,
|
||||
|
@ -110,7 +106,7 @@ func (l *loadBalancerEmulator) updateService(restClient rest.Interface, svc core
|
|||
return result, err
|
||||
}
|
||||
|
||||
func (l *loadBalancerEmulator) cleanupService(restClient rest.Interface, svc core_v1.Service) ([]byte, error) {
|
||||
func (l *loadBalancerEmulator) cleanupService(restClient rest.Interface, svc core.Service) ([]byte, error) {
|
||||
ingresses := svc.Status.LoadBalancer.Ingress
|
||||
if len(ingresses) == 0 {
|
||||
return nil, nil
|
||||
|
@ -118,7 +114,7 @@ func (l *loadBalancerEmulator) cleanupService(restClient rest.Interface, svc cor
|
|||
glog.V(3).Infof("[%s] cleanup: unset load balancer ingress", svc.Name)
|
||||
jsonPatch := `[{"op": "remove", "path": "/status/loadBalancer/ingress" }]`
|
||||
patch := &Patch{
|
||||
Type: k8s_types.JSONPatchType,
|
||||
Type: types.JSONPatchType,
|
||||
ResourceName: svc.Name,
|
||||
NameSpaceSet: true,
|
||||
NameSpace: svc.Namespace,
|
||||
|
@ -133,7 +129,7 @@ func (l *loadBalancerEmulator) cleanupService(restClient rest.Interface, svc cor
|
|||
|
||||
}
|
||||
|
||||
func newLoadBalancerEmulator(corev1Client v1.CoreV1Interface) loadBalancerEmulator {
|
||||
func newLoadBalancerEmulator(corev1Client typed_core.CoreV1Interface) loadBalancerEmulator {
|
||||
return loadBalancerEmulator{
|
||||
coreV1Client: corev1Client,
|
||||
requestSender: &defaultRequestSender{},
|
||||
|
|
|
@ -21,20 +21,20 @@ import (
|
|||
|
||||
"reflect"
|
||||
|
||||
apiV1 "k8s.io/api/core/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/kubernetes/typed/core/v1/fake"
|
||||
core "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
fake "k8s.io/client-go/kubernetes/typed/core/v1/fake"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type stubCoreClient struct {
|
||||
fake.FakeCoreV1
|
||||
servicesList *apiV1.ServiceList
|
||||
servicesList *core.ServiceList
|
||||
restClient *rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *stubCoreClient) Services(namespace string) v1.ServiceInterface {
|
||||
func (c *stubCoreClient) Services(namespace string) typed_core.ServiceInterface {
|
||||
return &stubServices{
|
||||
fake.FakeServices{Fake: &c.FakeCoreV1},
|
||||
c.servicesList,
|
||||
|
@ -47,17 +47,17 @@ func (c *stubCoreClient) RESTClient() rest.Interface {
|
|||
|
||||
type stubServices struct {
|
||||
fake.FakeServices
|
||||
servicesList *apiV1.ServiceList
|
||||
servicesList *core.ServiceList
|
||||
}
|
||||
|
||||
func (s *stubServices) List(opts metaV1.ListOptions) (*apiV1.ServiceList, error) {
|
||||
func (s *stubServices) List(opts meta.ListOptions) (*core.ServiceList, error) {
|
||||
return s.servicesList, nil
|
||||
}
|
||||
|
||||
func newStubCoreClient(servicesList *apiV1.ServiceList) *stubCoreClient {
|
||||
func newStubCoreClient(servicesList *core.ServiceList) *stubCoreClient {
|
||||
if servicesList == nil {
|
||||
servicesList = &apiV1.ServiceList{
|
||||
Items: []apiV1.Service{}}
|
||||
servicesList = &core.ServiceList{
|
||||
Items: []core.Service{}}
|
||||
}
|
||||
return &stubCoreClient{
|
||||
servicesList: servicesList,
|
||||
|
@ -84,8 +84,8 @@ func (r *recordingPatchConverter) convert(restClient rest.Interface, patch *Patc
|
|||
}
|
||||
|
||||
func TestEmptyListOfServicesDoesNothing(t *testing.T) {
|
||||
client := newStubCoreClient(&apiV1.ServiceList{
|
||||
Items: []apiV1.Service{}})
|
||||
client := newStubCoreClient(&core.ServiceList{
|
||||
Items: []core.Service{}})
|
||||
|
||||
patcher := newLoadBalancerEmulator(client)
|
||||
|
||||
|
@ -98,15 +98,15 @@ func TestEmptyListOfServicesDoesNothing(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServicesWithNoLoadbalancerType(t *testing.T) {
|
||||
client := newStubCoreClient(&apiV1.ServiceList{
|
||||
Items: []apiV1.Service{
|
||||
client := newStubCoreClient(&core.ServiceList{
|
||||
Items: []core.Service{
|
||||
{
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "ClusterIP",
|
||||
},
|
||||
},
|
||||
{
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "NodeIP",
|
||||
},
|
||||
},
|
||||
|
@ -124,20 +124,20 @@ func TestServicesWithNoLoadbalancerType(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServicesWithLoadbalancerType(t *testing.T) {
|
||||
client := newStubCoreClient(&apiV1.ServiceList{
|
||||
Items: []apiV1.Service{
|
||||
client := newStubCoreClient(&core.ServiceList{
|
||||
Items: []core.Service{
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc1-up-to-date",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "LoadBalancer",
|
||||
ClusterIP: "10.96.0.3",
|
||||
},
|
||||
Status: apiV1.ServiceStatus{
|
||||
LoadBalancer: apiV1.LoadBalancerStatus{
|
||||
Ingress: []apiV1.LoadBalancerIngress{
|
||||
Status: core.ServiceStatus{
|
||||
LoadBalancer: core.LoadBalancerStatus{
|
||||
Ingress: []core.LoadBalancerIngress{
|
||||
{
|
||||
IP: "10.96.0.3",
|
||||
},
|
||||
|
@ -146,17 +146,17 @@ func TestServicesWithLoadbalancerType(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc2-out-of-date",
|
||||
Namespace: "ns2",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "LoadBalancer",
|
||||
ClusterIP: "10.96.0.4",
|
||||
},
|
||||
Status: apiV1.ServiceStatus{
|
||||
LoadBalancer: apiV1.LoadBalancerStatus{
|
||||
Ingress: []apiV1.LoadBalancerIngress{
|
||||
Status: core.ServiceStatus{
|
||||
LoadBalancer: core.LoadBalancerStatus{
|
||||
Ingress: []core.LoadBalancerIngress{
|
||||
{
|
||||
IP: "10.96.0.5",
|
||||
},
|
||||
|
@ -165,25 +165,25 @@ func TestServicesWithLoadbalancerType(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc3-empty-ingress",
|
||||
Namespace: "ns3",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "LoadBalancer",
|
||||
ClusterIP: "10.96.0.2",
|
||||
},
|
||||
Status: apiV1.ServiceStatus{
|
||||
LoadBalancer: apiV1.LoadBalancerStatus{
|
||||
Ingress: []apiV1.LoadBalancerIngress{},
|
||||
Status: core.ServiceStatus{
|
||||
LoadBalancer: core.LoadBalancerStatus{
|
||||
Ingress: []core.LoadBalancerIngress{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc4-not-lb",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "NodeIP",
|
||||
},
|
||||
},
|
||||
|
@ -259,20 +259,20 @@ func TestCleanupPatchedIPs(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
client := newStubCoreClient(&apiV1.ServiceList{
|
||||
Items: []apiV1.Service{
|
||||
client := newStubCoreClient(&core.ServiceList{
|
||||
Items: []core.Service{
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc1-up-to-date",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "LoadBalancer",
|
||||
ClusterIP: "10.96.0.3",
|
||||
},
|
||||
Status: apiV1.ServiceStatus{
|
||||
LoadBalancer: apiV1.LoadBalancerStatus{
|
||||
Ingress: []apiV1.LoadBalancerIngress{
|
||||
Status: core.ServiceStatus{
|
||||
LoadBalancer: core.LoadBalancerStatus{
|
||||
Ingress: []core.LoadBalancerIngress{
|
||||
{
|
||||
IP: "10.96.0.3",
|
||||
},
|
||||
|
@ -281,17 +281,17 @@ func TestCleanupPatchedIPs(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc2-out-of-date",
|
||||
Namespace: "ns2",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "LoadBalancer",
|
||||
ClusterIP: "10.96.0.4",
|
||||
},
|
||||
Status: apiV1.ServiceStatus{
|
||||
LoadBalancer: apiV1.LoadBalancerStatus{
|
||||
Ingress: []apiV1.LoadBalancerIngress{
|
||||
Status: core.ServiceStatus{
|
||||
LoadBalancer: core.LoadBalancerStatus{
|
||||
Ingress: []core.LoadBalancerIngress{
|
||||
{
|
||||
IP: "10.96.0.5",
|
||||
},
|
||||
|
@ -300,25 +300,25 @@ func TestCleanupPatchedIPs(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc3-empty-ingress",
|
||||
Namespace: "ns3",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "LoadBalancer",
|
||||
ClusterIP: "10.96.0.2",
|
||||
},
|
||||
Status: apiV1.ServiceStatus{
|
||||
LoadBalancer: apiV1.LoadBalancerStatus{
|
||||
Ingress: []apiV1.LoadBalancerIngress{},
|
||||
Status: core.ServiceStatus{
|
||||
LoadBalancer: core.LoadBalancerStatus{
|
||||
Ingress: []core.LoadBalancerIngress{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metaV1.ObjectMeta{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "svc4-not-lb",
|
||||
},
|
||||
Spec: apiV1.ServiceSpec{
|
||||
Spec: core.ServiceSpec{
|
||||
Type: "NodeIP",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -76,6 +76,7 @@ func (t *routingTable) Check(route *Route) (exists bool, conflict string, overla
|
|||
exists = false
|
||||
overlaps = []string{}
|
||||
for _, tableLine := range *t {
|
||||
|
||||
if route.Equal(tableLine.route) {
|
||||
exists = true
|
||||
} else if route.DestCIDR.String() == tableLine.route.DestCIDR.String() &&
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
"github.com/docker/machine/libmachine/host"
|
||||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
)
|
||||
|
||||
|
@ -43,10 +43,7 @@ func errorTunnelAlreadyExists(id *ID) error {
|
|||
return fmt.Errorf("there is already a running tunnel for this machine: %s", id)
|
||||
}
|
||||
|
||||
func newTunnel(machineName string,
|
||||
machineAPI libmachine.API,
|
||||
configLoader config.Loader,
|
||||
v1Core v1.CoreV1Interface, registry *persistentRegistry, router router) (*tunnel, error) {
|
||||
func newTunnel(machineName string, machineAPI libmachine.API, configLoader config.Loader, v1Core typed_core.CoreV1Interface, registry *persistentRegistry, router router) (*tunnel, error) {
|
||||
ci := &clusterInspector{
|
||||
machineName: machineName,
|
||||
machineAPI: machineAPI,
|
||||
|
@ -154,7 +151,7 @@ func setupRoute(t *tunnel, h *host.Host) {
|
|||
|
||||
if h.DriverName == "hyperkit" {
|
||||
//the virtio-net interface acts up with ip tunnels :(
|
||||
setupBridge(t, h)
|
||||
setupBridge(t)
|
||||
if t.status.RouteError != nil {
|
||||
return
|
||||
}
|
||||
|
@ -193,7 +190,7 @@ func setupRoute(t *tunnel, h *host.Host) {
|
|||
|
||||
}
|
||||
|
||||
func setupBridge(t *tunnel, h *host.Host) {
|
||||
func setupBridge(t *tunnel) {
|
||||
command := exec.Command("ifconfig", "bridge100")
|
||||
glog.Infof("About to run command: %s\n", command.Args)
|
||||
response, err := command.CombinedOutput()
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
|
||||
"github.com/docker/machine/libmachine"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
typed_core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
)
|
||||
|
@ -53,7 +53,7 @@ func NewManager() *Manager {
|
|||
}
|
||||
|
||||
// StartTunnel starts the tunnel
|
||||
func (mgr *Manager) StartTunnel(ctx context.Context, machineName string, machineAPI libmachine.API, configLoader config.Loader, v1Core v1.CoreV1Interface) (done chan bool, err error) {
|
||||
func (mgr *Manager) StartTunnel(ctx context.Context, machineName string, machineAPI libmachine.API, configLoader config.Loader, v1Core typed_core.CoreV1Interface) (done chan bool, err error) {
|
||||
tunnel, err := newTunnel(machineName, machineAPI, configLoader, v1Core, mgr.registry, mgr.router)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating tunnel: %s", err)
|
||||
|
|
|
@ -24,13 +24,13 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/r2d4/external-storage/lib/controller"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
const provisionerName = "k8s.io/minikube-hostpath"
|
||||
|
@ -55,7 +55,7 @@ func NewHostPathProvisioner() controller.Provisioner {
|
|||
var _ controller.Provisioner = &hostPathProvisioner{}
|
||||
|
||||
// Provision creates a storage asset and returns a PV object representing it.
|
||||
func (p *hostPathProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) {
|
||||
func (p *hostPathProvisioner) Provision(options controller.VolumeOptions) (*core.PersistentVolume, error) {
|
||||
glog.Infof("Provisioning volume %v", options)
|
||||
path := path.Join(p.pvDir, options.PVName)
|
||||
if err := os.MkdirAll(path, 0777); err != nil {
|
||||
|
@ -67,21 +67,21 @@ func (p *hostPathProvisioner) Provision(options controller.VolumeOptions) (*v1.P
|
|||
return nil, err
|
||||
}
|
||||
|
||||
pv := &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
pv := &core.PersistentVolume{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: options.PVName,
|
||||
Annotations: map[string]string{
|
||||
"hostPathProvisionerIdentity": string(p.identity),
|
||||
},
|
||||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
Spec: core.PersistentVolumeSpec{
|
||||
PersistentVolumeReclaimPolicy: options.PersistentVolumeReclaimPolicy,
|
||||
AccessModes: options.PVC.Spec.AccessModes,
|
||||
Capacity: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceStorage): options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)],
|
||||
Capacity: core.ResourceList{
|
||||
core.ResourceStorage: options.PVC.Spec.Resources.Requests[core.ResourceStorage],
|
||||
},
|
||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
PersistentVolumeSource: core.PersistentVolumeSource{
|
||||
HostPath: &core.HostPathVolumeSource{
|
||||
Path: path,
|
||||
},
|
||||
},
|
||||
|
@ -93,7 +93,7 @@ func (p *hostPathProvisioner) Provision(options controller.VolumeOptions) (*v1.P
|
|||
|
||||
// Delete removes the storage asset that was created by Provision represented
|
||||
// by the given PV.
|
||||
func (p *hostPathProvisioner) Delete(volume *v1.PersistentVolume) error {
|
||||
func (p *hostPathProvisioner) Delete(volume *core.PersistentVolume) error {
|
||||
glog.Infof("Deleting volume %v", volume)
|
||||
ann, ok := volume.Annotations["hostPathProvisionerIdentity"]
|
||||
if !ok {
|
||||
|
@ -114,7 +114,7 @@ func (p *hostPathProvisioner) Delete(volume *v1.PersistentVolume) error {
|
|||
// StartStorageProvisioner will start storage provisioner server
|
||||
func StartStorageProvisioner() error {
|
||||
glog.Infof("Initializing the Minikube storage provisioner...")
|
||||
config, err := restclient.InClusterConfig()
|
||||
config, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ func StartStorageProvisioner() error {
|
|||
// provisioners aren't officially supported until 1.5
|
||||
serverVersion, err := clientset.Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting server version: %v", err)
|
||||
return fmt.Errorf("error getting server version: %v", err)
|
||||
}
|
||||
|
||||
// Create the provisioner: it implements the Provisioner interface expected by
|
||||
|
|
|
@ -39,7 +39,7 @@ func findNestedElement(s string, c interface{}) (reflect.Value, error) {
|
|||
|
||||
// FieldByName returns the zero value if the field does not exist.
|
||||
if e == (reflect.Value{}) {
|
||||
return e, fmt.Errorf("Unable to find field by name: %s", field)
|
||||
return e, fmt.Errorf("unable to find field by name: %s", field)
|
||||
}
|
||||
// Start the loop again, on the next level.
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ func convertMap(e reflect.Value, v string) error {
|
|||
return c == '<' || c == '=' || c == '>'
|
||||
})
|
||||
if len(subvals) != 2 {
|
||||
return fmt.Errorf("Unparsable %s", v)
|
||||
return fmt.Errorf("unparsable %s", v)
|
||||
}
|
||||
e.SetMapIndex(reflect.ValueOf(subvals[0]), reflect.ValueOf(subvals[1]))
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func convertKind(e reflect.Value, v string) error {
|
|||
case reflect.Bool:
|
||||
return convertBool(e, v)
|
||||
default:
|
||||
return fmt.Errorf("Unable to set type %T", e.Kind())
|
||||
return fmt.Errorf("unable to set type %T", e.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -176,8 +176,8 @@ func TestSetElement(t *testing.T) {
|
|||
{"E.J", "otherstring", func(t testConfig) bool { return t.E.J == "otherstring" }},
|
||||
{"E.K", "17", func(t testConfig) bool { return t.E.K == 17 }},
|
||||
{"E.L", "1.234", func(t testConfig) bool { return checkFloats(float64(t.E.L), 1.234) }},
|
||||
{"D.I.P", "true", func(t testConfig) bool { return bool(t.D.I.P) == true }},
|
||||
{"D.I.P", "false", func(t testConfig) bool { return bool(t.D.I.P) == false }},
|
||||
{"D.I.P", "true", func(t testConfig) bool { return t.D.I.P == true }},
|
||||
{"D.I.P", "false", func(t testConfig) bool { return t.D.I.P == false }},
|
||||
{"D.I.Q", "11.22.33.44", func(t testConfig) bool { return t.D.I.Q.Equal(net.ParseIP("11.22.33.44")) }},
|
||||
{"D.I.R", "7-11", func(t testConfig) bool { return t.D.I.R.Base == 7 && t.D.I.R.Size == 5 }},
|
||||
{"D.I.S", "a,b", func(t testConfig) bool { return reflect.DeepEqual(t.D.I.S, []string{"a", "b"}) }},
|
||||
|
|
|
@ -55,7 +55,9 @@ func TestCacheMinikubeISOFromURL(t *testing.T) {
|
|||
isoPath := filepath.Join(constants.GetMinipath(), "cache", "iso", "minikube-test.iso")
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
io.WriteString(w, testISOString)
|
||||
if _, err := io.WriteString(w, testISOString); err != nil {
|
||||
t.Fatalf("WriteString: %v", err)
|
||||
}
|
||||
}))
|
||||
isoURL := server.URL + "/minikube-test.iso"
|
||||
if err := dler.CacheMinikubeISOFromURL(isoURL); err != nil {
|
||||
|
@ -103,7 +105,9 @@ func TestIsMinikubeISOCached(t *testing.T) {
|
|||
t.Fatalf("Expected IsMinikubeISOCached with input %s to return %t but instead got: %t", testFileURI, expected, out)
|
||||
}
|
||||
|
||||
ioutil.WriteFile(filepath.Join(constants.GetMinipath(), "cache", "iso", "minikube-test.iso"), []byte(testISOString), os.FileMode(int(0644)))
|
||||
if err := ioutil.WriteFile(filepath.Join(constants.GetMinipath(), "cache", "iso", "minikube-test.iso"), []byte(testISOString), os.FileMode(int(0644))); err != nil {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
|
||||
expected = true
|
||||
if out := dler.IsMinikubeISOCached(testFileURI); out != expected {
|
||||
|
|
|
@ -40,14 +40,14 @@ func (es *ExtraOptionSlice) Set(value string) error {
|
|||
// The component is the value before the first dot.
|
||||
componentSplit := strings.SplitN(value, ".", 2)
|
||||
if len(componentSplit) < 2 {
|
||||
return fmt.Errorf("Invalid value for ExtraOption flag. Value must contain at least one period: %s", value)
|
||||
return fmt.Errorf("invalid value: must contain at least one period: %q", value)
|
||||
}
|
||||
|
||||
remainder := strings.Join(componentSplit[1:], "")
|
||||
|
||||
keySplit := strings.SplitN(remainder, "=", 2)
|
||||
if len(keySplit) != 2 {
|
||||
return fmt.Errorf("Invalid value for ExtraOption flag. Value must contain one equal sign: %s", value)
|
||||
return fmt.Errorf("invalid value: must contain one equal sign: %q", value)
|
||||
}
|
||||
|
||||
e := ExtraOption{
|
||||
|
|
|
@ -312,3 +312,16 @@ func GetPortFromKubeConfig(filename, machineName string) (int, error) {
|
|||
port, err := strconv.Atoi(kport)
|
||||
return port, err
|
||||
}
|
||||
|
||||
//UnsetCurrentContext unsets the current-context from minikube to "" on minikube stop
|
||||
func UnsetCurrentContext(filename, machineName string) error {
|
||||
confg, err := ReadConfigOrNew(filename)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error getting kubeconfig status")
|
||||
}
|
||||
confg.CurrentContext = ""
|
||||
if err := WriteConfig(confg, filename); err != nil {
|
||||
return errors.Wrap(err, "writing kubeconfig")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -146,7 +146,9 @@ func TestSetupKubeConfig(t *testing.T) {
|
|||
}
|
||||
test.cfg.SetKubeConfigFile(filepath.Join(tmpDir, "kubeconfig"))
|
||||
if len(test.existingCfg) != 0 {
|
||||
ioutil.WriteFile(test.cfg.GetKubeConfigFile(), test.existingCfg, 0600)
|
||||
if err := ioutil.WriteFile(test.cfg.GetKubeConfigFile(), test.existingCfg, 0600); err != nil {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
}
|
||||
err = SetupKubeConfig(test.cfg)
|
||||
if err != nil && !test.err {
|
||||
|
|
|
@ -22,10 +22,10 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
"github.com/pkg/errors"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
apierr "k8s.io/apimachinery/pkg/api/errors"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
@ -53,11 +53,11 @@ type PodStore struct {
|
|||
}
|
||||
|
||||
// List lists the pods
|
||||
func (s *PodStore) List() []*v1.Pod {
|
||||
func (s *PodStore) List() []*core.Pod {
|
||||
objects := s.Store.List()
|
||||
pods := make([]*v1.Pod, 0)
|
||||
pods := make([]*core.Pod, 0)
|
||||
for _, o := range objects {
|
||||
pods = append(pods, o.(*v1.Pod))
|
||||
pods = append(pods, o.(*core.Pod))
|
||||
}
|
||||
return pods
|
||||
}
|
||||
|
@ -84,29 +84,29 @@ func GetClient() (kubernetes.Interface, error) {
|
|||
}
|
||||
|
||||
// NewPodStore creates a new PodStore
|
||||
func NewPodStore(c kubernetes.Interface, namespace string, label labels.Selector, field fields.Selector) *PodStore {
|
||||
func NewPodStore(c kubernetes.Interface, namespace string, label fmt.Stringer, field fmt.Stringer) *PodStore {
|
||||
lw := &cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta.ListOptions) (runtime.Object, error) {
|
||||
options.LabelSelector = label.String()
|
||||
options.FieldSelector = field.String()
|
||||
obj, err := c.Core().Pods(namespace).List(options)
|
||||
obj, err := c.CoreV1().Pods(namespace).List(options)
|
||||
return runtime.Object(obj), err
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta.ListOptions) (watch.Interface, error) {
|
||||
options.LabelSelector = label.String()
|
||||
options.FieldSelector = field.String()
|
||||
return c.Core().Pods(namespace).Watch(options)
|
||||
return c.CoreV1().Pods(namespace).Watch(options)
|
||||
},
|
||||
}
|
||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
||||
stopCh := make(chan struct{})
|
||||
reflector := cache.NewReflector(lw, &v1.Pod{}, store, 0)
|
||||
reflector := cache.NewReflector(lw, &core.Pod{}, store, 0)
|
||||
go reflector.Run(stopCh)
|
||||
return &PodStore{Store: store, stopCh: stopCh, Reflector: reflector}
|
||||
}
|
||||
|
||||
// StartPods starts all pods
|
||||
func StartPods(c kubernetes.Interface, namespace string, pod v1.Pod, waitForRunning bool) error {
|
||||
func StartPods(c kubernetes.Interface, namespace string, pod core.Pod, waitForRunning bool) error {
|
||||
pod.ObjectMeta.Labels["name"] = pod.Name
|
||||
if waitForRunning {
|
||||
label := labels.SelectorFromSet(labels.Set(map[string]string{"name": pod.Name}))
|
||||
|
@ -123,7 +123,7 @@ func WaitForPodsWithLabelRunning(c kubernetes.Interface, ns string, label labels
|
|||
glog.Infof("Waiting for pod with label %q in ns %q ...", ns, label)
|
||||
lastKnownPodNumber := -1
|
||||
return wait.PollImmediate(constants.APICallRetryInterval, ReasonableStartTime, func() (bool, error) {
|
||||
listOpts := metav1.ListOptions{LabelSelector: label.String()}
|
||||
listOpts := meta.ListOptions{LabelSelector: label.String()}
|
||||
pods, err := c.CoreV1().Pods(ns).List(listOpts)
|
||||
if err != nil {
|
||||
glog.Infof("error getting Pods with label selector %q [%v]\n", label.String(), err)
|
||||
|
@ -140,7 +140,7 @@ func WaitForPodsWithLabelRunning(c kubernetes.Interface, ns string, label labels
|
|||
}
|
||||
|
||||
for _, pod := range pods.Items {
|
||||
if pod.Status.Phase != v1.PodRunning {
|
||||
if pod.Status.Phase != core.PodRunning {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
@ -150,9 +150,9 @@ func WaitForPodsWithLabelRunning(c kubernetes.Interface, ns string, label labels
|
|||
}
|
||||
|
||||
// WaitForPodDelete waits for a pod to be deleted
|
||||
func WaitForPodDelete(c kubernetes.Interface, ns string, label labels.Selector) error {
|
||||
func WaitForPodDelete(c kubernetes.Interface, ns string, label fmt.Stringer) error {
|
||||
return wait.PollImmediate(constants.APICallRetryInterval, ReasonableMutateTime, func() (bool, error) {
|
||||
listOpts := metav1.ListOptions{LabelSelector: label.String()}
|
||||
listOpts := meta.ListOptions{LabelSelector: label.String()}
|
||||
pods, err := c.CoreV1().Pods(ns).List(listOpts)
|
||||
if err != nil {
|
||||
glog.Infof("error getting Pods with label selector %q [%v]\n", label.String(), err)
|
||||
|
@ -165,7 +165,7 @@ func WaitForPodDelete(c kubernetes.Interface, ns string, label labels.Selector)
|
|||
// WaitForEvent waits for the given event to appear
|
||||
func WaitForEvent(c kubernetes.Interface, ns string, reason string) error {
|
||||
return wait.PollImmediate(constants.APICallRetryInterval, ReasonableMutateTime, func() (bool, error) {
|
||||
events, err := c.Events().Events("default").List(metav1.ListOptions{})
|
||||
events, err := c.EventsV1beta1().Events("default").List(meta.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Infof("error getting events: %v", err)
|
||||
return false, nil
|
||||
|
@ -181,21 +181,21 @@ func WaitForEvent(c kubernetes.Interface, ns string, reason string) error {
|
|||
|
||||
// WaitForRCToStabilize waits till the RC has a matching generation/replica count between spec and status.
|
||||
func WaitForRCToStabilize(c kubernetes.Interface, ns, name string, timeout time.Duration) error {
|
||||
options := metav1.ListOptions{FieldSelector: fields.Set{
|
||||
options := meta.ListOptions{FieldSelector: fields.Set{
|
||||
"metadata.name": name,
|
||||
"metadata.namespace": ns,
|
||||
}.AsSelector().String()}
|
||||
w, err := c.Core().ReplicationControllers(ns).Watch(options)
|
||||
w, err := c.CoreV1().ReplicationControllers(ns).Watch(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = watch.Until(timeout, w, func(event watch.Event) (bool, error) {
|
||||
switch event.Type {
|
||||
case watch.Deleted:
|
||||
return false, apierrs.NewNotFound(schema.GroupResource{Resource: "replicationcontrollers"}, "")
|
||||
if event.Type == watch.Deleted {
|
||||
return false, apierr.NewNotFound(schema.GroupResource{Resource: "replicationcontrollers"}, "")
|
||||
}
|
||||
switch rc := event.Object.(type) {
|
||||
case *v1.ReplicationController:
|
||||
|
||||
rc, ok := event.Object.(*core.ReplicationController)
|
||||
if ok {
|
||||
if rc.Name == name && rc.Namespace == ns &&
|
||||
rc.Generation <= rc.Status.ObservedGeneration &&
|
||||
*(rc.Spec.Replicas) == rc.Status.Replicas {
|
||||
|
@ -211,7 +211,7 @@ func WaitForRCToStabilize(c kubernetes.Interface, ns, name string, timeout time.
|
|||
|
||||
// WaitForDeploymentToStabilize waits till the Deployment has a matching generation/replica count between spec and status.
|
||||
func WaitForDeploymentToStabilize(c kubernetes.Interface, ns, name string, timeout time.Duration) error {
|
||||
options := metav1.ListOptions{FieldSelector: fields.Set{
|
||||
options := meta.ListOptions{FieldSelector: fields.Set{
|
||||
"metadata.name": name,
|
||||
"metadata.namespace": ns,
|
||||
}.AsSelector().String()}
|
||||
|
@ -220,12 +220,11 @@ func WaitForDeploymentToStabilize(c kubernetes.Interface, ns, name string, timeo
|
|||
return err
|
||||
}
|
||||
_, err = watch.Until(timeout, w, func(event watch.Event) (bool, error) {
|
||||
switch event.Type {
|
||||
case watch.Deleted:
|
||||
return false, apierrs.NewNotFound(schema.GroupResource{Resource: "deployments"}, "")
|
||||
if event.Type == watch.Deleted {
|
||||
return false, apierr.NewNotFound(schema.GroupResource{Resource: "deployments"}, "")
|
||||
}
|
||||
switch dp := event.Object.(type) {
|
||||
case *appsv1.Deployment:
|
||||
dp, ok := event.Object.(*apps.Deployment)
|
||||
if ok {
|
||||
if dp.Name == name && dp.Namespace == ns &&
|
||||
dp.Generation <= dp.Status.ObservedGeneration &&
|
||||
*(dp.Spec.Replicas) == dp.Status.Replicas {
|
||||
|
@ -242,12 +241,12 @@ func WaitForDeploymentToStabilize(c kubernetes.Interface, ns, name string, timeo
|
|||
// WaitForService waits until the service appears (exist == true), or disappears (exist == false)
|
||||
func WaitForService(c kubernetes.Interface, namespace, name string, exist bool, interval, timeout time.Duration) error {
|
||||
err := wait.PollImmediate(interval, timeout, func() (bool, error) {
|
||||
_, err := c.Core().Services(namespace).Get(name, metav1.GetOptions{})
|
||||
_, err := c.CoreV1().Services(namespace).Get(name, meta.GetOptions{})
|
||||
switch {
|
||||
case err == nil:
|
||||
glog.Infof("Service %s in namespace %s found.", name, namespace)
|
||||
return exist, nil
|
||||
case apierrs.IsNotFound(err):
|
||||
case apierr.IsNotFound(err):
|
||||
glog.Infof("Service %s in namespace %s disappeared.", name, namespace)
|
||||
return !exist, nil
|
||||
case !IsRetryableAPIError(err):
|
||||
|
@ -269,7 +268,7 @@ func WaitForService(c kubernetes.Interface, namespace, name string, exist bool,
|
|||
func WaitForServiceEndpointsNum(c kubernetes.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error {
|
||||
return wait.Poll(interval, timeout, func() (bool, error) {
|
||||
glog.Infof("Waiting for amount of service:%s endpoints to be %d", serviceName, expectNum)
|
||||
list, err := c.Core().Endpoints(namespace).List(metav1.ListOptions{})
|
||||
list, err := c.CoreV1().Endpoints(namespace).List(meta.ListOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -283,7 +282,7 @@ func WaitForServiceEndpointsNum(c kubernetes.Interface, namespace, serviceName s
|
|||
})
|
||||
}
|
||||
|
||||
func countEndpointsNum(e *v1.Endpoints) int {
|
||||
func countEndpointsNum(e *core.Endpoints) int {
|
||||
num := 0
|
||||
for _, sub := range e.Subsets {
|
||||
num += len(sub.Addresses)
|
||||
|
@ -293,5 +292,5 @@ func countEndpointsNum(e *v1.Endpoints) int {
|
|||
|
||||
// IsRetryableAPIError returns if this error is retryable or not
|
||||
func IsRetryableAPIError(err error) bool {
|
||||
return apierrs.IsTimeout(err) || apierrs.IsServerTimeout(err) || apierrs.IsTooManyRequests(err) || apierrs.IsInternalError(err)
|
||||
return apierr.IsTimeout(err) || apierr.IsServerTimeout(err) || apierr.IsTooManyRequests(err) || apierr.IsInternalError(err)
|
||||
}
|
||||
|
|
|
@ -98,11 +98,15 @@ var testSHAString = "test"
|
|||
|
||||
func TestParseSHAFromURL(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
io.WriteString(w, testSHAString)
|
||||
if _, err := io.WriteString(w, testSHAString); err != nil {
|
||||
t.Fatalf("WriteString: %v", err)
|
||||
}
|
||||
}))
|
||||
serverBadResponse := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte("500 HTTP status code returned!"))
|
||||
if _, err := w.Write([]byte("500 HTTP status code returned!")); err != nil {
|
||||
t.Fatalf("Write: %v", err)
|
||||
}
|
||||
}))
|
||||
|
||||
argsList := [...]getTestArgs{
|
||||
|
@ -175,7 +179,9 @@ func TestTeePrefix(t *testing.T) {
|
|||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
TeePrefix(":", &in, &out, logSink)
|
||||
if err := TeePrefix(":", &in, &out, logSink); err != nil {
|
||||
t.Errorf("TeePrefix: %v", err)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
|
|
80
test.sh
80
test.sh
|
@ -14,56 +14,42 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -e
|
||||
set -eu -o pipefail
|
||||
|
||||
# Check for python on host, and use it if possible, otherwise fall back on python dockerized
|
||||
if [[ -f $(which python 2>&1) ]]; then
|
||||
PYTHON="python"
|
||||
exitcode=0
|
||||
|
||||
echo "= go mod ================================================================"
|
||||
go mod download >/dev/null || ((exitcode+=1))
|
||||
go mod tidy -v && echo ok || ((exitcode+=2))
|
||||
|
||||
echo "= make lint ============================================================="
|
||||
make -s lint && echo ok || ((exitcode+=4))
|
||||
|
||||
echo "= boilerplate ==========================================================="
|
||||
readonly PYTHON=$(type -P python || echo docker run --rm -it -v $(pwd):/minikube -w /minikube python python)
|
||||
readonly BDIR="./hack/boilerplate"
|
||||
missing="$($PYTHON ${BDIR}/boilerplate.py --rootdir . --boilerplate-dir ${BDIR} | grep -v \/assets.go || true)"
|
||||
if [[ -n "${missing}" ]]; then
|
||||
echo "boilerplate missing: $missing"
|
||||
echo "consider running: ${BDIR}/fix.sh"
|
||||
((exitcode+=4))
|
||||
else
|
||||
PYTHON="docker run --rm -it -v $(pwd):/minikube -w /minikube python python"
|
||||
echo "ok"
|
||||
fi
|
||||
|
||||
echo "= schema_check =========================================================="
|
||||
go run deploy/minikube/schema_check.go >/dev/null && echo ok || ((exitcode+=8))
|
||||
|
||||
COV_FILE=coverage.txt
|
||||
COV_TMP_FILE=coverage_tmp.txt
|
||||
echo "= go test ==============================================================="
|
||||
cov_tmp="$(mktemp)"
|
||||
readonly COVERAGE_PATH=./out/coverage.txt
|
||||
echo "mode: count" > "${COVERAGE_PATH}"
|
||||
pkgs=$(go list -f '{{ if .TestGoFiles }}{{.ImportPath}}{{end}}' ./cmd/... ./pkg/... | xargs)
|
||||
go test \
|
||||
-tags "container_image_ostree_stub containers_image_openpgp" \
|
||||
-covermode=count \
|
||||
-coverprofile="${cov_tmp}" \
|
||||
${pkgs} && echo ok || ((exitcode+=16))
|
||||
tail -n +2 "${cov_tmp}" >> "${COVERAGE_PATH}"
|
||||
|
||||
# Run "go test" on packages that have test files. Also create coverage profile
|
||||
echo "Running go tests..."
|
||||
rm -f out/$COV_FILE || true
|
||||
echo "mode: count" > out/$COV_FILE
|
||||
for pkg in $(go list -f '{{ if .TestGoFiles }} {{.ImportPath}} {{end}}' ./cmd/... ./pkg/...); do
|
||||
go test -tags "container_image_ostree_stub containers_image_openpgp" -v $pkg -covermode=count -coverprofile=out/$COV_TMP_FILE
|
||||
# tail -n +2 skips the first line of the file
|
||||
# for coverprofile the first line is the `mode: count` line which we only want once in our file
|
||||
tail -n +2 out/$COV_TMP_FILE >> out/$COV_FILE || (echo "Unable to append coverage for $pkg" && exit 1)
|
||||
done
|
||||
rm out/$COV_TMP_FILE
|
||||
|
||||
# Ignore these paths in the following tests.
|
||||
ignore="vendor\|\_gopath\|assets.go\|out\/"
|
||||
|
||||
# Check gofmt
|
||||
echo "Checking gofmt..."
|
||||
set +e
|
||||
files=$(gofmt -l -s . | grep -v ${ignore})
|
||||
set -e
|
||||
if [[ $files ]]; then
|
||||
gofmt -d ${files}
|
||||
echo "Gofmt errors in files: $files"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check boilerplate
|
||||
echo "Checking boilerplate..."
|
||||
BOILERPLATEDIR=./hack/boilerplate
|
||||
# Grep returns a non-zero exit code if we don't match anything, which is good in this case.
|
||||
set +e
|
||||
files=$(${PYTHON} ${BOILERPLATEDIR}/boilerplate.py --rootdir . --boilerplate-dir ${BOILERPLATEDIR} | grep -v $ignore)
|
||||
set -e
|
||||
if [[ ! -z ${files} ]]; then
|
||||
echo "Boilerplate missing in: ${files}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Checking releases.json schema"
|
||||
go run deploy/minikube/schema_check.go
|
||||
exit "${exitcode}"
|
||||
|
|
|
@ -39,7 +39,11 @@ func testClusterDNS(t *testing.T) {
|
|||
|
||||
kr := util.NewKubectlRunner(t)
|
||||
busybox := busyBoxPod(t, client, kr)
|
||||
defer kr.RunCommand([]string{"delete", "po", busybox})
|
||||
defer func() {
|
||||
if _, err := kr.RunCommand([]string{"delete", "po", busybox}); err != nil {
|
||||
t.Errorf("delete failed: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
out := []byte{}
|
||||
|
||||
|
|
|
@ -36,8 +36,9 @@ func TestDocker(t *testing.T) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
// Pre-cleanup: this usually fails, because no instance is running.
|
||||
mk.RunWithContext(ctx, "delete")
|
||||
if _, _, err := mk.RunWithContext(ctx, "delete"); err != nil {
|
||||
t.Logf("pre-delete failed (probably ok): %v", err)
|
||||
}
|
||||
|
||||
startCmd := fmt.Sprintf("start %s %s %s", mk.StartArgs, mk.Args,
|
||||
"--docker-env=FOO=BAR --docker-env=BAZ=BAT --docker-opt=debug --docker-opt=icc=true --alsologtostderr --v=5")
|
||||
|
|
|
@ -147,7 +147,7 @@ func verifyFiles(minikubeRunner util.MinikubeRunner, kubectlRunner *util.Kubectl
|
|||
}
|
||||
// test that file written from pod can be read from host echo test > /mount-9p/frompod; in pod
|
||||
if string(out) != expected {
|
||||
return fmt.Errorf("Expected file %s to contain text %s, was %s.", path, expected, out)
|
||||
return fmt.Errorf("expected file %s to contain text %q, was %q", path, expected, out)
|
||||
}
|
||||
|
||||
// test that file written from host was read in by the pod via cat /mount-9p/fromhost;
|
||||
|
@ -155,7 +155,7 @@ func verifyFiles(minikubeRunner util.MinikubeRunner, kubectlRunner *util.Kubectl
|
|||
return err
|
||||
}
|
||||
if string(out) != expected {
|
||||
return fmt.Errorf("Expected file %s to contain text %s, was %s.", path, expected, out)
|
||||
return fmt.Errorf("expected file %s to contain text %q, was %q", path, expected, out)
|
||||
}
|
||||
|
||||
// test file timestamps are correct
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
storage "k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
commonutil "k8s.io/minikube/pkg/util"
|
||||
|
@ -60,7 +60,7 @@ func testProvisioning(t *testing.T) {
|
|||
if len(scl.Items) > 0 {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("No default StorageClass yet.")
|
||||
return fmt.Errorf("no default StorageClass yet")
|
||||
}
|
||||
|
||||
if err := util.Retry(t, checkStorageClass, 5*time.Second, 20); err != nil {
|
||||
|
@ -94,7 +94,7 @@ func testProvisioning(t *testing.T) {
|
|||
|
||||
// And check that it gets bound to a PV.
|
||||
checkStorage := func() error {
|
||||
pvc := api.PersistentVolumeClaim{}
|
||||
pvc := core.PersistentVolumeClaim{}
|
||||
if err := kubectlRunner.RunCommandParseOutput(pvcCmd, &pvc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -77,6 +77,16 @@ func TestStartStop(t *testing.T) {
|
|||
t.Fatalf("IP command returned an invalid address: %s", ip)
|
||||
}
|
||||
|
||||
// check for the current-context before and after the stop
|
||||
kubectlRunner := util.NewKubectlRunner(t)
|
||||
currentContext, err := kubectlRunner.RunCommand([]string{"config", "current-context"})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to fetch current-context")
|
||||
}
|
||||
if strings.TrimRight(string(currentContext), "\n") != "minikube" {
|
||||
t.Fatalf("got current-context - %q, want current-context %q", string(currentContext), "minikube")
|
||||
}
|
||||
|
||||
checkStop := func() error {
|
||||
r.RunCommand("stop", true)
|
||||
return r.CheckStatusNoFail(state.Stopped.String())
|
||||
|
@ -86,6 +96,11 @@ func TestStartStop(t *testing.T) {
|
|||
t.Fatalf("timed out while checking stopped status: %v", err)
|
||||
}
|
||||
|
||||
// running this command results in error when the current-context is not set
|
||||
if err := r.Run("config current-context"); err != nil {
|
||||
t.Logf("current-context is not set to minikube")
|
||||
}
|
||||
|
||||
r.Start(test.args...)
|
||||
r.CheckStatus(state.Running.String())
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ func testTunnel(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// getResponseBody returns the contents of a URL
|
||||
func getResponseBody(address string) (string, error) {
|
||||
httpClient := http.DefaultClient
|
||||
httpClient.Timeout = 5 * time.Second
|
||||
|
|
|
@ -94,7 +94,9 @@ func (m *MinikubeRunner) teeRun(cmd *exec.Cmd) (string, string, error) {
|
|||
return "", "", err
|
||||
}
|
||||
|
||||
cmd.Start()
|
||||
if err := cmd.Start(); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
var outB bytes.Buffer
|
||||
var errB bytes.Buffer
|
||||
var wg sync.WaitGroup
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -26,6 +27,7 @@ import (
|
|||
|
||||
"github.com/docker/machine/libmachine/state"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
@ -63,19 +65,14 @@ func TestVersionUpgrade(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
releaseRunner := util.MinikubeRunner{
|
||||
Args: currentRunner.Args,
|
||||
BinaryPath: tf.Name(),
|
||||
StartArgs: currentRunner.StartArgs,
|
||||
MountArgs: currentRunner.MountArgs,
|
||||
T: t,
|
||||
}
|
||||
releaseRunner.Start()
|
||||
releaseRunner := util.MinikubeRunner{BinaryPath: tf.Name(), T: t}
|
||||
// For full coverage: also test upgrading from oldest to newest supported k8s release
|
||||
releaseRunner.Start(fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion))
|
||||
releaseRunner.CheckStatus(state.Running.String())
|
||||
releaseRunner.RunCommand("stop", true)
|
||||
releaseRunner.CheckStatus(state.Stopped.String())
|
||||
|
||||
currentRunner.Start()
|
||||
currentRunner.Start(fmt.Sprintf("--kubernetes-version=%s", constants.NewestKubernetesVersion))
|
||||
currentRunner.CheckStatus(state.Running.String())
|
||||
currentRunner.RunCommand("delete", true)
|
||||
currentRunner.CheckStatus(state.None.String())
|
||||
|
|
Loading…
Reference in New Issue