func doRun(c *cli.Context) error { command := c.Args() if len(command) < 1 { cli.ShowCommandHelp(c, "run") return errors.New("command required") } rootDir := c.String("root") if rootDir == "" { cli.ShowCommandHelp(c, "run") return errors.New("--root option required") } if !osutil.ExistsDir(rootDir) { return fmt.Errorf("No such directory %s:", rootDir) } var err error uid, gid := os.Getuid(), os.Getgid() if group := c.String("group"); group != "" { if gid, err = osutil.LookupGroup(group); err != nil { return fmt.Errorf("Failed to lookup group:", err) } } if user := c.String("user"); user != "" { if uid, err = osutil.LookupUser(user); err != nil { return fmt.Errorf("Failed to lookup user:"******"copy-files") { for _, f := range copyFiles { srcFile, destFile := fp.Join("/", f), fp.Join(rootDir, f) if err := osutil.Cp(srcFile, destFile); err != nil { return fmt.Errorf("Failed to copy %s:", f, err) } if err := os.Lchown(destFile, uid, gid); err != nil { return fmt.Errorf("Failed to lchown %s:", f, err) } } } // mount -t proc none {{rootDir}}/proc if err := mount.Mount("none", fp.Join(rootDir, "/proc"), "proc", ""); err != nil { return fmt.Errorf("Failed to mount /proc: %s", err) } // mount --rbind /sys {{rootDir}}/sys if err := mount.Mount("/sys", fp.Join(rootDir, "/sys"), "none", "rbind"); err != nil { return fmt.Errorf("Failed to mount /sys: %s", err) } for _, dir := range c.StringSlice("bind") { if err := bindMount(dir, rootDir, false); err != nil { return fmt.Errorf("Failed to bind mount %s:", dir, err) } } for _, dir := range c.StringSlice("robind") { if err := bindMount(dir, rootDir, true); err != nil { return fmt.Errorf("Failed to robind mount %s:", dir, err) } } // create symlinks if err := osutil.Symlink("../run/lock", fp.Join(rootDir, "/var/lock")); err != nil { return fmt.Errorf("Failed to symlink lock file:", err) } if err := createDevices(rootDir, uid, gid); err != nil { return fmt.Errorf("Failed to create devices:", err) } log.Debug("chroot", rootDir, command) if err := syscall.Chroot(rootDir); err != nil { return fmt.Errorf("Failed to chroot:", err) } if err := syscall.Chdir("/"); err != nil { return fmt.Errorf("Failed to chdir /:", err) } if !c.Bool("no-dropcaps") { log.Debug("drop capabilities") if err := osutil.DropCapabilities(keepCaps); err != nil { return fmt.Errorf("Failed to drop capabilities:", err) } } log.Debug("setgid", gid) if err := osutil.Setgid(gid); err != nil { return fmt.Errorf("Failed to set group %d:", gid, err) } log.Debug("setuid", uid) if err := osutil.Setuid(uid); err != nil { return fmt.Errorf("Failed to set user %d:", uid, err) } return osutil.Execv(command[0], command[0:], os.Environ()) }
func doPull(c *cli.Context) error { destDir := c.String("dest") srcURL := c.String("src") if destDir == "" || srcURL == "" { cli.ShowCommandHelp(c, "pull") return errors.New("--src and --dest option required ") } s3URL, err := url.Parse(srcURL) if err != nil { return err } if s3URL.Scheme != "s3" { return fmt.Errorf("Not s3 scheme %s", srcURL) } uid, gid := os.Getuid(), os.Getgid() if group := c.String("group"); group != "" { if gid, err = osutil.LookupGroup(group); err != nil { return fmt.Errorf("Failed to lookup group:", err) } } if user := c.String("user"); user != "" { if uid, err = osutil.LookupUser(user); err != nil { return fmt.Errorf("Failed to lookup user:"******"droot_gzip") if err != nil { return fmt.Errorf("Failed to create temporary file: %s", err) } defer func(f *os.File) { f.Close() os.Remove(f.Name()) }(tmp) nBytes, err := aws.NewS3Client().Download(s3URL, tmp) if err != nil { return fmt.Errorf("Failed to download file(%s) from s3: %s", srcURL, err) } log.Info("downloaded", "from", s3URL, "to", tmp.Name(), nBytes, "bytes") rawDir, err := ioutil.TempDir(os.TempDir(), "droot_raw") if err != nil { return fmt.Errorf("Failed to create temporary dir: %s", err) } defer os.RemoveAll(rawDir) log.Info("Extract archive:", tmp.Name(), "to", rawDir) if err := archive.ExtractTarGz(tmp, rawDir, uid, gid); err != nil { return fmt.Errorf("Failed to extract archive: %s", err) } log.Info("Sync:", "from", rawDir, "to", destDir) if err := archive.Rsync(rawDir, destDir); err != nil { return fmt.Errorf("Failed to rsync: %s", err) } if err := os.Lchown(destDir, uid, gid); err != nil { return fmt.Errorf("Failed to chown %d:%d: %s", uid, gid, err) } if err := os.Chmod(destDir, os.FileMode(0755)); err != nil { return fmt.Errorf("Failed to chmod %s: %s", destDir, err) } return nil }