1
0
mirror of synced 2026-03-01 19:26:55 +00:00

Compare commits

...

48 Commits

Author SHA1 Message Date
Stefan Prodan
3dfd0bc2e1 Merge pull request #1117 from fluxcd/update-image-auto-guide]
Add push branch and commit template to image automation guide
2021-03-18 15:52:01 +02:00
Stefan Prodan
10ff99542f Add image update automation diagram
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-03-18 14:20:01 +02:00
Stefan Prodan
2449030ab8 Add push branch and commit template to image automation guide
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-03-18 13:56:42 +02:00
Stefan Prodan
3e85901f40 Merge pull request #1116 from fluxcd/get-all-sources-images
Implement get all for sources and images
2021-03-18 13:30:52 +02:00
Stefan Prodan
73b1576f81 Implement get all for sources and images
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-03-18 13:00:49 +02:00
Stefan Prodan
cdb5b7c9a2 Merge pull request #1113 from fluxcd/create-image-update
Add repo path and push branch to image update cmd
2021-03-18 12:35:08 +02:00
Stefan Prodan
d9331b0c91 Add repo path and push branch to image update cmd
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-03-18 11:10:21 +01:00
Stefan Prodan
b6a8163dd9 Add create image policy examples
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-03-18 11:10:21 +01:00
Stefan Prodan
185252ba48 Update flux logs examples
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-03-18 11:10:21 +01:00
Stefan Prodan
043d37921b Merge pull request #1091 from joebowbeer/patch-1
Fix deployment name in image update guide
2021-03-18 10:43:04 +02:00
Joe Bowbeer
02fb8d9958 Merge branch 'main' into patch-1 2021-03-17 14:29:42 -07:00
Stefan Prodan
cfa6c0a178 Merge pull request #1095 from fluxcd/update-components
Update toolkit components
2021-03-17 14:58:04 +02:00
fluxcdbot
e8b52bf2fc Update toolkit components
- helm-controller to v0.8.2
  https://github.com/fluxcd/helm-controller/blob/v0.8.2/CHANGELOG.md
- kustomize-controller to v0.9.3
  https://github.com/fluxcd/kustomize-controller/blob/v0.9.3/CHANGELOG.md
- source-controller to v0.9.1
  https://github.com/fluxcd/source-controller/blob/v0.9.1/CHANGELOG.md
- notification-controller to v0.10.0
  https://github.com/fluxcd/notification-controller/blob/v0.10.0/CHANGELOG.md
- image-reflector-controller to v0.7.1
  https://github.com/fluxcd/image-reflector-controller/blob/v0.7.1/CHANGELOG.md
- image-automation-controller to v0.7.0
  https://github.com/fluxcd/image-automation-controller/blob/v0.7.0/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2021-03-17 12:45:22 +00:00
Joe Bowbeer
85fbb780bf Update image-update.md
The filename is podinfo-deployment.yaml

Signed-off-by: Joe Bowbeer <joe.bowbeer@gmail.com>
2021-03-16 18:58:38 -07:00
Hidde Beydals
bd9f9bf518 Merge pull request #1103 from fluxcd/build/fix-go-mod-update
Fix updating of `go.mod` entries for components
2021-03-16 16:31:17 +01:00
Hidde Beydals
077860fff1 Fix updating of go.mod entries for components
We noticed that some of our components had not received `go.mod` updates
while they did receive updates for the versions declared in the YAML
manifests.

Was able to trace this back to a behavior change in Go since `1.16.x`,
resulting in it no longer making automated changes to `go.mod` and
`go.sum`[1]. This is an issue for our updater script as it relies
on `go list -m all`, which now after the first `go mod edit` returns:

```console
$ go list -m all
go: github.com/fluxcd/notification-controller/api@v0.10.0: missing
go.sum entry; to add it:
        go mod download github.com/fluxcd/notification-controller/api
```

To work around the issue without having to repeatedly call `go mod
tidy`, I have opted to simply `grep` on the contents of `go.mod` as a
workaround.

[1]: https://blog.golang.org/go116-module-changes#TOC_3.

Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-16 16:11:29 +01:00
Stefan Prodan
d29a4ee4d2 Merge pull request #1075 from SomtochiAma/formatted-logs
Implement flux logs command
2021-03-16 16:16:36 +02:00
Somtochi Onyekwere
6d2e34e9b2 Add flux logs command
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
2021-03-16 14:59:03 +01:00
Hidde Beydals
0b6969537b Merge pull request #1102 from fluxcd/fix-sshscan-port
Use Host from parsed URL instead of Hostname
2021-03-16 14:17:07 +01:00
Hidde Beydals
dc6b0d0f0d Use Host from parsed URL instead of Hostname
Regression bug introduced in #1001.

Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-16 14:01:46 +01:00
Hidde Beydals
b4dbb178fe Merge pull request #1098 from kingdonb/fixup-hint-1
Fix hint in Flux v1 Migration guide
2021-03-15 17:33:03 +01:00
Kingdon Barrett
4cf5290989 fixup hint in Flux v1 Migration guide
The wrong indenting means the hint body will not display as a hint

Signed-off-by: Kingdon Barrett <kingdon@weave.works>
2021-03-15 11:50:37 -04:00
Hidde Beydals
6ffd2222c2 Merge pull request #1094 from fluxcd/status-pkg
Move `StatusChecker` to separate and generic pkg
2021-03-15 11:57:52 +01:00
Hidde Beydals
e7725911a7 Move StatusChecker to separate and generic pkg
This commit moves the `StatusChecker` to a separate package, while
making it more generic so that it is able to assess the status of any
given set of `object.ObjMetadata` identifiers.

Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-15 11:41:02 +01:00
Hidde Beydals
0c1664cd01 Merge pull request #1093 from fluxcd/build-bootstrap-action-changes 2021-03-15 11:33:31 +01:00
Hidde Beydals
0239307d8e Change repository name used in bootstrap tests
This changes the name of the repository that is used for the GitHub
end-to-end tests to a name that is still traceable to the source
(repository) that created it, by using the format
`<ORIGIN_REPOSITORY_NAME>-<PSEUDO_RAND_SUFFIX>`.

The `PSEUDO_RAND_SUFFIX` is a SHA1 sum of the name of the branch and
commit SHA the tests run for, resulting in a 40 character suffix that
unlike the short commit SHA used before, should not result in collisions.

Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-15 11:20:26 +01:00
Hidde Beydals
9f10b6be1b Replace delete opt on GitHub bootstrap with curl
Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-15 11:20:26 +01:00
Stefan Prodan
01f613b39e Merge pull request #1036 from scottrigby/migration-timetable
Migration and Support Timetable
2021-03-14 09:52:20 +02:00
Scott Rigby
b775d11a70 Flux Migration and Support Timetable
* Set explicit column widths for timetable

  No need for old Firefox workaround. It appears fine on FF in 2021

  See:
  - https://github.com/squidfunk/mkdocs-material/issues/922
  - https://github.com/squidfunk/mkdocs-material/issues/118

* Hide TOC right column on migration table page

* SDK->GOTK footnote

* Cross-link admonitions between Roadmap and Timetable

  To-do: change structure and file names under migration menu dir when we
  move to fluxcd/website

* Add custom heart admonition

* Link to documentated deprecation of apiextensions.k8s.io/v1beta1
  CustomResourceDefinition

* Fix caret (^^ underlines short status)

* Initial migration and Support Timetable

  Add mkdocs markdown_extensions and sort them alphabetically

Co-authored-by: Stefan Prodan <stefan.prodan@gmail.com>
Signed-off-by: Scott Rigby <scott@r6by.com>
2021-03-13 22:24:21 -05:00
Stefan Prodan
022576697f Merge pull request #1086 from squat/export_source_typo
cmd/flux/export_source*: fix typo in comment
2021-03-12 14:55:01 +02:00
Lucas Servén Marín
065d0b2c06 cmd/flux/export_source*: fix typo in comment
This commit fixes a small typo in the comments for the export source
commands.

Signed-off-by: Lucas Servén Marín <lserven@gmail.com>
2021-03-12 13:41:46 +01:00
Stefan Prodan
ed4718205a Merge pull request #1065 from fluxcd/build-prerequisites
Add Go 1.16 to prerequisites (contributing doc)
2021-03-12 12:45:24 +02:00
Stefan Prodan
a29d0c536d Add Go 1.16 to prerequisites (contributing doc)
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-03-12 12:28:43 +02:00
Hidde Beydals
eaeb8ca5c1 Merge pull request #1025 from gliptak/patch-1
Correct ineffassign
2021-03-10 18:12:20 +01:00
Gábor Lipták
2092c14aca Correct ineffassign
Signed-off-by: Gábor Lipták <gliptak@gmail.com>
2021-03-10 17:10:26 +00:00
Stefan Prodan
69f38b8c77 Merge pull request #1027 from stealthybox/sops-gpg-batch
Improve SOPS GPG guide key management
2021-03-10 10:04:40 +02:00
leigh capili
d2cdd02a57 Parameterize GPG key input and fingerprint
Signed-off-by: leigh capili <leigh@null.net>
2021-03-09 17:11:53 -07:00
leigh capili
095c8323a1 Capitalize SOPS, K8s, and Git
Signed-off-by: leigh capili <leigh@null.net>
2021-03-09 17:11:53 -07:00
leigh capili
accb4c915e Improve SOPS GPG guide key management
- Switch to batch GPG key creation
- Accurately name the cluster's decryption key
- Suggest password-manager backup
- Optionally cleanup secret key from generating machine
- Optionally commit the public key to the repo for team members
- Document SOPS limitations decryption required for editing / appending fields

