Esempio n. 1
0
// Atomic deploy by symlink
// 1. rsync maindir => backupdir
// 2. mv -T backuplink destdir
// 3. rsync srcdir => maindir
// 4. mv -T mainlink destdir
func DeployWithSymlink(srcDir, destDir string) error {
	mainLink := destDir + ".drootmain"
	backupLink := destDir + ".drootbackup"
	mainDir := destDir + ".d/main"
	backupDir := destDir + ".d/backup"

	for _, dir := range []string{mainDir, backupDir} {
		if err := fileutils.CreateIfNotExists(dir, true); err != nil { // mkdir -p
			return fmt.Errorf("Failed to create directory %s: %s", dir, err)
		}
	}

	// Return error if the working directory that droot internally uses exists
	for _, link := range []string{mainLink, backupLink, destDir} {
		if !osutil.IsSymlink(link) && (osutil.ExistsFile(link) || osutil.ExistsDir(link)) {
			return fmt.Errorf("%s already exists. Please use another directory as --dest option or delete %s", link, link)
		}
	}

	if err := osutil.Symlink(mainDir, mainLink); err != nil {
		return fmt.Errorf("Failed to create symlink %s: %s", mainLink, err)
	}
	if err := osutil.Symlink(backupDir, backupLink); err != nil {
		return fmt.Errorf("Failed to create symlink %s: %s", backupLink, err)
	}

	log.Info("-->", "Syncing", "from", mainDir, "to", backupDir)
	if err := Rsync(mainDir, backupDir); err != nil {
		return fmt.Errorf("Failed to rsync: %s", err)
	}

	log.Info("-->", "Renaming", "from", backupLink, "to", destDir)
	if err := os.Rename(backupLink, destDir); err != nil {
		return fmt.Errorf("Failed to rename %s: %s", destDir, err)
	}

	log.Info("-->", "Syncing", "from", srcDir, "to", mainDir)
	if err := Rsync(srcDir, mainDir); err != nil {
		return fmt.Errorf("Failed to rsync: %s", err)
	}

	log.Info("-->", "Renaming", "from", mainLink, "to", destDir)
	if err := os.Rename(mainLink, destDir); err != nil {
		return fmt.Errorf("Failed to rename %s: %s", destDir, err)
	}

	return nil
}
Esempio n. 2
0
func doDeploy(c *cli.Context) error {
	if c.String("root") == "" {
		cli.ShowCommandHelp(c, "deploy")
		return errors.New("--root required")
	}

	rootDir, err := filepath.Abs(c.String("root"))
	if err != nil {
		return err
	}

	tmpDir, err := ioutil.TempDir(os.TempDir(), "droot")
	if err != nil {
		return fmt.Errorf("Failed to create temporary dir: %s", err)
	}
	defer os.RemoveAll(tmpDir)
	if err := os.Chmod(tmpDir, 0755); err != nil {
		return err
	}

	log.Info("-->", "Extracting", "from", "stdin", "to", tmpDir)
	if err := archive.Untar(os.Stdin, tmpDir, c.Bool("same-owner")); err != nil {
		return err
	}

	switch c.String("mode") {
	case "", "rsync":
		log.Info("-->", "Syncing", "from", tmpDir, "to", rootDir)

		if err := deploy.Rsync(tmpDir, rootDir); err != nil {
			return fmt.Errorf("Failed to rsync: %s", err)
		}
	case "symlink":
		if err := deploy.DeployWithSymlink(tmpDir, rootDir); err != nil {
			return err
		}
	default:
		return fmt.Errorf("Invalid mode %s. '--mode' must be 'rsync' or 'symlink'.", c.String("mode"))
	}

	return nil
}
Esempio n. 3
0
func CleanupSymlink(destDir string) error {
	mainLink := destDir + ".drootmain"
	backupLink := destDir + ".drootbackup"
	contentDir := destDir + ".d/"

	log.Info("-->", "Removing", backupLink)
	if err := osutil.RunCmd("rm", "-f", backupLink); err != nil {
		return err
	}
	log.Info("-->", "Removing", mainLink)
	if err := osutil.RunCmd("rm", "-f", mainLink); err != nil {
		return err
	}
	log.Info("-->", "Removing", contentDir)
	if err := osutil.RunCmd("rm", "-fr", contentDir); err != nil {
		return err
	}

	return osutil.RunCmd("rm", "-f", destDir)
}
Esempio n. 4
0
File: rm.go Progetto: 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)
}