package host import ( "archive/tar" "io" "io/fs" "os" "path/filepath" "syscall" "sirherobrine23.com.br/go-bds/exec/v2/process" ) var _ process.Rootfs = (*Rootfs)(nil) type Rootfs struct { Path string // Rootfs storage files Chroot bool // Start process with chroot Proot bool // Start process with proot avaible } func (rootfs *Rootfs) Close() error { return nil } func (rootfs *Rootfs) Tar(w io.Writer) error { t := tar.NewWriter(w) defer t.Close() return t.AddFS(os.DirFS(rootfs.Path)) } func (rootfs *Rootfs) FromTar(r io.Reader) error { t := tar.NewReader(r) for { h, err := t.Next() switch err { case nil: case io.EOF: return nil default: return err } rootName := filepath.Join(rootfs.Path, h.Name) switch h.FileInfo().Mode().Type() { case fs.ModeNamedPipe: case fs.ModeSocket: case fs.ModeDevice: case fs.ModeCharDevice: case fs.ModeAppend: case fs.ModeExclusive: case fs.ModeTemporary: case fs.ModeSetuid: case fs.ModeSetgid: case fs.ModeSticky: case fs.ModeIrregular: case fs.ModeDir: if err := os.Mkdir(rootName, h.FileInfo().Mode().Perm()); err != nil { return err } case fs.ModeSymlink: if err := os.Symlink(h.Linkname, rootName); err != nil { return err } default: f, err := os.OpenFile(rootName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, h.FileInfo().Mode().Perm()) if err != nil { return err } // Copy Content body _, err = io.Copy(f, t) f.Chmod(h.FileInfo().Mode().Perm()) f.Chown(h.Uid, h.Gid) f.Close() if err != nil { return err } } } } func (rootfs *Rootfs) NewProcess() (process.Proc, error) { newProc := new(Os) newProc.Rootfs = rootfs.Path if rootfs.Chroot { newProc.SysProc = &syscall.SysProcAttr{ Chroot: rootfs.Path, } } return newProc, nil }