Skip to content

Commit

Permalink
Merge pull request kubernetes#50872 from luxas/kubeadm_upgrade_cmds
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue (batch tested with PRs 50872, 51103, 51220, 51285, 50841)

kubeadm: Add 'kubeadm upgrade plan' and 'kubeadm upgrade apply' CLI commands

**What this PR does / why we need it**:

This PR is splitted out from: kubernetes#48899 and only handles the CLI/command code. It adds no-op functions only to `phases/upgrade`.

A large chunk of this code is unit tests.
The code here should be pretty straightforward as there is no actual upgrade or business logic here.
It would be cool to get this merged soon-ish.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

fixes: kubernetes/kubeadm#14

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```
@kubernetes/sig-cluster-lifecycle-pr-reviews PTAL
  • Loading branch information
Kubernetes Submit Queue authored Aug 25, 2017
2 parents b248f77 + 396a33d commit 43c1b5f
Show file tree
Hide file tree
Showing 34 changed files with 1,707 additions and 68 deletions.
1 change: 1 addition & 0 deletions cmd/kubeadm/app/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ filegroup(
"//cmd/kubeadm/app/phases/markmaster:all-srcs",
"//cmd/kubeadm/app/phases/selfhosting:all-srcs",
"//cmd/kubeadm/app/phases/token:all-srcs",
"//cmd/kubeadm/app/phases/upgrade:all-srcs",
"//cmd/kubeadm/app/phases/uploadconfig:all-srcs",
"//cmd/kubeadm/app/preflight:all-srcs",
"//cmd/kubeadm/app/util:all-srcs",
Expand Down
4 changes: 4 additions & 0 deletions cmd/kubeadm/app/cmd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ go_library(
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
"//cmd/kubeadm/app/cmd/phases:go_default_library",
"//cmd/kubeadm/app/cmd/upgrade:go_default_library",
"//cmd/kubeadm/app/cmd/util:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/discovery:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
Expand Down Expand Up @@ -95,6 +97,8 @@ filegroup(
srcs = [
":package-srcs",
"//cmd/kubeadm/app/cmd/phases:all-srcs",
"//cmd/kubeadm/app/cmd/upgrade:all-srcs",
"//cmd/kubeadm/app/cmd/util:all-srcs",
],
tags = ["automanaged"],
)
18 changes: 2 additions & 16 deletions cmd/kubeadm/app/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ limitations under the License.
package cmd

import (
"fmt"
"io"

"github.com/renstrom/dedent"
"github.com/spf13/cobra"

"k8s.io/apiserver/pkg/util/flag"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)

Expand Down Expand Up @@ -75,6 +75,7 @@ func NewKubeadmCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
cmds.AddCommand(NewCmdReset(out))
cmds.AddCommand(NewCmdVersion(out))
cmds.AddCommand(NewCmdToken(out, err))
cmds.AddCommand(upgrade.NewCmdUpgrade(out))

// Wrap not yet fully supported commands in an alpha subcommand
experimentalCmd := &cobra.Command{
Expand All @@ -86,18 +87,3 @@ func NewKubeadmCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob

return cmds
}

// subCmdRunE returns a function that handles a case where a subcommand must be specified
// Without this callback, if a user runs just the command without a subcommand,
// or with an invalid subcommand, cobra will print usage information, but still exit cleanly.
// We want to return an error code in these cases so that the
// user knows that their command was invalid.
func subCmdRunE(name string) func(*cobra.Command, []string) error {
return func(_ *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("missing subcommand; %q is not meant to be run on its own", name)
}

return fmt.Errorf("invalid subcommand: %q", args[0])
}
}
5 changes: 3 additions & 2 deletions cmd/kubeadm/app/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientset "k8s.io/client-go/kubernetes"
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
Expand All @@ -52,7 +53,7 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
// cobra will print usage information, but still exit cleanly.
// We want to return an error code in these cases so that the
// user knows that their command was invalid.
RunE: subCmdRunE("config"),
RunE: cmdutil.SubCmdRunE("config"),
}

cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
Expand All @@ -67,7 +68,7 @@ func NewCmdConfigUpload(out io.Writer, kubeConfigFile *string) *cobra.Command {
cmd := &cobra.Command{
Use: "upload",
Short: "Upload configuration about the current state so 'kubeadm upgrade' later can know how to configure the upgraded cluster",
RunE: subCmdRunE("upload"),
RunE: cmdutil.SubCmdRunE("upload"),
}

cmd.AddCommand(NewCmdConfigUploadFromFile(out, kubeConfigFile))
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/phases/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ go_library(
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
"//cmd/kubeadm/app/cmd/util:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
Expand Down Expand Up @@ -54,7 +55,6 @@ go_test(
"controlplane_test.go",
"etcd_test.go",
"kubeconfig_test.go",
"phase_test.go",
],
library = ":go_default_library",
deps = [
Expand Down
7 changes: 4 additions & 3 deletions cmd/kubeadm/app/cmd/phases/bootstraptoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/spf13/cobra"

clientset "k8s.io/client-go/kubernetes"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
Expand All @@ -36,7 +37,7 @@ func NewCmdBootstrapToken() *cobra.Command {
Use: "bootstrap-token",
Short: "Manage kubeadm-specific Bootstrap Token functions.",
Aliases: []string{"bootstraptoken"},
RunE: subCmdRunE("bootstrap-token"),
RunE: cmdutil.SubCmdRunE("bootstrap-token"),
}

cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
Expand All @@ -55,7 +56,7 @@ func NewSubCmdClusterInfo(kubeConfigFile *string) *cobra.Command {
Short: "Uploads and exposes the cluster-info ConfigMap publicly from the given cluster-info file",
Aliases: []string{"clusterinfo"},
Run: func(cmd *cobra.Command, args []string) {
err := validateExactArgNumber(args, []string{"clusterinfo-file"})
err := cmdutil.ValidateExactArgNumber(args, []string{"clusterinfo-file"})
kubeadmutil.CheckErr(err)

client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
Expand All @@ -81,7 +82,7 @@ func NewSubCmdNodeBootstrapToken(kubeConfigFile *string) *cobra.Command {
Use: "node",
Short: "Manages Node Bootstrap Tokens",
Aliases: []string{"clusterinfo"},
RunE: subCmdRunE("node"),
RunE: cmdutil.SubCmdRunE("node"),
}

cmd.AddCommand(NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile))
Expand Down
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/phases/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
Expand All @@ -34,7 +35,7 @@ func NewCmdCerts() *cobra.Command {
Use: "certs",
Aliases: []string{"certificates"},
Short: "Generate certificates for a Kubernetes cluster.",
RunE: subCmdRunE("certs"),
RunE: cmdutil.SubCmdRunE("certs"),
}

cmd.AddCommand(getCertsSubCommands()...)
Expand Down
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/phases/controlplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
"k8s.io/kubernetes/pkg/api"
Expand All @@ -31,7 +32,7 @@ func NewCmdControlplane() *cobra.Command {
cmd := &cobra.Command{
Use: "controlplane",
Short: "Generate all static pod manifest files necessary to establish the control plane.",
RunE: subCmdRunE("controlplane"),
RunE: cmdutil.SubCmdRunE("controlplane"),
}

manifestPath := kubeadmconstants.GetStaticPodDirectory()
Expand Down
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/phases/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
"k8s.io/kubernetes/pkg/api"
Expand All @@ -31,7 +32,7 @@ func NewCmdEtcd() *cobra.Command {
cmd := &cobra.Command{
Use: "etcd",
Short: "Generate static pod manifest file for etcd.",
RunE: subCmdRunE("etcd"),
RunE: cmdutil.SubCmdRunE("etcd"),
}

manifestPath := kubeadmconstants.GetStaticPodDirectory()
Expand Down
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/phases/kubeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
"k8s.io/kubernetes/pkg/api"
Expand All @@ -34,7 +35,7 @@ func NewCmdKubeConfig(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "kubeconfig",
Short: "Generate all kubeconfig files necessary to establish the control plane and the admin kubeconfig file.",
RunE: subCmdRunE("kubeconfig"),
RunE: cmdutil.SubCmdRunE("kubeconfig"),
}

cmd.AddCommand(getKubeConfigSubCommands(out, kubeadmconstants.KubernetesDir)...)
Expand Down
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/phases/markmaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package phases
import (
"github.com/spf13/cobra"

cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
Expand All @@ -32,7 +33,7 @@ func NewCmdMarkMaster() *cobra.Command {
Short: "Mark a node as master.",
Aliases: []string{"markmaster"},
RunE: func(_ *cobra.Command, args []string) error {
err := validateExactArgNumber(args, []string{"node-name"})
err := cmdutil.ValidateExactArgNumber(args, []string{"node-name"})
kubeadmutil.CheckErr(err)

client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
Expand Down
38 changes: 2 additions & 36 deletions cmd/kubeadm/app/cmd/phases/phase.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ limitations under the License.
package phases

import (
"fmt"
"io"

"github.com/spf13/cobra"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
)

// NewCmdPhase returns the cobra command for the "kubeadm phase" command (currently alpha-gated)
func NewCmdPhase(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "phase",
Short: "Invoke subsets of kubeadm functions separately for a manual install.",
RunE: subCmdRunE("phase"),
RunE: cmdutil.SubCmdRunE("phase"),
}

cmd.AddCommand(NewCmdBootstrapToken())
Expand All @@ -43,37 +43,3 @@ func NewCmdPhase(out io.Writer) *cobra.Command {

return cmd
}

// subCmdRunE returns a function that handles a case where a subcommand must be specified
// Without this callback, if a user runs just the command without a subcommand,
// or with an invalid subcommand, cobra will print usage information, but still exit cleanly.
// We want to return an error code in these cases so that the
// user knows that their command was invalid.
func subCmdRunE(name string) func(*cobra.Command, []string) error {
return func(_ *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("missing subcommand; %q is not meant to be run on its own", name)
}

return fmt.Errorf("invalid subcommand: %q", args[0])
}
}

// validateExactArgNumber validates that the required top-level arguments are specified
func validateExactArgNumber(args []string, supportedArgs []string) error {
validArgs := 0
// Disregard possible "" arguments; they are invalid
for _, arg := range args {
if len(arg) > 0 {
validArgs++
}
}

if validArgs < len(supportedArgs) {
return fmt.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs)
}
if validArgs > len(supportedArgs) {
return fmt.Errorf("too many arguments, only %d argument(s) supported: %v", validArgs, supportedArgs)
}
return nil
}
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/phases/preflight.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ import (
"github.com/spf13/cobra"

kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
)

func NewCmdPreFlight() *cobra.Command {
cmd := &cobra.Command{
Use: "preflight",
Short: "Run pre-flight checks",
RunE: subCmdRunE("preflight"),
RunE: cmdutil.SubCmdRunE("preflight"),
}

cmd.AddCommand(NewCmdPreFlightMaster())
Expand Down
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/phases/selfhosting.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
Expand All @@ -37,7 +38,7 @@ func NewCmdSelfhosting() *cobra.Command {
Use: "selfhosting",
Aliases: []string{"selfhosted"},
Short: "Make a kubeadm cluster self-hosted.",
RunE: subCmdRunE("selfhosting"),
RunE: cmdutil.SubCmdRunE("selfhosting"),
}

cmd.AddCommand(getSelfhostingSubCommand())
Expand Down
3 changes: 2 additions & 1 deletion cmd/kubeadm/app/cmd/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/fields"
clientset "k8s.io/client-go/kubernetes"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
Expand Down Expand Up @@ -77,7 +78,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
// cobra will print usage information, but still exit cleanly.
// We want to return an error code in these cases so that the
// user knows that their command was invalid.
RunE: subCmdRunE("token"),
RunE: cmdutil.SubCmdRunE("token"),
}

tokenCmd.PersistentFlags().StringVar(&kubeConfigFile,
Expand Down
55 changes: 55 additions & 0 deletions cmd/kubeadm/app/cmd/upgrade/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "go_default_library",
srcs = [
"apply.go",
"common.go",
"plan.go",
"upgrade.go",
],
visibility = ["//visibility:public"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
"//cmd/kubeadm/app/cmd/util:go_default_library",
"//cmd/kubeadm/app/phases/upgrade:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//pkg/api:go_default_library",
"//pkg/util/version:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
],
)

go_test(
name = "go_default_test",
srcs = [
"apply_test.go",
"common_test.go",
"plan_test.go",
],
library = ":go_default_library",
deps = [
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
"//cmd/kubeadm/app/phases/upgrade:go_default_library",
"//pkg/util/version:go_default_library",
],
)

filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)

filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
Loading

0 comments on commit 43c1b5f

Please sign in to comment.