Refactor the whole binary, a lot of changes in one commit I know, but I just hacked on this and modified everything I thought was messy or could be done better.

Fix boilerplates, comments in the code and make the output of kubeadm more user-friendly
Start using HostPKIPath and KubernetesDir everywhere in the code, so they can be changed for real
More robust kubeadm reset code now.
Removed old glog-things from app.Run()
Renamed /etc/kubernetes/cloud-config.json to /etc/kubernetes/cloud-config since it shouldn't be a json file
Simplification of the code
Less verbose output from master/pki.go
Cleaned up dead code

Start a small logging/output framework:
 - fmt.Println("[the-stage-here] Capital first letter of this message. Tell the user what the current state is")
 - fmt.Printf("[the-stage-here] Capital first letter. Maybe a [%v] in the end if an error should be displayed. Always ends with \n")
 - fmt.Errorf("Never starts with []. Includes a short error message plus the underlying error in [%v]. Never ends with \n")
pull/6/head
Lucas Käldström 2016-12-07 09:21:28 +02:00
parent e46d8fef60
commit 810e9e107f
23 changed files with 188 additions and 219 deletions

View File

@ -25,21 +25,18 @@ import (
var GlobalEnvParams = SetEnvParams()
// TODO(phase2) use componentconfig
// TODO(phase1+) Move these paramaters to the API group
// we need some params for testing etc, let's keep these hidden for now
func SetEnvParams() *EnvParams {
envParams := map[string]string{
// TODO(phase1+): Mode prefix and host_pki_path to another place as constants, and use them everywhere
// Right now they're used here and there, but not consequently
"kubernetes_dir": "/etc/kubernetes",
"host_pki_path": "/etc/kubernetes/pki",
"host_etcd_path": "/var/lib/etcd",
"hyperkube_image": "",
"repo_prefix": "gcr.io/google_containers",
"discovery_image": fmt.Sprintf("gcr.io/google_containers/kube-discovery-%s:%s", runtime.GOARCH, "1.0"),
"etcd_image": "",
"component_loglevel": "--v=2",
"kubernetes_dir": "/etc/kubernetes",
"host_pki_path": "/etc/kubernetes/pki",
"host_etcd_path": "/var/lib/etcd",
"hyperkube_image": "",
"repo_prefix": "gcr.io/google_containers",
"discovery_image": fmt.Sprintf("gcr.io/google_containers/kube-discovery-%s:%s", runtime.GOARCH, "1.0"),
"etcd_image": "",
}
for k := range envParams {
@ -49,13 +46,12 @@ func SetEnvParams() *EnvParams {
}
return &EnvParams{
KubernetesDir: envParams["kubernetes_dir"],
HostPKIPath: envParams["host_pki_path"],
HostEtcdPath: envParams["host_etcd_path"],
HyperkubeImage: envParams["hyperkube_image"],
RepositoryPrefix: envParams["repo_prefix"],
DiscoveryImage: envParams["discovery_image"],
EtcdImage: envParams["etcd_image"],
ComponentLoglevel: envParams["component_loglevel"],
KubernetesDir: envParams["kubernetes_dir"],
HostPKIPath: envParams["host_pki_path"],
HostEtcdPath: envParams["host_etcd_path"],
HyperkubeImage: envParams["hyperkube_image"],
RepositoryPrefix: envParams["repo_prefix"],
DiscoveryImage: envParams["discovery_image"],
EtcdImage: envParams["etcd_image"],
}
}

View File

@ -21,14 +21,13 @@ import (
)
type EnvParams struct {
KubernetesDir string
HostPKIPath string
HostEtcdPath string
HyperkubeImage string
RepositoryPrefix string
DiscoveryImage string
EtcdImage string
ComponentLoglevel string
KubernetesDir string
HostPKIPath string
HostEtcdPath string
HyperkubeImage string
RepositoryPrefix string
DiscoveryImage string
EtcdImage string
}
type MasterConfiguration struct {

View File

@ -37,14 +37,14 @@ func NewKubeadmCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
KUBEADM IS ALPHA, DO NOT USE IT FOR PRODUCTION CLUSTERS!
But, please try it out! Give us feedback at:
https://github.com/kubernetes/kubernetes/issues
https://github.com/kubernetes/kubeadm/issues
and at-mention @kubernetes/sig-cluster-lifecycle
Example usage:
Create a two-machine cluster with one master (which controls the cluster),
and one node (where workloads, like pods and replica sets run).
and one node (where your workloads, like Pods and ReplicaSets run).
On the first machine
@ -69,11 +69,10 @@ func NewKubeadmCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
//
// TODO(phase2) create an abstraction that defines files and the content that needs to
// be written to disc and write it all in one go at the end as we have a lot of
// crapy little files written from different parts of this code; this could also
// be useful for testing
// by having this model we can allow users to create some files before `kubeadm init` runs, e.g. PKI assets, we
// would then be able to look at files users has given an diff or validate if those are sane, we could also warn
// if any of the files had been deprecated
// crappy little files written from different parts of this code; this could also
// be useful for testing by having this model we can allow users to create some files before
// `kubeadm init` runs, e.g. PKI assets, we would then be able to look at files users has
// given an diff or validate if those are sane, we could also warn if any of the files had been deprecated
cmds.ResetFlags()
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)

View File

@ -52,7 +52,11 @@ const (
var (
initDoneMsgf = dedent.Dedent(`
Kubernetes master initialised successfully!
Your Kubernetes master has initialized successfully!
But you still need to deploy a pod network to the cluster.
You should "kubectl apply -f" some pod network yaml file that's listed at:
http://kubernetes.io/docs/admin/addons/
You can now join any number of machines by running the following on each node:
@ -163,6 +167,9 @@ type Init struct {
}
func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight bool) (*Init, error) {
fmt.Println("[kubeadm] Bear in mind that kubeadm is in alpha, do not use it in production clusters.")
if cfgPath != "" {
b, err := ioutil.ReadFile(cfgPath)
if err != nil {
@ -175,7 +182,6 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight
// Auto-detect the IP
if len(cfg.API.AdvertiseAddresses) == 0 {
// TODO(phase1+) perhaps we could actually grab eth0 and eth1
ip, err := netutil.ChooseHostInterface()
if err != nil {
return nil, err
@ -196,7 +202,7 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight
return nil, &preflight.PreFlightError{Msg: err.Error()}
}
} else {
fmt.Println("Skipping pre-flight checks")
fmt.Println("[preflight] Skipping pre-flight checks...")
}
// Try to start the kubelet service in case it's inactive
@ -257,7 +263,7 @@ func (i *Init) Run(out io.Writer) error {
// write a file that has already been written (the kubelet will be up and
// running in that case - they'd need to stop the kubelet, remove the file, and
// start it again in that case).
// TODO(phase1+) this is no longer the right place to guard agains foo-shooting,
// TODO(phase1+) this is no longer the right place to guard against foo-shooting,
// we need to decide how to handle existing files (it may be handy to support
// importing existing files, may be we could even make our command idempotant,
// or at least allow for external PKI and stuff)

View File

@ -95,6 +95,9 @@ type Join struct {
}
func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, skipPreFlight bool) (*Join, error) {
fmt.Println("[kubeadm] Bear in mind that kubeadm is in alpha, do not use it in production clusters.")
if cfgPath != "" {
b, err := ioutil.ReadFile(cfgPath)
if err != nil {
@ -110,7 +113,7 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s
}
cfg.MasterAddresses = append(cfg.MasterAddresses, args...)
if len(cfg.MasterAddresses) > 1 {
return nil, fmt.Errorf("Must not specify more than one master address (see --help)")
return nil, fmt.Errorf("Must not specify more than one master address (see --help)")
}
if !skipPreFlight {
@ -126,7 +129,7 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s
return nil, &preflight.PreFlightError{Msg: err.Error()}
}
} else {
fmt.Println("Skipping pre-flight checks")
fmt.Println("[preflight] Skipping pre-flight checks...")
}
// Try to start the kubelet service in case it's inactive
@ -137,9 +140,9 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s
ok, err := kubeadmutil.UseGivenTokenIfValid(&cfg.Secrets)
if !ok {
if err != nil {
return nil, fmt.Errorf("%v (see --help)\n", err)
return nil, fmt.Errorf("%v (see --help)", err)
}
return nil, fmt.Errorf("Must specify --token (see --help)\n")
return nil, fmt.Errorf("Must specify --token (see --help)")
}
return &Join{cfg: cfg}, nil

View File

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors.
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -19,7 +19,7 @@ package cmd
import (
"io/ioutil"
"os"
"path/filepath"
"path"
"testing"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
@ -147,14 +147,14 @@ func TestConfigDirCleaner(t *testing.T) {
defer os.RemoveAll(tmpDir)
for _, createDir := range test.setupDirs {
err := os.Mkdir(filepath.Join(tmpDir, createDir), 0700)
err := os.Mkdir(path.Join(tmpDir, createDir), 0700)
if err != nil {
t.Errorf("Unable to setup test config directory: %s", err)
}
}
for _, createFile := range test.setupFiles {
fullPath := filepath.Join(tmpDir, createFile)
fullPath := path.Join(tmpDir, createFile)
f, err := os.Create(fullPath)
defer f.Close()
if err != nil {
@ -166,17 +166,17 @@ func TestConfigDirCleaner(t *testing.T) {
// Verify the files we cleanup implicitly in every test:
assertExists(t, tmpDir)
assertNotExists(t, filepath.Join(tmpDir, "admin.conf"))
assertNotExists(t, filepath.Join(tmpDir, "kubelet.conf"))
assertDirEmpty(t, filepath.Join(tmpDir, "manifests"))
assertDirEmpty(t, filepath.Join(tmpDir, "pki"))
assertNotExists(t, path.Join(tmpDir, "admin.conf"))
assertNotExists(t, path.Join(tmpDir, "kubelet.conf"))
assertDirEmpty(t, path.Join(tmpDir, "manifests"))
assertDirEmpty(t, path.Join(tmpDir, "pki"))
// Verify the files as requested by the test:
for _, path := range test.verifyExists {
assertExists(t, filepath.Join(tmpDir, path))
assertExists(t, path.Join(tmpDir, path))
}
for _, path := range test.verifyNotExists {
assertNotExists(t, filepath.Join(tmpDir, path))
assertNotExists(t, path.Join(tmpDir, path))
}
}
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors.
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -24,13 +24,9 @@ import (
_ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/util/logs"
)
func Run() error {
logs.InitLogs()
defer logs.FlushLogs()
// We do not want these flags to show up in --help
pflag.CommandLine.MarkHidden("google-json-key")
pflag.CommandLine.MarkHidden("log-flush-frequency")

View File

@ -288,17 +288,17 @@ func CreateEssentialAddons(cfg *kubeadmapi.MasterConfiguration, client *clientse
SetNodeAffinity(&kubeProxyDaemonSet.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity())
if _, err := client.Extensions().DaemonSets(api.NamespaceSystem).Create(kubeProxyDaemonSet); err != nil {
return fmt.Errorf("<master/addons> failed creating essential kube-proxy addon [%v]", err)
return fmt.Errorf("failed creating essential kube-proxy addon [%v]", err)
}
fmt.Println("<master/addons> created essential addon: kube-proxy")
fmt.Println("[addons] Created essential addon: kube-proxy")
kubeDNSDeployment := NewDeployment("kube-dns", 1, createKubeDNSPodSpec(cfg))
SetMasterTaintTolerations(&kubeDNSDeployment.Spec.Template.ObjectMeta)
SetNodeAffinity(&kubeDNSDeployment.Spec.Template.ObjectMeta, NativeArchitectureNodeAffinity())
if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kubeDNSDeployment); err != nil {
return fmt.Errorf("<master/addons> failed creating essential kube-dns addon [%v]", err)
return fmt.Errorf("failed creating essential kube-dns addon [%v]", err)
}
kubeDNSServiceSpec, err := createKubeDNSServiceSpec(cfg)
@ -309,10 +309,10 @@ func CreateEssentialAddons(cfg *kubeadmapi.MasterConfiguration, client *clientse
kubeDNSService := NewService("kube-dns", *kubeDNSServiceSpec)
kubeDNSService.ObjectMeta.Labels["kubernetes.io/name"] = "KubeDNS"
if _, err := client.Services(api.NamespaceSystem).Create(kubeDNSService); err != nil {
return fmt.Errorf("<master/addons> failed creating essential kube-dns addon [%v]", err)
return fmt.Errorf("failed creating essential kube-dns addon [%v]", err)
}
fmt.Println("<master/addons> created essential addon: kube-dns")
fmt.Println("[addons] Created essential addon: kube-dns")
return nil
}

View File

@ -42,17 +42,15 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
&clientcmd.ConfigOverrides{},
).ClientConfig()
if err != nil {
return nil, fmt.Errorf("<master/apiclient> failed to create API client configuration [%v]", err)
return nil, fmt.Errorf("failed to create API client configuration [%v]", err)
}
fmt.Println("<master/apiclient> created API client configuration")
client, err := clientset.NewForConfig(adminClientConfig)
if err != nil {
return nil, fmt.Errorf("<master/apiclient> failed to create API client [%v]", err)
return nil, fmt.Errorf("failed to create API client [%v]", err)
}
fmt.Println("<master/apiclient> created API client, waiting for the control plane to become ready")
fmt.Println("[apiclient] Created API client, waiting for the control plane to become ready")
start := time.Now()
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
@ -62,28 +60,28 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
}
// TODO(phase2) must revisit this when we implement HA
if len(cs.Items) < 3 {
fmt.Println("<master/apiclient> not all control plane components are ready yet")
fmt.Println("[apiclient] Not all control plane components are ready yet")
return false, nil
}
for _, item := range cs.Items {
for _, condition := range item.Conditions {
if condition.Type != v1.ComponentHealthy {
fmt.Printf("<master/apiclient> control plane component %q is still unhealthy: %#v\n", item.ObjectMeta.Name, item.Conditions)
fmt.Printf("[apiclient] Control plane component %q is still unhealthy: %#v\n", item.ObjectMeta.Name, item.Conditions)
return false, nil
}
}
}
fmt.Printf("<master/apiclient> all control plane components are healthy after %f seconds\n", time.Since(start).Seconds())
fmt.Printf("[apiclient] All control plane components are healthy after %f seconds\n", time.Since(start).Seconds())
return true, nil
})
fmt.Println("<master/apiclient> waiting for at least one node to register and become ready")
fmt.Println("[apiclient] Waiting for at least one node to register and become ready")
start = time.Now()
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
nodeList, err := client.Nodes().List(v1.ListOptions{})
if err != nil {
fmt.Println("<master/apiclient> temporarily unable to list nodes (will retry)")
fmt.Println("[apiclient] Temporarily unable to list nodes (will retry)")
return false, nil
}
if len(nodeList.Items) < 1 {
@ -91,11 +89,11 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
}
n := &nodeList.Items[0]
if !v1.IsNodeReady(n) {
fmt.Println("<master/apiclient> first node has registered, but is not ready yet")
fmt.Println("[apiclient] First node has registered, but is not ready yet")
return false, nil
}
fmt.Printf("<master/apiclient> first node is ready after %f seconds\n", time.Since(start).Seconds())
fmt.Printf("[apiclient] First node is ready after %f seconds\n", time.Since(start).Seconds())
return true, nil
})
@ -180,7 +178,7 @@ func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, sched
if _, err := client.Nodes().Update(n); err != nil {
if apierrs.IsConflict(err) {
fmt.Println("<master/apiclient> temporarily unable to update master node metadata due to conflict (will retry)")
fmt.Println("[apiclient] Temporarily unable to update master node metadata due to conflict (will retry)")
time.Sleep(apiCallRetryInterval)
attemptToUpdateMasterRoleLabelsAndTaints(client, schedulable)
} else {
@ -195,7 +193,7 @@ func UpdateMasterRoleLabelsAndTaints(client *clientset.Clientset, schedulable bo
// TODO(phase1+) use iterate instead of recursion
err := attemptToUpdateMasterRoleLabelsAndTaints(client, schedulable)
if err != nil {
return fmt.Errorf("<master/apiclient> failed to update master node - %v", err)
return fmt.Errorf("failed to update master node - [%v]", err)
}
return nil
}
@ -240,7 +238,7 @@ func NativeArchitectureNodeAffinity() v1.NodeSelectorRequirement {
}
func createDummyDeployment(client *clientset.Clientset) {
fmt.Println("<master/apiclient> attempting a test deployment")
fmt.Println("[apiclient] Creating a test deployment")
dummyDeployment := NewDeployment("dummy", 1, v1.PodSpec{
HostNetwork: true,
SecurityContext: &v1.PodSecurityContext{},
@ -253,7 +251,7 @@ func createDummyDeployment(client *clientset.Clientset) {
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
// TODO: we should check the error, as some cases may be fatal
if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(dummyDeployment); err != nil {
fmt.Printf("<master/apiclient> failed to create test deployment [%v] (will retry)", err)
fmt.Printf("[apiclient] Failed to create test deployment [%v] (will retry)\n", err)
return false, nil
}
return true, nil
@ -262,7 +260,7 @@ func createDummyDeployment(client *clientset.Clientset) {
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
d, err := client.Extensions().Deployments(api.NamespaceSystem).Get("dummy")
if err != nil {
fmt.Printf("<master/apiclient> failed to get test deployment [%v] (will retry)", err)
fmt.Printf("[apiclient] Failed to get test deployment [%v] (will retry)\n", err)
return false, nil
}
if d.Status.AvailableReplicas < 1 {
@ -271,9 +269,9 @@ func createDummyDeployment(client *clientset.Clientset) {
return true, nil
})
fmt.Println("<master/apiclient> test deployment succeeded")
fmt.Println("[apiclient] Test deployment succeeded")
if err := client.Extensions().Deployments(api.NamespaceSystem).Delete("dummy", &v1.DeleteOptions{}); err != nil {
fmt.Printf("<master/apiclient> failed to delete test deployment [%v] (will ignore)", err)
fmt.Printf("[apiclient] Failed to delete test deployment [%v] (will ignore)\n", err)
}
}

View File

@ -123,13 +123,13 @@ func CreateDiscoveryDeploymentAndSecret(cfg *kubeadmapi.MasterConfiguration, cli
kd := newKubeDiscovery(cfg, caCert)
if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kd.Deployment); err != nil {
return fmt.Errorf("<master/discovery> failed to create %q deployment [%v]", kubeDiscoveryName, err)
return fmt.Errorf("failed to create %q deployment [%v]", kubeDiscoveryName, err)
}
if _, err := client.Secrets(api.NamespaceSystem).Create(kd.Secret); err != nil {
return fmt.Errorf("<master/discovery> failed to create %q secret [%v]", kubeDiscoverySecretName, err)
return fmt.Errorf("failed to create %q secret [%v]", kubeDiscoverySecretName, err)
}
fmt.Println("<master/discovery> created essential addon: kube-discovery, waiting for it to become ready")
fmt.Println("[token-discovery] Created the kube-discovery deployment, waiting for it to become ready")
start := time.Now()
wait.PollInfinite(apiCallRetryInterval, func() (bool, error) {
@ -142,7 +142,7 @@ func CreateDiscoveryDeploymentAndSecret(cfg *kubeadmapi.MasterConfiguration, cli
}
return true, nil
})
fmt.Printf("<master/discovery> kube-discovery is ready after %f seconds\n", time.Since(start).Seconds())
fmt.Printf("[token-discovery] kube-discovery is ready after %f seconds\n", time.Since(start).Seconds())
return nil
}

View File

@ -21,7 +21,6 @@ import (
"crypto/x509"
"fmt"
// TODO: "k8s.io/client-go/client/tools/clientcmd/api"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
@ -44,7 +43,7 @@ func CreateCertsAndConfigForClients(cfg kubeadmapi.API, clientNames []string, ca
for _, client := range clientNames {
key, cert, err := newClientKeyAndCert(caCert, caKey)
if err != nil {
return nil, fmt.Errorf("<master/kubeconfig> failure while creating %s client certificate - %v", client, err)
return nil, fmt.Errorf("failure while creating %s client certificate - [%v]", client, err)
}
config := kubeadmutil.MakeClientConfigWithCerts(
basicClientConfig,

View File

@ -47,7 +47,6 @@ const (
kubeControllerManager = "kube-controller-manager"
kubeScheduler = "kube-scheduler"
kubeProxy = "kube-proxy"
pkiDir = "/etc/kubernetes/pki"
)
// WriteStaticPodManifests builds manifest objects based on user provided configuration and then dumps it to disk
@ -124,16 +123,16 @@ func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration) error {
manifestsPath := path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")
if err := os.MkdirAll(manifestsPath, 0700); err != nil {
return fmt.Errorf("<master/manifests> failed to create directory %q [%v]", manifestsPath, err)
return fmt.Errorf("failed to create directory %q [%v]", manifestsPath, err)
}
for name, spec := range staticPodSpecs {
filename := path.Join(manifestsPath, name+".json")
serialized, err := json.MarshalIndent(spec, "", " ")
if err != nil {
return fmt.Errorf("<master/manifests> failed to marshall manifest for %q to JSON [%v]", name, err)
return fmt.Errorf("failed to marshal manifest for %q to JSON [%v]", name, err)
}
if err := cmdutil.DumpReaderToFile(bytes.NewReader(serialized), filename); err != nil {
return fmt.Errorf("<master/manifests> failed to create static pod manifest file for %q (%q) [%v]", name, filename, err)
return fmt.Errorf("failed to create static pod manifest file for %q (%q) [%v]", name, filename, err)
}
}
return nil
@ -191,7 +190,7 @@ func isPkiVolumeMountNeeded() bool {
func pkiVolume(cfg *kubeadmapi.MasterConfiguration) api.Volume {
return api.Volume{
Name: "pki",
Name: "k8s",
VolumeSource: api.VolumeSource{
// TODO(phase1+) make path configurable
HostPath: &api.HostPathVolumeSource{Path: "/etc/pki"},
@ -265,26 +264,24 @@ func componentPod(container api.Container, volumes ...api.Volume) api.Pod {
}
}
func getComponentBaseCommand(component string) (command []string) {
func getComponentBaseCommand(component string) []string {
if kubeadmapi.GlobalEnvParams.HyperkubeImage != "" {
command = []string{"/hyperkube", component}
} else {
command = []string{"kube-" + component}
return []string{"/hyperkube", component}
}
command = append(command, kubeadmapi.GlobalEnvParams.ComponentLoglevel)
return
return []string{"kube-" + component}
}
func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) {
command = append(getComponentBaseCommand(apiServer),
func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration) []string {
command := append(getComponentBaseCommand(apiServer),
"--insecure-bind-address=127.0.0.1",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
"--service-cluster-ip-range="+cfg.Networking.ServiceSubnet,
"--service-account-key-file="+pkiDir+"/apiserver-key.pem",
"--client-ca-file="+pkiDir+"/ca.pem",
"--tls-cert-file="+pkiDir+"/apiserver.pem",
"--tls-private-key-file="+pkiDir+"/apiserver-key.pem",
"--token-auth-file="+pkiDir+"/tokens.csv",
"--service-account-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem",
"--client-ca-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem",
"--tls-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver.pem",
"--tls-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem",
"--token-auth-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/tokens.csv",
fmt.Sprintf("--secure-port=%d", cfg.API.BindPort),
"--allow-privileged",
)
@ -320,19 +317,19 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string)
}
}
return
return command
}
func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) {
command = append(getComponentBaseCommand(controllerManager),
func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) []string {
command := append(getComponentBaseCommand(controllerManager),
"--address=127.0.0.1",
"--leader-elect",
"--master=127.0.0.1:8080",
"--cluster-name="+DefaultClusterName,
"--root-ca-file="+pkiDir+"/ca.pem",
"--service-account-private-key-file="+pkiDir+"/apiserver-key.pem",
"--cluster-signing-cert-file="+pkiDir+"/ca.pem",
"--cluster-signing-key-file="+pkiDir+"/ca-key.pem",
"--root-ca-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem",
"--service-account-private-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/apiserver-key.pem",
"--cluster-signing-cert-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca.pem",
"--cluster-signing-key-file="+kubeadmapi.GlobalEnvParams.HostPKIPath+"/ca-key.pem",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap",
)
@ -340,7 +337,6 @@ func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) (command [
command = append(command, "--cloud-provider="+cfg.CloudProvider)
// Only append the --cloud-config option if there's a such file
// TODO(phase1+) this won't work unless it's in one of the few directories we bind-mount
if _, err := os.Stat(DefaultCloudConfigPath); err == nil {
command = append(command, "--cloud-config="+DefaultCloudConfigPath)
}
@ -351,24 +347,19 @@ func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration) (command [
if cfg.Networking.PodSubnet != "" {
command = append(command, "--allocate-node-cidrs=true", "--cluster-cidr="+cfg.Networking.PodSubnet)
}
return
return command
}
func getSchedulerCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) {
command = append(getComponentBaseCommand(scheduler),
func getSchedulerCommand(cfg *kubeadmapi.MasterConfiguration) []string {
return append(getComponentBaseCommand(scheduler),
"--address=127.0.0.1",
"--leader-elect",
"--master=127.0.0.1:8080",
)
return
}
func getProxyCommand(cfg *kubeadmapi.MasterConfiguration) (command []string) {
command = getComponentBaseCommand(proxy)
return
func getProxyCommand(cfg *kubeadmapi.MasterConfiguration) []string {
return getComponentBaseCommand(proxy)
}
func getProxyEnvVars() []api.EnvVar {

View File

@ -24,7 +24,7 @@ import (
"path"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
certutil "k8s.io/kubernetes/pkg/util/cert"
)
@ -162,39 +162,32 @@ func CreatePKIAssets(cfg *kubeadmapi.MasterConfiguration) (*rsa.PrivateKey, *x50
caKey, caCert, err := newCertificateAuthority()
if err != nil {
return nil, nil, fmt.Errorf("<master/pki> failure while creating CA keys and certificate - %v", err)
return nil, nil, fmt.Errorf("failure while creating CA keys and certificate [%v]", err)
}
if err := writeKeysAndCert(pkiPath, "ca", caKey, caCert); err != nil {
return nil, nil, fmt.Errorf("<master/pki> failure while saving CA keys and certificate - %v", err)
return nil, nil, fmt.Errorf("failure while saving CA keys and certificate [%v]", err)
}
fmt.Printf("<master/pki> generated Certificate Authority key and certificate:\n%s\n", certutil.FormatCert(caCert))
pub, prv, cert := pathsKeysCerts(pkiPath, "ca")
fmt.Printf("Public: %s\nPrivate: %s\nCert: %s\n", pub, prv, cert)
fmt.Println("[certificates] Generated Certificate Authority key and certificate.")
apiKey, apiCert, err := newServerKeyAndCert(cfg, caCert, caKey, altNames)
if err != nil {
return nil, nil, fmt.Errorf("<master/pki> failure while creating API server keys and certificate - %v", err)
return nil, nil, fmt.Errorf("failure while creating API server keys and certificate [%v]", err)
}
if err := writeKeysAndCert(pkiPath, "apiserver", apiKey, apiCert); err != nil {
return nil, nil, fmt.Errorf("<master/pki> failure while saving API server keys and certificate - %v", err)
return nil, nil, fmt.Errorf("failure while saving API server keys and certificate [%v]", err)
}
fmt.Printf("<master/pki> generated API Server key and certificate:\n%s\n", certutil.FormatCert(apiCert))
pub, prv, cert = pathsKeysCerts(pkiPath, "apiserver")
fmt.Printf("Public: %s\nPrivate: %s\nCert: %s\n", pub, prv, cert)
fmt.Println("[certificates] Generated API Server key and certificate")
saKey, err := newServiceAccountKey()
if err != nil {
return nil, nil, fmt.Errorf("<master/pki> failure while creating service account signing keys [%v]", err)
return nil, nil, fmt.Errorf("failure while creating service account signing keys [%v]", err)
}
if err := writeKeysAndCert(pkiPath, "sa", saKey, nil); err != nil {
return nil, nil, fmt.Errorf("<master/pki> failure while saving service account signing keys - %v", err)
return nil, nil, fmt.Errorf("failure while saving service account signing keys [%v]", err)
}
fmt.Printf("<master/pki> generated Service Account Signing keys:\n")
pub, prv, _ = pathsKeysCerts(pkiPath, "sa")
fmt.Printf("Public: %s\nPrivate: %s\n", pub, prv)
fmt.Printf("<master/pki> created keys and certificates in %q\n", pkiPath)
fmt.Println("[certificates] Generated Service Account signing keys")
fmt.Printf("[certificates] Created keys and certificates in %q\n", pkiPath)
return caKey, caCert, nil
}

View File

@ -39,9 +39,9 @@ func generateTokenIfNeeded(s *kubeadmapi.Secrets) error {
if err != nil {
return err
}
fmt.Printf("<master/tokens> generated token: %q\n", s.GivenToken)
fmt.Printf("[tokens] Generated token: %q\n", s.GivenToken)
} else {
fmt.Println("<master/tokens> accepted provided token")
fmt.Println("[tokens] Accepted provided token")
}
return nil
@ -50,15 +50,15 @@ func generateTokenIfNeeded(s *kubeadmapi.Secrets) error {
func CreateTokenAuthFile(s *kubeadmapi.Secrets) error {
tokenAuthFilePath := path.Join(kubeadmapi.GlobalEnvParams.HostPKIPath, "tokens.csv")
if err := generateTokenIfNeeded(s); err != nil {
return fmt.Errorf("<master/tokens> failed to generate token(s) [%v]", err)
return fmt.Errorf("failed to generate token(s) [%v]", err)
}
if err := os.MkdirAll(kubeadmapi.GlobalEnvParams.HostPKIPath, 0700); err != nil {
return fmt.Errorf("<master/tokens> failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.HostPKIPath, err)
return fmt.Errorf("failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.HostPKIPath, err)
}
serialized := []byte(fmt.Sprintf("%s,kubeadm-node-csr,%s,system:kubelet-bootstrap\n", s.BearerToken, uuid.NewUUID()))
// DumpReaderToFile create a file with mode 0600
if err := cmdutil.DumpReaderToFile(bytes.NewReader(serialized), tokenAuthFilePath); err != nil {
return fmt.Errorf("<master/tokens> failed to save token auth file (%q) [%v]", tokenAuthFilePath, err)
return fmt.Errorf("failed to save token auth file (%q) [%v]", tokenAuthFilePath, err)
}
return nil
}

View File

@ -53,7 +53,7 @@ const retryTimeout = 5
func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kubeadmapi.ClusterInfo) (*ConnectionDetails, error) {
hostName, err := os.Hostname()
if err != nil {
return nil, fmt.Errorf("<node/bootstrap> failed to get node hostname [%v]", err)
return nil, fmt.Errorf("failed to get node hostname [%v]", err)
}
// TODO(phase1+) https://github.com/kubernetes/kubernetes/issues/33641
nodeName := types.NodeName(hostName)
@ -67,20 +67,20 @@ func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kub
for _, endpoint := range endpoints {
clientSet, err := createClients(caCert, endpoint, s.Secrets.BearerToken, nodeName)
if err != nil {
fmt.Printf("<node/bootstrap> warning: %s. Skipping endpoint %s\n", err, endpoint)
fmt.Printf("[bootstrap] Warning: %s. Skipping endpoint %s\n", err, endpoint)
continue
}
wg.Add(1)
go func(apiEndpoint string) {
defer wg.Done()
wait.Until(func() {
fmt.Printf("<node/bootstrap> trying to connect to endpoint %s\n", apiEndpoint)
fmt.Printf("[bootstrap] Trying to connect to endpoint %s\n", apiEndpoint)
err := checkAPIEndpoint(clientSet, apiEndpoint)
if err != nil {
fmt.Printf("<node/bootstrap> endpoint check failed [%v]\n", err)
fmt.Printf("[bootstrap] Endpoint check failed [%v]\n", err)
return
}
fmt.Printf("<node/bootstrap> successfully established connection with endpoint %s\n", apiEndpoint)
fmt.Printf("[bootstrap] Successfully established connection with endpoint %q\n", apiEndpoint)
// connection established, stop all wait threads
close(stopChan)
result <- &ConnectionDetails{
@ -102,8 +102,7 @@ func EstablishMasterConnection(s *kubeadmapi.NodeConfiguration, clusterInfo *kub
establishedConnection, ok := <-result
if !ok {
return nil, fmt.Errorf("<node/bootstrap> failed to create bootstrap clients " +
"for any of the provided API endpoints")
return nil, fmt.Errorf("failed to create bootstrap clients for any of the provided API endpoints")
}
return establishedConnection, nil
}
@ -122,7 +121,7 @@ func createClients(caCert []byte, endpoint, token string, nodeName types.NodeNam
}
clientSet, err := clientset.NewForConfig(bootstrapClientConfig)
if err != nil {
return nil, fmt.Errorf("failed to create clients for the API endpoint %s [%v]", endpoint, err)
return nil, fmt.Errorf("failed to create clients for the API endpoint %q: [%v]", endpoint, err)
}
return clientSet, nil
}
@ -150,9 +149,9 @@ func checkAPIEndpoint(clientSet *clientset.Clientset, endpoint string) error {
// check general connectivity
version, err := clientSet.DiscoveryClient.ServerVersion()
if err != nil {
return fmt.Errorf("failed to connect to %s [%v]", endpoint, err)
return fmt.Errorf("failed to connect to %q [%v]", endpoint, err)
}
fmt.Printf("<node/bootstrap> detected server version %s\n", version.String())
fmt.Printf("[bootstrap] Detected server version: %s\n", version.String())
// check certificates API
serverGroups, err := clientSet.DiscoveryClient.ServerGroups()

View File

@ -30,22 +30,22 @@ import (
func PerformTLSBootstrap(connection *ConnectionDetails) (*clientcmdapi.Config, error) {
csrClient := connection.CertClient.CertificateSigningRequests()
fmt.Println("<node/csr> created API client to obtain unique certificate for this node, generating keys and certificate signing request")
fmt.Println("[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request")
key, err := certutil.MakeEllipticPrivateKeyPEM()
if err != nil {
return nil, fmt.Errorf("<node/csr> failed to generating private key [%v]", err)
return nil, fmt.Errorf("failed to generating private key [%v]", err)
}
cert, err := csr.RequestNodeCertificate(csrClient, key, connection.NodeName)
if err != nil {
return nil, fmt.Errorf("<node/csr> failed to request signed certificate from the API server [%v]", err)
return nil, fmt.Errorf("failed to request signed certificate from the API server [%v]", err)
}
fmtCert, err := certutil.FormatBytesCert(cert)
if err != nil {
return nil, fmt.Errorf("<node/csr> failed to format certificate [%v]", err)
return nil, fmt.Errorf("failed to format certificate [%v]", err)
}
fmt.Printf("<node/csr> received signed certificate from the API server:\n%s\n", fmtCert)
fmt.Println("<node/csr> generating kubelet configuration")
fmt.Printf("[csr] Received signed certificate from the API server:\n%s\n", fmtCert)
fmt.Println("[csr] Generating kubelet configuration...")
bareClientConfig := kubeadmutil.CreateBasicClientConfig("kubernetes", connection.Endpoint, connection.CACert)
finalConfig := kubeadmutil.MakeClientConfigWithCerts(

View File

@ -37,16 +37,16 @@ func RetrieveTrustedClusterInfo(s *kubeadmapi.NodeConfiguration) (*kubeadmapi.Cl
requestURL := fmt.Sprintf("http://%s:%d/cluster-info/v1/?token-id=%s", host, port, s.Secrets.TokenID)
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return nil, fmt.Errorf("<node/discovery> failed to consturct an HTTP request [%v]", err)
return nil, fmt.Errorf("failed to consturct an HTTP request [%v]", err)
}
fmt.Printf("<node/discovery> created cluster info discovery client, requesting info from %q\n", requestURL)
fmt.Printf("[discovery] Created cluster info discovery client, requesting info from %q\n", requestURL)
var res *http.Response
wait.PollInfinite(discoveryRetryTimeout, func() (bool, error) {
res, err = http.DefaultClient.Do(req)
if err != nil {
fmt.Printf("<node/discovery> failed to request cluster info, will try again: [%s]\n", err)
fmt.Printf("[discovery] Failed to request cluster info, will try again: [%s]\n", err)
return false, nil
}
return true, nil
@ -58,28 +58,28 @@ func RetrieveTrustedClusterInfo(s *kubeadmapi.NodeConfiguration) (*kubeadmapi.Cl
object, err := jose.ParseSigned(buf.String())
if err != nil {
return nil, fmt.Errorf("<node/discovery> failed to parse response as JWS object [%v]", err)
return nil, fmt.Errorf("failed to parse response as JWS object [%v]", err)
}
fmt.Println("<node/discovery> cluster info object received, verifying signature using given token")
fmt.Println("[discovery] Cluster info object received, verifying signature using given token")
output, err := object.Verify(s.Secrets.Token)
if err != nil {
return nil, fmt.Errorf("<node/discovery> failed to verify JWS signature of received cluster info object [%v]", err)
return nil, fmt.Errorf("failed to verify JWS signature of received cluster info object [%v]", err)
}
clusterInfo := kubeadmapi.ClusterInfo{}
if err := json.Unmarshal(output, &clusterInfo); err != nil {
return nil, fmt.Errorf("<node/discovery> failed to decode received cluster info object [%v]", err)
return nil, fmt.Errorf("failed to decode received cluster info object [%v]", err)
}
if len(clusterInfo.CertificateAuthorities) == 0 || len(clusterInfo.Endpoints) == 0 {
return nil, fmt.Errorf("<node/discovery> cluster info object is invalid - no endpoint(s) and/or root CA certificate(s) found")
return nil, fmt.Errorf("cluster info object is invalid - no endpoint(s) and/or root CA certificate(s) found")
}
// TODO(phase1+) print summary info about the CA certificate, along with the the checksum signature
// we also need an ability for the user to configure the client to validate received CA cert against a checksum
fmt.Printf("<node/discovery> cluster info signature and contents are valid, will use API endpoints %v\n", clusterInfo.Endpoints)
fmt.Printf("[discovery] Cluster info signature and contents are valid, will use API endpoints %v\n", clusterInfo.Endpoints)
return &clusterInfo, nil
}

View File

@ -25,9 +25,11 @@ import (
"net/http"
"os"
"os/exec"
"path"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/pkg/api/validation"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/initsystem"
"k8s.io/kubernetes/pkg/util/node"
"k8s.io/kubernetes/test/e2e_node/system"
@ -243,13 +245,28 @@ type SystemVerificationCheck struct{}
func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
// Create a buffered writer and choose a quite large value (1M) and suppose the output from the system verification test won't exceed the limit
bufw := bufio.NewWriterSize(os.Stdout, 1*1024*1024)
// Run the system verification check, but write to out buffered writer instead of stdout
err := system.Validate(system.DefaultSysSpec, &system.StreamReporter{WriteStream: bufw})
bufw := bufio.NewWriterSize(os.Stdout, 1*1024*1024)
reporter := &system.StreamReporter{WriteStream: bufw}
var errs []error
// All the validators we'd like to run:
var validators = []system.Validator{
&system.OSValidator{Reporter: reporter},
&system.KernelValidator{Reporter: reporter},
&system.CgroupsValidator{Reporter: reporter},
&system.DockerValidator{Reporter: reporter},
}
// Run all validators
for _, v := range validators {
errs = append(errs, v.Validate(system.DefaultSysSpec))
}
err := utilerrors.NewAggregate(errs)
if err != nil {
// Only print the output from the system verification check if the check failed
fmt.Println("System verification failed. Printing the output from the verification...")
fmt.Println("[preflight] The system verification failed. Printing the output from the verification:")
bufw.Flush()
return nil, []error{err}
}
@ -271,11 +288,11 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
PortOpenCheck{port: 10251},
PortOpenCheck{port: 10252},
HTTPProxyCheck{Proto: "https", Host: cfg.API.AdvertiseAddresses[0], Port: int(cfg.API.BindPort)},
DirAvailableCheck{Path: "/etc/kubernetes/manifests"},
DirAvailableCheck{Path: "/etc/kubernetes/pki"},
DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")},
DirAvailableCheck{Path: kubeadmapi.GlobalEnvParams.HostPKIPath},
DirAvailableCheck{Path: "/var/lib/kubelet"},
FileAvailableCheck{Path: "/etc/kubernetes/admin.conf"},
FileAvailableCheck{Path: "/etc/kubernetes/kubelet.conf"},
FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "admin.conf")},
FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")},
InPathCheck{executable: "ip", mandatory: true},
InPathCheck{executable: "iptables", mandatory: true},
InPathCheck{executable: "mount", mandatory: true},
@ -308,9 +325,9 @@ func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error {
PortOpenCheck{port: 10250},
HTTPProxyCheck{Proto: "https", Host: cfg.MasterAddresses[0], Port: int(cfg.APIPort)},
HTTPProxyCheck{Proto: "http", Host: cfg.MasterAddresses[0], Port: int(cfg.DiscoveryPort)},
DirAvailableCheck{Path: "/etc/kubernetes/manifests"},
DirAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "manifests")},
DirAvailableCheck{Path: "/var/lib/kubelet"},
FileAvailableCheck{Path: "/etc/kubernetes/kubelet.conf"},
FileAvailableCheck{Path: path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, "kubelet.conf")},
InPathCheck{executable: "ip", mandatory: true},
InPathCheck{executable: "iptables", mandatory: true},
InPathCheck{executable: "mount", mandatory: true},

View File

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors.
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -22,37 +22,18 @@ import (
"strings"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
"github.com/golang/glog"
"github.com/renstrom/dedent"
)
const (
DefaultErrorExitCode = 1
PreFlight = 2
PreFlightExitCode = 2
)
var AlphaWarningOnExit = dedent.Dedent(`
kubeadm: I am an alpha version, my authors welcome your feedback and bug reports
kubeadm: please create an issue using https://github.com/kubernetes/kubernetes/issues/new
kubeadm: and make sure to mention @kubernetes/sig-cluster-lifecycle. Thank you!
`)
type debugError interface {
DebugError() (msg string, args []interface{})
}
var fatalErrHandler = fatal
// BehaviorOnFatal allows you to override the default behavior when a fatal
// error occurs, which is to call os.Exit(code). You can pass 'panic' as a function
// here if you prefer the panic() over os.Exit(1).
func BehaviorOnFatal(f func(string, int)) {
fatalErrHandler = f
}
// fatal prints the message if set and then exits. If V(2) or greater, glog.Fatal
// is invoked for extended information.
// fatal prints the message if set and then exits.
func fatal(msg string, code int) {
if len(msg) > 0 {
// add newline if needed
@ -60,9 +41,6 @@ func fatal(msg string, code int) {
msg += "\n"
}
if glog.V(2) {
glog.FatalDepth(2, msg)
}
fmt.Fprint(os.Stderr, msg)
}
os.Exit(code)
@ -74,7 +52,7 @@ func fatal(msg string, code int) {
// This method is generic to the command in use and may be used by non-Kubectl
// commands.
func CheckErr(err error) {
checkErr("", err, fatalErrHandler)
checkErr("", err, fatal)
}
// checkErr formats a given error as a string and calls the passed handleErr
@ -84,9 +62,8 @@ func checkErr(prefix string, err error, handleErr func(string, int)) {
case nil:
return
case *preflight.PreFlightError:
handleErr(err.Error(), PreFlight)
handleErr(err.Error(), PreFlightExitCode)
default:
fmt.Printf(AlphaWarningOnExit)
handleErr(err.Error(), DefaultErrorExitCode)
}
}

View File

@ -21,7 +21,6 @@ import (
"os"
"path"
// TODO: "k8s.io/client-go/client/tools/clientcmd/api"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
@ -77,21 +76,21 @@ func MakeClientConfigWithToken(config *clientcmdapi.Config, clusterName string,
func WriteKubeconfigIfNotExists(name string, kubeconfig *clientcmdapi.Config) error {
if err := os.MkdirAll(kubeadmapi.GlobalEnvParams.KubernetesDir, 0700); err != nil {
return fmt.Errorf("<util/kubeconfig> failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.KubernetesDir, err)
return fmt.Errorf("failed to create directory %q [%v]", kubeadmapi.GlobalEnvParams.KubernetesDir, err)
}
filename := path.Join(kubeadmapi.GlobalEnvParams.KubernetesDir, fmt.Sprintf("%s.conf", name))
// Create and open the file, only if it does not already exist.
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600)
if err != nil {
return fmt.Errorf("<util/kubeconfig> failed to create %q, it already exists [%v]", filename, err)
return fmt.Errorf("failed to create %q, it already exists [%v]", filename, err)
}
f.Close()
if err := clientcmd.WriteToFile(*kubeconfig, filename); err != nil {
return fmt.Errorf("<util/kubeconfig> failed to write to %q [%v]", filename, err)
return fmt.Errorf("failed to write to %q [%v]", filename, err)
}
fmt.Printf("<util/kubeconfig> created %q\n", filename)
fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", filename)
return nil
}

View File

@ -64,10 +64,10 @@ func UseGivenTokenIfValid(s *kubeadmapi.Secrets) (bool, error) {
if s.GivenToken == "" {
return false, nil // not given
}
fmt.Println("<util/tokens> validating provided token")
fmt.Println("[tokens] Validating provided token...")
givenToken := strings.Split(strings.ToLower(s.GivenToken), ".")
// TODO(phase1+) could also print more specific messages in each case
invalidErr := "<util/tokens> provided token does not match expected <6 characters>.<16 characters> format - %s"
invalidErr := "[tokens] Provided token does not match expected <6 characters>.<16 characters> format - %s"
if len(givenToken) != 2 {
return false, fmt.Errorf(invalidErr, "not in 2-part dot-separated format")
}

View File

@ -17,16 +17,13 @@ limitations under the License.
package main
import (
"fmt"
"os"
"k8s.io/kubernetes/cmd/kubeadm/app"
"k8s.io/kubernetes/cmd/kubeadm/app/util"
)
func main() {
if err := app.Run(); err != nil {
fmt.Printf(util.AlphaWarningOnExit)
os.Exit(1)
}
os.Exit(0)