Signed-off-by: leigh capili <leigh@null.net>
2021-03-09 17:11:52 -07:00
Hidde Beydals
242809f61d Merge pull request #1069 from fluxcd/doc-link-fix
docs: fix link to source-controller documentation
2021-03-09 12:15:06 +01:00
Hidde Beydals
c4907cf6c6 docs: fix link to source-controller documentation
Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-09 10:16:15 +01:00
Hidde Beydals
a4b9191fa3 Merge pull request #1066 from fluxcd/manifest-bundle-tweaks 2021-03-09 09:14:07 +01:00
Hidde Beydals
5fd3d0bd41 Generate manifests in flux-{go,scm} AUR packages
This commit makes a couple of changes to the `flux-{go,scm}` packages
so that they properly build again:

- The manifests are generated before the compilation of the `flux`
  binary.
- The `makedepends` have been updated to require a version of Go
  `>=1.16` (which is a requirement for `embed`).
- The `makedepends` have been updated to require a `kustomize` version
  `>=3.0` (as we use `transformers`).

Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-08 19:06:07 +01:00
Hidde Beydals
ba6da23323 Make manifests dir bundle.sh configurable
There was an assumption in this script that it is always executed in Git
repository/directory, this is however not always true, for example when
one downloads the `.tar.gz` that is made available for every release
by GitHub (and used in one of our AUR packages).

This commit changes this, and makes the first argument of `bundle.sh`
configurable, so a custom manifests directory can always be defined
_without_ relying on Git.

Omitting it, or passing an empty string, will still fall back to the
previous behavior of using `git rev-parse --show-toplevel`.

Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-08 18:45:05 +01:00
Hidde Beydals
0328bb14ce Merge pull request #1062 from fluxcd/improve-embedded-manifests-build
Improve build process embedded manifests
2021-03-08 16:25:48 +01:00
Hidde Beydals
2b7a0f3fd4 Improve build process embedded manifests
This commit changes the way the build of manifests is triggered by
making smarter use of the capabilities of Make. The result should be
that the manifests are only regenerated if:

1. There is no `cmd/flux/manifests/` directory.
2. There have been made changes to the YAML files in the `manifests/`
   directory that are newer than the files in `cmd/flux/manifests/`.

Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-08 16:06:44 +01:00
Hidde Beydals
527886bea0 Merge pull request #1060 from fluxcd/aur-pkg-autocomplete-install
Install Bash, Fish, ZSH auto complete in AUR pkgs
2021-03-08 13:35:01 +01:00
Hidde Beydals
98078a0c65 Install Bash, Fish, ZSH auto complete in AUR pkgs
Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-03-08 13:16:50 +01:00
81 changed files with 1298 additions and 356 deletions

View File

@@ -8,18 +8,20 @@ pkgdesc="Open and extensible continuous delivery solution for Kubernetes"
url="https://fluxcd.io/"
arch=("x86_64" "armv6h" "armv7h" "aarch64")
license=("APACHE")
optdepends=("kubectl")
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
'bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source_x86_64=(
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_amd64.tar.gz"
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_amd64.tar.gz"
)
source_armv6h=(
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
)
source_armv7h=(
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
)
source_aarch64=(
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm64.tar.gz"
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm64.tar.gz"
)
sha256sums_x86_64=(
${SHA256SUM_AMD64}
@@ -33,7 +35,12 @@ sha256sums_armv7h=(
sha256sums_aarch64=(
${SHA256SUM_ARM64}
)
_srcname=flux
package() {
install -Dm755 flux "$pkgdir/usr/bin/flux"
install -Dm755 ${_srcname} "${pkgdir}/usr/bin/${_srcname}"
"${pkgdir}/usr/bin/${_srcname}" completion bash | install -Dm644 /dev/stdin "${pkgdir}/usr/share/bash-completion/completions/${_srcname}"
"${pkgdir}/usr/bin/${_srcname}" completion fish | install -Dm644 /dev/stdin "${pkgdir}/usr/share/fish/vendor_completions.d/${_srcname}.fish"
"${pkgdir}/usr/bin/${_srcname}" completion zsh | install -Dm644 /dev/stdin "${pkgdir}/usr/share/zsh/site-functions/_${_srcname}"
}

View File

@@ -12,32 +12,40 @@ provides=("flux-bin")
conflicts=("flux-bin")
replaces=("flux-cli")
depends=("glibc")
makedepends=("go")
optdepends=("kubectl")
makedepends=('go>=1.16', 'kustomize>=3.0')
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
'bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source=(
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/archive/v$pkgver.tar.gz"
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/archive/v${pkgver}.tar.gz"
)
sha256sums=(
${SHA256SUM}
)
_srcname=flux
build() {
cd "flux2-$pkgver"
cd "flux2-${pkgver}"
export CGO_LDFLAGS="$LDFLAGS"
export CGO_CFLAGS="$CFLAGS"
export CGO_CXXFLAGS="$CXXFLAGS"
export CGO_CPPFLAGS="$CPPFLAGS"
export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"
go build -ldflags "-X main.VERSION=$pkgver" -o flux-bin ./cmd/flux
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
./manifests/scripts/bundle.sh "${PWD}/manifests" "${PWD}/cmd/flux/manifests"
go build -ldflags "-linkmode=external -X main.VERSION=${pkgver}" -o ${_srcname} ./cmd/flux
}
check() {
cd "flux2-$pkgver"
cd "flux2-${pkgver}"
make test
}
package() {
cd "flux2-$pkgver"
install -Dm755 flux-bin "$pkgdir/usr/bin/flux"
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
cd "flux2-${pkgver}"
install -Dm755 ${_srcname} "${pkgdir}/usr/bin/${_srcname}"
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
"${pkgdir}/usr/bin/${_srcname}" completion bash | install -Dm644 /dev/stdin "${pkgdir}/usr/share/bash-completion/completions/${_srcname}"
"${pkgdir}/usr/bin/${_srcname}" completion fish | install -Dm644 /dev/stdin "${pkgdir}/usr/share/fish/vendor_completions.d/${_srcname}.fish"
"${pkgdir}/usr/bin/${_srcname}" completion zsh | install -Dm644 /dev/stdin "${pkgdir}/usr/share/zsh/site-functions/_${_srcname}"
}

View File

@@ -11,12 +11,15 @@ license=("APACHE")
provides=("flux-bin")
conflicts=("flux-bin")
depends=("glibc")
makedepends=("go")
optdepends=("kubectl")
makedepends=('go>=1.16', 'kustomize>=3.0')
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
'bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source=(
"git+https://github.com/fluxcd/flux2.git"
)
md5sums=('SKIP')
_srcname=flux
pkgver() {
cd "flux2"
@@ -29,8 +32,9 @@ build() {
export CGO_CFLAGS="$CFLAGS"
export CGO_CXXFLAGS="$CXXFLAGS"
export CGO_CPPFLAGS="$CPPFLAGS"
export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"
go build -ldflags "-X main.VERSION=$pkgver" -o flux-bin ./cmd/flux
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
make cmd/flux/manifests
go build -ldflags "-linkmode=external -X main.VERSION=${pkgver}" -o ${_srcname} ./cmd/flux
}
check() {
@@ -40,6 +44,10 @@ check() {
package() {
cd "flux2"
install -Dm755 flux-bin "$pkgdir/usr/bin/flux"
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -Dm755 ${_srcname} "${pkgdir}/usr/bin/${_srcname}"
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
"${pkgdir}/usr/bin/${_srcname}" completion bash | install -Dm644 /dev/stdin "${pkgdir}/usr/share/bash-completion/completions/${_srcname}"
"${pkgdir}/usr/bin/${_srcname}" completion fish | install -Dm644 /dev/stdin "${pkgdir}/usr/share/fish/vendor_completions.d/${_srcname}.fish"
"${pkgdir}/usr/bin/${_srcname}" completion zsh | install -Dm644 /dev/stdin "${pkgdir}/usr/share/zsh/site-functions/_${_srcname}"
}

View File

@@ -30,16 +30,22 @@ jobs:
uses: fluxcd/pkg//actions/kustomize@main
- name: Build
run: |
make build-manifests
make cmd/flux/manifests
go build -o /tmp/flux ./cmd/flux
- name: Set outputs
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
run: |
/tmp/flux bootstrap github --manifests ./manifests/install/ \
--owner=fluxcd-testing \
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
--repository=${{ steps.vars.outputs.test_repo_name }} \
--branch=main \
--path=test-cluster
env:
@@ -48,7 +54,7 @@ jobs:
run: |
/tmp/flux bootstrap github --manifests ./manifests/install/ \
--owner=fluxcd-testing \
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
--repository=${{ steps.vars.outputs.test_repo_name }} \
--branch=main \
--path=test-cluster
env:
@@ -61,19 +67,19 @@ jobs:
run: |
/tmp/flux bootstrap github --manifests ./manifests/install/ \
--owner=fluxcd-testing \
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
--repository=${{ steps.vars.outputs.test_repo_name }} \
--branch=main \
--path=test-cluster
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: delete repository
run: |
/tmp/flux bootstrap github --manifests ./manifests/install/ \
--owner=fluxcd-testing \
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
--branch=main \
--path=test-cluster \
--delete
curl \
-X DELETE \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${GITHUB_TOKEN}" \
--fail --silent \
https://api.github.com/repos/fluxcd-testing/${{ steps.vars.outputs.test_repo_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: Debug failure

View File

@@ -30,8 +30,8 @@ jobs:
uses: fluxcd/pkg//actions/kustomize@main
- name: Generate manifests
run: |
make build-manifests
./manifests/scripts/bundle.sh ./output manifests.tar.gz
make cmd/flux/manifests
./manifests/scripts/bundle.sh "" ./output manifests.tar.gz
kustomize build ./manifests/install > ./output/install.yaml
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v1

View File

@@ -31,7 +31,7 @@ jobs:
uses: fluxcd/pkg//actions/kustomize@main
- name: Build manifests
run: |
make build-manifests
make cmd/flux/manifests
- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/golang@master
continue-on-error: true

View File

@@ -30,7 +30,7 @@ jobs:
# bump kustomize
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
go mod edit -require="github.com/fluxcd/$1/api@${RELEASE_VERSION}"
fi

View File

@@ -48,11 +48,13 @@ you might want to take a look at the [introductory talk and demo](https://www.yo
This project is composed of:
- [/f/flux2](https://github.com/fluxcd/flux2): The Flux CLI
- [/f/source-manager](https://github.com/fluxcd/source-controller): Kubernetes operator for managing sources
- [/f/kustomize-controller](https://github.com/fluxcd/kustomize-controller): Kubernetes operator for building GitOps pipelines with Kustomize
- [/f/helm-controller](https://github.com/fluxcd/helm-controller): Kubernetes operator for building GitOps pipelines with Helm
- [/f/notification-controller](https://github.com/fluxcd/notification-controller): Kubernetes operator for handling inbound and outbound events
- [flux2](https://github.com/fluxcd/flux2): The Flux CLI
- [source-manager](https://github.com/fluxcd/source-controller): Kubernetes operator for managing sources (Git and Helm repositories, S3-compatible Buckets)
- [kustomize-controller](https://github.com/fluxcd/kustomize-controller): Kubernetes operator for building GitOps pipelines with Kustomize
- [helm-controller](https://github.com/fluxcd/helm-controller): Kubernetes operator for building GitOps pipelines with Helm
- [notification-controller](https://github.com/fluxcd/notification-controller): Kubernetes operator for handling inbound and outbound events
- [image-reflector-controller](https://github.com/fluxcd/image-reflector-controller): Kubernetes operator for scanning container registries
- [image-automation-controller](https://github.com/fluxcd/image-automation-controller): Kubernetes operator for patches container image tags in Git
### Understanding the code
@@ -63,6 +65,12 @@ for source changes.
### How to run the test suite
Prerequisites:
* go >= 1.16
* kubectl >= 1.18
* kustomize >= 3.1
You can run the unit tests by simply doing
```bash

View File

@@ -1,4 +1,7 @@
VERSION?=$(shell grep 'VERSION' cmd/flux/main.go | awk '{ print $$4 }' | tr -d '"')
EMBEDDED_MANIFESTS_TARGET=cmd/flux/manifests
rwildcard=$(foreach d,$(wildcard $(addsuffix *,$(1))),$(call rwildcard,$(d)/,$(2)) $(filter $(subst *,%,$(2)),$(d)))
all: test build
@@ -11,13 +14,13 @@ fmt:
vet:
go vet ./...
test: build-manifests tidy fmt vet docs
test: $(EMBEDDED_MANIFESTS_TARGET) tidy fmt vet docs
go test ./... -coverprofile cover.out
build-manifests:
$(EMBEDDED_MANIFESTS_TARGET): $(call rwildcard,manifests/,*.yaml *.json)
./manifests/scripts/bundle.sh
build:
build: $(EMBEDDED_MANIFESTS_TARGET)
CGO_ENABLED=0 go build -o ./bin/flux ./cmd/flux
install:
@@ -25,7 +28,7 @@ install:
.PHONY: docs
docs:
rm docs/cmd/*
rm -rf docs/cmd/*
mkdir -p ./docs/cmd && go run ./cmd/flux/ docgen
install-dev:

View File

@@ -36,6 +36,7 @@ import (
"github.com/fluxcd/flux2/pkg/manifestgen/install"
kus "github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
"github.com/fluxcd/flux2/pkg/manifestgen/sync"
"github.com/fluxcd/flux2/pkg/status"
)
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 {
kubectlArgs := []string{"apply", "-f", manifestPath}
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)
}
statusChecker, err := NewStatusChecker(time.Second, rootArgs.timeout)
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 {
return fmt.Errorf("install failed: %w", err)
}
logger.Waitingf("verifying installation")
if err := statusChecker.Assess(components...); err != nil {
if err := statusChecker.Assess(componentRefs...); err != nil {
return fmt.Errorf("install failed")
}
return nil
}

View File

@@ -80,7 +80,6 @@ type githubFlags struct {
hostname string
path flags.SafeRelativePath
teams []string
delete bool
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().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)
}
@@ -163,14 +159,6 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
}
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
logger.Actionf("connecting to %s", githubArgs.hostname)
changed, err := provider.CreateRepository(ctx, repository)
@@ -260,7 +248,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
if err != nil {
return fmt.Errorf("git URL parse failed: %w", err)
}
secretOpts.SSHHostname = u.Hostname()
secretOpts.SSHHostname = u.Host
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
secretOpts.RSAKeyBits = 2048
}

View File

@@ -235,7 +235,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
if err != nil {
return fmt.Errorf("git URL parse failed: %w", err)
}
secretOpts.SSHHostname = u.Hostname()
secretOpts.SSHHostname = u.Host
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
secretOpts.RSAKeyBits = 2048
}

View File

@@ -34,6 +34,7 @@ import (
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/flux2/pkg/manifestgen/install"
"github.com/fluxcd/flux2/pkg/status"
)
var checkCmd = &cobra.Command{
@@ -205,12 +206,17 @@ func componentsCheck() bool {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
if err != nil {
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 {
return false
}
@@ -220,10 +226,10 @@ func componentsCheck() bool {
var list v1.DeploymentList
if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err == nil {
for _, d := range list.Items {
if err := statusChecker.Assess(d.Name); err != nil {
ok = false
} else {
logger.Successf("%s: healthy", d.Name)
if ref, err := buildComponentObjectRefs(d.Name); err == nil {
if err := statusChecker.Assess(ref...); err != nil {
ok = false
}
}
for _, c := range d.Spec.Template.Spec.Containers {
logger.Actionf(c.Image)

View File

@@ -32,7 +32,7 @@ import (
)
var createImagePolicyCmd = &cobra.Command{
Use: "policy <name>",
Use: "policy [name]",
Short: "Create or update an ImagePolicy object",
Long: `The create image policy command generates an ImagePolicy resource.
An ImagePolicy object calculates a "latest image" given an image
@@ -40,6 +40,18 @@ repository and a policy, e.g., semver.
The image that sorts highest according to the policy is recorded in
the status of the object.`,
Example: ` # Create an ImagePolicy to select the latest stable release
flux create image policy podinfo \
--image-ref=podinfo \
--select-semver=">=1.0.0"
# Create an ImagePolicy to select the latest main branch build tagged as "${GIT_BRANCH}-${GIT_SHA:0:7}-$(date +%s)"
flux create image policy podinfo \
--image-ref=podinfo \
--select-numeric=asc \
--filter-regex='^main-[a-f0-9]+-(?P<ts>[0-9]+)' \
--filter-extract='$ts'
`,
RunE: createImagePolicyRun}
type imagePolicyFlags struct {

View File

@@ -30,7 +30,7 @@ import (
)
var createImageRepositoryCmd = &cobra.Command{
Use: "repository <name>",
Use: "repository [name]",
Short: "Create or update an ImageRepository object",
Long: `The create image repository command generates an ImageRepository resource.
An ImageRepository object specifies an image repository to scan.`,

View File

@@ -28,19 +28,38 @@ import (
)
var createImageUpdateCmd = &cobra.Command{
Use: "update <name>",
Use: "update [name]",
Short: "Create or update an ImageUpdateAutomation object",
Long: `The create image update command generates an ImageUpdateAutomation resource.
An ImageUpdateAutomation object specifies an automated update to images
mentioned in YAMLs in a git repository.`,
Example: ` # Configure image updates for the main repository created by flux bootstrap
flux create image update flux-system \
--git-repo-ref=flux-system \
--git-repo-path="./clusters/my-cluster" \
--checkout-branch=main \
--author-name=flux \
--author-email=flux@example.com \
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
# Configure image updates to push changes to a different branch, if the branch doesn't exists it will be created
flux create image update flux-system \
--git-repo-ref=flux-system \
--git-repo-path="./clusters/my-cluster" \
--checkout-branch=main \
--push-branch=image-updates \
--author-name=flux \
--author-email=flux@example.com \
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
`,
RunE: createImageUpdateRun,
}
type imageUpdateFlags struct {
// git checkout spec
gitRepoRef string
branch string
// commit spec
gitRepoRef string
gitRepoPath string
checkoutBranch string
pushBranch string
commitTemplate string
authorName string
authorEmail string
@@ -50,8 +69,10 @@ var imageUpdateArgs = imageUpdateFlags{}
func init() {
flags := createImageUpdateCmd.Flags()
flags.StringVar(&imageUpdateArgs.gitRepoRef, "git-repo-ref", "", "the name of a GitRepository resource with details of the upstream git repository")
flags.StringVar(&imageUpdateArgs.branch, "branch", "", "the branch to checkout and push commits to")
flags.StringVar(&imageUpdateArgs.gitRepoRef, "git-repo-ref", "", "the name of a GitRepository resource with details of the upstream Git repository")
flags.StringVar(&imageUpdateArgs.gitRepoPath, "git-repo-path", "", "path to the directory containing the manifests to be updated, defaults to the repository root")
flags.StringVar(&imageUpdateArgs.checkoutBranch, "checkout-branch", "", "the branch to checkout")
flags.StringVar(&imageUpdateArgs.pushBranch, "push-branch", "", "the branch to push commits to, defaults to the checkout branch if not specified")
flags.StringVar(&imageUpdateArgs.commitTemplate, "commit-template", "", "a template for commit messages")
flags.StringVar(&imageUpdateArgs.authorName, "author-name", "", "the name to use for commit author")
flags.StringVar(&imageUpdateArgs.authorEmail, "author-email", "", "the email to use for commit author")
@@ -69,8 +90,16 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("a reference to a GitRepository is required (--git-repo-ref)")
}
if imageUpdateArgs.branch == "" {
return fmt.Errorf("the Git repository branch is required (--branch)")
if imageUpdateArgs.checkoutBranch == "" {
return fmt.Errorf("the Git repository branch is required (--checkout-branch)")
}
if imageUpdateArgs.authorName == "" {
return fmt.Errorf("the author name is required (--author-name)")
}
if imageUpdateArgs.authorEmail == "" {
return fmt.Errorf("the author email is required (--author-email)")
}
labels, err := parseLabels()
@@ -89,9 +118,11 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
GitRepositoryRef: meta.LocalObjectReference{
Name: imageUpdateArgs.gitRepoRef,
},
Branch: imageUpdateArgs.branch,
Branch: imageUpdateArgs.checkoutBranch,
},
Interval: metav1.Duration{
Duration: createArgs.interval,
},
Interval: metav1.Duration{Duration: createArgs.interval},
Commit: autov1.CommitSpec{
AuthorName: imageUpdateArgs.authorName,
AuthorEmail: imageUpdateArgs.authorEmail,
@@ -100,6 +131,19 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
},
}
if imageUpdateArgs.pushBranch != "" {
update.Spec.Push = &autov1.PushSpec{
Branch: imageUpdateArgs.pushBranch,
}
}
if imageUpdateArgs.gitRepoPath != "" {
update.Spec.Update = &autov1.UpdateStrategy{
Path: imageUpdateArgs.gitRepoPath,
Strategy: autov1.UpdateStrategySetters,
}
}
if createArgs.export {
return printExport(exportImageUpdate(&update))
}

View File

@@ -129,7 +129,7 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
}
switch u.Scheme {
case "ssh":
opts.SSHHostname = u.Hostname()
opts.SSHHostname = u.Host
opts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(secretGitArgs.keyAlgorithm)
opts.RSAKeyBits = int(secretGitArgs.rsaBits)
opts.ECDSACurve = secretGitArgs.ecdsaCurve.Curve

View File

@@ -215,7 +215,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
switch u.Scheme {
case "ssh":
secretOpts.SSHHostname = u.Hostname()
secretOpts.SSHHostname = u.Host
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(sourceGitArgs.keyAlgorithm)
secretOpts.RSAKeyBits = int(sourceGitArgs.keyRSABits)
secretOpts.ECDSACurve = sourceGitArgs.keyECDSACurve.Curve

View File

@@ -34,7 +34,7 @@ import (
var exportSourceBucketCmd = &cobra.Command{
Use: "bucket [name]",
Short: "Export Bucket sources in YAML format",
Long: "The export source git command exports on or all Bucket sources in YAML format.",
Long: "The export source git command exports one or all Bucket sources in YAML format.",
Example: ` # Export all Bucket sources
flux export source bucket --all > sources.yaml

View File

@@ -34,7 +34,7 @@ import (
var exportSourceGitCmd = &cobra.Command{
Use: "git [name]",
Short: "Export GitRepository sources in YAML format",
Long: "The export source git command exports on or all GitRepository sources in YAML format.",
Long: "The export source git command exports one or all GitRepository sources in YAML format.",
Example: ` # Export all GitRepository sources
flux export source git --all > sources.yaml

View File

@@ -34,7 +34,7 @@ import (
var exportSourceHelmCmd = &cobra.Command{
Use: "helm [name]",
Short: "Export HelmRepository sources in YAML format",
Long: "The export source git command exports on or all HelmRepository sources in YAML format.",
Long: "The export source git command exports one or all HelmRepository sources in YAML format.",
Example: ` # Export all HelmRepository sources
flux export source helm --all > sources.yaml

View File

@@ -18,7 +18,9 @@ package main
import (
"context"
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
apimeta "k8s.io/apimachinery/pkg/api/meta"
@@ -32,8 +34,8 @@ import (
var getCmd = &cobra.Command{
Use: "get",
Short: "Get sources and resources",
Long: "The get sub-commands print the statuses of sources and resources.",
Short: "Get the resources and their status",
Long: "The get sub-commands print the statuses of Flux resources.",
}
type GetFlags struct {
@@ -50,7 +52,7 @@ func init() {
type summarisable interface {
listAdapter
summariseItem(i int, includeNamespace bool) []string
summariseItem(i int, includeNamespace bool, includeKind bool) []string
headers(includeNamespace bool) []string
}
@@ -63,11 +65,17 @@ func statusAndMessage(conditions []metav1.Condition) (string, string) {
return string(metav1.ConditionFalse), "waiting to be reconciled"
}
func nameColumns(item named, includeNamespace bool) []string {
if includeNamespace {
return []string{item.GetNamespace(), item.GetName()}
func nameColumns(item named, includeNamespace bool, includeKind bool) []string {
name := item.GetName()
if includeKind {
name = fmt.Sprintf("%s/%s",
strings.ToLower(item.GetObjectKind().GroupVersionKind().Kind),
item.GetName())
}
return []string{item.GetName()}
if includeNamespace {
return []string{item.GetNamespace(), name}
}
return []string{name}
}
var namespaceHeader = []string{"Namespace"}
@@ -100,17 +108,25 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error {
return err
}
getAll := cmd.Use == "all"
if get.list.len() == 0 {
logger.Failuref("no %s objects found in %s namespace", get.kind, rootArgs.namespace)
if !getAll {
logger.Failuref("no %s objects found in %s namespace", get.kind, rootArgs.namespace)
}
return nil
}
header := get.list.headers(getArgs.allNamespaces)
var rows [][]string
for i := 0; i < get.list.len(); i++ {
row := get.list.summariseItem(i, getArgs.allNamespaces)
row := get.list.summariseItem(i, getArgs.allNamespaces, getAll)
rows = append(rows, row)
}
utils.PrintTable(os.Stdout, header, rows)
if getAll {
fmt.Println()
}
return nil
}

View File

@@ -42,11 +42,11 @@ func init() {
getCmd.AddCommand(getHelmReleaseCmd)
}
func (a helmReleaseListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (a helmReleaseListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := a.Items[i]
revision := item.Status.LastAppliedRevision
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace),
return append(nameColumns(&item, includeNamespace, includeKind),
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}

66
cmd/flux/get_image_all.go Normal file
View File

@@ -0,0 +1,66 @@
/*
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 (
autov1 "github.com/fluxcd/image-automation-controller/api/v1alpha1"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
"github.com/spf13/cobra"
)
var getImageAllCmd = &cobra.Command{
Use: "all",
Short: "Get all image statuses",
Long: "The get image sub-commands print the statuses of all image objects.",
Example: ` # List all image objects in a namespace
flux get images all --namespace=flux-system
# List all image objects in all namespaces
flux get images all --all-namespaces
`,
RunE: func(cmd *cobra.Command, args []string) error {
c := getCommand{
apiType: imageRepositoryType,
list: imageRepositoryListAdapter{&imagev1.ImageRepositoryList{}},
}
if err := c.run(cmd, args); err != nil {
logger.Failuref(err.Error())
}
c = getCommand{
apiType: imagePolicyType,
list: &imagePolicyListAdapter{&imagev1.ImagePolicyList{}},
}
if err := c.run(cmd, args); err != nil {
logger.Failuref(err.Error())
}
c = getCommand{
apiType: imageUpdateAutomationType,
list: &imageUpdateAutomationListAdapter{&autov1.ImageUpdateAutomationList{}},
}
if err := c.run(cmd, args); err != nil {
logger.Failuref(err.Error())
}
return nil
},
}
func init() {
getImageCmd.AddCommand(getImageAllCmd)
}

View File

@@ -42,10 +42,10 @@ func init() {
getImageCmd.AddCommand(getImagePolicyCmd)
}
func (s imagePolicyListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (s imagePolicyListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := s.Items[i]
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace), status, msg, item.Status.LatestImage)
return append(nameColumns(&item, includeNamespace, includeKind), status, msg, item.Status.LatestImage)
}
func (s imagePolicyListAdapter) headers(includeNamespace bool) []string {

View File

@@ -46,14 +46,14 @@ func init() {
getImageCmd.AddCommand(getImageRepositoryCmd)
}
func (s imageRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (s imageRepositoryListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := s.Items[i]
status, msg := statusAndMessage(item.Status.Conditions)
var lastScan string
if item.Status.LastScanResult != nil {
lastScan = item.Status.LastScanResult.ScanTime.Time.Format(time.RFC3339)
}
return append(nameColumns(&item, includeNamespace),
return append(nameColumns(&item, includeNamespace, includeKind),
status, msg, lastScan, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}

View File

@@ -46,14 +46,14 @@ func init() {
getImageCmd.AddCommand(getImageUpdateCmd)
}
func (s imageUpdateAutomationListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (s imageUpdateAutomationListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := s.Items[i]
status, msg := statusAndMessage(item.Status.Conditions)
var lastRun string
if item.Status.LastAutomationRunTime != nil {
lastRun = item.Status.LastAutomationRunTime.Time.Format(time.RFC3339)
}
return append(nameColumns(&item, includeNamespace), status, msg, lastRun, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
return append(nameColumns(&item, includeNamespace, includeKind), status, msg, lastRun, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}
func (s imageUpdateAutomationListAdapter) headers(includeNamespace bool) []string {

View File

@@ -42,11 +42,11 @@ func init() {
getCmd.AddCommand(getKsCmd)
}
func (a kustomizationListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (a kustomizationListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := a.Items[i]
revision := item.Status.LastAppliedRevision
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace),
return append(nameColumns(&item, includeNamespace, includeKind),
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}

View File

@@ -77,7 +77,7 @@ func getReceiverCmdRun(cmd *cobra.Command, args []string) error {
}
var rows [][]string
for _, receiver := range list.Items {
row := []string{}
var row []string
if c := apimeta.FindStatusCondition(receiver.Status.Conditions, meta.ReadyCondition); c != nil {
row = []string{
receiver.GetName(),

View File

@@ -0,0 +1,73 @@
/*
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 (
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/spf13/cobra"
)
var getSourceAllCmd = &cobra.Command{
Use: "all",
Short: "Get all source statuses",
Long: "The get sources all command print the statuses of all sources.",
Example: ` # List all sources in a namespace
flux get sources all --namespace=flux-system
# List all sources in all namespaces
flux get sources all --all-namespaces
`,
RunE: func(cmd *cobra.Command, args []string) error {
c := getCommand{
apiType: bucketType,
list: &bucketListAdapter{&sourcev1.BucketList{}},
}
if err := c.run(cmd, args); err != nil {
logger.Failuref(err.Error())
}
c = getCommand{
apiType: gitRepositoryType,
list: &gitRepositoryListAdapter{&sourcev1.GitRepositoryList{}},
}
if err := c.run(cmd, args); err != nil {
logger.Failuref(err.Error())
}
c = getCommand{
apiType: helmRepositoryType,
list: &helmRepositoryListAdapter{&sourcev1.HelmRepositoryList{}},
}
if err := c.run(cmd, args); err != nil {
logger.Failuref(err.Error())
}
c = getCommand{
apiType: helmChartType,
list: &helmChartListAdapter{&sourcev1.HelmChartList{}},
}
if err := c.run(cmd, args); err != nil {
logger.Failuref(err.Error())
}
return nil
},
}
func init() {
getSourceCmd.AddCommand(getSourceAllCmd)
}

View File

@@ -44,14 +44,14 @@ func init() {
getSourceCmd.AddCommand(getSourceBucketCmd)
}
func (a *bucketListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (a *bucketListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := a.Items[i]
var revision string
if item.GetArtifact() != nil {
revision = item.GetArtifact().Revision
}
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace),
return append(nameColumns(&item, includeNamespace, includeKind),
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}

View File

@@ -44,14 +44,14 @@ func init() {
getSourceCmd.AddCommand(getSourceHelmChartCmd)
}
func (a *helmChartListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (a *helmChartListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := a.Items[i]
var revision string
if item.GetArtifact() != nil {
revision = item.GetArtifact().Revision
}
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace),
return append(nameColumns(&item, includeNamespace, includeKind),
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}

View File

@@ -44,14 +44,14 @@ func init() {
getSourceCmd.AddCommand(getSourceGitCmd)
}
func (a *gitRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (a *gitRepositoryListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := a.Items[i]
var revision string
if item.GetArtifact() != nil {
revision = item.GetArtifact().Revision
}
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace),
return append(nameColumns(&item, includeNamespace, includeKind),
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}

View File

@@ -44,14 +44,14 @@ func init() {
getSourceCmd.AddCommand(getSourceHelmCmd)
}
func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
item := a.Items[i]
var revision string
if item.GetArtifact() != nil {
revision = item.GetArtifact().Revision
}
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace),
return append(nameColumns(&item, includeNamespace, includeKind),
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}

View File

@@ -30,6 +30,7 @@ import (
"github.com/fluxcd/flux2/internal/flags"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/flux2/pkg/manifestgen/install"
"github.com/fluxcd/flux2/pkg/status"
)
var installCmd = &cobra.Command{
@@ -200,7 +201,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
applyOutput = utils.ModeOS
}
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 {
@@ -208,13 +209,20 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
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 {
return fmt.Errorf("install failed: %w", err)
}
logger.Waitingf("verifying installation")
if err := statusChecker.Assess(components...); err != nil {
if err := statusChecker.Assess(componentRefs...); err != nil {
return fmt.Errorf("install failed")
}

261
cmd/flux/logs.go Normal file
View File

@@ -0,0 +1,261 @@
/*
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"
"html/template"
"io"
"os"
"strings"
"sync"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"github.com/fluxcd/flux2/internal/flags"
"github.com/fluxcd/flux2/internal/utils"
)
var logsCmd = &cobra.Command{
Use: "logs",
Short: "Display formatted logs for Flux components",
Long: "The logs command displays formatted logs from various Flux components.",
Example: ` # Print the reconciliation logs of all Flux custom resources in your cluster
flux logs --all-namespaces
# Stream logs for a particular log level
flux logs --follow --level=error --all-namespaces
# Filter logs by kind, name and namespace
flux logs --kind=Kustomization --name=podinfo --namespace=default
# Print logs when Flux is installed in a different namespace than flux-system
flux logs --flux-namespace=my-namespace
`,
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"`
}

View File

@@ -17,6 +17,7 @@ limitations under the License.
package main
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -62,6 +63,7 @@ func (c universalAdapter) asClientObject() client.Object {
type named interface {
GetName() string
GetNamespace() string
GetObjectKind() schema.ObjectKind
SetName(string)
SetNamespace(string)
}

View File

@@ -70,7 +70,7 @@ func (a helmChartAdapter) asClientObject() client.Object {
return a.HelmChart
}
// sourcev1.ImagePolicyList
// sourcev1.HelmChartList
type helmChartListAdapter struct {
*sourcev1.HelmChartList

View File

@@ -19,26 +19,16 @@ package main
import (
"context"
"fmt"
"time"
appsv1 "k8s.io/api/apps/v1"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"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/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"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
@@ -51,13 +41,6 @@ type statusable interface {
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,
namespacedName types.NamespacedName, object statusable) wait.ConditionFunc {
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) {
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) {
func buildComponentObjectRefs(components ...string) ([]object.ObjMetadata, error) {
var objRefs []object.ObjMetadata
for _, deployment := range components {
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
}
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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -94,4 +94,29 @@ body {
.progress-0plus .progress-bar {
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%; }

View File

@@ -83,8 +83,9 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
* [flux create](flux_create.md) - Create or update sources and resources
* [flux delete](flux_delete.md) - Delete sources and resources
* [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 the resources and their status
* [flux install](flux_install.md) - Install or upgrade Flux
* [flux logs](flux_logs.md) - Display formatted logs for Flux components
* [flux reconcile](flux_reconcile.md) - Reconcile sources and resources
* [flux resume](flux_resume.md) - Resume suspended resources
* [flux suspend](flux_suspend.md) - Suspend resources

View File

@@ -12,7 +12,24 @@ The image that sorts highest according to the policy is recorded in
the status of the object.
```
flux create image policy <name> [flags]
flux create image policy [name] [flags]
```
### Examples
```
# Create an ImagePolicy to select the latest stable release
flux create image policy podinfo \
--image-ref=podinfo \
--select-semver=">=1.0.0"
# Create an ImagePolicy to select the latest main branch build tagged as "${GIT_BRANCH}-${GIT_SHA:0:7}-$(date +%s)"
flux create image policy podinfo \
--image-ref=podinfo \
--select-numeric=asc \
--filter-regex='^main-[a-f0-9]+-(?P<ts>[0-9]+)' \
--filter-extract='$ts'
```
### Options

View File

@@ -8,7 +8,7 @@ The create image repository command generates an ImageRepository resource.
An ImageRepository object specifies an image repository to scan.
```
flux create image repository <name> [flags]
flux create image repository [name] [flags]
```
### Examples

View File

@@ -9,7 +9,31 @@ An ImageUpdateAutomation object specifies an automated update to images
mentioned in YAMLs in a git repository.
```
flux create image update <name> [flags]
flux create image update [name] [flags]
```
### Examples
```
# Configure image updates for the main repository created by flux bootstrap
flux create image update flux-system \
--git-repo-ref=flux-system \
--git-repo-path="./clusters/my-cluster" \
--checkout-branch=main \
--author-name=flux \
--author-email=flux@example.com \
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
# Configure image updates to push changes to a different branch, if the branch doesn't exists it will be created
flux create image update flux-system \
--git-repo-ref=flux-system \
--git-repo-path="./clusters/my-cluster" \
--checkout-branch=main \
--push-branch=image-updates \
--author-name=flux \
--author-email=flux@example.com \
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
```
### Options
@@ -17,10 +41,12 @@ flux create image update <name> [flags]
```
--author-email string the email to use for commit author
--author-name string the name to use for commit author
--branch string the branch to checkout and push commits to
--checkout-branch string the branch to checkout
--commit-template string a template for commit messages
--git-repo-ref string the name of a GitRepository resource with details of the upstream git repository
--git-repo-path string path to the directory containing the manifests to be updated, defaults to the repository root
--git-repo-ref string the name of a GitRepository resource with details of the upstream Git repository
-h, --help help for update
--push-branch string the branch to push commits to, defaults to the checkout branch if not specified
```
### Options inherited from parent commands

View File

@@ -4,7 +4,7 @@ Export Bucket sources in YAML format
### Synopsis
The export source git command exports on or all Bucket sources in YAML format.
The export source git command exports one or all Bucket sources in YAML format.
```
flux export source bucket [name] [flags]

View File

@@ -4,7 +4,7 @@ Export GitRepository sources in YAML format
### Synopsis
The export source git command exports on or all GitRepository sources in YAML format.
The export source git command exports one or all GitRepository sources in YAML format.
```
flux export source git [name] [flags]

View File

@@ -4,7 +4,7 @@ Export HelmRepository sources in YAML format
### Synopsis
The export source git command exports on or all HelmRepository sources in YAML format.
The export source git command exports one or all HelmRepository sources in YAML format.
```
flux export source helm [name] [flags]

View File

@@ -1,10 +1,10 @@
## flux get
Get sources and resources
Get the resources and their status
### Synopsis
The get sub-commands print the statuses of sources and resources.
The get sub-commands print the statuses of Flux resources.
### Options

View File

@@ -37,5 +37,5 @@ flux get alert-providers [flags]
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get](flux_get.md) - Get the resources and their status

View File

@@ -37,5 +37,5 @@ flux get alerts [flags]
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get](flux_get.md) - Get the resources and their status

View File

@@ -37,5 +37,5 @@ flux get helmreleases [flags]
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get](flux_get.md) - Get the resources and their status

View File

@@ -25,7 +25,8 @@ The get image sub-commands print the status of image automation objects.
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get](flux_get.md) - Get the resources and their status
* [flux get images all](flux_get_images_all.md) - Get all image statuses
* [flux get images policy](flux_get_images_policy.md) - Get ImagePolicy status
* [flux get images repository](flux_get_images_repository.md) - Get ImageRepository status
* [flux get images update](flux_get_images_update.md) - Get ImageUpdateAutomation status

View File

@@ -0,0 +1,44 @@
## flux get images all
Get all image statuses
### Synopsis
The get image sub-commands print the statuses of all image objects.
```
flux get images all [flags]
```
### Examples
```
# List all image objects in a namespace
flux get images all --namespace=flux-system
# List all image objects in all namespaces
flux get images all --all-namespaces
```
### Options
```
-h, --help help for all
```
### Options inherited from parent commands
```
-A, --all-namespaces list the requested object(s) across all namespaces
--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 get images](flux_get_images.md) - Get image automation object status

View File

@@ -37,5 +37,5 @@ flux get kustomizations [flags]
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get](flux_get.md) - Get the resources and their status

View File

@@ -37,5 +37,5 @@ flux get receivers [flags]
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get](flux_get.md) - Get the resources and their status

View File

@@ -25,7 +25,8 @@ The get source sub-commands print the statuses of the sources.
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get](flux_get.md) - Get the resources and their status
* [flux get sources all](flux_get_sources_all.md) - Get all source statuses
* [flux get sources bucket](flux_get_sources_bucket.md) - Get Bucket source statuses
* [flux get sources chart](flux_get_sources_chart.md) - Get HelmChart statuses
* [flux get sources git](flux_get_sources_git.md) - Get GitRepository source statuses

View File

@@ -0,0 +1,44 @@
## flux get sources all
Get all source statuses
### Synopsis
The get sources all command print the statuses of all sources.
```
flux get sources all [flags]
```
### Examples
```
# List all sources in a namespace
flux get sources all --namespace=flux-system
# List all sources in all namespaces
flux get sources all --all-namespaces
```
### Options
```
-h, --help help for all
```
### Options inherited from parent commands
```
-A, --all-namespaces list the requested object(s) across all namespaces
--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 get sources](flux_get_sources.md) - Get source statuses

56
docs/cmd/flux_logs.md Normal file
View File

@@ -0,0 +1,56 @@
## flux logs
Display formatted logs for Flux components
### Synopsis
The logs command displays formatted logs from various Flux components.
```
flux logs [flags]
```
### Examples
```
# Print the reconciliation logs of all Flux custom resources in your cluster
flux logs --all-namespaces
# Stream logs for a particular log level
flux logs --follow --level=error --all-namespaces
# Filter logs by kind, name and namespace
flux logs --kind=Kustomization --name=podinfo --namespace=default
# Print logs when Flux is installed in a different namespace than flux-system
flux logs --flux-namespace=my-namespace
```
### 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

View File

@@ -8,6 +8,8 @@ repository when new container images are available.
- The image-automation-controller updates YAML files based on the latest images scanned, and commits
the changes to a given Git repository.
![](../../_files/image-update-automation.png)
Links:
- Source code [fluxcd/image-reflector-controller](https://github.com/fluxcd/image-reflector-controller)

View File

@@ -28,7 +28,7 @@ is produced.
All sources are specified as Custom Resources in a Kubernetes cluster, examples
of sources are `GitRepository`, `HelmRepository` and `Bucket` resources.
For more information, take a look at [the source controller documentation](../components/source/source.md).
For more information, take a look at [the source controller documentation](../components/source/controller.md).
## Reconciliation

View File

@@ -431,8 +431,8 @@ spec:
```
!!! hint
If you are using the same image repository in several manifests, you only need one
`ImageRepository` object for it.
If you are using the same image repository in several manifests, you only need one
`ImageRepository` object for it.
##### Using image registry credentials for scanning

View File

@@ -232,7 +232,7 @@ podinfo True Latest image tag for 'ghcr.io/stefanprodan/podinfo' resolved to: 5
## Configure image updates
Edit the `podinfo-deploy.yaml` and add a marker to tell Flux which policy to use when updating the container image:
Edit the `podinfo-deployment.yaml` and add a marker to tell Flux which policy to use when updating the container image:
```yaml
spec:
@@ -247,9 +247,12 @@ Create an `ImageUpdateAutomation` to tell Flux which Git repository to write ima
flux create image update flux-system \
--git-repo-ref=flux-system \
--branch=main \
--git-repo-path="./clusters/my-cluster" \
--checkout-branch=main \
--push-branch=main \
--author-name=fluxcdbot \
--author-email=fluxcdbot@users.noreply.github.com \
--commit-template="[ci skip] update image" \
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}" \
--export > ./clusters/my-cluster/flux-system-automation.yaml
```
@@ -269,9 +272,12 @@ spec:
commit:
authorEmail: fluxcdbot@users.noreply.github.com
authorName: fluxcdbot
messageTemplate: '[ci skip] update image'
messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
interval: 1m0s
push:
branch: main
update:
path: ./clusters/my-cluster
strategy: Setters
```
@@ -306,6 +312,12 @@ $ watch "kubectl get deployment/podinfo -oyaml | grep 'image:'"
image: ghcr.io/stefanprodan/podinfo:5.0.3
```
You can check the status of the image automation objects with:
```sh
flux get images all --all-namespaces
```
## Configure image update for custom resources
Besides Kubernetes native kinds (Deployment, StatefulSet, DaemonSet, CronJob),
@@ -374,6 +386,68 @@ images:
newTag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo:tag"}
```
## Push updates to a different branch
With `.spec.push.branch` you can configure Flux to push the image updates to different branch
than the one used for checkout. If the specified branch doesn't exist, Flux will create it for you.
```yaml
apiVersion: image.toolkit.fluxcd.io/v1alpha1
kind: ImageUpdateAutomation
metadata:
name: flux-system
spec:
checkout:
branch: main
gitRepositoryRef:
name: flux-system
push:
branch: image-updates
```
You can use CI automation e.g. GitHub Actions such as
[create-pull-request](https://github.com/peter-evans/create-pull-request)
to open a pull request against the checkout branch.
This way you can manually approve the image updates before they are applied on your clusters.
## Configure the commit message
The `.spec.commit.messageTemplate` field is a string which is used as a template for the commit message.
The message template is a [Go text template](https://golang.org/pkg/text/template/) that
lets you range over the objects and images e.g.:
```yaml
apiVersion: image.toolkit.fluxcd.io/v1alpha1
kind: ImageUpdateAutomation
metadata:
name: flux-system
spec:
commit:
messsageTemplate: |
Automated image update
Automation name: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Updated.Files -}}
- {{ $filename }}
{{ end -}}
Objects:
{{ range $resource, $_ := .Updated.Objects -}}
- {{ $resource.Kind }} {{ $resource.Name }}
{{ end -}}
Images:
{{ range .Updated.Images -}}
- {{.}}
{{ end -}}
authorEmail: flux@example.com
authorName: flux
```
## Trigger image updates with webhooks
You may want to trigger a deployment

View File

@@ -11,7 +11,7 @@ toolkit controllers installed on it.
Please see the [get started guide](../get-started/index.md)
or the [installation guide](installation.md).
Install [gnupg](https://www.gnupg.org/) and [sops](https://github.com/mozilla/sops):
Install [gnupg](https://www.gnupg.org/) and [SOPS](https://github.com/mozilla/sops):
```sh
brew install gnupg sops
@@ -19,38 +19,144 @@ brew install gnupg sops
## Generate a GPG key
Generate a GPG key with OpenPGP without specifying a passphrase:
Generate a GPG/OpenPGP key with no passphrase (`%no-protection`):
```console
$ gpg --full-generate-key
```sh
export KEY_NAME="cluster0.yourdomain.com"
export KEY_COMMENT="flux secrets"
Real name: stefanprodan
Email address: stefanprodan@users.noreply.github.com
Comment:
You selected this USER-ID:
"stefanprodan <stefanprodan@users.noreply.github.com>"
gpg --batch --full-generate-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 4096
Subkey-Type: 1
Subkey-Length: 4096
Expire-Date: 0
Name-Comment: ${KEY_COMMENT}
Name-Real: ${KEY_NAME}
EOF
```
Retrieve the GPG key ID (second row of the sec column):
The above configuration creates an rsa4096 key that does not expire.
For a full list of options to consider for your environment, see [Unattended GPG key generation](https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html).
```console
$ gpg --list-secret-keys stefanprodan@users.noreply.github.com
Retrieve the GPG key fingerprint (second row of the sec column):
sec rsa3072 2020-09-06 [SC]
```sh
gpg --list-secret-keys "${KEY_NAME}"
sec rsa4096 2020-09-06 [SC]
1F3D1CED2F865F5E59CA564553241F147E7C5FA4
```
Store the key fingerprint as an environment variable:
```sh
export KEY_FP=1F3D1CED2F865F5E59CA564553241F147E7C5FA4
```
Export the public and private keypair from your local GPG keyring and
create a Kubernetes secret named `sops-gpg` in the `flux-system` namespace:
```sh
gpg --export-secret-keys \
--armor 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 |
gpg --export-secret-keys --armor "${KEY_FP}" |
kubectl create secret generic sops-gpg \
--namespace=flux-system \
--from-file=sops.asc=/dev/stdin
```
It's a good idea to back up this secret-key/K8s-Secret with a password manager or offline storage.
Also consider deleting the secret decryption key from you machine:
```sh
gpg --delete-secret-keys "${KEY_FP}"
```
## Configure in-cluster secrets decryption
Register the Git repository on your cluster:
```sh
flux create source git my-secrets \
--url=https://github.com/my-org/my-secrets
```
Create a kustomization for reconciling the secrets on the cluster:
```sh
flux create kustomization my-secrets \
--source=my-secrets \
--path=./clusters/cluster0 \
--prune=true \
--interval=10m \
--decryption-provider=sops \
--decryption-secret=sops-gpg
```
Note that the `sops-gpg` can contain more than one key, SOPS will try to decrypt the
secrets by iterating over all the private keys until it finds one that works.
## Optional: Export the public key into the Git directory
Commit the public key to the repository so that team members who clone the repo can encrypt new files:
```sh
gpg --export --armor "${KEY_FP}" > ./clusters/cluster0/.sops.pub.asc
```
Check the file contents to ensure it's the public key before adding it to the repo and committing.
```sh
git add ./clusters/cluster0/.sops.pub.asc
git commit -am 'Share GPG public key for secrets generation'
```
Team members can then import this key when they pull the Git repository:
```sh
gpg --import ./clusters/cluster0/.sops.pub.asc
```
!!! hint
The public key is sufficient for creating brand new files.
The secret key is required for decrypting and editing existing files because SOPS computes a MAC on all values.
When using solely the public key to add or remove a field, the whole file should be deleted and recreated.
## Configure the Git directory for encryption
Write a [SOPS config file](https://github.com/mozilla/sops#using-sops-yaml-conf-to-select-kms-pgp-for-new-files) to the specific cluster or namespace directory used
to store encrypted objects with this particular GPG key's fingerprint.
```yaml
cat <<EOF > ./clusters/cluster0/.sops.yaml
creation_rules:
- path_regex: .*.yaml
encrypted_regex: ^(data|stringData)$
pgp: ${KEY_FP}
EOF
```
This config applies recursively to all sub-directories.
Multiple directories can use separate SOPS configs.
Contributors using the `sops` CLI to create and encrypt files
won't have to worry about specifying the proper key for the target cluster or namespace.
`encrypted_regex` helps encrypt the the proper `data` and `stringData` fields for Secrets.
You may wish to add other fields if you are encrypting other types of Objects.
!!! hint
Note that you should encrypt only the `data` or `stringData` section. Encrypting the Kubernetes
secret metadata, kind or apiVersion is not supported by kustomize-controller.
Ignore all `.sops.yaml` files in a [`.sourceignore`](../components/source/gitrepositories#excluding-files) file at the root of your repo.
```sh
touch .sourceignore
echo '**/.sops.yaml' >> .sourceignore
```
You can now commit your SOPS config.
## Encrypt secrets
Generate a Kubernetes secret manifest with kubectl:
@@ -63,47 +169,17 @@ kubectl -n default create secret generic basic-auth \
-o yaml > basic-auth.yaml
```
Encrypt the secret with sops using your GPG key:
Encrypt the secret with SOPS using your GPG key:
```sh
sops --encrypt \
--pgp=1F3D1CED2F865F5E59CA564553241F147E7C5FA4 \
--encrypted-regex '^(data|stringData)$' \
--in-place basic-auth.yaml
sops --encrypt --in-place basic-auth.yaml
```
!!! hint
Note that you should encrypt only the `data` section. Encrypting the Kubernetes
secret metadata, kind or apiVersion is not supported by kustomize-controller.
You can now commit the encrypted secret to your Git repository.
!!! hint
Note that you shouldn't apply the encrypted secrets onto the cluster with kubectl. SOPS encrypted secrets are designed to be consumed by kustomize-controller.
## Configure secrets decryption
Registry the Git repository on your cluster:
```sh
flux create source git my-secrets \
--url=https://github.com/my-org/my-secrets
```
Create a kustomization for reconciling the secrets on the cluster:
```sh
flux create kustomization my-secrets \
--source=my-secrets \
--prune=true \
--interval=10m \
--decryption-provider=sops \
--decryption-secret=sops-gpg
```
Note that the `sops-gpg` can contain more than one key, sops will try to decrypt the
secrets by iterating over all the private keys until it finds one that works.
### Using various cloud providers
When using AWS/GCP KMS, you don't have to include the gpg `secretRef` under
@@ -210,5 +286,5 @@ Once the manifests have been pushed to the Git repository, the following happens
* source-controller pulls the changes from Git
* kustomize-controller loads the GPG keys from the `sops-pgp` secret
* kustomize-controller decrypts the Kubernetes secrets with sops and applies them on the cluster
* kustomize-controller decrypts the Kubernetes secrets with SOPS and applies them on the cluster
* kubelet creates the pods and mounts the secret as a volume or env variable inside the app container

View 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 dont 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.

View File

@@ -4,6 +4,7 @@
The Flux 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.
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))
are considered production ready:

16
go.mod
View File

@@ -5,18 +5,18 @@ go 1.16
require (
github.com/Masterminds/semver/v3 v3.1.0
github.com/cyphar/filepath-securejoin v0.2.2
github.com/fluxcd/helm-controller/api v0.8.1
github.com/fluxcd/image-automation-controller/api v0.6.1
github.com/fluxcd/image-reflector-controller/api v0.7.0
github.com/fluxcd/kustomize-controller/api v0.9.1
github.com/fluxcd/notification-controller/api v0.9.0
github.com/fluxcd/helm-controller/api v0.8.2
github.com/fluxcd/image-automation-controller/api v0.7.0
github.com/fluxcd/image-reflector-controller/api v0.7.1
github.com/fluxcd/kustomize-controller/api v0.9.3
github.com/fluxcd/notification-controller/api v0.10.0
github.com/fluxcd/pkg/apis/meta v0.8.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/untar v0.0.5
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/manifoldco/promptui v0.7.0
github.com/olekukonko/tablewriter v0.0.4
@@ -29,7 +29,7 @@ require (
k8s.io/cli-runtime v0.20.2 // indirect
k8s.io/client-go v0.20.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/yaml v1.2.0
)

34
go.sum
View File

@@ -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/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
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.1/go.mod h1:cFceNc/mOBa+Qi3NE8NDY2w3FAEectauTm8c10mcBis=
github.com/fluxcd/image-automation-controller/api v0.6.1 h1:LgjjNYXrVojfgjit37GA0SDYre3AaDabYzT7L6lWO7I=
github.com/fluxcd/image-automation-controller/api v0.6.1/go.mod h1:8Q/baOONPrSJFMq7+zxp/t2WGrqVFRUx4HnTrg37pNE=
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.0/go.mod h1:KHWknF2xu/GZ4uLSQcAmfONZYjsbwNqyk3OvMQTmMsA=
github.com/fluxcd/kustomize-controller/api v0.9.1 h1:o6cxtLiXUdEeTJMxoeoLdld7hsgf7L4mNO6+i2MD2U8=
github.com/fluxcd/kustomize-controller/api v0.9.1/go.mod h1:VhUwaSsgrXVgO8Qcx6ZO0isqb5TpDgbyyitCeXYqSM4=
github.com/fluxcd/notification-controller/api v0.9.0 h1:aEIZu01EHlDH7I8/TyOkvMknlDV8NBNhuZ9cMQ8Kp0Q=
github.com/fluxcd/notification-controller/api v0.9.0/go.mod h1:nJqSGiecNkJLxuO2KWMu5YUTLaYT/A57854FMm4oX9Q=
github.com/fluxcd/helm-controller/api v0.8.2 h1:ELSC6dal01jtzn8B6ffArNklbul9/k9lpEd6msefVAE=
github.com/fluxcd/helm-controller/api v0.8.2/go.mod h1:WDVuo3g6n3eZy8l5U/Zqo0aL+LcFV1C/HoNAUzWLtzU=
github.com/fluxcd/image-automation-controller/api v0.7.0 h1:mLaELYT52/FpZ93Mr+QMSK8UT0OBVQT4oA9kxO8NiEk=
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.1 h1:Cng36D1J25WYZ0ZB6dwzDtGR9MIyIcSUMYxHpb0IYXA=
github.com/fluxcd/image-reflector-controller/api v0.7.1/go.mod h1:J18L71jiHYrAu2dg0tgOkOjP+GtQldC1oslhTeX0jqc=
github.com/fluxcd/kustomize-controller/api v0.9.3 h1:VbeU97pmx3vmgverqZIRyyBm1IKyPBZZAIo7mc3fZ+8=
github.com/fluxcd/kustomize-controller/api v0.9.3/go.mod h1:MDTwohIXqbId3qbhVNF7lAYLSBMzxq5MHINFN4bqDRs=
github.com/fluxcd/notification-controller/api v0.10.0 h1:7mxeBPnFzpL4Z+X5YiytQRzaDKrryb6TIQkC9ASJO28=
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/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/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/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.3/go.mod h1:AM/hMD0mKtRqhKPU7NGDzm+3UXPpdnX8oBlcxLt11AY=
github.com/fluxcd/pkg/runtime v0.8.4/go.mod h1:JD0eZIn5xkTeHHQUWXSqJPIh/ecO0d0qrUKbSVHnpnw=
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/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/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
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/source-controller/api v0.9.0 h1:ohV8AvmvkUK0N7+YKPIOlMSLaNG0SpFcNLtlmW18xuM=
github.com/fluxcd/source-controller/api v0.9.0/go.mod h1:68+cPuz1G45f0SDRwEfTL419011ffveLIDA9nssLlkU=
github.com/fluxcd/source-controller/api v0.9.1 h1:kaL+tBflccsuj3NDESPPQyKXlZXlAgyNoT2nYY02JAE=
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/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=
@@ -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/go.mod h1:unl8itcwGPqo41QSyksbXTWFbfMqap1o/4oiUxPnQfw=
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.2/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
sigs.k8s.io/controller-runtime v0.8.3 h1:GMHvzjTmaWHQB8HadW+dIvBoJuLvZObYJ5YoZruPRao=
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/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
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.1/helm-controller.deployment.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.2/helm-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
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.6.1/image-automation-controller.deployment.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.7.0/image-automation-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
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.0/image-reflector-controller.deployment.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.1/image-reflector-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
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.2/kustomize-controller.deployment.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.3/kustomize-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
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.9.0/notification-controller.deployment.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.10.0/notification-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
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.0/source-controller.deployment.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.1/source-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Copyright 2020 The Flux authors. All rights reserved.
# Copyright 2020, 2021 The Flux authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
set -e
REPO_ROOT=$(git rev-parse --show-toplevel)
OUT_PATH=${1:-"${REPO_ROOT}/cmd/flux/manifests"}
TAR=${2}
IN_PATH=${1:-"$(git rev-parse --show-toplevel)/manifests"}
OUT_PATH=${2:-"$(git rev-parse --show-toplevel)/cmd/flux/manifests"}
TAR=${3}
info() {
echo '[INFO] ' "$@"
@@ -45,20 +45,20 @@ files=""
info using "$(kustomize version --short)"
# build controllers
for controller in ${REPO_ROOT}/manifests/bases/*/; do
for controller in ${IN_PATH}/bases/*/; do
output_path="${OUT_PATH}/$(basename $controller).yaml"
build $controller $output_path
files+=" $(basename $output_path)"
done
# build rbac
rbac_path="${REPO_ROOT}/manifests/rbac"
rbac_path="${IN_PATH}/rbac"
rbac_output_path="${OUT_PATH}/rbac.yaml"
build $rbac_path $rbac_output_path
files+=" $(basename $rbac_output_path)"
# build policies
policies_path="${REPO_ROOT}/manifests/policies"
policies_path="${IN_PATH}/policies"
policies_output_path="${OUT_PATH}/policies.yaml"
build $policies_path $policies_output_path
files+=" $(basename $policies_output_path)"

View File

@@ -26,31 +26,34 @@ plugins:
markdown_extensions:
- admonition
- meta
- codehilite:
guess_lang: false
- toc:
permalink: true
- footnotes
- 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:
highlight_code: true
- pymdownx.tabbed
- pymdownx.tilde
- pymdownx.progressbar
- pymdownx.tasklist
- pymdownx.superfences
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
- pymdownx.tilde
- toc:
permalink: true
nav:
- Introduction: index.md
- Core Concepts: core-concepts/index.md
- Get Started: get-started/index.md
- Migration:
- Migrate from Flux v1: guides/flux-v1-migration.md
- Migrate from Flux v1 image update automation: guides/flux-v1-automation-migration.md
- Migrate from the Helm Operator: guides/helm-operator-migration.md
- FAQ: guides/faq-migration.md
- Migration and Support Timetable: migration/timetable.md
- Migrate from Flux v1: guides/flux-v1-migration.md
- Migrate from Flux v1 image update automation: guides/flux-v1-automation-migration.md
- Migrate from the Helm Operator: guides/helm-operator-migration.md
- FAQ: guides/faq-migration.md
- Guides:
- Installation: guides/installation.md
- Manage Helm Releases: guides/helmreleases.md
@@ -145,6 +148,7 @@ nav:
- Get kustomizations: cmd/flux_get_kustomizations.md
- Get helmreleases: cmd/flux_get_helmreleases.md
- Get sources: cmd/flux_get_sources.md
- Get sources all: cmd/flux_get_sources_all.md
- Get sources git: cmd/flux_get_sources_git.md
- Get sources helm: cmd/flux_get_sources_helm.md
- Get sources chart: cmd/flux_get_sources_chart.md
@@ -154,10 +158,12 @@ nav:
- Get alert providers: cmd/flux_get_alert-providers.md
- Get receivers: cmd/flux_get_receivers.md
- Get images: cmd/flux_get_images.md
- Get images all: cmd/flux_get_images_all.md
- Get images policy: cmd/flux_get_images_policy.md
- Get images repository: cmd/flux_get_images_repository.md
- Get images update: cmd/flux_get_images_update.md
- Install: cmd/flux_install.md
- Logs: cmd/flux_logs.md
- Resume: cmd/flux_resume.md
- Resume kustomization: cmd/flux_resume_kustomization.md
- Resume helmrelease: cmd/flux_resume_helmrelease.md

View File

@@ -22,7 +22,7 @@ type Logger interface {
Generatef(format string, a ...interface{})
// Waitingf logs a formatted waiting message.
Waitingf(format string, a ...interface{})
// Waitingf logs a formatted success message.
// Successf logs a formatted success message.
Successf(format string, a ...interface{})
// Failuref logs a formatted failure message.
Failuref(format string, a ...interface{})

109
pkg/status/status.go Normal file
View 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()
}
}
}