miniroot/main.go

64 lines
1.3 KiB
Go
Raw Normal View History

2022-01-18 01:01:40 +00:00
package main
import (
"flag"
"fmt"
"os"
"os/exec"
"os/signal"
2022-01-18 01:01:40 +00:00
"strings"
"syscall"
)
var rootPath = flag.String("root", "", "path to root directory")
var initCmd = flag.String("init", "/sbin/init", "init command")
var workdir = flag.String("workdir", "/", "work directory")
2022-01-18 13:49:41 +00:00
var pidns = flag.Bool("pidns", false, "create pid namespace")
2022-01-18 01:01:40 +00:00
func main() {
flag.Parse()
if *rootPath == "" {
fmt.Println("root directory not set")
os.Exit(1)
}
initParts := strings.Split(*initCmd, " ")
cmd := exec.Command(initParts[0], initParts[1:]...)
cmd.Dir = *workdir
cmd.SysProcAttr = &syscall.SysProcAttr{
Chroot: *rootPath,
2022-01-18 13:49:41 +00:00
Cloneflags: syscall.CLONE_NEWUSER,
2022-01-18 01:01:40 +00:00
UidMappings: []syscall.SysProcIDMap{
{ContainerID: 0, HostID: os.Getuid(), Size: 1},
},
GidMappings: []syscall.SysProcIDMap{
{ContainerID: 0, HostID: os.Getgid(), Size: 1},
},
}
2022-01-18 13:49:41 +00:00
if *pidns {
cmd.SysProcAttr.Cloneflags |= syscall.CLONE_NEWPID
}
2022-01-18 01:01:40 +00:00
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Start()
if err != nil {
fmt.Printf("failed to start: %s\n", err)
}
sigs := make(chan os.Signal, 1)
go func() {
for {
_ = <-sigs
cmd.Process.Signal(syscall.SIGTERM)
}
}()
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
2022-01-18 01:01:40 +00:00
err = cmd.Wait()
if err != nil {
fmt.Printf("process exited with error: %s\n", err)
}
}