Manual changes to remove localkube.

pull/3014/head
dlorenc 2018-06-04 10:49:57 -07:00 committed by dlorenc
parent 18a84504c8
commit 15b035748c
31 changed files with 8 additions and 2560 deletions

View File

@ -49,8 +49,6 @@ PYTHON := $(shell command -v python || echo "docker run --rm -it -v $(shell pwd)
BUILD_OS := $(shell uname -s)
LOCALKUBE_VERSION := $(shell $(PYTHON) hack/get_k8s_version.py --k8s-version-only 2>&1)
LOCALKUBE_BUCKET ?= minikube/k8sReleases
LOCALKUBE_UPLOAD_LOCATION := gs://${LOCALKUBE_BUCKET}
TAG ?= $(LOCALKUBE_VERSION)
STORAGE_PROVISIONER_TAG := v1.8.1
@ -61,7 +59,6 @@ LOCALKUBE_LDFLAGS := "$(K8S_VERSION_LDFLAGS) $(MINIKUBE_LDFLAGS) -s -w"
MAKEDEPEND := GOPATH=$(GOPATH) ./makedepend.sh
LOCALKUBEFILES := ./cmd/localkube/
MINIKUBEFILES := ./cmd/minikube/
HYPERKIT_FILES := ./cmd/drivers/hyperkit
STORAGE_PROVISIONER_FILES := ./cmd/storage-provisioner
@ -80,12 +77,6 @@ endef
ifeq ($(BUILD_IN_DOCKER),y)
MINIKUBE_BUILD_IN_DOCKER=y
LOCALKUBE_BUILD_IN_DOCKER=y
endif
# If not on linux, localkube must be built in docker
ifneq ($(BUILD_OS),Linux)
LOCALKUBE_BUILD_IN_DOCKER=y
endif
# If we are already running in docker,
@ -93,7 +84,6 @@ endif
# The _BUILD_IN_DOCKER variables should not be modified after this conditional.
ifeq ($(IN_DOCKER),1)
MINIKUBE_BUILD_IN_DOCKER=n
LOCALKUBE_BUILD_IN_DOCKER=n
endif
ifeq ($(GOOS),windows)
@ -102,17 +92,6 @@ endif
out/minikube$(IS_EXE): out/minikube-$(GOOS)-$(GOARCH)$(IS_EXE)
cp $< $@
out/localkube.d:
GOOS=linux GOARCH=$(GOARCH) $(MAKEDEPEND) out/localkube $(ORG) $(LOCALKUBEFILES) $^ > $@
-include out/localkube.d
out/localkube:
ifeq ($(LOCALKUBE_BUILD_IN_DOCKER),y)
$(call DOCKER,$(BUILD_IMAGE),/usr/bin/make $@)
else
CGO_ENABLED=1 go build -ldflags=$(LOCALKUBE_LDFLAGS) -o $(BUILD_DIR)/localkube ./cmd/localkube
endif
out/minikube-windows-amd64.exe: out/minikube-windows-amd64
cp out/minikube-windows-amd64 out/minikube-windows-amd64.exe
@ -182,20 +161,14 @@ test-pkg/%:
go test -v -test.timeout=30m $(REPOPATH)/$* --tags="$(MINIKUBE_BUILD_TAGS)"
.PHONY: depend
depend: out/localkube.d out/minikube.d out/test.d out/docker-machine-driver-hyperkit.d out/storage-provisioner.d out/docker-machine-driver-kvm2.d
depend: out/minikube.d out/test.d out/docker-machine-driver-hyperkit.d out/storage-provisioner.d out/docker-machine-driver-kvm2.d
.PHONY: all
all: cross drivers e2e-cross images out/localkube
all: cross drivers e2e-cross images
.PHONY: drivers
drivers: out/docker-machine-driver-hyperkit out/docker-machine-driver-kvm2
.PHONY: images
images: localkube-image localkube-dind-image localkube-dind-image-devshell
gcloud docker -- push $(REGISTRY)/localkube-image:$(TAG)
gcloud docker -- push $(REGISTRY)/localkube-dind-image:$(TAG)
gcloud docker -- push $(REGISTRY)/localkube-dind-image-devshell:$(TAG)
.PHONY: integration
integration: out/minikube
go test -v -test.timeout=30m $(REPOPATH)/test/integration --tags="$(MINIKUBE_INTEGRATION_BUILD_TAGS)" $(TEST_ARGS)
@ -228,7 +201,7 @@ e2e-cross: e2e-linux-amd64 e2e-darwin-amd64 e2e-windows-amd64.exe
.PHONY: checksum
checksum:
for f in out/localkube out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe out/minikube.iso; do \
for f in out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe out/minikube.iso; do \
if [ -f "$${f}" ]; then \
openssl sha256 "$${f}" | awk '{print $$2}' > "$${f}.sha256" ; \
fi ; \
@ -304,36 +277,10 @@ install-hyperkit-driver: out/docker-machine-driver-hyperkit
check-release:
go test -v ./deploy/minikube/release_sanity_test.go -tags=release
.PHONY: release-localkube
release-localkube: out/localkube checksum
gsutil cp out/localkube $(LOCALKUBE_UPLOAD_LOCATION)/$(LOCALKUBE_VERSION)/localkube-linux-amd64
gsutil cp out/localkube.sha256 $(LOCALKUBE_UPLOAD_LOCATION)/$(LOCALKUBE_VERSION)/localkube-linux-amd64.sha256
.PHONY: update-releases
update-releases:
gsutil cp deploy/minikube/k8s_releases.json gs://minikube/k8s_releases.json
localkube-image: out/localkube
# TODO(aprindle) make addons placed into container configurable
docker build -t $(REGISTRY)/localkube-image:$(TAG) -f deploy/docker/Dockerfile .
@echo ""
@echo "${REGISTRY}/localkube-image:$(TAG) successfully built"
@echo "See https://github.com/kubernetes/minikube/tree/master/deploy/docker for instructions on how to run image"
localkube-dind-image: out/localkube
# TODO(aprindle) make addons placed into container configurable
docker build -t $(REGISTRY)/localkube-dind-image:$(TAG) -f deploy/docker/localkube-dind/Dockerfile .
@echo ""
@echo "${REGISTRY}/localkube-dind-image:$(TAG) successfully built"
@echo "See https://github.com/kubernetes/minikube/tree/master/deploy/docker for instructions on how to run image"
localkube-dind-image-devshell: out/localkube
# TODO(aprindle) make addons placed into container configurable
docker build -t $(REGISTRY)/localkube-dind-image-devshell:$(TAG) -f deploy/docker/localkube-dind/Dockerfile .
@echo ""
@echo "${REGISTRY}/localkube-dind-image-devshell:$(TAG) successfully built"
@echo "See https://github.com/kubernetes/minikube/tree/master/deploy/docker for instructions on how to run image"
buildroot-image: $(ISO_BUILD_IMAGE) # convenient alias to build the docker container
$(ISO_BUILD_IMAGE): deploy/iso/minikube-iso/Dockerfile
docker build $(ISO_DOCKER_EXTRA_ARGS) -t $@ -f $< $(dir $<)

View File

@ -1,81 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"net"
flag "github.com/spf13/pflag"
"k8s.io/minikube/pkg/localkube"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/util"
)
func NewLocalkubeServer() *localkube.LocalkubeServer {
_, defaultServiceCIDR, _ := net.ParseCIDR(util.DefaultServiceCIDR)
return &localkube.LocalkubeServer{
Containerized: false,
DNSDomain: util.DefaultDNSDomain,
LocalkubeDirectory: util.DefaultLocalkubeDirectory,
APIServerAddress: net.ParseIP("0.0.0.0"),
APIServerPort: util.APIServerPort,
APIServerInsecureAddress: net.ParseIP("127.0.0.1"),
APIServerInsecurePort: 0,
APIServerName: constants.APIServerName,
ShouldGenerateKubeconfig: false,
ShouldGenerateCerts: true,
ShowVersion: false,
ServiceClusterIPRange: *defaultServiceCIDR,
RuntimeConfig: map[string]string{"api/all": "true"},
ExtraConfig: util.ExtraOptionSlice{},
}
}
// AddFlags adds flags for a specific LocalkubeServer
func AddFlags(s *localkube.LocalkubeServer) {
flag.BoolVar(&s.Containerized, "containerized", s.Containerized, "If kubelet should run in containerized mode")
flag.BoolVar(&s.EnableDNS, "enable-dns", s.EnableDNS, "DEPRECATED: Please run kube-dns as a cluster addon")
flag.StringVar(&s.DNSDomain, "dns-domain", s.DNSDomain, "The cluster dns domain")
flag.StringVar(&s.LocalkubeDirectory, "localkube-directory", s.LocalkubeDirectory, "The directory localkube will store files in")
flag.IPNetVar(&s.ServiceClusterIPRange, "service-cluster-ip-range", s.ServiceClusterIPRange, "The service-cluster-ip-range for the apiserver")
flag.IPVar(&s.APIServerAddress, "apiserver-address", s.APIServerAddress, "The address the apiserver will listen securely on")
flag.IntVar(&s.APIServerPort, "apiserver-port", s.APIServerPort, "The port the apiserver will listen securely on")
flag.IPVar(&s.APIServerInsecureAddress, "apiserver-insecure-address", s.APIServerInsecureAddress, "The address the apiserver will listen insecurely on")
flag.IntVar(&s.APIServerInsecurePort, "apiserver-insecure-port", s.APIServerInsecurePort, "The port the apiserver will listen insecurely on")
flag.StringVar(&s.APIServerName, "apiserver-name", s.APIServerName, "The apiserver name which is used in the generated certificate for localkube/kubernetes. This can be used if you want to make the API server available from outside the machine")
flag.BoolVar(&s.ShouldGenerateKubeconfig, "generate-kubeconfig", s.ShouldGenerateKubeconfig, "If localkube should generate its own kubeconfig")
flag.BoolVar(&s.ShouldGenerateCerts, "generate-certs", s.ShouldGenerateCerts, "If localkube should generate it's own certificates")
flag.BoolVar(&s.ShowVersion, "show-version", s.ShowVersion, "If localkube should just print the version and exit.")
flag.BoolVar(&s.ShowHostIP, "host-ip", s.ShowHostIP, "If localkube should just print the host IP and exit.")
flag.Var(&s.RuntimeConfig, "runtime-config", "A set of key=value pairs that describe runtime configuration that may be passed to apiserver. apis/<groupVersion> key can be used to turn on/off specific api versions. apis/<groupVersion>/<resource> can be used to turn on/off specific resources. api/all and api/legacy are special keys to control all and legacy api versions respectively.")
flag.IPVar(&s.NodeIP, "node-ip", s.NodeIP, "IP address of the node. If set, kubelet will use this IP address for the node.")
flag.StringVar(&s.ContainerRuntime, "container-runtime", "", "The container runtime to be used")
flag.StringVar(&s.RemoteRuntimeEndpoint, "remote-runtime-endpoint", "", "The container runtime endpoint (CRI) to be used (if this is set, then --container-runtime is forced as 'remote')")
flag.StringVar(&s.RemoteImageEndpoint, "remote-image-endpoint", "", "The container image endpoint (CRI) to be used (if this is set, then --container-runtime is forced as 'remote')")
flag.StringVar(&s.NetworkPlugin, "network-plugin", "", "The name of the network plugin")
flag.StringVar(&s.FeatureGates, "feature-gates", "", "A set of key=value pairs that describe feature gates for alpha/experimental features.")
flag.Var(&s.ExtraConfig, "extra-config", "A set of key=value pairs that describe configuration that may be passed to different components. The key should be '.' separated, and the first part before the dot is the component to apply the configuration to.")
// These two come from vendor/ packages that use flags. We should hide them
flag.CommandLine.MarkHidden("google-json-key")
flag.CommandLine.MarkHidden("log-flush-frequency")
// Parse them
flag.Parse()
}

