github.com/greenboxal/deis@v1.12.1/swarm/swarm.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "log" 9 "net/http" 10 "net/url" 11 "os" 12 "os/exec" 13 "strings" 14 "text/template" 15 "time" 16 17 "github.com/coreos/go-etcd/etcd" 18 "github.com/deis/deis/tests/utils" 19 ) 20 21 // EtcdCluster information about the nodes in the etcd cluster 22 type EtcdCluster struct { 23 Members []etcd.Member `json:"members"` 24 } 25 26 // NodeStat information about the local node in etcd 27 type NodeStats struct { 28 LeaderInfo struct { 29 Name string `json:"leader"` 30 Uptime string `json:"uptime"` 31 StartTime time.Time `json:"startTime"` 32 } `json:"leaderInfo"` 33 } 34 35 const ( 36 swarmpath = "/deis/scheduler/swarm/node" 37 swarmetcd = "/deis/scheduler/swarm/host" 38 etcdport = "4001" 39 timeout time.Duration = 3 * time.Second 40 ttl time.Duration = timeout * 2 41 ) 42 43 func run(cmd string) { 44 var cmdBuf bytes.Buffer 45 tmpl := template.Must(template.New("cmd").Parse(cmd)) 46 if err := tmpl.Execute(&cmdBuf, nil); err != nil { 47 log.Fatal(err) 48 } 49 cmdString := cmdBuf.String() 50 fmt.Println(cmdString) 51 var cmdl *exec.Cmd 52 cmdl = exec.Command("sh", "-c", cmdString) 53 if _, _, err := utils.RunCommandWithStdoutStderr(cmdl); err != nil { 54 log.Fatal(err) 55 } else { 56 fmt.Println("ok") 57 } 58 } 59 60 func getleaderHost() string { 61 var nodeStats NodeStats 62 client := &http.Client{} 63 resp, _ := client.Get("http://" + os.Getenv("HOST") + ":2379/v2/stats/self") 64 65 body, _ := ioutil.ReadAll(resp.Body) 66 json.Unmarshal(body, &nodeStats) 67 68 etcdLeaderID := nodeStats.LeaderInfo.Name 69 70 var etcdCluster EtcdCluster 71 resp, _ = client.Get("http://" + os.Getenv("HOST") + ":2379/v2/members") 72 defer resp.Body.Close() 73 74 body, _ = ioutil.ReadAll(resp.Body) 75 json.Unmarshal(body, &etcdCluster) 76 77 for _, node := range etcdCluster.Members { 78 if node.ID == etcdLeaderID { 79 u, err := url.Parse(node.ClientURLs[0]) 80 if err == nil { 81 return u.Host 82 } 83 } 84 } 85 86 return "" 87 } 88 89 func publishService(client *etcd.Client, host string, ttl uint64) { 90 for { 91 setEtcd(client, swarmetcd, host, ttl) 92 time.Sleep(timeout) 93 } 94 } 95 96 func setEtcd(client *etcd.Client, key, value string, ttl uint64) { 97 _, err := client.Set(key, value, ttl) 98 if err != nil && !strings.Contains(err.Error(), "Key already exists") { 99 log.Println(err) 100 } 101 } 102 103 func main() { 104 etcdproto := "etcd://" + getleaderHost() + swarmpath 105 etcdhost := os.Getenv("HOST") 106 addr := "--addr=" + etcdhost + ":2375" 107 client := etcd.NewClient([]string{"http://" + etcdhost + ":" + etcdport}) 108 switch os.Args[1] { 109 case "join": 110 run("./deis-swarm join " + addr + " " + etcdproto) 111 case "manage": 112 go publishService(client, etcdhost, uint64(ttl.Seconds())) 113 run("./deis-swarm manage " + etcdproto) 114 } 115 }