不知道大家在日常工作中有没有遇到如下场景,有多个环境,其中的数据库更新需要我们到每个环境上去更新,我们就是有这样的场景,数据库docker部署的,DBA感觉特别麻烦,所以我们来撸一个相关的工具。
首先我们先要定义配置文件格式,方面的到服务器中执行命令
[
{
"name": "postgres",
"host": "10.255.175.229",
"password": "test123",
"database": "test",
"port": 22
},
{
"name": "postgres",
"host": "10.255.175.230",
"password": "test123",
"database": "test",
"port": 22
}
]
其中name是我们的容器名
然后就要选定我们的编程语言了,我这里是用的是go, 废话少说,直接放代码
package main
import (
"bufio"
"encoding/json"
"fmt"
"golang.org/x/crypto/ssh"
"log"
"os"
"strconv"
)
type Config struct {
Name string `json:"name"`
Host string `json:"host"`
Password string `json:"password"`
Database string `json:"database"`
Port int `json:"port"`
}
func getConfig() []Config {
// 读取JSON文件
data, err := os.ReadFile("config.json")
if err != nil {
log.Fatal("无法读取配置文件:", err)
}
// 解析JSON数据
var configs []Config
err = json.Unmarshal(data, &configs)
if err != nil {
log.Fatal("无法解析配置文件:", err)
}
return configs
}
func main() {
sql, err := os.ReadFile("./update.sql")
if err != nil {
log.Fatal(err)
}
configs := getConfig()
for _, c := range configs {
// SSH连接的配置信息
config := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
ssh.Password(c.Password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// 建立SSH连接
client, err := ssh.Dial("tcp", c.Host+":"+strconv.Itoa(c.Port), config)
if err != nil {
log.Fatalf("拨号失败: %v", err)
}
defer client.Close()
// 创建一个新的会话
session, err := client.NewSession()
if err != nil {
log.Fatalf("创建会话失败: %v", err)
}
defer session.Close()
command := "docker exec -i " + c.Name + " psql -U postgres -d " + c.Database + " << EOF \n" + string(sql) + "\nEOF"
// 执行命令并获取输出
output, err := session.Output(command)
if err != nil {
log.Fatalf("不能够执行命令: %v", err)
}
// 输出命令执行结果
fmt.Println("[" + c.Host + "]: " + string(output))
}
fmt.Println("执行完毕,输入任意字符以退出:")
reader := bufio.NewReader(os.Stdin)
for {
_, err := reader.ReadString('\n')
if err != nil {
fmt.Println("读取输入时发生错误:", err)
os.Exit(1)
}
fmt.Println("程序已退出")
os.Exit(0)
}
}
在当前目录创建一个update.sql,把需要更新的sql粘贴进去即可。
编译为windows可执行程序
export GOOS=windows
export GOARCH=amd64
go build -o db_update.exe db_update.go
以上的代码简单易懂,我觉得没有必要解释,如果有疑问请在评论区留言。
ps: 作为一个go语言新手,写的不太好,不喜勿喷,但欢迎指正!