Merge pull request #117 from jkaninda/refactor
chore: add backup prune, replace period flag by BACKUP_RETENTION_DAYS…
This commit is contained in:
@@ -27,6 +27,8 @@ TZ=Europe/Paris
|
||||
|
||||
### Backup Cron Expression
|
||||
#BACKUP_CRON_EXPRESSION=@midnight
|
||||
##Delete old backup created more than specified days ago
|
||||
#BACKUP_RETENTION_DAYS=7
|
||||
|
||||
####SSH Storage
|
||||
#SSH_HOST_NAME=
|
||||
|
||||
@@ -60,7 +60,7 @@ services:
|
||||
# for a list of available releases.
|
||||
image: jkaninda/pg-bkup
|
||||
container_name: pg-bkup
|
||||
command: backup --storage s3 -d my-database --mode scheduled --period "0 1 * * *"
|
||||
command: backup --storage s3 -d my-database"
|
||||
environment:
|
||||
- DB_PORT=5432
|
||||
- DB_HOST=postgres
|
||||
@@ -74,6 +74,8 @@ services:
|
||||
- AWS_ACCESS_KEY=xxxx
|
||||
- AWS_SECRET_KEY=xxxxx
|
||||
# - BACKUP_CRON_EXPRESSION=0 1 * * * # Optional
|
||||
#Delete old backup created more than specified days ago
|
||||
#- BACKUP_RETENTION_DAYS=7
|
||||
## In case you are using S3 alternative such as Minio and your Minio instance is not secured, you change it to true
|
||||
- AWS_DISABLE_SSL="false"
|
||||
# pg-bkup container must be connected to the same network with your database
|
||||
|
||||
@@ -78,6 +78,8 @@ services:
|
||||
- SSH_USER=user
|
||||
- REMOTE_PATH=/home/jkaninda/backups
|
||||
- SSH_IDENTIFY_FILE=/tmp/id_ed25519
|
||||
#Delete old backup created more than specified days ago
|
||||
#- BACKUP_RETENTION_DAYS=7
|
||||
## We advise you to use a private jey instead of password
|
||||
#- SSH_PASSWORD=password
|
||||
# pg-bkup container must be connected to the same network with your database
|
||||
|
||||
@@ -77,6 +77,8 @@ services:
|
||||
- DB_USERNAME=username
|
||||
- DB_PASSWORD=password
|
||||
- BACKUP_CRON_EXPRESSION=0 1 * * *
|
||||
#Delete old backup created more than specified days ago
|
||||
#- BACKUP_RETENTION_DAYS=7
|
||||
# pg-bkup container must be connected to the same network with your database
|
||||
networks:
|
||||
- web
|
||||
|
||||
@@ -26,8 +26,6 @@ Backup, restore and migrate targets, schedule and retention are configured using
|
||||
| --dbname | -d | Database name |
|
||||
| --port | -p | Database port (default: 5432) |
|
||||
| --disable-compression | | Disable database backup compression |
|
||||
| --prune | | Delete old backup, default disabled |
|
||||
| --keep-last | | Delete old backup created more than specified days ago, default 7 days |
|
||||
| --cron-expression | | Backup cron expression, eg: (* * * * *) or @daily |
|
||||
| --help | -h | Print this help message and exit |
|
||||
| --version | -V | Print version information and exit |
|
||||
@@ -52,6 +50,7 @@ Backup, restore and migrate targets, schedule and retention are configured using
|
||||
| GPG_PASSPHRASE | Optional, required to encrypt and restore backup | GPG passphrase |
|
||||
| GPG_PUBLIC_KEY | Optional, required to encrypt backup | GPG public key, used to encrypt backup (/config/public_key.asc) |
|
||||
| BACKUP_CRON_EXPRESSION | Optional if it was provided from the `--cron-expression` flag | Backup cron expression for docker in scheduled mode |
|
||||
| BACKUP_RETENTION_DAYS | Optional | Delete old backup created more than specified days ago |
|
||||
| SSH_HOST | Optional, required for SSH storage | ssh remote hostname or ip |
|
||||
| SSH_USER | Optional, required for SSH storage | ssh remote user |
|
||||
| SSH_PASSWORD | Optional, required for SSH storage | ssh remote user's password |
|
||||
|
||||
@@ -46,6 +46,7 @@ func StartBackup(cmd *cobra.Command) {
|
||||
func scheduledMode(db *dbConfig, config *BackupConfig) {
|
||||
utils.Info("Running in Scheduled mode")
|
||||
utils.Info("Backup cron expression: %s", config.cronExpression)
|
||||
utils.Info("The next scheduled time is: %v", utils.CronNextTime(config.cronExpression).Format(timeFormat))
|
||||
utils.Info("Storage type %s ", config.storage)
|
||||
|
||||
//Test backup
|
||||
@@ -58,6 +59,8 @@ func scheduledMode(db *dbConfig, config *BackupConfig) {
|
||||
|
||||
_, err := c.AddFunc(config.cronExpression, func() {
|
||||
BackupTask(db, config)
|
||||
utils.Info("Next backup time is: %v", utils.CronNextTime(config.cronExpression).Format(timeFormat))
|
||||
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
@@ -80,6 +83,8 @@ func multiBackupTask(databases []Database, bkConfig *BackupConfig) {
|
||||
BackupTask(getDatabase(db), bkConfig)
|
||||
}
|
||||
}
|
||||
|
||||
// BackupTask backups database
|
||||
func BackupTask(db *dbConfig, config *BackupConfig) {
|
||||
utils.Info("Starting backup task...")
|
||||
//Generate file name
|
||||
@@ -121,6 +126,7 @@ func startMultiBackup(bkConfig *BackupConfig, configFile string) {
|
||||
if utils.IsValidCronExpression(bkConfig.cronExpression) {
|
||||
utils.Info("Running MultiBackup in Scheduled mode")
|
||||
utils.Info("Backup cron expression: %s", bkConfig.cronExpression)
|
||||
utils.Info("The next scheduled time is: %v", utils.CronNextTime(bkConfig.cronExpression).Format(timeFormat))
|
||||
utils.Info("Storage type %s ", bkConfig.storage)
|
||||
|
||||
//Test backup
|
||||
@@ -132,8 +138,9 @@ func startMultiBackup(bkConfig *BackupConfig, configFile string) {
|
||||
c := cron.New()
|
||||
|
||||
_, err := c.AddFunc(bkConfig.cronExpression, func() {
|
||||
// Create a channel
|
||||
multiBackupTask(conf.Databases, bkConfig)
|
||||
utils.Info("Next backup time is: %v", utils.CronNextTime(bkConfig.cronExpression).Format(timeFormat))
|
||||
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
@@ -172,7 +172,6 @@ func initAWSConfig() *AWSConfig {
|
||||
func initBackupConfig(cmd *cobra.Command) *BackupConfig {
|
||||
utils.SetEnv("STORAGE_PATH", storagePath)
|
||||
utils.GetEnv(cmd, "cron-expression", "BACKUP_CRON_EXPRESSION")
|
||||
utils.GetEnv(cmd, "period", "BACKUP_CRON_EXPRESSION")
|
||||
utils.GetEnv(cmd, "path", "REMOTE_PATH")
|
||||
//Get flag value and set env
|
||||
remotePath := utils.GetEnvVariable("REMOTE_PATH", "SSH_REMOTE_PATH")
|
||||
|
||||
@@ -10,6 +10,7 @@ const tmpPath = "/tmp/backup"
|
||||
const gpgHome = "/config/gnupg"
|
||||
const algorithm = "aes256"
|
||||
const gpgExtension = "gpg"
|
||||
const timeFormat = "2006-01-02 at 15:04:05"
|
||||
|
||||
var (
|
||||
storage = "local"
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/go-mail/mail"
|
||||
"github.com/robfig/cron/v3"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -177,7 +176,3 @@ func getTgUrl() string {
|
||||
return fmt.Sprintf("https://api.telegram.org/bot%s", os.Getenv("TG_TOKEN"))
|
||||
|
||||
}
|
||||
func IsValidCronExpression(cronExpr string) bool {
|
||||
_, err := cron.ParseStandard(cronExpr)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
@@ -8,11 +8,13 @@ package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/robfig/cron/v3"
|
||||
"github.com/spf13/cobra"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// FileExists checks if the file does exist
|
||||
@@ -188,3 +190,26 @@ func EnvWithDefault(envName string, defaultValue string) string {
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// IsValidCronExpression verify cronExpression and returns boolean
|
||||
func IsValidCronExpression(cronExpr string) bool {
|
||||
// Parse the cron expression
|
||||
_, err := cron.ParseStandard(cronExpr)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// CronNextTime returns cronExpression next time
|
||||
func CronNextTime(cronExpr string) time.Time {
|
||||
// Parse the cron expression
|
||||
schedule, err := cron.ParseStandard(cronExpr)
|
||||
if err != nil {
|
||||
Error("Error parsing cron expression:", err)
|
||||
return time.Time{}
|
||||
}
|
||||
// Get the current time
|
||||
now := time.Now()
|
||||
// Get the next scheduled time
|
||||
next := schedule.Next(now)
|
||||
//Info("The next scheduled time is: %v\n", next)
|
||||
return next
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user