From 8ce83904212225652c3fd7f726f3a0e1edf907ce Mon Sep 17 00:00:00 2001 From: Ollie Agent Date: Tue, 11 Aug 2026 21:12:51 +0200 Subject: [PATCH] toolsrv/fs: move Server into spec.go, delete state.go Server is the top-level type that Spec() takes as input. It belongs with the namespace declaration, not in a separate file. --- cmd/toolsrv/internal/fs/spec.go | 92 +++++++++++++++++++++++++++ cmd/toolsrv/internal/fs/state.go | 103 ------------------------------- 2 files changed, 92 insertions(+), 103 deletions(-) delete mode 100644 cmd/toolsrv/internal/fs/state.go diff --git a/cmd/toolsrv/internal/fs/spec.go b/cmd/toolsrv/internal/fs/spec.go index d4faa2f..849bbc7 100644 --- a/cmd/toolsrv/internal/fs/spec.go +++ b/cmd/toolsrv/internal/fs/spec.go @@ -3,14 +3,106 @@ package fs import ( "context" + "crypto/rand" + "encoding/hex" "fmt" "os" + "runtime" "strconv" "strings" + "sync" + "ollie/cmd/toolsrv/internal/registry" "ollie/virtfs" ) +// Server holds the state for the toolsrv 9P server. +type Server struct { + mu sync.RWMutex + + secret string // set on first auth, verified on subsequent + token string // session token returned after auth + registry *registry.Registry // tool registry + yolo bool // skip sandbox + + // Process management + Fs *State +} + +// NewServer creates a new toolsrv server. +func NewServer() *Server { + return &Server{ + Fs: NewState(""), // cwd set per-agent + } +} + +// SetRegistry configures the tool registry. +func (s *Server) SetRegistry(r *registry.Registry) { + s.mu.Lock() + s.registry = r + s.Fs.SetRegistry(r) + s.mu.Unlock() +} + +// SetYolo enables/disables sandbox bypass. +func (s *Server) SetYolo(yolo bool) { + s.mu.Lock() + s.yolo = yolo + s.Fs.SetYolo(yolo) + s.mu.Unlock() +} + +// Authenticate handles secret verification. +// First call sets the secret; subsequent calls must match it. +func (s *Server) Authenticate(clientSecret string) (string, error) { + s.mu.Lock() + defer s.mu.Unlock() + + if s.secret == "" { + s.secret = clientSecret + s.token = randomToken() + return s.token, nil + } + + if clientSecret != s.secret { + return "", fmt.Errorf("authentication failed") + } + + return s.token, nil +} + +// Token returns the current session token. +func (s *Server) Token() string { + s.mu.RLock() + defer s.mu.RUnlock() + return s.token +} + +// HostInfo returns platform info as key=value lines. +func (s *Server) HostInfo() string { + return fmt.Sprintf("platform=%s\narch=%s\n", runtime.GOOS, runtime.GOARCH) +} + +// BuildTree creates the virtfs tree for this server. +func (s *Server) BuildTree() *virtfs.Tree { + return virtfs.BuildTree(Spec(s)) +} + +// GenerateSecret generates a random shared secret for toolsrv auth. +func GenerateSecret() (string, error) { + secret := make([]byte, 32) + if _, err := rand.Read(secret); err != nil { + return "", err + } + return hex.EncodeToString(secret), nil +} + +func randomToken() string { + b := make([]byte, 16) + rand.Read(b) + return hex.EncodeToString(b) +} + // Spec returns the virtfs specification for the toolsrv namespace. // The server is captured by closures — no context threading needed. func Spec(srv *Server) virtfs.FsNodeDecl { diff --git a/cmd/toolsrv/internal/fs/state.go b/cmd/toolsrv/internal/fs/state.go deleted file mode 100644 index 828539f..0000000 --- a/cmd/toolsrv/internal/fs/state.go +++ /dev/null @@ -1,103 +0,0 @@ -// state.go - Server state management for toolsrv. -package fs - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "runtime" - "sync" - - "ollie/cmd/toolsrv/internal/registry" - "ollie/virtfs" -) - -// Server holds the state for the toolsrv 9P server. -type Server struct { - mu sync.RWMutex - - secret string // set on first auth, verified on subsequent - token string // session token returned after auth - registry *registry.Registry // tool registry - yolo bool // skip sandbox - - // Process management - Fs *State -} - -// NewServer creates a new toolsrv server. -func NewServer() *Server { - return &Server{ - Fs: NewState(""), // cwd set per-agent - } -} - -// SetRegistry configures the tool registry. -func (s *Server) SetRegistry(r *registry.Registry) { - s.mu.Lock() - s.registry = r - s.Fs.SetRegistry(r) - s.mu.Unlock() -} - -// SetYolo enables/disables sandbox bypass. -func (s *Server) SetYolo(yolo bool) { - s.mu.Lock() - s.yolo = yolo - s.Fs.SetYolo(yolo) - s.mu.Unlock() -} - -// Authenticate handles secret verification. -// First call sets the secret; subsequent calls must match it. -// Returns (token, nil) on success, ("", error) on failure. -func (s *Server) Authenticate(clientSecret string) (string, error) { - s.mu.Lock() - defer s.mu.Unlock() - - if s.secret == "" { - // First auth - set the secret - s.secret = clientSecret - s.token = randomToken() - return s.token, nil - } - - // Subsequent auth - verify secret - if clientSecret != s.secret { - return "", fmt.Errorf("authentication failed") - } - - return s.token, nil -} - -// Token returns the current session token (empty if not authenticated). -func (s *Server) Token() string { - s.mu.RLock() - defer s.mu.RUnlock() - return s.token -} - -// HostInfo returns platform info as key=value lines. -func (s *Server) HostInfo() string { - return fmt.Sprintf("platform=%s\narch=%s\n", runtime.GOOS, runtime.GOARCH) -} - -// BuildTree creates the virtfs tree for this server. -func (s *Server) BuildTree() *virtfs.Tree { - return virtfs.BuildTree(Spec(s)) -} - -// GenerateSecret generates a random shared secret for toolsrv auth. -func GenerateSecret() (string, error) { - secret := make([]byte, 32) - if _, err := rand.Read(secret); err != nil { - return "", err - } - return hex.EncodeToString(secret), nil -} - -func randomToken() string { - b := make([]byte, 16) - rand.Read(b) - return hex.EncodeToString(b) -}