Merge pull request #7 from fluxcd/components-select

Implement components selection
pull/8/head
Stefan Prodan 5 years ago committed by GitHub
commit 29cc8f8fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,6 +2,7 @@ package main
import ( import (
"context" "context"
"fmt"
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
@ -14,12 +15,17 @@ import (
var checkCmd = &cobra.Command{ var checkCmd = &cobra.Command{
Use: "check", Use: "check",
Short: "Check requirements", Short: "Check requirements and installation",
Long: ` Long: `
The check command will perform a series of checks to validate that The check command will perform a series of checks to validate that
the local environment is configured correctly.`, the local environment is configured correctly and if the installed components are healthy.`,
Example: ` check --pre`, Example: ` # Run pre-installation checks
RunE: runCheckCmd, check --pre
# Run installation checks
check
`,
RunE: runCheckCmd,
} }
var ( var (
@ -37,7 +43,7 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel() defer cancel()
logAction("starting verification") logAction("checking prerequisites")
checkFailed := false checkFailed := false
if !sshCheck() { if !sshCheck() {
checkFailed = true checkFailed = true
@ -51,18 +57,21 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
checkFailed = true checkFailed = true
} }
if !kubernetesCheck(">=1.14.0") {
checkFailed = true
}
if checkPre { if checkPre {
if checkFailed { if checkFailed {
os.Exit(1) os.Exit(1)
} }
logSuccess("all prerequisites checks passed") logSuccess("prerequisites checks passed")
return nil return nil
} }
if !kubernetesCheck(">=1.14.0") { if !componentsCheck() {
checkFailed = true checkFailed = true
} }
if checkFailed { if checkFailed {
os.Exit(1) os.Exit(1)
} }
@ -188,3 +197,19 @@ func kubernetesCheck(version string) bool {
logSuccess("kubernetes %s %s", v.String(), version) logSuccess("kubernetes %s %s", v.String(), version)
return true return true
} }
func componentsCheck() bool {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
for _, deployment := range components {
command := fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
namespace, deployment, timeout.String())
if output, err := utils.execCommand(ctx, ModeCapture, command); err != nil {
logFailure("%s: %s", deployment, strings.TrimSuffix(output, "\n"))
} else {
logSuccess("%s is healthy", deployment)
}
}
return true
}

@ -15,10 +15,18 @@ var installCmd = &cobra.Command{
Use: "install", Use: "install",
Short: "Install the toolkit components", Short: "Install the toolkit components",
Long: ` Long: `
The install command deploys the toolkit components The install command deploys the toolkit components in the specified namespace.
on the configured Kubernetes cluster in ~/.kube/config`, If a previous version is installed, then an in-place upgrade will be performed.`,
Example: ` install --version=master --namespace=gitops-systems`, Example: ` # Install the latest version in the gitops-systems namespace
RunE: installCmdRun, install --version=master --namespace=gitops-systems
# Dry-run install for a specific version and a series of components
install --dry-run --version=0.0.1 --components="source-controller,kustomize-controller"
# Dry-run install with manifests preview
install --dry-run --verbose
`,
RunE: installCmdRun,
} }
var ( var (
@ -57,7 +65,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
logAction("generating install manifests") logAction("generating install manifests")
if kustomizePath == "" { if kustomizePath == "" {
err = genInstallManifests(installVersion, namespace, tmpDir) err = genInstallManifests(installVersion, namespace, components, tmpDir)
if err != nil { if err != nil {
return fmt.Errorf("install failed: %w", err) return fmt.Errorf("install failed: %w", err)
} }
@ -103,7 +111,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
} }
logAction("verifying installation") logAction("verifying installation")
for _, deployment := range []string{"source-controller", "kustomize-controller"} { for _, deployment := range components {
command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s", command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
namespace, deployment, timeout.String()) namespace, deployment, timeout.String())
if _, err := utils.execCommand(ctx, applyOutput, command); err != nil { if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
@ -138,6 +146,7 @@ fieldSpecs:
` `
var kustomizationTmpl = `--- var kustomizationTmpl = `---
{{- $version := .Version }}
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
namespace: {{.Namespace}} namespace: {{.Namespace}}
@ -146,9 +155,10 @@ transformers:
resources: resources:
- namespace.yaml - namespace.yaml
- roles - roles
- github.com/fluxcd/toolkit/manifests/bases/source-controller?ref={{.Version}} - github.com/fluxcd/toolkit/manifests/policies?ref={{$version}}
- github.com/fluxcd/toolkit/manifests/bases/kustomize-controller?ref={{.Version}} {{- range .Components }}
- github.com/fluxcd/toolkit/manifests/policies?ref={{.Version}} - github.com/fluxcd/toolkit/manifests/bases/{{.}}?ref={{$version}}
{{- end }}
` `
var kustomizationRolesTmpl = `--- var kustomizationRolesTmpl = `---
@ -159,13 +169,15 @@ resources:
nameSuffix: -{{.Namespace}} nameSuffix: -{{.Namespace}}
` `
func genInstallManifests(ver, ns, tmpDir string) error { func genInstallManifests(version string, namespace string, components []string, tmpDir string) error {
model := struct { model := struct {
Version string Version string
Namespace string Namespace string
Components []string
}{ }{
Version: ver, Version: version,
Namespace: ns, Namespace: namespace,
Components: components,
} }
if err := utils.execTemplate(model, namespaceTmpl, path.Join(tmpDir, "namespace.yaml")); err != nil { if err := utils.execTemplate(model, namespaceTmpl, path.Join(tmpDir, "namespace.yaml")); err != nil {

@ -28,6 +28,7 @@ var (
namespace string namespace string
timeout time.Duration timeout time.Duration
verbose bool verbose bool
components []string
utils Utils utils Utils
) )
@ -38,6 +39,9 @@ func init() {
"timeout for this operation") "timeout for this operation")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false, rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false,
"print generated objects") "print generated objects")
rootCmd.PersistentFlags().StringSliceVar(&components, "components",
[]string{"source-controller", "kustomize-controller"},
"list of components, accepts comma-separated values")
} }
func main() { func main() {

@ -13,9 +13,14 @@ var uninstallCmd = &cobra.Command{
Short: "Uninstall the toolkit components", Short: "Uninstall the toolkit components",
Long: ` Long: `
The uninstall command removes the namespace, cluster roles, The uninstall command removes the namespace, cluster roles,
cluster role bindings and CRDs`, cluster role bindings and CRDs.`,
Example: ` uninstall --namespace=gitops-system --crds --dry-run`, Example: ` # Dry-run uninstall of all components
RunE: uninstallCmdRun, uninstall --dry-run --namespace=gitops-system
# Uninstall all components and custom resource definitions
uninstall --crds --namespace=gitops-system
`,
RunE: uninstallCmdRun,
} }
var ( var (

@ -49,10 +49,12 @@ func (*Utils) execCommand(ctx context.Context, mode ExecMode, command string) (s
} }
if mode == ModeCapture { if mode == ModeCapture {
if output, err := c.CombinedOutput(); err != nil { c.Stdout = &stdoutBuf
return "", err c.Stderr = &stderrBuf
if err := c.Run(); err != nil {
return stderrBuf.String(), err
} else { } else {
return string(output), nil return stdoutBuf.String(), nil
} }
} }

Loading…
Cancel
Save