Merge pull request #16 from netbenix/develop

SQL Changes
This commit is contained in:
netbenix 2021-12-23 11:20:18 +01:00 committed by GitHub
commit 5dbd1e4179
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 95 additions and 49 deletions

View file

@ -39,7 +39,7 @@ func compress(fileToWrite *os.File, folderPath string, backupName string){
zr, _ := gzip.NewWriterLevel(fileToWrite, flate.BestCompression)
tw := tar.NewWriter(zr)
go fmt.Printf("[%s] Start compression...\n", filepath.Base(folderPath))
go fmt.Printf("[%s] Start compression...\n", backupName)
SQL.NewLogEntry(SQL.GetSQLInstance(), uuid.New(), SQL.LogInfo, backupName, SQL.SQLStage_Compress, SQL.REMOTE_NONE, "Start compression", time.Now())
filepath.Walk(folderPath, func(file string, fi os.FileInfo, err error) error {
header, err := tar.FileInfoHeader(fi, file)
@ -60,7 +60,7 @@ func compress(fileToWrite *os.File, folderPath string, backupName string){
logger.Fatal(err)
}
go fmt.Printf("[%s] Compressing: %s (%d bytes)\n", filepath.Base(folderPath) ,relPath, fi.Size())
go fmt.Printf("[%s] Compressing: %s (%d bytes)\n", backupName, relPath, fi.Size())
if _, err := io.Copy(tw, data); err != nil {
logger.Fatal(err)
}
@ -78,6 +78,6 @@ func compress(fileToWrite *os.File, folderPath string, backupName string){
}
go fmt.Printf("[%s] Compression Done.\n", filepath.Base(folderPath))
go fmt.Printf("[%s] Compression Done.\n", backupName)
SQL.NewLogEntry(SQL.GetSQLInstance(), uuid.New(), SQL.LogInfo, backupName, SQL.SQLStage_Compress, SQL.REMOTE_NONE, "Compression complete.", time.Now())
}

View file

@ -9,6 +9,10 @@ Trello board: [Click me!](https://trello.com/b/6zWLE6Jm)
- Log the Backup progress to a database
- Upload the files to a remote storage of your choice (see [Storage Types](#storage-types))
## Planned features for the Future!
- Backup restore
- Service for scheduled updates
- (Maybe) a web interface
## Database Types
- MariaDB
@ -21,9 +25,9 @@ Trello board: [Click me!](https://trello.com/b/6zWLE6Jm)
## Storage types
- Local storage (soon)
- Azure Blob Storage (planned)
- Local storage
- Azure File Share
- Azure Blob Storage (planned)
- S3 Bucket (far future)
- Dropbox (far future)
- OneDrive (far future)
@ -32,24 +36,26 @@ Trello board: [Click me!](https://trello.com/b/6zWLE6Jm)
| Storage Type | Config Type |
|-------------------------|--------------------------|
| Azure File Share | azure-fileshare |
| Local Storage | none |
## Config Explaination
### config.json
| Field | Type | Description |
|---------------------|:----------------:|------------------------------------------------|
| localBackupPath | string | Path where local backups are stored |
| **sqlConfig** | ---------------- | ---------------------------------------------- |
| enableSQL | boolean | Enable/Disables the SQL entries
| sqlType | string | See [DatabaseTypes](#database-types) |
| sql-address | string | Address to the SQL Server |
| sql-port | uint16 | SQL Server Port |
| database | string | Database name |
| db-user | string | SQL username from user which should be used |
| db-password | string | SQL password from user which should be used |
| **foldersToBackup** | ---------------- | ---------------------------------------------- |
| backupName | string | .bak file name |
| folderPath | string | Path to folder which should be backed up |
| storageType | string | See [StorageTypes](#storage-types) |
| createLocalBackup | boolean | Sets if .bak file should also be saved locally |
| Field | Type | Description |
|---------------------------|:----------------:|------------------------------------------------|
| localBackupPath | string | Path where local backups are stored |
| **sqlConfig** | ---------------- | ---------------------------------------------- |
| enableSQL | boolean | Enable/Disables the SQL entries
| sqlType | string | See [DatabaseTypes](#database-types) |
| sql-address | string | Address to the SQL Server |
| sql-port | uint16 | SQL Server Port |
| database | string | Database name |
| db-user | string | SQL username from user which should be used |
| db-password | string | SQL password from user which should be used |
| **foldersToBackup** | ---------------- | ---------------------------------------------- |
| backupName | string | .bak file name |
| folderPath | string | Path to folder which should be backed up |
| remoteStorageType | string | See [StorageTypes](#storage-types) |
| targetPath | string | Sets the targetPath for local backups |
| createLocalBackup | boolean | Sets if .bak file should also be saved locally |

View file

@ -4,6 +4,7 @@ import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"github.com/google/uuid"
"os"
"scabiosa/Logging"
"scabiosa/Tools"
"strconv"
@ -30,7 +31,6 @@ func GetMariaDBInstance(config Tools.Config) MariaDBConnector {
return mariadb
}
func checkIfEventLogTableExist(db *sql.DB, mariadb MariaDBConnector) bool {
rows, _ := db.Query("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = 'EventLog';", mariadb.Database)
if !rows.Next(){ return false }
@ -43,8 +43,8 @@ func checkIfBackupTableExist(db *sql.DB, mariadb MariaDBConnector) bool {
return true
}
func checkIfBackupEntryExist(db *sql.DB, mariadb MariaDBConnector, backupName string) bool {
rows, _ := db.Query("SELECT * FROM `" + mariadb.Database + "`.Backups WHERE BackupName = '" + backupName + "';")
func checkIfBackupEntryExist(db *sql.DB, mariadb MariaDBConnector, backupName string, hostname string) bool {
rows, _ := db.Query("SELECT * FROM `" + mariadb.Database + "`.Backups WHERE Hostname = ? AND BackupName = ?;", hostname, backupName)
if !rows.Next(){ return false; }
return true
}
@ -61,9 +61,8 @@ func createMariaDBConnection(mariadb MariaDBConnector) *sql.DB{
func (mariadb MariaDBConnector) createDefaultTables(){
logger := Logging.DetailedLogger("MariaDB", "createDefaultTables")
eventLogSQL := "create table " + mariadb.Database +".EventLog\n(\n UUID text null,\n LogType enum ('INFO', 'WARNING', 'ERROR', 'FATAL') null,\n BackupName varchar(256) null,\n Stage enum ('COMPRESS', 'UPLOAD', 'DELETE TMP') null,\n RemoteStorage enum ('AZURE-FILE', 'AZURE-BLOB', 'NONE') null,\n Description text null,\n Timestamp datetime null\n);"
backupSQL := "create table " + mariadb.Database +".Backups\n(\n UUID text null,\n BackupName varchar(256) null,\n LastBackup datetime null,\n LocalBackup tinyint(1) null,\n FilePath varchar(256) null,\n RemoteStorage enum ('AZURE-FILE', 'AZURE-BLOB', 'NONE') null,\n RemotePath varchar(256) null\n);\n\n"
eventLogSQL := "create table `" + mariadb.Database +"`.EventLog(UUID text null, LogType enum ('INFO', 'WARNING', 'ERROR', 'FATAL') null, Hostname varchar(256) null,BackupName varchar(256) null, Stage enum ('COMPRESS', 'UPLOAD', 'DELETE TMP') null, RemoteStorage enum ('AZURE-FILE', 'AZURE-BLOB', 'NONE') null, Description text null, Timestamp datetime null);"
backupSQL := "create table `" + mariadb.Database +"`.Backups(UUID text null, Hostname varchar(256) null, BackupName varchar(256) null, LastBackup datetime null, LocalBackup tinyint(1) null, FilePath varchar(256) null, RemoteStorage enum ('AZURE-FILE', 'AZURE-BLOB', 'NONE') null, RemotePath varchar(256) null, LocalPath varchar(256) null);"
db := createMariaDBConnection(mariadb)
@ -88,26 +87,28 @@ func (mariadb MariaDBConnector) newLogEntry(uuid uuid.UUID, logType LogType, bac
logger := Logging.DetailedLogger("MariaDB", "newLogEntry")
db := createMariaDBConnection(mariadb)
_, err := db.Query("INSERT INTO `" + mariadb.Database + "`.EventLog VALUES (?, ?, ?, ?, ?, ?, ?);", uuid.String(), strconv.FormatInt(int64(logType), 10), backupName, stage, strconv.FormatInt(int64(storageType), 10), description ,timestamp)
hostname, _ := os.Hostname()
_, err := db.Query("INSERT INTO `" + mariadb.Database + "`.EventLog VALUES (?, ?, ?, ?, ?, ?, ?, ?);", uuid.String(), strconv.FormatInt(int64(logType), 10), hostname, backupName, stage, strconv.FormatInt(int64(storageType), 10), description ,timestamp)
if err != nil{
logger.Fatal(err)
}
}
func (mariadb MariaDBConnector) newBackupEntry(backupName string, lastBackup time.Time, localBackup bool, filePath string, storageType RemoteStorageType, remotePath string){
func (mariadb MariaDBConnector) newBackupEntry(backupName string, lastBackup time.Time, localBackup bool, filePath string, storageType RemoteStorageType, remotePath string, localPath string){
logger := Logging.DetailedLogger("MariaDB", "newBackupEntry")
db := createMariaDBConnection(mariadb)
if checkIfBackupEntryExist(db, mariadb, backupName){
_, err := db.Query("UPDATE `" + mariadb.Database + "`.Backups SET LastBackup = ? WHERE BackupName = ?;", lastBackup, backupName)
hostname, _ := os.Hostname()
if checkIfBackupEntryExist(db, mariadb, backupName, hostname){
_, err := db.Query("UPDATE `" + mariadb.Database + "`.Backups SET LastBackup = ?, LocalBackup = ?, RemoteStorage = ?, RemotePath = ?, LocalPath = ? WHERE Hostname = ? AND BackupName = ?;",lastBackup, localBackup, strconv.FormatInt(int64(storageType), 10), remotePath, localPath, hostname, backupName)
if err != nil {
logger.Fatal(err)
}
} else {
_, err := db.Query("INSERT INTO `" + mariadb.Database + "`.Backups VALUES (?, ?, ?, ?, ?, ?, ?);", uuid.New(), backupName, lastBackup, localBackup, filePath, strconv.FormatInt(int64(storageType), 10), remotePath)
_, err := db.Query("INSERT INTO `" + mariadb.Database + "`.Backups VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", uuid.New(), hostname, backupName, lastBackup, localBackup, filePath, strconv.FormatInt(int64(storageType), 10), remotePath, localPath)
if err != nil {
logger.Fatal(err)
}

View file

@ -9,7 +9,7 @@ import (
type SQLService interface {
createDefaultTables()
newLogEntry(uuid uuid.UUID, logType LogType, backupName string, stage SQLStage, storageType RemoteStorageType, description string, timestamp time.Time)
newBackupEntry(backupName string, lastBackup time.Time, localBackup bool, filePath string, storageType RemoteStorageType, remotePath string)
newBackupEntry(backupName string, lastBackup time.Time, localBackup bool, filePath string, storageType RemoteStorageType, remotePath string, localPath string)
}
func CreateDefaultTables(sqlService SQLService){
@ -26,10 +26,10 @@ func NewLogEntry(sqlService SQLService, uuid uuid.UUID, logType LogType, backupN
}
}
func NewBackupEntry(sqlService SQLService, backupName string, lastBackup time.Time, localBackup bool, filePath string, storageType RemoteStorageType, remotePath string){
func NewBackupEntry(sqlService SQLService, backupName string, lastBackup time.Time, localBackup bool, filePath string, storageType RemoteStorageType, remotePath string, localPath string){
config := Tools.GetConfig()
if config.SQLConfig.EnableSQL{
sqlService.newBackupEntry(backupName, lastBackup, localBackup, filePath, storageType, remotePath)
sqlService.newBackupEntry(backupName, lastBackup, localBackup, filePath, storageType, remotePath, localPath)
}
}

View file

@ -21,8 +21,9 @@ type Config struct {
BackupName string `json:"backupName"`
FolderPath string `json:"folderPath"`
RemoteStorageType string `json:"remoteStorageType"`
TargetPath string `json:"targetPath"`
CreateLocalBackup bool `json:"createLocalBackup"`
RemoteTargetPath string `json:"remoteTargetPath"`
CreateLocalBackup bool `json:"createLocalBackup"`
LocalTargetPath string `json:"LocalTargetPath"`
} `json:"foldersToBackup"`
}
@ -36,9 +37,40 @@ func readConfig() []byte {
return file
}
func CheckIfConfigExists(){
logger := Logging.DetailedLogger("ConfigHandler", "CheckIfConfigExists")
if _, err := os.Stat("config/config.json"); os.IsNotExist(err){
_, fileErr := os.OpenFile("config/config.json", os.O_CREATE, 0775)
if fileErr != nil{
logger.Fatal(fileErr)
}
generateDefaultConfig()
}
}
func generateDefaultConfig() {
logger := Logging.DetailedLogger("ConfigHandler", "GenerateDefaultConfig")
var config Config
var conf []byte
conf, err := json.MarshalIndent(config, "", "\t")
//conf, err := json.Marshal(config)
if err != nil {
logger.Fatal(err)
}
err = os.WriteFile("config/config.json", conf, 0755)
if err != nil {
logger.Fatal(err)
}
}
func GetConfig() Config {
logger := Logging.DetailedLogger("ConfigHandler", "GetConfig()")
logger := Logging.DetailedLogger("ConfigHandler", "GetConfig")
var config Config
err := json.Unmarshal(readConfig(), &config)

View file

@ -12,9 +12,10 @@
{
"backupName": "",
"folderPath": "",
"storageType": "",
"targetPath": "",
"createLocalBackup": false
"remoteStorageType": "",
"remoteTargetPath": "",
"createLocalBackup": false,
"localTargetPath": ""
}
]
}

18
main.go
View file

@ -12,6 +12,7 @@ import (
)
func main(){
Tools.CheckIfConfigExists()
config := Tools.GetConfig()
SQL.CreateDefaultTables(SQL.GetSQLInstance())
@ -23,22 +24,27 @@ func main(){
if backupItem.RemoteStorageType != "none"{
storage = StorageTypes.CheckStorageType(backupItem.RemoteStorageType)
destPath = checkTmpPath(backupItem.CreateLocalBackup, backupItem.TargetPath)
destPath = checkTmpPath(backupItem.CreateLocalBackup, backupItem.LocalTargetPath)
} else {
destPath = backupItem.TargetPath
destPath = backupItem.LocalTargetPath
}
bakFile := Compressor.CreateBakFile(backupItem.BackupName + getTimeSuffix(), backupItem.FolderPath, destPath, backupItem.BackupName)
if backupItem.RemoteStorageType != "none"{
StorageTypes.UploadFile(storage, bakFile, backupItem.BackupName, backupItem.TargetPath)
StorageTypes.UploadFile(storage, bakFile, backupItem.BackupName, backupItem.RemoteTargetPath)
}
if !backupItem.CreateLocalBackup && backupItem.RemoteStorageType != "none"{
_ = os.Remove(bakFile)
SQL.NewLogEntry(SQL.GetSQLInstance(), uuid.New(), SQL.LogInfo, backupItem.BackupName, SQL.SQLStage_DeleteTmp, SQL.REMOTE_NONE, "Deleted tmp file" ,time.Now())
}
SQL.NewBackupEntry(SQL.GetSQLInstance(), backupItem.BackupName, time.Now(), backupItem.CreateLocalBackup, backupItem.FolderPath, StorageTypes.CheckRemoteStorageType(backupItem.RemoteStorageType), StorageTypes.GetAzureStorage().TargetDirectory)
SQL.NewLogEntry(SQL.GetSQLInstance(), uuid.New(), SQL.LogInfo, backupItem.BackupName, SQL.SQLStage_DeleteTmp, SQL.REMOTE_NONE, "Deleted tmp file" ,time.Now())
}
if backupItem.RemoteStorageType == "none" {
backupItem.CreateLocalBackup = true
backupItem.RemoteTargetPath = "NONE"
}
SQL.NewBackupEntry(SQL.GetSQLInstance(), backupItem.BackupName, time.Now(), backupItem.CreateLocalBackup, backupItem.FolderPath, StorageTypes.CheckRemoteStorageType(backupItem.RemoteStorageType), backupItem.RemoteTargetPath, backupItem.LocalTargetPath)
}
}