Example #1
0
File: rsync.go Project: yuuki/droot
func Rsync(from, to string, arg ...string) error {
	from = from + "/"
	// append "/" when not terminated by "/"
	if strings.LastIndex(to, "/") != len(to)-1 {
		to = to + "/"
	}

	rsyncArgs := []string{}
	rsyncArgs = append(rsyncArgs, RsyncDefaultOpts...)

	// Exclude bind-mounted directory by droot run
	mnt := mounter.NewMounter(to)
	mounts, err := mnt.GetMountsRoot()
	if err != nil {
		return err
	}
	for _, m := range mounts {
		mp := strings.TrimPrefix(m.Mountpoint, to)
		rsyncArgs = append(rsyncArgs, fmt.Sprintf("--exclude=/%s", mp))
	}

	rsyncArgs = append(rsyncArgs, from, to)

	if err := osutil.RunCmd("rsync", rsyncArgs...); err != nil {
		return err
	}

	return nil
}
Example #2
0
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()
}
Example #3
0
File: rm.go Project: yuuki/droot
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)
}
Example #4
0
File: run.go Project: yuuki/droot
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)
}