diff --git a/pkg/agent/core.go b/pkg/agent/core.go index e382dc1..4c38e17 100644 --- a/pkg/agent/core.go +++ b/pkg/agent/core.go @@ -235,6 +235,7 @@ type AgentCoreConfig struct { AgentsDir string SessionsDir string SessionID string + Uname string // immutable user principal for 9P identity CWD string // working directory for tool execution and system prompt Session *Session Env AgentEnv @@ -257,6 +258,7 @@ type agent struct { agentsDir string sessionsDir string sessionID string + uname string dispatcher tools.Dispatcher newDispatcher func() tools.Dispatcher newBackend func(string) (backend.Backend, error) @@ -311,6 +313,9 @@ func (s *agent) pushSessionEnv() { if srv, ok := s.dispatcher.GetServer("execute"); ok { if es, ok := srv.(tools.EnvSetter); ok { es.SetEnv("OLLIE_SESSION_ID", s.sessionID) + if s.uname != "" { + es.SetEnv("OLLIE_UNAME", s.uname) + } } } } @@ -416,6 +421,7 @@ func NewAgentCore(cfg AgentCoreConfig) Core { agentsDir: cfg.AgentsDir, sessionsDir: cfg.SessionsDir, sessionID: cfg.SessionID, + uname: cfg.Uname, cwd: paths.ExpandHome(cfg.CWD), startupMessages: cfg.Env.Messages, dispatcher: cfg.Env.dispatcher, diff --git a/pkg/tools/execute/server.go b/pkg/tools/execute/server.go index e40492b..eb822d0 100644 --- a/pkg/tools/execute/server.go +++ b/pkg/tools/execute/server.go @@ -42,8 +42,9 @@ type Server struct { lockDir string // mountProc is the ollie-9p-mount subprocess for this session's FUSE proxy. - mountProc *os.Process - mountPath string + mountProc *os.Process + mountPath string + mountEnabled bool // Strict rejects inline {code} steps; only {tool} steps are allowed. Strict bool @@ -75,6 +76,9 @@ func WithStrict() Option { return func(s *Server) { s.Strict = true } } // WithYolo skips the landrun sandbox. func WithYolo() Option { return func(s *Server) { s.Yolo = true } } +// WithMount enables per-session FUSE mount for 9P identity. +func WithMount() Option { return func(s *Server) { s.mountEnabled = true } } + // WithAllowExecutors restricts which executors are available. func WithAllowExecutors(names []string) Option { return func(s *Server) { @@ -362,7 +366,8 @@ func (e *Server) SetEnv(key, value string) { e.envExtra = make(map[string]string) } e.envExtra[key] = value - if key == "OLLIE_SESSION_ID" && value != "" { + // Start mount once we have the principal. + if key == "OLLIE_UNAME" && value != "" { e.startMount(value) } e.envMu.Unlock() @@ -370,9 +375,12 @@ func (e *Server) SetEnv(key, value string) { // startMount launches ollie-9p-mount for this session. Must be called with envMu held. func (e *Server) startMount(sessionID string) { + if !e.mountEnabled { + return + } bin, err := exec.LookPath("ollie-9p-mount") if err != nil { - return // binary not installed; skip silently + return } mnt := filepath.Join(os.TempDir(), "ollie-mount-"+sessionID) os.MkdirAll(mnt, 0755) //nolint:errcheck @@ -404,9 +412,11 @@ func (e *Server) Close() { e.mountPath = "" e.envMu.Unlock() if proc != nil { - exec.Command("fusermount", "-u", mnt).Run() //nolint:errcheck - syscall.Kill(proc.Pid, syscall.SIGKILL) //nolint:errcheck - os.Remove(mnt) //nolint:errcheck + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + exec.CommandContext(ctx, "fusermount", "-u", mnt).Run() //nolint:errcheck + cancel() + syscall.Kill(proc.Pid, syscall.SIGKILL) //nolint:errcheck + os.Remove(mnt) //nolint:errcheck } }