mirror of https://github.com/qwc/backive.git
Working version, now let's beautify that MVP.
This commit is contained in:
parent
6aa693c7cb
commit
f51fb7042d
10
backive.yml
10
backive.yml
|
@ -1,4 +1,7 @@
|
||||||
devices:
|
devices:
|
||||||
|
dev_test:
|
||||||
|
uuid: 714dc1f8-00d7-44b4-b03c-b54498c7cb86
|
||||||
|
owner: qwc
|
||||||
scanner-usbstick:
|
scanner-usbstick:
|
||||||
uuid: 72A9-D8C5
|
uuid: 72A9-D8C5
|
||||||
#mountname: scanner_usbstick
|
#mountname: scanner_usbstick
|
||||||
|
@ -8,6 +11,13 @@ devices:
|
||||||
#mountname: server_backups
|
#mountname: server_backups
|
||||||
owner: qwc
|
owner: qwc
|
||||||
backups:
|
backups:
|
||||||
|
dev_test_backup:
|
||||||
|
user: qwc
|
||||||
|
targetDevice: dev_test
|
||||||
|
frequency: 0
|
||||||
|
scriptPath: ./testbackup.sh
|
||||||
|
sourcePath: /home/qwc/web/worktime
|
||||||
|
targetPath: worktime
|
||||||
scanner_usbstick_test:
|
scanner_usbstick_test:
|
||||||
user: qwc
|
user: qwc
|
||||||
targetDevice: scanner-usbstick
|
targetDevice: scanner-usbstick
|
||||||
|
|
|
@ -47,6 +47,7 @@ var (
|
||||||
runs Runs
|
runs Runs
|
||||||
events EventHandler
|
events EventHandler
|
||||||
)
|
)
|
||||||
|
var devsByUuid string = "/dev/disk/by-uuid"
|
||||||
|
|
||||||
// Database is a simple string to string mapping, where arbitrary strings can be stored and safed to disk or loaded
|
// Database is a simple string to string mapping, where arbitrary strings can be stored and safed to disk or loaded
|
||||||
type Database struct {
|
type Database struct {
|
||||||
|
@ -89,20 +90,27 @@ type Device struct {
|
||||||
UUID string `mapstructure:"uuid"`
|
UUID string `mapstructure:"uuid"`
|
||||||
OwnerUser string `mapstructure:"owner,omitempty"`
|
OwnerUser string `mapstructure:"owner,omitempty"`
|
||||||
isMounted bool
|
isMounted bool
|
||||||
devsByUuid string "/dev/disk/by-uuid/"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mount will mount a device
|
// Mount will mount a device
|
||||||
func (d *Device) Mount() error {
|
func (d *Device) Mount() error {
|
||||||
createDirectoryIfNotExists(config.Settings.SystemMountPoint)
|
log.Printf("Mounting device %s, creating directory if it does not exist.\n", d.Name)
|
||||||
cmd := exec.Command(
|
createDirectoryIfNotExists(
|
||||||
"mount",
|
|
||||||
path.Join(d.devsByUuid, d.UUID),
|
|
||||||
path.Join(config.Settings.SystemMountPoint, d.Name),
|
path.Join(config.Settings.SystemMountPoint, d.Name),
|
||||||
)
|
)
|
||||||
|
time.Sleep(3000 * time.Millisecond)
|
||||||
|
log.Printf("Executing mount command for %s", d.Name)
|
||||||
|
cmd := exec.Command(
|
||||||
|
"mount",
|
||||||
|
path.Join(devsByUuid, d.UUID),
|
||||||
|
path.Join(config.Settings.SystemMountPoint, d.Name),
|
||||||
|
)
|
||||||
|
cmd.Stdout = log.Writer()
|
||||||
|
cmd.Stderr = log.Writer()
|
||||||
|
log.Printf("Command to execute: %s", cmd.String())
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Printf("Mounting failed with error %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
d.isMounted = true
|
d.isMounted = true
|
||||||
|
@ -111,10 +119,11 @@ func (d *Device) Mount() error {
|
||||||
|
|
||||||
// Unmount will unmount a device
|
// Unmount will unmount a device
|
||||||
func (d *Device) Unmount() error {
|
func (d *Device) Unmount() error {
|
||||||
|
log.Printf("Unmounting %s", d.Name)
|
||||||
sync := exec.Command("sync")
|
sync := exec.Command("sync")
|
||||||
syncErr := sync.Run()
|
syncErr := sync.Run()
|
||||||
if syncErr != nil {
|
if syncErr != nil {
|
||||||
log.Fatal(syncErr)
|
log.Println(syncErr)
|
||||||
return syncErr
|
return syncErr
|
||||||
}
|
}
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
|
@ -123,7 +132,7 @@ func (d *Device) Unmount() error {
|
||||||
)
|
)
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Println(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
d.isMounted = false
|
d.isMounted = false
|
||||||
|
@ -164,15 +173,16 @@ type Settings struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Devices is nothing else than a name to Device type mapping
|
// Devices is nothing else than a name to Device type mapping
|
||||||
type Devices map[string]Device
|
type Devices map[string]*Device
|
||||||
|
|
||||||
// Backups is nothing else than a name to Backup type mapping
|
// Backups is nothing else than a name to Backup type mapping
|
||||||
type Backups map[string]Backup
|
type Backups map[string]*Backup
|
||||||
|
|
||||||
|
// findBackupForDevice only finds the first backup which is configured for a given device.
|
||||||
func (bs *Backups) findBackupForDevice(d Device) (*Backup, bool) {
|
func (bs *Backups) findBackupForDevice(d Device) (*Backup, bool) {
|
||||||
for _, b := range *bs {
|
for _, b := range *bs {
|
||||||
if d.Name == b.TargetDevice {
|
if d.Name == b.TargetDevice {
|
||||||
return &b, true
|
return b, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@ -210,10 +220,14 @@ func (c *Configuration) Load() {
|
||||||
panic("No configuration available!")
|
panic("No configuration available!")
|
||||||
}
|
}
|
||||||
for k, v := range c.Backups {
|
for k, v := range c.Backups {
|
||||||
|
log.Printf("Initializing backup '%s'\n", k)
|
||||||
v.Name = k
|
v.Name = k
|
||||||
|
log.Printf("Initialized backup '%s'\n", v.Name)
|
||||||
}
|
}
|
||||||
for k, v := range c.Devices {
|
for k, v := range c.Devices {
|
||||||
|
log.Printf("Initializing device '%s'\n", k)
|
||||||
v.Name = k
|
v.Name = k
|
||||||
|
log.Printf("Initialized device '%s'\n", v.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +285,7 @@ func (eh *EventHandler) process() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdata := string(bytes.Trim(data, "\x00"))
|
sdata := string(bytes.Trim(data, "\x00"))
|
||||||
log.Println(sdata)
|
//log.Println(sdata)
|
||||||
env := map[string]string{}
|
env := map[string]string{}
|
||||||
errjson := json.Unmarshal([]byte(sdata), &env)
|
errjson := json.Unmarshal([]byte(sdata), &env)
|
||||||
if errjson != nil {
|
if errjson != nil {
|
||||||
|
@ -318,13 +332,27 @@ func (b *Backup) PrepareRun() error {
|
||||||
|
|
||||||
// Run runs the backup script with appropriate rights.
|
// Run runs the backup script with appropriate rights.
|
||||||
func (b *Backup) Run() error {
|
func (b *Backup) Run() error {
|
||||||
if dev, ok := config.Devices[b.Name]; ok && dev.IsMounted() {
|
log.Printf("Running backup '%s'.", b.Name)
|
||||||
|
dev, ok := config.Devices[b.TargetDevice]
|
||||||
|
if ok {
|
||||||
|
log.Printf("Device found: %s (%s).", dev.Name, dev.UUID)
|
||||||
|
} else {
|
||||||
|
log.Printf("Device %s not found", b.TargetDevice)
|
||||||
|
}
|
||||||
|
if ok && dev.IsMounted() {
|
||||||
// setup script environment including user to use
|
// setup script environment including user to use
|
||||||
cmd := exec.Command("/usr/bin/sh", b.ScriptPath)
|
cmd := exec.Command("/usr/bin/sh", b.ScriptPath)
|
||||||
b.logger.Printf("Running backup script of '%s'", b.Name)
|
b.logger.Printf("Running backup script of '%s'", b.Name)
|
||||||
// does this work?
|
// does this work?
|
||||||
cmd.Stdout = b.logger.Writer()
|
cmd.Stdout = b.logger.Writer()
|
||||||
cmd.Stderr = b.logger.Writer()
|
cmd.Stderr = b.logger.Writer()
|
||||||
|
cmd.Env = []string{
|
||||||
|
fmt.Sprintf("BACKIVE_MOUNT=%s", config.Settings.SystemMountPoint),
|
||||||
|
fmt.Sprintf("BACKIVE_TO=%s",
|
||||||
|
path.Join(config.Settings.SystemMountPoint, dev.Name, b.TargetPath),
|
||||||
|
),
|
||||||
|
fmt.Sprintf("BACKIVE_FROM=%s", b.SourcePath),
|
||||||
|
}
|
||||||
// run script
|
// run script
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -407,14 +435,15 @@ func (r *Runs) LastRun(b Backup) (time.Time, error) {
|
||||||
|
|
||||||
func defaultCallback(envMap map[string]string) {
|
func defaultCallback(envMap map[string]string) {
|
||||||
if action, ok := envMap["ACTION"]; ok && action == "add" {
|
if action, ok := envMap["ACTION"]; ok && action == "add" {
|
||||||
var dev Device
|
var dev *Device
|
||||||
var uuid string
|
var uuid string
|
||||||
if fs_uuid, ok := envMap["ID_FS_UUID"]; !ok {
|
if fs_uuid, ok := envMap["ID_FS_UUID"]; !ok {
|
||||||
log.Fatalln("ID_FS_UUID not available ?!")
|
log.Println("ID_FS_UUID not available ?!")
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
uuid = fs_uuid
|
uuid = fs_uuid
|
||||||
}
|
}
|
||||||
log.Println("Device Added")
|
log.Println("Device connected.")
|
||||||
var uuidFound bool
|
var uuidFound bool
|
||||||
// Check the devices if the UUID is in the config
|
// Check the devices if the UUID is in the config
|
||||||
for _, device := range config.Devices {
|
for _, device := range config.Devices {
|
||||||
|
@ -424,15 +453,23 @@ func defaultCallback(envMap map[string]string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if uuidFound {
|
if uuidFound {
|
||||||
|
log.Println("Device recognized.")
|
||||||
|
log.Printf("Device: Name: %s, UUID: %s", dev.Name, dev.UUID)
|
||||||
dev.Mount()
|
dev.Mount()
|
||||||
backup, found := config.Backups.findBackupForDevice(dev)
|
log.Println("Device mounted.")
|
||||||
|
backup, found := config.Backups.findBackupForDevice(*dev)
|
||||||
|
log.Println("Searching configured backups...")
|
||||||
if found {
|
if found {
|
||||||
|
log.Println("Backup found.")
|
||||||
err := backup.CanRun()
|
err := backup.CanRun()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
log.Println("Backup is able to run (config check passed).")
|
||||||
prepErr := backup.PrepareRun()
|
prepErr := backup.PrepareRun()
|
||||||
|
log.Println("Prepared run.")
|
||||||
if prepErr != nil {
|
if prepErr != nil {
|
||||||
log.Fatalf("Error running the backup routine: %v", err)
|
log.Fatalf("Error running the backup routine: %v", err)
|
||||||
}
|
}
|
||||||
|
log.Println("Running backup.")
|
||||||
rerr := backup.Run()
|
rerr := backup.Run()
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
log.Fatalf("Error running the backup routine: %v", err)
|
log.Fatalf("Error running the backup routine: %v", err)
|
||||||
|
@ -440,6 +477,8 @@ func defaultCallback(envMap map[string]string) {
|
||||||
} else {
|
} else {
|
||||||
log.Fatalf("Error running the backup routine: %v", err)
|
log.Fatalf("Error running the backup routine: %v", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Println("No backup found, unmounting.")
|
||||||
}
|
}
|
||||||
dev.Unmount()
|
dev.Unmount()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#! /usr/bin/env bash
|
||||||
|
#
|
||||||
|
set -x
|
||||||
|
ls -la ${BACKIVE_TO}
|
||||||
|
echo "This is a test..."
|
||||||
|
echo "mount/to ${BACKIVE_TO}"
|
||||||
|
cp -Rv ${BACKIVE_FROM}/* ${BACKIVE_TO}/
|
||||||
|
ls -la ${BACKIVE_MOUNT}
|
||||||
|
ls -la ${BACKIVE_TO}
|
Loading…
Reference in New Issue