实时刷新配置文件例子,不多说 直接上代码
dir
➜ test tree
.
├── app
│ ├── de.tmpl.go
│ └── demo.tmpl
├── linesearch.go
├── linked.go
├── snowflake.go
└── template.go
1 directory, 6 files
configfile
# [member]
ETCD_NAME="$hostname"
ETCD_DATA_DIR="/work/etcd"
ETCD_LISTEN_PEER_URLS="http://k8s_master_ip:2380"
ETCD_LISTEN_CLIENT_URLS="http://$hostip,http://k8s_master_ip:2379"
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://k8s_master_ip:2380"
ETCD_INITIAL_CLUSTER="k8s_master_ip_name=http://k8s_master_ip:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://$hostip:2379"
{{$PeerCount:=.PeerCount}}
ETCD_INITIAL_CLUSTER="{{range $index,$ele:=.Peers}}{{if eq $index $PeerCount }}{{.Hostname}}=http://{{.Hostname}}:2380{{else}}{{.Hostname}}=http://{{.Hostname}}:2380,{{end}}{{end}}"
{{range $index,$ele:=.Peers}}
server.{{$index}}={{.Hostname}}:2888:3888
{{end}}
#$all server-0,server-1,server-2,server-3
golang code
package main
import (
"fmt"
"os"
"net"
"text/template"
"strings"
"io/ioutil"
"encoding/hex"
"crypto/md5"
"time"
"io"
)
func main() {
t := time.NewTicker(10 * time.Second)
fmt.Printf("server start time ================> %s \n",time.Now())
for {
select {
case <-t.C:
fmt.Printf("begin time ================> %s\n",time.Now())
run()
fmt.Printf("end time ================> %s\n",time.Now())
//default:
// fmt.Println("this is demo")
}
}
}
//hostip hostname peer all
var OldMd5Sum string
type Peer struct {
Hostname string
}
type TemplateData struct {
Peers []Peer
PeerCount int
Hostname string
HostIp string
}
func run() {
filePath := os.Getenv("FILE_PATH")
if filePath == "" {
filePath = "app/demo.tmpl"
}
var templateData TemplateData
configData := ""
//check the file if exist
ok, err := FileExists(filePath)
if err != nil {
fmt.Printf("the file is not exist %#v\n", err)
return
}
//the file exist
if ok {
yes, err := Md5SumFile(filePath)
if err == nil && !yes {
filedata, err := ReadFile(filePath)
if err != nil {
fmt.Println("\n", err)
return
}
configData = filedata
} else {
fmt.Printf("the file is not change or read file failed %#v\n", err)
return
}
ALL := ""
if configData != "" {
if strings.Contains(configData, "$all") {
ALL = strings.Split(configData, "$all")[1]
serverlist := strings.Split(strings.Replace(ALL, " ", "", -1), ",")
serverLen := len(serverlist)
templateData.PeerCount = serverLen - 1
templateData.Peers = make([]Peer, 0)
var peer Peer
for _, server := range serverlist {
peer.Hostname = server
templateData.Peers = append(templateData.Peers, peer)
}
} else {
fmt.Printf(" No $all parameter\n")
return
}
if strings.Contains(configData, "$hostname") {
configData = strings.Replace(configData, "$hostname", "{{.Hostname}}", -1)
}
if strings.Contains(configData, "$hostip") {
configData = strings.Replace(configData, "$hostip", "{{.HostIp}}", -1)
}
}
fmt.Printf("configData=======================\n%s\n", configData)
hostname, err := os.Hostname()
if err != nil {
fmt.Printf("get hostname failed \n", err)
return
}
templateData.Hostname = hostname
ns, err := net.LookupHost("www.baidu.cn")
if err != nil {
fmt.Fprintf(os.Stderr, "Err: %s", err.Error())
return
}
for _, n := range ns {
fmt.Fprintf(os.Stdout, "%s\n", n)
templateData.HostIp = n
}
tpl, err := template.New("demo").Parse(configData)
if err != nil {
fmt.Printf("%s ", err)
return
}
file, err := os.OpenFile("app/de.tmpl.go", os.O_RDWR, 0777)
if err != nil {
fmt.Printf("OpenFile failed %#v\n", err)
return
}
defer file.Close()
err = tpl.Execute(file, templateData)
if err != nil {
panic(err)
return
}
} else {
fmt.Printf("the file %s not exist or read the file %s failed \n ", filePath, filePath)
return
}
}
//判断文件是否存在
func FileExists(filepath string) (bool, error) {
_, err := os.Stat(filepath)
if err == nil {
return true, nil
}
return false, err
}
func ReadFile(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
fmt.Printf("Open file failed %#v\n", err)
return "", err
}
defer file.Close()
fileData, err := ioutil.ReadAll(file)
if err != nil {
fmt.Printf("ReadAll file failed %#v\n", err)
return string(fileData), err
}
return string(fileData), nil
}
func Md5SumFile(filePath string) (bool, error) {
file, err := os.Open(filePath)
if err != nil {
fmt.Printf("Open file failed %#v\n", err)
return false, err
}
md5hash := md5.New()
_, err = io.Copy(md5hash, file)
if err != nil {
fmt.Printf("io.Copy file failed %#v\n", err)
return false, err
}
strSum := md5hash.Sum(nil)
resMd5 := hex.EncodeToString(strSum)
if OldMd5Sum != "" && resMd5 == OldMd5Sum {
return true, nil
}
defer file.Close()
OldMd5Sum = resMd5
return false, nil
}
result
# [member]
ETCD_NAME="xinzhiyundeMacBook-Pro.local"
ETCD_DATA_DIR="/work/etcd"
ETCD_LISTEN_PEER_URLS="http://k8s_master_ip:2380"
ETCD_LISTEN_CLIENT_URLS="http://119.75.213.61,http://k8s_master_ip:2379"
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://k8s_master_ip:2380"
ETCD_INITIAL_CLUSTER="k8s_master_ip_name=http://k8s_master_ip:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://119.75.213.61:2379"
ETCD_INITIAL_CLUSTER="server-0=http://server-0:2380,server-1=http://server-1:2380,server-2=http://server-2:2380,server-3=http://server-3:2380"
server.0=server-0:2888:3888
server.1=server-1:2888:3888
server.2=server-2:2888:3888
server.3=server-3:2888:3888
#$all server-0,server-1,server-2,server-3-3