mirror of
https://github.com/fluxcd/flux2.git
synced 2026-02-24 16:41:47 +00:00
Merge branch 'main' into patch-1
This commit is contained in:
commit
02fb8d9958
28 changed files with 611 additions and 199 deletions
26
.github/workflows/bootstrap.yaml
vendored
26
.github/workflows/bootstrap.yaml
vendored
|
|
@ -34,12 +34,18 @@ jobs:
|
||||||
go build -o /tmp/flux ./cmd/flux
|
go build -o /tmp/flux ./cmd/flux
|
||||||
- name: Set outputs
|
- name: Set outputs
|
||||||
id: vars
|
id: vars
|
||||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
run: |
|
||||||
|
REPOSITORY_NAME=${{ github.event.repository.name }}
|
||||||
|
BRANCH_NAME=${GITHUB_REF##*/}
|
||||||
|
COMMIT_SHA=$(git rev-parse HEAD)
|
||||||
|
PSEUDO_RAND_SUFFIX=$(echo "${BRANCH_NAME}-${COMMIT_SHA}" | shasum | awk '{print $1}')
|
||||||
|
TEST_REPO_NAME="${REPOSITORY_NAME}-${PSEUDO_RAND_SUFFIX}"
|
||||||
|
echo "::set-output name=test_repo_name::$TEST_REPO_NAME"
|
||||||
- name: bootstrap init
|
- name: bootstrap init
|
||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
||||||
--owner=fluxcd-testing \
|
--owner=fluxcd-testing \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
--repository=${{ steps.vars.outputs.test_repo_name }} \
|
||||||
--branch=main \
|
--branch=main \
|
||||||
--path=test-cluster
|
--path=test-cluster
|
||||||
env:
|
env:
|
||||||
|
|
@ -48,7 +54,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
||||||
--owner=fluxcd-testing \
|
--owner=fluxcd-testing \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
--repository=${{ steps.vars.outputs.test_repo_name }} \
|
||||||
--branch=main \
|
--branch=main \
|
||||||
--path=test-cluster
|
--path=test-cluster
|
||||||
env:
|
env:
|
||||||
|
|
@ -61,19 +67,19 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
||||||
--owner=fluxcd-testing \
|
--owner=fluxcd-testing \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
--repository=${{ steps.vars.outputs.test_repo_name }} \
|
||||||
--branch=main \
|
--branch=main \
|
||||||
--path=test-cluster
|
--path=test-cluster
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
||||||
- name: delete repository
|
- name: delete repository
|
||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
curl \
|
||||||
--owner=fluxcd-testing \
|
-X DELETE \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
--branch=main \
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
--path=test-cluster \
|
--fail --silent \
|
||||||
--delete
|
https://api.github.com/repos/fluxcd-testing/${{ steps.vars.outputs.test_repo_name }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
||||||
- name: Debug failure
|
- name: Debug failure
|
||||||
|
|
|
||||||
2
.github/workflows/update.yaml
vendored
2
.github/workflows/update.yaml
vendored
|
|
@ -30,7 +30,7 @@ jobs:
|
||||||
# bump kustomize
|
# bump kustomize
|
||||||
sed -i "s/\($1\/releases\/download\/\)v.*\(\/.*\)/\1${RELEASE_VERSION}\2/g" "manifests/bases/$1/kustomization.yaml"
|
sed -i "s/\($1\/releases\/download\/\)v.*\(\/.*\)/\1${RELEASE_VERSION}\2/g" "manifests/bases/$1/kustomization.yaml"
|
||||||
|
|
||||||
if [[ ! -z $(go list -m all | grep "github.com/fluxcd/$1/api" | awk '{print $2}') ]]; then
|
if [[ ! -z $(grep "github.com/fluxcd/$1/api" go.mod | awk '{print $2}') ]]; then
|
||||||
# bump go mod
|
# bump go mod
|
||||||
go mod edit -require="github.com/fluxcd/$1/api@${RELEASE_VERSION}"
|
go mod edit -require="github.com/fluxcd/$1/api@${RELEASE_VERSION}"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import (
|
||||||
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
||||||
kus "github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
|
kus "github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
|
||||||
"github.com/fluxcd/flux2/pkg/manifestgen/sync"
|
"github.com/fluxcd/flux2/pkg/manifestgen/sync"
|
||||||
|
"github.com/fluxcd/flux2/pkg/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bootstrapCmd = &cobra.Command{
|
var bootstrapCmd = &cobra.Command{
|
||||||
|
|
@ -176,19 +177,24 @@ func generateInstallManifests(targetPath, namespace, tmpDir string, localManifes
|
||||||
func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error {
|
func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error {
|
||||||
kubectlArgs := []string{"apply", "-f", manifestPath}
|
kubectlArgs := []string{"apply", "-f", manifestPath}
|
||||||
if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
statusChecker, err := NewStatusChecker(time.Second, rootArgs.timeout)
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
statusChecker, err := status.NewStatusChecker(kubeConfig, time.Second, rootArgs.timeout, logger)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
componentRefs, err := buildComponentObjectRefs(components...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("install failed: %w", err)
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Waitingf("verifying installation")
|
logger.Waitingf("verifying installation")
|
||||||
if err := statusChecker.Assess(components...); err != nil {
|
if err := statusChecker.Assess(componentRefs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,6 @@ type githubFlags struct {
|
||||||
hostname string
|
hostname string
|
||||||
path flags.SafeRelativePath
|
path flags.SafeRelativePath
|
||||||
teams []string
|
teams []string
|
||||||
delete bool
|
|
||||||
sshHostname string
|
sshHostname string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,9 +100,6 @@ func init() {
|
||||||
bootstrapGitHubCmd.Flags().StringVar(&githubArgs.sshHostname, "ssh-hostname", "", "GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one")
|
bootstrapGitHubCmd.Flags().StringVar(&githubArgs.sshHostname, "ssh-hostname", "", "GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one")
|
||||||
bootstrapGitHubCmd.Flags().Var(&githubArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path")
|
bootstrapGitHubCmd.Flags().Var(&githubArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path")
|
||||||
|
|
||||||
bootstrapGitHubCmd.Flags().BoolVar(&githubArgs.delete, "delete", false, "delete repository (used for testing only)")
|
|
||||||
bootstrapGitHubCmd.Flags().MarkHidden("delete")
|
|
||||||
|
|
||||||
bootstrapCmd.AddCommand(bootstrapGitHubCmd)
|
bootstrapCmd.AddCommand(bootstrapGitHubCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,14 +159,6 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
if githubArgs.delete {
|
|
||||||
if err := provider.DeleteRepository(ctx, repository); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("repository deleted")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// create GitHub repository if doesn't exists
|
// create GitHub repository if doesn't exists
|
||||||
logger.Actionf("connecting to %s", githubArgs.hostname)
|
logger.Actionf("connecting to %s", githubArgs.hostname)
|
||||||
changed, err := provider.CreateRepository(ctx, repository)
|
changed, err := provider.CreateRepository(ctx, repository)
|
||||||
|
|
@ -260,7 +248,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("git URL parse failed: %w", err)
|
return fmt.Errorf("git URL parse failed: %w", err)
|
||||||
}
|
}
|
||||||
secretOpts.SSHHostname = u.Hostname()
|
secretOpts.SSHHostname = u.Host
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
||||||
secretOpts.RSAKeyBits = 2048
|
secretOpts.RSAKeyBits = 2048
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("git URL parse failed: %w", err)
|
return fmt.Errorf("git URL parse failed: %w", err)
|
||||||
}
|
}
|
||||||
secretOpts.SSHHostname = u.Hostname()
|
secretOpts.SSHHostname = u.Host
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
||||||
secretOpts.RSAKeyBits = 2048
|
secretOpts.RSAKeyBits = 2048
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
||||||
|
"github.com/fluxcd/flux2/pkg/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkCmd = &cobra.Command{
|
var checkCmd = &cobra.Command{
|
||||||
|
|
@ -205,12 +206,17 @@ func componentsCheck() bool {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
statusChecker, err := NewStatusChecker(time.Second, rootArgs.timeout)
|
statusChecker, err := status.NewStatusChecker(kubeConfig, time.Second, rootArgs.timeout, logger)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -220,10 +226,10 @@ func componentsCheck() bool {
|
||||||
var list v1.DeploymentList
|
var list v1.DeploymentList
|
||||||
if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err == nil {
|
if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err == nil {
|
||||||
for _, d := range list.Items {
|
for _, d := range list.Items {
|
||||||
if err := statusChecker.Assess(d.Name); err != nil {
|
if ref, err := buildComponentObjectRefs(d.Name); err == nil {
|
||||||
ok = false
|
if err := statusChecker.Assess(ref...); err != nil {
|
||||||
} else {
|
ok = false
|
||||||
logger.Successf("%s: healthy", d.Name)
|
}
|
||||||
}
|
}
|
||||||
for _, c := range d.Spec.Template.Spec.Containers {
|
for _, c := range d.Spec.Template.Spec.Containers {
|
||||||
logger.Actionf(c.Image)
|
logger.Actionf(c.Image)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
opts.SSHHostname = u.Hostname()
|
opts.SSHHostname = u.Host
|
||||||
opts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(secretGitArgs.keyAlgorithm)
|
opts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(secretGitArgs.keyAlgorithm)
|
||||||
opts.RSAKeyBits = int(secretGitArgs.rsaBits)
|
opts.RSAKeyBits = int(secretGitArgs.rsaBits)
|
||||||
opts.ECDSACurve = secretGitArgs.ecdsaCurve.Curve
|
opts.ECDSACurve = secretGitArgs.ecdsaCurve.Curve
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
secretOpts.SSHHostname = u.Hostname()
|
secretOpts.SSHHostname = u.Host
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(sourceGitArgs.keyAlgorithm)
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(sourceGitArgs.keyAlgorithm)
|
||||||
secretOpts.RSAKeyBits = int(sourceGitArgs.keyRSABits)
|
secretOpts.RSAKeyBits = int(sourceGitArgs.keyRSABits)
|
||||||
secretOpts.ECDSACurve = sourceGitArgs.keyECDSACurve.Curve
|
secretOpts.ECDSACurve = sourceGitArgs.keyECDSACurve.Curve
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"github.com/fluxcd/flux2/internal/flags"
|
"github.com/fluxcd/flux2/internal/flags"
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
||||||
|
"github.com/fluxcd/flux2/pkg/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
var installCmd = &cobra.Command{
|
var installCmd = &cobra.Command{
|
||||||
|
|
@ -200,7 +201,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
applyOutput = utils.ModeOS
|
applyOutput = utils.ModeOS
|
||||||
}
|
}
|
||||||
if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if installArgs.dryRun {
|
if installArgs.dryRun {
|
||||||
|
|
@ -208,13 +209,20 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
statusChecker, err := NewStatusChecker(time.Second, time.Minute)
|
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
statusChecker, err := status.NewStatusChecker(kubeConfig, time.Second, rootArgs.timeout, logger)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
componentRefs, err := buildComponentObjectRefs(components...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("install failed: %w", err)
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Waitingf("verifying installation")
|
logger.Waitingf("verifying installation")
|
||||||
if err := statusChecker.Assess(components...); err != nil {
|
if err := statusChecker.Assess(componentRefs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
262
cmd/flux/logs.go
Normal file
262
cmd/flux/logs.go
Normal file
|
|
@ -0,0 +1,262 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/fluxcd/flux2/internal/flags"
|
||||||
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logsCmd = &cobra.Command{
|
||||||
|
Use: "logs",
|
||||||
|
Short: "Display formatted logs for toolkit components",
|
||||||
|
Long: "The logs command displays formatted logs from various toolkit components.",
|
||||||
|
Example: `# Get logs from toolkit components
|
||||||
|
flux logs
|
||||||
|
|
||||||
|
# Stream logs from toolkit components
|
||||||
|
flux logs --follow
|
||||||
|
|
||||||
|
# Get logs from toolkit components in a particular namespace
|
||||||
|
flux logs --flux-namespace my-namespace
|
||||||
|
|
||||||
|
# Get logs for a particular log level
|
||||||
|
flux logs --level=info
|
||||||
|
|
||||||
|
# Filter logs by kind, name, or namespace
|
||||||
|
flux logs --kind=kustomization --name podinfo --namespace default
|
||||||
|
`,
|
||||||
|
RunE: logsCmdRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
type logsFlags struct {
|
||||||
|
logLevel flags.LogLevel
|
||||||
|
follow bool
|
||||||
|
tail int64
|
||||||
|
kind string
|
||||||
|
name string
|
||||||
|
fluxNamespace string
|
||||||
|
allNamespaces bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var logsArgs = &logsFlags{
|
||||||
|
tail: -1,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
logsCmd.Flags().Var(&logsArgs.logLevel, "level", logsArgs.logLevel.Description())
|
||||||
|
logsCmd.Flags().StringVarP(&logsArgs.kind, "kind", "", logsArgs.kind, "displays errors of a particular toolkit kind e.g GitRepository")
|
||||||
|
logsCmd.Flags().StringVarP(&logsArgs.name, "name", "", logsArgs.name, "specifies the name of the object logs to be displayed")
|
||||||
|
logsCmd.Flags().BoolVarP(&logsArgs.follow, "follow", "f", logsArgs.follow, "Specifies if the logs should be streamed")
|
||||||
|
logsCmd.Flags().Int64VarP(&logsArgs.tail, "tail", "", logsArgs.tail, "lines of recent log file to display")
|
||||||
|
logsCmd.Flags().StringVarP(&logsArgs.fluxNamespace, "flux-namespace", "", rootArgs.defaults.Namespace, "the namespace where the Flux components are running.")
|
||||||
|
logsCmd.Flags().BoolVarP(&logsArgs.allNamespaces, "all-namespaces", "A", false, "displays logs for objects across all namespaces")
|
||||||
|
rootCmd.AddCommand(logsCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func logsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
|
fluxSelector := fmt.Sprintf("app.kubernetes.io/instance=%s", logsArgs.fluxNamespace)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var pods []corev1.Pod
|
||||||
|
cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
clientset, err := kubernetes.NewForConfig(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
return fmt.Errorf("no argument required")
|
||||||
|
}
|
||||||
|
|
||||||
|
pods, err = getPods(ctx, clientset, fluxSelector)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logOpts := &corev1.PodLogOptions{
|
||||||
|
Follow: logsArgs.follow,
|
||||||
|
}
|
||||||
|
|
||||||
|
if logsArgs.tail > -1 {
|
||||||
|
logOpts.TailLines = &logsArgs.tail
|
||||||
|
}
|
||||||
|
|
||||||
|
var requests []rest.ResponseWrapper
|
||||||
|
for _, pod := range pods {
|
||||||
|
req := clientset.CoreV1().Pods(logsArgs.fluxNamespace).GetLogs(pod.Name, logOpts)
|
||||||
|
requests = append(requests, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
if logsArgs.follow && len(requests) > 1 {
|
||||||
|
return parallelPodLogs(ctx, requests)
|
||||||
|
}
|
||||||
|
|
||||||
|
return podLogs(ctx, requests)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPods(ctx context.Context, c *kubernetes.Clientset, label string) ([]corev1.Pod, error) {
|
||||||
|
var ret []corev1.Pod
|
||||||
|
|
||||||
|
opts := metav1.ListOptions{
|
||||||
|
LabelSelector: label,
|
||||||
|
}
|
||||||
|
deployList, err := c.AppsV1().Deployments(logsArgs.fluxNamespace).List(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, deploy := range deployList.Items {
|
||||||
|
label := deploy.Spec.Template.Labels
|
||||||
|
opts := metav1.ListOptions{
|
||||||
|
LabelSelector: createLabelStringFromMap(label),
|
||||||
|
}
|
||||||
|
podList, err := c.CoreV1().Pods(logsArgs.fluxNamespace).List(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret = append(ret, podList.Items...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parallelPodLogs(ctx context.Context, requests []rest.ResponseWrapper) error {
|
||||||
|
reader, writer := io.Pipe()
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(len(requests))
|
||||||
|
|
||||||
|
var mutex = &sync.Mutex{}
|
||||||
|
|
||||||
|
for _, request := range requests {
|
||||||
|
go func(req rest.ResponseWrapper) {
|
||||||
|
defer wg.Done()
|
||||||
|
if err := logRequest(mutex, ctx, req, os.Stdout); err != nil {
|
||||||
|
writer.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
wg.Wait()
|
||||||
|
writer.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err := io.Copy(os.Stdout, reader)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func podLogs(ctx context.Context, requests []rest.ResponseWrapper) error {
|
||||||
|
mutex := &sync.Mutex{}
|
||||||
|
for _, req := range requests {
|
||||||
|
if err := logRequest(mutex, ctx, req, os.Stdout); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createLabelStringFromMap(m map[string]string) string {
|
||||||
|
var strArr []string
|
||||||
|
for key, val := range m {
|
||||||
|
pair := fmt.Sprintf("%v=%v", key, val)
|
||||||
|
strArr = append(strArr, pair)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(strArr, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func logRequest(mu *sync.Mutex, ctx context.Context, request rest.ResponseWrapper, w io.Writer) error {
|
||||||
|
stream, err := request.Stream(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer stream.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(stream)
|
||||||
|
|
||||||
|
const logTmpl = "{{.Timestamp}} {{.Level}} {{.Kind}}{{if .Name}}/{{.Name}}.{{.Namespace}}{{end}} - {{.Message}} {{.Error}}\n"
|
||||||
|
t, err := template.New("log").Parse(logTmpl)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create template, err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if !strings.HasPrefix(line, "{") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var l ControllerLogEntry
|
||||||
|
if err := json.Unmarshal([]byte(line), &l); err != nil {
|
||||||
|
logger.Failuref("parse error: %s", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
mu.Lock()
|
||||||
|
filterPrintLog(t, &l)
|
||||||
|
mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterPrintLog(t *template.Template, l *ControllerLogEntry) {
|
||||||
|
if logsArgs.logLevel != "" && logsArgs.logLevel != l.Level ||
|
||||||
|
logsArgs.kind != "" && strings.ToLower(logsArgs.kind) != strings.ToLower(l.Kind) ||
|
||||||
|
logsArgs.name != "" && strings.ToLower(logsArgs.name) != strings.ToLower(l.Name) ||
|
||||||
|
!logsArgs.allNamespaces && strings.ToLower(rootArgs.namespace) != strings.ToLower(l.Namespace) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := t.Execute(os.Stdout, l)
|
||||||
|
if err != nil {
|
||||||
|
logger.Failuref("log template error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ControllerLogEntry struct {
|
||||||
|
Timestamp string `json:"ts"`
|
||||||
|
Level flags.LogLevel `json:"level"`
|
||||||
|
Message string `json:"msg"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
Logger string `json:"logger"`
|
||||||
|
Kind string `json:"reconciler kind,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Namespace string `json:"namespace,omitempty"`
|
||||||
|
}
|
||||||
|
|
@ -19,26 +19,16 @@ package main
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
|
||||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/aggregator"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/object"
|
"sigs.k8s.io/cli-utils/pkg/object"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// statusable is used to see if a resource is considered ready in the usual way
|
// statusable is used to see if a resource is considered ready in the usual way
|
||||||
|
|
@ -51,13 +41,6 @@ type statusable interface {
|
||||||
GetStatusConditions() *[]metav1.Condition
|
GetStatusConditions() *[]metav1.Condition
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusChecker struct {
|
|
||||||
pollInterval time.Duration
|
|
||||||
timeout time.Duration
|
|
||||||
client client.Client
|
|
||||||
statusPoller *polling.StatusPoller
|
|
||||||
}
|
|
||||||
|
|
||||||
func isReady(ctx context.Context, kubeClient client.Client,
|
func isReady(ctx context.Context, kubeClient client.Client,
|
||||||
namespacedName types.NamespacedName, object statusable) wait.ConditionFunc {
|
namespacedName types.NamespacedName, object statusable) wait.ConditionFunc {
|
||||||
return func() (bool, error) {
|
return func() (bool, error) {
|
||||||
|
|
@ -83,74 +66,7 @@ func isReady(ctx context.Context, kubeClient client.Client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStatusChecker(pollInterval time.Duration, timeout time.Duration) (*StatusChecker, error) {
|
func buildComponentObjectRefs(components ...string) ([]object.ObjMetadata, error) {
|
||||||
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
restMapper, err := apiutil.NewDynamicRESTMapper(kubeConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
client, err := client.New(kubeConfig, client.Options{Mapper: restMapper})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &StatusChecker{
|
|
||||||
pollInterval: pollInterval,
|
|
||||||
timeout: timeout,
|
|
||||||
client: client,
|
|
||||||
statusPoller: polling.NewStatusPoller(client, restMapper),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *StatusChecker) Assess(components ...string) error {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
objRefs, err := sc.getObjectRefs(components)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := polling.Options{PollInterval: sc.pollInterval, UseCache: true}
|
|
||||||
eventsChan := sc.statusPoller.Poll(ctx, objRefs, opts)
|
|
||||||
|
|
||||||
coll := collector.NewResourceStatusCollector(objRefs)
|
|
||||||
done := coll.ListenWithObserver(eventsChan, collector.ObserverFunc(
|
|
||||||
func(statusCollector *collector.ResourceStatusCollector, e event.Event) {
|
|
||||||
var rss []*event.ResourceStatus
|
|
||||||
for _, rs := range statusCollector.ResourceStatuses {
|
|
||||||
rss = append(rss, rs)
|
|
||||||
}
|
|
||||||
desired := status.CurrentStatus
|
|
||||||
aggStatus := aggregator.AggregateStatus(rss, desired)
|
|
||||||
if aggStatus == desired {
|
|
||||||
cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
<-done
|
|
||||||
|
|
||||||
if coll.Error != nil || ctx.Err() == context.DeadlineExceeded {
|
|
||||||
for _, rs := range coll.ResourceStatuses {
|
|
||||||
if rs.Status != status.CurrentStatus {
|
|
||||||
if !sc.deploymentExists(rs.Identifier) {
|
|
||||||
logger.Failuref("%s: deployment not found", rs.Identifier.Name)
|
|
||||||
} else {
|
|
||||||
logger.Failuref("%s: unhealthy (timed out waiting for rollout)", rs.Identifier.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("timed out waiting for condition")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *StatusChecker) getObjectRefs(components []string) ([]object.ObjMetadata, error) {
|
|
||||||
var objRefs []object.ObjMetadata
|
var objRefs []object.ObjMetadata
|
||||||
for _, deployment := range components {
|
for _, deployment := range components {
|
||||||
objMeta, err := object.CreateObjMetadata(rootArgs.namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"})
|
objMeta, err := object.CreateObjMetadata(rootArgs.namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"})
|
||||||
|
|
@ -161,20 +77,3 @@ func (sc *StatusChecker) getObjectRefs(components []string) ([]object.ObjMetadat
|
||||||
}
|
}
|
||||||
return objRefs, nil
|
return objRefs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *StatusChecker) objMetadataToString(om object.ObjMetadata) string {
|
|
||||||
return fmt.Sprintf("%s '%s/%s'", om.GroupKind.Kind, om.Namespace, om.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *StatusChecker) deploymentExists(om object.ObjMetadata) bool {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
namespacedName := types.NamespacedName{
|
|
||||||
Namespace: om.Namespace,
|
|
||||||
Name: om.Name,
|
|
||||||
}
|
|
||||||
var existing appsv1.Deployment
|
|
||||||
err := sc.client.Get(ctx, namespacedName, &existing)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
25
docs/_static/custom.css
vendored
25
docs/_static/custom.css
vendored
|
|
@ -95,3 +95,28 @@ body {
|
||||||
.progress-0plus .progress-bar {
|
.progress-0plus .progress-bar {
|
||||||
background-color: #ff1744;
|
background-color: #ff1744;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Custom admonitions */
|
||||||
|
/* See https://squidfunk.github.io/mkdocs-material/reference/admonitions */
|
||||||
|
:root {
|
||||||
|
--md-admonition-icon--heart: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 20.408c-.492.308-.903.546-1.192.709-.153.086-.308.17-.463.252h-.002a.75.75 0 0 1-.686 0 16.709 16.709 0 0 1-.465-.252 31.147 31.147 0 0 1-4.803-3.34C3.8 15.572 1 12.331 1 8.513 1 5.052 3.829 2.5 6.736 2.5 9.03 2.5 10.881 3.726 12 5.605 13.12 3.726 14.97 2.5 17.264 2.5 20.17 2.5 23 5.052 23 8.514c0 3.818-2.801 7.06-5.389 9.262A31.146 31.146 0 0 1 14 20.408z"/></svg>')
|
||||||
|
}
|
||||||
|
.md-typeset .admonition.heart,
|
||||||
|
.md-typeset details.heart {
|
||||||
|
border-color: rgb(233, 30, 99);
|
||||||
|
}
|
||||||
|
.md-typeset .heart > .admonition-title,
|
||||||
|
.md-typeset .heart > summary {
|
||||||
|
background-color: rgba(233, 30, 99, 0.1);
|
||||||
|
}
|
||||||
|
.md-typeset .heart > .admonition-title::before,
|
||||||
|
.md-typeset .heart > summary::before {
|
||||||
|
background-color: rgb(233, 30, 99);
|
||||||
|
-webkit-mask-image: var(--md-admonition-icon--heart);
|
||||||
|
mask-image: var(--md-admonition-icon--heart);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timetable-explicit-col-widths th:nth-child(1) { width: 4%; }
|
||||||
|
.timetable-explicit-col-widths th:nth-child(2) { width: 32%; }
|
||||||
|
.timetable-explicit-col-widths th:nth-child(3) { width: 32%; }
|
||||||
|
.timetable-explicit-col-widths th:nth-child(4) { width: 32%; }
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
|
||||||
* [flux export](flux_export.md) - Export resources in YAML format
|
* [flux export](flux_export.md) - Export resources in YAML format
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get sources and resources
|
||||||
* [flux install](flux_install.md) - Install or upgrade Flux
|
* [flux install](flux_install.md) - Install or upgrade Flux
|
||||||
|
* [flux logs](flux_logs.md) - Display formatted logs for toolkit components
|
||||||
* [flux reconcile](flux_reconcile.md) - Reconcile sources and resources
|
* [flux reconcile](flux_reconcile.md) - Reconcile sources and resources
|
||||||
* [flux resume](flux_resume.md) - Resume suspended resources
|
* [flux resume](flux_resume.md) - Resume suspended resources
|
||||||
* [flux suspend](flux_suspend.md) - Suspend resources
|
* [flux suspend](flux_suspend.md) - Suspend resources
|
||||||
|
|
|
||||||
59
docs/cmd/flux_logs.md
Normal file
59
docs/cmd/flux_logs.md
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
## flux logs
|
||||||
|
|
||||||
|
Display formatted logs for toolkit components
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
The logs command displays formatted logs from various toolkit components.
|
||||||
|
|
||||||
|
```
|
||||||
|
flux logs [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
# Get logs from toolkit components
|
||||||
|
flux logs
|
||||||
|
|
||||||
|
# Stream logs from toolkit components
|
||||||
|
flux logs --follow
|
||||||
|
|
||||||
|
# Get logs from toolkit components in a particular namespace
|
||||||
|
flux logs --flux-namespace my-namespace
|
||||||
|
|
||||||
|
# Get logs for a particular log level
|
||||||
|
flux logs --level=info
|
||||||
|
|
||||||
|
# Filter logs by kind, name, or namespace
|
||||||
|
flux logs --kind=kustomization --name podinfo --namespace default
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-A, --all-namespaces displays logs for objects across all namespaces
|
||||||
|
--flux-namespace string the namespace where the Flux components are running. (default "flux-system")
|
||||||
|
-f, --follow Specifies if the logs should be streamed
|
||||||
|
-h, --help help for logs
|
||||||
|
--kind string displays errors of a particular toolkit kind e.g GitRepository
|
||||||
|
--level logLevel log level, available options are: (debug, info, error)
|
||||||
|
--name string specifies the name of the object logs to be displayed
|
||||||
|
--tail int lines of recent log file to display (default -1)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options inherited from parent commands
|
||||||
|
|
||||||
|
```
|
||||||
|
--context string kubernetes context to use
|
||||||
|
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||||
|
-n, --namespace string the namespace scope for this operation (default "flux-system")
|
||||||
|
--timeout duration timeout for this operation (default 5m0s)
|
||||||
|
--verbose print generated objects
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [flux](flux.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||||
|
|
||||||
|
|
@ -431,8 +431,8 @@ spec:
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! hint
|
!!! hint
|
||||||
If you are using the same image repository in several manifests, you only need one
|
If you are using the same image repository in several manifests, you only need one
|
||||||
`ImageRepository` object for it.
|
`ImageRepository` object for it.
|
||||||
|
|
||||||
##### Using image registry credentials for scanning
|
##### Using image registry credentials for scanning
|
||||||
|
|
||||||
|
|
|
||||||
38
docs/migration/timetable.md
Normal file
38
docs/migration/timetable.md
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
hide:
|
||||||
|
# The table data on this page is easier to read when wider
|
||||||
|
# The TOC right column is already blank anyway
|
||||||
|
- toc
|
||||||
|
---
|
||||||
|
# Migration and Support Timetable
|
||||||
|
|
||||||
|
!!! heart "Flux Migration Commitment"
|
||||||
|
This public timetable clarifies our commitment to end users.
|
||||||
|
Its purpose is to help improve your experience in deciding how and when to plan infra decisions related to Flux versions.
|
||||||
|
Please refer to the [Roadmap](../roadmap/index.md) for additional details.
|
||||||
|
|
||||||
|
<!-- Note: this div allows us to set fixed column widths in custom.css -->
|
||||||
|
<!-- See: https://github.com/squidfunk/mkdocs-material/issues/118 -->
|
||||||
|
<div markdown="1" class="timetable-explicit-col-widths">
|
||||||
|
|
||||||
|
<!-- Requires mkdocs markdown_extensions footnotes and pymdownx.caret -->
|
||||||
|
<!-- markdownlint-disable-file MD033 -->
|
||||||
|
| Date | Flux 1 | Flux 2 CLI | GOTK[^1] |
|
||||||
|
| -- | -- | -- | -- |
|
||||||
|
| Oct 6, 2020 | ^^[Maintenance Mode](https://github.com/fluxcd/website/pull/25)^^<br><ul><li>Flux 1 releases only include critical bug fixes (which don’t require changing Flux 1 architecture), and security patches (for OS packages, Go runtime, and kubectl). No new features</li><li>Existing projects encouraged to test migration to Flux 2 pre-releases in non-production</li></ul> | ^^Development Mode^^<br><ul><li>Working to finish parity with Flux 1</li><li>New projects encouraged to test Flux 2 pre-releases in non-production</li></ul> | ^^All Alpha^^[^2] |
|
||||||
|
Feb 18, 2021 | ^^Partial Migration Mode^^<br><ul><li>Existing projects encouraged to migrate to `v1beta1`/`v2beta1` if you only use those features (Flux 1 read-only mode, and Helm Operator)</li><li>Existing projects encouraged to test image automation Alpha in non-production</li></ul> | ^^Feature Parity^^ | ^^Image Automation Alpha. All others reached Feature Parity, Beta^^ |
|
||||||
|
| TBD | ^^Superseded^^<br><ul><li>All existing projects encouraged to [migrate to Flux 2](https://toolkit.fluxcd.io/guides/flux-v1-migration/), and [report any bugs](https://github.com/fluxcd/flux2/issues/new/choose)</li><li>Flux 1 Helm Operator archived – no further updates due to unsupported dependencies</li></ul> | ^^Needs further testing, may get breaking changes^^<br><ul><li>CLI needs further user testing during this migration period</li></ul> | ^^All Beta, Production Ready^^[^3]<br><ul><li>All Flux 1 features stable and supported in Flux 2</li><li>Promoting Alpha versions to Beta makes this Production Ready</li></ul> |
|
||||||
|
| TBD | ^^Migration and security support only^^<br><ul><li>Flux 1 releases only include security patches (no bug fixes)</li><li>Maintainers support users with migration to Flux 2 only, no longer with Flux 1 issues</li><li>Flux 1 archive date announced</li></ul> | ^^Public release (GA), Production Ready^^<br><ul><li>CLI commits to backwards compatibility moving forward</li><li>CLI follows kubectl style backwards compatibility support: +1 -1 MINOR version for server components (e.g., APIs, Controllers, validation webhooks)</li></ul> | ^^All Beta, Production Ready^^ |
|
||||||
|
| TBD | ^^Archived^^<br><ul><li>Flux 1 obsolete, no further releases or maintainer support</li><li>Flux 1 repo archived</li></ul> | ^^Continued active development^^ | ^^Continued active development^^ |
|
||||||
|
|
||||||
|
<!-- end .timetable-explicit-col-widths -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
[^1]: GOTK is shorthand for the [GitOps Toolkit](https://toolkit.fluxcd.io/components/) APIs and Controllers
|
||||||
|
|
||||||
|
[^2]: Versioning: Flux 2 is a multi-service architecture, so requires a more complex explanation than Flux 1:
|
||||||
|
- Flux 2 CLI follows [Semantic Versioning](https://semver.org/) scheme
|
||||||
|
- The GitOps Toolkit APIs follow the [Kubernetes API versioning](https://kubernetes.io/docs/reference/using-api/#api-versioning) pattern. See [Roadmap](https://toolkit.fluxcd.io/roadmap/) for component versions.
|
||||||
|
- These are coordinated for cross-compatibility: For each Flux 2 CLI tag, CLI and GOTK versions are end-to-end tested together, so you may safely upgrade from one MINOR/PATCH version to another.
|
||||||
|
|
||||||
|
[^3]: The GOTK Custom Resource Definitions which are at `v1beta1` and `v2beta1` and their controllers are considered stable and production ready. Going forward, breaking changes to the beta CRDs will be accompanied by a conversion mechanism.
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
The Flux custom resource definitions which are at `v1beta1` and `v2beta1`
|
The Flux custom resource definitions which are at `v1beta1` and `v2beta1`
|
||||||
and their controllers are considered stable and production ready.
|
and their controllers are considered stable and production ready.
|
||||||
Going forward, breaking changes to the beta CRDs will be accompanied by a conversion mechanism.
|
Going forward, breaking changes to the beta CRDs will be accompanied by a conversion mechanism.
|
||||||
|
Please see the [Migration and Suport Timetable](../migration/timetable.md) for our commitment to end users.
|
||||||
|
|
||||||
The following components (included by default in [flux bootstrap](../guides/installation.md#bootstrap))
|
The following components (included by default in [flux bootstrap](../guides/installation.md#bootstrap))
|
||||||
are considered production ready:
|
are considered production ready:
|
||||||
|
|
|
||||||
16
go.mod
16
go.mod
|
|
@ -5,18 +5,18 @@ go 1.16
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/semver/v3 v3.1.0
|
github.com/Masterminds/semver/v3 v3.1.0
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2
|
github.com/cyphar/filepath-securejoin v0.2.2
|
||||||
github.com/fluxcd/helm-controller/api v0.8.1
|
github.com/fluxcd/helm-controller/api v0.8.2
|
||||||
github.com/fluxcd/image-automation-controller/api v0.6.1
|
github.com/fluxcd/image-automation-controller/api v0.7.0
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.7.0
|
github.com/fluxcd/image-reflector-controller/api v0.7.1
|
||||||
github.com/fluxcd/kustomize-controller/api v0.9.1
|
github.com/fluxcd/kustomize-controller/api v0.9.3
|
||||||
github.com/fluxcd/notification-controller/api v0.9.0
|
github.com/fluxcd/notification-controller/api v0.10.0
|
||||||
github.com/fluxcd/pkg/apis/meta v0.8.0
|
github.com/fluxcd/pkg/apis/meta v0.8.0
|
||||||
github.com/fluxcd/pkg/git v0.3.0
|
github.com/fluxcd/pkg/git v0.3.0
|
||||||
github.com/fluxcd/pkg/runtime v0.8.3
|
github.com/fluxcd/pkg/runtime v0.8.5
|
||||||
github.com/fluxcd/pkg/ssh v0.0.5
|
github.com/fluxcd/pkg/ssh v0.0.5
|
||||||
github.com/fluxcd/pkg/untar v0.0.5
|
github.com/fluxcd/pkg/untar v0.0.5
|
||||||
github.com/fluxcd/pkg/version v0.0.1
|
github.com/fluxcd/pkg/version v0.0.1
|
||||||
github.com/fluxcd/source-controller/api v0.9.0
|
github.com/fluxcd/source-controller/api v0.9.1
|
||||||
github.com/google/go-containerregistry v0.2.0
|
github.com/google/go-containerregistry v0.2.0
|
||||||
github.com/manifoldco/promptui v0.7.0
|
github.com/manifoldco/promptui v0.7.0
|
||||||
github.com/olekukonko/tablewriter v0.0.4
|
github.com/olekukonko/tablewriter v0.0.4
|
||||||
|
|
@ -29,7 +29,7 @@ require (
|
||||||
k8s.io/cli-runtime v0.20.2 // indirect
|
k8s.io/cli-runtime v0.20.2 // indirect
|
||||||
k8s.io/client-go v0.20.2
|
k8s.io/client-go v0.20.2
|
||||||
sigs.k8s.io/cli-utils v0.22.2
|
sigs.k8s.io/cli-utils v0.22.2
|
||||||
sigs.k8s.io/controller-runtime v0.8.2
|
sigs.k8s.io/controller-runtime v0.8.3
|
||||||
sigs.k8s.io/kustomize/api v0.7.4
|
sigs.k8s.io/kustomize/api v0.7.4
|
||||||
sigs.k8s.io/yaml v1.2.0
|
sigs.k8s.io/yaml v1.2.0
|
||||||
)
|
)
|
||||||
|
|
|
||||||
34
go.sum
34
go.sum
|
|
@ -188,33 +188,33 @@ github.com/evanphx/json-patch/v5 v5.1.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fluxcd/helm-controller/api v0.8.1 h1:AEmw/xaRi2y9lD6TB+2w1Govj7OhD5oxoDx6HGty1yM=
|
github.com/fluxcd/helm-controller/api v0.8.2 h1:ELSC6dal01jtzn8B6ffArNklbul9/k9lpEd6msefVAE=
|
||||||
github.com/fluxcd/helm-controller/api v0.8.1/go.mod h1:cFceNc/mOBa+Qi3NE8NDY2w3FAEectauTm8c10mcBis=
|
github.com/fluxcd/helm-controller/api v0.8.2/go.mod h1:WDVuo3g6n3eZy8l5U/Zqo0aL+LcFV1C/HoNAUzWLtzU=
|
||||||
github.com/fluxcd/image-automation-controller/api v0.6.1 h1:LgjjNYXrVojfgjit37GA0SDYre3AaDabYzT7L6lWO7I=
|
github.com/fluxcd/image-automation-controller/api v0.7.0 h1:mLaELYT52/FpZ93Mr+QMSK8UT0OBVQT4oA9kxO8NiEk=
|
||||||
github.com/fluxcd/image-automation-controller/api v0.6.1/go.mod h1:8Q/baOONPrSJFMq7+zxp/t2WGrqVFRUx4HnTrg37pNE=
|
github.com/fluxcd/image-automation-controller/api v0.7.0/go.mod h1:7E2dCvoxmTkDttp+Hk8v9eoSK/CdFmFhRKInEXC3yVY=
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.7.0 h1:Mlu9ybrL+MtWcaIex4+FOcYuk+0vA/7bYj8MxVvLR1A=
|
github.com/fluxcd/image-reflector-controller/api v0.7.1 h1:Cng36D1J25WYZ0ZB6dwzDtGR9MIyIcSUMYxHpb0IYXA=
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.7.0/go.mod h1:KHWknF2xu/GZ4uLSQcAmfONZYjsbwNqyk3OvMQTmMsA=
|
github.com/fluxcd/image-reflector-controller/api v0.7.1/go.mod h1:J18L71jiHYrAu2dg0tgOkOjP+GtQldC1oslhTeX0jqc=
|
||||||
github.com/fluxcd/kustomize-controller/api v0.9.1 h1:o6cxtLiXUdEeTJMxoeoLdld7hsgf7L4mNO6+i2MD2U8=
|
github.com/fluxcd/kustomize-controller/api v0.9.3 h1:VbeU97pmx3vmgverqZIRyyBm1IKyPBZZAIo7mc3fZ+8=
|
||||||
github.com/fluxcd/kustomize-controller/api v0.9.1/go.mod h1:VhUwaSsgrXVgO8Qcx6ZO0isqb5TpDgbyyitCeXYqSM4=
|
github.com/fluxcd/kustomize-controller/api v0.9.3/go.mod h1:MDTwohIXqbId3qbhVNF7lAYLSBMzxq5MHINFN4bqDRs=
|
||||||
github.com/fluxcd/notification-controller/api v0.9.0 h1:aEIZu01EHlDH7I8/TyOkvMknlDV8NBNhuZ9cMQ8Kp0Q=
|
github.com/fluxcd/notification-controller/api v0.10.0 h1:7mxeBPnFzpL4Z+X5YiytQRzaDKrryb6TIQkC9ASJO28=
|
||||||
github.com/fluxcd/notification-controller/api v0.9.0/go.mod h1:nJqSGiecNkJLxuO2KWMu5YUTLaYT/A57854FMm4oX9Q=
|
github.com/fluxcd/notification-controller/api v0.10.0/go.mod h1:CA02ixmq+kFN9eBkruvJClkMqffgRjYBMxym3AfhO6c=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v0.0.1 h1:TkA80R0GopRY27VJqzKyS6ifiKIAfwBd7OHXtV3t2CI=
|
github.com/fluxcd/pkg/apis/kustomize v0.0.1 h1:TkA80R0GopRY27VJqzKyS6ifiKIAfwBd7OHXtV3t2CI=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v0.0.1/go.mod h1:JAFPfnRmcrAoG1gNiA8kmEXsnOBuDyZ/F5X4DAQcVV0=
|
github.com/fluxcd/pkg/apis/kustomize v0.0.1/go.mod h1:JAFPfnRmcrAoG1gNiA8kmEXsnOBuDyZ/F5X4DAQcVV0=
|
||||||
github.com/fluxcd/pkg/apis/meta v0.7.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
|
||||||
github.com/fluxcd/pkg/apis/meta v0.8.0 h1:wqWpUsxhKHB1ZztcvOz+vnyhdKW9cWmjFp8Vci/XOdk=
|
github.com/fluxcd/pkg/apis/meta v0.8.0 h1:wqWpUsxhKHB1ZztcvOz+vnyhdKW9cWmjFp8Vci/XOdk=
|
||||||
github.com/fluxcd/pkg/apis/meta v0.8.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
github.com/fluxcd/pkg/apis/meta v0.8.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
||||||
github.com/fluxcd/pkg/git v0.3.0 h1:nrKZWZ/ymDevud3Wf1LEieO/QcNPnqz1/MrkZBFcg9o=
|
github.com/fluxcd/pkg/git v0.3.0 h1:nrKZWZ/ymDevud3Wf1LEieO/QcNPnqz1/MrkZBFcg9o=
|
||||||
github.com/fluxcd/pkg/git v0.3.0/go.mod h1:ZwG0iLOqNSyNw6lsPIAO+v6+BqqCXyV+r1Oq6Lm+slg=
|
github.com/fluxcd/pkg/git v0.3.0/go.mod h1:ZwG0iLOqNSyNw6lsPIAO+v6+BqqCXyV+r1Oq6Lm+slg=
|
||||||
github.com/fluxcd/pkg/runtime v0.8.3 h1:Zjk4fyAfBdBQ4GTokjisab7KyHHczCqKSpJi8+oVrNw=
|
github.com/fluxcd/pkg/runtime v0.8.4/go.mod h1:JD0eZIn5xkTeHHQUWXSqJPIh/ecO0d0qrUKbSVHnpnw=
|
||||||
github.com/fluxcd/pkg/runtime v0.8.3/go.mod h1:AM/hMD0mKtRqhKPU7NGDzm+3UXPpdnX8oBlcxLt11AY=
|
github.com/fluxcd/pkg/runtime v0.8.5 h1:ynh8fszbLQ3QSisQBNOABEUTnvt+/QfCdaL6gOJQcoQ=
|
||||||
|
github.com/fluxcd/pkg/runtime v0.8.5/go.mod h1:JD0eZIn5xkTeHHQUWXSqJPIh/ecO0d0qrUKbSVHnpnw=
|
||||||
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
|
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
|
||||||
github.com/fluxcd/pkg/ssh v0.0.5/go.mod h1:7jXPdXZpc0ttMNz2kD9QuMi3RNn/e0DOFbj0Tij/+Hs=
|
github.com/fluxcd/pkg/ssh v0.0.5/go.mod h1:7jXPdXZpc0ttMNz2kD9QuMi3RNn/e0DOFbj0Tij/+Hs=
|
||||||
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
|
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
|
||||||
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
|
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
|
||||||
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
|
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
|
||||||
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
|
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
|
||||||
github.com/fluxcd/source-controller/api v0.9.0 h1:ohV8AvmvkUK0N7+YKPIOlMSLaNG0SpFcNLtlmW18xuM=
|
github.com/fluxcd/source-controller/api v0.9.1 h1:kaL+tBflccsuj3NDESPPQyKXlZXlAgyNoT2nYY02JAE=
|
||||||
github.com/fluxcd/source-controller/api v0.9.0/go.mod h1:68+cPuz1G45f0SDRwEfTL419011ffveLIDA9nssLlkU=
|
github.com/fluxcd/source-controller/api v0.9.1/go.mod h1:Vuw+7UqEUUOdkKBfTUPHwaQgbn6LL2FwqPDx2UAk7NE=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
|
|
@ -1205,8 +1205,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyz
|
||||||
sigs.k8s.io/cli-utils v0.22.2 h1:xPD02b++uK990/dAg/rM0LKDOb2sTWZPI1v8IZPfCn0=
|
sigs.k8s.io/cli-utils v0.22.2 h1:xPD02b++uK990/dAg/rM0LKDOb2sTWZPI1v8IZPfCn0=
|
||||||
sigs.k8s.io/cli-utils v0.22.2/go.mod h1:unl8itcwGPqo41QSyksbXTWFbfMqap1o/4oiUxPnQfw=
|
sigs.k8s.io/cli-utils v0.22.2/go.mod h1:unl8itcwGPqo41QSyksbXTWFbfMqap1o/4oiUxPnQfw=
|
||||||
sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
|
sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
|
||||||
sigs.k8s.io/controller-runtime v0.8.2 h1:SBWmI0b3uzMIUD/BIXWNegrCeZmPJ503pOtwxY0LPHM=
|
sigs.k8s.io/controller-runtime v0.8.3 h1:GMHvzjTmaWHQB8HadW+dIvBoJuLvZObYJ5YoZruPRao=
|
||||||
sigs.k8s.io/controller-runtime v0.8.2/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
|
sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
|
||||||
sigs.k8s.io/kind v0.9.0/go.mod h1:cxKQWwmbtRDzQ+RNKnR6gZG6fjbeTtItp5cGf+ww+1Y=
|
sigs.k8s.io/kind v0.9.0/go.mod h1:cxKQWwmbtRDzQ+RNKnR6gZG6fjbeTtItp5cGf+ww+1Y=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.1/helm-controller.crds.yaml
|
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.2/helm-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.1/helm-controller.deployment.yaml
|
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.2/helm-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.6.1/image-automation-controller.crds.yaml
|
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.7.0/image-automation-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.6.1/image-automation-controller.deployment.yaml
|
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.7.0/image-automation-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.0/image-reflector-controller.crds.yaml
|
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.1/image-reflector-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.0/image-reflector-controller.deployment.yaml
|
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.1/image-reflector-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.2/kustomize-controller.crds.yaml
|
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.3/kustomize-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.2/kustomize-controller.deployment.yaml
|
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.3/kustomize-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/notification-controller/releases/download/v0.9.0/notification-controller.crds.yaml
|
- https://github.com/fluxcd/notification-controller/releases/download/v0.10.0/notification-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/notification-controller/releases/download/v0.9.0/notification-controller.deployment.yaml
|
- https://github.com/fluxcd/notification-controller/releases/download/v0.10.0/notification-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v0.9.0/source-controller.crds.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v0.9.1/source-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v0.9.0/source-controller.deployment.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v0.9.1/source-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|
|
||||||
30
mkdocs.yml
30
mkdocs.yml
|
|
@ -26,31 +26,34 @@ plugins:
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- admonition
|
- admonition
|
||||||
- meta
|
|
||||||
- codehilite:
|
- codehilite:
|
||||||
guess_lang: false
|
guess_lang: false
|
||||||
- toc:
|
- footnotes
|
||||||
permalink: true
|
- meta
|
||||||
|
- pymdownx.caret
|
||||||
|
- pymdownx.emoji:
|
||||||
|
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||||
|
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||||
|
- pymdownx.extra
|
||||||
|
- pymdownx.progressbar
|
||||||
- pymdownx.superfences:
|
- pymdownx.superfences:
|
||||||
highlight_code: true
|
highlight_code: true
|
||||||
- pymdownx.tabbed
|
- pymdownx.tabbed
|
||||||
- pymdownx.tilde
|
|
||||||
- pymdownx.progressbar
|
|
||||||
- pymdownx.tasklist
|
- pymdownx.tasklist
|
||||||
- pymdownx.superfences
|
- pymdownx.tilde
|
||||||
- pymdownx.emoji:
|
- toc:
|
||||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
permalink: true
|
||||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
- Introduction: index.md
|
- Introduction: index.md
|
||||||
- Core Concepts: core-concepts/index.md
|
- Core Concepts: core-concepts/index.md
|
||||||
- Get Started: get-started/index.md
|
- Get Started: get-started/index.md
|
||||||
- Migration:
|
- Migration:
|
||||||
- Migrate from Flux v1: guides/flux-v1-migration.md
|
- Migration and Support Timetable: migration/timetable.md
|
||||||
- Migrate from Flux v1 image update automation: guides/flux-v1-automation-migration.md
|
- Migrate from Flux v1: guides/flux-v1-migration.md
|
||||||
- Migrate from the Helm Operator: guides/helm-operator-migration.md
|
- Migrate from Flux v1 image update automation: guides/flux-v1-automation-migration.md
|
||||||
- FAQ: guides/faq-migration.md
|
- Migrate from the Helm Operator: guides/helm-operator-migration.md
|
||||||
|
- FAQ: guides/faq-migration.md
|
||||||
- Guides:
|
- Guides:
|
||||||
- Installation: guides/installation.md
|
- Installation: guides/installation.md
|
||||||
- Manage Helm Releases: guides/helmreleases.md
|
- Manage Helm Releases: guides/helmreleases.md
|
||||||
|
|
@ -158,6 +161,7 @@ nav:
|
||||||
- Get images repository: cmd/flux_get_images_repository.md
|
- Get images repository: cmd/flux_get_images_repository.md
|
||||||
- Get images update: cmd/flux_get_images_update.md
|
- Get images update: cmd/flux_get_images_update.md
|
||||||
- Install: cmd/flux_install.md
|
- Install: cmd/flux_install.md
|
||||||
|
- Logs: cmd/flux_logs.md
|
||||||
- Resume: cmd/flux_resume.md
|
- Resume: cmd/flux_resume.md
|
||||||
- Resume kustomization: cmd/flux_resume_kustomization.md
|
- Resume kustomization: cmd/flux_resume_kustomization.md
|
||||||
- Resume helmrelease: cmd/flux_resume_helmrelease.md
|
- Resume helmrelease: cmd/flux_resume_helmrelease.md
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type Logger interface {
|
||||||
Generatef(format string, a ...interface{})
|
Generatef(format string, a ...interface{})
|
||||||
// Waitingf logs a formatted waiting message.
|
// Waitingf logs a formatted waiting message.
|
||||||
Waitingf(format string, a ...interface{})
|
Waitingf(format string, a ...interface{})
|
||||||
// Waitingf logs a formatted success message.
|
// Successf logs a formatted success message.
|
||||||
Successf(format string, a ...interface{})
|
Successf(format string, a ...interface{})
|
||||||
// Failuref logs a formatted failure message.
|
// Failuref logs a formatted failure message.
|
||||||
Failuref(format string, a ...interface{})
|
Failuref(format string, a ...interface{})
|
||||||
|
|
|
||||||
109
pkg/status/status.go
Normal file
109
pkg/status/status.go
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020, 2021 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package status
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/aggregator"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/object"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||||
|
|
||||||
|
"github.com/fluxcd/flux2/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusChecker struct {
|
||||||
|
pollInterval time.Duration
|
||||||
|
timeout time.Duration
|
||||||
|
client client.Client
|
||||||
|
statusPoller *polling.StatusPoller
|
||||||
|
logger log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStatusChecker(kubeConfig *rest.Config, pollInterval time.Duration, timeout time.Duration, log log.Logger) (*StatusChecker, error) {
|
||||||
|
restMapper, err := apiutil.NewDynamicRESTMapper(kubeConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c, err := client.New(kubeConfig, client.Options{Mapper: restMapper})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &StatusChecker{
|
||||||
|
pollInterval: pollInterval,
|
||||||
|
timeout: timeout,
|
||||||
|
client: c,
|
||||||
|
statusPoller: polling.NewStatusPoller(c, restMapper),
|
||||||
|
logger: log,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *StatusChecker) Assess(identifiers ...object.ObjMetadata) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
opts := polling.Options{PollInterval: sc.pollInterval, UseCache: true}
|
||||||
|
eventsChan := sc.statusPoller.Poll(ctx, identifiers, opts)
|
||||||
|
|
||||||
|
coll := collector.NewResourceStatusCollector(identifiers)
|
||||||
|
done := coll.ListenWithObserver(eventsChan, desiredStatusNotifierFunc(cancel, status.CurrentStatus))
|
||||||
|
|
||||||
|
<-done
|
||||||
|
|
||||||
|
for _, rs := range coll.ResourceStatuses {
|
||||||
|
switch rs.Status {
|
||||||
|
case status.CurrentStatus:
|
||||||
|
sc.logger.Successf("%s: %s ready", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))
|
||||||
|
case status.NotFoundStatus:
|
||||||
|
sc.logger.Failuref("%s: %s not found", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))
|
||||||
|
default:
|
||||||
|
sc.logger.Failuref("%s: %s not ready", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if coll.Error != nil || ctx.Err() == context.DeadlineExceeded {
|
||||||
|
return fmt.Errorf("timed out waiting for condition")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// desiredStatusNotifierFunc returns an Observer function for the
|
||||||
|
// ResourceStatusCollector that will cancel the context (using the cancelFunc)
|
||||||
|
// when all resources have reached the desired status.
|
||||||
|
func desiredStatusNotifierFunc(cancelFunc context.CancelFunc,
|
||||||
|
desired status.Status) collector.ObserverFunc {
|
||||||
|
return func(rsc *collector.ResourceStatusCollector, _ event.Event) {
|
||||||
|
var rss []*event.ResourceStatus
|
||||||
|
for _, rs := range rsc.ResourceStatuses {
|
||||||
|
rss = append(rss, rs)
|
||||||
|
}
|
||||||
|
aggStatus := aggregator.AggregateStatus(rss, desired)
|
||||||
|
if aggStatus == desired {
|
||||||
|
cancelFunc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue