<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Flux – Toolkit Dev Guides</title><link>https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/</link><description>Recent content in Toolkit Dev Guides on Flux</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/index.xml" rel="self" type="application/rss+xml"/><item><title>Flux: Using the GitOps Toolkit APIs with Go</title><link>https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/packages/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/packages/</guid><description>
&lt;p>While you can use the GitOps Toolkit APIs in a declarative manner with &lt;code>kubectl apply&lt;/code>,
we provide client library code for all our toolkit APIs that makes it easier to access them from Go.&lt;/p>
&lt;h2 id="go-packages">Go Packages&lt;/h2>
&lt;p>The GitOps Toolkit Go modules and controllers are released by following the
&lt;a href="https://semver.org" target="_blank">semver&lt;/a> conventions.&lt;/p>
&lt;p>The API schema definitions modules have the following dependencies:&lt;/p>
&lt;ul>
&lt;li>
&lt;a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta" target="_blank">github.com/fluxcd/pkg/apis/meta&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://pkg.go.dev/github.com/fluxcd/pkg/runtime" target="_blank">github.com/fluxcd/pkg/runtime&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://pkg.go.dev/k8s.io/apimachinery" target="_blank">k8s.io/apimachinery&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://pkg.go.dev/sigs.k8s.io/controller-runtime" target="_blank">sigs.k8s.io/controller-runtime&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>The APIs can be consumed with the
&lt;a href="https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client" target="_blank">controller-runtime client&lt;/a>.&lt;/p>
&lt;h3 id="sourcetoolkitfluxcdio">source.toolkit.fluxcd.io&lt;/h3>
&lt;p>Download package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>go get github.com/fluxcd/source-controller/api
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Import package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> sourcev1 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/source-controller/api/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>API Types&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Version&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/gitrepositories/">GitRepository&lt;/a>&lt;/td>
&lt;td>v1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/helmrepositories/">HelmRepository&lt;/a>&lt;/td>
&lt;td>v1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/helmcharts/">HelmChart&lt;/a>&lt;/td>
&lt;td>v1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/ocirepositories/">OCIRepository&lt;/a>&lt;/td>
&lt;td>v1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/buckets/">Bucket&lt;/a>&lt;/td>
&lt;td>v1&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="kustomizetoolkitfluxcdio">kustomize.toolkit.fluxcd.io&lt;/h3>
&lt;p>Download package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>go get github.com/fluxcd/kustomize-controller/api
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Import package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> kustomizev1 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/kustomize-controller/api/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>API Types&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Version&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/kustomize/kustomizations/">Kustomization&lt;/a>&lt;/td>
&lt;td>v1&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="helmtoolkitfluxcdio">helm.toolkit.fluxcd.io&lt;/h3>
&lt;p>Download package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>go get github.com/fluxcd/helm-controller/api
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Import package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> helmv2 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/helm-controller/api/v2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>API Types&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Version&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/helm/helmreleases/">HelmRelease&lt;/a>&lt;/td>
&lt;td>v2&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="notificationtoolkitfluxcdio">notification.toolkit.fluxcd.io&lt;/h3>
&lt;p>Download package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>go get github.com/fluxcd/notification-controller/api
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Import package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> notificationv1b3 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/notification-controller/api/v1beta3&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>and for &lt;code>Receiver&lt;/code> objects:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> notificationv1 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/notification-controller/api/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>API Types&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Version&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/notification/receivers/">Receiver&lt;/a>&lt;/td>
&lt;td>v1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/notification/providers/">Provider&lt;/a>&lt;/td>
&lt;td>v1beta3&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/notification/alerts/">Alert&lt;/a>&lt;/td>
&lt;td>v1beta3&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="imagetoolkitfluxcdio">image.toolkit.fluxcd.io&lt;/h3>
&lt;p>Download package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>go get github.com/fluxcd/image-reflector-controller/api
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>go get github.com/fluxcd/image-automation-controller/api
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Import package&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> imagev1 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/image-reflector-controller/api/v1beta2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> autov1 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/image-automation-controller/api/v1beta2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>API Types&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Name&lt;/th>
&lt;th>Version&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/image/imagerepositories/">ImageRepository&lt;/a>&lt;/td>
&lt;td>v1beta2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/image/imagepolicies/">ImagePolicy&lt;/a>&lt;/td>
&lt;td>v1beta2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/image/imageupdateautomations/">ImageUpdateAutomation&lt;/a>&lt;/td>
&lt;td>v1beta2&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="crud-example">CRUD Example&lt;/h2>
&lt;p>Here is an example of how to create a Helm release, wait for it to install, then delete it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">package&lt;/span> main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;context&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;time&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> apiextensionsv1 &lt;span style="color:#4070a0">&amp;#34;k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;k8s.io/apimachinery/pkg/api/meta&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> metav1 &lt;span style="color:#4070a0">&amp;#34;k8s.io/apimachinery/pkg/apis/meta/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;k8s.io/apimachinery/pkg/runtime&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;k8s.io/apimachinery/pkg/types&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;k8s.io/apimachinery/pkg/util/wait&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _ &lt;span style="color:#4070a0">&amp;#34;k8s.io/client-go/plugin/pkg/client/auth&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ctrl &lt;span style="color:#4070a0">&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4070a0">&amp;#34;sigs.k8s.io/controller-runtime/pkg/client&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> helmv2 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/helm-controller/api/v2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> apimeta &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/pkg/apis/meta&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sourcev1 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/source-controller/api/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">func&lt;/span> &lt;span style="color:#06287e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// register the GitOps Toolkit schema definitions
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> scheme &lt;span style="color:#666">:=&lt;/span> runtime.&lt;span style="color:#06287e">NewScheme&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _ = sourcev1.&lt;span style="color:#06287e">AddToScheme&lt;/span>(scheme)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _ = helmv2.&lt;span style="color:#06287e">AddToScheme&lt;/span>(scheme)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// init Kubernetes client
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> kubeClient, err &lt;span style="color:#666">:=&lt;/span> client.&lt;span style="color:#06287e">New&lt;/span>(ctrl.&lt;span style="color:#06287e">GetConfigOrDie&lt;/span>(), client.Options{Scheme: scheme})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020">panic&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// set a deadline for the Kubernetes API operations
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> ctx, cancel &lt;span style="color:#666">:=&lt;/span> context.&lt;span style="color:#06287e">WithTimeout&lt;/span>(context.&lt;span style="color:#06287e">Background&lt;/span>(), &lt;span style="color:#40a070">60&lt;/span>&lt;span style="color:#666">*&lt;/span>time.Second)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">defer&lt;/span> &lt;span style="color:#06287e">cancel&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// create a Helm repository pointing to Bitnami
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> helmRepository &lt;span style="color:#666">:=&lt;/span> &lt;span style="color:#666">&amp;amp;&lt;/span>sourcev1.HelmRepository{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ObjectMeta: metav1.ObjectMeta{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Name: &lt;span style="color:#4070a0">&amp;#34;bitnami&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Namespace: &lt;span style="color:#4070a0">&amp;#34;default&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Spec: sourcev1.HelmRepositorySpec{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> URL: &lt;span style="color:#4070a0">&amp;#34;https://charts.bitnami.com/bitnami&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Interval: metav1.Duration{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Duration: &lt;span style="color:#40a070">30&lt;/span> &lt;span style="color:#666">*&lt;/span> time.Minute,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> kubeClient.&lt;span style="color:#06287e">Create&lt;/span>(ctx, helmRepository); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#007020;font-weight:bold">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;HelmRepository bitnami created&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// create a Helm release for nginx
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> helmRelease &lt;span style="color:#666">:=&lt;/span> &lt;span style="color:#666">&amp;amp;&lt;/span>helmv2.HelmRelease{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ObjectMeta: metav1.ObjectMeta{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Name: &lt;span style="color:#4070a0">&amp;#34;nginx&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Namespace: &lt;span style="color:#4070a0">&amp;#34;default&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Spec: helmv2.HelmReleaseSpec{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ReleaseName: &lt;span style="color:#4070a0">&amp;#34;nginx&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Interval: metav1.Duration{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Duration: &lt;span style="color:#40a070">5&lt;/span> &lt;span style="color:#666">*&lt;/span> time.Minute,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Chart: helmv2.HelmChartTemplate{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Spec: helmv2.HelmChartTemplateSpec{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Chart: &lt;span style="color:#4070a0">&amp;#34;nginx&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Version: &lt;span style="color:#4070a0">&amp;#34;8.x&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> SourceRef: helmv2.CrossNamespaceObjectReference{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Kind: sourcev1.HelmRepositoryKind,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Name: &lt;span style="color:#4070a0">&amp;#34;bitnami&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Values: &lt;span style="color:#666">&amp;amp;&lt;/span>apiextensionsv1.JSON{Raw: []&lt;span style="color:#007020">byte&lt;/span>(&lt;span style="color:#4070a0">`{&amp;#34;service&amp;#34;: {&amp;#34;type&amp;#34;: &amp;#34;ClusterIP&amp;#34;}}`&lt;/span>)},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> kubeClient.&lt;span style="color:#06287e">Create&lt;/span>(ctx, helmRelease); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#007020;font-weight:bold">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;HelmRelease nginx created&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// wait for the a Helm release to be reconciled
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;Waiting for nginx to be installed&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> wait.&lt;span style="color:#06287e">PollImmediate&lt;/span>(&lt;span style="color:#40a070">2&lt;/span>&lt;span style="color:#666">*&lt;/span>time.Second, &lt;span style="color:#40a070">1&lt;/span>&lt;span style="color:#666">*&lt;/span>time.Minute,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">func&lt;/span>() (done &lt;span style="color:#902000">bool&lt;/span>, err &lt;span style="color:#902000">error&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> namespacedName &lt;span style="color:#666">:=&lt;/span> types.NamespacedName{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Namespace: helmRelease.&lt;span style="color:#06287e">GetNamespace&lt;/span>(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Name: helmRelease.&lt;span style="color:#06287e">GetName&lt;/span>(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> kubeClient.&lt;span style="color:#06287e">Get&lt;/span>(ctx, namespacedName, helmRelease); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> &lt;span style="color:#007020;font-weight:bold">false&lt;/span>, err
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> meta.&lt;span style="color:#06287e">IsStatusConditionTrue&lt;/span>(helmRelease.Status.Conditions, apimeta.ReadyCondition), &lt;span style="color:#007020;font-weight:bold">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// print the reconciliation status
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(meta.&lt;span style="color:#06287e">FindStatusCondition&lt;/span>(helmRelease.Status.Conditions, apimeta.ReadyCondition).Message)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// uninstall the release and delete the repository
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> kubeClient.&lt;span style="color:#06287e">Delete&lt;/span>(ctx, helmRelease); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> kubeClient.&lt;span style="color:#06287e">Delete&lt;/span>(ctx, helmRepository); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#06287e">Println&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;Helm repository and release deleted&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For an example on how to build a Kubernetes controller that interacts with the GitOps Toolkit APIs see
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/source-watcher/">source-watcher&lt;/a>.&lt;/p></description></item><item><title>Flux: Watching for source changes</title><link>https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/source-watcher/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/source-watcher/</guid><description>
&lt;p>In this guide you&amp;rsquo;ll be developing a Kubernetes controller with
&lt;a href="https://github.com/kubernetes-sigs/kubebuilder" target="_blank">Kubebuilder&lt;/a>
that subscribes to
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/gitrepositories/">GitRepository&lt;/a>
events and reacts to revision changes by downloading the artifact produced by
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/">source-controller&lt;/a>.&lt;/p>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;p>On your dev machine install the following tools:&lt;/p>
&lt;ul>
&lt;li>go &amp;gt;= 1.22&lt;/li>
&lt;li>kubebuilder &amp;gt;= 3.0&lt;/li>
&lt;li>kind &amp;gt;= 0.22&lt;/li>
&lt;li>kubectl &amp;gt;= 1.29&lt;/li>
&lt;/ul>
&lt;h2 id="install-flux">Install Flux&lt;/h2>
&lt;p>Install the Flux CLI with Homebrew on macOS or Linux:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>brew install fluxcd/tap/flux
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Create a cluster for testing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>kind create cluster --name dev
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Verify that your dev machine satisfies the prerequisites with:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>flux check --pre
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Install source-controller on the dev cluster:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>flux install &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--namespace&lt;span style="color:#666">=&lt;/span>flux-system &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--network-policy&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#007020">false&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--components&lt;span style="color:#666">=&lt;/span>source-controller
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="clone-the-sample-controller">Clone the sample controller&lt;/h2>
&lt;p>You&amp;rsquo;ll be using
&lt;a href="https://github.com/fluxcd/source-watcher" target="_blank">fluxcd/source-watcher&lt;/a> as
a template for developing your own controller. The source-watcher was scaffolded with &lt;code>kubebuilder init&lt;/code>.&lt;/p>
&lt;p>Clone the source-watcher repository:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>git clone https://github.com/fluxcd/source-watcher
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">cd&lt;/span> source-watcher
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git checkout release/v1.3.x
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Build the controller:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>make
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="run-the-controller">Run the controller&lt;/h2>
&lt;p>Port forward to source-controller artifacts server:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>kubectl -n flux-system port-forward svc/source-controller 8181:80
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Export the local address as &lt;code>SOURCE_CONTROLLER_LOCALHOST&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">export&lt;/span> &lt;span style="color:#bb60d5">SOURCE_CONTROLLER_LOCALHOST&lt;/span>&lt;span style="color:#666">=&lt;/span>localhost:8181
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Run source-watcher locally:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>make run
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Create a Git source:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>flux create &lt;span style="color:#007020">source&lt;/span> git &lt;span style="color:#007020">test&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--url&lt;span style="color:#666">=&lt;/span>https://github.com/fluxcd/flux2 &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--ignore-paths&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#39;/*,!/manifests&amp;#39;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--tag&lt;span style="color:#666">=&lt;/span>v2.2.0
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The source-watcher will log the revision:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#666">{&lt;/span>&lt;span style="color:#4070a0">&amp;#34;level&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;info&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;ts&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;2024-05-14T16:43:42.703+0200&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;msg&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;New revision detected&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;controller&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;gitrepository&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;controllerGroup&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;source.toolkit.fluxcd.io&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;controllerKind&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;GitRepository&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;GitRepository&amp;#34;&lt;/span>:&lt;span style="color:#666">{&lt;/span>&lt;span style="color:#4070a0">&amp;#34;name&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;test&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;namespace&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;flux-system&amp;#34;&lt;/span>&lt;span style="color:#666">}&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;namespace&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;flux-system&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;name&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;test&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;reconcileID&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;ef0fe80e-3952-4835-ae9d-01760c4eadde&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;revision&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;v2.2.0@sha1:81606709114f6d16a432f9f4bfc774942f054327&amp;#34;&lt;/span>&lt;span style="color:#666">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Change the Git tag:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>flux create &lt;span style="color:#007020">source&lt;/span> git &lt;span style="color:#007020">test&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--url&lt;span style="color:#666">=&lt;/span>https://github.com/fluxcd/flux2 &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--ignore-paths&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#39;/*,!/manifests&amp;#39;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span>--tag&lt;span style="color:#666">=&lt;/span>v2.3.0
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And source-watcher will log the new revision:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#666">{&lt;/span>&lt;span style="color:#4070a0">&amp;#34;level&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;info&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;ts&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;2024-05-14T16:51:33.499+0200&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;msg&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;New revision detected&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;controller&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;gitrepository&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;controllerGroup&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;source.toolkit.fluxcd.io&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;controllerKind&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;GitRepository&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;GitRepository&amp;#34;&lt;/span>:&lt;span style="color:#666">{&lt;/span>&lt;span style="color:#4070a0">&amp;#34;name&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;test&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;namespace&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;flux-system&amp;#34;&lt;/span>&lt;span style="color:#666">}&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;namespace&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;flux-system&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;name&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;test&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;reconcileID&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;cc0f83bb-b7a0-4c19-a254-af9962ae39cd&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;revision&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;v2.3.0@sha1:658925c2c0e6c408597d907a8ebee06a9a6d7f30&amp;#34;&lt;/span>&lt;span style="color:#666">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The source-controller reports the revision under &lt;code>GitRepository.Status.Artifact.Revision&lt;/code> in the format: &lt;code>&amp;lt;branch|tag&amp;gt;@sha1:&amp;lt;commit&amp;gt;&lt;/code>.&lt;/p>
&lt;h2 id="how-it-works">How it works&lt;/h2>
&lt;p>The
&lt;a href="https://github.com/fluxcd/source-watcher/blob/main/controllers/gitrepository_watcher.go" target="_blank">GitRepositoryWatcher&lt;/a>
controller does the following:&lt;/p>
&lt;ul>
&lt;li>subscribes to &lt;code>GitRepository&lt;/code> events&lt;/li>
&lt;li>detects when the Git revision changes&lt;/li>
&lt;li>downloads and extracts the source artifact&lt;/li>
&lt;li>writes the extracted dir names to stdout&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">type&lt;/span> GitRepositoryWatcher &lt;span style="color:#007020;font-weight:bold">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> client.Client
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> HttpRetry &lt;span style="color:#902000">int&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> artifactFetcher &lt;span style="color:#666">*&lt;/span>fetch.ArchiveFetcher
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">func&lt;/span> (r &lt;span style="color:#666">*&lt;/span>GitRepositoryWatcher) &lt;span style="color:#06287e">SetupWithManager&lt;/span>(mgr ctrl.Manager) &lt;span style="color:#902000">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> r.artifactFetcher = fetch.&lt;span style="color:#06287e">NewArchiveFetcher&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> r.HttpRetry,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> tar.UnlimitedUntarSize,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> os.&lt;span style="color:#06287e">Getenv&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;SOURCE_CONTROLLER_LOCALHOST&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> ctrl.&lt;span style="color:#06287e">NewControllerManagedBy&lt;/span>(mgr).
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#06287e">For&lt;/span>(&lt;span style="color:#666">&amp;amp;&lt;/span>sourcev1.GitRepository{}, builder.&lt;span style="color:#06287e">WithPredicates&lt;/span>(GitRepositoryRevisionChangePredicate{})).
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#06287e">Complete&lt;/span>(r)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories,verbs=get;list;watch
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories/status,verbs=get
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">func&lt;/span> (r &lt;span style="color:#666">*&lt;/span>GitRepositoryWatcher) &lt;span style="color:#06287e">Reconcile&lt;/span>(ctx context.Context, req ctrl.Request) (ctrl.Result, &lt;span style="color:#902000">error&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log &lt;span style="color:#666">:=&lt;/span> ctrl.&lt;span style="color:#06287e">LoggerFrom&lt;/span>(ctx)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// get source object
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> &lt;span style="color:#007020;font-weight:bold">var&lt;/span> repository sourcev1.GitRepository
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> r.&lt;span style="color:#06287e">Get&lt;/span>(ctx, req.NamespacedName, &lt;span style="color:#666">&amp;amp;&lt;/span>repository); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> ctrl.Result{}, client.&lt;span style="color:#06287e">IgnoreNotFound&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> artifact &lt;span style="color:#666">:=&lt;/span> repository.Status.Artifact
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log.&lt;span style="color:#06287e">Info&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;New revision detected&amp;#34;&lt;/span>, &lt;span style="color:#4070a0">&amp;#34;revision&amp;#34;&lt;/span>, artifact.Revision)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// create tmp dir
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> tmpDir, err &lt;span style="color:#666">:=&lt;/span> os.&lt;span style="color:#06287e">MkdirTemp&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;&amp;#34;&lt;/span>, repository.Name)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> ctrl.Result{}, fmt.&lt;span style="color:#06287e">Errorf&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;failed to create temp dir, error: %w&amp;#34;&lt;/span>, err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">defer&lt;/span> os.&lt;span style="color:#06287e">RemoveAll&lt;/span>(tmpDir)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// download and extract artifact
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">:=&lt;/span> r.artifactFetcher.&lt;span style="color:#06287e">Fetch&lt;/span>(artifact.URL, artifact.Digest, tmpDir); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log.&lt;span style="color:#06287e">Error&lt;/span>(err, &lt;span style="color:#4070a0">&amp;#34;unable to fetch artifact&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> ctrl.Result{}, err
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// list artifact content
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> files, err &lt;span style="color:#666">:=&lt;/span> os.&lt;span style="color:#06287e">ReadDir&lt;/span>(tmpDir)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> ctrl.Result{}, fmt.&lt;span style="color:#06287e">Errorf&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;failed to list files, error: %w&amp;#34;&lt;/span>, err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// do something with the artifact content
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span> &lt;span style="color:#007020;font-weight:bold">for&lt;/span> _, f &lt;span style="color:#666">:=&lt;/span> &lt;span style="color:#007020;font-weight:bold">range&lt;/span> files {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log.&lt;span style="color:#06287e">Info&lt;/span>(&lt;span style="color:#4070a0">&amp;#34;Processing &amp;#34;&lt;/span> &lt;span style="color:#666">+&lt;/span> f.&lt;span style="color:#06287e">Name&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">return&lt;/span> ctrl.Result{}, &lt;span style="color:#007020;font-weight:bold">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To add the watcher to an existing project, copy the controller and the revision change predicate to your &lt;code>controllers&lt;/code> dir:&lt;/p>
&lt;ul>
&lt;li>
&lt;a href="https://github.com/fluxcd/source-watcher/blob/main/controllers/gitrepository_watcher.go" target="_blank">gitrepository_watcher.go&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://github.com/fluxcd/source-watcher/blob/main/controllers/gitrepository_predicate.go" target="_blank">gitrepository_predicate.go&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>In your &lt;code>main.go&lt;/code> init function, register the Source API schema:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> utilruntime &lt;span style="color:#4070a0">&amp;#34;k8s.io/apimachinery/pkg/util/runtime&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> clientgoscheme &lt;span style="color:#4070a0">&amp;#34;k8s.io/client-go/kubernetes/scheme&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sourcev1 &lt;span style="color:#4070a0">&amp;#34;github.com/fluxcd/source-controller/api/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">func&lt;/span> &lt;span style="color:#06287e">init&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> utilruntime.&lt;span style="color:#06287e">Must&lt;/span>(clientgoscheme.&lt;span style="color:#06287e">AddToScheme&lt;/span>(scheme))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> utilruntime.&lt;span style="color:#06287e">Must&lt;/span>(sourcev1.&lt;span style="color:#06287e">AddToScheme&lt;/span>(scheme)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#60a0b0;font-style:italic">// +kubebuilder:scaffold:scheme
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#60a0b0;font-style:italic">&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Start the controller in the main function:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020;font-weight:bold">func&lt;/span> &lt;span style="color:#06287e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#007020;font-weight:bold">if&lt;/span> err = (&lt;span style="color:#666">&amp;amp;&lt;/span>controllers.GitRepositoryWatcher{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Client: mgr.&lt;span style="color:#06287e">GetClient&lt;/span>(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> HttpRetry: httpRetry,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }).&lt;span style="color:#06287e">SetupWithManager&lt;/span>(mgr); err &lt;span style="color:#666">!=&lt;/span> &lt;span style="color:#007020;font-weight:bold">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> setupLog.&lt;span style="color:#06287e">Error&lt;/span>(err, &lt;span style="color:#4070a0">&amp;#34;unable to create controller&amp;#34;&lt;/span>, &lt;span style="color:#4070a0">&amp;#34;controller&amp;#34;&lt;/span>, &lt;span style="color:#4070a0">&amp;#34;GitRepositoryWatcher&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> os.&lt;span style="color:#06287e">Exit&lt;/span>(&lt;span style="color:#40a070">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Note that the watcher depends on Flux
&lt;a href="https://pkg.go.dev/github.com/fluxcd/pkg/runtime" target="_blank">runtime&lt;/a>
and Kubernetes
&lt;a href="https://pkg.go.dev/sigs.k8s.io/controller-runtime" target="_blank">controller-runtime&lt;/a>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#06287e">require&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> github.com&lt;span style="color:#666">/&lt;/span>fluxcd&lt;span style="color:#666">/&lt;/span>pkg&lt;span style="color:#666">/&lt;/span>runtime v0&lt;span style="color:#40a070">.47.1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sigs.k8s.io&lt;span style="color:#666">/&lt;/span>controller&lt;span style="color:#666">-&lt;/span>runtime v0&lt;span style="color:#40a070">.18.2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That&amp;rsquo;s it! Happy hacking!&lt;/p></description></item><item><title>Flux: Advanced debugging</title><link>https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/debugging/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/flux/gitops-toolkit/debugging/</guid><description>
&lt;p>This guide covers more advanced debugging topics such as collecting
runtime profiling data from GitOps Toolkit components.&lt;/p>
&lt;p>As a user, this page normally should be a last resort, but you may
be asked by a maintainer to share a
&lt;a href="#collecting-a-profile">collected profile&lt;/a>
to debug e.g. performance issues.&lt;/p>
&lt;h2 id="pprof">Pprof&lt;/h2>
&lt;p>The
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/">GitOps Toolkit components&lt;/a> serve
&lt;a href="https://golang.org/pkg/net/http/pprof/" target="_blank">&lt;code>pprof&lt;/code>&lt;/a>
runtime profiling data on their metrics HTTP server (default &lt;code>:8080&lt;/code>).&lt;/p>
&lt;h3 id="endpoints">Endpoints&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Endpoint&lt;/th>
&lt;th>Path&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Index&lt;/td>
&lt;td>&lt;code>/debug/pprof/&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>CPU profile&lt;/td>
&lt;td>&lt;code>/debug/pprof/profile&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Symbol&lt;/td>
&lt;td>&lt;code>/debug/pprof/symbol&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Trace&lt;/td>
&lt;td>&lt;code>/debug/pprof/trace&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="collecting-a-profile">Collecting a profile&lt;/h3>
&lt;p>To collect a profile, port-forward to the component&amp;rsquo;s metrics endpoint
and collect the data from the
&lt;a href="#endpoints">endpoint&lt;/a> of choice:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ kubectl port-forward -n &amp;lt;namespace&amp;gt; deploy/&amp;lt;component&amp;gt; &lt;span style="color:#40a070">8080&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ curl -Sk -v http://localhost:8080/debug/pprof/heap &amp;gt; heap.out
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The collected profile
&lt;a href="https://blog.golang.org/pprof" target="_blank">can be analyzed using &lt;code>go&lt;/code>&lt;/a>,
or shared with one of the maintainers.&lt;/p>
&lt;h2 id="resource-usage">Resource usage&lt;/h2>
&lt;p>As &lt;code>kubectl top&lt;/code> gives a limited (and at times inaccurate) overview of
resource usage, it is often better to make use of the Grafana metrics
to gather insights. See
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/monitoring/metrics/">Flux Prometheus metrics&lt;/a> for a
guide on how to visualize this data with a Grafana dashboard.&lt;/p></description></item></channel></rss>