View File

@ -1,37 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
goflag "flag"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var RootCmd = &cobra.Command{
Use: "localkube",
Short: "localkube is an all-in-one kubernetes binary.",
Long: `localkube is an all-in-one kubernetes binary that runs all Kubernetes server binaries.`,
Run: func(command *cobra.Command, args []string) {
StartLocalkube()
},
}
func init() {
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
}

View File

@ -1,145 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"os/signal"
"github.com/golang/glog"
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/capabilities"
"k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/minikube/pkg/localkube"
"k8s.io/minikube/pkg/version"
)
// The main instance of the current localkube server that is started
var Server *localkube.LocalkubeServer
func StartLocalkube() {
if Server.ShowVersion {
fmt.Println("localkube version:", version.GetVersion())
os.Exit(0)
}
if Server.ShowHostIP {
hostIP, _ := Server.GetHostIP()
fmt.Println("localkube host ip: ", hostIP.String())
os.Exit(0)
}
if os.Geteuid() != 0 {
fmt.Println("localkube should run as root!")
os.Exit(1)
}
SetupServer(Server)
Server.StartAll()
defer Server.StopAll()
interruptChan := make(chan os.Signal, 1)
signal.Notify(interruptChan, os.Interrupt)
<-interruptChan
fmt.Println("Shutting down...")
}
func SetupServer(s *localkube.LocalkubeServer) {
if s.ContainerRuntime == "remote" && s.RemoteRuntimeEndpoint == "" {
panic("Failed to connect to --container-runtime='remote' with no --container-runtime-endpoint")
}
// localkube flags can handle `--container-runtime=remote --remote-runtime-endpoint=/var/run/crio/crio.sock --remote-image-endpoint=/var/run/crio/crio.sock`,
// but this allows for a convenience of just e.g.`--container-runtime=crio` and the same for minikube
switch s.ContainerRuntime {
case "crio", "cri-o":
s.ContainerRuntime = "remote"
s.RemoteRuntimeEndpoint = "unix:///var/run/crio/crio.sock"
s.RemoteImageEndpoint = "unix:///var/run/crio/crio.sock"
}
if s.ShouldGenerateCerts {
if err := s.GenerateCerts(); err != nil {
fmt.Println("Failed to create certificates!")
panic(err)
}
}
if s.ShouldGenerateKubeconfig {
if err := s.GenerateKubeconfig(); err != nil {
fmt.Println("Failed to create kubeconfig!")
panic(err)
}
}
// Set feature gates
if s.FeatureGates != "" {
glog.Infof("Setting Feature Gates: %s", s.FeatureGates)
err := feature.DefaultFeatureGate.Set(s.FeatureGates)
if err != nil {
fmt.Printf("Error setting feature gates: %s", err)
}
}
// Setup capabilities. This can only be done once per binary.
allSources, _ := types.GetValidatedSources([]string{types.AllSource})
c := capabilities.Capabilities{
AllowPrivileged: true,
PrivilegedSources: capabilities.PrivilegedSources{
HostNetworkSources: allSources,
HostIPCSources: allSources,
HostPIDSources: allSources,
},
}
capabilities.Initialize(c)
// setup etcd
etcd, err := s.NewEtcd(s.GetEtcdDataDirectory())
if err != nil {
panic(err)
}
// Start etcd first
etcd.Start()
// setup access to etcd
netIP, _ := s.GetHostIP()
fmt.Printf("localkube host ip address: %s\n", netIP.String())
// setup apiserver
apiserver := s.NewAPIServer()
s.AddServer(apiserver)
// setup controller-manager
controllerManager := s.NewControllerManagerServer()
s.AddServer(controllerManager)
// setup scheduler
scheduler := s.NewSchedulerServer()
s.AddServer(scheduler)
// setup kubelet
kubelet := s.NewKubeletServer()
s.AddServer(kubelet)
// setup proxy
proxy := s.NewProxyServer()
s.AddServer(proxy)
}

View File

@ -1,36 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"os"
"k8s.io/minikube/cmd/localkube/cmd"
)
func main() {
// Create the localkube server and parse the flags
cmd.Server = cmd.NewLocalkubeServer()
cmd.AddFlags(cmd.Server)
if err := cmd.RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}

View File

