Advertisement
Uno-Dan

Go Container

Jul 27th, 2021
1,316
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 1.81 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "io/ioutil"
  6.     "os"
  7.     "os/exec"
  8.     "path/filepath"
  9.     "strconv"
  10.     "syscall"
  11. )
  12.  
  13. func main() {
  14.     switch os.Args[1] {
  15.     case "run":
  16.         run()
  17.     case "child":
  18.         child()
  19.  
  20.     default:
  21.         panic("bad command")
  22.     }
  23. }
  24.  
  25. func run() {
  26.     fmt.Printf("Running %v as pid %d\n", os.Args[2:], os.Getpid())
  27.  
  28.     cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
  29.     cmd.Stdin = os.Stdin
  30.     cmd.Stdout = os.Stdout
  31.     cmd.Stderr = os.Stderr
  32.  
  33.     cmd.SysProcAttr = &syscall.SysProcAttr{
  34.         Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER,
  35.         Credential: &syscall.Credential{Uid: 0, Gid: 0},
  36.         UidMappings: []syscall.SysProcIDMap{
  37.             {ContainerID: 0, HostID: os.Getuid(), Size: 1},
  38.         },
  39.         GidMappings: []syscall.SysProcIDMap{
  40.             {ContainerID: 0, HostID: os.Getgid(), Size: 1},
  41.         },
  42.     }
  43.  
  44.     must(cmd.Run())
  45. }
  46.  
  47. func child() {
  48.     fmt.Printf("Running %v as pid %d\n", os.Args[2:], os.Getpid())
  49.  
  50.     cg()
  51.  
  52.     cmd := exec.Command(os.Args[2], os.Args[3:]...)
  53.     cmd.Stdin = os.Stdin
  54.     cmd.Stdout = os.Stdout
  55.     cmd.Stderr = os.Stderr
  56.  
  57.     must(syscall.Sethostname([]byte("MACHINE")))
  58.     must(syscall.Chroot("/home/dan/images/rocky"))
  59.     must(syscall.Chdir("/"))
  60.     must(syscall.Mount("proc", "proc", "proc", 0, ""))
  61.  
  62.     must(cmd.Run())
  63.     must(syscall.Unmount("proc", 0))
  64. }
  65.  
  66. func cg() {
  67.     cgroups := "/sys/fs/cgroup/"
  68.     pids := filepath.Join(cgroups, "pids")
  69.  
  70.     must(os.MkdirAll(filepath.Join(pids, "dan"), 0755))
  71.  
  72.     must(ioutil.WriteFile(filepath.Join(pids, "dan/pids.max"), []byte("20"), 0700))
  73.     must(ioutil.WriteFile(filepath.Join(pids, "dan/notify_on_release"), []byte("1"), 0700))
  74.     must(ioutil.WriteFile(filepath.Join(pids, "dan/cgroup.procs"), []byte(strconv.Itoa(os.Getpid())), 0700))
  75. }
  76.  
  77. func must(err error) {
  78.     if err != nil {
  79.         panic(err)
  80.     }
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement