Skip to content

Commit

Permalink
extend cluster iso images information
Browse files Browse the repository at this point in the history
  • Loading branch information
floreks committed Feb 7, 2025
1 parent 390891f commit 461535a
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 11 deletions.
42 changes: 42 additions & 0 deletions api/v1alpha2/cloudconfig_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package v1alpha2

type CloudConfig struct {
Users Users `json:"users,omitempty"`
Plural Plural `json:"plural,omitempty"`
}

type Users []User

func (in Users) FirstUser() *User {
for _, user := range in {
return &user
}

return nil
}

type User struct {
Name string `json:"name"`
Passwd string `json:"passwd"`
}

func (in *User) GetName() *string {
if in == nil {
return nil
}

return &in.Name
}

func (in *User) GetPasswd() *string {
if in == nil {
return nil
}

return &in.Passwd
}

type Plural struct {
Token string `json:"token"`
URL string `json:"url"`
}
8 changes: 6 additions & 2 deletions api/v1alpha2/osartifact_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,24 @@ const (

// OSArtifactSpec defines the desired state of OSArtifact
type OSArtifactSpec struct {
// There are 3 ways to specify a Kairos image:

// Points to a prepared kairos image (e.g. a released one)
// +optional
ImageName string `json:"imageName,omitempty"`

// +optional
ISO bool `json:"iso,omitempty"`

// +kubebuilder:validation:Type:=string
// +kubebuilder:validation:Enum:=rpi3;rpi4
// +optional
Model *Model `json:"model,omitempty"`

// +optional
CloudConfigRef *corev1.SecretKeySelector `json:"cloudConfigRef,omitempty"`

// +optional
Project string `json:"project,omitempty"`

// +optional
Bundles []string `json:"bundles,omitempty"`

Expand Down
2 changes: 1 addition & 1 deletion charts/osartifact/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ maintainers:
- name: Plural
email: [email protected]
type: application
version: 0.8.2
version: 0.9.0
3 changes: 3 additions & 0 deletions charts/osartifact/templates/osartifact.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ spec:
cloudConfigRef:
name: {{ include "osartifact.fullname" . }}-config
key: cloud-config.yaml
{{- if .Values.project }}
project: {{ .Values.project }}
{{- end }}
exporter:
serviceAccount: {{ include "osartifact.fullname" . }}
{{- with .Values.exporter.extraEnvVars }}
Expand Down
3 changes: 3 additions & 0 deletions charts/osartifact/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ image: quay.io/kairos/alpine:3.19-standard-arm64-rpi4-v3.2.4-k3sv1.31.3-k3s1
# Target device. Currently supported values: rpi4
device: rpi4

# Plural project name this image should be tied to.
project: ~

# WiFi configuration. It will attempt the connection on the first boot.
wifi:
enabled: false
Expand Down
52 changes: 46 additions & 6 deletions controllers/osartifact_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ package controllers

import (
"context"
"encoding/json"
"fmt"
"time"

osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
consoleclient "github.com/kairos-io/osbuilder/pkg/client"
console "github.com/pluralsh/console/go/client"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
Expand All @@ -41,6 +40,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
consoleclient "github.com/kairos-io/osbuilder/pkg/client"
)

const (
Expand Down Expand Up @@ -406,7 +408,7 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
} else if job.Spec.Completions != nil {
if job.Status.Succeeded > 0 && artifact.Status.Phase == osbuilder.Exporting {
artifact.Status.Phase = osbuilder.Ready
if err := r.upsertClusterIsoImage(artifact); err != nil {
if err := r.upsertClusterIsoImage(ctx, artifact); err != nil {
artifact.Status.Phase = osbuilder.Error
meta.SetStatusCondition(&artifact.Status.Conditions, metav1.Condition{
Type: "Ready",
Expand Down Expand Up @@ -444,11 +446,25 @@ func (r *OSArtifactReconciler) checkExport(ctx context.Context, artifact *osbuil
return requeue, nil
}

func (r *OSArtifactReconciler) upsertClusterIsoImage(artifact *osbuilder.OSArtifact) error {
func (r *OSArtifactReconciler) upsertClusterIsoImage(ctx context.Context, artifact *osbuilder.OSArtifact) error {
cloudConfig, err := r.getCloudConfig(ctx, artifact)
if err != nil {
return err
}

var projectID *string = nil
project, _ := r.ConsoleClient.GetProject(artifact.Spec.Project)
if project != nil {
projectID = &project.ID
}

image := fmt.Sprintf("%s:%s", artifact.Spec.Exporter.Registry.Image.Repository, artifact.Spec.Exporter.Registry.Image.Tag)
attr := console.ClusterIsoImageAttributes{
Image: image,
Registry: artifact.Spec.Exporter.Registry.Name,
Image: image,
Registry: artifact.Spec.Exporter.Registry.Name,
User: cloudConfig.Users.FirstUser().GetName(),
Password: cloudConfig.Users.FirstUser().GetPasswd(),
ProjectID: projectID,
}

getResponse, err := r.ConsoleClient.GetClusterIsoImage(&image)
Expand Down Expand Up @@ -518,3 +534,27 @@ func (r *OSArtifactReconciler) CreateConfigMap(ctx context.Context, artifact *os

return nil
}

func (r *OSArtifactReconciler) getCloudConfig(ctx context.Context, artifact *osbuilder.OSArtifact) (*osbuilder.CloudConfig, error) {
config := &osbuilder.CloudConfig{}
secret := &corev1.Secret{}
key := client.ObjectKey{
Namespace: artifact.Namespace,
Name: artifact.Spec.CloudConfigRef.Name,
}

if err := r.Get(ctx, key, secret); err != nil {
return config, err
}

configBytes, exists := secret.Data[artifact.Spec.CloudConfigRef.Key]
if !exists {
return config, fmt.Errorf("could not find key %s in secret %s", artifact.Spec.CloudConfigRef.Key, artifact.Spec.CloudConfigRef.Name)
}

if err := json.Unmarshal(configBytes, config); err != nil {
return config, err
}

return config, nil
}
22 changes: 20 additions & 2 deletions pkg/client/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import (
"net/http"

rawclient "github.com/Yamashou/gqlgenc/clientv2"
internalerror "github.com/kairos-io/osbuilder/pkg/errors"
"github.com/kairos-io/osbuilder/pkg/helpers"
"github.com/pkg/errors"
console "github.com/pluralsh/console/go/client"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"

internalerror "github.com/kairos-io/osbuilder/pkg/errors"
"github.com/kairos-io/osbuilder/pkg/helpers"
)

type client struct {
Expand All @@ -37,6 +38,7 @@ type Client interface {
UpdateClusterIsoImage(id string, attributes console.ClusterIsoImageAttributes) (*console.ClusterIsoImageFragment, error)
GetClusterIsoImage(image *string) (*console.ClusterIsoImageFragment, error)
DeleteClusterIsoImage(id string) (*console.ClusterIsoImageFragment, error)
GetProject(name string) (*console.ProjectFragment, error)
}

func (c *client) CreateClusterIsoImage(attributes console.ClusterIsoImageAttributes) (*console.ClusterIsoImageFragment, error) {
Expand Down Expand Up @@ -82,6 +84,22 @@ func (c *client) GetClusterIsoImage(image *string) (*console.ClusterIsoImageFrag
return response.ClusterIsoImage, nil
}

func (c *client) GetProject(name string) (*console.ProjectFragment, error) {
response, err := c.consoleClient.GetProject(c.ctx, nil, &name)
if internalerror.IsNotFound(err) {
return nil, apierrors.NewNotFound(schema.GroupResource{}, name)
}
if err == nil && (response == nil || response.Project == nil) {
return nil, apierrors.NewNotFound(schema.GroupResource{}, name)
}

if response == nil {
return nil, err
}

return response.Project, nil
}

func GetErrorResponse(err error, methodName string) error {
if err == nil {
return nil
Expand Down

0 comments on commit 461535a

Please sign in to comment.