feat: add backup encryption using public key and decryption using private key
This commit is contained in:
@@ -166,9 +166,10 @@ func localBackup(db *dbConfig, config *BackupConfig) {
|
||||
BackupDatabase(db, config.backupFileName, disableCompression)
|
||||
finalFileName := config.backupFileName
|
||||
if config.encryption {
|
||||
encryptBackup(config.backupFileName, config.passphrase)
|
||||
encryptBackup(config)
|
||||
finalFileName = fmt.Sprintf("%s.%s", config.backupFileName, gpgExtension)
|
||||
}
|
||||
|
||||
utils.Info("Backup name is %s", finalFileName)
|
||||
moveToBackup(finalFileName, storagePath)
|
||||
//Send notification
|
||||
@@ -189,7 +190,7 @@ func s3Backup(db *dbConfig, config *BackupConfig) {
|
||||
BackupDatabase(db, config.backupFileName, disableCompression)
|
||||
finalFileName := config.backupFileName
|
||||
if config.encryption {
|
||||
encryptBackup(config.backupFileName, config.passphrase)
|
||||
encryptBackup(config)
|
||||
finalFileName = fmt.Sprintf("%s.%s", config.backupFileName, "gpg")
|
||||
}
|
||||
utils.Info("Uploading backup archive to remote storage S3 ... ")
|
||||
@@ -226,7 +227,7 @@ func sshBackup(db *dbConfig, config *BackupConfig) {
|
||||
BackupDatabase(db, config.backupFileName, disableCompression)
|
||||
finalFileName := config.backupFileName
|
||||
if config.encryption {
|
||||
encryptBackup(config.backupFileName, config.passphrase)
|
||||
encryptBackup(config)
|
||||
finalFileName = fmt.Sprintf("%s.%s", config.backupFileName, "gpg")
|
||||
}
|
||||
utils.Info("Uploading backup archive to remote storage ... ")
|
||||
@@ -261,7 +262,7 @@ func ftpBackup(db *dbConfig, config *BackupConfig) {
|
||||
BackupDatabase(db, config.backupFileName, disableCompression)
|
||||
finalFileName := config.backupFileName
|
||||
if config.encryption {
|
||||
encryptBackup(config.backupFileName, config.passphrase)
|
||||
encryptBackup(config)
|
||||
finalFileName = fmt.Sprintf("%s.%s", config.backupFileName, "gpg")
|
||||
}
|
||||
utils.Info("Uploading backup archive to the remote FTP server ... ")
|
||||
@@ -291,10 +292,18 @@ func ftpBackup(db *dbConfig, config *BackupConfig) {
|
||||
deleteTemp()
|
||||
}
|
||||
|
||||
func encryptBackup(backupFileName, gpqPassphrase string) {
|
||||
err := Encrypt(filepath.Join(tmpPath, backupFileName), gpqPassphrase)
|
||||
if err != nil {
|
||||
utils.Fatal("Error during encrypting backup %v", err)
|
||||
func encryptBackup(config *BackupConfig) {
|
||||
if config.usingKey {
|
||||
err := encrypt(filepath.Join(tmpPath, config.backupFileName), config.publicKey)
|
||||
if err != nil {
|
||||
utils.Fatal("Error during encrypting backup %v", err)
|
||||
}
|
||||
} else if config.passphrase != "" {
|
||||
err := Encrypt(filepath.Join(tmpPath, config.backupFileName), config.passphrase)
|
||||
if err != nil {
|
||||
utils.Fatal("Error during encrypting backup %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,9 +40,11 @@ type BackupConfig struct {
|
||||
backupRetention int
|
||||
disableCompression bool
|
||||
prune bool
|
||||
encryption bool
|
||||
remotePath string
|
||||
encryption bool
|
||||
usingKey bool
|
||||
passphrase string
|
||||
publicKey string
|
||||
storage string
|
||||
cronExpression string
|
||||
}
|
||||
@@ -163,10 +165,14 @@ func initBackupConfig(cmd *cobra.Command) *BackupConfig {
|
||||
_ = utils.GetEnv(cmd, "path", "AWS_S3_PATH")
|
||||
cronExpression := os.Getenv("BACKUP_CRON_EXPRESSION")
|
||||
|
||||
if passphrase != "" {
|
||||
publicKeyFile, err := checkPubKeyFile(os.Getenv("GPG_PUBLIC_KEY"))
|
||||
if err == nil {
|
||||
encryption = true
|
||||
usingKey = true
|
||||
} else if passphrase != "" {
|
||||
encryption = true
|
||||
usingKey = false
|
||||
}
|
||||
|
||||
//Initialize backup configs
|
||||
config := BackupConfig{}
|
||||
config.backupRetention = backupRetention
|
||||
@@ -176,17 +182,21 @@ func initBackupConfig(cmd *cobra.Command) *BackupConfig {
|
||||
config.encryption = encryption
|
||||
config.remotePath = remotePath
|
||||
config.passphrase = passphrase
|
||||
config.publicKey = publicKeyFile
|
||||
config.usingKey = usingKey
|
||||
config.cronExpression = cronExpression
|
||||
return &config
|
||||
}
|
||||
|
||||
type RestoreConfig struct {
|
||||
s3Path string
|
||||
remotePath string
|
||||
storage string
|
||||
file string
|
||||
bucket string
|
||||
gpqPassphrase string
|
||||
s3Path string
|
||||
remotePath string
|
||||
storage string
|
||||
file string
|
||||
bucket string
|
||||
usingKey bool
|
||||
passphrase string
|
||||
privateKey string
|
||||
}
|
||||
|
||||
func initRestoreConfig(cmd *cobra.Command) *RestoreConfig {
|
||||
@@ -199,7 +209,14 @@ func initRestoreConfig(cmd *cobra.Command) *RestoreConfig {
|
||||
storage = utils.GetEnv(cmd, "storage", "STORAGE")
|
||||
file = utils.GetEnv(cmd, "file", "FILE_NAME")
|
||||
bucket := utils.GetEnvVariable("AWS_S3_BUCKET_NAME", "BUCKET_NAME")
|
||||
gpqPassphrase := os.Getenv("GPG_PASSPHRASE")
|
||||
passphrase := os.Getenv("GPG_PASSPHRASE")
|
||||
privateKeyFile, err := checkPrKeyFile(os.Getenv("GPG_PRIVATE_KEY"))
|
||||
if err == nil {
|
||||
usingKey = true
|
||||
} else if passphrase != "" {
|
||||
usingKey = false
|
||||
}
|
||||
|
||||
//Initialize restore configs
|
||||
rConfig := RestoreConfig{}
|
||||
rConfig.s3Path = s3Path
|
||||
@@ -208,7 +225,9 @@ func initRestoreConfig(cmd *cobra.Command) *RestoreConfig {
|
||||
rConfig.bucket = bucket
|
||||
rConfig.file = file
|
||||
rConfig.storage = storage
|
||||
rConfig.gpqPassphrase = gpqPassphrase
|
||||
rConfig.passphrase = passphrase
|
||||
rConfig.usingKey = usingKey
|
||||
rConfig.privateKey = privateKeyFile
|
||||
return &rConfig
|
||||
}
|
||||
func initTargetDbConfig() *targetDbConfig {
|
||||
|
||||
118
pkg/encrypt.go
118
pkg/encrypt.go
@@ -7,14 +7,19 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
"github.com/jkaninda/pg-bkup/utils"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Decrypt decrypts backup file using a passphrase
|
||||
func Decrypt(inputFile string, passphrase string) error {
|
||||
utils.Info("Decrypting backup file: %s...", inputFile)
|
||||
utils.Info("Decrypting backup using passphrase...")
|
||||
|
||||
//Create gpg home dir
|
||||
err := utils.MakeDirAll(gpgHome)
|
||||
if err != nil {
|
||||
@@ -29,13 +34,15 @@ func Decrypt(inputFile string, passphrase string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
utils.Info("Decrypting backup using passphrase...done")
|
||||
utils.Info("Backup file decrypted successful!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encrypt encrypts backup using a passphrase
|
||||
func Encrypt(inputFile string, passphrase string) error {
|
||||
utils.Info("Encrypting backup...")
|
||||
utils.Info("Encrypting backup using passphrase...")
|
||||
|
||||
//Create gpg home dir
|
||||
err := utils.MakeDirAll(gpgHome)
|
||||
if err != nil {
|
||||
@@ -50,11 +57,114 @@ func Encrypt(inputFile string, passphrase string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
utils.Info("Encrypting backup using passphrase...done")
|
||||
utils.Info("Backup file encrypted successful!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// encrypt encrypts backup using a public key
|
||||
func encrypt(inputFile string, publicKey string) error {
|
||||
utils.Info("Encrypting backup using public key...")
|
||||
// Read the public key
|
||||
pubKeyBytes, err := os.ReadFile(publicKey)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error reading public key: %s", err))
|
||||
}
|
||||
// Create a new keyring with the public key
|
||||
publicKeyObj, err := crypto.NewKeyFromArmored(string(pubKeyBytes))
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error parsing public key: %s", err))
|
||||
}
|
||||
|
||||
keyRing, err := crypto.NewKeyRing(publicKeyObj)
|
||||
if err != nil {
|
||||
|
||||
return errors.New(fmt.Sprintf("Error creating key ring: %v", err))
|
||||
}
|
||||
|
||||
// Read the file to encrypt
|
||||
fileContent, err := os.ReadFile(inputFile)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error reading file: %v", err))
|
||||
}
|
||||
|
||||
// Encrypt the file
|
||||
message := crypto.NewPlainMessage(fileContent)
|
||||
encMessage, err := keyRing.Encrypt(message, nil)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error encrypting file: %v", err))
|
||||
}
|
||||
|
||||
// Save the encrypted file
|
||||
err = os.WriteFile(fmt.Sprintf("%s.%s", inputFile, gpgExtension), encMessage.GetBinary(), 0644)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error saving encrypted file: %v", err))
|
||||
}
|
||||
utils.Info("Encrypting backup using public key...done")
|
||||
utils.Info("Backup file encrypted successful!")
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// decrypt decrypts backup file using a private key and passphrase.
|
||||
// privateKey GPG private key
|
||||
// passphrase GPG passphrase
|
||||
func decrypt(inputFile, privateKey, passphrase string) error {
|
||||
utils.Info("Encrypting backup using private key...")
|
||||
|
||||
// Read the private key
|
||||
priKeyBytes, err := os.ReadFile(privateKey)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error reading private key: %s", err))
|
||||
}
|
||||
|
||||
// Read the password for the private key (if it’s password-protected)
|
||||
password := []byte(passphrase)
|
||||
|
||||
// Create a key object from the armored private key
|
||||
privateKeyObj, err := crypto.NewKeyFromArmored(string(priKeyBytes))
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error parsing private key: %s", err))
|
||||
}
|
||||
|
||||
// Unlock the private key with the password
|
||||
if passphrase != "" {
|
||||
// Unlock the private key with the password
|
||||
_, err = privateKeyObj.Unlock(password)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error unlocking private key: %s", err))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create a new keyring with the private key
|
||||
keyRing, err := crypto.NewKeyRing(privateKeyObj)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error creating key ring: %v", err))
|
||||
}
|
||||
|
||||
// Read the encrypted file
|
||||
encFileContent, err := os.ReadFile(inputFile)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error reading encrypted file: %s", err))
|
||||
}
|
||||
|
||||
// Decrypt the file
|
||||
encryptedMessage := crypto.NewPGPMessage(encFileContent)
|
||||
message, err := keyRing.Decrypt(encryptedMessage, nil, 0)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error decrypting file: %s", err))
|
||||
}
|
||||
|
||||
// Save the decrypted file
|
||||
err = os.WriteFile(RemoveLastExtension(inputFile), message.GetBinary(), 0644)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error saving decrypted file: %s", err))
|
||||
}
|
||||
utils.Info("Encrypting backup using public key...done")
|
||||
fmt.Println("File successfully decrypted!")
|
||||
return nil
|
||||
}
|
||||
func RemoveLastExtension(filename string) string {
|
||||
if idx := strings.LastIndex(filename, "."); idx != -1 {
|
||||
return filename[:idx]
|
||||
|
||||
@@ -8,13 +8,16 @@ package pkg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/jkaninda/pg-bkup/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// copyToTmp copy file to temporary directory
|
||||
func copyToTmp(sourcePath string, backupFileName string) {
|
||||
//Copy backup from storage to /tmp
|
||||
err := utils.CopyFile(filepath.Join(sourcePath, backupFileName), filepath.Join(tmpPath, backupFileName))
|
||||
@@ -137,3 +140,64 @@ func testDatabaseConnection(db *dbConfig) {
|
||||
utils.Info("Successfully connected to %s database", db.dbName)
|
||||
|
||||
}
|
||||
func readConf(filename string) (*Config, error) {
|
||||
configFile := filepath.Join("", filename)
|
||||
if utils.FileExists(configFile) {
|
||||
buf, err := os.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Config{}
|
||||
err = yaml.Unmarshal(buf, c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in file %q: %w", filename, err)
|
||||
}
|
||||
|
||||
return c, err
|
||||
}
|
||||
return nil, fmt.Errorf("config file %q not found", filename)
|
||||
}
|
||||
func checkPubKeyFile(pubKey string) (string, error) {
|
||||
utils.Info("Checking file %s ...", pubKey)
|
||||
// Define possible key file names
|
||||
keyFiles := []string{filepath.Join(gpgHome, "public_key.asc"), filepath.Join(gpgHome, "public_key.gpg"), pubKey}
|
||||
|
||||
// Loop through key file names and check if they exist
|
||||
for _, keyFile := range keyFiles {
|
||||
if _, err := os.Stat(keyFile); err == nil {
|
||||
// File exists
|
||||
return keyFile, nil
|
||||
} else if os.IsNotExist(err) {
|
||||
// File does not exist, continue to the next one
|
||||
continue
|
||||
} else {
|
||||
// An unexpected error occurred
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Return an error if neither file exists
|
||||
return "", fmt.Errorf("no public key file found")
|
||||
}
|
||||
func checkPrKeyFile(prKey string) (string, error) {
|
||||
// Define possible key file names
|
||||
keyFiles := []string{filepath.Join(gpgHome, "private_key.asc"), filepath.Join(gpgHome, "private_key.gpg"), prKey}
|
||||
|
||||
// Loop through key file names and check if they exist
|
||||
for _, keyFile := range keyFiles {
|
||||
if _, err := os.Stat(keyFile); err == nil {
|
||||
// File exists
|
||||
return keyFile, nil
|
||||
} else if os.IsNotExist(err) {
|
||||
// File does not exist, continue to the next one
|
||||
continue
|
||||
} else {
|
||||
// An unexpected error occurred
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Return an error if neither file exists
|
||||
return "", fmt.Errorf("no public key file found")
|
||||
}
|
||||
|
||||
@@ -30,11 +30,13 @@ func StartMigration(cmd *cobra.Command) {
|
||||
|
||||
//Generate file name
|
||||
backupFileName := fmt.Sprintf("%s_%s.sql", dbConf.dbName, time.Now().Format("20060102_150405"))
|
||||
conf := &RestoreConfig{}
|
||||
conf.file = backupFileName
|
||||
//Backup source Database
|
||||
BackupDatabase(dbConf, backupFileName, true)
|
||||
//Restore source database into target database
|
||||
utils.Info("Restoring [%s] database into [%s] database...", dbConf.dbName, targetDbConf.targetDbName)
|
||||
RestoreDatabase(&newDbConfig, backupFileName)
|
||||
RestoreDatabase(&newDbConfig, conf)
|
||||
utils.Info("[%s] database has been restored into [%s] database", dbConf.dbName, targetDbConf.targetDbName)
|
||||
utils.Info("Database migration completed.")
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jkaninda/pg-bkup/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
@@ -24,75 +23,76 @@ func StartRestore(cmd *cobra.Command) {
|
||||
case "local":
|
||||
utils.Info("Restore database from local")
|
||||
copyToTmp(storagePath, restoreConf.file)
|
||||
RestoreDatabase(dbConf, restoreConf.file)
|
||||
RestoreDatabase(dbConf, restoreConf)
|
||||
case "s3", "S3":
|
||||
restoreFromS3(dbConf, restoreConf.file, restoreConf.bucket, restoreConf.s3Path)
|
||||
restoreFromS3(dbConf, restoreConf)
|
||||
case "ssh", "SSH", "remote":
|
||||
restoreFromRemote(dbConf, restoreConf.file, restoreConf.remotePath)
|
||||
restoreFromRemote(dbConf, restoreConf)
|
||||
case "ftp", "FTP":
|
||||
restoreFromFTP(dbConf, restoreConf.file, restoreConf.remotePath)
|
||||
restoreFromFTP(dbConf, restoreConf)
|
||||
default:
|
||||
utils.Info("Restore database from local")
|
||||
copyToTmp(storagePath, restoreConf.file)
|
||||
RestoreDatabase(dbConf, restoreConf.file)
|
||||
RestoreDatabase(dbConf, restoreConf)
|
||||
}
|
||||
}
|
||||
|
||||
func restoreFromS3(db *dbConfig, file, bucket, s3Path string) {
|
||||
func restoreFromS3(db *dbConfig, conf *RestoreConfig) {
|
||||
utils.Info("Restore database from s3")
|
||||
err := DownloadFile(tmpPath, file, bucket, s3Path)
|
||||
err := DownloadFile(tmpPath, conf.file, conf.bucket, conf.s3Path)
|
||||
if err != nil {
|
||||
utils.Fatal("Error download file from s3 %s %v ", file, err)
|
||||
utils.Fatal("Error download file from s3 %s %v ", conf.file, err)
|
||||
}
|
||||
RestoreDatabase(db, file)
|
||||
RestoreDatabase(db, conf)
|
||||
}
|
||||
func restoreFromRemote(db *dbConfig, file, remotePath string) {
|
||||
func restoreFromRemote(db *dbConfig, conf *RestoreConfig) {
|
||||
utils.Info("Restore database from remote server")
|
||||
err := CopyFromRemote(file, remotePath)
|
||||
err := CopyFromRemote(conf.file, conf.remotePath)
|
||||
if err != nil {
|
||||
utils.Fatal("Error download file from remote server: %s %v", filepath.Join(remotePath, file), err)
|
||||
utils.Fatal("Error download file from remote server: %s %v", filepath.Join(conf.remotePath, conf.file), err)
|
||||
}
|
||||
RestoreDatabase(db, file)
|
||||
RestoreDatabase(db, conf)
|
||||
}
|
||||
func restoreFromFTP(db *dbConfig, file, remotePath string) {
|
||||
func restoreFromFTP(db *dbConfig, conf *RestoreConfig) {
|
||||
utils.Info("Restore database from FTP server")
|
||||
err := CopyFromFTP(file, remotePath)
|
||||
err := CopyFromFTP(conf.file, conf.remotePath)
|
||||
if err != nil {
|
||||
utils.Fatal("Error download file from FTP server: %s %v", filepath.Join(remotePath, file), err)
|
||||
utils.Fatal("Error download file from FTP server: %s %v", filepath.Join(conf.remotePath, conf.file), err)
|
||||
}
|
||||
RestoreDatabase(db, file)
|
||||
RestoreDatabase(db, conf)
|
||||
}
|
||||
|
||||
// RestoreDatabase restore database
|
||||
func RestoreDatabase(db *dbConfig, file string) {
|
||||
gpgPassphrase := os.Getenv("GPG_PASSPHRASE")
|
||||
if file == "" {
|
||||
func RestoreDatabase(db *dbConfig, conf *RestoreConfig) {
|
||||
if conf.file == "" {
|
||||
utils.Fatal("Error, file required")
|
||||
}
|
||||
extension := filepath.Ext(fmt.Sprintf("%s/%s", tmpPath, file))
|
||||
extension := filepath.Ext(filepath.Join(tmpPath, conf.file))
|
||||
if extension == ".gpg" {
|
||||
if gpgPassphrase == "" {
|
||||
utils.Fatal("Error: GPG passphrase is required, your file seems to be a GPG file.\nYou need to provide GPG keys. GPG_PASSPHRASE environment variable is required.")
|
||||
|
||||
} else {
|
||||
//Decrypt file
|
||||
err := Decrypt(filepath.Join(tmpPath, file), gpgPassphrase)
|
||||
if conf.usingKey {
|
||||
err := decrypt(filepath.Join(tmpPath, conf.file), conf.privateKey, conf.passphrase)
|
||||
if err != nil {
|
||||
utils.Fatal("Error decrypting file %s %v", file, err)
|
||||
utils.Fatal("Error during decrypting backup %v", err)
|
||||
}
|
||||
} else {
|
||||
if conf.passphrase == "" {
|
||||
utils.Error("Error, passphrase or private key required")
|
||||
utils.Fatal("Your file seems to be a GPG file.\nYou need to provide GPG keys. GPG_PASSPHRASE or GPG_PRIVATE_KEY environment variable is required.")
|
||||
} else {
|
||||
//Decrypt file
|
||||
err := Decrypt(filepath.Join(tmpPath, conf.file), conf.passphrase)
|
||||
if err != nil {
|
||||
utils.Fatal("Error decrypting file %s %v", file, err)
|
||||
}
|
||||
//Update file name
|
||||
file = RemoveLastExtension(file)
|
||||
}
|
||||
//Update file name
|
||||
file = RemoveLastExtension(file)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err := utils.CheckEnvVars(dbHVars)
|
||||
if err != nil {
|
||||
utils.Error("Please make sure all required environment variables for database are set")
|
||||
utils.Fatal("Error checking environment variables: %s", err)
|
||||
}
|
||||
|
||||
if utils.FileExists(fmt.Sprintf("%s/%s", tmpPath, file)) {
|
||||
if utils.FileExists(filepath.Join(tmpPath, conf.file)) {
|
||||
|
||||
err := os.Setenv("PGPASSWORD", db.dbPassword)
|
||||
if err != nil {
|
||||
@@ -101,10 +101,10 @@ func RestoreDatabase(db *dbConfig, file string) {
|
||||
testDatabaseConnection(db)
|
||||
utils.Info("Restoring database...")
|
||||
|
||||
extension := filepath.Ext(file)
|
||||
extension := filepath.Ext(conf.file)
|
||||
// Restore from compressed file / .sql.gz
|
||||
if extension == ".gz" {
|
||||
str := "zcat " + filepath.Join(tmpPath, file) + " | psql -h " + db.dbHost + " -p " + db.dbPort + " -U " + db.dbUserName + " -v -d " + db.dbName
|
||||
str := "zcat " + filepath.Join(tmpPath, conf.file) + " | psql -h " + db.dbHost + " -p " + db.dbPort + " -U " + db.dbUserName + " -v -d " + db.dbName
|
||||
_, err := exec.Command("sh", "-c", str).Output()
|
||||
if err != nil {
|
||||
utils.Fatal("Error, in restoring the database %v", err)
|
||||
@@ -130,6 +130,6 @@ func RestoreDatabase(db *dbConfig, file string) {
|
||||
}
|
||||
|
||||
} else {
|
||||
utils.Fatal("File not found in %s", fmt.Sprintf("%s/%s", tmpPath, file))
|
||||
utils.Fatal("File not found in %s", filepath.Join(tmpPath, conf.file))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ var (
|
||||
storagePath = "/backup"
|
||||
disableCompression = false
|
||||
encryption = false
|
||||
usingKey = false
|
||||
)
|
||||
|
||||
// dbHVars Required environment variables for database
|
||||
|
||||
Reference in New Issue
Block a user