basic structure of idea

This commit is contained in:
CRThaze 2024-07-03 08:33:12 +00:00 committed by Diego Fernando Carrión
parent fd424a83c9
commit 83eaae6a73
Signed by: CRThaze
GPG Key ID: 8279B79A1A7F8194
5 changed files with 209 additions and 1 deletions

4
files/test.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "I'm working!"
pwd

5
go.mod
View File

@ -1,3 +1,8 @@
module git.sdf.org/CRThaze/gfw
go 1.22.5
require (
bazil.org/fuse v0.0.0-20230120002735-62a210ff1fd5 // indirect
golang.org/x/sys v0.4.0 // indirect
)

4
go.sum Normal file
View File

@ -0,0 +1,4 @@
bazil.org/fuse v0.0.0-20230120002735-62a210ff1fd5 h1:A0NsYy4lDBZAC6QiYeJ4N+XuHIKBpyhAVRMHRQZKTeQ=
bazil.org/fuse v0.0.0-20230120002735-62a210ff1fd5/go.mod h1:gG3RZAMXCa/OTes6rr9EwusmR1OH1tDDy+cg9c5YliY=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

26
main.go Normal file
View File

@ -0,0 +1,26 @@
package main
import (
"embed"
"log"
)
//go:embed files/*
var content embed.FS
func main() {
gfw, err := NewGFW(GFWConfig{
EmbedFS: content,
DefaultExecutable: "test.sh",
})
if err != nil {
log.Fatalf("Unable to create GFW: %v", err)
}
if err := gfw.Mount(); err != nil {
log.Fatalf("Unable to mount GFW:, %v", err)
}
defer gfw.Unmount()
if err := gfw.Execute(); err != nil {
log.Fatalf("Failed to execute: %v", err)
}
}

171
wrap.go
View File

@ -1 +1,170 @@
package gfw
package main
import (
"context"
"embed"
"fmt"
"io/fs"
"os"
"os/exec"
"path"
"strings"
"time"
"bazil.org/fuse"
fuseFS "bazil.org/fuse/fs"
)
type FS struct {
fsys fs.FS
}
func (f *FS) Root() (fuseFS.Node, error) {
return &Dir{fsys: f.fsys}, nil
}
type Dir struct {
fsys fs.FS
}
func (d *Dir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Mode = os.ModeDir | 0o555
return nil
}
func (d *Dir) Lookup(name string) (fuseFS.Node, error) {
file, err := d.fsys.Open(name)
if err != nil {
return nil, fuse.ToErrno(err)
}
defer file.Close()
stat, err := file.Stat()
if err != nil {
return nil, err
}
if stat.IsDir() {
return &Dir{fsys: d.fsys}, nil
}
return &File{file: file, size: uint64(stat.Size())}, nil
}
type File struct {
file fs.File
size uint64
}
func (f *File) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Mode = 0o444
attr.Size = f.size
attr.Mtime = time.Now()
return nil
}
// func (f *File) ReadAll() ([]byte, error) {
// return fs.ReadFile(f.file)
// }
type GFWConfig struct {
EmbedFS embed.FS
DefaultExecutable string
OtherExecutables []string
Mountpoint string
}
type GFW interface {
Mount() error
Unmount() error
Execute(...string) error
}
type gfw struct {
fs embed.FS
conn *fuse.Conn
mounted bool
mountpoint string
defaultExecutable string
executables map[string]struct{}
}
func (g *gfw) Mount() error {
if g.mounted {
return fmt.Errorf("Already mounted.")
}
tempDir := os.TempDir()
if strings.HasSuffix(g.mountpoint, "/*") {
tempDir = strings.TrimSuffix(g.mountpoint, "/*")
g.mountpoint = ""
}
if g.mountpoint == "" {
if dir, err := os.MkdirTemp(tempDir, "*"); err == nil {
g.mountpoint = dir
} else {
return err
}
}
if conn, err := fuse.Mount(g.mountpoint); err == nil {
g.conn = conn
} else {
return err
}
if err := fuseFS.Serve(g.conn, &FS{fsys: g.fs}); err != nil {
return err
}
g.mounted = true
return nil
}
func (g *gfw) Unmount() error {
if err := fuse.Unmount(g.mountpoint); err != nil {
return err
}
return g.conn.Close()
}
func (g *gfw) Execute(execAndArgs ...string) error {
if !g.mounted {
return fmt.Errorf("GFW is not mounted.")
}
if len(g.executables) == 0 {
return fmt.Errorf("No registerd executables.")
}
execName := g.defaultExecutable
args := []string{}
if len(execAndArgs) > 0 {
execName = execAndArgs[0]
if _, ok := g.executables[execName]; !ok {
return fmt.Errorf("Unregisterd executable.")
}
if len(execAndArgs) > 1 {
args = execAndArgs[1:]
}
}
execName = path.Join(g.mountpoint, execName)
cmd := exec.Command(execName, args[1:]...)
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func NewGFW(conf GFWConfig) (GFW, error) {
if conf.OtherExecutables == nil {
conf.OtherExecutables = []string{}
if conf.DefaultExecutable != "" {
conf.OtherExecutables = append(conf.OtherExecutables, conf.DefaultExecutable)
}
}
g := gfw{
fs: conf.EmbedFS,
mountpoint: conf.Mountpoint,
defaultExecutable: conf.DefaultExecutable,
executables: map[string]struct{}{},
}
for _, e := range conf.OtherExecutables {
g.executables[e] = struct{}{}
}
return &g, nil
}