chore: add backup app

This commit is contained in:
henry.chen
2021-07-14 10:54:30 +08:00
parent a15791a792
commit c1c9e6025a
10 changed files with 307 additions and 28 deletions

View File

@@ -0,0 +1,18 @@
// Package ping provides ...
package ping
import (
"net/http"
"github.com/gin-gonic/gin"
)
// RegisterRoutes register routes
func RegisterRoutes(group gin.IRoutes) {
group.GET("/ping", handlePing)
}
// handlePing ping
func handlePing(c *gin.Context) {
c.String(http.StatusOK, "it's ok")
}

View File

@@ -0,0 +1,15 @@
// Package swag provides ...
package swag
import (
_ "github.com/eiblog/eiblog/pkg/core/backup/docs" // docs
"github.com/gin-gonic/gin"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
)
// RegisterRoutes register routes
func RegisterRoutes(group gin.IRoutes) {
group.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}

View File

@@ -0,0 +1,77 @@
// Package qiniu provides ...
package qiniu
import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"time"
"github.com/eiblog/eiblog/pkg/config"
"github.com/eiblog/eiblog/pkg/internal"
)
// Storage qiniu storage
type Storage struct{}
// BackupData implements timer.Storage
func (s Storage) BackupData(now time.Time) error {
switch config.Conf.Database.Source {
case "mongodb":
return backupFromMongoDB(now)
default:
return errors.New("unsupported database source backup to qiniu")
}
}
func backupFromMongoDB(now time.Time) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*20)
defer cancel()
// dump
arg := fmt.Sprintf("mongodump -h %s -d eiblog -o /tmp",
config.Conf.Database.Source)
cmd := exec.CommandContext(ctx, "sh", "-c", arg)
err := cmd.Run()
if err != nil {
return err
}
// tar
name := fmt.Sprintf("eiblog-%s.tar.gz", now.Format("2006-01-02"))
arg = fmt.Sprintf("tar czf %s /tmp/eiblog", name)
cmd = exec.CommandContext(ctx, "sh", "-c", arg)
err = cmd.Run()
if err != nil {
return err
}
// upload file
f, err := os.Open("/tmp/eiblog/" + name)
if err != nil {
return err
}
s, err := f.Stat()
if err != nil {
return err
}
uploadParams := internal.UploadParams{
Name: name,
Size: s.Size(),
Data: f,
Conf: config.Conf.BackupApp.Qiniu,
}
_, err = internal.QiniuUpload(uploadParams)
if err != nil {
return err
}
// after days delete
deleteParams := internal.DeleteParams{
Name: name,
Conf: config.Conf.BackupApp.Qiniu,
}
return internal.QiniuDelete(deleteParams)
}

View File

@@ -0,0 +1,68 @@
// Package timer provides ...
package timer
import (
"errors"
"strconv"
"time"
"github.com/eiblog/eiblog/pkg/config"
"github.com/eiblog/eiblog/pkg/core/backup/timer/qiniu"
"github.com/sirupsen/logrus"
)
// Start to backup with ticker
func Start() error {
var storage Storage
// backup instance
switch config.Conf.BackupApp.BackupTo {
case "qiniu":
storage = qiniu.Storage{}
default:
return errors.New("timer: unknown backup to driver: " +
config.Conf.BackupApp.BackupTo)
}
// parse duration
interval, err := ParseDuration(config.Conf.BackupApp.Interval)
if err != nil {
return err
}
t := time.NewTicker(interval)
for now := range t.C {
err = storage.BackupData(now)
if err != nil {
logrus.Error("timer: Start.BackupData: ", now, err)
}
}
return nil
}
// ParseDuration parse string to duration
func ParseDuration(d string) (time.Duration, error) {
if len(d) == 0 {
return 0, errors.New("timer: incorrect duration input")
}
length := len(d)
switch d[length-1] {
case 's', 'm', 'h':
return time.ParseDuration(d)
case 'd':
di, err := strconv.Atoi(d[:length-1])
if err != nil {
return 0, err
}
return time.Duration(di) * time.Hour * 24, nil
}
return 0, errors.New("timer: unsupported duration:" + d)
}
// Storage backup backend
type Storage interface {
BackupData(now time.Time) error
}

View File

@@ -467,7 +467,15 @@ func handleAPIQiniuUpload(c *gin.Context) {
return
}
filename := strings.ToLower(header.Filename)
url, err := internal.QiniuUpload(filename, s.Size(), file)
params := internal.UploadParams{
Name: filename,
Size: s.Size(),
Data: file,
Conf: config.Conf.EiBlogApp.Qiniu,
}
url, err := internal.QiniuUpload(params)
if err != nil {
logrus.Error("handleAPIQiniuUpload.QiniuUpload: ", err)
c.String(http.StatusBadRequest, err.Error())
@@ -491,7 +499,13 @@ func handleAPIQiniuDelete(c *gin.Context) {
logrus.Error("handleAPIQiniuDelete.PostForm: 参数错误")
return
}
err := internal.QiniuDelete(name)
params := internal.DeleteParams{
Name: name,
Conf: config.Conf.EiBlogApp.Qiniu,
}
err := internal.QiniuDelete(params)
if err != nil {
logrus.Error("handleAPIQiniuDelete.QiniuDelete: ", err)
}