// Snapshot create a btrfs snapshot of a subvolume. func Snapshot(subvolumeDir string, snapshotDir string, readonly bool) error { // Check if the passed subvolume directory is a btrfs subvolume. if !IsSubvolume(subvolumeDir) { return fmt.Errorf("failed to create btrfs snapshot: the subvolume directory '%s' is not a btrfs subvolume!", subvolumeDir) } // The destination snapshot directory should not exist! e, err := utils.Exists(snapshotDir) if err != nil { return err } else if e { return fmt.Errorf("failed to create btrfs snapshot: the snapshot directory '%s' already exists!", snapshotDir) } // Create the snapshot directory. if readonly { err = utils.RunCommand("btrfs", "subvolume", "snapshot", "-r", subvolumeDir, snapshotDir) } else { err = utils.RunCommand("btrfs", "subvolume", "snapshot", subvolumeDir, snapshotDir) } if err != nil { return fmt.Errorf("failed to create btrfs snapshot '%s': %v", snapshotDir, err) } // Force changed blocks to disk, update the super block. err = utils.RunCommand("sync") if err != nil { return fmt.Errorf("failed to force changed blocks to disk, update the super block: %v", err) } return nil }
// SetSubvolumeReadonly sets the readonly flag on a btrfs subvolume. func SetSubvolumeReadonly(subvolumeDir string, readonly bool) error { // Run the command. err := utils.RunCommand("btrfs", "property", "set", "-ts", subvolumeDir, "ro", strconv.FormatBool(readonly)) if err != nil { return fmt.Errorf("failed to set readonly flag of btrfs subvolume '%s': %v", subvolumeDir, err) } return nil }
// DeleteSubvolume deletes a btrfs subvolume. func DeleteSubvolume(subvolumeDir string) error { // Run the command. err := utils.RunCommand("btrfs", "subvolume", "delete", subvolumeDir) if err != nil { return fmt.Errorf("failed to delete the btrfs subvolume '%s': %v", subvolumeDir, err) } return nil }
// IsSubvolume checks if the directory is a btrfs subvolume. func IsSubvolume(subvolumeDir string) bool { // Run the command. err := utils.RunCommand("btrfs", "subvolume", "show", subvolumeDir) if err != nil { return false } return true }
// Balance a btrfs partition. func Balance(path string) error { // Run the command. err := utils.RunCommand("btrfs", "fi", "balance", "start", "-dusage="+strconv.Itoa(config.Config.BtrfsBalanceDusage), path) if err != nil { return fmt.Errorf("failed to balance btrfs path '%s': %v", path, err) } return nil }
func taskFuncCloneSource(app *App) error { app.setState("cloning source") // Clone the source with git. err := utils.RunCommand("git", "clone", "-b", app.settings.Branch, "--single-branch", app.settings.SourceURL, app.SourceDirectoryPath()) if err != nil { return fmt.Errorf("failed to clone application source with git: %v", err) } return nil }