Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add cachedimage pulling progress status #400

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3a8c5ca
update release workflow (#1)
aDisplayName Aug 19, 2024
495456b
fix: remove build test image step
aDisplayName Aug 19, 2024
f0f3599
fix: Disable docker hub image tagging
aDisplayName Aug 19, 2024
c0db58d
fix: use a different secret to access helm-charts repo for upload
aDisplayName Aug 19, 2024
a33f916
fix: move helm chart image index file to `charts` folder
aDisplayName Aug 19, 2024
c3d883e
Pr/develop/add progress in cached image crd (#2)
aDisplayName Aug 20, 2024
96d446f
Update readme.md (#3)
aDisplayName Aug 20, 2024
724db34
fix: Commit message. add progress in cachedimage crd
aDisplayName Aug 20, 2024
53b79df
fix: Update Repository CRD (#5)
aDisplayName Aug 20, 2024
97514b2
fix: Fix repository CRD (#6)
aDisplayName Aug 20, 2024
4ce6da3
fix: Update README.md
aDisplayName Aug 21, 2024
2bd338c
feat: Add callback with progress update (#7)
aDisplayName Aug 21, 2024
56ca1fd
fix: Fix branding in docker build (#8)
aDisplayName Aug 21, 2024
11714b1
fix: Update CRD with progress
aDisplayName Aug 21, 2024
7183d22
fix: Force rebuild release
aDisplayName Aug 21, 2024
6076cac
fix: reduce rate limit
aDisplayName Aug 22, 2024
1ce48d3
fix: Add logging regardless on every call back (#10)
aDisplayName Aug 26, 2024
8e83c1b
fix: Add more logs (#11)
aDisplayName Aug 26, 2024
fcbcab6
add even more logs
aDisplayName Aug 26, 2024
e679aa7
fix: Title (#13)
aDisplayName Aug 26, 2024
3285930
fix: Move progress update to outter loop (#14)
aDisplayName Aug 26, 2024
88acc28
fix: Fix unit test (#15)
aDisplayName Aug 26, 2024
fbf572e
fix: Remove debug log (#16)
aDisplayName Aug 26, 2024
d73deb8
Revert back chagnes on github
aDisplayName Aug 26, 2024
7534ab0
Add missing newlines
aDisplayName Aug 26, 2024
6a86186
bug
aDisplayName Aug 26, 2024
2c53c69
revert back change on release.json
aDisplayName Aug 26, 2024
a8c33b4
revert
aDisplayName Aug 26, 2024
bbc4a43
revert
aDisplayName Aug 26, 2024
9e1d058
Revert to original branding
aDisplayName Aug 26, 2024
24e9ecc
rename kuikv1alpha1 to kuikv1alpha1ext1
aDisplayName Aug 26, 2024
4ac479f
remove not used test
aDisplayName Aug 26, 2024
dab19c1
formatting
aDisplayName Aug 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ Note that persistence requires your cluster to have some PersistentVolumes. If y
Sometimes, you want images to stay cached even when they are not used anymore (for instance when you run a workload for a fixed amount of time, stop it, and run it again later). You can choose to prevent `CachedImages` from expiring by manually setting the `spec.retain` flag to `true` like shown below:

```yaml
apiVersion: kuik.enix.io/v1alpha1
apiVersion: kuik.enix.io/v1alpha1ext1
kind: CachedImage
metadata:
name: docker.io-library-nginx-1.25
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v1alpha1
package v1alpha1ext1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -26,12 +26,19 @@ type UsedBy struct {
Count int `json:"count,omitempty"`
}

type Progress struct {
Total int64 `json:"total,omitempty"`
Available int64 `json:"available,omitempty"`
}

// CachedImageStatus defines the observed state of CachedImage
type CachedImageStatus struct {
IsCached bool `json:"isCached,omitempty"`
Phase string `json:"phase,omitempty"`
UsedBy UsedBy `json:"usedBy,omitempty"`

Progress Progress `json:"progress,omitempty"`

Digest string `json:"digest,omitempty"`
UpstreamDigest string `json:"upstreamDigest,omitempty"`
UpToDate bool `json:"upToDate,omitempty"`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v1alpha1
package v1alpha1ext1

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v1alpha1
package v1alpha1ext1

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v1alpha1
package v1alpha1ext1

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Package v1alpha1 contains API Schema definitions for the kuik.enix.io v1alpha1 API group
// Package v1alpha1ext1 contains API Schema definitions for the kuik.enix.io v1alpha1ext1 API group
// +kubebuilder:object:generate=true
// +groupName=kuik.enix.io
package v1alpha1
package v1alpha1ext1

import (
"k8s.io/apimachinery/pkg/runtime/schema"
Expand All @@ -10,7 +10,7 @@ import (

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "kuik.enix.io", Version: "v1alpha1"}
GroupVersion = schema.GroupVersion{Group: "kuik.enix.io", Version: "v1alpha1ext1"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v1alpha1
package v1alpha1ext1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v1alpha1
package v1alpha1ext1

import (
"regexp"
Expand Down
4 changes: 2 additions & 2 deletions cmd/cache/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

kuikenixiov1 "github.com/enix/kube-image-keeper/api/core/v1"
kuikv1alpha1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1"
kuikv1alpha1ext1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1ext1"
"github.com/enix/kube-image-keeper/internal"
kuikController "github.com/enix/kube-image-keeper/internal/controller"
"github.com/enix/kube-image-keeper/internal/controller/core"
Expand Down Expand Up @@ -116,7 +116,7 @@ func main() {
Decoder: admission.NewDecoder(mgr.GetScheme()),
}
mgr.GetWebhookServer().Register("/mutate-core-v1-pod", &webhook.Admission{Handler: &imageRewriter})
if err = (&kuikv1alpha1.CachedImage{}).SetupWebhookWithManager(mgr); err != nil {
if err = (&kuikv1alpha1ext1.CachedImage{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "CachedImage")
os.Exit(1)
}
Expand Down
11 changes: 10 additions & 1 deletion config/crd/bases/kuik.enix.io_cachedimages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
name: v1alpha1ext1
schema:
openAPIV3Schema:
description: CachedImage is the Schema for the cachedimages API
Expand Down Expand Up @@ -90,6 +90,15 @@ spec:
type: string
phase:
type: string
progress:
properties:
available:
format: int64
type: integer
total:
format: int64
type: integer
type: object
upToDate:
type: boolean
upstreamDigest:
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/kuik.enix.io_repositories.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
name: v1alpha1ext1
schema:
openAPIV3Schema:
description: Repository is the Schema for the repositories API
Expand Down
2 changes: 1 addition & 1 deletion config/samples/kuik_v1alpha1_cachedimage.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: kuik.enix.io/v1alpha1
apiVersion: kuik.enix.io/v1alpha1ext1
kind: CachedImage
metadata:
labels:
Expand Down
2 changes: 1 addition & 1 deletion config/samples/kuik_v1alpha1_repository.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: kuik.enix.io/v1alpha1
apiVersion: kuik.enix.io/v1alpha1ext1
kind: Repository
metadata:
labels:
Expand Down
14 changes: 13 additions & 1 deletion helm/kube-image-keeper/crds/cachedimage-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
- jsonPath: .status.progress.available
name: Downloaded
type: integer
name: v1alpha1ext1
schema:
openAPIV3Schema:
description: CachedImage is the Schema for the cachedimages API
Expand Down Expand Up @@ -93,6 +96,15 @@ spec:
type: boolean
upstreamDigest:
type: string
progress:
type: object
properties:
total:
type: integer
description: Total size of the compressed blob in bytes, including all layers.
available:
type: integer
description: Total downloaded / available size of the compressed blob in bytes, including all layers.
usedBy:
properties:
count:
Expand Down
2 changes: 1 addition & 1 deletion helm/kube-image-keeper/crds/repository-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
name: v1alpha1ext1
schema:
openAPIV3Schema:
description: Repository is the Schema for the repositories API
Expand Down
6 changes: 3 additions & 3 deletions internal/controller/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"strconv"

kuikv1alpha1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1"
kuikv1alpha1ext1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1ext1"
kuikMetrics "github.com/enix/kube-image-keeper/internal/metrics"
"github.com/prometheus/client_golang/prometheus"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -70,7 +70,7 @@ func RegisterMetrics(client client.Client) {
)
}

func cachedImagesWithLabelValues(gaugeVec *prometheus.GaugeVec, cachedImage *kuikv1alpha1.CachedImage) prometheus.Gauge {
func cachedImagesWithLabelValues(gaugeVec *prometheus.GaugeVec, cachedImage *kuikv1alpha1ext1.CachedImage) prometheus.Gauge {
return gaugeVec.WithLabelValues(strconv.FormatBool(cachedImage.Status.IsCached), strconv.FormatBool(cachedImage.Spec.ExpiresAt != nil))
}

Expand All @@ -83,7 +83,7 @@ func (c *ControllerCollector) Describe(ch chan<- *prometheus.Desc) {
}

func (c *ControllerCollector) Collect(ch chan<- prometheus.Metric) {
cachedImageList := &kuikv1alpha1.CachedImageList{}
cachedImageList := &kuikv1alpha1ext1.CachedImageList{}
if err := c.List(context.Background(), cachedImageList); err == nil {
cachedImageGaugeVec := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Expand Down
32 changes: 16 additions & 16 deletions internal/controller/core/pod_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"k8s.io/apimachinery/pkg/types"

"github.com/distribution/reference"
kuikv1alpha1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1"
kuikv1alpha1ext1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1ext1"
"github.com/enix/kube-image-keeper/internal/registry"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -92,7 +92,7 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
}

for _, cachedImage := range cachedImages {
var ci kuikv1alpha1.CachedImage
var ci kuikv1alpha1ext1.CachedImage
err := r.Get(ctx, client.ObjectKeyFromObject(&cachedImage), &ci)
if err != nil && !apierrors.IsNotFound(err) {
return ctrl.Result{}, err
Expand Down Expand Up @@ -141,7 +141,7 @@ func (r *PodReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ok
}))).
Watches(
&kuikv1alpha1.CachedImage{},
&kuikv1alpha1ext1.CachedImage{},
handler.EnqueueRequestsFromMapFunc(r.podsWithDeletingCachedImages),
builder.WithPredicates(p),
).
Expand All @@ -154,8 +154,8 @@ func (r *PodReconciler) podsWithDeletingCachedImages(ctx context.Context, obj cl
WithName("controller-runtime.manager.controller.pod.deletingCachedImages").
WithValues("cachedImage", klog.KObj(obj))

cachedImage := obj.(*kuikv1alpha1.CachedImage)
var currentCachedImage kuikv1alpha1.CachedImage
cachedImage := obj.(*kuikv1alpha1ext1.CachedImage)
var currentCachedImage kuikv1alpha1ext1.CachedImage
// wait for the CachedImage to be really deleted
if err := r.Get(ctx, client.ObjectKeyFromObject(cachedImage), &currentCachedImage); err == nil || !apierrors.IsNotFound(err) {
return make([]ctrl.Request, 0)
Expand Down Expand Up @@ -187,8 +187,8 @@ func (r *PodReconciler) podsWithDeletingCachedImages(ctx context.Context, obj cl
return make([]ctrl.Request, 0)
}

func (r *PodReconciler) desiredRepositories(ctx context.Context, pod *corev1.Pod, cachedImages []kuikv1alpha1.CachedImage) ([]kuikv1alpha1.Repository, error) {
repositories := map[string]kuikv1alpha1.Repository{}
func (r *PodReconciler) desiredRepositories(ctx context.Context, pod *corev1.Pod, cachedImages []kuikv1alpha1ext1.CachedImage) ([]kuikv1alpha1ext1.Repository, error) {
repositories := map[string]kuikv1alpha1ext1.Repository{}

pullSecretNames, err := r.imagePullSecretNamesFromPod(ctx, pod)
if err != nil {
Expand All @@ -201,11 +201,11 @@ func (r *PodReconciler) desiredRepositories(ctx context.Context, pod *corev1.Pod
return nil, err
}
repositoryName := named.Name()
repositories[repositoryName] = kuikv1alpha1.Repository{
repositories[repositoryName] = kuikv1alpha1ext1.Repository{
ObjectMeta: metav1.ObjectMeta{
Name: registry.SanitizeName(repositoryName),
},
Spec: kuikv1alpha1.RepositorySpec{
Spec: kuikv1alpha1ext1.RepositorySpec{
Name: repositoryName,
PullSecretNames: pullSecretNames,
PullSecretsNamespace: pod.Namespace,
Expand All @@ -216,15 +216,15 @@ func (r *PodReconciler) desiredRepositories(ctx context.Context, pod *corev1.Pod
return maps.Values(repositories), nil
}

func DesiredCachedImages(ctx context.Context, pod *corev1.Pod) []kuikv1alpha1.CachedImage {
func DesiredCachedImages(ctx context.Context, pod *corev1.Pod) []kuikv1alpha1ext1.CachedImage {
cachedImages := desiredCachedImagesForContainers(ctx, pod.Spec.Containers, pod.Annotations, false)
cachedImages = append(cachedImages, desiredCachedImagesForContainers(ctx, pod.Spec.InitContainers, pod.Annotations, true)...)
return cachedImages
}

func desiredCachedImagesForContainers(ctx context.Context, containers []corev1.Container, annotations map[string]string, initContainer bool) []kuikv1alpha1.CachedImage {
func desiredCachedImagesForContainers(ctx context.Context, containers []corev1.Container, annotations map[string]string, initContainer bool) []kuikv1alpha1ext1.CachedImage {
log := log.FromContext(ctx)
cachedImages := []kuikv1alpha1.CachedImage{}
cachedImages := []kuikv1alpha1ext1.CachedImage{}

for _, container := range containers {
annotationKey := registry.ContainerAnnotationKey(container.Name, initContainer)
Expand All @@ -249,7 +249,7 @@ func desiredCachedImagesForContainers(ctx context.Context, containers []corev1.C
return cachedImages
}

func cachedImageFromSourceImage(sourceImage string) (*kuikv1alpha1.CachedImage, error) {
func cachedImageFromSourceImage(sourceImage string) (*kuikv1alpha1ext1.CachedImage, error) {
ref, err := reference.ParseAnyReference(sourceImage)
if err != nil {
return nil, err
Expand All @@ -260,12 +260,12 @@ func cachedImageFromSourceImage(sourceImage string) (*kuikv1alpha1.CachedImage,
sanitizedName += "-latest"
}

cachedImage := kuikv1alpha1.CachedImage{
TypeMeta: metav1.TypeMeta{APIVersion: kuikv1alpha1.GroupVersion.String(), Kind: "CachedImage"},
cachedImage := kuikv1alpha1ext1.CachedImage{
TypeMeta: metav1.TypeMeta{APIVersion: kuikv1alpha1ext1.GroupVersion.String(), Kind: "CachedImage"},
ObjectMeta: metav1.ObjectMeta{
Name: sanitizedName,
},
Spec: kuikv1alpha1.CachedImageSpec{
Spec: kuikv1alpha1ext1.CachedImageSpec{
SourceImage: sourceImage,
},
}
Expand Down
22 changes: 11 additions & 11 deletions internal/controller/core/pod_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"testing"
"time"

kuikv1alpha1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1"
kuikv1alpha1ext1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1ext1"
"github.com/enix/kube-image-keeper/internal/registry"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -57,19 +57,19 @@ func TestDesiredCachedImages(t *testing.T) {
tests := []struct {
name string
pod corev1.Pod
cachedImages []kuikv1alpha1.CachedImage
cachedImages []kuikv1alpha1ext1.CachedImage
}{
{
name: "basic",
pod: podStub,
cachedImages: []kuikv1alpha1.CachedImage{
{Spec: kuikv1alpha1.CachedImageSpec{
cachedImages: []kuikv1alpha1ext1.CachedImage{
{Spec: kuikv1alpha1ext1.CachedImageSpec{
SourceImage: "nginx",
}},
{Spec: kuikv1alpha1.CachedImageSpec{
{Spec: kuikv1alpha1ext1.CachedImageSpec{
SourceImage: "busybox",
}},
{Spec: kuikv1alpha1.CachedImageSpec{
{Spec: kuikv1alpha1ext1.CachedImageSpec{
SourceImage: "alpine",
}},
},
Expand Down Expand Up @@ -146,16 +146,16 @@ var _ = Describe("Pod Controller", func() {
podStubNotRewritten.ResourceVersion = ""

By("Deleting all cached images")
Expect(k8sClient.DeleteAllOf(context.Background(), &kuikv1alpha1.CachedImage{})).Should(Succeed())
Expect(k8sClient.DeleteAllOf(context.Background(), &kuikv1alpha1ext1.CachedImage{})).Should(Succeed())
})

Context("Pod with containers and init containers", func() {
It("Should handle CachedImages creation and deletion", func() {
By("Creating a pod")
Expect(k8sClient.Create(context.Background(), &podStub)).Should(Succeed())

fetched := &kuikv1alpha1.CachedImageList{}
Eventually(func() []kuikv1alpha1.CachedImage {
fetched := &kuikv1alpha1ext1.CachedImageList{}
Eventually(func() []kuikv1alpha1ext1.CachedImage {
_ = k8sClient.List(context.Background(), fetched)
return fetched.Items
}, timeout, interval).Should(HaveLen(len(podStub.Spec.Containers) + len(podStub.Spec.InitContainers)))
Expand All @@ -177,8 +177,8 @@ var _ = Describe("Pod Controller", func() {
By("Creating a pod without rewriting images")
Expect(k8sClient.Create(context.Background(), &podStubNotRewritten)).Should(Succeed())

fetched := &kuikv1alpha1.CachedImageList{}
Eventually(func() []kuikv1alpha1.CachedImage {
fetched := &kuikv1alpha1ext1.CachedImageList{}
Eventually(func() []kuikv1alpha1ext1.CachedImage {
_ = k8sClient.List(context.Background(), fetched)
return fetched.Items
}, timeout, interval).Should(HaveLen(0))
Expand Down
Loading