package server import ( "io" "net/http" "os" "path/filepath" "time" ) func (s *Server) adminExecEnv(w http.ResponseWriter, r *http.Request) { if _, ok := s.requireAdmin(w, r); !ok { return } if s.ExecEnv == nil { writeJSON(w, http.StatusOK, map[string]any{"configured": false}) return } base, err := s.ExecEnv.Root.CurrentBase() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } reqs, err := s.ExecEnv.Store.ListExecEnvRequests("", 50) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } binds, err := s.ExecEnv.Store.ListExecEnvBindings() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } bin, _ := s.ExecEnv.Root.PythonBin() ents, _ := os.ReadDir(s.ExecEnv.Root.LayersDir()) layers := make([]string, 0, len(ents)) for _, ent := range ents { if ent.IsDir() { layers = append(layers, ent.Name()) } } writeJSON(w, http.StatusOK, map[string]any{ "configured": true, "root": s.ExecEnv.Root.Path, "python": bin, "base": base, "layers": layers, "requests": reqs, "bindings": binds, }) } func (s *Server) adminExecEnvDecision(w http.ResponseWriter, r *http.Request) { actor, ok := s.requireAdmin(w, r) if !ok { return } if s.ExecEnv == nil { http.Error(w, "exec env is not configured", http.StatusConflict) return } var body struct { Allow bool `json:"allow"` Isolate bool `json:"isolate"` } if err := decodeJSON(r, &body); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } out, err := s.ExecEnv.Decide(r.Context(), r.PathValue("id"), actor, true, body.Allow, body.Isolate) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } writeJSON(w, http.StatusOK, out) } func (s *Server) adminExecEnvRebase(w http.ResponseWriter, r *http.Request) { if _, ok := s.requireAdmin(w, r); !ok { return } if s.ExecEnv == nil { http.Error(w, "exec env is not configured", http.StatusConflict) return } id, err := s.ExecEnv.Rebase(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusBadGateway) return } writeJSON(w, http.StatusOK, map[string]any{"base": id}) } func (s *Server) adminExecEnvGC(w http.ResponseWriter, r *http.Request) { if _, ok := s.requireAdmin(w, r); !ok { return } if s.ExecEnv == nil { http.Error(w, "exec env is not configured", http.StatusConflict) return } removed, err := s.ExecEnv.GC(7 * 24 * time.Hour) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } writeJSON(w, http.StatusOK, map[string]any{"removed": removed}) } func (s *Server) adminExecEnvWheel(w http.ResponseWriter, r *http.Request) { actor, ok := s.requireAdmin(w, r) if !ok { return } if s.ExecEnv == nil { http.Error(w, "exec env is not configured", http.StatusConflict) return } if err := r.ParseMultipartForm(64 << 20); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } file, hdr, err := r.FormFile("wheel") if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } defer file.Close() dir := filepath.Join(s.ExecEnv.Root.Path, "uploads") if err := os.MkdirAll(dir, 0o755); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } dst, err := os.CreateTemp(dir, "upload-*.whl") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if _, err := io.Copy(dst, file); err != nil { dst.Close() http.Error(w, err.Error(), http.StatusInternalServerError) return } dst.Close() out, err := s.ExecEnv.RequestPackages(r.Context(), r.FormValue("conversationId"), actor, r.FormValue("reason"), nil, dst.Name()) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } writeJSON(w, http.StatusOK, map[string]any{"file": hdr.Filename, "outcome": out}) }