1
0
mirror of https://github.com/kairos-io/osbuilder.git synced 2025-04-30 04:14:03 +00:00
osbuilder/controllers/osartifact_controller_test.go
Dimitris Karakasilis e55bd03800
1546 byoi ()
* Add fields to the CRDs

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* WIP Create test

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Refactor code to split in testable functions

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* WIP

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Do something actually useful in tests

- Create a random namespace
- Create an artifact
- Check that CreateConfigmap doesn't error

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* WIP

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Refactor before each so that we can change the artifact object per test

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* WIP

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* WIP

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Run kaniko to build the Dockerfile

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Build the image from Dockerfile with kaniko

Currently can build an image. For example apply these:

```
kind: Secret
apiVersion: v1
metadata:
  name: mydockerfile
stringData:
  Dockerfile: |
    FROM ubuntu
    RUN touch myfile

---
kind: OSArtifact
apiVersion: build.kairos.io/v1alpha2
metadata:
  name: hello-kairos
spec:
  imageName: "quay.io/kairos/core-opensuse-leap:latest"
  baseImageDockerfile:
    name: "mydockerfile"
    key: "Dockerfile"
  iso: true
```

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Clarify that convert-to-kairos is not yet implemented

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Remove implemented TODO

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* WIP

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Bump linting action

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix linting errors

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Bump it again

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Unexport function and run controller tests in CI

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Unexport the other one too

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Extract case to a function

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Split controller tests in a separate job

so that they run on a fresh cluster and they run in parallel

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Remove non-implemented functionality

Will happen as part of this: https://github.com/kairos-io/kairos/issues/1721

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* go mod tidy

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Try to use a random (free) port in tests

because sometimes we collide

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

---------

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2023-08-31 15:30:55 +03:00

174 lines
5.2 KiB
Go

package controllers
import (
"context"
"fmt"
"time"
osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/phayes/freeport"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
)
var _ = Describe("OSArtifactReconciler", func() {
var r *OSArtifactReconciler
var artifact *osbuilder.OSArtifact
var namespace string
var restConfig *rest.Config
var clientset *kubernetes.Clientset
var err error
BeforeEach(func() {
restConfig = ctrl.GetConfigOrDie()
clientset, err = kubernetes.NewForConfig(restConfig)
Expect(err).ToNot(HaveOccurred())
namespace = createRandomNamespace(clientset)
artifact = &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
Kind: "OSArtifact",
APIVersion: osbuilder.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: randStringRunes(10),
},
}
scheme := runtime.NewScheme()
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(osbuilder.AddToScheme(scheme))
metricsPort, err := freeport.GetFreePort()
Expect(err).ToNot(HaveOccurred())
fmt.Printf("metricsPort = %+v\n", metricsPort)
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: fmt.Sprintf("127.0.0.1:%d", metricsPort),
})
Expect(err).ToNot(HaveOccurred())
r = &OSArtifactReconciler{
ToolImage: "quay.io/kairos/osbuilder-tools:latest",
}
err = (r).SetupWithManager(mgr)
Expect(err).ToNot(HaveOccurred())
})
JustBeforeEach(func() {
k8s := dynamic.NewForConfigOrDie(restConfig)
artifacts := k8s.Resource(
schema.GroupVersionResource{
Group: osbuilder.GroupVersion.Group,
Version: osbuilder.GroupVersion.Version,
Resource: "osartifacts"}).Namespace(namespace)
uArtifact := unstructured.Unstructured{}
uArtifact.Object, _ = runtime.DefaultUnstructuredConverter.ToUnstructured(artifact)
resp, err := artifacts.Create(context.TODO(), &uArtifact, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
// Update the local object with the one fetched from k8s
err = runtime.DefaultUnstructuredConverter.FromUnstructured(resp.Object, artifact)
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
deleteNamepace(clientset, namespace)
})
Describe("CreateConfigMap", func() {
It("creates a ConfigMap with no error", func() {
ctx := context.Background()
err := r.CreateConfigMap(ctx, artifact)
Expect(err).ToNot(HaveOccurred())
c, err := clientset.CoreV1().ConfigMaps(namespace).Get(context.TODO(), artifact.Name, metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
Expect(c).ToNot(BeNil())
})
})
Describe("CreateBuilderPod", func() {
When("BaseImageDockerfile is set", func() {
BeforeEach(func() {
secretName := artifact.Name + "-dockerfile"
_, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(),
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
Namespace: namespace,
},
StringData: map[string]string{
"Dockerfile": "FROM ubuntu",
},
Type: "Opaque",
}, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifact.Spec.BaseImageDockerfile = &osbuilder.SecretKeySelector{
Name: secretName,
Key: "Dockerfile",
}
// Whatever, just to let it work
artifact.Spec.ImageName = "quay.io/kairos-ci/" + artifact.Name + ":latest"
})
It("creates an Init Container to build the image", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
By("checking if an init container was created")
initContainerNames := []string{}
for _, c := range pod.Spec.InitContainers {
initContainerNames = append(initContainerNames, c.Name)
}
Expect(initContainerNames).To(ContainElement("kaniko-build"))
By("checking if init containers complete successfully")
Eventually(func() bool {
p, err := clientset.CoreV1().Pods(namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
var allReady = false
if len(p.Status.InitContainerStatuses) > 0 {
allReady = true
}
for _, c := range p.Status.InitContainerStatuses {
allReady = allReady && c.Ready
}
return allReady
}, 2*time.Minute, 5*time.Second).Should(BeTrue())
// req := clientset.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &v1.PodLogOptions{})
// podLogs, err := req.Stream(context.TODO())
// Expect(err).ToNot(HaveOccurred())
// defer podLogs.Close()
// buf := new(bytes.Buffer)
// _, err = io.Copy(buf, podLogs)
// Expect(err).ToNot(HaveOccurred())
// str := buf.String()
// fmt.Printf("str = %+v\n", str)
})
})
})
})