@@ -2,10 +2,10 @@ package main
22
33import (
44 "context"
5+ crand "crypto/rand"
56 "flag"
67 "fmt"
78 "log"
8- "math/rand"
99 "net"
1010 "net/url"
1111 "os"
@@ -245,48 +245,30 @@ func registerWithMAAS(maasEndpoint, maasAPIKey, systemID, nodeIP, trustPassword,
245245 ctx := context .Background ()
246246 client := maasclient .NewAuthenticatedClientSet (maasEndpoint , maasAPIKey )
247247
248- // Guard 1: Verify the MAAS machine identified by systemID owns nodeIP (or derive power IP)
249- m , err := client .Machines ().Machine (systemID ).Get (ctx )
250- if err != nil {
251- return fmt .Errorf ("get machine %s: %w" , systemID , err )
252- }
253- hostIP := nodeIP
254- owns := false
255- for _ , ip := range m .IPAddresses () {
256- if ip .String () == nodeIP {
257- owns = true
258- break
259- }
260- }
261- if ! owns {
262- ips := m .IPAddresses ()
263- if len (ips ) == 0 {
264- return fmt .Errorf ("ownership check failed: system-id %s has no IPs; cannot register" , systemID )
265- }
266- hostIP = ips [0 ].String ()
267- }
268-
269248 // Idempotency/conflict checks via API for speed
270249 hosts , err := client .VMHosts ().List (ctx , nil )
271250 if err != nil {
272251 return fmt .Errorf ("list vm hosts: %w" , err )
273252 }
274- // Align with manual flow: bare IP for power_address
275- wantHost := hostIP
253+ // Align with manual flow: bare IP for power_address (still used for create below)
254+ wantHost := nodeIP
255+ // Strict guards: rely only on name and system-id for idempotency
256+ expectedName := hostName
276257 for _ , h := range hosts {
277- if normalizeHost (h .PowerAddress ()) == normalizeHost (wantHost ) {
278- if h .HostSystemID () != "" && h .HostSystemID () != systemID {
279- return fmt .Errorf ("conflict: existing VM host %s uses %s mapped to %s" , h .Name (), wantHost , h .HostSystemID ())
258+ // 1) Exact name match → idempotent or conflict
259+ if h .Name () == expectedName {
260+ if h .HostSystemID () == "" || h .HostSystemID () == systemID {
261+ log .Printf ("MAAS VM host already present (name=%s, system-id=%s); skipping re-registration" , h .Name (), h .HostSystemID ())
262+ return nil
280263 }
281- if h .Name () != hostName {
282- return fmt .Errorf ("conflict: power_address %s already used by VM host %s (name mismatch)" , wantHost , h .Name ())
283- }
284- log .Printf ("MAAS VM host already present: name=%s power_address=%s" , h .Name (), h .PowerAddress ())
285- return nil
264+ return fmt .Errorf ("conflict: VM host %q belongs to system-id %s (expected %s)" , h .Name (), h .HostSystemID (), systemID )
286265 }
287- if h .Name () == hostName && h .HostSystemID () != "" && h .HostSystemID () != systemID {
288- return fmt .Errorf ("conflict: existing VM host %s belongs to system-id %s (expected %s)" , h .Name (), h .HostSystemID (), systemID )
266+ // 2) Same system already registered under a different name → idempotent
267+ if h .HostSystemID () == systemID {
268+ log .Printf ("MAAS VM host for system-id=%s already exists under name=%s; skipping re-registration" , systemID , h .Name ())
269+ return nil
289270 }
271+ // 3) Non-matching entry → ignore
290272 }
291273
292274 // Prefer MAAS CLI for creation to match manual success path
@@ -561,6 +543,20 @@ func main() {
561543 actionStr = "both" // Default to both init and register
562544 }
563545
546+ // Early exit: if node already marked initialized, skip all work
547+ if nodeName != "" {
548+ if client , err := getKubernetesClient (); err == nil {
549+ if node , gerr := client .CoreV1 ().Nodes ().Get (context .TODO (), nodeName , metav1.GetOptions {}); gerr == nil {
550+ if node .Labels != nil {
551+ if node .Labels [LXDHostInitializedLabel ] == LabelValueTrue {
552+ log .Printf ("Node %s already labeled %s=true; skipping initializer" , nodeName , LXDHostInitializedLabel )
553+ return
554+ }
555+ }
556+ }
557+ }
558+ }
559+
564560 // Perform actions based on the specified action
565561 if actionStr == "init" || actionStr == "both" {
566562 // Initialize LXD
@@ -632,8 +628,16 @@ func main() {
632628 }
633629 actualDelaySec := delaySec
634630 if jitterSec > 0 {
635- rand .Seed (time .Now ().UnixNano ())
636- actualDelaySec += rand .Intn (jitterSec + 1 )
631+ // crypto-strong jitter in [0, jitterSec]
632+ var rb [8 ]byte
633+ if _ , err := crand .Read (rb [:]); err == nil {
634+ // Convert to uint64, then mod
635+ rnd := int (rb [0 ])
636+ if jitterSec > 0 {
637+ rnd = rnd % (jitterSec + 1 )
638+ }
639+ actualDelaySec += rnd
640+ }
637641 }
638642 delay := time .Duration (actualDelaySec ) * time .Second
639643 log .Printf ("LXD init complete; staggering for %v before host registration (index=%d/%d, per=%ds, cap=%ds, jitter<=%ds)" , delay , nodeIndex , nodeCount , perNodeSec , maxCapSec , jitterSec )
0 commit comments