Example #1
0
func (d *Btrfs) Subvolumes(config config.Config) ([]string, error) {

	var stderr bytes.Buffer
	var stdout bytes.Buffer
	cmd := exec.Command("btrfs", "subvolume", "list", config.Subvolume())
	cmd.Stderr = &stderr
	cmd.Stdout = &stdout

	log.Printf("Getting subvolume list for: %s", config.Subvolume())
	if err := cmd.Start(); err != nil {
		return nil, err
	}

	if err := cmd.Wait(); err != nil {
		err = fmt.Errorf("Error getting subvolume list: %s\nStderr: %s",
			err, stderr.String())
		return nil, err
	}

	output := stdout.String()

	// partition output into slice
	subvols := strings.Split(output, "\n")[0 : len(strings.Split(output, "\n"))-1]

	return subvols, nil
}
Example #2
0
func (d *Btrfs) Prepare(config config.Config) error {
	// test to see if subvolume is a valid btrfs file system

	var stderr bytes.Buffer
	cmd := exec.Command("btrfs", "subvolume", "show", config.Subvolume())
	cmd.Stderr = &stderr

	log.Printf("Checking to see if valid subvolume: %s", config.Subvolume())
	if err := cmd.Start(); err != nil {
		return err
	}

	if err := cmd.Wait(); err != nil {
		err = fmt.Errorf("Error checking for a valid subvolume: %s\nStderr: %s",
			err, stderr.String())
		return err
	}

	// all good, is a valid subvolume
	log.Printf("Valid subvolume found: %s", config.Subvolume())

	return nil

}
Example #3
0
func (d *Btrfs) Snapshot(config config.Config, srcSnapshot string) (string, error) {

	snapshot_dir := config.Subvolume() + "/" + config.SubvolumeDirectory()

	t := time.Now()

	timestamp := t.Format("20060102150405")

	snapshot := snapshot_dir + "/btrfs_backup_" + timestamp

	log.Printf("Making sure of the source directory: %s", srcSnapshot)

	var stderr bytes.Buffer
	cmd := exec.Command("btrfs", "subvolume", "show", srcSnapshot)
	cmd.Stderr = &stderr

	if err := cmd.Start(); err != nil {
		return "", err
	}

	if err := cmd.Wait(); err != nil {
		err = fmt.Errorf("Error checking for a valid subvolume: %s\nStderr: %s",
			err, stderr.String())
		return "", err
	}

	log.Printf("Valid subvolume found: %s", srcSnapshot)

	log.Printf("Making sure of the destination directory: %s", snapshot_dir)

	create_destination := false
	var stderr3 bytes.Buffer
	cmd = exec.Command("btrfs", "subvolume", "show", snapshot_dir)
	cmd.Stderr = &stderr3

	if err := cmd.Start(); err != nil {
		return "", err
	}

	if err := cmd.Wait(); err != nil {
		create_destination = true
	}

	if create_destination == true {

		log.Printf("Error in verifying the destination subvolume %s, trying to create it", snapshot_dir)

		new_volume, err_create := d.CreateSubvolume(snapshot_dir)

		if new_volume == snapshot_dir && err_create == nil {
			log.Printf("New subvolume created: %s", snapshot_dir)
		} else {

			err_create = fmt.Errorf("Error creating new subvolume. \nStderr: %s",
				err_create)

			return "", err_create
		}

	}

	log.Printf("Valid subvolume found: %s", snapshot_dir)

	// all good, is a valid subvolume source and destination
	log.Printf("Creating snapshot in: %s", snapshot)

	var stderr2 bytes.Buffer

	cmd = exec.Command("btrfs", "subvolume", "snapshot", "-r", srcSnapshot, snapshot)
	cmd.Stderr = &stderr2

	if err := cmd.Start(); err != nil {
		return "", err
	}

	if err := cmd.Wait(); err != nil {
		err = fmt.Errorf("Error creating snapshot: %s\nStderr: %s",
			err, stderr2.String())
		return "", err
	}

	cmd = exec.Command("sync", snapshot_dir)
	cmd.Stderr = &stderr2

	if err := cmd.Start(); err != nil {
		return "", err
	}

	if err := cmd.Wait(); err != nil {
		err = fmt.Errorf("Error running filesystem sync: %s\nStderr: %s",
			err, stderr2.String())
		return "", err
	}

	log.Printf("Snapshot created: %s from %s", snapshot, srcSnapshot)

	return snapshot, nil
}