zhangzengfei
2023-09-04 e8e536d1cb52d2126c8c7ce2ba1c7a76f7208678
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package service
 
import (
    "context"
    "fmt"
    "os"
    "os/exec"
    "path/filepath"
    "time"
    "vamicro/extend/util"
    "vamicro/version-control/models"
 
    "basic.com/valib/logger.git"
)
 
/*
    系统备份、备份还原、按设置周期性备份
    备份的数据主要包括sqlite数据、config以及exe(按需要)
    按钮可以触发立即备份
    参数:
        1.备份开关
        2.备份目录文件夹(/opt/vasystem/backup_auto)
        3.备份周期(每7天备份一次,备份时间是夜间0点)
        4.备份数据保存时间
*/
func BakSchedule(ctx context.Context) {
    // tk := time.NewTicker(time.Minute)
    tk := time.Tick(24 * time.Hour)
    for {
        select {
        case <-ctx.Done():
            return
        case <-tk:
            removeCheck()
            backupCheck()
        }
    }
}
 
//自动清理大于保存时间的备份数据
func removeCheck() {
    var ab models.AutoBackupConf
    i, e := ab.Select()
    if e != nil || i <= 0 {
        return
    }
    if ab.Dir == "" {
        logger.Error("备份目录未配置")
        return
    }
 
    if ab.Period < 1 || ab.SaveDays < 1 {
        logger.Error("周期和保存天数不合法")
        return
    }
 
    t := time.Now()
    err := filepath.Walk(ab.Dir, func(src string, f os.FileInfo, err error) error {
        if f.IsDir() {
            nt, e := time.ParseInLocation("2006-01-02-15-04-05", f.Name(), time.Local)
            if e != nil {
                return e
            }
 
            if int(t.Sub(nt).Hours()) > ab.SaveDays*24 {
                os.RemoveAll(ab.Dir + "/" + f.Name())
            }
        }
        return nil
    })
    if err != nil {
        logger.Error(err)
    }
}
 
func backupCheck() {
    //检查当前时间
    t := time.Now()
    if t.Hour() > 1 {
        return
    }
    var ab models.AutoBackupConf
    i, e := ab.Select()
    if e != nil || i <= 0 {
        return
    }
    if !ab.Enable {
        logger.Info("自动备份开关未打开")
        return
    }
    if ab.Dir == "" {
        logger.Error("备份目录未配置")
        return
    }
    if ab.Period < 1 || ab.SaveDays < 1 {
        logger.Error("周期和保存天数不合法")
        return
    }
 
    if !util.DirExists(ab.Dir) {
        os.Mkdir(ab.Dir, os.ModePerm)
    }
    lbd, err := exec.Command(fmt.Sprintf("ls %s | sort -r|head -1", ab.Dir)).Output()
    if err != nil {
        logger.Error("get last auto backup day err:", err)
        return
    }
 
    sbd := string(lbd)
    if sbd == "" { //未备份过,则执行备份
        DoAutoBackup(&ab)
    } else {
        tl, _ := time.ParseInLocation("2006-01-02-15-04-05", sbd, time.Local)
        if int(t.Sub(tl).Hours()) >= ab.Period*24 {
            DoAutoBackup(&ab)
        }
    }
}
 
func DoAutoBackup(ab *models.AutoBackupConf) error {
    backDirName := time.Now().Format("2006-01-02-15-04-05")
    dir := ab.Dir + "/" + backDirName
    if !util.DirExists(dir) {
        if err := os.Mkdir(dir, os.ModePerm); err != nil {
            return err
        }
    }
    //备份数据库和配置文件
    _, err := util.CopyDirByCmd("/opt/vasystem/config", dir)
    if err != nil {
        return err
    }
    return nil
}
func DoBackupRecover(dir string) error {
    //防止还原失败,做一个还原点备份
    //先停止所有进程
    //还原
    //重启系统
    recoverBakDir := util.GetVamicroPath() + "/recover_backup"
    if util.DirExists(recoverBakDir) {
        os.RemoveAll(recoverBakDir)
    }
    os.Mkdir(recoverBakDir, os.ModePerm)
    util.CopyDirByCmd("/opt/vasystem/config", recoverBakDir)
 
    _, err := exec.Command("/bin/sh", "-c", fmt.Sprintf(`
        /opt/vasystem/procs/killAllProcs.sh && 
        cp -rf %s/* /opt/vasystem/config/ && 
        /opt/vasystem/daemon.sh`, dir)).Output()
    return err
}