-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from micro-in-cn/agent
Agent
- Loading branch information
Showing
18 changed files
with
661 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,3 +14,4 @@ | |
.idea/ | ||
|
||
deployments/docker-compose/.env | ||
agent/config.json* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
|
||
run: | ||
go run main.go | ||
go run main.go -u http://xconf.mogutou.xyz -a test -c dev -d /tmp/xconf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/micro-in-cn/XConf/agent/file" | ||
"github.com/micro-in-cn/XConf/agent/source" | ||
"github.com/micro/go-micro/util/log" | ||
) | ||
|
||
var ErrStopped = errors.New("config file stopped") | ||
|
||
type Config struct { | ||
file file.ConfigFile | ||
source source.Source | ||
watcher source.Watcher | ||
exit chan interface{} | ||
name string | ||
} | ||
|
||
func New(filePatch string, url, appName, clusterName, namespaceName, format string) *Config { | ||
return &Config{ | ||
file: file.New(filePatch), | ||
source: source.New(url, appName, clusterName, namespaceName), | ||
exit: make(chan interface{}), | ||
name: fmt.Sprintf("host:%s app:%s cluster:%s namespace:%s.%s", url, appName, clusterName, namespaceName, format), | ||
} | ||
} | ||
|
||
func (s *Config) Init() error { | ||
b, err := s.source.Read() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err := s.file.Update(b); err != nil { | ||
return err | ||
} | ||
|
||
s.watcher, err = s.source.Watch() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (s *Config) Sync() (err error) { | ||
if s.watcher == nil { | ||
return errors.New("Init function is not called ") | ||
} | ||
|
||
log.Info("Start watch ", s.name) | ||
for { | ||
select { | ||
case <-s.exit: | ||
return ErrStopped | ||
default: | ||
nb, err := s.watcher.Next() | ||
if err != nil { | ||
if err == source.ErrWatcherStopped { | ||
return ErrStopped | ||
} | ||
|
||
log.Error("watch:", err) | ||
continue | ||
} | ||
|
||
//log.Info("watch:\n", string(nb)) | ||
if err := s.file.Update(nb); err != nil { | ||
log.Error("update:", err) | ||
continue | ||
} | ||
} | ||
} | ||
} | ||
|
||
func (s *Config) Stop() { | ||
select { | ||
case <-s.exit: | ||
default: | ||
_ = s.watcher.Stop() | ||
close(s.exit) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package file | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/micro/go-micro/util/log" | ||
) | ||
|
||
type ConfigFile interface { | ||
Update(content []byte) error | ||
Read() ([]byte, error) | ||
} | ||
|
||
type configFile struct { | ||
filePath string | ||
} | ||
|
||
func New(filePatch string) ConfigFile { | ||
return &configFile{ | ||
filePath: filePatch, | ||
} | ||
} | ||
|
||
func (c *configFile) Update(content []byte) error { | ||
if err := os.MkdirAll(filepath.Dir(c.filePath), 0755); err != nil { | ||
return err | ||
} | ||
// create backup file | ||
exist, err := ExistFile(c.filePath) | ||
if err != nil { | ||
return err | ||
} | ||
if exist { | ||
if err := CopyFile(c.filePath, fmt.Sprintf("%s_backup", c.filePath)); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
tmpFile := fmt.Sprintf("%s_tmp", c.filePath) | ||
if err := ioutil.WriteFile(tmpFile, content, 0755); err != nil { | ||
log.Error("write file error:", err) | ||
return err | ||
} | ||
|
||
if err := os.Rename(tmpFile, c.filePath); err != nil { | ||
log.Error("rename file error:", err) | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *configFile) Read() ([]byte, error) { | ||
return ioutil.ReadFile(c.filePath) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package file | ||
|
||
import ( | ||
"bytes" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestConfigFile(t *testing.T) { | ||
file := New("/tmp/test.conf") | ||
|
||
content := []byte(strings.Repeat("hello xconf agent\n", 512)) | ||
if err := file.Update(content); err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
b, err := file.Read() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if !bytes.Equal(content, b) { | ||
t.Fatal() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package file | ||
|
||
import ( | ||
"io" | ||
"os" | ||
) | ||
|
||
func CopyFile(source string, dest string) error { | ||
src, err := os.Open(source) | ||
if err != nil { | ||
return err | ||
} | ||
defer src.Close() | ||
|
||
dst, err := os.Create(dest) | ||
if err != nil { | ||
return err | ||
} | ||
defer dst.Close() | ||
|
||
_, err = io.Copy(dst, src) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
info, err := os.Stat(source) | ||
if err != nil { | ||
err = os.Chmod(dest, info.Mode()) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func DeleteFile(file string) error { | ||
return os.Remove(file) | ||
} | ||
|
||
func ExistFile(file string) (bool, error) { | ||
_, err := os.Stat(file) | ||
if err == nil { | ||
return true, nil | ||
} | ||
if os.IsNotExist(err) { | ||
return false, nil | ||
} | ||
return false, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,85 @@ | ||
package main | ||
|
||
import "fmt" | ||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/micro-in-cn/XConf/agent/server" | ||
"github.com/micro/cli" | ||
) | ||
|
||
func main() { | ||
fmt.Println("Hello XConf agent") | ||
var ( | ||
baseURL string | ||
appName string | ||
clusterName string | ||
dir string | ||
) | ||
|
||
app := cli.NewApp() | ||
app.Name = "agent" | ||
app.Usage = "XConf agent client" | ||
app.Version = "0.0.1" | ||
|
||
app.Flags = []cli.Flag{ | ||
cli.StringFlag{ | ||
Name: "url, u", | ||
Value: "127.0.0.1:8080", | ||
Usage: "base url", | ||
EnvVar: "XCONF_BASE_URL", | ||
Destination: &baseURL, | ||
}, | ||
cli.StringFlag{ | ||
Name: "app, a", | ||
Value: "", | ||
Usage: "app name", | ||
EnvVar: "XCONF_APP_NAME", | ||
Destination: &appName, | ||
}, | ||
cli.StringFlag{ | ||
Name: "cluster, c", | ||
Value: "", | ||
Usage: "cluster name", | ||
EnvVar: "XCONF_CLUSTER_NAME", | ||
Destination: &clusterName, | ||
}, | ||
cli.StringFlag{ | ||
Name: "dir, d", | ||
Value: "/tmp", | ||
Usage: "directory", | ||
EnvVar: "XCONF_DIR", | ||
Destination: &dir, | ||
}, | ||
} | ||
|
||
app.Action = func(c *cli.Context) error { | ||
if len(baseURL) <= 0 { | ||
return errors.New("base url cannot be empty") | ||
} | ||
if len(appName) <= 0 { | ||
return errors.New("app name cannot be empty") | ||
} | ||
if len(clusterName) <= 0 { | ||
return errors.New("cluster name cannot be empty") | ||
} | ||
if len(dir) <= 0 { | ||
return errors.New("dir path cannot be empty") | ||
} | ||
return nil | ||
} | ||
|
||
if err := app.Run(os.Args); err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
s := server.New(dir, baseURL, appName, clusterName) | ||
if err := s.Init(); err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
fmt.Println(s.Dir(), s.HostURL(), s.AppName(), s.ClusterName()) | ||
s.Run() | ||
} |
Oops, something went wrong.