Something went wrong. Try again.
Social cloud hosting
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166package cli
import ( "fmt" "os" "os/exec" "os/signal" "syscall"
"github.com/neutrino2211/at-rund/internal/atproto" "github.com/neutrino2211/at-rund/internal/config" "github.com/neutrino2211/at-rund/internal/server" "github.com/neutrino2211/at-rund/internal/vm" "github.com/spf13/cobra")
var ( servePort int serveDev bool serveIsolation string)
var serveCmd = &cobra.Command{ Use: "serve", Short: "Start the at-rund server", Long: `Starts the HTTP server and initializes the execution backend.`, RunE: runServe,}
func init() { serveCmd.Flags().IntVarP(&servePort, "port", "p", 0, "port to listen on (default: from config)") serveCmd.Flags().BoolVar(&serveDev, "dev", false, "enable development mode (alias for --isolation=none)") serveCmd.Flags().StringVar(&serveIsolation, "isolation", "", "isolation backend: auto, none, container, firecracker")}
func kvmAvailable() bool { _, err := os.Stat("/dev/kvm") return err == nil}
func dockerAvailable() bool { cmd := exec.Command("docker", "info") return cmd.Run() == nil}
func podmanAvailable() bool { cmd := exec.Command("podman", "info") return cmd.Run() == nil}
func detectIsolation() string { if kvmAvailable() { return "firecracker" } if dockerAvailable() || podmanAvailable() { return "container" } return "none"}
func runServe(cmd *cobra.Command, args []string) error { // Load config cfg, err := config.Load(cfgFile) if err != nil { return fmt.Errorf("failed to load config: %w", err) }
// Override with flags if servePort != 0 { cfg.Port = servePort } if serveDev { cfg.Isolation = "none" } if serveIsolation != "" { cfg.Isolation = serveIsolation }
// Auto-detect isolation if set to auto or empty if cfg.Isolation == "" || cfg.Isolation == "auto" { cfg.Isolation = detectIsolation() }
fmt.Printf("at-rund starting...\n") fmt.Printf(" Port: %d\n", cfg.Port) fmt.Printf(" Isolation: %s\n", cfg.Isolation) if cfg.DID != "" { fmt.Printf(" DID: %s\n", cfg.DID) }
// Initialize executor based on isolation mode var executor vm.Executor flakePath := vm.GetFlakePath()
switch cfg.Isolation { case "none": fmt.Println(" Executor: Nix (direct execution, no isolation)") executor, err = vm.NewNixPool(flakePath) if err != nil { fmt.Println("\n Nix is required. Install it with:") fmt.Println(" curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install") fmt.Println("") return fmt.Errorf("failed to initialize Nix executor: %w", err) }
case "container": fmt.Println(" Executor: Container (namespace isolation)") executor, err = vm.NewContainerPool(flakePath) if err != nil { fmt.Println("\n Docker or Podman is required for container isolation.") fmt.Println(" Install Docker: https://docs.docker.com/engine/install/") fmt.Println(" Or use --isolation=none for dev mode") fmt.Println("") return fmt.Errorf("failed to initialize Container executor: %w", err) }
case "firecracker": fmt.Println(" Executor: Firecracker (VM isolation)") if !kvmAvailable() { return fmt.Errorf("firecracker requires KVM (/dev/kvm not accessible)") } executor, err = vm.NewFirecrackerPool(nil) if err != nil { return fmt.Errorf("failed to initialize Firecracker pool: %w", err) }
default: return fmt.Errorf("unknown isolation mode: %s (valid: auto, none, container, firecracker)", cfg.Isolation) } defer executor.Shutdown()
// Pre-warm if configured if cfg.Pool.PreWarm > 0 { fmt.Printf(" Pre-warming runtimes...\n") if err := executor.Warm(cfg.Pool.PreWarm); err != nil { fmt.Printf(" Warning: failed to pre-warm: %v\n", err) } }
// Initialize bundle client bundleClient := atproto.NewBundleClient(cfg.BundlesDir(), cfg.DevMode) fmt.Println(" Bundle client: ready")
// Start HTTP server srv := server.New(cfg, executor, bundleClient)
// Handle shutdown gracefully sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
errCh := make(chan error, 1) go func() { fmt.Printf("\nListening on http://localhost:%d\n", cfg.Port) errCh <- srv.ListenAndServe() }()
select { case err := <-errCh: return err case sig := <-sigCh: fmt.Printf("\nReceived %s, shutting down...\n", sig) executor.Drain() return srv.Shutdown() }}