Compare commits

...

7 Commits

Author SHA1 Message Date
Mauro Morales
4ce89a76a9 Merge pull request #64 from kairos-io/1548-os-release-update
Introduce os-release-update
2023-06-28 09:28:30 +02:00
Mauro Morales
5b3c765080 Introduce os-release-update
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2023-06-27 17:47:25 +02:00
Dimitris Karakasilis
893de1cc1d Merge pull request #62 from kairos-io/1477-fix-osbuilder-tests
Remove old parameters (no longer supported)
2023-06-23 14:31:46 +03:00
Dimitris Karakasilis
3eafb953b2 Declare variables in container nodes but initialize them in setup nodes
as per the docs:

https://onsi.github.io/ginkgo/#avoid-spec-pollution-dont-initialize-variables-in-container-nodes

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2023-06-21 14:14:35 +03:00
Dimitris Karakasilis
278abfa84d Remove old parameters (no longer supported)
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2023-06-21 13:13:26 +03:00
Itxaka
d8d8d70eca Merge pull request #61 from Itxaka/zstd_tools_image 2023-06-13 12:29:15 +02:00
Itxaka
f59f5bac75 Add zstd to the osbuilder image
Useful to support zstd compression when working with arm images

Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-06-13 11:12:01 +02:00
5 changed files with 163 additions and 124 deletions

View File

@@ -38,7 +38,3 @@ spec:
- "--health-probe-bind-address=:8081"
- "--metrics-bind-address=127.0.0.1:8080"
- "--leader-elect"
- "--copy-to-namespace=$(NGINX_NAMESPACE)"
- "--copy-role=$(ARTIFACT_COPIER_ROLE)"
- --copy-to-pod-label=app.kubernetes.io/name=osbuilder-nginx
- --copy-to-path="/usr/share/nginx/html"

View File

