Skip to content

Commit d5a437a

Browse files
committed
Construct UKIURL from the OCI format for the HTTPBoot
1 parent c18df2f commit d5a437a

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

internal/controller/serverbootconfiguration_http_controller.go

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ package controller
55

66
import (
77
"context"
8+
"encoding/json"
89
"fmt"
910
"strings"
1011

12+
"github.com/containerd/containerd/remotes/docker"
13+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
14+
1115
corev1 "k8s.io/api/core/v1"
1216
"k8s.io/apimachinery/pkg/types"
1317
"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -25,6 +29,10 @@ import (
2529
metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1"
2630
)
2731

32+
const (
33+
MediaTypeUKI = "application/vnd.ironcore.image.uki"
34+
)
35+
2836
type ServerBootConfigurationHTTPReconciler struct {
2937
client.Client
3038
Scheme *runtime.Scheme
@@ -75,7 +83,10 @@ func (r *ServerBootConfigurationHTTPReconciler) reconcile(ctx context.Context, l
7583
}
7684
log.V(1).Info("Got system IPs from Server", "systemIPs", systemIPs)
7785

78-
ukiURL := r.constructUKIURL(config.Spec.Image)
86+
ukiURL, err := r.constructUKIURL(ctx, config.Spec.Image)
87+
if err != nil {
88+
return ctrl.Result{}, fmt.Errorf("failed to construct UKI URL: %w", err)
89+
}
7990
log.V(1).Info("Extracted UKI URL for boot")
8091

8192
httpBootConfig := &bootv1alpha1.HTTPBootConfig{
@@ -166,16 +177,46 @@ func (r *ServerBootConfigurationHTTPReconciler) getSystemIPFromServer(ctx contex
166177
return systemIPs, nil
167178
}
168179

169-
func (r *ServerBootConfigurationHTTPReconciler) constructUKIURL(image string) string {
170-
sanitizedImage := strings.ReplaceAll(image, "/", "-")
171-
sanitizedImage = strings.ReplaceAll(sanitizedImage, ":", "-")
172-
sanitizedImage = strings.ReplaceAll(sanitizedImage, "https://", "")
173-
sanitizedImage = strings.ReplaceAll(sanitizedImage, "http://", "")
180+
func (r *ServerBootConfigurationHTTPReconciler) constructUKIURL(ctx context.Context, image string) (string, error) {
181+
imageDetails := strings.Split(image, ":")
182+
if len(imageDetails) != 2 {
183+
return "", fmt.Errorf("invalid image format")
184+
}
185+
186+
ukiDigest, err := r.getUKIDigestFromNestedManifest(ctx, imageDetails[0], imageDetails[1])
187+
if err != nil {
188+
return "", fmt.Errorf("failed to fetch UKI layer digest: %w", err)
189+
}
190+
191+
ukiURL := fmt.Sprintf("%s/image?imageName=%s&version=%s&layerDigest=%s", r.ImageServerURL, imageDetails[0], imageDetails[1], ukiDigest)
192+
return ukiURL, nil
193+
}
174194

175-
filename := fmt.Sprintf("%s-uki.efi", sanitizedImage)
195+
func (r *ServerBootConfigurationHTTPReconciler) getUKIDigestFromNestedManifest(ctx context.Context, imageName, imageVersion string) (string, error) {
196+
resolver := docker.NewResolver(docker.ResolverOptions{})
197+
imageRef := fmt.Sprintf("%s:%s", imageName, imageVersion)
198+
name, desc, err := resolver.Resolve(ctx, imageRef)
199+
if err != nil {
200+
return "", fmt.Errorf("failed to resolve image reference: %w", err)
201+
}
202+
203+
manifestData, err := fetchContent(ctx, resolver, name, desc)
204+
if err != nil {
205+
return "", fmt.Errorf("failed to fetch manifest data: %w", err)
206+
}
207+
208+
var manifest ocispec.Manifest
209+
if err := json.Unmarshal(manifestData, &manifest); err != nil {
210+
return "", fmt.Errorf("failed to unmarshal manifest: %w", err)
211+
}
212+
213+
for _, layer := range manifest.Layers {
214+
if layer.MediaType == MediaTypeUKI {
215+
return layer.Digest.String(), nil
216+
}
217+
}
176218

177-
ukiURL := fmt.Sprintf("%s/%s", r.ImageServerURL, filename)
178-
return ukiURL
219+
return "", fmt.Errorf("UKI layer digest not found")
179220
}
180221

181222
// SetupWithManager sets up the controller with the Manager.

internal/controller/serverbootconfiguration_http_controller_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ var _ = Describe("ServerBootConfiguration Controller", func() {
8989
})),
9090
HaveField("Spec.SystemUUID", server.Spec.UUID),
9191
HaveField("Spec.SystemIPs", ContainElement("1.1.1.1")),
92-
HaveField("Spec.UKIURL", "http://localhost:5000/httpboot/foo-bar-uki.efi"),
9392
HaveField("Spec.IgnitionSecretRef.Name", "foo"),
9493
))
9594
})

0 commit comments

Comments
 (0)