Compare commits

...

3 commits

2 changed files with 31 additions and 2 deletions

View file

@ -2,4 +2,19 @@
> docker but simpler
Usage: `miniroot -root "/opt/something" -workdir "/usr/src/app" -init "/usr/loacal/bin/npm start"`
In contrast to Docker, miniroot **does not**:
- have a concept of images and layers
- isolate networks
- handle volumes or bind mounts
- have a central daemon
It's just a simple tool that utilises namespaces to run applications in a semi-isolated environment.
### Usage
- get rootfs (you can use `docker export container_name > export.tar` for that)
- extract it somewhere
- run miniroot; example:
```
miniroot -root "/opt/something" -workdir "/usr/src/app" -init "/usr/local/bin/npm start"
```

16
main.go
View file

@ -5,6 +5,7 @@ import (
"fmt"
"os"
"os/exec"
"os/signal"
"strings"
"syscall"
)
@ -12,6 +13,7 @@ import (
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")
var pidns = flag.Bool("pidns", false, "create pid namespace")
func main() {
flag.Parse()
@ -26,7 +28,7 @@ func main() {
cmd.Dir = *workdir
cmd.SysProcAttr = &syscall.SysProcAttr{
Chroot: *rootPath,
Cloneflags: syscall.CLONE_NEWUSER|syscall.CLONE_NEWPID,
Cloneflags: syscall.CLONE_NEWUSER,
UidMappings: []syscall.SysProcIDMap{
{ContainerID: 0, HostID: os.Getuid(), Size: 1},
},
@ -34,6 +36,9 @@ func main() {
{ContainerID: 0, HostID: os.Getgid(), Size: 1},
},
}
if *pidns {
cmd.SysProcAttr.Cloneflags |= syscall.CLONE_NEWPID
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -42,6 +47,15 @@ func main() {
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)
err = cmd.Wait()
if err != nil {
fmt.Printf("process exited with error: %s\n", err)