func doUmount(c *cli.Context) error { optRootDir := c.String("root") if optRootDir == "" { cli.ShowCommandHelp(c, "umount") return errors.New("--root option required") } rootDir, err := mounter.ResolveRootDir(optRootDir) if err != nil { return err } mnt := mounter.NewMounter(rootDir) return mnt.UmountRoot() }
func doRm(c *cli.Context) error { optRootDir := c.String("root") if optRootDir == "" { cli.ShowCommandHelp(c, "run") return errors.New("--root option required") } rootDir, err := mounter.ResolveRootDir(optRootDir) if err != nil { return err } mnt := mounter.NewMounter(rootDir) if err := mnt.UmountRoot(); err != nil { return err } if osutil.IsSymlink(optRootDir) { return deploy.CleanupSymlink(optRootDir) } log.Info("-->", "Removing", rootDir) return osutil.RunCmd("rm", "-fr", rootDir) }
func doRun(c *cli.Context) error { command := c.Args() if len(command) < 1 { cli.ShowCommandHelp(c, "run") return errors.New("command required") } optRootDir := c.String("root") if optRootDir == "" { cli.ShowCommandHelp(c, "run") return errors.New("--root option required") } rootDir, err := mounter.ResolveRootDir(optRootDir) if err != nil { return err } // Check env format KEY=VALUE env := c.StringSlice("env") if len(env) > 0 { for _, e := range env { if len(strings.SplitN(e, "=", 2)) != 2 { return fmt.Errorf("Invalid env format: %s", e) } } } 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: %s", err) } } if user := c.String("user"); user != "" { if uid, err = osutil.LookupUser(user); err != nil { return fmt.Errorf("Failed to lookup user: %s", err) } } // copy files if c.Bool("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: %s", f, err) } if err := os.Lchown(destFile, uid, gid); err != nil { return fmt.Errorf("Failed to lchown %s: %s", f, err) } } } mnt := mounter.NewMounter(rootDir) if err := mnt.MountSysProc(); err != nil { return err } for _, val := range c.StringSlice("bind") { hostDir, containerDir, err := parseBindOption(val) if err != nil { return err } if err := mnt.BindMount(hostDir, containerDir); err != nil { return err } } for _, val := range c.StringSlice("robind") { hostDir, containerDir, err := parseBindOption(val) if err != nil { return err } if err := mnt.RoBindMount(hostDir, containerDir); err != nil { return fmt.Errorf("Failed to robind mount %s: %s", val, err) } } // create symlinks if err := osutil.Symlink("../run/lock", fp.Join(rootDir, "/var/lock")); err != nil { return fmt.Errorf("Failed to symlink lock file: %s", err) } if err := createDevices(rootDir, uid, gid); err != nil { return fmt.Errorf("Failed to create devices: %s", err) } if err := osutil.Chroot(rootDir); err != nil { return fmt.Errorf("Failed to chroot: %s", err) } if !c.Bool("no-dropcaps") { if err := osutil.DropCapabilities(keepCaps); err != nil { return fmt.Errorf("Failed to drop capabilities: %s", err) } } if err := osutil.Setgid(gid); err != nil { return fmt.Errorf("Failed to set group %d: %s", gid, err) } if err := osutil.Setuid(uid); err != nil { return fmt.Errorf("Failed to set user %d: %s", uid, err) } if osutil.ExistsFile(environ.DROOT_ENV_FILE_PATH) { envFromFile, err := environ.GetEnvironFromEnvFile(environ.DROOT_ENV_FILE_PATH) if err != nil { return fmt.Errorf("Failed to read environ from '%s'", environ.DROOT_ENV_FILE_PATH) } env, err = environ.MergeEnviron(envFromFile, env) if err != nil { return fmt.Errorf("Failed to merge environ: %s", err) } } return osutil.Execv(command[0], command[0:], env) }