join-phases-texts

This commit is contained in:
fabriziopandini 2019-03-02 21:52:04 +01:00
parent e1b79abfec
commit a3ed9f0c2c
7 changed files with 45 additions and 33 deletions

View File

@ -157,7 +157,7 @@ func NewCmdJoin(out io.Writer, joinOptions *joinOptions) *cobra.Command {
joinRunner := workflow.NewRunner() joinRunner := workflow.NewRunner()
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "join", Use: "join [api-server-endpoint]",
Short: "Run this on any machine you wish to join an existing cluster", Short: "Run this on any machine you wish to join an existing cluster",
Long: joinLongDescription, Long: joinLongDescription,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
@ -336,7 +336,7 @@ func newJoinData(cmd *cobra.Command, args []string, opt *joinOptions, out io.Wri
opt.externalcfg.Discovery.BootstrapToken = nil opt.externalcfg.Discovery.BootstrapToken = nil
} else { } else {
if len(opt.cfgPath) == 0 && len(args) > 1 { if len(opt.cfgPath) == 0 && len(args) > 1 {
klog.Warningf("[join] WARNING: More than one API server endpoint supplied on command line %v. Using the first one.", args) klog.Warningf("[preflight] WARNING: More than one API server endpoint supplied on command line %v. Using the first one.", args)
} }
opt.externalcfg.Discovery.BootstrapToken.APIServerEndpoint = args[0] opt.externalcfg.Discovery.BootstrapToken.APIServerEndpoint = args[0]
} }
@ -352,7 +352,7 @@ func newJoinData(cmd *cobra.Command, args []string, opt *joinOptions, out io.Wri
var tlsBootstrapCfg *clientcmdapi.Config var tlsBootstrapCfg *clientcmdapi.Config
if _, err := os.Stat(adminKubeConfigPath); err == nil && opt.controlPlane { if _, err := os.Stat(adminKubeConfigPath); err == nil && opt.controlPlane {
// use the admin.conf as tlsBootstrapCfg, that is the kubeconfig file used for reading the kubeadm-config during discovery // use the admin.conf as tlsBootstrapCfg, that is the kubeconfig file used for reading the kubeadm-config during discovery
klog.V(1).Infof("[join] found %s. Use it for skipping discovery", adminKubeConfigPath) klog.V(1).Infof("[preflight] found %s. Use it for skipping discovery", adminKubeConfigPath)
tlsBootstrapCfg, err = clientcmd.LoadFromFile(adminKubeConfigPath) tlsBootstrapCfg, err = clientcmd.LoadFromFile(adminKubeConfigPath)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "Error loading %s", adminKubeConfigPath) return nil, errors.Wrapf(err, "Error loading %s", adminKubeConfigPath)
@ -371,11 +371,11 @@ func newJoinData(cmd *cobra.Command, args []string, opt *joinOptions, out io.Wri
// Either use the config file if specified, or convert public kubeadm API to the internal JoinConfiguration // Either use the config file if specified, or convert public kubeadm API to the internal JoinConfiguration
// and validates JoinConfiguration // and validates JoinConfiguration
if opt.externalcfg.NodeRegistration.Name == "" { if opt.externalcfg.NodeRegistration.Name == "" {
klog.V(1).Infoln("[join] found NodeName empty; using OS hostname as NodeName") klog.V(1).Infoln("[preflight] found NodeName empty; using OS hostname as NodeName")
} }
if opt.externalcfg.ControlPlane != nil && opt.externalcfg.ControlPlane.LocalAPIEndpoint.AdvertiseAddress == "" { if opt.externalcfg.ControlPlane != nil && opt.externalcfg.ControlPlane.LocalAPIEndpoint.AdvertiseAddress == "" {
klog.V(1).Infoln("[join] found advertiseAddress empty; using default interface's IP address as advertiseAddress") klog.V(1).Infoln("[preflight] found advertiseAddress empty; using default interface's IP address as advertiseAddress")
} }
// in case the command doesn't have flags for discovery, makes the join cfg validation pass checks on discovery // in case the command doesn't have flags for discovery, makes the join cfg validation pass checks on discovery
@ -383,7 +383,7 @@ func newJoinData(cmd *cobra.Command, args []string, opt *joinOptions, out io.Wri
if _, err := os.Stat(adminKubeConfigPath); os.IsNotExist(err) { if _, err := os.Stat(adminKubeConfigPath); os.IsNotExist(err) {
return nil, errors.Errorf("File %s does not exists. Please use 'kubeadm join phase control-plane-prepare' subcommands to generate it.", adminKubeConfigPath) return nil, errors.Errorf("File %s does not exists. Please use 'kubeadm join phase control-plane-prepare' subcommands to generate it.", adminKubeConfigPath)
} }
klog.V(1).Infof("[join] found discovery flags missing for this command. using FileDiscovery: %s", adminKubeConfigPath) klog.V(1).Infof("[preflight] found discovery flags missing for this command. using FileDiscovery: %s", adminKubeConfigPath)
opt.externalcfg.Discovery.File = &kubeadmapiv1beta1.FileDiscovery{KubeConfigPath: adminKubeConfigPath} opt.externalcfg.Discovery.File = &kubeadmapiv1beta1.FileDiscovery{KubeConfigPath: adminKubeConfigPath}
opt.externalcfg.Discovery.BootstrapToken = nil //NB. this could be removed when we get better control on args (e.g. phases without discovery should have NoArgs ) opt.externalcfg.Discovery.BootstrapToken = nil //NB. this could be removed when we get better control on args (e.g. phases without discovery should have NoArgs )
} }
@ -431,7 +431,7 @@ func (j *joinData) TLSBootstrapCfg() (*clientcmdapi.Config, error) {
if j.tlsBootstrapCfg != nil { if j.tlsBootstrapCfg != nil {
return j.tlsBootstrapCfg, nil return j.tlsBootstrapCfg, nil
} }
klog.V(1).Infoln("[join] Discovering cluster-info") klog.V(1).Infoln("[preflight] Discovering cluster-info")
tlsBootstrapCfg, err := discovery.For(j.cfg) tlsBootstrapCfg, err := discovery.For(j.cfg)
j.tlsBootstrapCfg = tlsBootstrapCfg j.tlsBootstrapCfg = tlsBootstrapCfg
return tlsBootstrapCfg, err return tlsBootstrapCfg, err
@ -445,7 +445,7 @@ func (j *joinData) InitCfg() (*kubeadmapi.InitConfiguration, error) {
if _, err := j.TLSBootstrapCfg(); err != nil { if _, err := j.TLSBootstrapCfg(); err != nil {
return nil, err return nil, err
} }
klog.V(1).Infoln("[join] Fetching init configuration") klog.V(1).Infoln("[preflight] Fetching init configuration")
initCfg, err := fetchInitConfigurationFromJoinConfiguration(j.cfg, j.tlsBootstrapCfg) initCfg, err := fetchInitConfigurationFromJoinConfiguration(j.cfg, j.tlsBootstrapCfg)
j.initCfg = initCfg j.initCfg = initCfg
return initCfg, err return initCfg, err
@ -459,7 +459,7 @@ func (j *joinData) ClientSet() (*clientset.Clientset, error) {
path := kubeadmconstants.GetAdminKubeConfigPath() path := kubeadmconstants.GetAdminKubeConfigPath()
client, err := kubeconfigutil.ClientSetFromFile(path) client, err := kubeconfigutil.ClientSetFromFile(path)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "[join] couldn't create Kubernetes client") return nil, errors.Wrap(err, "[preflight] couldn't create Kubernetes client")
} }
j.clientSet = client j.clientSet = client
return client, nil return client, nil
@ -478,7 +478,7 @@ func (j *joinData) OutputWriter() io.Writer {
// fetchInitConfigurationFromJoinConfiguration retrieves the init configuration from a join configuration, performing the discovery // fetchInitConfigurationFromJoinConfiguration retrieves the init configuration from a join configuration, performing the discovery
func fetchInitConfigurationFromJoinConfiguration(cfg *kubeadmapi.JoinConfiguration, tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.InitConfiguration, error) { func fetchInitConfigurationFromJoinConfiguration(cfg *kubeadmapi.JoinConfiguration, tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.InitConfiguration, error) {
// Retrieves the kubeadm configuration // Retrieves the kubeadm configuration
klog.V(1).Infoln("[join] Retrieving KubeConfig objects") klog.V(1).Infoln("[preflight] Retrieving KubeConfig objects")
initConfiguration, err := fetchInitConfiguration(tlsBootstrapCfg) initConfiguration, err := fetchInitConfiguration(tlsBootstrapCfg)
if err != nil { if err != nil {
return nil, err return nil, err
@ -509,7 +509,7 @@ func fetchInitConfiguration(tlsBootstrapCfg *clientcmdapi.Config) (*kubeadmapi.I
} }
// Fetches the init configuration // Fetches the init configuration
initConfiguration, err := configutil.FetchInitConfigurationFromCluster(tlsClient, os.Stdout, "join", true) initConfiguration, err := configutil.FetchInitConfigurationFromCluster(tlsClient, os.Stdout, "preflight", true)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap") return nil, errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap")
} }

View File

@ -62,7 +62,7 @@ func NewControlPlaneJoinPhase() workflow.Phase {
RunAllSiblings: true, RunAllSiblings: true,
}, },
newEtcdLocalSubphase(), newEtcdLocalSubphase(),
newUploadConfigSubphase(), newUpdateStatusSubphase(),
newMarkControlPlaneSubphase(), newMarkControlPlaneSubphase(),
}, },
} }
@ -71,17 +71,21 @@ func NewControlPlaneJoinPhase() workflow.Phase {
func newEtcdLocalSubphase() workflow.Phase { func newEtcdLocalSubphase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "etcd", Name: "etcd",
Short: "Generates the static Pod manifest file for a local etcd member", Short: "Add a new local etcd member",
Run: runEtcdPhase, Run: runEtcdPhase,
InheritFlags: getControlPlaneJoinPhaseFlags(), InheritFlags: getControlPlaneJoinPhaseFlags(),
} }
} }
func newUploadConfigSubphase() workflow.Phase { func newUpdateStatusSubphase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "upload-config", Name: "update-status",
Short: "Upload the currently used configuration to the cluster", Short: fmt.Sprintf(
Run: runUploadConfigPhase, "Register the new control-plane node into the %s maintained in the %s ConfigMap",
kubeadmconstants.ClusterStatusConfigMapKey,
kubeadmconstants.KubeadmConfigConfigMap,
),
Run: runUpdateStatusPhase,
InheritFlags: getControlPlaneJoinPhaseFlags(), InheritFlags: getControlPlaneJoinPhaseFlags(),
} }
} }
@ -136,7 +140,7 @@ func runEtcdPhase(c workflow.RunData) error {
return nil return nil
} }
func runUploadConfigPhase(c workflow.RunData) error { func runUpdateStatusPhase(c workflow.RunData) error {
data, ok := c.(JoinData) data, ok := c.(JoinData)
if !ok { if !ok {
return errors.New("control-plane-join phase invoked with an invalid data struct") return errors.New("control-plane-join phase invoked with an invalid data struct")

View File

@ -25,7 +25,6 @@ import (
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
@ -41,7 +40,7 @@ func NewControlPlanePreparePhase() workflow.Phase {
Short: "Prepares the machine for serving a control plane.", Short: "Prepares the machine for serving a control plane.",
Phases: []workflow.Phase{ Phases: []workflow.Phase{
{ {
Name: "all", Name: "all [api-server-endpoint]",
Short: "Prepares the machine for serving a control plane.", Short: "Prepares the machine for serving a control plane.",
InheritFlags: getControlPlanePreparePhaseFlags("all"), InheritFlags: getControlPlanePreparePhaseFlags("all"),
RunAllSiblings: true, RunAllSiblings: true,
@ -82,9 +81,8 @@ func getControlPlanePreparePhaseFlags(name string) []string {
func newControlPlanePrepareDownloadCertsSubphase() workflow.Phase { func newControlPlanePrepareDownloadCertsSubphase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "download-certs", Name: "download-certs [api-server-endpoint]",
Short: fmt.Sprintf("Download certificates from %s", kubeadmconstants.KubeadmCertsSecret), Short: fmt.Sprintf("[EXPERIMENTAL] Downloads certificates shared among control-plane nodes from the %s Secret", kubeadmconstants.KubeadmCertsSecret),
Long: cmdutil.MacroCommandLongDescription,
Run: runControlPlanePrepareDownloadCertsPhaseLocal, Run: runControlPlanePrepareDownloadCertsPhaseLocal,
InheritFlags: getControlPlanePreparePhaseFlags("download-certs"), InheritFlags: getControlPlanePreparePhaseFlags("download-certs"),
} }
@ -92,7 +90,7 @@ func newControlPlanePrepareDownloadCertsSubphase() workflow.Phase {
func newControlPlanePrepareCertsSubphase() workflow.Phase { func newControlPlanePrepareCertsSubphase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "certs", Name: "certs [api-server-endpoint]",
Short: "Generates the certificates for the new control plane components", Short: "Generates the certificates for the new control plane components",
Run: runControlPlanePrepareCertsPhaseLocal, //NB. eventually in future we would like to break down this in sub phases for each cert or add the --csr option Run: runControlPlanePrepareCertsPhaseLocal, //NB. eventually in future we would like to break down this in sub phases for each cert or add the --csr option
InheritFlags: getControlPlanePreparePhaseFlags("certs"), InheritFlags: getControlPlanePreparePhaseFlags("certs"),
@ -101,7 +99,7 @@ func newControlPlanePrepareCertsSubphase() workflow.Phase {
func newControlPlanePrepareKubeconfigSubphase() workflow.Phase { func newControlPlanePrepareKubeconfigSubphase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "kubeconfig", Name: "kubeconfig [api-server-endpoint]",
Short: "Generates the kubeconfig for the new control plane components", Short: "Generates the kubeconfig for the new control plane components",
Run: runControlPlanePrepareKubeconfigPhaseLocal, //NB. eventually in future we would like to break down this in sub phases for each kubeconfig Run: runControlPlanePrepareKubeconfigPhaseLocal, //NB. eventually in future we would like to break down this in sub phases for each kubeconfig
InheritFlags: getControlPlanePreparePhaseFlags("kubeconfig"), InheritFlags: getControlPlanePreparePhaseFlags("kubeconfig"),
@ -110,7 +108,7 @@ func newControlPlanePrepareKubeconfigSubphase() workflow.Phase {
func newControlPlanePrepareManifestsSubphases() workflow.Phase { func newControlPlanePrepareManifestsSubphases() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "manifests", Name: "control-plane",
Short: "Generates the manifests for the new control plane components", Short: "Generates the manifests for the new control plane components",
Run: runControlPlanePrepareManifestsSubphase, //NB. eventually in future we would like to break down this in sub phases for each component Run: runControlPlanePrepareManifestsSubphase, //NB. eventually in future we would like to break down this in sub phases for each component
InheritFlags: getControlPlanePreparePhaseFlags("manifests"), InheritFlags: getControlPlanePreparePhaseFlags("manifests"),

View File

@ -56,7 +56,7 @@ var (
// NewKubeletStartPhase creates a kubeadm workflow phase that start kubelet on a node. // NewKubeletStartPhase creates a kubeadm workflow phase that start kubelet on a node.
func NewKubeletStartPhase() workflow.Phase { func NewKubeletStartPhase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "kubelet-start", Name: "kubelet-start [api-server-endpoint]",
Short: "Writes kubelet settings, certificates and (re)starts the kubelet", Short: "Writes kubelet settings, certificates and (re)starts the kubelet",
Long: "Writes a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)starts kubelet.", Long: "Writes a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)starts kubelet.",
Run: runKubeletStartJoinPhase, Run: runKubeletStartJoinPhase,
@ -102,7 +102,7 @@ func runKubeletStartJoinPhase(c workflow.RunData) error {
bootstrapKubeConfigFile := kubeadmconstants.GetBootstrapKubeletKubeConfigPath() bootstrapKubeConfigFile := kubeadmconstants.GetBootstrapKubeletKubeConfigPath()
// Write the bootstrap kubelet config file or the TLS-Boostrapped kubelet config file down to disk // Write the bootstrap kubelet config file or the TLS-Boostrapped kubelet config file down to disk
klog.V(1).Infoln("[join] writing bootstrap kubelet config file at", bootstrapKubeConfigFile) klog.V(1).Infoln("[kubelet-start] writing bootstrap kubelet config file at", bootstrapKubeConfigFile)
if err := kubeconfigutil.WriteToDisk(bootstrapKubeConfigFile, tlsBootstrapCfg); err != nil { if err := kubeconfigutil.WriteToDisk(bootstrapKubeConfigFile, tlsBootstrapCfg); err != nil {
return errors.Wrap(err, "couldn't save bootstrap-kubelet.conf to disk") return errors.Wrap(err, "couldn't save bootstrap-kubelet.conf to disk")
} }

View File

@ -54,7 +54,7 @@ var (
// NewPreflightPhase creates a kubeadm workflow phase that implements preflight checks for a new node join // NewPreflightPhase creates a kubeadm workflow phase that implements preflight checks for a new node join
func NewPreflightPhase() workflow.Phase { func NewPreflightPhase() workflow.Phase {
return workflow.Phase{ return workflow.Phase{
Name: "preflight", Name: "preflight [api-server-endpoint]",
Short: "Run join pre-flight checks", Short: "Run join pre-flight checks",
Long: "Run pre-flight checks for kubeadm join.", Long: "Run pre-flight checks for kubeadm join.",
Example: preflightExample, Example: preflightExample,

View File

@ -442,8 +442,8 @@ func (e *Runner) prepareForExecution() {
// addPhaseRunner adds the phaseRunner for a given phase to the phaseRunners list // addPhaseRunner adds the phaseRunner for a given phase to the phaseRunners list
func addPhaseRunner(e *Runner, parentRunner *phaseRunner, phase Phase) { func addPhaseRunner(e *Runner, parentRunner *phaseRunner, phase Phase) {
// computes contextual information derived by the workflow managed by the Runner. // computes contextual information derived by the workflow managed by the Runner.
generatedName := strings.ToLower(phase.Name) use := cleanName(phase.Name)
use := generatedName generatedName := use
selfPath := []string{generatedName} selfPath := []string{generatedName}
if parentRunner != nil { if parentRunner != nil {
@ -471,3 +471,13 @@ func addPhaseRunner(e *Runner, parentRunner *phaseRunner, phase Phase) {
addPhaseRunner(e, currentRunner, childPhase) addPhaseRunner(e, currentRunner, childPhase)
} }
} }
// cleanName makes phase name suitable for the runner help, by lowercasing the name
// and removing args descriptors, if any
func cleanName(name string) string {
ret := strings.ToLower(name)
if pos := strings.Index(ret, " "); pos != -1 {
ret = ret[:pos]
}
return ret
}

View File

@ -262,7 +262,7 @@ func TestHelp(t *testing.T) {
var w = Runner{ var w = Runner{
Phases: []Phase{ Phases: []Phase{
phaseBuilder3("foo", false, phaseBuilder3("foo", false,
phaseBuilder3("bar", false), phaseBuilder3("bar [arg]", false),
phaseBuilder3("baz", true), phaseBuilder3("baz", true),
), ),
phaseBuilder3("qux", false), phaseBuilder3("qux", false),
@ -272,7 +272,7 @@ func TestHelp(t *testing.T) {
expected := "The \"myCommand\" command executes the following phases:\n" + expected := "The \"myCommand\" command executes the following phases:\n" +
"```\n" + "```\n" +
"foo long description for foo ...\n" + "foo long description for foo ...\n" +
" /bar long description for bar ...\n" + " /bar long description for bar [arg] ...\n" +
"qux long description for qux ...\n" + "qux long description for qux ...\n" +
"```" "```"