@ -36,8 +36,8 @@ var (
// logsCmd represents the logs command
var logsCmd = &cobra.Command{
Use: "logs",
Short: "Gets the logs of the running localkube instance, used for debugging minikube, not user code",
Long: `Gets the logs of the running localkube instance, used for debugging minikube, not user code.`,
Short: "Gets the logs of the running instance, used for debugging minikube, not user code",
Long: `Gets the logs of the running instance, used for debugging minikube, not user code.`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {

View File

@ -35,7 +35,6 @@ import (
"k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/bootstrapper/kubeadm"
"k8s.io/minikube/pkg/minikube/bootstrapper/localkube"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/notify"
@ -47,7 +46,6 @@ var dirs = [...]string{
constants.MakeMiniPath("machines"),
constants.MakeMiniPath("cache"),
constants.MakeMiniPath("cache", "iso"),
constants.MakeMiniPath("cache", "localkube"),
constants.MakeMiniPath("config"),
constants.MakeMiniPath("addons"),
constants.MakeMiniPath("files"),
@ -173,17 +171,6 @@ func GetClusterBootstrapper(api libmachine.API, bootstrapperName string) (bootst
var b bootstrapper.Bootstrapper
var err error
switch bootstrapperName {
case bootstrapper.BootstrapperTypeLocalkube:
if viper.GetBool(config.ShowBootstrapperDeprecationNotification) {
fmt.Fprintln(os.Stderr, `WARNING: The localkube bootstrapper is now deprecated and support for it
will be removed in a future release. Please consider switching to the kubeadm bootstrapper, which
is intended to replace the localkube bootstrapper. To disable this message, run
[minikube config set ShowBootstrapperDeprecationNotification false]`)
}
b, err = localkube.NewLocalkubeBootstrapper(api)
if err != nil {
return nil, errors.Wrap(err, "getting localkube bootstrapper")
}
case bootstrapper.BootstrapperTypeKubeadm:
b, err = kubeadm.NewKubeadmBootstrapper(api)
if err != nil {

View File

@ -40,7 +40,6 @@ import (
"k8s.io/minikube/pkg/minikube/cluster"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/kubernetes_versions"
"k8s.io/minikube/pkg/minikube/machine"
pkgutil "k8s.io/minikube/pkg/util"
"k8s.io/minikube/pkg/util/kubeconfig"
@ -376,19 +375,6 @@ This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_
}
}
func validateK8sVersion(version string) {
validVersion, err := kubernetes_versions.IsValidLocalkubeVersion(version, constants.KubernetesVersionGCSURL)
if err != nil {
glog.Errorln("Error getting valid kubernetes versions", err)
os.Exit(1)
}
if !validVersion {
fmt.Println("Invalid Kubernetes version.")
kubernetes_versions.PrintKubernetesVersionsFromGCS(os.Stdout)
os.Exit(1)
}
}
func init() {
startCmd.Flags().Bool(keepContext, constants.DefaultKeepContext, "This will keep the existing kubectl context and will create a minikube context.")
startCmd.Flags().Bool(createMount, false, "This will start the mount daemon and automatically mount files into minikube")

View File

@ -22,7 +22,7 @@ import (
"os"
"github.com/golang/glog"
"k8s.io/minikube/pkg/localkube"
"k8s.io/minikube/pkg/storage"
)
func main() {
@ -33,7 +33,7 @@ func main() {
}
flag.Parse()
if err := localkube.StartStorageProvisioner(); err != nil {
if err := storage.StartStorageProvisioner(); err != nil {
glog.Exit(err)
}

View File

@ -44,9 +44,3 @@ cp -r ${KUBE_ROOT}/pkg/generated/openapi ${MINIKUBE_ROOT}/vendor/k8s.io/kubernet
godep::remove_staging_from_json
git checkout -- ${MINIKUBE_ROOT}/vendor/golang.org/x/sys/windows
pushd ${MINIKUBE_ROOT} >/dev/null
git apply ${MINIKUBE_ROOT}/hack/tpr-patch.diff
git apply ${MINIKUBE_ROOT}/hack/kube-proxy-patch.diff
popd >/dev/null

View File

@ -43,13 +43,3 @@ gsutil -m cp out/* gs://$BUCKET/releases/$TAGNAME/
# Bump latest
gsutil cp -r gs://$BUCKET/releases/$TAGNAME/* gs://$BUCKET/releases/latest/
# Upload localkube containers
TAG="$(docker images "gcr.io/k8s-minikube/localkube-image" --format="{{.Tag}}" | head -n 1)"
gcloud docker -- push gcr.io/k8s-minikube/localkube-image:$TAG
TAG="$(docker images "gcr.io/k8s-minikube/localkube-dind-image" --format="{{.Tag}}" | head -n 1)"
gcloud docker -- push gcr.io/k8s-minikube/localkube-dind-image:$TAG
TAG="$(docker images "gcr.io/k8s-minikube/localkube-dind-image-devshell" --format="{{.Tag}}" | head -n 1)"
gcloud docker -- push gcr.io/k8s-minikube/localkube-dind-image-devshell:$TAG

View File

@ -1,41 +0,0 @@
diff --git b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server.go a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server.go
index 2f9ea2ea..35a7c14e 100644
--- b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server.go
+++ a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server.go
@@ -318,6 +318,10 @@ func (o *Options) ApplyDefaults(in *kubeproxyconfig.KubeProxyConfiguration) (*ku
return out, nil
}
+func (o *Options) SetConfig(in *kubeproxyconfig.KubeProxyConfiguration) {
+ o.config = in
+}
+
// NewProxyCommand creates a *cobra.Command object with default parameters
func NewProxyCommand() *cobra.Command {
opts := NewOptions()
diff --git b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_others.go a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_others.go
index 380e83e2..51bb09fd 100644
--- b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_others.go
+++ a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/server_others.go
@@ -72,7 +72,7 @@ func newProxyServer(
if c, err := configz.New(proxyconfigapi.GroupName); err == nil {
c.Set(config)
} else {
- return nil, fmt.Errorf("unable to register configz: %s", err)
+ glog.Warningf("unable to register configz: %s", err)
}
protocol := utiliptables.ProtocolIpv4
diff --git b/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go a/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go
index 93982f89..a116da41 100644
--- b/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go
+++ a/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/server.go
@@ -380,7 +380,7 @@ func NewSchedulerServer(config *componentconfig.KubeSchedulerConfiguration, mast
if c, err := configz.New("componentconfig"); err == nil {
c.Set(config)
} else {
- return nil, fmt.Errorf("unable to register configz: %s", err)
+ glog.Warningf("unable to register configz: %s", err)
}
// Prepare some Kube clients.

View File

@ -1,18 +0,0 @@
diff --git a/vendor/k8s.io/apimachinery/pkg/apimachinery/registered/registered.go b/vendor/k8s.io/apimachinery/pkg/apimachinery/registered/registered.go
index f2e32c88c..f1c96c43d 100644
--- a/vendor/k8s.io/apimachinery/pkg/apimachinery/registered/registered.go
+++ b/vendor/k8s.io/apimachinery/pkg/apimachinery/registered/registered.go
@@ -282,7 +282,12 @@ func (m *APIRegistrationManager) RESTMapper(versionPatterns ...schema.GroupVersi
for enabledVersion := range m.enabledVersions {
if !unionedGroups.Has(enabledVersion.Group) {
unionedGroups.Insert(enabledVersion.Group)
- groupMeta := m.groupMetaMap[enabledVersion.Group]
+ groupMeta, found := m.groupMetaMap[enabledVersion.Group]
+ // TODO(r2d4): hack until tprs are decoupled from restMapper
+ if !found {
+ glog.Warningf("Could not find groupMeta for %s", enabledVersion.Group)
+ continue
+ }
unionMapper = append(unionMapper, groupMeta.RESTMapper)
}
}

View File

@ -1,100 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"net"
"path"
"strconv"
"k8s.io/minikube/pkg/util"
"github.com/coreos/etcd/embed"
apiserveroptions "k8s.io/apiserver/pkg/server/options"
"k8s.io/apiserver/pkg/storage/storagebackend"
genericoptions "k8s.io/apiserver/pkg/server/options"
apiserver "k8s.io/kubernetes/cmd/kube-apiserver/app"
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
)
func (lk LocalkubeServer) NewAPIServer() Server {
return NewSimpleServer("apiserver", serverInterval, StartAPIServer(lk), readyFunc(lk))
}
func StartAPIServer(lk LocalkubeServer) func() error {
config := options.NewServerRunOptions()
config.SecureServing.BindAddress = lk.APIServerAddress
config.SecureServing.BindPort = lk.APIServerPort
config.InsecureServing.BindAddress = lk.APIServerInsecureAddress
config.InsecureServing.BindPort = lk.APIServerInsecurePort
config.Authentication.ClientCert.ClientCA = lk.GetCAPublicKeyCertPath()
config.SecureServing.ServerCert.CertKey.CertFile = lk.GetPublicKeyCertPath()
config.SecureServing.ServerCert.CertKey.KeyFile = lk.GetPrivateKeyCertPath()
config.Admission.PluginNames = util.DefaultAdmissionControllers
// use localkube etcd
config.Etcd.StorageConfig.ServerList = []string{embed.DefaultListenClientURLs}
config.Etcd.StorageConfig.Type = storagebackend.StorageTypeETCD3
// set Service IP range
config.ServiceClusterIPRange = lk.ServiceClusterIPRange
config.Etcd.EnableWatchCache = true
config.Features = &apiserveroptions.FeatureOptions{
EnableProfiling: true,
}
// defaults from apiserver command
config.GenericServerRunOptions.MinRequestTimeout = 1800
config.AllowPrivileged = true
config.APIEnablement = &genericoptions.APIEnablementOptions{
RuntimeConfig: lk.RuntimeConfig,
}
config.ProxyClientCertFile = lk.GetProxyClientPublicKeyCertPath()
config.ProxyClientKeyFile = lk.GetProxyClientPrivateKeyCertPath()
config.Authentication.RequestHeader.AllowedNames =
[]string{}
config.Authentication.RequestHeader.UsernameHeaders =
[]string{"X-Remote-User"}
config.Authentication.RequestHeader.GroupHeaders =
[]string{"X-Remote-Group"}
config.Authentication.RequestHeader.ExtraHeaderPrefixes =
[]string{"X-Remote-Extra-"}
config.Authentication.RequestHeader.ClientCAFile =
lk.GetProxyClientCAPublicKeyCertPath()
lk.SetExtraConfigForComponent("apiserver", &config)
return func() error {
stop := make(chan struct{})
return apiserver.Run(config, stop)
}
}
func readyFunc(lk LocalkubeServer) HealthCheck {
return healthCheck(lk.GetAPIServerProtocol()+path.Join(
net.JoinHostPort("localhost", strconv.Itoa(lk.APIServerPort)), "healthz"), lk)
}

View File

@ -1,55 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
controllerManager "k8s.io/kubernetes/cmd/kube-controller-manager/app"
"k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
"k8s.io/minikube/pkg/util"
)
func (lk LocalkubeServer) NewControllerManagerServer() Server {
return NewSimpleServer("controller-manager", serverInterval, StartControllerManagerServer(lk), noop)
}
func StartControllerManagerServer(lk LocalkubeServer) func() error {
opts := options.NewKubeControllerManagerOptions()
opts.Generic.Kubeconfig = util.DefaultKubeConfigPath
// defaults from command
opts.Generic.ComponentConfig.DeletingPodsQps = 0.1
opts.Generic.ComponentConfig.DeletingPodsBurst = 10
opts.Generic.ComponentConfig.NodeEvictionRate = 0.1
opts.Generic.ComponentConfig.EnableProfiling = true
opts.Generic.ComponentConfig.VolumeConfiguration.EnableHostPathProvisioning = true
opts.Generic.ComponentConfig.VolumeConfiguration.EnableDynamicProvisioning = true
opts.Generic.ComponentConfig.ServiceAccountKeyFile = lk.GetPrivateKeyCertPath()
opts.Generic.ComponentConfig.RootCAFile = lk.GetCAPublicKeyCertPath()
lk.SetExtraConfigForComponent("controller-manager", &opts)
cfg := config.Config{}
if err := opts.ApplyTo(&cfg); err != nil {
panic(err)
}
return func() error {
return controllerManager.Run(cfg.Complete())
}
}

View File

@ -1,75 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"time"
"github.com/coreos/etcd/embed"
"github.com/golang/glog"
)
const (
// EtcdName is the name of the extra-config component for etcd
EtcdName = "etcd"
)
// EtcdServer is a Server which manages an Etcd cluster
type EtcdServer struct {
Etcd *embed.Etcd
Config *embed.Config
}
// NewEtcd creates a new default etcd Server using 'dataDir' for persistence. Panics if could not be configured.
func (lk LocalkubeServer) NewEtcd(dataDir string) (*EtcdServer, error) {
cfg := embed.NewConfig()
cfg.Dir = dataDir
lk.SetExtraConfigForComponent(EtcdName, &cfg)
return &EtcdServer{
Config: cfg,
}, nil
}
// Start starts the etcd server and listening for client connections
func (e *EtcdServer) Start() {
var err error
e.Etcd, err = embed.StartEtcd(e.Config)
if err != nil {
glog.Fatalf("Error starting up etcd: %s", err)
}
select {
case <-e.Etcd.Server.ReadyNotify():
glog.Infoln("Etcd server is ready")
case <-time.After(60 * time.Second):
e.Etcd.Server.Stop() // trigger a shutdown
glog.Fatalf("Etcd took too long to start")
}
}
// Stop closes all connections and stops the Etcd server
func (e *EtcdServer) Stop() {
if e.Etcd != nil {
e.Etcd.Server.Stop()
}
}
// Name returns the servers unique name
func (e EtcdServer) Name() string {
return e.Config.Name
}

View File

@ -1,83 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
kubelet "k8s.io/kubernetes/cmd/kubelet/app"
"k8s.io/kubernetes/cmd/kubelet/app/options"
"k8s.io/minikube/pkg/util"
)
func (lk LocalkubeServer) NewKubeletServer() Server {
return NewSimpleServer("kubelet", serverInterval, StartKubeletServer(lk), noop)
}
func StartKubeletServer(lk LocalkubeServer) func() error {
config, err := options.NewKubeletServer()
if err != nil {
return func() error { return err }
}
dnsIP, err := util.GetDNSIP(lk.ServiceClusterIPRange.String())
if err != nil {
return func() error { return err }
}
// Master details
config.KubeConfig = util.DefaultKubeConfigPath
// Set containerized based on the flag
config.Containerized = lk.Containerized
config.AllowPrivileged = true
config.StaticPodPath = "/etc/kubernetes/manifests"
// Networking
config.ClusterDomain = lk.DNSDomain
config.ClusterDNS = []string{dnsIP.String()}
// For kubenet plugin.
config.PodCIDR = "10.180.1.0/24"
config.NodeIP = lk.NodeIP.String()
config.FailSwapOn = false
if lk.NetworkPlugin != "" {
config.NetworkPluginName = lk.NetworkPlugin
}
// Runtime
if lk.ContainerRuntime != "" {
config.ContainerRuntime = lk.ContainerRuntime
}
if lk.RemoteRuntimeEndpoint != "" {
config.RemoteRuntimeEndpoint = lk.RemoteRuntimeEndpoint
}
if lk.RemoteImageEndpoint != "" {
config.RemoteImageEndpoint = lk.RemoteImageEndpoint
}
lk.SetExtraConfigForComponent("kubelet", &config)
// Use the host's resolver config
if lk.Containerized {
config.ResolverConfig = "/rootfs/etc/resolv.conf"
} else {
config.ResolverConfig = "/etc/resolv.conf"
}
return func() error {
return kubelet.Run(config, nil)
}
}

View File

@ -1,369 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"net"
"net/http"
"path"
"strconv"
"strings"
"github.com/golang/glog"
"github.com/pkg/errors"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/util/flag"
"k8s.io/minikube/pkg/util/kubeconfig"
"k8s.io/minikube/pkg/util"
)
const serverInterval = 200
// LocalkubeServer provides a fully functional Kubernetes cluster running entirely through goroutines
type LocalkubeServer struct {
// Inherits Servers
Servers
// Options
Containerized bool
EnableDNS bool
DNSDomain string
LocalkubeDirectory string
ServiceClusterIPRange net.IPNet
APIServerAddress net.IP
APIServerPort int
APIServerInsecureAddress net.IP
APIServerInsecurePort int
APIServerName string
ShouldGenerateCerts bool
ShouldGenerateKubeconfig bool
ShowVersion bool
ShowHostIP bool
RuntimeConfig flag.ConfigurationMap
NodeIP net.IP
ContainerRuntime string
RemoteRuntimeEndpoint string
RemoteImageEndpoint string
NetworkPlugin string
FeatureGates string
ExtraConfig util.ExtraOptionSlice
}
func (lk *LocalkubeServer) AddServer(server Server) {
lk.Servers = append(lk.Servers, server)
}
func (lk LocalkubeServer) GetEtcdDataDirectory() string {
return path.Join(lk.LocalkubeDirectory, "etcd")
}
func (lk LocalkubeServer) GetDNSDataDirectory() string {
return path.Join(lk.LocalkubeDirectory, "dns")
}
func (lk LocalkubeServer) GetCertificateDirectory() string {
return path.Join(lk.LocalkubeDirectory, "certs")
}
func (lk LocalkubeServer) GetPrivateKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "apiserver.key")
}
func (lk LocalkubeServer) GetPublicKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "apiserver.crt")
}
func (lk LocalkubeServer) GetCAPrivateKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "ca.key")
}
func (lk LocalkubeServer) GetCAPublicKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "ca.crt")
}
func (lk LocalkubeServer) GetProxyClientPrivateKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "proxy-client.key")
}
func (lk LocalkubeServer) GetProxyClientPublicKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "proxy-client.crt")
}
func (lk LocalkubeServer) GetProxyClientCAPublicKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "proxy-client-ca.crt")
}
func (lk LocalkubeServer) GetProxyClientCAPrivateKeyCertPath() string {
return path.Join(lk.GetCertificateDirectory(), "proxy-client-ca.key")
}
func (lk LocalkubeServer) GetAPIServerSecureURL() string {
return fmt.Sprintf("https://%s:%d", lk.APIServerAddress.String(), lk.APIServerPort)
}
func (lk LocalkubeServer) GetAPIServerInsecureURL() string {
if lk.APIServerInsecurePort != 0 {
return fmt.Sprintf("http://%s:%d", lk.APIServerInsecureAddress.String(), lk.APIServerInsecurePort)
}
return ""
}
func (lk LocalkubeServer) GetAPIServerProtocol() string {
if lk.APIServerInsecurePort != 0 {
return "http://"
}
return "https://"
}
func (lk LocalkubeServer) GetTransport() (*http.Transport, error) {
if lk.APIServerInsecurePort != 0 {
return &http.Transport{}, nil
}
cert, err := tls.LoadX509KeyPair(lk.GetPublicKeyCertPath(), lk.GetPrivateKeyCertPath())
if err != nil {
glog.Error(err)
return &http.Transport{}, err
}
// Load CA cert
caCert, err := ioutil.ReadFile(lk.GetCAPublicKeyCertPath())
if err != nil {
glog.Warning(err)
return &http.Transport{}, err
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
tlsConfig.BuildNameToCertificate()
return &http.Transport{TLSClientConfig: tlsConfig}, nil
}
// Get the host's public IP address
func (lk LocalkubeServer) GetHostIP() (net.IP, error) {
return utilnet.ChooseBindAddress(net.ParseIP("0.0.0.0"))
}
func (lk LocalkubeServer) getExtraConfigForComponent(component string) []util.ExtraOption {
e := []util.ExtraOption{}
for _, c := range lk.ExtraConfig {
if c.Component == component {
e = append(e, c)
}
}
return e
}
func (lk LocalkubeServer) SetExtraConfigForComponent(component string, config interface{}) {
extra := lk.getExtraConfigForComponent(component)
for _, e := range extra {
glog.Infof("Setting %s to %s on %s.\n", e.Key, e.Value, component)
if err := util.FindAndSet(e.Key, config, e.Value); err != nil {
glog.Warningf("Unable to set %s to %s. Error: %s", e.Key, e.Value, err)
}
}
}
func (lk LocalkubeServer) GetFeatureGates() (map[string]bool, error) {
fg := map[string]bool{}
if lk.FeatureGates == "" {
return fg, nil
}
gates := strings.Split(lk.FeatureGates, ",")
for _, g := range gates {
kvp := strings.SplitN(g, "=", 2)
if len(kvp) != 2 {
return nil, fmt.Errorf("invalid feature gate specification: %s", g)
}
value, err := strconv.ParseBool(kvp[1])
if err != nil {
return nil, fmt.Errorf("invalid feature gate specification: %s", g)
}
fg[kvp[0]] = value
}
return fg, nil
}
func (lk LocalkubeServer) loadCert(path string) (*x509.Certificate, error) {
contents, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
decoded, _ := pem.Decode(contents)
if decoded == nil {
return nil, fmt.Errorf("Unable to decode certificate.")
}
return x509.ParseCertificate(decoded.Bytes)
}
func (lk LocalkubeServer) shouldGenerateCerts(ips []net.IP) bool {
if !(util.CanReadFile(lk.GetPublicKeyCertPath()) &&
util.CanReadFile(lk.GetPrivateKeyCertPath())) {
fmt.Println("Regenerating certs because the files aren't readable")
return true
}
cert, err := lk.loadCert(lk.GetPublicKeyCertPath())
if err != nil {
fmt.Println("Regenerating certs because there was an error loading the certificate: ", err)
return true
}
certIPs := map[string]bool{}
for _, certIP := range cert.IPAddresses {
certIPs[certIP.String()] = true
}
for _, ip := range ips {
if _, ok := certIPs[ip.String()]; !ok {
fmt.Println("Regenerating certs becase an IP is missing: ", ip)
return true
}
}
return false
}
func (lk LocalkubeServer) shouldGenerateCACerts() bool {
if !(util.CanReadFile(lk.GetCAPublicKeyCertPath()) &&
util.CanReadFile(lk.GetCAPrivateKeyCertPath())) {
fmt.Println("Regenerating CA certs because the files aren't readable")
return true
}
_, err := lk.loadCert(lk.GetCAPublicKeyCertPath())
if err != nil {
fmt.Println("Regenerating CA certs because there was an error loading the certificate: ", err)
return true
}
return false
}
func (lk LocalkubeServer) GenerateKubeconfig() error {
if !lk.ShouldGenerateKubeconfig {
return nil
}
// setup kubeconfig
kubeConfigFile := util.DefaultKubeConfigPath
glog.Infof("Setting up kubeconfig at: %s", kubeConfigFile)
kubeHost := "http://127.0.0.1:" + strconv.Itoa(lk.APIServerInsecurePort)
//TODO(aaron-prindle) configure this so that it can generate secure certs as well
kubeCfgSetup := &kubeconfig.KubeConfigSetup{
ClusterName: lk.APIServerName,
ClusterServerAddress: kubeHost,
KeepContext: false,
}
kubeCfgSetup.SetKubeConfigFile(kubeConfigFile)
if err := kubeconfig.SetupKubeConfig(kubeCfgSetup); err != nil {
glog.Errorln("Error setting up kubeconfig: ", err)
return err
}
return nil
}
func (lk LocalkubeServer) getAllIPs() ([]net.IP, error) {
serviceIP, err := util.GetServiceClusterIP(lk.ServiceClusterIPRange.String())
if err != nil {
return nil, errors.Wrap(err, "getting service cluster ip")
}
ips := []net.IP{serviceIP}
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
ipnet, ok := addr.(*net.IPNet)
if !ok {
fmt.Println("Skipping: ", addr)
continue
}
ips = append(ips, ipnet.IP)
}
return ips, nil
}
func (lk LocalkubeServer) GenerateCerts() error {
if !lk.shouldGenerateCACerts() {
fmt.Println(
"Using these existing CA certs: ", lk.GetCAPublicKeyCertPath(),
lk.GetCAPrivateKeyCertPath(), lk.GetProxyClientCAPublicKeyCertPath(),
lk.GetProxyClientCAPrivateKeyCertPath(),
)
} else {
fmt.Println("Creating CA cert")
if err := util.GenerateCACert(
lk.GetCAPublicKeyCertPath(), lk.GetCAPrivateKeyCertPath(),
lk.APIServerName,
); err != nil {
fmt.Println("Failed to create CA cert: ", err)
return err
}
fmt.Println("Creating proxy client CA cert")
if err := util.GenerateCACert(
lk.GetProxyClientCAPublicKeyCertPath(),
lk.GetProxyClientCAPrivateKeyCertPath(), "proxyClientCA",
); err != nil {
fmt.Println("Failed to create proxy client CA cert: ", err)
return err
}
}
ips, err := lk.getAllIPs()
if err != nil {
return err
}
if !lk.shouldGenerateCerts(ips) {
fmt.Println(
"Using these existing certs: ", lk.GetPublicKeyCertPath(),
lk.GetPrivateKeyCertPath(), lk.GetProxyClientPublicKeyCertPath(),
lk.GetProxyClientPrivateKeyCertPath(),
)
return nil
}
fmt.Println("Creating cert with IPs: ", ips)
if err := util.GenerateSignedCert(
lk.GetPublicKeyCertPath(), lk.GetPrivateKeyCertPath(), "minikube", ips,
util.GetAlternateDNS(lk.DNSDomain), lk.GetCAPublicKeyCertPath(),
lk.GetCAPrivateKeyCertPath(),
); err != nil {
fmt.Println("Failed to create cert: ", err)
return err
}
if err := util.GenerateSignedCert(
lk.GetProxyClientPublicKeyCertPath(), lk.GetProxyClientPrivateKeyCertPath(),
"aggregator", []net.IP{}, []string{},
lk.GetProxyClientCAPublicKeyCertPath(),
lk.GetProxyClientCAPrivateKeyCertPath(),
); err != nil {
fmt.Println("Failed to create proxy client cert: ", err)
return err
}
return nil
}

View File

@ -1,124 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"io/ioutil"
"net"
"os"
"path/filepath"
"testing"
"k8s.io/minikube/pkg/minikube/tests"
"k8s.io/minikube/pkg/util"
)
var testIPs = []net.IP{net.ParseIP("1.2.3.4")}
func TestGenerateCerts(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
os.Mkdir(filepath.Join(tempDir, "certs"), 0777)
_, ipRange, _ := net.ParseCIDR(util.DefaultServiceCIDR)
lk := LocalkubeServer{
LocalkubeDirectory: tempDir,
ServiceClusterIPRange: *ipRange,
}
if err := lk.GenerateCerts(); err != nil {
t.Fatalf("Unexpected error generating certs: %s", err)
}
for _, f := range []string{"apiserver.crt", "apiserver.key"} {
p := filepath.Join(tempDir, "certs", f)
_, err := os.Stat(p)
if os.IsNotExist(err) {
t.Fatalf("Certificate not created: %s", p)
}
}
_, err := lk.loadCert(filepath.Join(tempDir, "certs", "apiserver.crt"))
if err != nil {
t.Fatalf("Error parsing cert: %s", err)
}
}
func TestShouldGenerateCertsNoFiles(t *testing.T) {
lk := LocalkubeServer{LocalkubeDirectory: "baddir"}
if !lk.shouldGenerateCerts(testIPs) {
t.Fatalf("No certs exist, we should generate.")
}
}
func TestShouldGenerateCertsOneFile(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
os.Mkdir(filepath.Join(tempDir, "certs"), 0777)
ioutil.WriteFile(filepath.Join(tempDir, "certs", "apiserver.crt"), []byte(""), 0644)
lk := LocalkubeServer{LocalkubeDirectory: tempDir}
if !lk.shouldGenerateCerts(testIPs) {
t.Fatalf("Not all certs exist, we should generate.")
}
}
func TestShouldGenerateCertsBadFiles(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
os.Mkdir(filepath.Join(tempDir, "certs"), 0777)
for _, f := range []string{"apiserver.crt", "apiserver.key"} {
ioutil.WriteFile(filepath.Join(tempDir, "certs", f), []byte(""), 0644)
}
lk := LocalkubeServer{LocalkubeDirectory: tempDir}
if !lk.shouldGenerateCerts(testIPs) {
t.Fatalf("Certs are badly formatted, we should generate.")
}
}
func TestShouldGenerateCertsMismatchedIP(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
os.Mkdir(filepath.Join(tempDir, "certs"), 0777)
_, ipRange, _ := net.ParseCIDR(util.DefaultServiceCIDR)
lk := LocalkubeServer{
LocalkubeDirectory: tempDir,
ServiceClusterIPRange: *ipRange,
}
lk.GenerateCerts()
if !lk.shouldGenerateCerts([]net.IP{net.ParseIP("4.3.2.1")}) {
t.Fatalf("IPs don't match, we should generate.")
}
}
func TestShouldNotGenerateCerts(t *testing.T) {
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
os.Mkdir(filepath.Join(tempDir, "certs"), 0777)
_, ipRange, _ := net.ParseCIDR(util.DefaultServiceCIDR)
lk := LocalkubeServer{
LocalkubeDirectory: tempDir,
ServiceClusterIPRange: *ipRange,
}
lk.GenerateCerts()
ips, _ := lk.getAllIPs()
if lk.shouldGenerateCerts(ips) {
t.Fatalf("IPs match, we should not generate.")
}
}

View File

@ -1,78 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
kubeproxy "k8s.io/kubernetes/cmd/kube-proxy/app"
"k8s.io/minikube/pkg/util"
"time"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/kubelet/qos"
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
)
var (
MasqueradeBit = int32(14)
OOMScoreAdj = int32(qos.KubeProxyOOMScoreAdj)
)
func (lk LocalkubeServer) NewProxyServer() Server {
return NewSimpleServer("proxy", serverInterval, StartProxyServer(lk), noop)
}
func StartProxyServer(lk LocalkubeServer) func() error {
bindaddress := lk.APIServerAddress.String()
if lk.APIServerInsecurePort != 0 {
bindaddress = lk.APIServerInsecureAddress.String()
}
opts := kubeproxy.NewOptions()
fg, err := lk.GetFeatureGates()
if err != nil {
panic(err)
}
config := &kubeproxyconfig.KubeProxyConfiguration{
OOMScoreAdj: &OOMScoreAdj,
ClientConnection: kubeproxyconfig.ClientConnectionConfiguration{
Burst: 10,
QPS: 5,
KubeConfigFile: util.DefaultKubeConfigPath,
},
ConfigSyncPeriod: v1.Duration{Duration: 15 * time.Minute},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: &MasqueradeBit,
SyncPeriod: v1.Duration{Duration: 30 * time.Second},
MinSyncPeriod: v1.Duration{Duration: 5 * time.Second},
},
BindAddress: bindaddress,
Mode: kubeproxyconfig.ProxyModeIPTables,
FeatureGates: fg,
// Disable the healthz check
HealthzBindAddress: "",
}
if _, err := opts.ApplyDefaults(config); err != nil {
panic(err)
}
lk.SetExtraConfigForComponent("proxy", &config)
opts.SetConfig(config)
return func() error {
return opts.Run()
}
}

View File

@ -1,56 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"io/ioutil"
"net/http"
"github.com/golang/glog"
)
type HealthCheck func() bool
func healthCheck(addr string, lk LocalkubeServer) HealthCheck {
return func() bool {
glog.Infof("Performing healthcheck on %s\n", addr)
transport, err := lk.GetTransport()
if err != nil {
return false
}
client := http.Client{Transport: transport}
resp, err := client.Get(addr)
if err != nil {
glog.Errorf("Error performing healthcheck: %s", err)
return false
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
glog.Errorf("Error reading healthcheck response: %s", err)
return false
}
glog.Infof("Got healthcheck response: %s", body)
return string(body) == "ok"
}
}
func noop() bool {
return true
}

View File

@ -1,96 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"crypto/tls"
"crypto/x509"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
"os"
"testing"
"k8s.io/minikube/pkg/minikube/tests"
"k8s.io/minikube/pkg/util"
)
func TestBasicHealthCheck(t *testing.T) {
tcs := []struct {
body string
statusCode int
shouldSucceed bool
}{
{"ok", 200, true},
{"notok", 200, false},
}
tempDir := tests.MakeTempDir()
defer os.RemoveAll(tempDir)
_, ipnet, err := net.ParseCIDR(util.DefaultServiceCIDR)
if err != nil {
t.Fatalf("Error parsing default service cidr range: %s", err)
}
lk := LocalkubeServer{
LocalkubeDirectory: tempDir,
ServiceClusterIPRange: *ipnet,
}
lk.GenerateCerts()
cert, err := tls.LoadX509KeyPair(lk.GetPublicKeyCertPath(), lk.GetPrivateKeyCertPath())
if err != nil {
t.Fatalf("Unable to load server certs.")
}
caCert, err := ioutil.ReadFile(lk.GetCAPublicKeyCertPath())
if err != nil {
t.Fatalf("Unable to load CA certs.")
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tls := tls.Config{
Certificates: []tls.Certificate{cert},
ClientCAs: caCertPool,
}
tls.BuildNameToCertificate()
for _, tc := range tcs {
// Do this in a func so we can use defer.
doTest := func() {
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(tc.statusCode)
io.WriteString(w, tc.body)
}
server := httptest.NewUnstartedServer(http.HandlerFunc(handler))
defer server.Close()
server.TLS = &tls
server.StartTLS()
hcFunc := healthCheck(server.URL, lk)
result := hcFunc()
if result != tc.shouldSucceed {
t.Errorf("Expected healthcheck to return %v. Got %v", result, tc.shouldSucceed)
}
}
doTest()
}
}

View File

@ -1,55 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
scheduler "k8s.io/kubernetes/cmd/kube-scheduler/app"
"k8s.io/kubernetes/pkg/apis/componentconfig"
"k8s.io/minikube/pkg/util"
)
func (lk LocalkubeServer) NewSchedulerServer() Server {
return NewSimpleServer("scheduler", serverInterval, StartSchedulerServer(lk), noop)
}
func StartSchedulerServer(lk LocalkubeServer) func() error {
config := &componentconfig.KubeSchedulerConfiguration{}
opts, err := scheduler.NewOptions()
if err != nil {
panic(err)
}
config, err = opts.ApplyDefaults(config)
if err != nil {
panic(err)
}
// master details
config.ClientConnection.KubeConfigFile = util.DefaultKubeConfigPath
// defaults from command
config.EnableProfiling = true
lk.SetExtraConfigForComponent("scheduler", &config)
return func() error {
s, err := scheduler.NewSchedulerServer(config, "")
if err != nil {
return err
}
return s.Run(nil)
}
}

View File

@ -1,79 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"os"
"time"
"k8s.io/minikube/pkg/util"
)
// Server represents a component that Kubernetes depends on. It allows for the management of
// the lifecycle of the component.
type Server interface {
// Start immediately starts the component.
Start()
// Stop begins the process of stopping the component.
Stop()
// Name returns a unique identifier for the component.
Name() string
Ready() (bool, error)
}
// SimpleServer provides a minimal implementation of Server.
type SimpleServer struct {
ComponentName string
Interval time.Duration
serverRoutine func() error
stopChannel chan struct{}
readyFunc func() bool
}
func NewSimpleServer(componentName string, msInterval int32, serverRoutine func() error, ready HealthCheck) *SimpleServer {
return &SimpleServer{
ComponentName: componentName,
Interval: time.Duration(msInterval) * time.Millisecond,
serverRoutine: serverRoutine,
stopChannel: make(chan struct{}),
readyFunc: ready,
}
}
// Start calls startup function.
func (s *SimpleServer) Start() {
go util.Until(s.serverRoutine, os.Stdout, s.ComponentName, s.Interval, s.stopChannel)
}
// Stop calls shutdown function.
func (s *SimpleServer) Stop() {
close(s.stopChannel)
}
// Name returns the name of the service.
func (s SimpleServer) Name() string {
return s.ComponentName
}
func (s SimpleServer) Ready() (bool, error) {
return s.readyFunc(), nil
}

View File

@ -1,81 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"fmt"
"time"
"k8s.io/apimachinery/pkg/util/wait"
)
// Servers allows operations to be performed on many servers at once.
// Uses slice to preserve ordering.
type Servers []Server
// Get returns a server matching name, returns nil if server doesn't exit.
func (servers Servers) Get(name string) (Server, error) {
for _, server := range servers {
if server.Name() == name {
return server, nil
}
}
return nil, fmt.Errorf("server '%s' does not exist", name)
}
// StartAll starts all services, starting from 0th item and ascending.
func (servers Servers) StartAll() {
for _, server := range servers {
fmt.Printf("Starting %s...\n", server.Name())
server.Start()
fmt.Printf("Waiting for %s to be healthy...\n", server.Name())
wait.PollInfinite(time.Second, server.Ready)
fmt.Printf("%s is ready!\n", server.Name())
}
}
// StopAll stops all services, starting with the last item.
func (servers Servers) StopAll() {
for i := len(servers) - 1; i >= 0; i-- {
server := servers[i]
fmt.Printf("Stopping %s...\n", server.Name())
server.Stop()
}
}
// Start is a helper method to start the Server specified, returns error if server doesn't exist.
func (servers Servers) Start(serverName string) error {
server, err := servers.Get(serverName)
if err != nil {
return err
}
server.Start()
return nil
}
// Stop is a helper method to start the Server specified, returns error if server doesn't exist.
func (servers Servers) Stop(serverName string) error {
server, err := servers.Get(serverName)
if err != nil {
return err
}
server.Stop()
return nil
}

View File

@ -1,229 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"bytes"
gflag "flag"
"fmt"
"strings"
"text/template"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
)
// Kill any running instances.
var localkubeStartCmdTemplate = "/usr/local/bin/localkube {{.Flags}} --generate-certs=false --logtostderr=true --enable-dns=false"
var startCommandNoSystemdTemplate = `
# Run with nohup so it stays up. Redirect logs to useful places.
sudo sh -c 'PATH=/usr/local/sbin:$PATH GODEBUG=netdns=go nohup {{.LocalkubeStartCmd}} > {{.Stdout}} 2> {{.Stderr}} < /dev/null & echo $! > {{.Pidfile}} &'
`
var localkubeSystemdTmpl = `[Unit]
Description=Localkube
Documentation=https://github.com/kubernetes/minikube/tree/master/pkg/localkube
[Service]
Type=notify
Restart=always
RestartSec=3
Environment=GODEBUG=netdns=go
ExecStart={{.LocalkubeStartCmd}}
ExecReload=/bin/kill -s HUP $MAINPID
[Install]
WantedBy=multi-user.target
`
var startCommandTemplate = "if [[ `systemctl` =~ -\\.mount ]] &>/dev/null;" + `then
{{.StartCommandSystemd}}
sudo systemctl daemon-reload
sudo systemctl enable localkube.service
sudo systemctl restart localkube.service || true
else
sudo killall localkube || true
{{.StartCommandNoSystemd}}
fi
`
func GetStartCommand(kubernetesConfig config.KubernetesConfig) (string, error) {
localkubeStartCommand, err := GenLocalkubeStartCmd(kubernetesConfig)
if err != nil {
return "", err
}
startCommandNoSystemd, err := GetStartCommandNoSystemd(kubernetesConfig, localkubeStartCommand)
if err != nil {
return "", err
}
startCommandSystemd, err := GetStartCommandSystemd(kubernetesConfig, localkubeStartCommand)
if err != nil {
return "", err
}
t := template.Must(template.New("startCommand").Parse(startCommandTemplate))
buf := bytes.Buffer{}
data := struct {
StartCommandNoSystemd string
StartCommandSystemd string
}{
StartCommandNoSystemd: startCommandNoSystemd,
StartCommandSystemd: startCommandSystemd,
}
if err := t.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
func GetStartCommandNoSystemd(kubernetesConfig config.KubernetesConfig, localkubeStartCmd string) (string, error) {
t := template.Must(template.New("startCommand").Parse(startCommandNoSystemdTemplate))
buf := bytes.Buffer{}
data := struct {
LocalkubeStartCmd string
Stdout string
Stderr string
Pidfile string
}{
LocalkubeStartCmd: localkubeStartCmd,
Stdout: constants.RemoteLocalKubeOutPath,
Stderr: constants.RemoteLocalKubeErrPath,
Pidfile: constants.LocalkubePIDPath,
}
if err := t.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
func GetStartCommandSystemd(kubernetesConfig config.KubernetesConfig, localkubeStartCmd string) (string, error) {
t, err := template.New("localkubeConfig").Parse(localkubeSystemdTmpl)
if err != nil {
return "", err
}
buf := bytes.Buffer{}
data := struct {
LocalkubeStartCmd string
}{
LocalkubeStartCmd: localkubeStartCmd,
}
if err := t.Execute(&buf, data); err != nil {
return "", err
}
return fmt.Sprintf("printf %%s \"%s\" | sudo tee %s", buf.String(),
constants.LocalkubeServicePath), nil
}
func GenLocalkubeStartCmd(kubernetesConfig config.KubernetesConfig) (string, error) {
flagVals := make([]string, len(constants.LogFlags))
for _, logFlag := range constants.LogFlags {
if logVal := gflag.Lookup(logFlag); logVal != nil && logVal.Value.String() != logVal.DefValue {
flagVals = append(flagVals, fmt.Sprintf("--%s %s", logFlag, logVal.Value.String()))
}
}
if kubernetesConfig.ContainerRuntime != "" {
flagVals = append(flagVals, "--container-runtime="+kubernetesConfig.ContainerRuntime)
}
if kubernetesConfig.NetworkPlugin != "" {
flagVals = append(flagVals, "--network-plugin="+kubernetesConfig.NetworkPlugin)
}
if kubernetesConfig.FeatureGates != "" {
flagVals = append(flagVals, "--feature-gates="+kubernetesConfig.FeatureGates)
}
if kubernetesConfig.APIServerName != constants.APIServerName {
flagVals = append(flagVals, "--apiserver-name="+kubernetesConfig.APIServerName)
}
if kubernetesConfig.DNSDomain != "" {
flagVals = append(flagVals, "--dns-domain="+kubernetesConfig.DNSDomain)
}
if kubernetesConfig.NodeIP != "127.0.0.1" {
flagVals = append(flagVals, "--node-ip="+kubernetesConfig.NodeIP)
}
for _, e := range kubernetesConfig.ExtraOptions {
flagVals = append(flagVals, fmt.Sprintf("--extra-config=%s", e.String()))
}
flags := strings.Join(flagVals, " ")
t := template.Must(template.New("localkubeStartCmd").Parse(localkubeStartCmdTemplate))
buf := bytes.Buffer{}
data := struct {
Flags string
APIServerName string
}{
Flags: flags,
APIServerName: kubernetesConfig.APIServerName,
}
if err := t.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
const logsTemplate = "if [[ `systemctl` =~ -\\.mount ]] &>/dev/null; " + `then
sudo journalctl {{.Flags}} -u localkube
else
tail -n +1 {{.Flags}} {{.RemoteLocalkubeErrPath}} {{.RemoteLocalkubeOutPath}}
fi
`
func GetLogsCommand(follow bool) (string, error) {
t, err := template.New("logsTemplate").Parse(logsTemplate)
if err != nil {
return "", err
}
var flags []string
if follow {
flags = append(flags, "-f")
}
buf := bytes.Buffer{}
data := struct {
RemoteLocalkubeErrPath string
RemoteLocalkubeOutPath string
Flags string
}{
RemoteLocalkubeErrPath: constants.RemoteLocalKubeErrPath,
RemoteLocalkubeOutPath: constants.RemoteLocalKubeOutPath,
Flags: strings.Join(flags, " "),
}
if err := t.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
var localkubeStatusCommand = fmt.Sprintf("if [[ `systemctl` =~ -\\.mount ]] &>/dev/null; "+`then
sudo systemctl is-active localkube &>/dev/null && echo "Running" || echo "Stopped"
else
if ps $(cat %s) &>/dev/null; then
echo "Running"
else
echo "Stopped"
fi
fi
`, constants.LocalkubePIDPath)

View File

@ -1,74 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
gflag "flag"
"fmt"
"strings"
"testing"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/util"
)
func TestGetStartCommandCustomValues(t *testing.T) {
flagMap := map[string]string{
"v": "10",
"vmodule": "cluster*=5",
}
flagMapToSetFlags(flagMap)
startCommand, err := GetStartCommand(config.KubernetesConfig{})
if err != nil {
t.Fatalf("Error generating start command: %s", err)
}
for flag, val := range flagMap {
if val != "" {
if expectedFlag := getSingleFlagValue(flag, val); !strings.Contains(startCommand, getSingleFlagValue(flag, val)) {
t.Fatalf("Expected GetStartCommand to contain: %s.", expectedFlag)
}
}
}
}
func TestGetStartCommandExtraOptions(t *testing.T) {
k := config.KubernetesConfig{
ExtraOptions: util.ExtraOptionSlice{
util.ExtraOption{Component: "a", Key: "b", Value: "c"},
util.ExtraOption{Component: "d", Key: "e.f", Value: "g"},
},
}
startCommand, err := GetStartCommand(k)
if err != nil {
t.Fatalf("Error generating start command: %s", err)
}
for _, arg := range []string{"--extra-config=a.b=c", "--extra-config=d.e.f=g"} {
if !strings.Contains(startCommand, arg) {
t.Fatalf("Error, expected to find argument: %s. Got: %s", arg, startCommand)
}
}
}
func flagMapToSetFlags(flagMap map[string]string) {
for flag, val := range flagMap {
gflag.Set(flag, val)
}
}
func getSingleFlagValue(flag, val string) string {
return fmt.Sprintf("--%s %s", flag, val)
}

View File

@ -1,160 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"fmt"
"io"
"strings"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/sshutil"
"github.com/docker/machine/libmachine"
"github.com/docker/machine/libmachine/state"
"github.com/pkg/errors"
)
type LocalkubeBootstrapper struct {
cmd bootstrapper.CommandRunner
}
func NewLocalkubeBootstrapper(api libmachine.API) (*LocalkubeBootstrapper, error) {
h, err := api.Load(config.GetMachineName())
if err != nil {
return nil, errors.Wrap(err, "getting api client")
}
var cmd bootstrapper.CommandRunner
// The none driver executes commands directly on the host
if h.Driver.DriverName() == constants.DriverNone {
cmd = &bootstrapper.ExecRunner{}
} else {
client, err := sshutil.NewSSHClient(h.Driver)
if err != nil {
return nil, errors.Wrap(err, "getting ssh client")
}
cmd = bootstrapper.NewSSHRunner(client)
}
return &LocalkubeBootstrapper{
cmd: cmd,
}, nil
}
// GetClusterLogs
// If follow is specified, it will tail the logs
func (lk *LocalkubeBootstrapper) GetClusterLogsTo(follow bool, out io.Writer) error {
logsCommand, err := GetLogsCommand(follow)
if err != nil {
return errors.Wrap(err, "Error getting logs command")
}
if follow {
err = lk.cmd.CombinedOutputTo(logsCommand, out)
if err != nil {
return errors.Wrap(err, "getting cluster logs")
}
} else {
logs, err := lk.cmd.CombinedOutput(logsCommand)
if err != nil {
return errors.Wrap(err, "getting cluster logs")
}
fmt.Fprint(out, logs)
}
return nil
}
// GetClusterStatus gets the status of localkube from the host VM.
func (lk *LocalkubeBootstrapper) GetClusterStatus() (string, error) {
s, err := lk.cmd.CombinedOutput(localkubeStatusCommand)
if err != nil {
return "", err
}
s = strings.TrimSpace(s)
if state.Running.String() == s {
return state.Running.String(), nil
} else if state.Stopped.String() == s {
return state.Stopped.String(), nil
} else {
return "", fmt.Errorf("Error: Unrecognize output from GetLocalkubeStatus: %s", s)
}
}
// StartCluster starts a k8s cluster on the specified Host.
func (lk *LocalkubeBootstrapper) StartCluster(kubernetesConfig config.KubernetesConfig) error {
startCommand, err := GetStartCommand(kubernetesConfig)
if err != nil {
return errors.Wrapf(err, "Error generating start command: %s", err)
}
err = lk.cmd.Run(startCommand) //needs to be sudo for none driver
if err != nil {
return errors.Wrapf(err, "Error running ssh command: %s", startCommand)
}
return nil
}
func (lk *LocalkubeBootstrapper) RestartCluster(kubernetesConfig config.KubernetesConfig) error {
return lk.StartCluster(kubernetesConfig)
}
func (lk *LocalkubeBootstrapper) UpdateCluster(config config.KubernetesConfig) error {
if config.ShouldLoadCachedImages {
// Make best effort to load any cached images
go machine.LoadImages(lk.cmd, constants.LocalkubeCachedImages, constants.ImageCacheDir)
}
copyableFiles := []assets.CopyableFile{}
var localkubeFile assets.CopyableFile
var err error
//add url/file/bundled localkube to file list
lCacher := localkubeCacher{config}
localkubeFile, err = lCacher.fetchLocalkubeFromURI()
if err != nil {
return errors.Wrap(err, "Error updating localkube from uri")
}
copyableFiles = append(copyableFiles, localkubeFile)
// custom addons
if err := assets.AddMinikubeDirAssets(&copyableFiles); err != nil {
return errors.Wrap(err, "adding minikube dir assets")
}
// bundled addons
for _, addonBundle := range assets.Addons {
if isEnabled, err := addonBundle.IsEnabled(); err == nil && isEnabled {
for _, addon := range addonBundle.Assets {
copyableFiles = append(copyableFiles, addon)
}
} else if err != nil {
return err
}
}
for _, f := range copyableFiles {
if err := lk.cmd.Copy(f); err != nil {
return err
}
}
return nil
}
func (lk *LocalkubeBootstrapper) SetupCerts(k8s config.KubernetesConfig) error {
return bootstrapper.SetupCerts(lk.cmd, k8s)
}

View File

@ -1,161 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/golang/glog"
download "github.com/jimmidyson/go-download"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/util"
)
// localkubeCacher is a struct with methods designed for caching localkube
type localkubeCacher struct {
k8sConf config.KubernetesConfig
}
func (l *localkubeCacher) getLocalkubeCacheFilepath() string {
return filepath.Join(constants.GetMinipath(), "cache", "localkube",
filepath.Base(url.QueryEscape("localkube-"+l.k8sConf.KubernetesVersion)))
}
func (l *localkubeCacher) getLocalkubeSha256CacheFilepath() string {
return l.getLocalkubeCacheFilepath() + ".sha256"
}
func localkubeURIWasSpecified(config config.KubernetesConfig) bool {
// see if flag is different than default -> it was passed by user
return config.KubernetesVersion != constants.DefaultKubernetesVersion
}
func (l *localkubeCacher) isLocalkubeCached() bool {
url, err := util.GetLocalkubeDownloadURL(l.k8sConf.KubernetesVersion, constants.LocalkubeLinuxFilename)
if err != nil {
glog.Warningf("Unable to get localkube checksum url...continuing.")
return true
}
opts := download.FileOptions{
Mkdirs: download.MkdirAll,
}
if err := download.ToFile(url+".sha256", l.getLocalkubeSha256CacheFilepath(), opts); err != nil {
glog.Warningf("Unable to check localkube checksum... continuing.")
return true
}
if _, err := os.Stat(l.getLocalkubeCacheFilepath()); os.IsNotExist(err) {
return false
}
localkubeSha256, err := ioutil.ReadFile(l.getLocalkubeSha256CacheFilepath())
if err != nil {
glog.Infof("Error reading localkube checksum: %s", err)
return false
}
h := sha256.New()
f, err := os.Open(l.getLocalkubeCacheFilepath())
if err != nil {
glog.Infof("Error opening localkube for checksum verification: %s", err)
return false
}
if _, err := io.Copy(h, f); err != nil {
glog.Infof("Error copying contents to hasher: %s", err)
}
actualChecksum := hex.EncodeToString(h.Sum(nil))
if strings.TrimSpace(string(localkubeSha256)) != actualChecksum {
glog.Infof("Localkube checksums do not match actual: %s expected: %s", actualChecksum, string(localkubeSha256))
return false
}
return true
}
func (l *localkubeCacher) downloadAndCacheLocalkube() error {
url, err := util.GetLocalkubeDownloadURL(l.k8sConf.KubernetesVersion, constants.LocalkubeLinuxFilename)
if err != nil {
return errors.Wrap(err, "Error getting localkube download url")
}
opts := download.FileOptions{
Mkdirs: download.MkdirAll,
Options: download.Options{
ProgressBars: &download.ProgressBarOptions{
MaxWidth: 80,
},
},
}
fmt.Println("Downloading localkube binary")
if err := download.ToFile(url, l.getLocalkubeCacheFilepath(), opts); err != nil {
return errors.Wrap(err, "downloading localkube")
}
if err := download.ToFile(url+".sha256", l.getLocalkubeSha256CacheFilepath(), opts); err != nil {
return errors.Wrap(err, "downloading localkube checksum")
}
return nil
}
func (l *localkubeCacher) fetchLocalkubeFromURI() (assets.CopyableFile, error) {
urlObj, err := url.Parse(l.k8sConf.KubernetesVersion)
if err != nil {
return nil, errors.Wrap(err, "Error parsing --kubernetes-version url")
}
if urlObj.Scheme == constants.FileScheme {
return l.genLocalkubeFileFromFile()
}
return l.genLocalkubeFileFromURL()
}
func (l *localkubeCacher) genLocalkubeFileFromURL() (assets.CopyableFile, error) {
if !l.isLocalkubeCached() {
glog.Infoln("Localkube not cached or checksum does not match, downloading...")
if err := l.downloadAndCacheLocalkube(); err != nil {
return nil, errors.Wrap(err, "Error attempting to download and cache localkube")
}
} else {
glog.Infoln("Using cached localkube")
}
localkubeFile, err := assets.NewFileAsset(l.getLocalkubeCacheFilepath(), "/usr/local/bin", "localkube", "0777")
if err != nil {
return nil, errors.Wrap(err, "Error creating localkube asset from url")
}
return localkubeFile, nil
}
func (l *localkubeCacher) genLocalkubeFileFromFile() (assets.CopyableFile, error) {
path := strings.TrimPrefix(l.k8sConf.KubernetesVersion, "file://")
path = filepath.FromSlash(path)
localkubeFile, err := assets.NewFileAsset(path, "/usr/local/bin", "localkube", "0777")
if err != nil {
return nil, errors.Wrap(err, "Error creating localkube asset from file")
}
return localkubeFile, nil
}

View File

@ -1,223 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
import (
"bytes"
"testing"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
)
func TestStartCluster(t *testing.T) {
expectedStartCmd, err := GetStartCommand(config.KubernetesConfig{})
if err != nil {
t.Fatalf("generating start command: %s", err)
}
cases := []struct {
description string
startCmd string
}{
{
description: "start cluster success",
startCmd: expectedStartCmd,
},
{
description: "start cluster failure",
startCmd: "something else",
},
}
for _, test := range cases {
t.Run(test.description, func(t *testing.T) {
t.Parallel()
f := bootstrapper.NewFakeCommandRunner()
f.SetCommandToOutput(map[string]string{test.startCmd: "ok"})
l := LocalkubeBootstrapper{f}
err := l.StartCluster(config.KubernetesConfig{})
if err != nil && test.startCmd == expectedStartCmd {
t.Errorf("Error starting cluster: %s", err)
}
})
}
}
func TestUpdateCluster(t *testing.T) {
defaultCfg := config.KubernetesConfig{
KubernetesVersion: constants.DefaultKubernetesVersion,
}
defaultAddons := []string{
"deploy/addons/kube-dns/kube-dns-cm.yaml",
"deploy/addons/kube-dns/kube-dns-svc.yaml",
"deploy/addons/addon-manager.yaml",
"deploy/addons/dashboard/dashboard-rc.yaml",
"deploy/addons/dashboard/dashboard-svc.yaml",
"deploy/addons/storageclass/storageclass.yaml",
"deploy/addons/kube-dns/kube-dns-controller.yaml",
}
cases := []struct {
description string
k8s config.KubernetesConfig
expectedFiles []string
shouldErr bool
}{
{
description: "transfer localkube correct",
k8s: defaultCfg,
expectedFiles: []string{"out/localkube"},
},
{
description: "addons are transferred",
k8s: defaultCfg,
expectedFiles: defaultAddons,
},
{
description: "no localkube version",
k8s: config.KubernetesConfig{},
shouldErr: true,
},
}
for _, test := range cases {
t.Run(test.description, func(t *testing.T) {
t.Parallel()
f := bootstrapper.NewFakeCommandRunner()
l := LocalkubeBootstrapper{f}
err := l.UpdateCluster(test.k8s)
if err != nil && !test.shouldErr {
t.Errorf("Error updating cluster: %s", err)
return
}
if err == nil && test.shouldErr {
t.Error("Didn't get error, but expected to")
return
}
for _, expectedFile := range test.expectedFiles {
_, err := f.GetFileToContents(expectedFile)
if err != nil {
t.Errorf("Expected file %s, but was not present", expectedFile)
}
}
})
}
}
func TestGetLocalkubeStatus(t *testing.T) {
cases := []struct {
description string
statusCmdMap map[string]string
expectedStatus string
shouldErr bool
}{
{
description: "get status running",
statusCmdMap: map[string]string{localkubeStatusCommand: "Running"},
expectedStatus: "Running",
},
{
description: "get status stopped",
statusCmdMap: map[string]string{localkubeStatusCommand: "Stopped"},
expectedStatus: "Stopped",
},
{
description: "get status unknown status",
statusCmdMap: map[string]string{localkubeStatusCommand: "Recalculating..."},
shouldErr: true,
},
{
description: "get status error",
statusCmdMap: map[string]string{"a": "b"},
shouldErr: true,
},
}
for _, test := range cases {
t.Run(test.description, func(t *testing.T) {
t.Parallel()
f := bootstrapper.NewFakeCommandRunner()
f.SetCommandToOutput(test.statusCmdMap)
l := LocalkubeBootstrapper{f}
actualStatus, err := l.GetClusterStatus()
if err != nil && !test.shouldErr {
t.Errorf("Error getting localkube status: %s", err)
return
}
if err == nil && test.shouldErr {
t.Error("Didn't get error, but expected to")
return
}
if test.expectedStatus != actualStatus {
t.Errorf("Expected status: %s, Actual status: %s", test.expectedStatus, actualStatus)
}
})
}
}
func TestGetHostLogs(t *testing.T) {
logs, err := GetLogsCommand(false)
if err != nil {
t.Fatalf("Error getting logs command: %s", err)
}
logsf, err := GetLogsCommand(true)
if err != nil {
t.Fatalf("Error gettings logs -f command: %s", err)
}
cases := []struct {
description string
logsCmdMap map[string]string
follow bool
shouldErr bool
}{
{
description: "get logs correct",
logsCmdMap: map[string]string{logs: "fee"},
},
{
description: "follow logs correct",
logsCmdMap: map[string]string{logsf: "fi"},
follow: true,
},
{
description: "get logs incorrect",
logsCmdMap: map[string]string{"fo": "fum"},
shouldErr: true,
},
}
var b bytes.Buffer
for _, test := range cases {
t.Run(test.description, func(t *testing.T) {
t.Parallel()
f := bootstrapper.NewFakeCommandRunner()
f.SetCommandToOutput(test.logsCmdMap)
l := LocalkubeBootstrapper{f}
err := l.GetClusterLogsTo(test.follow, &b)
if err != nil && !test.shouldErr {
t.Errorf("Error getting localkube logs: %s", err)
return
}
if err == nil && test.shouldErr {
t.Error("Didn't get error, but expected to")
return
}
})
}
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package localkube
package storage
import (
"fmt"