@@ -2,6 +2,8 @@ package e2e_test
import (
"context"
"time"
osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -16,48 +18,54 @@ import (
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
ctrl "sigs.k8s.io/controller-runtime"
"time"
)
var _ = Describe("ISO build test", func() {
k8s := dynamic.NewForConfigOrDie(ctrl.GetConfigOrDie())
scheme := runtime.NewScheme()
_ = osbuilder.AddToScheme(scheme)
var artifactName string
artifacts := k8s.Resource(schema.GroupVersionResource{Group: osbuilder.GroupVersion.Group, Version: osbuilder.GroupVersion.Version, Resource: "osartifacts"}).Namespace("default")
pods := k8s.Resource(schema.GroupVersionResource{Group: corev1.GroupName, Version: corev1.SchemeGroupVersion.Version, Resource: "pods"}).Namespace("default")
pvcs := k8s.Resource(schema.GroupVersionResource{Group: corev1.GroupName, Version: corev1.SchemeGroupVersion.Version, Resource: "persistentvolumeclaims"}).Namespace("default")
jobs := k8s.Resource(schema.GroupVersionResource{Group: batchv1.GroupName, Version: batchv1.SchemeGroupVersion.Version, Resource: "jobs"}).Namespace("default")
var artifacts, pods, pvcs, jobs dynamic.ResourceInterface
var scheme *runtime.Scheme
var artifactLabelSelector labels.Selector
artifact := &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
Kind: "OSArtifact",
APIVersion: osbuilder.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "simple-",
},
Spec: osbuilder.OSArtifactSpec{
ImageName: "quay.io/kairos/core-opensuse:latest",
ISO: true,
DiskSize: "",
Exporters: []batchv1.JobSpec{
{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
Containers: []corev1.Container{
{
Name: "test",
Image: "debian:latest",
Command: []string{"bash"},
Args: []string{"-xec", "[ -f /artifacts/*.iso ]"},
VolumeMounts: []corev1.VolumeMount{
{
Name: "artifacts",
ReadOnly: true,
MountPath: "/artifacts",
BeforeEach(func() {
k8s := dynamic.NewForConfigOrDie(ctrl.GetConfigOrDie())
scheme = runtime.NewScheme()
err := osbuilder.AddToScheme(scheme)
Expect(err).ToNot(HaveOccurred())
artifacts = k8s.Resource(schema.GroupVersionResource{Group: osbuilder.GroupVersion.Group, Version: osbuilder.GroupVersion.Version, Resource: "osartifacts"}).Namespace("default")
pods = k8s.Resource(schema.GroupVersionResource{Group: corev1.GroupName, Version: corev1.SchemeGroupVersion.Version, Resource: "pods"}).Namespace("default")
pvcs = k8s.Resource(schema.GroupVersionResource{Group: corev1.GroupName, Version: corev1.SchemeGroupVersion.Version, Resource: "persistentvolumeclaims"}).Namespace("default")
jobs = k8s.Resource(schema.GroupVersionResource{Group: batchv1.GroupName, Version: batchv1.SchemeGroupVersion.Version, Resource: "jobs"}).Namespace("default")
artifact := &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
Kind: "OSArtifact",
APIVersion: osbuilder.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "simple-",
},
Spec: osbuilder.OSArtifactSpec{
ImageName: "quay.io/kairos/core-opensuse:latest",
ISO: true,
DiskSize: "",
Exporters: []batchv1.JobSpec{
{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
Containers: []corev1.Container{
{
Name: "test",
Image: "debian:latest",
Command: []string{"bash"},
Args: []string{"-xec", "[ -f /artifacts/*.iso ]"},
VolumeMounts: []corev1.VolumeMount{
{
Name: "artifacts",
ReadOnly: true,
MountPath: "/artifacts",
},
},
},
},
@@ -66,92 +74,89 @@ var _ = Describe("ISO build test", func() {
},
},
},
},
}
}
uArtifact := unstructured.Unstructured{}
uArtifact.Object, _ = runtime.DefaultUnstructuredConverter.ToUnstructured(artifact)
resp, err := artifacts.Create(context.TODO(), &uArtifact, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifactName = resp.GetName()
uArtifact := unstructured.Unstructured{}
uArtifact.Object, _ = runtime.DefaultUnstructuredConverter.ToUnstructured(artifact)
resp, err := artifacts.Create(context.TODO(), &uArtifact, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifactName = resp.GetName()
Context("simple", func() {
artifactLabelSelectorReq, _ := labels.NewRequirement("build.kairos.io/artifact", selection.Equals, []string{artifactName})
artifactLabelSelector := labels.NewSelector().Add(*artifactLabelSelectorReq)
artifactLabelSelectorReq, err := labels.NewRequirement("build.kairos.io/artifact", selection.Equals, []string{artifactName})
Expect(err).ToNot(HaveOccurred())
artifactLabelSelector = labels.NewSelector().Add(*artifactLabelSelectorReq)
})
It("starts the build", func() {
Eventually(func(g Gomega) {
w, err := pods.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
})
It("exports the artifacts", func() {
Eventually(func(g Gomega) {
w, err := jobs.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
})
It("artifact successfully builds", func() {
Eventually(func(g Gomega) {
w, err := artifacts.Watch(context.TODO(), metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
var artifact osbuilder.OSArtifact
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = !ok
if event.Type == watch.Modified && event.Object.(*unstructured.Unstructured).GetName() == artifactName {
err := scheme.Convert(event.Object, &artifact, nil)
Expect(err).ToNot(HaveOccurred())
stopped = artifact.Status.Phase == osbuilder.Ready
}
}
}).WithTimeout(time.Hour).Should(Succeed())
})
It("cleans up resources on deleted", func() {
err := artifacts.Delete(context.TODO(), artifactName, metav1.DeleteOptions{})
It("works", func() {
By("starting the build")
Eventually(func(g Gomega) {
w, err := pods.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
Eventually(func(g Gomega) int {
res, err := artifacts.List(context.TODO(), metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := pods.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := pvcs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := jobs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
})
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
By("exporting the artifacts")
Eventually(func(g Gomega) {
w, err := jobs.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
By("building the artifacts successfully")
Eventually(func(g Gomega) {
w, err := artifacts.Watch(context.TODO(), metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
var artifact osbuilder.OSArtifact
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = !ok
if event.Type == watch.Modified && event.Object.(*unstructured.Unstructured).GetName() == artifactName {
err := scheme.Convert(event.Object, &artifact, nil)
Expect(err).ToNot(HaveOccurred())
stopped = artifact.Status.Phase == osbuilder.Ready
}
}
}).WithTimeout(time.Hour).Should(Succeed())
By("cleaning up resources on deletion")
err := artifacts.Delete(context.TODO(), artifactName, metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
Eventually(func(g Gomega) int {
res, err := artifacts.List(context.TODO(), metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := pods.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := pvcs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := jobs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
})
})

View File

@@ -71,7 +71,7 @@ COPY --from=grub-artifacts / /arm/grub/artifacts
RUN zypper ref && zypper dup -y
## ISO Build depedencies
RUN zypper ref && zypper in -y xfsprogs parted util-linux-systemd e2fsprogs curl util-linux udev rsync grub2 dosfstools grub2-x86_64-efi squashfs mtools xorriso lvm2
RUN zypper ref && zypper in -y xfsprogs parted util-linux-systemd e2fsprogs curl util-linux udev rsync grub2 dosfstools grub2-x86_64-efi squashfs mtools xorriso lvm2 zstd
RUN mkdir /config
# Arm image build deps
@@ -85,6 +85,8 @@ RUN zypper in -y bc qemu-tools
COPY ./config.yaml /config/manifest.yaml
COPY ./entrypoint.sh /entrypoint.sh
COPY ./add-cloud-init.sh /add-cloud-init.sh
COPY ./os-release.tmpl /os-release.tmpl
COPY ./update-os-release.sh /update-os-release.sh
# ARM helpers
COPY ./build-arm-image.sh /build-arm-image.sh

View File

@@ -0,0 +1,13 @@
KAIROS_NAME="${OS_NAME}"
KAIROS_VERSION="${OS_VERSION}"
KAIROS_ID="${OS_ID}"
KAIROS_ID_LIKE="${OS_NAME}"
KAIROS_VERSION_ID="${OS_VERSION}"
KAIROS_PRETTY_NAME="${OS_NAME} ${OS_VERSION}"
KAIROS_BUG_REPORT_URL="${BUG_REPORT_URL}"
KAIROS_HOME_URL="${HOME_URL}"
KAIROS_IMAGE_REPO="${OS_REPO}"
KAIROS_IMAGE_LABEL="${OS_LABEL}"
KAIROS_GITHUB_REPO="${GITHUB_REPO}"
KAIROS_VARIANT="${VARIANT}"
KAIROS_FLAVOR="${FLAVOR}"

View File

@@ -0,0 +1,23 @@
#!/bin/bash
# usage:
# docker run --rm -ti --entrypoint /update-os-release.sh \
# -v /etc:/workspace \ # mount the directory where your os-release is, this is by default in /etc but you can mount a different dir for testing
# -e OS_NAME=kairos-core-opensuse-leap \
# -e OS_VERSION=v2.2.0 \
# -e OS_ID="kairos" \
# -e OS_NAME=kairos-core-opensuse-leap \
# -e BUG_REPORT_URL="https://github.com/kairos-io/kairos/issues" \
# -e HOME_URL="https://github.com/kairos-io/kairos" \
# -e OS_REPO="quay.io/kairos/core-opensuse-leap" \
# -e OS_LABEL="latest" \
# -e GITHUB_REPO="kairos-io/kairos" \
# -e VARIANT="core" \
# -e FLAVOR="opensuse-leap"
# quay.io/kairos/osbuilder-tools:latest
set -ex
sed -i -n '/KAIROS_/!p' /workspace/os-release
envsubst >>/workspace/os-release < /os-release.tmpl
cat /workspace/os-release