Skip to content

Commit

Permalink
Add databases configuration for MySQL backup
Browse files Browse the repository at this point in the history
Allowing to backup multiple databases. See pliz.example.yml for an example of the configuration.
  • Loading branch information
matthmart committed Apr 4, 2018
1 parent 40a6937 commit e58fb68
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 28 deletions.
40 changes: 23 additions & 17 deletions actions/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func makeDump(ctx domain.ExecutionContext, dbBackup domain.DatabaseBackupConfig,
}

if dbType == "mysql" {
err := mysqlDump(path.Join(backupDir, "dump.sql"), containerID, config.Env, backupDir)
err := mysqlDump(containerID, config.Env, backupDir, dbBackup.Databases)
return err
} else if dbType == "mongo" {
err := mongoDump(path.Join(backupDir, "mongodb.archive"), containerID, config.Env, backupDir)
Expand All @@ -168,33 +168,39 @@ func makeDump(ctx domain.ExecutionContext, dbBackup domain.DatabaseBackupConfig,
}
}

func mysqlDump(destination string, containerId string, env domain.DockerContainerEnv, backupDir string) error {
func mysqlDump(containerId string, env domain.DockerContainerEnv, backupDir string, databases []string) error {

password := ""
if value, ok := env["MYSQL_ROOT_PASSWORD"]; ok {
password = value
}

database := "db"
if value, ok := env["MYSQL_DATABASE"]; ok {
database = value
mysqlDatabases := []string{"db"}
if len(databases) > 0 {
mysqlDatabases = databases
} else {
if value, ok := env["MYSQL_DATABASE"]; ok {
mysqlDatabases = []string{value}
}
}

cmd := domain.NewCommand([]string{"docker", "exec", "-i", containerId, "mysqldump", fmt.Sprintf("--password=%s", password), database})
for _, database := range mysqlDatabases {
cmd := domain.NewCommand([]string{"docker", "exec", "-i", containerId, "mysqldump", fmt.Sprintf("--password=%s", password), database})

file, err := ioutil.TempFile(backupDir, "plizdump")
if err != nil {
fmt.Println("Unable to create a tmp file:")
return err
}
defer file.Close()
file, err := ioutil.TempFile(backupDir, "plizdump")
if err != nil {
fmt.Println("Unable to create a tmp file:")
return err
}
defer file.Close()

if err := cmd.WriteResultToFile(file); err != nil {
os.Remove(file.Name())
return err
}
if err := cmd.WriteResultToFile(file); err != nil {
os.Remove(file.Name())
return err
}

os.Rename(file.Name(), destination)
os.Rename(file.Name(), path.Join(backupDir, database+".sql"))
}

return nil
}
Expand Down
16 changes: 10 additions & 6 deletions actions/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,9 @@ func untar(ctx domain.ExecutionContext, tarball string, configFilesRestoration b

if strings.Contains(comps[1], "mongo") {
restoreMongo(containerID, tarReader)
} else if strings.Contains(comps[1], "dump") {
restoreMySQL(ctx, containerID, tarReader)
} else if strings.Contains(comps[1], "sql") {
// comps[1] is the filename of the dump (containing the database name, e.g. db.sql)
restoreMySQL(ctx, containerID, comps[1], tarReader)
} else {
fmt.Println("Unrecognized db backup.")
}
Expand Down Expand Up @@ -188,7 +189,7 @@ func restoreMongo(containerID string, mongoArchiveReader *tar.Reader) {
cmd.ExecuteWithStdin(mongoArchiveReader)
}

func restoreMySQL(ctx domain.ExecutionContext, containerID string, mysqlDumpReader *tar.Reader) {
func restoreMySQL(ctx domain.ExecutionContext, containerID string, dumpFilename string, mysqlDumpReader *tar.Reader) {

containerConfig, err := utils.GetContainerConfig(containerID, ctx)
if err != nil {
Expand All @@ -200,9 +201,12 @@ func restoreMySQL(ctx domain.ExecutionContext, containerID string, mysqlDumpRead
password = value
}

database := "db"
if value, ok := containerConfig.Env["MYSQL_DATABASE"]; ok {
database = value
ext := filepath.Ext(dumpFilename)
database := strings.Replace(dumpFilename, ext, "", 1)

// backward compatibility, supporting previous filename (dump.sql)
if database == "dump" {
database = "db"
}

cmd := domain.NewCommand([]string{"docker", "exec", "-i", containerID, "mysql", fmt.Sprintf("--password=%s", password), database})
Expand Down
6 changes: 5 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,11 @@ func (parsed parserConfig) convertToConfig(config *domain.Config) error {
// backup
backupConfig := domain.Backup{Files: parsed.Backup.Files, Databases: []domain.DatabaseBackupConfig{}}
for i := range parsed.Backup.Databases {
dbBackupConfig := domain.DatabaseBackupConfig{Container: parsed.Backup.Databases[i].Container, Type: parsed.Backup.Databases[i].Type}
dbBackupConfig := domain.DatabaseBackupConfig{
Container: parsed.Backup.Databases[i].Container,
Type: parsed.Backup.Databases[i].Type,
Databases: parsed.Backup.Databases[i].Databases,
}
backupConfig.Databases = append(backupConfig.Databases, dbBackupConfig)
}
config.BackupConfig = backupConfig
Expand Down
5 changes: 3 additions & 2 deletions config/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type BackupSpec struct {
}

type DatabaseBackupSpec struct {
Container string `yaml:"container"`
Type string `yaml:"type"`
Container string `yaml:"container"`
Type string `yaml:"type"`
Databases []string `yaml:"databases"`
}
1 change: 1 addition & 0 deletions domain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ type Backup struct {
type DatabaseBackupConfig struct {
Container string
Type string
Databases []string
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func main() {

app := cli.App("pliz", "Manage projects building")

app.Version("v version", "Pliz 6 (build 17)")
app.Version("v version", "Pliz 7 (build 18)")

// option to change the Pliz env
plizEnv := app.String(cli.StringOpt{
Expand Down
5 changes: 4 additions & 1 deletion pliz.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,7 @@ backup:
# supported DB: MySQL or MongoDB
databases:
- container: db
type: mongo # mysql|mongo, optional. If not present, the image name is used to try to guess the type
type: mysql # mysql|mongo, optional. If not present, the image name is used to try to guess the type
databases: # only used for mysql. List of databases to backup
- db
- ghost

0 comments on commit e58fb68

Please sign in to comment.