Some checks failed
Golang test / go-test (push) Failing after 11s
177 lines
5.0 KiB
Go
177 lines
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"path/filepath"
|
|
|
|
"sirherobrine23.com.br/Sirherobrine23/cgofuse/fs"
|
|
"sirherobrine23.com.br/go-bds/overlayfs"
|
|
)
|
|
|
|
type arrayFlags []string
|
|
|
|
// String is an implementation of the flag.Value interface
|
|
func (i *arrayFlags) String() string {
|
|
return fmt.Sprintf("%v", *i)
|
|
}
|
|
|
|
// Set is an implementation of the flag.Value interface
|
|
func (i *arrayFlags) Set(value string) error {
|
|
*i = append(*i, value)
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
Config = flag.String("config", "", "config gile")
|
|
Target = flag.String("target", "target", "Target folder to mount")
|
|
Upper = flag.String("upper", "", "Upper folder to write modifications")
|
|
Work = flag.String("work", "", "Work folder to write temporary files")
|
|
Lower = arrayFlags{}
|
|
)
|
|
|
|
func main() {
|
|
flag.Var(&Lower, "lower", "Lower folder to read")
|
|
flag.Parse()
|
|
|
|
// Mounting config
|
|
var overlayFSConfig *overlayfs.Overlayfs
|
|
if *Config == "" {
|
|
overlayFSConfig = overlayfs.NewOverlayFS(*Target, *Upper, *Work, Lower...)
|
|
} else {
|
|
var jsConfig map[string]any
|
|
data, err := os.ReadFile(*Config)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
|
os.Exit(1)
|
|
return
|
|
} else if err = json.Unmarshal(data, &jsConfig); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
|
|
dirBase := filepath.Dir(*Config)
|
|
overlayFSConfig = new(overlayfs.Overlayfs)
|
|
for key, value := range jsConfig {
|
|
var ok bool
|
|
switch key {
|
|
case "target":
|
|
if overlayFSConfig.Target, ok = value.(string); !ok {
|
|
fmt.Fprintln(os.Stderr, "Config: target must be a string")
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
overlayFSConfig.Target = filepath.Join(dirBase, overlayFSConfig.Target)
|
|
case "upper":
|
|
if overlayFSConfig.Upper, ok = value.(string); !ok {
|
|
fmt.Fprintln(os.Stderr, "Config: upper must be a string")
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
overlayFSConfig.Upper = filepath.Join(dirBase, overlayFSConfig.Upper)
|
|
case "work":
|
|
if overlayFSConfig.Workdir, ok = value.(string); !ok {
|
|
fmt.Fprintln(os.Stderr, "Config: work must be a string")
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
overlayFSConfig.Workdir = filepath.Join(dirBase, overlayFSConfig.Workdir)
|
|
case "lower":
|
|
for index, lower := range value.([]any) {
|
|
value, ok := lower.(string)
|
|
if !ok {
|
|
fmt.Fprintf(os.Stderr, "Config: lower[%d] must be a string\n", index)
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
overlayFSConfig.Lower = append(overlayFSConfig.Lower, filepath.Join(dirBase, value))
|
|
}
|
|
case "lower_mkdir":
|
|
// [string, {name: string, type: "file"|"dir"}...]
|
|
if lowerMkdir, ok := value.([]any); ok && len(lowerMkdir) > 0 {
|
|
for _, v := range lowerMkdir {
|
|
var mkdirPath string
|
|
for _, value := range v.([]any) {
|
|
switch v := value.(type) {
|
|
case string:
|
|
mkdirPath = filepath.Join(dirBase, v)
|
|
overlayFSConfig.Lower = append(overlayFSConfig.Lower, filepath.Join(dirBase, v))
|
|
case map[string]any:
|
|
name, ok := v["name"].(string)
|
|
if !ok {
|
|
continue
|
|
}
|
|
ftype, ok := v["type"].(string)
|
|
if !ok {
|
|
continue
|
|
}
|
|
mkdirPath := filepath.Join(mkdirPath, name)
|
|
switch ftype {
|
|
case "file":
|
|
os.MkdirAll(filepath.Join(mkdirPath, filepath.Dir(mkdirPath)), 0777)
|
|
os.WriteFile(mkdirPath, []byte{}, 0666)
|
|
case "dir":
|
|
os.MkdirAll(mkdirPath, 0777)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, folderPath := range append(overlayFSConfig.Lower, overlayFSConfig.Target, overlayFSConfig.Upper, overlayFSConfig.Workdir) {
|
|
if folderPath == "" {
|
|
continue
|
|
} else if _, err := os.Stat(folderPath); os.IsNotExist(err) {
|
|
if err = os.MkdirAll(folderPath, 0777); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
wd, _ := os.Getwd()
|
|
if !filepath.IsAbs(overlayFSConfig.Target) {
|
|
overlayFSConfig.Target = filepath.Join(wd, overlayFSConfig.Target)
|
|
}
|
|
if overlayFSConfig.Upper != "" && !filepath.IsAbs(overlayFSConfig.Upper) {
|
|
overlayFSConfig.Upper = filepath.Join(wd, overlayFSConfig.Upper)
|
|
}
|
|
if overlayFSConfig.Workdir != "" && !filepath.IsAbs(overlayFSConfig.Workdir) {
|
|
overlayFSConfig.Workdir = filepath.Join(wd, overlayFSConfig.Workdir)
|
|
}
|
|
for index, lowPath := range overlayFSConfig.Lower {
|
|
if !filepath.IsAbs(lowPath) {
|
|
overlayFSConfig.Lower[index] = filepath.Join(wd, lowPath)
|
|
}
|
|
}
|
|
|
|
d, _ := json.MarshalIndent(overlayFSConfig, "", " ")
|
|
println(string(d))
|
|
|
|
fmt.Fprintf(os.Stderr, "Mount overlayfs into %q\n", overlayFSConfig.Target)
|
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
|
defer stop()
|
|
|
|
fs := fs.New(overlayFSConfig.Target, overlayFSConfig)
|
|
if err := fs.Mount(ctx); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
|
os.Exit(1)
|
|
return
|
|
}
|
|
fmt.Fprintf(os.Stderr, "Mounted overlayfs\n")
|
|
|
|
<-ctx.Done()
|
|
fmt.Fprintf(os.Stderr, "Unmount overlayfs\n")
|
|
fs.Done()
|
|
fmt.Fprintf(os.Stderr, "Unmounted overlayfs\n")
|
|
}
|