rename fsedsl → virtfs
The package has outgrown its original 'eDSL' framing. It's a virtual filesystem library. Rename to match.
This commit is contained in:
parent
d71ff80993
commit
ee7426d628
|
|
@ -11,7 +11,7 @@ import (
|
|||
"ollie/cmd/olliesrv/internal/agent"
|
||||
"ollie/cmd/olliesrv/internal/backend"
|
||||
"ollie/cmd/olliesrv/internal/bypass"
|
||||
"ollie/fsedsl"
|
||||
"ollie/virtfs"
|
||||
"ollie/cmd/olliesrv/internal/session"
|
||||
"ollie/toolsrv"
|
||||
)
|
||||
|
|
@ -44,7 +44,7 @@ func readBackends() ([]byte, error) {
|
|||
var helpFn func() string
|
||||
|
||||
// helpSpec stores the spec for help generation. Set during tree build.
|
||||
var helpSpec *fsedsl.FsNodeDecl
|
||||
var helpSpec *virtfs.FsNodeDecl
|
||||
|
||||
func readHelp() ([]byte, error) {
|
||||
if helpFn == nil {
|
||||
|
|
@ -57,7 +57,7 @@ func init() {
|
|||
helpFn = func() string {
|
||||
helpOnce.Do(func() {
|
||||
if helpSpec != nil {
|
||||
helpText = fsedsl.GenerateHelp(*helpSpec)
|
||||
helpText = virtfs.GenerateHelp(*helpSpec)
|
||||
}
|
||||
})
|
||||
return helpText
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
|
||||
"ollie/cmd/olliesrv/internal/bypass"
|
||||
"ollie/fsedsl"
|
||||
"ollie/virtfs"
|
||||
olog "ollie/log"
|
||||
"ollie/cmd/olliesrv/internal/session"
|
||||
)
|
||||
|
|
@ -45,7 +45,7 @@ func NewRoot(cfg Config) *Tree {
|
|||
// Build the tree from the spec.
|
||||
spec := buildTreeSpec(rs)
|
||||
helpSpec = &spec
|
||||
tree := fsedsl.BuildTree(spec)
|
||||
tree := virtfs.BuildTree(spec)
|
||||
tree.Data = rs
|
||||
|
||||
// Restore persisted sessions from disk.
|
||||
|
|
|
|||
|
|
@ -11,29 +11,29 @@ import (
|
|||
"ollie/cmd/olliesrv/internal/agent"
|
||||
"ollie/cmd/olliesrv/internal/bypass"
|
||||
"ollie/cmd/olliesrv/internal/session"
|
||||
"ollie/fsedsl"
|
||||
"ollie/virtfs"
|
||||
)
|
||||
|
||||
// Type aliases for fsedsl types used throughout the package.
|
||||
// Type aliases for virtfs types used throughout the package.
|
||||
type (
|
||||
Tree = fsedsl.Tree
|
||||
File = fsedsl.File
|
||||
SyntheticFileInfo = fsedsl.SyntheticFileInfo
|
||||
Tree = virtfs.Tree
|
||||
File = virtfs.File
|
||||
SyntheticFileInfo = virtfs.SyntheticFileInfo
|
||||
)
|
||||
|
||||
// Structural permissions.
|
||||
const (
|
||||
PermChildDir = fsedsl.PermChildDir
|
||||
PermIdx = fsedsl.PermIdx
|
||||
PermMkdir = fsedsl.PermMkdir
|
||||
PermMkdirPrivate = fsedsl.PermMkdirPrivate
|
||||
PermChildDir = virtfs.PermChildDir
|
||||
PermIdx = virtfs.PermIdx
|
||||
PermMkdir = virtfs.PermMkdir
|
||||
PermMkdirPrivate = virtfs.PermMkdirPrivate
|
||||
)
|
||||
|
||||
var treeSpecUID, treeSpecGID string
|
||||
|
||||
// buildTreeSpec constructs the full 9P namespace as an fsedsl.FsNodeDecl.
|
||||
// buildTreeSpec constructs the full 9P namespace as an virtfs.FsNodeDecl.
|
||||
// All handlers are closures that capture their dependencies at binding time.
|
||||
func buildTreeSpec(rs *RootState) fsedsl.FsNodeDecl {
|
||||
func buildTreeSpec(rs *RootState) virtfs.FsNodeDecl {
|
||||
cfg := &rs.Cfg
|
||||
mc := cfg.ModelCache
|
||||
broker := cfg.BypassBroker
|
||||
|
|
@ -45,71 +45,71 @@ func buildTreeSpec(rs *RootState) fsedsl.FsNodeDecl {
|
|||
treeSpecUID = u.Username
|
||||
}
|
||||
|
||||
return fsedsl.DirNode("/",
|
||||
fsedsl.UID(treeSpecUID),
|
||||
fsedsl.GID(treeSpecGID),
|
||||
return virtfs.DirNode("/",
|
||||
virtfs.UID(treeSpecUID),
|
||||
virtfs.GID(treeSpecGID),
|
||||
|
||||
fsedsl.FileNode("backends", 0444,
|
||||
fsedsl.Doc("Available backend names, one per line"),
|
||||
fsedsl.Read(readBackends),
|
||||
virtfs.FileNode("backends", 0444,
|
||||
virtfs.Doc("Available backend names, one per line"),
|
||||
virtfs.Read(readBackends),
|
||||
),
|
||||
fsedsl.FileNode("help", 0444,
|
||||
fsedsl.Doc("Filesystem reference"),
|
||||
fsedsl.Read(readHelp),
|
||||
virtfs.FileNode("help", 0444,
|
||||
virtfs.Doc("Filesystem reference"),
|
||||
virtfs.Read(readHelp),
|
||||
),
|
||||
fsedsl.FileNode("models", 0444,
|
||||
fsedsl.Doc("Available models. Format: backend<tab>model per line."),
|
||||
fsedsl.Read(func() ([]byte, error) { return readModels(mc) }),
|
||||
virtfs.FileNode("models", 0444,
|
||||
virtfs.Doc("Available models. Format: backend<tab>model per line."),
|
||||
virtfs.Read(func() ([]byte, error) { return readModels(mc) }),
|
||||
),
|
||||
fsedsl.FileNode("agents", 0444,
|
||||
fsedsl.Doc("Available agent profiles, one per line"),
|
||||
fsedsl.Read(readAgents),
|
||||
virtfs.FileNode("agents", 0444,
|
||||
virtfs.Doc("Available agent profiles, one per line"),
|
||||
virtfs.Read(readAgents),
|
||||
),
|
||||
fsedsl.FileNode("tools", 0444,
|
||||
fsedsl.Doc("Available tools. Format: name<spaces>description per line."),
|
||||
fsedsl.Read(readTools),
|
||||
virtfs.FileNode("tools", 0444,
|
||||
virtfs.Doc("Available tools. Format: name<spaces>description per line."),
|
||||
virtfs.Read(readTools),
|
||||
),
|
||||
fsedsl.FileNode("ctl", 0666,
|
||||
fsedsl.Doc("Server control. Write: 'invalidate', 'kill'"),
|
||||
fsedsl.Request(rootCtlHandler(mc, cfg.Invalidate, cfg.Shutdown)),
|
||||
virtfs.FileNode("ctl", 0666,
|
||||
virtfs.Doc("Server control. Write: 'invalidate', 'kill'"),
|
||||
virtfs.Request(rootCtlHandler(mc, cfg.Invalidate, cfg.Shutdown)),
|
||||
),
|
||||
fsedsl.FileNode("eventwait", 0444,
|
||||
fsedsl.Doc("Blocking read for server events"),
|
||||
fsedsl.Read(readEventwait),
|
||||
fsedsl.BlockOnce(blockEventwait),
|
||||
virtfs.FileNode("eventwait", 0444,
|
||||
virtfs.Doc("Blocking read for server events"),
|
||||
virtfs.Read(readEventwait),
|
||||
virtfs.BlockOnce(blockEventwait),
|
||||
),
|
||||
fsedsl.FileNode("generate", 0666,
|
||||
fsedsl.Doc("One-shot LLM generation"),
|
||||
fsedsl.Request(func(data []byte) ([]byte, error) { return requestGenerate(cfg.Ctx, data) }),
|
||||
virtfs.FileNode("generate", 0666,
|
||||
virtfs.Doc("One-shot LLM generation"),
|
||||
virtfs.Request(func(data []byte) ([]byte, error) { return requestGenerate(cfg.Ctx, data) }),
|
||||
),
|
||||
fsedsl.FileNode("aliases", 0444,
|
||||
fsedsl.Doc("Alias table. Format: id<tab>path per line."),
|
||||
fsedsl.Read(readAliases),
|
||||
virtfs.FileNode("aliases", 0444,
|
||||
virtfs.Doc("Alias table. Format: id<tab>path per line."),
|
||||
virtfs.Read(readAliases),
|
||||
),
|
||||
|
||||
fsedsl.DirNode("bypass",
|
||||
fsedsl.Doc("Bypass broker for sandboxed command approval"),
|
||||
fsedsl.FileNode("policy", 0666,
|
||||
fsedsl.Doc("Global bypass policy"),
|
||||
fsedsl.Read(func() ([]byte, error) { return readBypassPolicy(broker) }),
|
||||
fsedsl.Write(func(data []byte) error { return writeBypassPolicy(broker, data) }),
|
||||
virtfs.DirNode("bypass",
|
||||
virtfs.Doc("Bypass broker for sandboxed command approval"),
|
||||
virtfs.FileNode("policy", 0666,
|
||||
virtfs.Doc("Global bypass policy"),
|
||||
virtfs.Read(func() ([]byte, error) { return readBypassPolicy(broker) }),
|
||||
virtfs.Write(func(data []byte) error { return writeBypassPolicy(broker, data) }),
|
||||
),
|
||||
fsedsl.Each("{reqid}", func() ([]fsedsl.Binding, error) {
|
||||
virtfs.Each("{reqid}", func() ([]virtfs.Binding, error) {
|
||||
return adaptBypassBindings(broker)
|
||||
}),
|
||||
),
|
||||
|
||||
fsedsl.DirNode("session",
|
||||
fsedsl.Doc("Session management"),
|
||||
fsedsl.FileNode("new", 0666,
|
||||
fsedsl.Doc("Create session"),
|
||||
fsedsl.Request(requestSessionNew),
|
||||
virtfs.DirNode("session",
|
||||
virtfs.Doc("Session management"),
|
||||
virtfs.FileNode("new", 0666,
|
||||
virtfs.Doc("Create session"),
|
||||
virtfs.Request(requestSessionNew),
|
||||
),
|
||||
fsedsl.FileNode("idx", 0444,
|
||||
fsedsl.Doc("Session index"),
|
||||
fsedsl.Read(readSessionIdx),
|
||||
virtfs.FileNode("idx", 0444,
|
||||
virtfs.Doc("Session index"),
|
||||
virtfs.Read(readSessionIdx),
|
||||
),
|
||||
fsedsl.Each("{sname}", func() ([]fsedsl.Binding, error) {
|
||||
virtfs.Each("{sname}", func() ([]virtfs.Binding, error) {
|
||||
return buildSessionBindings(rs, broker)
|
||||
}),
|
||||
),
|
||||
|
|
@ -117,9 +117,9 @@ func buildTreeSpec(rs *RootState) fsedsl.FsNodeDecl {
|
|||
}
|
||||
|
||||
// buildSessionBindings produces bindings for each session.
|
||||
func buildSessionBindings(rs *RootState, broker *bypass.Broker) ([]fsedsl.Binding, error) {
|
||||
func buildSessionBindings(rs *RootState, broker *bypass.Broker) ([]virtfs.Binding, error) {
|
||||
sessions := session.Sessions()
|
||||
var out []fsedsl.Binding
|
||||
var out []virtfs.Binding
|
||||
|
||||
for name, sess := range sessions {
|
||||
node := rs.GetOrCreateNode(sess)
|
||||
|
|
@ -138,7 +138,7 @@ func buildSessionBindings(rs *RootState, broker *bypass.Broker) ([]fsedsl.Bindin
|
|||
return nil
|
||||
}
|
||||
|
||||
out = append(out, fsedsl.Binding{
|
||||
out = append(out, virtfs.Binding{
|
||||
Name: sess.Name(),
|
||||
Aliases: []string{sess.ID},
|
||||
Remove: removeFn,
|
||||
|
|
@ -156,39 +156,39 @@ func buildSessionChildren(
|
|||
broker *bypass.Broker,
|
||||
removeFn func(),
|
||||
renameFn func(string) error,
|
||||
) []fsedsl.FsNodeDecl {
|
||||
return []fsedsl.FsNodeDecl{
|
||||
fsedsl.FileNode("env", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readSessionEnv(s) }),
|
||||
) []virtfs.FsNodeDecl {
|
||||
return []virtfs.FsNodeDecl{
|
||||
virtfs.FileNode("env", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readSessionEnv(s) }),
|
||||
),
|
||||
fsedsl.FileNode("paused", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readSessionPaused(s) }),
|
||||
virtfs.FileNode("paused", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readSessionPaused(s) }),
|
||||
),
|
||||
fsedsl.FileNode("connected", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readSessionConnected(s) }),
|
||||
virtfs.FileNode("connected", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readSessionConnected(s) }),
|
||||
),
|
||||
fsedsl.FileNode("ctl", 0666,
|
||||
fsedsl.Request(sessionCtlHandler(s, removeFn, renameFn)),
|
||||
virtfs.FileNode("ctl", 0666,
|
||||
virtfs.Request(sessionCtlHandler(s, removeFn, renameFn)),
|
||||
),
|
||||
fsedsl.FileNode("name", 0666,
|
||||
fsedsl.Read(func() ([]byte, error) { return readSessionName(s) }),
|
||||
fsedsl.Write(func(data []byte) error { return writeSessionName(s, renameFn, data) }),
|
||||
virtfs.FileNode("name", 0666,
|
||||
virtfs.Read(func() ([]byte, error) { return readSessionName(s) }),
|
||||
virtfs.Write(func(data []byte) error { return writeSessionName(s, renameFn, data) }),
|
||||
),
|
||||
fsedsl.FileNode("id", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readSessionID(s) }),
|
||||
virtfs.FileNode("id", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readSessionID(s) }),
|
||||
),
|
||||
fsedsl.FileNode("bypass", 0666,
|
||||
fsedsl.Read(func() ([]byte, error) { return readSessionBypass(broker, s) }),
|
||||
fsedsl.Write(func(data []byte) error { return writeSessionBypass(broker, s, data) }),
|
||||
virtfs.FileNode("bypass", 0666,
|
||||
virtfs.Read(func() ([]byte, error) { return readSessionBypass(broker, s) }),
|
||||
virtfs.Write(func(data []byte) error { return writeSessionBypass(broker, s, data) }),
|
||||
),
|
||||
fsedsl.DirNode("agent",
|
||||
fsedsl.FileNode("new", 0666,
|
||||
fsedsl.Request(func(data []byte) ([]byte, error) { return requestAgentNew(s, data) }),
|
||||
virtfs.DirNode("agent",
|
||||
virtfs.FileNode("new", 0666,
|
||||
virtfs.Request(func(data []byte) ([]byte, error) { return requestAgentNew(s, data) }),
|
||||
),
|
||||
fsedsl.FileNode("idx", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentIdx(s.Session) }),
|
||||
virtfs.FileNode("idx", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentIdx(s.Session) }),
|
||||
),
|
||||
fsedsl.Each("{aname}", func() ([]fsedsl.Binding, error) {
|
||||
virtfs.Each("{aname}", func() ([]virtfs.Binding, error) {
|
||||
return buildAgentBindings(s, rs)
|
||||
}),
|
||||
),
|
||||
|
|
@ -196,9 +196,9 @@ func buildSessionChildren(
|
|||
}
|
||||
|
||||
// buildAgentBindings produces bindings for each agent in a session.
|
||||
func buildAgentBindings(s *SessionNode, rs *RootState) ([]fsedsl.Binding, error) {
|
||||
func buildAgentBindings(s *SessionNode, rs *RootState) ([]virtfs.Binding, error) {
|
||||
agents := s.Agents()
|
||||
var out []fsedsl.Binding
|
||||
var out []virtfs.Binding
|
||||
|
||||
for _, ag := range agents {
|
||||
a := ag
|
||||
|
|
@ -209,7 +209,7 @@ func buildAgentBindings(s *SessionNode, rs *RootState) ([]fsedsl.Binding, error)
|
|||
wireAgentEvents(s.ID, a, al)
|
||||
}
|
||||
|
||||
out = append(out, fsedsl.Binding{
|
||||
out = append(out, virtfs.Binding{
|
||||
Name: a.Name(),
|
||||
Aliases: []string{a.ID()},
|
||||
Remove: func() {
|
||||
|
|
@ -223,67 +223,67 @@ func buildAgentBindings(s *SessionNode, rs *RootState) ([]fsedsl.Binding, error)
|
|||
}
|
||||
|
||||
// buildAgentChildren returns the file nodes for a single agent.
|
||||
func buildAgentChildren(a *agent.Agent, al *AgentLog, s *SessionNode) []fsedsl.FsNodeDecl {
|
||||
return []fsedsl.FsNodeDecl{
|
||||
fsedsl.FileNode("prompt", 0666,
|
||||
fsedsl.Write(func(data []byte) error { return writeAgentPrompt(s, a, al, data) }),
|
||||
func buildAgentChildren(a *agent.Agent, al *AgentLog, s *SessionNode) []virtfs.FsNodeDecl {
|
||||
return []virtfs.FsNodeDecl{
|
||||
virtfs.FileNode("prompt", 0666,
|
||||
virtfs.Write(func(data []byte) error { return writeAgentPrompt(s, a, al, data) }),
|
||||
),
|
||||
fsedsl.FileNode("fifo", 0666,
|
||||
fsedsl.Write(func(data []byte) error { return writeAgentFifoIn(a, data) }),
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentFifoOut(a) }),
|
||||
virtfs.FileNode("fifo", 0666,
|
||||
virtfs.Write(func(data []byte) error { return writeAgentFifoIn(a, data) }),
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentFifoOut(a) }),
|
||||
),
|
||||
fsedsl.FileNode("chat", 0444,
|
||||
fsedsl.StatOverride(statAgentChat),
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentChatText(al) }),
|
||||
fsedsl.Stream(func(cctx context.Context, base string) ([]byte, string, error) {
|
||||
virtfs.FileNode("chat", 0444,
|
||||
virtfs.StatOverride(statAgentChat),
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentChatText(al) }),
|
||||
virtfs.Stream(func(cctx context.Context, base string) ([]byte, string, error) {
|
||||
return streamAgentChatText(s, al, cctx, base)
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("chat.raw", 0444,
|
||||
fsedsl.StatOverride(statAgentChat),
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentChat(al) }),
|
||||
fsedsl.Stream(func(cctx context.Context, base string) ([]byte, string, error) {
|
||||
virtfs.FileNode("chat.raw", 0444,
|
||||
virtfs.StatOverride(statAgentChat),
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentChat(al) }),
|
||||
virtfs.Stream(func(cctx context.Context, base string) ([]byte, string, error) {
|
||||
return streamAgentChat(s, al, cctx, base)
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("statewait", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) {
|
||||
virtfs.FileNode("statewait", 0444,
|
||||
virtfs.Read(func() ([]byte, error) {
|
||||
return []byte(a.State() + "\n"), nil
|
||||
}),
|
||||
fsedsl.BlockOnce(func(cctx context.Context, base string) ([]byte, string, error) {
|
||||
virtfs.BlockOnce(func(cctx context.Context, base string) ([]byte, string, error) {
|
||||
return blockAgentStateWait(s, a, cctx, base)
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("log", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentLog(al) }),
|
||||
virtfs.FileNode("log", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentLog(al) }),
|
||||
),
|
||||
fsedsl.FileNode("plan", 0666,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentPlan(al) }),
|
||||
fsedsl.Write(func(data []byte) error { return writeAgentPlan(al, data) }),
|
||||
virtfs.FileNode("plan", 0666,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentPlan(al) }),
|
||||
virtfs.Write(func(data []byte) error { return writeAgentPlan(al, data) }),
|
||||
),
|
||||
fsedsl.FileNode("cfg", 0666,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentCfg(s, a, al) }),
|
||||
fsedsl.Write(func(data []byte) error { return writeAgentCfg(a, data) }),
|
||||
virtfs.FileNode("cfg", 0666,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentCfg(s, a, al) }),
|
||||
virtfs.Write(func(data []byte) error { return writeAgentCfg(a, data) }),
|
||||
),
|
||||
fsedsl.FileNode("ctl", 0666,
|
||||
fsedsl.Request(agentCtlHandler(s, a)),
|
||||
virtfs.FileNode("ctl", 0666,
|
||||
virtfs.Request(agentCtlHandler(s, a)),
|
||||
),
|
||||
fsedsl.FileNode("stats", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentStats(a) }),
|
||||
virtfs.FileNode("stats", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentStats(a) }),
|
||||
),
|
||||
fsedsl.FileNode("tools", 0666,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentTools(a) }),
|
||||
fsedsl.Write(func(data []byte) error { return writeAgentTools(a, data) }),
|
||||
virtfs.FileNode("tools", 0666,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentTools(a) }),
|
||||
virtfs.Write(func(data []byte) error { return writeAgentTools(a, data) }),
|
||||
),
|
||||
fsedsl.FileNode("name", 0666,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentName(a) }),
|
||||
fsedsl.Write(func(data []byte) error { return writeAgentName(s, a, data) }),
|
||||
virtfs.FileNode("name", 0666,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentName(a) }),
|
||||
virtfs.Write(func(data []byte) error { return writeAgentName(s, a, data) }),
|
||||
),
|
||||
fsedsl.FileNode("id", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) { return readAgentID(a) }),
|
||||
virtfs.FileNode("id", 0444,
|
||||
virtfs.Read(func() ([]byte, error) { return readAgentID(a) }),
|
||||
),
|
||||
fsedsl.DirNode("proc",
|
||||
fsedsl.Each("{pid}", func() ([]fsedsl.Binding, error) {
|
||||
virtfs.DirNode("proc",
|
||||
virtfs.Each("{pid}", func() ([]virtfs.Binding, error) {
|
||||
return adaptProcessBindings(s)
|
||||
}),
|
||||
),
|
||||
|
|
@ -291,22 +291,22 @@ func buildAgentChildren(a *agent.Agent, al *AgentLog, s *SessionNode) []fsedsl.F
|
|||
}
|
||||
|
||||
// adaptBypassBindings returns bindings for pending bypass requests.
|
||||
func adaptBypassBindings(broker *bypass.Broker) ([]fsedsl.Binding, error) {
|
||||
func adaptBypassBindings(broker *bypass.Broker) ([]virtfs.Binding, error) {
|
||||
if broker == nil {
|
||||
return nil, errNoBypass
|
||||
}
|
||||
pending := broker.Pending()
|
||||
var out []fsedsl.Binding
|
||||
var out []virtfs.Binding
|
||||
for _, r := range pending {
|
||||
req := r
|
||||
out = append(out, fsedsl.Binding{
|
||||
out = append(out, virtfs.Binding{
|
||||
Name: req.ID,
|
||||
Children: []fsedsl.FsNodeDecl{
|
||||
fsedsl.FileNode("request", 0666,
|
||||
fsedsl.Read(func() ([]byte, error) {
|
||||
Children: []virtfs.FsNodeDecl{
|
||||
virtfs.FileNode("request", 0666,
|
||||
virtfs.Read(func() ([]byte, error) {
|
||||
return readBypassRequest(req)
|
||||
}),
|
||||
fsedsl.Write(func(data []byte) error {
|
||||
virtfs.Write(func(data []byte) error {
|
||||
return writeBypassRequest(broker, req, data)
|
||||
}),
|
||||
),
|
||||
|
|
@ -317,7 +317,7 @@ func adaptBypassBindings(broker *bypass.Broker) ([]fsedsl.Binding, error) {
|
|||
}
|
||||
|
||||
// adaptProcessBindings returns bindings for detached processes.
|
||||
func adaptProcessBindings(s *SessionNode) ([]fsedsl.Binding, error) {
|
||||
func adaptProcessBindings(s *SessionNode) ([]virtfs.Binding, error) {
|
||||
if s == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -327,26 +327,26 @@ func adaptProcessBindings(s *SessionNode) ([]fsedsl.Binding, error) {
|
|||
}
|
||||
defer conn.Close()
|
||||
raw := conn.ListDetachedRaw()
|
||||
var out []fsedsl.Binding
|
||||
var out []virtfs.Binding
|
||||
for _, r := range raw {
|
||||
if m, ok := r.(map[string]any); ok {
|
||||
if id, ok := m["pid"].(int); ok {
|
||||
pid := id
|
||||
out = append(out, fsedsl.Binding{
|
||||
out = append(out, virtfs.Binding{
|
||||
Name: strconv.Itoa(pid),
|
||||
Children: []fsedsl.FsNodeDecl{
|
||||
fsedsl.FileNode("out", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) {
|
||||
Children: []virtfs.FsNodeDecl{
|
||||
virtfs.FileNode("out", 0444,
|
||||
virtfs.Read(func() ([]byte, error) {
|
||||
return readProcess(s, pid)
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("ctl", 0222,
|
||||
fsedsl.Write(func(data []byte) error {
|
||||
virtfs.FileNode("ctl", 0222,
|
||||
virtfs.Write(func(data []byte) error {
|
||||
return writeProcessCtl(s, pid, data)
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("status", 0444,
|
||||
fsedsl.Read(func() ([]byte, error) {
|
||||
virtfs.FileNode("status", 0444,
|
||||
virtfs.Read(func() ([]byte, error) {
|
||||
return readProcessStatus(s, pid)
|
||||
}),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// spec.go - fsedsl-based namespace specification for toolsrv.
|
||||
// spec.go - virtfs-based namespace specification for toolsrv.
|
||||
package fs
|
||||
|
||||
import (
|
||||
|
|
@ -8,22 +8,22 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"ollie/fsedsl"
|
||||
"ollie/virtfs"
|
||||
)
|
||||
|
||||
// Spec returns the fsedsl specification for the toolsrv namespace.
|
||||
// Spec returns the virtfs specification for the toolsrv namespace.
|
||||
// The server is captured by closures — no context threading needed.
|
||||
func Spec(srv *Server) fsedsl.FsNodeDecl {
|
||||
return fsedsl.DirNode("/",
|
||||
fsedsl.FileNode("ctl", 0222,
|
||||
fsedsl.Doc("Control: write 'load <agentID> <tool>' or 'unload <agentID> <tool>'"),
|
||||
fsedsl.Write(func(data []byte) error {
|
||||
func Spec(srv *Server) virtfs.FsNodeDecl {
|
||||
return virtfs.DirNode("/",
|
||||
virtfs.FileNode("ctl", 0222,
|
||||
virtfs.Doc("Control: write 'load <agentID> <tool>' or 'unload <agentID> <tool>'"),
|
||||
virtfs.Write(func(data []byte) error {
|
||||
return srv.Fs.HandleCtl(strings.TrimSpace(string(data)))
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("tools", 0666,
|
||||
fsedsl.Doc("Tools: write agent ID, read tool list (rdwr)"),
|
||||
fsedsl.Request(func(data []byte) ([]byte, error) {
|
||||
virtfs.FileNode("tools", 0666,
|
||||
virtfs.Doc("Tools: write agent ID, read tool list (rdwr)"),
|
||||
virtfs.Request(func(data []byte) ([]byte, error) {
|
||||
agentID := strings.TrimSpace(string(data))
|
||||
if agentID == "" {
|
||||
return nil, fmt.Errorf("agent ID required")
|
||||
|
|
@ -31,16 +31,16 @@ func Spec(srv *Server) fsedsl.FsNodeDecl {
|
|||
return []byte(srv.Fs.HandleToolsRequest(agentID)), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("info", 0444,
|
||||
fsedsl.Doc("Host info: platform, arch"),
|
||||
fsedsl.Read(func() ([]byte, error) {
|
||||
virtfs.FileNode("info", 0444,
|
||||
virtfs.Doc("Host info: platform, arch"),
|
||||
virtfs.Read(func() ([]byte, error) {
|
||||
return []byte(srv.HostInfo()), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.DirNode("proc",
|
||||
fsedsl.FileNode("new", 0666,
|
||||
fsedsl.Doc("Execute tool: write token + tool + args, read result (blocking)"),
|
||||
fsedsl.Request(func(data []byte) ([]byte, error) {
|
||||
virtfs.DirNode("proc",
|
||||
virtfs.FileNode("new", 0666,
|
||||
virtfs.Doc("Execute tool: write token + tool + args, read result (blocking)"),
|
||||
virtfs.Request(func(data []byte) ([]byte, error) {
|
||||
result, err := srv.Fs.HandleProcNew(context.Background(), string(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -48,9 +48,9 @@ func Spec(srv *Server) fsedsl.FsNodeDecl {
|
|||
return []byte(result), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("new.bg", 0666,
|
||||
fsedsl.Doc("Execute tool in background: write token + tool + args, read pid"),
|
||||
fsedsl.Request(func(data []byte) ([]byte, error) {
|
||||
virtfs.FileNode("new.bg", 0666,
|
||||
virtfs.Doc("Execute tool in background: write token + tool + args, read pid"),
|
||||
virtfs.Request(func(data []byte) ([]byte, error) {
|
||||
result, err := srv.Fs.HandleProcNewBg(context.Background(), string(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -58,40 +58,40 @@ func Spec(srv *Server) fsedsl.FsNodeDecl {
|
|||
return []byte(result), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.Each("{pid}", func() ([]fsedsl.Binding, error) {
|
||||
virtfs.Each("{pid}", func() ([]virtfs.Binding, error) {
|
||||
pids := srv.Fs.ListProcs()
|
||||
var bindings []fsedsl.Binding
|
||||
var bindings []virtfs.Binding
|
||||
for _, pid := range pids {
|
||||
proc := srv.Fs.GetProc(pid)
|
||||
if proc == nil {
|
||||
continue
|
||||
}
|
||||
p := proc
|
||||
bindings = append(bindings, fsedsl.Binding{
|
||||
bindings = append(bindings, virtfs.Binding{
|
||||
Name: strconv.Itoa(pid),
|
||||
Children: []fsedsl.FsNodeDecl{
|
||||
fsedsl.FileNode("out", 0444,
|
||||
fsedsl.Doc("Process output"),
|
||||
fsedsl.Read(func() ([]byte, error) {
|
||||
Children: []virtfs.FsNodeDecl{
|
||||
virtfs.FileNode("out", 0444,
|
||||
virtfs.Doc("Process output"),
|
||||
virtfs.Read(func() ([]byte, error) {
|
||||
return []byte(p.Output()), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("wait", 0444,
|
||||
fsedsl.Doc("Block until process exits, returns exit code"),
|
||||
fsedsl.BlockOnce(func(_ context.Context, _ string) ([]byte, string, error) {
|
||||
virtfs.FileNode("wait", 0444,
|
||||
virtfs.Doc("Block until process exits, returns exit code"),
|
||||
virtfs.BlockOnce(func(_ context.Context, _ string) ([]byte, string, error) {
|
||||
exitCode := p.Wait()
|
||||
return []byte(fmt.Sprintf("%d\n", exitCode)), "", nil
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("stat", 0444,
|
||||
fsedsl.Doc("Process status: running/exited, runtime, tool"),
|
||||
fsedsl.Read(func() ([]byte, error) {
|
||||
virtfs.FileNode("stat", 0444,
|
||||
virtfs.Doc("Process status: running/exited, runtime, tool"),
|
||||
virtfs.Read(func() ([]byte, error) {
|
||||
return []byte(p.Stat()), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode("ctl", 0222,
|
||||
fsedsl.Doc("Process control: write 'signal <N>' or 'dismiss'"),
|
||||
fsedsl.Write(func(data []byte) error {
|
||||
virtfs.FileNode("ctl", 0222,
|
||||
virtfs.Doc("Process control: write 'signal <N>' or 'dismiss'"),
|
||||
virtfs.Write(func(data []byte) error {
|
||||
return srv.Fs.HandleProcCtl(p.ID, strings.TrimSpace(string(data)))
|
||||
}),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"ollie/cmd/toolsrv/internal/registry"
|
||||
"ollie/fsedsl"
|
||||
"ollie/virtfs"
|
||||
)
|
||||
|
||||
// Server holds the state for the toolsrv 9P server.
|
||||
|
|
@ -82,9 +82,9 @@ func (s *Server) HostInfo() string {
|
|||
return fmt.Sprintf("platform=%s\narch=%s\n", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
// BuildTree creates the fsedsl tree for this server.
|
||||
func (s *Server) BuildTree() *fsedsl.Tree {
|
||||
return fsedsl.BuildTree(Spec(s))
|
||||
// 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.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"ollie/cmd/toolsrv/internal/fs"
|
||||
"ollie/fsedsl"
|
||||
"ollie/virtfs"
|
||||
|
||||
"9fans.net/go/plan9"
|
||||
)
|
||||
|
|
@ -21,7 +21,7 @@ type fid struct {
|
|||
qid plan9.Qid
|
||||
mode uint8
|
||||
opened bool
|
||||
entry fsedsl.File
|
||||
entry virtfs.File
|
||||
readBuf []byte // buffer for read data
|
||||
readDone bool // true if file has been read
|
||||
dirCache []byte
|
||||
|
|
@ -46,8 +46,8 @@ type connState struct {
|
|||
noAuth bool // skip authentication (for debugging)
|
||||
}
|
||||
|
||||
// serve9P handles a single 9P connection using the fsedsl tree.
|
||||
func serve9P(ctx context.Context, conn net.Conn, tree *fsedsl.Tree, srv *fs.Server, noAuth bool) {
|
||||
// serve9P handles a single 9P connection using the virtfs tree.
|
||||
func serve9P(ctx context.Context, conn net.Conn, tree *virtfs.Tree, srv *fs.Server, noAuth bool) {
|
||||
defer conn.Close()
|
||||
|
||||
cs := &connState{
|
||||
|
|
@ -81,7 +81,7 @@ func serve9P(ctx context.Context, conn net.Conn, tree *fsedsl.Tree, srv *fs.Serv
|
|||
}
|
||||
}
|
||||
|
||||
func handleFcall(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleFcall(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
switch fc.Type {
|
||||
case plan9.Tversion:
|
||||
return handleVersion(fc)
|
||||
|
|
@ -133,7 +133,7 @@ func handleAuth(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
}
|
||||
}
|
||||
|
||||
func handleAttach(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleAttach(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
// Skip auth check if noAuth is set (for debugging)
|
||||
if cs.noAuth {
|
||||
cs.mu.Lock()
|
||||
|
|
@ -210,7 +210,7 @@ func handleAuthRead(cs *connState, fc *plan9.Fcall, af *authFid) *plan9.Fcall {
|
|||
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Data: data[offset:end]}
|
||||
}
|
||||
|
||||
func handleWalk(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleWalk(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
cs.mu.RLock()
|
||||
f, ok := cs.fids[fc.Fid]
|
||||
cs.mu.RUnlock()
|
||||
|
|
@ -288,7 +288,7 @@ func handleWalk(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall
|
|||
return &plan9.Fcall{Type: plan9.Rwalk, Tag: fc.Tag, Wqid: qids}
|
||||
}
|
||||
|
||||
func handleOpen(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleOpen(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
cs.mu.Lock()
|
||||
defer cs.mu.Unlock()
|
||||
|
||||
|
|
@ -325,7 +325,7 @@ func handleOpen(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall
|
|||
return &plan9.Fcall{Type: plan9.Ropen, Tag: fc.Tag, Qid: f.qid, Iounit: 8192}
|
||||
}
|
||||
|
||||
func handleRead(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleRead(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
// Check if reading from auth fid
|
||||
cs.mu.RLock()
|
||||
af, isAuthFid := cs.authFids[fc.Fid]
|
||||
|
|
@ -380,7 +380,7 @@ func handleRead(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall
|
|||
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Data: f.readBuf[offset:end]}
|
||||
}
|
||||
|
||||
func handleDirRead(cs *connState, f *fid, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleDirRead(cs *connState, f *fid, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
if fc.Offset == 0 || f.dirCache == nil {
|
||||
path := f.path
|
||||
if path == "/" {
|
||||
|
|
@ -428,7 +428,7 @@ func handleDirRead(cs *connState, f *fid, fc *plan9.Fcall, tree *fsedsl.Tree) *p
|
|||
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Data: f.dirCache[offset:end]}
|
||||
}
|
||||
|
||||
func handleWrite(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleWrite(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
// Check if writing to auth fid
|
||||
cs.mu.Lock()
|
||||
af, isAuthFid := cs.authFids[fc.Fid]
|
||||
|
|
@ -465,7 +465,7 @@ func handleClunk(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
return &plan9.Fcall{Type: plan9.Rclunk, Tag: fc.Tag}
|
||||
}
|
||||
|
||||
func handleStat(cs *connState, fc *plan9.Fcall, tree *fsedsl.Tree) *plan9.Fcall {
|
||||
func handleStat(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
|
||||
cs.mu.RLock()
|
||||
f, ok := cs.fids[fc.Fid]
|
||||
cs.mu.RUnlock()
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
module ollie/fsedsl
|
||||
|
||||
go 1.25.6
|
||||
4
go.mod
4
go.mod
|
|
@ -9,9 +9,9 @@ require (
|
|||
github.com/simonfxr/pubsub v0.0.5
|
||||
golang.org/x/time v0.15.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
ollie/fsedsl v0.0.0
|
||||
ollie/virtfs v0.0.0
|
||||
)
|
||||
|
||||
require golang.org/x/sys v0.47.0 // indirect
|
||||
|
||||
replace ollie/fsedsl => ./fsedsl
|
||||
replace ollie/virtfs => ./virtfs
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# fsedsl
|
||||
# virtfs
|
||||
|
||||
A Go library providing an embedded domain-specific language (EDSL) for declaring synthetic filesystems. Define your namespace structure statically while populating it dynamically at runtime.
|
||||
|
||||
|
|
@ -14,19 +14,19 @@ The library produces a generic `Tree` that can be used with any filesystem proto
|
|||
|
||||
## Installation
|
||||
|
||||
The library is currently embedded in the [ollie](https://git.lneely.de/lkn/ollie) repository at `fsedsl/`.
|
||||
The library is currently embedded in the [ollie](https://git.lneely.de/lkn/ollie) repository at `virtfs/`.
|
||||
|
||||
To use it in your project, add a replace directive to your `go.mod`:
|
||||
|
||||
```bash
|
||||
# Clone or copy the fsedsl directory to your project, then:
|
||||
go mod edit -replace=git.lneely.de/lkn/fsedsl=./fsedsl
|
||||
# Clone or copy the virtfs directory to your project, then:
|
||||
go mod edit -replace=git.lneely.de/lkn/virtfs=./virtfs
|
||||
```
|
||||
|
||||
Or reference it directly from the ollie repo:
|
||||
|
||||
```bash
|
||||
go mod edit -replace=git.lneely.de/lkn/fsedsl=git.lneely.de/lkn/ollie/fsedsl@main
|
||||
go mod edit -replace=git.lneely.de/lkn/virtfs=git.lneely.de/lkn/ollie/virtfs@main
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
|
@ -36,7 +36,7 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"git.lneely.de/lkn/fsedsl"
|
||||
"git.lneely.de/lkn/virtfs"
|
||||
)
|
||||
|
||||
type Ctx struct {
|
||||
|
|
@ -55,18 +55,18 @@ var users = []*User{
|
|||
|
||||
func main() {
|
||||
// Declare the filesystem spec
|
||||
spec := fsedsl.DirNode[Ctx]("/",
|
||||
fsedsl.FileNode[Ctx]("version", 0444,
|
||||
fsedsl.Doc[Ctx]("API version"),
|
||||
fsedsl.Read(func(ctx Ctx) ([]byte, error) {
|
||||
spec := virtfs.DirNode[Ctx]("/",
|
||||
virtfs.FileNode[Ctx]("version", 0444,
|
||||
virtfs.Doc[Ctx]("API version"),
|
||||
virtfs.Read(func(ctx Ctx) ([]byte, error) {
|
||||
return []byte("1.0\n"), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.Each[Ctx]("{user}", func(ctx Ctx) ([]fsedsl.Binding[Ctx], error) {
|
||||
var out []fsedsl.Binding[Ctx]
|
||||
virtfs.Each[Ctx]("{user}", func(ctx Ctx) ([]virtfs.Binding[Ctx], error) {
|
||||
var out []virtfs.Binding[Ctx]
|
||||
for _, u := range users {
|
||||
user := u // capture
|
||||
out = append(out, fsedsl.Binding[Ctx]{
|
||||
out = append(out, virtfs.Binding[Ctx]{
|
||||
Name: user.Name,
|
||||
Aliases: []string{user.ID},
|
||||
Applier: func(c Ctx) Ctx {
|
||||
|
|
@ -77,13 +77,13 @@ func main() {
|
|||
}
|
||||
return out, nil
|
||||
},
|
||||
fsedsl.FileNode[Ctx]("id", 0444,
|
||||
fsedsl.Read(func(ctx Ctx) ([]byte, error) {
|
||||
virtfs.FileNode[Ctx]("id", 0444,
|
||||
virtfs.Read(func(ctx Ctx) ([]byte, error) {
|
||||
return []byte(ctx.User.ID + "\n"), nil
|
||||
}),
|
||||
),
|
||||
fsedsl.FileNode[Ctx]("name", 0444,
|
||||
fsedsl.Read(func(ctx Ctx) ([]byte, error) {
|
||||
virtfs.FileNode[Ctx]("name", 0444,
|
||||
virtfs.Read(func(ctx Ctx) ([]byte, error) {
|
||||
return []byte(ctx.User.Name + "\n"), nil
|
||||
}),
|
||||
),
|
||||
|
|
@ -91,7 +91,7 @@ func main() {
|
|||
)
|
||||
|
||||
// Build the tree
|
||||
tree := fsedsl.BuildTree(spec, Ctx{})
|
||||
tree := virtfs.BuildTree(spec, Ctx{})
|
||||
|
||||
// Use the tree
|
||||
entries, _ := tree.List()
|
||||
|
|
@ -112,7 +112,7 @@ Define your context type, then create type and function aliases that bake it in:
|
|||
```go
|
||||
package fs
|
||||
|
||||
import "git.lneely.de/lkn/fsedsl"
|
||||
import "git.lneely.de/lkn/virtfs"
|
||||
|
||||
// Ctx carries runtime dependencies for handler functions.
|
||||
type Ctx struct {
|
||||
|
|
@ -122,19 +122,19 @@ type Ctx struct {
|
|||
|
||||
// Type aliases for external consumers
|
||||
type (
|
||||
FsNodeDecl = fsedsl.FsNodeDecl[Ctx]
|
||||
Binding = fsedsl.Binding[Ctx]
|
||||
Tree = fsedsl.Tree
|
||||
FsNodeDecl = virtfs.FsNodeDecl[Ctx]
|
||||
Binding = virtfs.Binding[Ctx]
|
||||
Tree = virtfs.Tree
|
||||
)
|
||||
|
||||
// Function aliases for clean spec definitions
|
||||
var (
|
||||
DirNode = fsedsl.DirNode[Ctx]
|
||||
FileNode = fsedsl.FileNode[Ctx]
|
||||
Each = fsedsl.Each[Ctx]
|
||||
Doc = fsedsl.Doc[Ctx]
|
||||
Read = fsedsl.Read[Ctx]
|
||||
Write = fsedsl.Write[Ctx]
|
||||
DirNode = virtfs.DirNode[Ctx]
|
||||
FileNode = virtfs.FileNode[Ctx]
|
||||
Each = virtfs.Each[Ctx]
|
||||
Doc = virtfs.Doc[Ctx]
|
||||
Read = virtfs.Read[Ctx]
|
||||
Write = virtfs.Write[Ctx]
|
||||
// ... add others as needed
|
||||
)
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ func userBindings(ctx Ctx) ([]Binding, error) {
|
|||
Build and use:
|
||||
|
||||
```go
|
||||
tree := fsedsl.BuildTree(fs.Spec, fs.Ctx{DB: db})
|
||||
tree := virtfs.BuildTree(fs.Spec, fs.Ctx{DB: db})
|
||||
entries, _ := tree.List()
|
||||
f, _ := tree.Open("alice/name")
|
||||
data, _ := f.Read()
|
||||
|
|
@ -208,7 +208,7 @@ data, _ := f.Read()
|
|||
### Binding
|
||||
|
||||
```go
|
||||
fsedsl.Binding[Ctx]{
|
||||
virtfs.Binding[Ctx]{
|
||||
Name: "filename", // Primary name
|
||||
Aliases: []string{"alt-name"}, // Alternate lookup names
|
||||
UID: "owner", // Owner (optional)
|
||||
|
|
@ -225,7 +225,7 @@ fsedsl.Binding[Ctx]{
|
|||
### Tree Operations
|
||||
|
||||
```go
|
||||
tree := fsedsl.BuildTree(spec, rootCtx)
|
||||
tree := virtfs.BuildTree(spec, rootCtx)
|
||||
|
||||
tree.List() // List entries
|
||||
tree.Stat(name) // Get file info
|
||||
|
|
@ -239,7 +239,7 @@ tree.Readdir(path) // List subdirectory
|
|||
### Help Generation
|
||||
|
||||
```go
|
||||
help := fsedsl.GenerateHelp(spec)
|
||||
help := virtfs.GenerateHelp(spec)
|
||||
// Returns formatted documentation from Doc() annotations
|
||||
```
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package fsedsl
|
||||
package virtfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Package fsedsl provides an embedded domain-specific language for declaring
|
||||
// Package virtfs provides an embedded domain-specific language for declaring
|
||||
// synthetic filesystems. It is designed for building 9P namespaces where the
|
||||
// entire filesystem structure is declared statically but populated dynamically.
|
||||
//
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
// )
|
||||
//
|
||||
// tree := BuildTree(spec)
|
||||
package fsedsl
|
||||
package virtfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package fsedsl
|
||||
package virtfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package fsedsl
|
||||
package virtfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module ollie/virtfs
|
||||
|
||||
go 1.25.6
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package fsedsl
|
||||
package virtfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package fsedsl
|
||||
package virtfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package fsedsl
|
||||
package virtfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
Loading…
Reference in New Issue