@@ -412,63 +412,141 @@ func printLocalFileSizes(basePath, buildID string) {
412412}
413413
414414func setupKernel (ctx context.Context , dir , version string ) error {
415- dstPath := filepath .Join (dir , version , "vmlinux.bin" )
415+ arch := utils .TargetArch ()
416+ dstPath := filepath .Join (dir , version , arch , "vmlinux.bin" )
417+
416418 if err := os .MkdirAll (filepath .Dir (dstPath ), 0o755 ); err != nil {
417419 return fmt .Errorf ("mkdir kernel dir: %w" , err )
418420 }
419421
420422 if _ , err := os .Stat (dstPath ); err == nil {
421- fmt .Printf ("✓ Kernel %s exists\n " , version )
423+ fmt .Printf ("✓ Kernel %s (%s) exists\n " , version , arch )
422424
423425 return nil
424426 }
425427
426- kernelURL , _ := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/kernels/" , version , "vmlinux.bin" )
427- fmt .Printf ("⬇ Downloading kernel %s...\n " , version )
428+ // Try arch-specific URL first: {version}/{arch}/vmlinux.bin
429+ archURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/kernels/" , version , arch , "vmlinux.bin" )
430+ if err != nil {
431+ return fmt .Errorf ("invalid kernel URL: %w" , err )
432+ }
433+
434+ fmt .Printf ("⬇ Downloading kernel %s (%s)...\n " , version , arch )
435+
436+ if err := download (ctx , archURL , dstPath , 0o644 ); err == nil {
437+ return nil
438+ } else if ! errors .Is (err , errNotFound ) {
439+ return fmt .Errorf ("failed to download kernel: %w" , err )
440+ }
441+
442+ // Legacy URLs are x86_64-only; only fall back for amd64.
443+ if arch != "amd64" {
444+ return fmt .Errorf ("kernel %s not found for %s (no legacy fallback for non-amd64)" , version , arch )
445+ }
446+
447+ legacyURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/kernels/" , version , "vmlinux.bin" )
448+ if err != nil {
449+ return fmt .Errorf ("invalid kernel legacy URL: %w" , err )
450+ }
451+
452+ fmt .Printf (" %s path not found, trying legacy URL...\n " , arch )
428453
429- return download (ctx , kernelURL , dstPath , 0o644 )
454+ return download (ctx , legacyURL , dstPath , 0o644 )
430455}
431456
432457func setupFC (ctx context.Context , dir , version string ) error {
433- dstPath := filepath .Join (dir , version , "firecracker" )
458+ arch := utils .TargetArch ()
459+ dstPath := filepath .Join (dir , version , arch , "firecracker" )
460+
434461 if err := os .MkdirAll (filepath .Dir (dstPath ), 0o755 ); err != nil {
435462 return fmt .Errorf ("mkdir firecracker dir: %w" , err )
436463 }
437464
438465 if _ , err := os .Stat (dstPath ); err == nil {
439- fmt .Printf ("✓ Firecracker %s exists\n " , version )
466+ fmt .Printf ("✓ Firecracker %s (%s) exists\n " , version , arch )
440467
441468 return nil
442469 }
443470
444- fcURL := fmt .Sprintf ("https://github.com/e2b-dev/fc-versions/releases/download/%s/firecracker" , version )
445- fmt .Printf ("⬇ Downloading Firecracker %s...\n " , version )
471+ // Download from GCS bucket with {version}/{arch}/firecracker path
472+ fcURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/fc-versions/" , version , arch , "firecracker" )
473+ if err != nil {
474+ return fmt .Errorf ("invalid Firecracker URL: %w" , err )
475+ }
476+
477+ fmt .Printf ("⬇ Downloading Firecracker %s (%s)...\n " , version , arch )
478+
479+ if err := download (ctx , fcURL , dstPath , 0o755 ); err == nil {
480+ return nil
481+ } else if ! errors .Is (err , errNotFound ) {
482+ return fmt .Errorf ("failed to download Firecracker: %w" , err )
483+ }
484+
485+ // Legacy URLs are x86_64-only; only fall back for amd64.
486+ if arch != "amd64" {
487+ return fmt .Errorf ("firecracker %s not found for %s (no legacy fallback for non-amd64)" , version , arch )
488+ }
489+
490+ legacyURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/fc-versions/" , version , "firecracker" )
491+ if err != nil {
492+ return fmt .Errorf ("invalid Firecracker legacy URL: %w" , err )
493+ }
494+
495+ fmt .Printf (" %s path not found, trying legacy URL...\n " , arch )
446496
447- return download (ctx , fcURL , dstPath , 0o755 )
497+ return download (ctx , legacyURL , dstPath , 0o755 )
448498}
449499
450- func download (ctx context.Context , url , path string , perm os.FileMode ) error {
451- req , _ := http .NewRequestWithContext (ctx , http .MethodGet , url , nil )
500+ var errNotFound = errors .New ("not found" )
501+
502+ func download (ctx context.Context , rawURL , path string , perm os.FileMode ) error {
503+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , rawURL , nil )
504+ if err != nil {
505+ return fmt .Errorf ("invalid download URL %s: %w" , rawURL , err )
506+ }
507+
452508 resp , err := (& http.Client {Timeout : 5 * time .Minute }).Do (req )
453509 if err != nil {
454510 return err
455511 }
456512 defer resp .Body .Close ()
457513
514+ if resp .StatusCode == http .StatusNotFound {
515+ return fmt .Errorf ("%w: %s" , errNotFound , rawURL )
516+ }
458517 if resp .StatusCode != http .StatusOK {
459- return fmt .Errorf ("HTTP %d: %s" , resp .StatusCode , url )
518+ return fmt .Errorf ("HTTP %d: %s" , resp .StatusCode , rawURL )
460519 }
461520
462- f , err := os .OpenFile (path , os .O_CREATE | os .O_WRONLY | os .O_TRUNC , perm )
521+ // Write to a temporary file and rename atomically to avoid partial files
522+ // on network errors or disk-full conditions.
523+ tmpPath := path + ".tmp"
524+
525+ f , err := os .OpenFile (tmpPath , os .O_CREATE | os .O_WRONLY | os .O_TRUNC , perm )
463526 if err != nil {
464527 return err
465528 }
466- defer f .Close ()
467529
468- _ , err = io .Copy (f , resp .Body )
469- if err == nil {
470- fmt .Printf ("✓ Downloaded %s\n " , filepath .Base (path ))
530+ if _ , err := io .Copy (f , resp .Body ); err != nil {
531+ f .Close ()
532+ os .Remove (tmpPath )
533+
534+ return err
535+ }
536+
537+ if err := f .Close (); err != nil {
538+ os .Remove (tmpPath )
539+
540+ return err
471541 }
472542
473- return err
543+ if err := os .Rename (tmpPath , path ); err != nil {
544+ os .Remove (tmpPath )
545+
546+ return err
547+ }
548+
549+ fmt .Printf ("✓ Downloaded %s\n " , filepath .Base (path ))
550+
551+ return nil
474552}
0 commit comments