9p: rename s/ → session/ in filesystem namespace

The top-level sessions directory is now /session/ instead of /s/.
Clearer, self-documenting namespace. The agent/{aid} sublevel
will be added in a future change.
This commit is contained in:
Levi Neely 2026-07-29 20:32:50 +02:00
parent f75dbc33a7
commit 55fcebd032
2 changed files with 15 additions and 15 deletions

View File

@ -17,11 +17,11 @@ import "os"
// {file} — file name within a session directory // {file} — file name within a session directory
const ( const (
PathRoot = "/" PathRoot = "/"
PathSessions = "/s/" PathSessions = "/session/"
PathElevate = "/elevate/" PathElevate = "/elevate/"
PathSessionDir = "s/{id}" PathSessionDir = "session/{id}"
PathTools = "t/" PathTools = "t/"
PathSessionFile = "s/{id}/{file}" PathSessionFile = "session/{id}/{file}"
) )
// Perm declares permissions for a filesystem node. // Perm declares permissions for a filesystem node.

View File

@ -257,7 +257,7 @@ func (s *Server) InGroup(group, user string) bool {
} }
// fileOwnerGroup returns the uid and gid for a given path. // fileOwnerGroup returns the uid and gid for a given path.
// Session namespace (/s/{sid}/**) is owned by the agent principal with group "agent". // Session namespace (/session/{sid}/**) is owned by the agent principal with group "agent".
// Everything else is owned by the current system user and their primary group. // Everything else is owned by the current system user and their primary group.
func (s *Server) fileOwnerGroup(path string) (uid, gid string) { func (s *Server) fileOwnerGroup(path string) (uid, gid string) {
if strings.HasPrefix(path, fs.PathSessions) { if strings.HasPrefix(path, fs.PathSessions) {
@ -484,8 +484,8 @@ func fcallTypeName(t uint8) string {
} }
} }
// isSessionFile reports whether path is a fixed file directly under /s/ // isSessionFile reports whether path is a fixed file directly under /session/
// (i.e. /s/<name> where name is in sessionStoreFiles). // (i.e. /session/<name> where name is in sessionStoreFiles).
func isSessionFile(path string) bool { func isSessionFile(path string) bool {
name, ok := strings.CutPrefix(path, fs.PathSessions) name, ok := strings.CutPrefix(path, fs.PathSessions)
if !ok || strings.Contains(name, "/") { if !ok || strings.Contains(name, "/") {
@ -525,18 +525,18 @@ func (s *Server) pathType(path string) string {
if strings.HasPrefix(path, fs.PathSessions) { if strings.HasPrefix(path, fs.PathSessions) {
name := strings.TrimPrefix(path, fs.PathSessions) name := strings.TrimPrefix(path, fs.PathSessions)
if !strings.Contains(name, "/") { if !strings.Contains(name, "/") {
// /s/{name} — could be a session dir or a fixed file (new, idx, ls, etc.) // /session/{name} — could be a session dir or a fixed file (new, idx, ls, etc.)
if isSessionFile(path) { if isSessionFile(path) {
return "file" return "file"
} }
return "dir" return "dir"
} }
// /s/{id}/peer or /s/{id}/proc — directory // /session/{id}/peer or /session/{id}/proc — directory
parts := strings.SplitN(name, "/", 3) parts := strings.SplitN(name, "/", 3)
if len(parts) == 2 && (parts[1] == "peer" || parts[1] == "proc") { if len(parts) == 2 && (parts[1] == "peer" || parts[1] == "proc") {
return "dir" return "dir"
} }
// /s/{id}/peer/{peer-id} — verify peer exists // /session/{id}/peer/{peer-id} — verify peer exists
if len(parts) == 3 && parts[1] == "peer" { if len(parts) == 3 && parts[1] == "peer" {
sess := s.sessionMgr.Session(parts[0]) sess := s.sessionMgr.Session(parts[0])
if sess == nil { if sess == nil {
@ -547,7 +547,7 @@ func (s *Server) pathType(path string) string {
} }
return "" return ""
} }
// /s/{id}/proc/{pid} — verify PID exists in detached list // /session/{id}/proc/{pid} — verify PID exists in detached list
if len(parts) == 3 && parts[1] == "proc" { if len(parts) == 3 && parts[1] == "proc" {
sess := s.sessionMgr.Session(parts[0]) sess := s.sessionMgr.Session(parts[0])
if sess == nil { if sess == nil {
@ -560,7 +560,7 @@ func (s *Server) pathType(path string) string {
} }
return "" return ""
} }
// /s/{id}/{file} — file // /session/{id}/{file} — file
return "file" return "file"
} }
@ -1126,7 +1126,7 @@ func (s *Server) buildDirData(path string) []byte {
var dirs []plan9.Dir var dirs []plan9.Dir
if path == "/" { if path == "/" {
rootEntries := []string{"agents", "backends", "complete", "ctl", "generate", "help", "models", "route", "s"} rootEntries := []string{"agents", "backends", "complete", "ctl", "generate", "help", "models", "route", "session"}
for _, name := range rootEntries { for _, name := range rootEntries {
fpath := "/" + name fpath := "/" + name
st := s.makeStat(fpath) st := s.makeStat(fpath)
@ -1145,7 +1145,7 @@ func (s *Server) buildDirData(path string) []byte {
dirs = append(dirs, d) dirs = append(dirs, d)
} }
} else if st, name := s.route(path); st != nil { } else if st, name := s.route(path); st != nil {
// Subdirectory within a tree (e.g. /s/mysession, /s/mysession/t). // Subdirectory within a tree (e.g. /session/mysession, /session/mysession/t).
type dirLister interface { type dirLister interface {
Readdir(string) ([]os.DirEntry, error) Readdir(string) ([]os.DirEntry, error)
} }
@ -1227,10 +1227,10 @@ func (s *Server) makeStat(path string) plan9.Dir {
// For chat and tailable mutable files, report actual size and // For chat and tailable mutable files, report actual size and
// Qid version so polling tools (tail -f) can detect changes via stat. // Qid version so polling tools (tail -f) can detect changes via stat.
// Path format: /s/{sessid}/{file} // Path format: /session/{sessid}/{file}
if strings.HasPrefix(path, fs.PathSessions) { if strings.HasPrefix(path, fs.PathSessions) {
parts := strings.SplitN(strings.TrimPrefix(path, "/"), "/", 3) parts := strings.SplitN(strings.TrimPrefix(path, "/"), "/", 3)
if len(parts) == 3 && parts[0] == "s" { if len(parts) == 3 && parts[0] == "session" {
if sess := s.sessionMgr.Session(parts[1]); sess != nil { if sess := s.sessionMgr.Session(parts[1]); sess != nil {
if base == "chat" { if base == "chat" {
length, vers := sess.LogInfo() length, vers := sess.LogInfo()