概要
このブログのDBバックアップを原始人のごとく手動でやっていたのでコマンド一発でバックアップをリモートからローカルにバックアップを取れるツールをgoでつくってみた。
パッケージ
- "net"
- ネットワークI/O、TCP/IP、UDP、ドメイン名前解決、Unixドメインソケットなどのインターフェースを提供してくれるやつ
- "time"
- 時間の計算や表示のための機能を提供してくれるやつ
- "io/ioutil"
- ファイル周りのI/Oユーティリティを提供してくれるやつ
- "golang.org/x/crypto/ssh"
- sshのクライアント・サーバーの実装を提供してくれるやつ
- "github.com/BurntSushi/toml"
- TOMLパーサー
- goのjsonやxmlといったパーサーの標準ライブラリライクに作られているらしい
- 焦げた寿司さん
実装
ざっくり動く形まで実装してみた。Goに不慣れなので愚直な感じになっている。。。 あとテストがかけていない。
package main
import (
"net"
"time"
"io/ioutil"
"golang.org/x/crypto/ssh"
"github.com/BurntSushi/toml"
)
type Config struct {
SSH SSH
Mysql Mysql
}
type SSH struct {
IP string
Port string
User string
IdentityFile string
}
type Mysql struct {
MysqlConf string
Database string
DumpDir string
DumpFilePrefix string
}
func dump() {
var config Config
if _, err := toml.DecodeFile("config.toml", &config); err != nil {
panic(err)
}
buf, err := ioutil.ReadFile(config.SSH.IdentityFile)
if err != nil {
panic(err)
}
key, err := ssh.ParsePrivateKey(buf)
if err != nil {
panic(err)
}
conn, err := ssh.Dial("tcp", config.SSH.IP+":"+config.SSH.Port, &ssh.ClientConfig{
User: config.SSH.User,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(key),
},
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
})
if err != nil {
panic(err)
}
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
panic(err)
}
defer session.Close()
byte, err := session.Output("sudo mysqldump --defaults-file="+config.Mysql.MysqlConf+" "+config.Mysql.Database+" "+"--quick --single-transaction")
if err != nil {
panic(err)
}
ioutil.WriteFile(config.Mysql.DumpDir+config.Mysql.DumpFilePrefix+time.Now().Format("2006-01-02")+".sql", byte, 0644)
}
func main() {
dump()
}
github
置いといた。
所感
とりあえずgoの色んな実装をみて知見を貯めていく...
参考
- GoDoc - package mysql
- GoDoc - package ssh
- Golang.org - Package net
- Golang.org - Package time
- Golang.org - Package ioutil
golang.jp - netパッケージ- Go言語で認証鍵を使ってSSHの接続を行う
github.com - siddontang/go-mysql- Mysqldump Through a HTTP Request with Golang