mirror of
https://github.com/jkaninda/mysql-bkup.git
synced 2025-12-06 21:49:40 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf566af4f8 | |||
| 99ea4e18e5 | |||
| 748416af9b | |||
| bce9512d6a | |||
| 8eff38bdb1 | |||
| c12a6751ae | |||
| 05eda4213a | |||
| a919b161c8 | |||
| 4b07a78f29 | |||
| 4a0ad39d70 | |||
| 0be493d51f | |||
| cdb4b2017a | |||
| 09ba8f8981 | |||
| 2ae78fec57 | |||
| 2cd74167de | |||
| aaad8a010c |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -35,5 +35,5 @@ jobs:
|
||||
file: "./docker/Dockerfile"
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
"${{env.BUILDKIT_IMAGE}}:v0.4"
|
||||
"${{env.BUILDKIT_IMAGE}}:v0.5"
|
||||
"${{env.BUILDKIT_IMAGE}}:latest"
|
||||
|
||||
64
README.md
64
README.md
@@ -38,21 +38,23 @@ MySQL Backup and Restoration tool. Backup database to AWS S3 storage or any S3 A
|
||||
|
||||
## Usage
|
||||
|
||||
| Options | Shorts | Usage |
|
||||
|---------------|--------|------------------------------------|
|
||||
| mysql_bkup | bkup | CLI utility |
|
||||
| --operation | -o | Set operation. backup or restore (default: backup) |
|
||||
| --storage | -s | Set storage. local or s3 (default: local) |
|
||||
| --file | -f | Set file name for restoration |
|
||||
| --path | | Set s3 path without file name. eg: /custom_path |
|
||||
| --dbname | -d | Set database name |
|
||||
| --port | -p | Set database port (default: 3306) |
|
||||
| --mode | -m | Set execution mode. default or scheduled (default: default) |
|
||||
| --disable-compression | | Disable database backup compression |
|
||||
| --period | | Set crontab period for scheduled mode only. (default: "0 1 * * *") |
|
||||
| --timeout | -t | Set timeout (default: 60s) |
|
||||
| --help | -h | Print this help message and exit |
|
||||
| --version | -V | Print version information and exit |
|
||||
| Options | Shorts | Usage |
|
||||
|-----------------------|--------|--------------------------------------------------------------------|
|
||||
| mysql-bkup | bkup | CLI utility |
|
||||
| backup | | Backup database operation |
|
||||
| restore | | Restore database operation |
|
||||
| history | | Show the history of backup |
|
||||
| --storage | -s | Set storage. local or s3 (default: local) |
|
||||
| --file | -f | Set file name for restoration |
|
||||
| --path | | Set s3 path without file name. eg: /custom_path |
|
||||
| --dbname | -d | Set database name |
|
||||
| --port | -p | Set database port (default: 3306) |
|
||||
| --mode | -m | Set execution mode. default or scheduled (default: default) |
|
||||
| --disable-compression | | Disable database backup compression |
|
||||
| --period | | Set crontab period for scheduled mode only. (default: "0 1 * * *") |
|
||||
| --timeout | -t | Set timeout (default: 60s) |
|
||||
| --help | -h | Print this help message and exit |
|
||||
| --version | -V | Print version information and exit |
|
||||
|
||||
## Note:
|
||||
|
||||
@@ -81,20 +83,20 @@ FLUSH PRIVILEGES;
|
||||
Simple backup usage
|
||||
|
||||
```sh
|
||||
bkup --operation backup --dbname database_name
|
||||
bkup backup --dbname database_name
|
||||
```
|
||||
```sh
|
||||
bkup -o backup -d database_name
|
||||
bkup backup -d database_name
|
||||
```
|
||||
### S3
|
||||
|
||||
```sh
|
||||
bkup --operation backup --storage s3 --dbname database_name
|
||||
bkup backup --storage s3 --dbname database_name
|
||||
```
|
||||
## Docker run:
|
||||
|
||||
```sh
|
||||
docker run --rm --network your_network_name --name mysql-bkup -v $PWD/backup:/backup/ -e "DB_HOST=database_host_name" -e "DB_USERNAME=username" -e "DB_PASSWORD=password" jkaninda/mysql-bkup:latest bkup -o backup -d database_name
|
||||
docker run --rm --network your_network_name --name mysql-bkup -v $PWD/backup:/backup/ -e "DB_HOST=database_host_name" -e "DB_USERNAME=username" -e "DB_PASSWORD=password" jkaninda/mysql-bkup:latest bkup backup -d database_name
|
||||
```
|
||||
|
||||
## Docker compose file:
|
||||
@@ -115,7 +117,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation backup -d database_name
|
||||
- bkup backup -d database_name
|
||||
volumes:
|
||||
- ./backup:/backup
|
||||
environment:
|
||||
@@ -129,22 +131,22 @@ services:
|
||||
Simple database restore operation usage
|
||||
|
||||
```sh
|
||||
bkup --operation restore --dbname database_name --file database_20231217_115621.sql
|
||||
bkup restore --dbname database_name --file database_20231217_115621.sql
|
||||
```
|
||||
|
||||
```sh
|
||||
bkup -o restore -f database_20231217_115621.sql
|
||||
bkup restore -f database_20231217_115621.sql
|
||||
```
|
||||
### S3
|
||||
|
||||
```sh
|
||||
bkup --operation restore --storage s3 --file database_20231217_115621.sql
|
||||
bkup restore --storage s3 --file database_20231217_115621.sql
|
||||
```
|
||||
|
||||
## Docker run:
|
||||
|
||||
```sh
|
||||
docker run --rm --network your_network_name --name mysql-bkup -v $PWD/backup:/backup/ -e "DB_HOST=database_host_name" -e "DB_USERNAME=username" -e "DB_PASSWORD=password" jkaninda/mysql-bkup bkup -o backup -d database_name -f mydb_20231219_022941.sql.gz
|
||||
docker run --rm --network your_network_name --name mysql-bkup -v $PWD/backup:/backup/ -e "DB_HOST=database_host_name" -e "DB_USERNAME=username" -e "DB_PASSWORD=password" jkaninda/mysql-bkup bkup backup -d database_name -f db_20231219_022941.sql.gz
|
||||
```
|
||||
|
||||
## Docker compose file:
|
||||
@@ -166,7 +168,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation restore --file database_20231217_115621.sql --dbname database_name
|
||||
- bkup restore --file database_20231217_115621.sql --dbname database_name
|
||||
volumes:
|
||||
- ./backup:/backup
|
||||
environment:
|
||||
@@ -185,14 +187,14 @@ docker-compose up -d
|
||||
## Backup to S3
|
||||
|
||||
```sh
|
||||
docker run --rm --privileged --device /dev/fuse --name mysql-bkup -e "DB_HOST=db_hostname" -e "DB_USERNAME=username" -e "DB_PASSWORD=password" -e "ACCESS_KEY=your_access_key" -e "SECRET_KEY=your_secret_key" -e "BUCKETNAME=your_bucket_name" -e "S3_ENDPOINT=https://s3.us-west-2.amazonaws.com" jkaninda/mysql-bkup bkup -o backup -s s3 -d database_name
|
||||
docker run --rm --privileged --device /dev/fuse --name mysql-bkup -e "DB_HOST=db_hostname" -e "DB_USERNAME=username" -e "DB_PASSWORD=password" -e "ACCESS_KEY=your_access_key" -e "SECRET_KEY=your_secret_key" -e "BUCKETNAME=your_bucket_name" -e "S3_ENDPOINT=https://s3.us-west-2.amazonaws.com" jkaninda/mysql-bkup bkup backup -s s3 -d database_name
|
||||
```
|
||||
> To change s3 backup path add this flag : --path /myPath . default path is /mysql_bkup
|
||||
|
||||
Simple S3 backup usage
|
||||
|
||||
```sh
|
||||
bkup --operation backup --storage s3 --dbname mydatabase
|
||||
bkup backup --storage s3 --dbname mydatabase
|
||||
```
|
||||
```yaml
|
||||
version: '3'
|
||||
@@ -206,7 +208,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- mysql_bkup --operation restore --storage s3 -f database_20231217_115621.sql.gz
|
||||
- mysql-bkup restore --storage s3 -f database_20231217_115621.sql.gz
|
||||
environment:
|
||||
- DB_PORT=3306
|
||||
- DB_HOST=mysql
|
||||
@@ -273,7 +275,7 @@ Easy to remember format:
|
||||
> Docker run :
|
||||
|
||||
```sh
|
||||
docker run --rm --name mysql-bkup -v $BACKUP_DIR:/backup/ -e "DB_HOST=$DB_HOST" -e "DB_USERNAME=$DB_USERNAME" -e "DB_PASSWORD=$DB_PASSWORD" jkaninda/mysql-bkup bkup --operation backup --dbname $DB_NAME --mode scheduled --period "0 1 * * *"
|
||||
docker run --rm --name mysql-bkup -v $BACKUP_DIR:/backup/ -e "DB_HOST=$DB_HOST" -e "DB_USERNAME=$DB_USERNAME" -e "DB_PASSWORD=$DB_PASSWORD" jkaninda/mysql-bkup bkup backup --dbname $DB_NAME --mode scheduled --period "0 1 * * *"
|
||||
```
|
||||
|
||||
> With Docker compose
|
||||
@@ -290,7 +292,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation backup --storage s3 --path /mys3_custome_path --dbname database_name --mode scheduled --period "*/30 * * * *"
|
||||
- bkup backup --storage s3 --path /mys3_custome_path --dbname database_name --mode scheduled --period "*/30 * * * *"
|
||||
environment:
|
||||
- DB_PORT=3306
|
||||
- DB_HOST=mysqlhost
|
||||
@@ -327,7 +329,7 @@ spec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup -o backup -s s3 --path /custom_path
|
||||
- bkup backup -s s3 --path /custom_path
|
||||
env:
|
||||
- name: DB_PORT
|
||||
value: "3306"
|
||||
|
||||
28
cmd/backup.go
Normal file
28
cmd/backup.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/jkaninda/mysql-bkup/pkg"
|
||||
"github.com/jkaninda/mysql-bkup/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var BackupCmd = &cobra.Command{
|
||||
Use: "backup ",
|
||||
Short: "Backup database operation",
|
||||
Example: utils.BackupExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
pkg.StartBackup(cmd)
|
||||
} else {
|
||||
utils.Fatal("Error, no argument required")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
//Backup
|
||||
BackupCmd.PersistentFlags().StringP("mode", "m", "default", "Set execution mode. default or scheduled")
|
||||
BackupCmd.PersistentFlags().StringP("period", "", "0 1 * * *", "Set schedule period time")
|
||||
BackupCmd.PersistentFlags().BoolP("disable-compression", "", false, "Disable backup compression")
|
||||
|
||||
}
|
||||
14
cmd/history.go
Normal file
14
cmd/history.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/jkaninda/mysql-bkup/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var HistoryCmd = &cobra.Command{
|
||||
Use: "history",
|
||||
Short: "Show the history of backup",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
utils.ShowHistory()
|
||||
},
|
||||
}
|
||||
28
cmd/restore.go
Normal file
28
cmd/restore.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/jkaninda/mysql-bkup/pkg"
|
||||
"github.com/jkaninda/mysql-bkup/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var RestoreCmd = &cobra.Command{
|
||||
Use: "restore",
|
||||
Short: "Restore database operation",
|
||||
Example: utils.RestoreExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
pkg.StartRestore(cmd)
|
||||
} else {
|
||||
utils.Fatal("Error, no argument required")
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
//Restore
|
||||
RestoreCmd.PersistentFlags().StringP("file", "f", "", "File name of database")
|
||||
|
||||
}
|
||||
54
cmd/root.go
54
cmd/root.go
@@ -5,20 +5,32 @@ Copyright © 2024 Jonas Kaninda <jonaskaninda@gmail.com>
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"fmt"
|
||||
"github.com/jkaninda/mysql-bkup/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "mysql-bkup",
|
||||
Short: "MySQL Backup tool, backup database to S3 or Object Storage",
|
||||
Long: `MySQL Backup and Restoration tool. Backup database to AWS S3 storage or any S3 Alternatives for Object Storage.`,
|
||||
// Uncomment the following line if your bare application
|
||||
// has an action associated with it:
|
||||
// Run: func(cmd *cobra.Command, args []string) { },
|
||||
Use: "mysql-bkup [Command]",
|
||||
Short: "MySQL Backup tool, backup database to S3 or Object Storage",
|
||||
Long: `MySQL Database backup and restoration tool. Backup database to AWS S3 storage or any S3 Alternatives for Object Storage.`,
|
||||
Example: utils.MainExample,
|
||||
Version: appVersion,
|
||||
//TODO: To remove
|
||||
//For old user || To remove
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if operation != "" {
|
||||
if operation == "backup" || operation == "restore" {
|
||||
fmt.Println(utils.Notice)
|
||||
utils.Fatal("New config required, please check --help")
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
var operation = ""
|
||||
var s3Path = "/mysql-bkup"
|
||||
|
||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||
@@ -30,25 +42,21 @@ func Execute() {
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Here you will define your flags and configuration settings.
|
||||
// Cobra supports persistent flags, which, if defined here,
|
||||
// will be global for your application.
|
||||
|
||||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.mysql-bkup.yaml)")
|
||||
|
||||
// Cobra also supports local flags, which will only run
|
||||
// when this action is called directly.
|
||||
rootCmd.PersistentFlags().StringP("operation", "o", "backup", "Set operation")
|
||||
rootCmd.PersistentFlags().StringP("storage", "s", "local", "Set storage. local or s3")
|
||||
rootCmd.PersistentFlags().StringP("file", "f", "", "Set file name")
|
||||
rootCmd.PersistentFlags().StringP("path", "P", "/mysql-bkup", "Set s3 path, without file name")
|
||||
rootCmd.PersistentFlags().StringP("path", "P", s3Path, "Set s3 path, without file name. for S3 storage only")
|
||||
rootCmd.PersistentFlags().StringP("dbname", "d", "", "Set database name")
|
||||
rootCmd.PersistentFlags().IntP("timeout", "t", 30, "Set timeout")
|
||||
rootCmd.PersistentFlags().IntP("port", "p", 3306, "Set database port")
|
||||
rootCmd.PersistentFlags().StringVarP(&operation, "operation", "o", "", "Set operation, for old version only")
|
||||
|
||||
rootCmd.PersistentFlags().StringP("mode", "m", "default", "Set execution mode. default or scheduled")
|
||||
rootCmd.PersistentFlags().StringP("period", "", "0 1 * * *", "Set schedule period time")
|
||||
rootCmd.PersistentFlags().IntP("timeout", "t", 30, "Set timeout")
|
||||
rootCmd.PersistentFlags().BoolP("disable-compression", "", false, "Disable backup compression")
|
||||
rootCmd.PersistentFlags().IntP("port", "p", 3306, "Set database port")
|
||||
rootCmd.PersistentFlags().BoolP("help", "h", false, "Print this help message")
|
||||
rootCmd.PersistentFlags().BoolP("version", "v", false, "shows version information")
|
||||
rootCmd.PersistentFlags().StringP("file", "f", "", "File name of database")
|
||||
|
||||
rootCmd.AddCommand(VersionCmd)
|
||||
rootCmd.AddCommand(BackupCmd)
|
||||
rootCmd.AddCommand(RestoreCmd)
|
||||
rootCmd.AddCommand(S3MountCmd)
|
||||
rootCmd.AddCommand(HistoryCmd)
|
||||
}
|
||||
|
||||
14
cmd/s3mount.go
Normal file
14
cmd/s3mount.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/jkaninda/mysql-bkup/pkg"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var S3MountCmd = &cobra.Command{
|
||||
Use: "s3mount",
|
||||
Short: "Mount AWS S3 storage",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
pkg.S3Mount()
|
||||
},
|
||||
}
|
||||
26
cmd/version.go
Normal file
26
cmd/version.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package cmd
|
||||
|
||||
/*
|
||||
Copyright © 2024 Jonas Kaninda <jonaskaninda@gmail.com>
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
var appVersion = os.Getenv("VERSION")
|
||||
|
||||
var VersionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Show version",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Version()
|
||||
},
|
||||
}
|
||||
|
||||
func Version() {
|
||||
fmt.Printf("Version: %s \n", appVersion)
|
||||
fmt.Println()
|
||||
}
|
||||
@@ -21,7 +21,7 @@ ENV ACCESS_KEY=""
|
||||
ENV SECRET_KEY=""
|
||||
ENV S3_ENDPOINT=https://s3.amazonaws.com
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ENV VERSION="v0.4"
|
||||
ENV VERSION="v0.5"
|
||||
LABEL authors="Jonas Kaninda"
|
||||
|
||||
RUN apt-get update -qq
|
||||
@@ -40,6 +40,8 @@ COPY --from=build /app/mysql-bkup /usr/local/bin/mysql-bkup
|
||||
RUN chmod +x /usr/local/bin/mysql-bkup
|
||||
|
||||
RUN ln -s /usr/local/bin/mysql-bkup /usr/local/bin/bkup
|
||||
RUN ln -s /usr/local/bin/mysql-bkup /usr/local/bin/mysql_bkup
|
||||
|
||||
|
||||
ADD docker/supervisord.conf /etc/supervisor/supervisord.conf
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation backup --storage s3 --path /mys3_custom_path --dbname database_name
|
||||
- bkup backup --storage s3 --path /mys3_custom_path --dbname database_name
|
||||
environment:
|
||||
- DB_PORT=3306
|
||||
- DB_HOST=mysqlhost
|
||||
|
||||
@@ -6,7 +6,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation backup --dbname database_name --mode scheduled --period "0 1 * * *"
|
||||
- bkup backup --dbname database_name --mode scheduled --period "0 1 * * *"
|
||||
volumes:
|
||||
- ./backup:/backup
|
||||
environment:
|
||||
|
||||
@@ -9,7 +9,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation backup --storage s3 --path /mys3_custom_path --dbname database_name --mode scheduled --period "0 1 * * *"
|
||||
- bkup backup --storage s3 --path /mys3_custom_path --dbname database_name --mode scheduled --period "0 1 * * *"
|
||||
environment:
|
||||
- DB_PORT=3306
|
||||
- DB_HOST=mysqlhost
|
||||
|
||||
@@ -6,7 +6,7 @@ services:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation backup --dbname database_name
|
||||
- bkup backup --dbname database_name
|
||||
volumes:
|
||||
- ./backup:/backup
|
||||
environment:
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- bkup --operation backup --storage s3 --path /custom_path
|
||||
- bkup backup --storage s3 --path /custom_path
|
||||
env:
|
||||
- name: DB_PORT
|
||||
value: "3306"
|
||||
|
||||
214
main.go
214
main.go
@@ -1,222 +1,16 @@
|
||||
package main
|
||||
|
||||
//main
|
||||
/*****
|
||||
* MySQL Backup & Restore
|
||||
* MySQL Backup & Restore
|
||||
* @author Jonas Kaninda
|
||||
* @license MIT License <https://opensource.org/licenses/MIT>
|
||||
* @link https://github.com/jkaninda/mysql-bkup
|
||||
**/
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jkaninda/mysql-bkup/pkg"
|
||||
"github.com/jkaninda/mysql-bkup/utils"
|
||||
flag "github.com/spf13/pflag"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
import "github.com/jkaninda/mysql-bkup/cmd"
|
||||
|
||||
var appVersion string = os.Getenv("VERSION")
|
||||
|
||||
const s3MountPath string = "/s3mnt"
|
||||
|
||||
var (
|
||||
operation string = "backup"
|
||||
storage string = "local"
|
||||
file string = ""
|
||||
s3Path string = "/mysql-bkup"
|
||||
dbName string = ""
|
||||
dbHost string = ""
|
||||
dbPort string = ""
|
||||
dbPassword string = ""
|
||||
dbUserName string = ""
|
||||
executionMode string = "default"
|
||||
storagePath string = "/backup"
|
||||
accessKey string = ""
|
||||
secretKey string = ""
|
||||
bucketName string = ""
|
||||
s3Endpoint string = ""
|
||||
s3fsPasswdFile string = "/etc/passwd-s3fs"
|
||||
disableCompression bool = false
|
||||
startBackup bool = true
|
||||
|
||||
timeout int = 30
|
||||
period string = "0 1 * * *"
|
||||
)
|
||||
|
||||
func init() {
|
||||
var (
|
||||
operationFlag = flag.StringP("operation", "o", "backup", "Operation")
|
||||
storageFlag = flag.StringP("storage", "s", "local", "Storage, local or s3")
|
||||
fileFlag = flag.StringP("file", "f", "", "File name")
|
||||
pathFlag = flag.StringP("path", "P", "/mysql-bkup", "S3 path, without file name")
|
||||
dbnameFlag = flag.StringP("dbname", "d", "", "Database name")
|
||||
modeFlag = flag.StringP("mode", "m", "default", "Execution mode. default or scheduled")
|
||||
periodFlag = flag.StringP("period", "", "0 1 * * *", "Schedule period time")
|
||||
timeoutFlag = flag.IntP("timeout", "t", 30, "Timeout (in seconds) to stop database connexion")
|
||||
disableCompressionFlag = flag.BoolP("disable-compression", "", false, "Disable backup compression")
|
||||
portFlag = flag.IntP("port", "p", 3306, "Database port")
|
||||
helpFlag = flag.BoolP("help", "h", false, "Print this help message")
|
||||
versionFlag = flag.BoolP("version", "v", false, "Version information")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
operation = *operationFlag
|
||||
storage = *storageFlag
|
||||
file = *fileFlag
|
||||
s3Path = *pathFlag
|
||||
dbName = *dbnameFlag
|
||||
executionMode = *modeFlag
|
||||
dbPort = fmt.Sprint(*portFlag)
|
||||
timeout = *timeoutFlag
|
||||
period = *periodFlag
|
||||
disableCompression = *disableCompressionFlag
|
||||
|
||||
flag.Usage = func() {
|
||||
fmt.Print("MySQL BackupDatabase and Restoration tool. BackupDatabase database to AWS S3 storage or any S3 Alternatives for Object Storage.\n\n")
|
||||
fmt.Print("Usage: bkup --operation backup -storage s3 --dbname databasename --path /my_path ...\n")
|
||||
fmt.Print(" bkup -o backup -d databasename --disable-compression ...\n")
|
||||
fmt.Print(" RestoreDatabase: bkup -o restore -d databasename -f db_20231217_051339.sql.gz ...\n\n")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
if *helpFlag {
|
||||
startBackup = false
|
||||
flag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
if *versionFlag {
|
||||
startBackup = false
|
||||
version()
|
||||
os.Exit(0)
|
||||
}
|
||||
if *dbnameFlag != "" {
|
||||
err := os.Setenv("DB_NAME", dbName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if *pathFlag != "" {
|
||||
s3Path = *pathFlag
|
||||
err := os.Setenv("S3_PATH", fmt.Sprint(*pathFlag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
if *fileFlag != "" {
|
||||
file = *fileFlag
|
||||
err := os.Setenv("FILE_NAME", fmt.Sprint(*fileFlag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
if *portFlag != 3306 {
|
||||
err := os.Setenv("DB_PORT", fmt.Sprint(*portFlag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if *periodFlag != "" {
|
||||
err := os.Setenv("SCHEDULE_PERIOD", fmt.Sprint(*periodFlag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if *storageFlag != "" {
|
||||
err := os.Setenv("STORAGE", fmt.Sprint(*storageFlag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
storage = os.Getenv("STORAGE")
|
||||
err := os.Setenv("STORAGE_PATH", storagePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func version() {
|
||||
fmt.Printf("Version: %s \n", appVersion)
|
||||
fmt.Print()
|
||||
}
|
||||
func main() {
|
||||
//cmd.Execute()
|
||||
|
||||
err := os.Setenv("STORAGE_PATH", storagePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if startBackup {
|
||||
start()
|
||||
}
|
||||
cmd.Execute()
|
||||
|
||||
}
|
||||
func start() {
|
||||
|
||||
if executionMode == "default" {
|
||||
if operation != "backup" {
|
||||
if storage != "s3" {
|
||||
utils.Info("RestoreDatabase from local")
|
||||
pkg.RestoreDatabase(file)
|
||||
} else {
|
||||
utils.Info("RestoreDatabase from s3")
|
||||
s3Restore()
|
||||
}
|
||||
} else {
|
||||
if storage != "s3" {
|
||||
utils.Info("BackupDatabase to local storage")
|
||||
pkg.BackupDatabase(disableCompression)
|
||||
} else {
|
||||
utils.Info("BackupDatabase to s3 storage")
|
||||
s3Backup()
|
||||
}
|
||||
}
|
||||
} else if executionMode == "scheduled" {
|
||||
scheduledMode()
|
||||
} else {
|
||||
utils.Fatal("Error, unknown execution mode!")
|
||||
}
|
||||
}
|
||||
|
||||
func s3Backup() {
|
||||
// Backup Database to S3 storage
|
||||
pkg.MountS3Storage(s3Path)
|
||||
pkg.BackupDatabase(disableCompression)
|
||||
}
|
||||
|
||||
// Run in scheduled mode
|
||||
func scheduledMode() {
|
||||
// Verify operation
|
||||
if operation == "backup" {
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("**********************************")
|
||||
fmt.Println(" Starting MySQL Bkup... ")
|
||||
fmt.Println("***********************************")
|
||||
utils.Info("Running in Scheduled mode")
|
||||
utils.Info("Log file in /var/log/mysql-bkup.log")
|
||||
utils.Info("Execution period ", os.Getenv("SCHEDULE_PERIOD"))
|
||||
|
||||
//Test database connexion
|
||||
utils.TestDatabaseConnection()
|
||||
|
||||
utils.Info("Creating backup job...")
|
||||
pkg.CreateCrontabScript(disableCompression, storage)
|
||||
|
||||
supervisordCmd := exec.Command("supervisord", "-c", "/etc/supervisor/supervisord.conf")
|
||||
if err := supervisordCmd.Run(); err != nil {
|
||||
utils.Fatalf("Error starting supervisord: %v\n", err)
|
||||
}
|
||||
} else {
|
||||
utils.Fatal("Scheduled mode supports only backup operation")
|
||||
}
|
||||
}
|
||||
|
||||
func s3Restore() {
|
||||
// Restore database from S3
|
||||
pkg.MountS3Storage(s3Path)
|
||||
pkg.RestoreDatabase(file)
|
||||
}
|
||||
|
||||
@@ -7,26 +7,75 @@ package pkg
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jkaninda/mysql-bkup/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
dbName = ""
|
||||
dbHost = ""
|
||||
dbPort = ""
|
||||
dbPassword = ""
|
||||
dbUserName = ""
|
||||
storagePath = "/backup"
|
||||
)
|
||||
func StartBackup(cmd *cobra.Command) {
|
||||
_, _ = cmd.Flags().GetString("operation")
|
||||
|
||||
//Set env
|
||||
utils.SetEnv("STORAGE_PATH", storagePath)
|
||||
utils.GetEnv(cmd, "dbname", "DB_NAME")
|
||||
utils.GetEnv(cmd, "port", "DB_PORT")
|
||||
utils.GetEnv(cmd, "period", "SCHEDULE_PERIOD")
|
||||
|
||||
//Get flag value and set env
|
||||
s3Path = utils.GetEnv(cmd, "path", "S3_PATH")
|
||||
storage = utils.GetEnv(cmd, "storage", "STORAGE")
|
||||
file = utils.GetEnv(cmd, "file", "FILE_NAME")
|
||||
disableCompression, _ = cmd.Flags().GetBool("disable-compression")
|
||||
executionMode, _ = cmd.Flags().GetString("mode")
|
||||
|
||||
if executionMode == "default" {
|
||||
if storage == "s3" {
|
||||
utils.Info("Backup database to s3 storage")
|
||||
s3Backup(disableCompression, s3Path)
|
||||
} else {
|
||||
utils.Info("Backup database to local storage")
|
||||
BackupDatabase(disableCompression)
|
||||
|
||||
}
|
||||
} else if executionMode == "scheduled" {
|
||||
scheduledMode()
|
||||
} else {
|
||||
utils.Fatal("Error, unknown execution mode!")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Run in scheduled mode
|
||||
func scheduledMode() {
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("**********************************")
|
||||
fmt.Println(" Starting MySQL Bkup... ")
|
||||
fmt.Println("***********************************")
|
||||
utils.Info("Running in Scheduled mode")
|
||||
utils.Info("Log file in /var/log/mysql-bkup.log")
|
||||
utils.Info("Execution period ", os.Getenv("SCHEDULE_PERIOD"))
|
||||
|
||||
//Test database connexion
|
||||
utils.TestDatabaseConnection()
|
||||
|
||||
utils.Info("Creating backup job...")
|
||||
CreateCrontabScript(disableCompression, storage)
|
||||
|
||||
//Start Supervisor
|
||||
supervisordCmd := exec.Command("supervisord", "-c", "/etc/supervisor/supervisord.conf")
|
||||
if err := supervisordCmd.Run(); err != nil {
|
||||
utils.Fatalf("Error starting supervisord: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// BackupDatabase backup database
|
||||
func BackupDatabase(disableCompression bool) {
|
||||
dbHost = os.Getenv("DB_HOST")
|
||||
dbPassword = os.Getenv("DB_PASSWORD")
|
||||
dbUserName = os.Getenv("DB_USERNAME")
|
||||
dbPassword := os.Getenv("DB_PASSWORD")
|
||||
dbUserName := os.Getenv("DB_USERNAME")
|
||||
dbName = os.Getenv("DB_NAME")
|
||||
dbPort = os.Getenv("DB_PORT")
|
||||
storagePath = os.Getenv("STORAGE_PATH")
|
||||
@@ -37,10 +86,14 @@ func BackupDatabase(disableCompression bool) {
|
||||
utils.TestDatabaseConnection()
|
||||
// Backup Database database
|
||||
utils.Info("Backing up database...")
|
||||
//Generate file name
|
||||
bkFileName := fmt.Sprintf("%s_%s.sql.gz", dbName, time.Now().Format("20060102_150405"))
|
||||
|
||||
// Verify is compression is disabled
|
||||
if disableCompression {
|
||||
//Generate file name
|
||||
bkFileName = fmt.Sprintf("%s_%s.sql", dbName, time.Now().Format("20060102_150405"))
|
||||
// Execute mysqldump
|
||||
cmd := exec.Command("mysqldump",
|
||||
"-h", dbHost,
|
||||
"-P", dbPort,
|
||||
@@ -53,6 +106,7 @@ func BackupDatabase(disableCompression bool) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// save output
|
||||
file, err := os.Create(fmt.Sprintf("%s/%s", storagePath, bkFileName))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -63,14 +117,13 @@ func BackupDatabase(disableCompression bool) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
utils.Info("Database has been backed up")
|
||||
utils.Done("Database has been backed up")
|
||||
|
||||
} else {
|
||||
// Execute mysqldump
|
||||
cmd := exec.Command("mysqldump", "-h", dbHost, "-P", dbPort, "-u", dbUserName, "--password="+dbPassword, dbName)
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
utils.Info("Mysql")
|
||||
|
||||
log.Fatal(err)
|
||||
}
|
||||
gzipCmd := exec.Command("gzip")
|
||||
@@ -86,7 +139,7 @@ func BackupDatabase(disableCompression bool) {
|
||||
if err := gzipCmd.Wait(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
utils.Info("Database has been backed up")
|
||||
utils.Done("Database has been backed up")
|
||||
|
||||
}
|
||||
|
||||
@@ -101,3 +154,9 @@ func BackupDatabase(disableCompression bool) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func s3Backup(disableCompression bool, s3Path string) {
|
||||
// Backup Database to S3 storage
|
||||
MountS3Storage(s3Path)
|
||||
BackupDatabase(disableCompression)
|
||||
}
|
||||
|
||||
@@ -3,19 +3,44 @@ package pkg
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jkaninda/mysql-bkup/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func StartRestore(cmd *cobra.Command) {
|
||||
|
||||
//Set env
|
||||
utils.SetEnv("STORAGE_PATH", storagePath)
|
||||
utils.GetEnv(cmd, "dbname", "DB_NAME")
|
||||
utils.GetEnv(cmd, "port", "DB_PORT")
|
||||
|
||||
//Get flag value and set env
|
||||
s3Path = utils.GetEnv(cmd, "path", "S3_PATH")
|
||||
storage = utils.GetEnv(cmd, "storage", "STORAGE")
|
||||
file = utils.GetEnv(cmd, "file", "FILE_NAME")
|
||||
executionMode, _ = cmd.Flags().GetString("mode")
|
||||
|
||||
if storage == "s3" {
|
||||
utils.Info("Restore database from s3")
|
||||
s3Restore(file, s3Path)
|
||||
} else {
|
||||
utils.Info("Restore database from local")
|
||||
RestoreDatabase(file)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// RestoreDatabase restore database
|
||||
func RestoreDatabase(file string) {
|
||||
dbHost = os.Getenv("DB_HOST")
|
||||
dbPassword = os.Getenv("DB_PASSWORD")
|
||||
dbUserName = os.Getenv("DB_USERNAME")
|
||||
dbName = os.Getenv("DB_NAME")
|
||||
dbPort = os.Getenv("DB_PORT")
|
||||
storagePath = os.Getenv("STORAGE_PATH")
|
||||
if file == "" {
|
||||
utils.Fatal("Error required --file")
|
||||
}
|
||||
|
||||
if os.Getenv("DB_HOST") == "" || os.Getenv("DB_NAME") == "" || os.Getenv("DB_USERNAME") == "" || os.Getenv("DB_PASSWORD") == "" || file == "" {
|
||||
utils.Fatal("Please make sure all required environment variables are set")
|
||||
@@ -25,7 +50,7 @@ func RestoreDatabase(file string) {
|
||||
utils.TestDatabaseConnection()
|
||||
|
||||
extension := filepath.Ext(fmt.Sprintf("%s/%s", storagePath, file))
|
||||
// GZ compressed file
|
||||
// Restore from compressed file / .sql.gz
|
||||
if extension == ".gz" {
|
||||
str := "zcat " + fmt.Sprintf("%s/%s", storagePath, file) + " | mysql -h " + os.Getenv("DB_HOST") + " -P " + os.Getenv("DB_PORT") + " -u " + os.Getenv("DB_USERNAME") + " --password=" + os.Getenv("DB_PASSWORD") + " " + os.Getenv("DB_NAME")
|
||||
_, err := exec.Command("bash", "-c", str).Output()
|
||||
@@ -33,17 +58,17 @@ func RestoreDatabase(file string) {
|
||||
utils.Fatal("Error, in restoring the database")
|
||||
}
|
||||
|
||||
utils.Info("Database has been restored")
|
||||
utils.Done("Database has been restored")
|
||||
|
||||
} else if extension == ".sql" {
|
||||
//SQL file
|
||||
//Restore from sql file
|
||||
str := "cat " + fmt.Sprintf("%s/%s", storagePath, file) + " | mysql -h " + os.Getenv("DB_HOST") + " -P " + os.Getenv("DB_PORT") + " -u " + os.Getenv("DB_USERNAME") + " --password=" + os.Getenv("DB_PASSWORD") + " " + os.Getenv("DB_NAME")
|
||||
_, err := exec.Command("bash", "-c", str).Output()
|
||||
if err != nil {
|
||||
utils.Fatal("Error, in restoring the database", err)
|
||||
}
|
||||
|
||||
utils.Info("Database has been restored")
|
||||
utils.Done("Database has been restored")
|
||||
} else {
|
||||
utils.Fatal("Unknown file extension ", extension)
|
||||
}
|
||||
@@ -54,3 +79,8 @@ func RestoreDatabase(file string) {
|
||||
|
||||
}
|
||||
}
|
||||
func s3Restore(file, s3Path string) {
|
||||
// Restore database from S3
|
||||
MountS3Storage(s3Path)
|
||||
RestoreDatabase(file)
|
||||
}
|
||||
|
||||
11
pkg/s3fs.go
11
pkg/s3fs.go
@@ -11,9 +11,6 @@ import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
const s3MountPath string = "/s3mnt"
|
||||
const s3fsPasswdFile string = "/etc/passwd-s3fs"
|
||||
|
||||
var (
|
||||
accessKey = ""
|
||||
secretKey = ""
|
||||
@@ -21,6 +18,10 @@ var (
|
||||
s3Endpoint = ""
|
||||
)
|
||||
|
||||
func S3Mount() {
|
||||
MountS3Storage(s3Path)
|
||||
}
|
||||
|
||||
// MountS3Storage Mount s3 storage using s3fs
|
||||
func MountS3Storage(s3Path string) {
|
||||
accessKey = os.Getenv("ACCESS_KEY")
|
||||
@@ -44,7 +45,9 @@ func MountS3Storage(s3Path string) {
|
||||
}
|
||||
//Change file permission
|
||||
utils.ChangePermission(s3fsPasswdFile, 0600)
|
||||
utils.Info("Mounting Object storage in", s3MountPath)
|
||||
|
||||
//Mount object storage
|
||||
utils.Info("Mounting Object storage in ", s3MountPath)
|
||||
if isEmpty, _ := utils.IsDirEmpty(s3MountPath); isEmpty {
|
||||
cmd := exec.Command("s3fs", bucketName, s3MountPath,
|
||||
"-o", "passwd_file="+s3fsPasswdFile,
|
||||
|
||||
@@ -30,12 +30,12 @@ func CreateCrontabScript(disableCompression bool, storage string) {
|
||||
if storage == "s3" {
|
||||
scriptContent = fmt.Sprintf(`#!/usr/bin/env bash
|
||||
set -e
|
||||
bkup --operation backup --dbname %s --port %s --storage s3 --path %s %v
|
||||
bkup backup --dbname %s --port %s --storage s3 --path %s %v
|
||||
`, os.Getenv("DB_NAME"), os.Getenv("DB_PORT"), os.Getenv("S3_PATH"), disableC)
|
||||
} else {
|
||||
scriptContent = fmt.Sprintf(`#!/usr/bin/env bash
|
||||
set -e
|
||||
bkup --operation backup --dbname %s --port %s %v
|
||||
bkup backup --dbname %s --port %s %v
|
||||
`, os.Getenv("DB_NAME"), os.Getenv("DB_PORT"), disableC)
|
||||
}
|
||||
|
||||
|
||||
16
pkg/var.go
Normal file
16
pkg/var.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package pkg
|
||||
|
||||
const s3MountPath string = "/s3mnt"
|
||||
const s3fsPasswdFile string = "/etc/passwd-s3fs"
|
||||
|
||||
var (
|
||||
storage = "local"
|
||||
file = ""
|
||||
s3Path = "/mysql-bkup"
|
||||
dbName = ""
|
||||
dbHost = ""
|
||||
dbPort = "3306"
|
||||
executionMode = "default"
|
||||
storagePath = "/backup"
|
||||
disableCompression = false
|
||||
)
|
||||
@@ -5,4 +5,4 @@ DB_HOST='db_hostname'
|
||||
DB_NAME='db_name'
|
||||
BACKUP_DIR="$PWD/backup"
|
||||
|
||||
docker run --rm --name mysql-bkup -v $BACKUP_DIR:/backup/ -e "DB_HOST=$DB_HOST" -e "DB_USERNAME=$DB_USERNAME" -e "DB_PASSWORD=$DB_PASSWORD" jkaninda/mysql-bkup:latest bkup -o backup -d $DB_NAME
|
||||
docker run --rm --name mysql-bkup -v $BACKUP_DIR:/backup/ -e "DB_HOST=$DB_HOST" -e "DB_USERNAME=$DB_USERNAME" -e "DB_PASSWORD=$DB_PASSWORD" jkaninda/mysql-bkup:latest backup -d $DB_NAME
|
||||
16
utils/constant.go
Normal file
16
utils/constant.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package utils
|
||||
|
||||
const Notice = "Please remove --operation flag.\n" +
|
||||
"Use: \n" +
|
||||
"- backup for database backup operation [eg: bkup backup -d database_name ...]\n" +
|
||||
"- restore for database restore operation [eg. bkup restore -d database_name ...]\n" +
|
||||
"Example: bkup backup --storage s3 ...( instead of < bkup --operation backup >)\n" +
|
||||
"We are sorry for this inconvenient\n"
|
||||
const RestoreExample = "mysql-bkup restore --dbname database --file db_20231219_022941.sql.gz\n" +
|
||||
"bkup restore --dbname database --storage s3 --path /custom-path --file db_20231219_022941.sql.gz"
|
||||
const BackupExample = "mysql-bkup backup --dbname database --disable-compression\n" +
|
||||
"mysql-bkup backup --dbname database --storage s3 --path /custom-path --disable-compression"
|
||||
|
||||
const MainExample = "mysql-bkup backup --dbname database --disable-compression\n" +
|
||||
"mysql-bkup backup --dbname database --storage s3 --path /custom-path\n" +
|
||||
"mysql-bkup restore --dbname database --file db_20231219_022941.sql.gz"
|
||||
@@ -8,29 +8,24 @@ package utils
|
||||
**/
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func Info(v ...any) {
|
||||
fmt.Println("[INFO] ", fmt.Sprint(v...))
|
||||
fmt.Println("⒤ ", fmt.Sprint(v...))
|
||||
}
|
||||
func Infof(msg string, v ...any) {
|
||||
fmt.Printf("[INFO] "+msg, v...)
|
||||
}
|
||||
func Warning(message string) {
|
||||
fmt.Println("[WARNING]", message)
|
||||
}
|
||||
func Warningf(msg string, v ...any) {
|
||||
fmt.Printf("[WARNING] "+msg, v...)
|
||||
func Done(v ...any) {
|
||||
fmt.Println("✔ ", fmt.Sprint(v...))
|
||||
}
|
||||
func Fatal(v ...any) {
|
||||
fmt.Println("[ERROR] ", fmt.Sprint(v...))
|
||||
fmt.Println("✘ ", fmt.Sprint(v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
func Fatalf(msg string, v ...any) {
|
||||
fmt.Printf("[ERROR] "+msg, v...)
|
||||
fmt.Printf("✘ "+msg, v...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -84,3 +79,36 @@ func TestDatabaseConnection() {
|
||||
}
|
||||
|
||||
}
|
||||
func GetEnv(cmd *cobra.Command, flagName, envName string) string {
|
||||
value, _ := cmd.Flags().GetString(flagName)
|
||||
if value != "" {
|
||||
err := os.Setenv(envName, value)
|
||||
if err != nil {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return os.Getenv(envName)
|
||||
}
|
||||
func FlagGetString(cmd *cobra.Command, flagName string) string {
|
||||
value, _ := cmd.Flags().GetString(flagName)
|
||||
if value != "" {
|
||||
return value
|
||||
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func FlagGetBool(cmd *cobra.Command, flagName string) bool {
|
||||
value, _ := cmd.Flags().GetBool(flagName)
|
||||
return value
|
||||
}
|
||||
|
||||
func SetEnv(key, value string) {
|
||||
|
||||
err := os.Setenv(key, value)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func ShowHistory() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user