package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"syscall"

)
/*func main(){
	cmd:= exec.Command("sh")
	cmd.SysProcAttr=&syscall.SysProcAttr{
		Cloneflags:syscall.CLONE_NEWUTS,
	}
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err !=nil{
		log.Fatal(err)
	}
}*/
func main() {
	switch os.Args[1] {
	case "run":
		run()
	case "parent":
		parent()
	case "child":
		child()
	default:
		panic("default, wat should I do")
	}
}

func run() {
	cmd:= exec.Command("sh")
	cmd.SysProcAttr=&syscall.SysProcAttr{
		Cloneflags:syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWNET | syscall.CLONE_NEWIPC ,
	}
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err !=nil{
		log.Fatal(err)
	}
	/*
	fmt.Println("runing cmd \r\n", os.Args[1:])
	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWNET | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER,
	}
	cmd.Stdin =  os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	must(cmd.Run())*/
}
func must(err error) {
	if err != nil {
		panic(err)
	}
}
func parent(){
	cmd:= exec.Command("/proc/self/exe",append([]string{"child"},os.Args[2:]...)...)
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWNET | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER,
	}
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err:=cmd.Run();err !=nil{
		fmt.Println("ERROR",err)
		os.Exit(1)
	}
}
func child(){
	must(syscall.Mount("rootfs","rootfs","",syscall.MS_BIND,""))
	must(os.MkdirAll("rootfs/oldrootfs",0700))
	must(syscall.PivotRoot("rootfs","rootfs/oldrootfs"))
	must(os.Chdir("/"))
	cmd:= exec.Command(os.Args[2],os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err !=nil {
		fmt.Println("ERROR",err)
		os.Exit(1)
	}
}
02-18 12:27