1- // main.go
21package main
32
43import (
@@ -19,7 +18,6 @@ import (
1918
2019 "ghcr.io/compspec/ocifit-k8s/pkg/artifact"
2120 "ghcr.io/compspec/ocifit-k8s/pkg/validator"
22- ocispec "github.com/opencontainers/image-spec/specs-go/v1"
2321 admissionv1 "k8s.io/api/admission/v1"
2422 corev1 "k8s.io/api/core/v1"
2523 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -31,8 +29,6 @@ import (
3129 v1listers "k8s.io/client-go/listers/core/v1"
3230 "k8s.io/client-go/tools/cache"
3331 "k8s.io/client-go/tools/clientcmd"
34- "oras.land/oras-go/v2/content"
35- "oras.land/oras-go/v2/registry/remote"
3632)
3733
3834const (
@@ -108,7 +104,6 @@ func (ws *WebhookServer) recalculateHomogeneity() {
108104 // We can't include control plane nodes - they don't have NFD labels
109105 workerNodeSelector , err := labels .Parse ("!node-role.kubernetes.io/control-plane" )
110106 if err != nil {
111- // This is a static string, so this failure is fatal for the controller's logic.
112107 log .Fatalf ("FATAL: Failed to parse worker node selector: %v" , err )
113108 }
114109
@@ -148,82 +143,17 @@ func (ws *WebhookServer) recalculateHomogeneity() {
148143 ws .commonLabels = referenceLabels
149144}
150145
151- // --- WebhookServer with Node Cache ---
146+ // WebhookServer with Node Cache
152147type WebhookServer struct {
153148 nodeLister v1listers.NodeLister
154149 server * http.Server
155150
156- // Cached state and a lock to protect it ---
151+ // Cached state and a lock to protect it
157152 stateLock sync.RWMutex
158153 isHomogenous bool
159154 commonLabels map [string ]string
160155}
161156
162- // findCompatibleImage uses ORAS to find an image that matches the requirements
163- func findCompatibleImage (ctx context.Context , imageRef string , requirements map [string ]string ) (string , error ) {
164- registryName , repoAndTag , found := strings .Cut (imageRef , "/" )
165- if ! found {
166- return "" , fmt .Errorf ("invalid image reference format: %s" , imageRef )
167- }
168- repoName , tag , found := strings .Cut (repoAndTag , ":" )
169- if ! found {
170- tag = "latest" // Default tag
171- }
172-
173- // 1. Connect to the remote registry
174- reg , err := remote .NewRegistry (registryName )
175- if err != nil {
176- return "" , fmt .Errorf ("failed to connect to registry %s: %w" , registryName , err )
177- }
178- repo , err := reg .Repository (ctx , repoName )
179- if err != nil {
180- return "" , fmt .Errorf ("failed to access repository %s: %w" , repoName , err )
181- }
182-
183- // 2. Resolve the image index descriptor by its tag
184- indexDesc , err := repo .Resolve (ctx , tag )
185- if err != nil {
186- return "" , fmt .Errorf ("failed to resolve image index %s:%s: %w" , repoName , tag , err )
187- }
188-
189- // 3. Fetch and unmarshal the image index
190- indexBytes , err := content .FetchAll (ctx , repo , indexDesc )
191- if err != nil {
192- return "" , fmt .Errorf ("failed to fetch image index content: %w" , err )
193- }
194- var index ocispec.Index
195- if err := json .Unmarshal (indexBytes , & index ); err != nil {
196- return "" , fmt .Errorf ("failed to unmarshal image index: %w" , err )
197- }
198-
199- log .Printf ("Checking %d manifests in index for %s" , len (index .Manifests ), imageRef )
200-
201- // 4. Iterate through manifests in the index to find a compatible one
202- for _ , manifestDesc := range index .Manifests {
203- if manifestDesc .Annotations == nil {
204- continue
205- }
206-
207- match := true
208- // Check if all pod requirements are met by the manifest's annotations
209- for reqKey , reqVal := range requirements {
210- if manifestVal , ok := manifestDesc .Annotations [reqKey ]; ! ok || manifestVal != reqVal {
211- match = false
212- break
213- }
214- }
215-
216- if match {
217- // Found a compatible image!
218- finalImage := fmt .Sprintf ("%s/%s@%s" , registryName , repoName , manifestDesc .Digest )
219- log .Printf ("Found compatible image: %s" , finalImage )
220- return finalImage , nil
221- }
222- }
223-
224- return "" , fmt .Errorf ("no compatible image found for requirements: %v" , requirements )
225- }
226-
227157// findMatchingNode searches the cache for a node that satisfies the pod's nodeSelector.
228158func (ws * WebhookServer ) findMatchingNode (nodeSelector map [string ]string ) (* corev1.Node , error ) {
229159 if len (nodeSelector ) == 0 {
@@ -246,8 +176,8 @@ func (ws *WebhookServer) findMatchingNode(nodeSelector map[string]string) (*core
246176}
247177
248178// mutate is the core logic to look for compatibility labels and select a new image
249- // mutate is the core logic of our webhook. It uses a cached state for efficiency.
250179func (ws * WebhookServer ) mutate (ar * admissionv1.AdmissionReview ) * admissionv1.AdmissionResponse {
180+
251181 // Decode the Pod from the AdmissionReview
252182 pod := & corev1.Pod {}
253183 if err := json .Unmarshal (ar .Request .Object .Raw , pod ); err != nil {
@@ -273,7 +203,7 @@ func (ws *WebhookServer) mutate(ar *admissionv1.AdmissionReview) *admissionv1.Ad
273203 targetRef = targetRefDefault
274204 }
275205
276- // 2. Determine the target node's labels. We either have a homogenous cluster
206+ // Determine the target node's labels. We either have a homogenous cluster
277207 // (all nodes are the same) or we have to use a node selector for the image.
278208 var nodeLabels map [string ]string
279209 if len (pod .Spec .NodeSelector ) > 0 {
@@ -292,24 +222,24 @@ func (ws *WebhookServer) mutate(ar *admissionv1.AdmissionReview) *admissionv1.Ad
292222 nodeLabels = commonLabels
293223 }
294224
295- // 3. Download and parse the compatibility spec from the OCI registry.
225+ // Download and parse the compatibility spec from the OCI registry.
296226 ctx := context .Background ()
297227
298228 // Download the artifact (compatibility spec) from the uri
299- // TODO we should have mode to cache these and not need to re-download
229+ // TODO (vsoch) we should have mode to cache these and not need to re-download
300230 spec , err := artifact .DownloadCompatibilityArtifact (ctx , imageRef )
301231 if err != nil {
302232 return deny (ar , fmt .Sprintf ("compatibility spec %s issue: %v" , imageRef , err ))
303233 }
304234
305- // 4. Evaluate the spec against the node's labels to find the winning tag.
235+ // Evaluate the spec against the node's labels to find the winning tag.
306236 // The "tag" attribute we are hijacking here to put the full container URI
307237 finalImage , err := validator .EvaluateCompatibilitySpec (spec , nodeLabels )
308238 if err != nil {
309239 return deny (ar , fmt .Sprintf ("failed to find compatible image: %v" , err ))
310240 }
311241
312- // 6. Create and apply the JSON patch (this logic is unchanged).
242+ // Create and apply the JSON patch
313243 var patches []JSONPatch
314244 containerFound := false
315245 for i , c := range pod .Spec .Containers {
@@ -375,7 +305,7 @@ func (ws *WebhookServer) handleMutate(w http.ResponseWriter, r *http.Request) {
375305
376306func main () {
377307
378- // --- Kubernetes Client and Informer Setup ---
308+ // Kubernetes Client and Informer Setup
379309 // We want to have a view of cluster nodes via NFD
380310 config , err := clientcmd .BuildConfigFromFlags ("" , os .Getenv ("KUBECONFIG" ))
381311 if err != nil {
@@ -405,7 +335,7 @@ func main() {
405335 ws .recalculateHomogeneity ()
406336 },
407337 UpdateFunc : func (oldObj , newObj interface {}) {
408- // Optimization: only recalculate if compatibility labels have changed.
338+ // Only recalculate if compatibility labels have changed.
409339 oldNode := oldObj .(* corev1.Node )
410340 newNode := newObj .(* corev1.Node )
411341 if ! reflect .DeepEqual (getCompatibilityLabels (oldNode ), getCompatibilityLabels (newNode )) {
@@ -414,13 +344,13 @@ func main() {
414344 },
415345 })
416346
417- // Start informer and wait for cache sync (same as before)
347+ // Start informer and wait for cache sync
418348 go factory .Start (stopCh )
419349 if ! cache .WaitForCacheSync (stopCh , nodeInformer .HasSynced ) {
420350 log .Fatal ("failed to wait for caches to sync" )
421351 }
422352
423- // --- NEW: Perform the initial calculation after cache sync ---
353+ // Perform the initial calculation after cache sync
424354 log .Println ("Performing initial cluster homogeneity check..." )
425355 ws .recalculateHomogeneity ()
426356
@@ -446,7 +376,7 @@ func main() {
446376 }
447377 }()
448378
449- // Graceful shutdown
379+ // Graceful (or not so graceful) shutdown
450380 sigCh := make (chan os.Signal , 1 )
451381 signal .Notify (sigCh , syscall .SIGINT , syscall .SIGTERM )
452382 <- sigCh
0 commit comments