@@ -408,63 +408,141 @@ func printLocalFileSizes(basePath, buildID string) {
408408}
409409
410410func setupKernel (ctx context.Context , dir , version string ) error {
411- dstPath := filepath .Join (dir , version , "vmlinux.bin" )
411+ arch := utils .TargetArch ()
412+ dstPath := filepath .Join (dir , version , arch , "vmlinux.bin" )
413+
412414 if err := os .MkdirAll (filepath .Dir (dstPath ), 0o755 ); err != nil {
413415 return fmt .Errorf ("mkdir kernel dir: %w" , err )
414416 }
415417
416418 if _ , err := os .Stat (dstPath ); err == nil {
417- fmt .Printf ("✓ Kernel %s exists\n " , version )
419+ fmt .Printf ("✓ Kernel %s (%s) exists\n " , version , arch )
418420
419421 return nil
420422 }
421423
422- kernelURL , _ := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/kernels/" , version , "vmlinux.bin" )
423- fmt .Printf ("⬇ Downloading kernel %s...\n " , version )
424+ // Try arch-specific URL first: {version}/{arch}/vmlinux.bin
425+ archURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/kernels/" , version , arch , "vmlinux.bin" )
426+ if err != nil {
427+ return fmt .Errorf ("invalid kernel URL: %w" , err )
428+ }
429+
430+ fmt .Printf ("⬇ Downloading kernel %s (%s)...\n " , version , arch )
431+
432+ if err := download (ctx , archURL , dstPath , 0o644 ); err == nil {
433+ return nil
434+ } else if ! errors .Is (err , errNotFound ) {
435+ return fmt .Errorf ("failed to download kernel: %w" , err )
436+ }
437+
438+ // Legacy URLs are x86_64-only; only fall back for amd64.
439+ if arch != "amd64" {
440+ return fmt .Errorf ("kernel %s not found for %s (no legacy fallback for non-amd64)" , version , arch )
441+ }
442+
443+ legacyURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/kernels/" , version , "vmlinux.bin" )
444+ if err != nil {
445+ return fmt .Errorf ("invalid kernel legacy URL: %w" , err )
446+ }
447+
448+ fmt .Printf (" %s path not found, trying legacy URL...\n " , arch )
424449
425- return download (ctx , kernelURL , dstPath , 0o644 )
450+ return download (ctx , legacyURL , dstPath , 0o644 )
426451}
427452
428453func setupFC (ctx context.Context , dir , version string ) error {
429- dstPath := filepath .Join (dir , version , "firecracker" )
454+ arch := utils .TargetArch ()
455+ dstPath := filepath .Join (dir , version , arch , "firecracker" )
456+
430457 if err := os .MkdirAll (filepath .Dir (dstPath ), 0o755 ); err != nil {
431458 return fmt .Errorf ("mkdir firecracker dir: %w" , err )
432459 }
433460
434461 if _ , err := os .Stat (dstPath ); err == nil {
435- fmt .Printf ("✓ Firecracker %s exists\n " , version )
462+ fmt .Printf ("✓ Firecracker %s (%s) exists\n " , version , arch )
436463
437464 return nil
438465 }
439466
440- fcURL := fmt .Sprintf ("https://github.com/e2b-dev/fc-versions/releases/download/%s/firecracker" , version )
441- fmt .Printf ("⬇ Downloading Firecracker %s...\n " , version )
467+ // Download from GCS bucket with {version}/{arch}/firecracker path
468+ fcURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/fc-versions/" , version , arch , "firecracker" )
469+ if err != nil {
470+ return fmt .Errorf ("invalid Firecracker URL: %w" , err )
471+ }
472+
473+ fmt .Printf ("⬇ Downloading Firecracker %s (%s)...\n " , version , arch )
474+
475+ if err := download (ctx , fcURL , dstPath , 0o755 ); err == nil {
476+ return nil
477+ } else if ! errors .Is (err , errNotFound ) {
478+ return fmt .Errorf ("failed to download Firecracker: %w" , err )
479+ }
480+
481+ // Legacy URLs are x86_64-only; only fall back for amd64.
482+ if arch != "amd64" {
483+ return fmt .Errorf ("firecracker %s not found for %s (no legacy fallback for non-amd64)" , version , arch )
484+ }
485+
486+ legacyURL , err := url .JoinPath ("https://storage.googleapis.com/e2b-prod-public-builds/fc-versions/" , version , "firecracker" )
487+ if err != nil {
488+ return fmt .Errorf ("invalid Firecracker legacy URL: %w" , err )
489+ }
490+
491+ fmt .Printf (" %s path not found, trying legacy URL...\n " , arch )
442492
443- return download (ctx , fcURL , dstPath , 0o755 )
493+ return download (ctx , legacyURL , dstPath , 0o755 )
444494}
445495
446- func download (ctx context.Context , url , path string , perm os.FileMode ) error {
447- req , _ := http .NewRequestWithContext (ctx , http .MethodGet , url , nil )
496+ var errNotFound = errors .New ("not found" )
497+
498+ func download (ctx context.Context , rawURL , path string , perm os.FileMode ) error {
499+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , rawURL , nil )
500+ if err != nil {
501+ return fmt .Errorf ("invalid download URL %s: %w" , rawURL , err )
502+ }
503+
448504 resp , err := (& http.Client {Timeout : 5 * time .Minute }).Do (req )
449505 if err != nil {
450506 return err
451507 }
452508 defer resp .Body .Close ()
453509
510+ if resp .StatusCode == http .StatusNotFound {
511+ return fmt .Errorf ("%w: %s" , errNotFound , rawURL )
512+ }
454513 if resp .StatusCode != http .StatusOK {
455- return fmt .Errorf ("HTTP %d: %s" , resp .StatusCode , url )
514+ return fmt .Errorf ("HTTP %d: %s" , resp .StatusCode , rawURL )
456515 }
457516
458- f , err := os .OpenFile (path , os .O_CREATE | os .O_WRONLY | os .O_TRUNC , perm )
517+ // Write to a temporary file and rename atomically to avoid partial files
518+ // on network errors or disk-full conditions.
519+ tmpPath := path + ".tmp"
520+
521+ f , err := os .OpenFile (tmpPath , os .O_CREATE | os .O_WRONLY | os .O_TRUNC , perm )
459522 if err != nil {
460523 return err
461524 }
462- defer f .Close ()
463525
464- _ , err = io .Copy (f , resp .Body )
465- if err == nil {
466- fmt .Printf ("✓ Downloaded %s\n " , filepath .Base (path ))
526+ if _ , err := io .Copy (f , resp .Body ); err != nil {
527+ f .Close ()
528+ os .Remove (tmpPath )
529+
530+ return err
531+ }
532+
533+ if err := f .Close (); err != nil {
534+ os .Remove (tmpPath )
535+
536+ return err
467537 }
468538
469- return err
539+ if err := os .Rename (tmpPath , path ); err != nil {
540+ os .Remove (tmpPath )
541+
542+ return err
543+ }
544+
545+ fmt .Printf ("✓ Downloaded %s\n " , filepath .Base (path ))
546+
547+ return nil
470548}
0 commit comments