Backup snapshoting
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-05-05 01:04:16 +02:00
parent 9e174565ce
commit c0ad8cffb2

59
main.go
View File

@@ -35,11 +35,14 @@ import (
)
type ofsVolume struct {
Volume *volume.Volume
Fs string
Opts string
Env []string
Asap bool
Volume *volume.Volume
Fs string
Opts string
Env []string
Asap bool
// Create a snaphot on each mount (and delete the previous one)
Backup bool
BackupSnapshot string
MountSnapshots bool
SnapshotsFilter string
}
@@ -103,6 +106,8 @@ func (d *ofsDriver) Create(r *volume.CreateRequest) error {
}
case "asap":
v.Asap = true
case "backup":
v.Backup = true
case "mountSnapshots":
v.MountSnapshots = val == "yes"
case "snapshotsFilter":
@@ -200,6 +205,15 @@ func umount(v *ofsVolume, rt *ofsVolumeRt) error {
if err := os.Remove(v.Volume.Mountpoint); err != nil {
return err
}
if v.Backup {
if err := applyEnv(exec.Command("/sbin/mount.objectivefs", "destroy", v.BackupSnapshot, "-f"), v.Env).Wait(); err == nil {
log.WithFields(log.Fields{"name": v.Volume.Name, "snapshot": v.BackupSnapshot}).Info("Failed to destroy the previous snapshot")
return err
}
v.BackupSnapshot = ""
}
rt.mounted = false
return nil
}
@@ -276,17 +290,48 @@ func (d *ofsDriver) Mount(r *volume.MountRequest) (*volume.MountResponse, error)
}
log.WithFields(log.Fields{"name": r.Name, "id": r.ID}).Info("Attach ObjectiveFS Volume")
// Each mount request causes new snapshot to get created and the old one deleted
if v.Backup && rt.mounted {
log.WithFields(log.Fields{"name": r.Name, "snapshot": v.BackupSnapshot}).Info("Going to unmount and destroy the previous backup snapshot")
if err := umount(v, rt); err != nil {
return &volume.MountResponse{}, err
}
}
if !rt.mounted {
if err := os.MkdirAll(v.Volume.Mountpoint, 0755); err != nil {
return &volume.MountResponse{}, err
}
var fs string
if v.Backup {
log.WithFields(log.Fields{"name": r.Name}).Info("Going to create a backup snapshot")
if snapshotTextB, err := applyEnv(exec.Command("/sbin/mount.objectivefs", "snapshot", v.Fs), v.Env).CombinedOutput(); err == nil {
log.WithFields(log.Fields{"name": v.Volume.Name, "output": string(snapshotTextB[:])}).Info("Failed to create a new backup snapshot")
return &volume.MountResponse{}, err
} else {
// Format: NOTE: Successfully created snapshot: snapshotId (<current UTC time>)
const okPrefix = "NOTE: Successfully created snapshot:"
snapshotText := string(snapshotTextB[:])
if snapshotIdWithSuffix, isOk := strings.CutPrefix(snapshotText, okPrefix); !isOk {
log.WithFields(log.Fields{"name": v.Volume.Name, "snapshot": v.BackupSnapshot}).Info("Failed to create a new backup snapshot")
return &volume.MountResponse{}, err
} else {
v.BackupSnapshot = strings.SplitAfter(snapshotIdWithSuffix, " ")[0]
fs = v.BackupSnapshot
}
}
} else {
fs = v.Fs
}
// Note: The first argument ("mount") causes running in the foreground, its absence in the background
var cmd *exec.Cmd
if len(v.Opts) == 0 {
cmd = exec.Command("/sbin/mount.objectivefs", "mount", v.Fs, v.Volume.Mountpoint)
cmd = exec.Command("/sbin/mount.objectivefs", "mount", fs, v.Volume.Mountpoint)
} else {
cmd = exec.Command("/sbin/mount.objectivefs", "mount", "-o"+v.Opts, v.Fs, v.Volume.Mountpoint)
cmd = exec.Command("/sbin/mount.objectivefs", "mount", "-o"+v.Opts, fs, v.Volume.Mountpoint)
}
cmd.Env = v.Env