Skip to content

Commit

Permalink
Add synapse to configureNerve command
Browse files Browse the repository at this point in the history
  • Loading branch information
mcoffin committed Jan 20, 2016
1 parent 6e5f13b commit 992aa3b
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 38 deletions.
21 changes: 14 additions & 7 deletions example-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ patterns:
task: chronos
port_index: 0
service_port: 31004
check_interval: 2
checks:
- type: http
uri: /
timeout: 0.2
rise: 3
fall: 2
nerve:
check_interval: 2
checks:
- type: http
uri: /
timeout: 0.2
rise: 3
fall: 2
synapse:
haproxy:
server_options: check inter 2s rise 3 fall 2
listen:
- mode http
- option httpchk /
115 changes: 93 additions & 22 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"flag"
"fmt"
"github.com/FlukeNetworks/apheleia/nerve"
"github.com/FlukeNetworks/apheleia/synapse"
"github.com/samuel/go-zookeeper/zk"
yaml "gopkg.in/yaml.v2"
"io"
Expand All @@ -20,15 +21,30 @@ import (

const ChecksumSize = md5.Size

func createSynapseService(svc Service, zkHosts []string, zkPath string) synapse.Service {
ssvc := svc.Synapse
if len(ssvc.DefaultServers) < 1 {
ssvc.DefaultServers = []synapse.Server{}
}
ssvc.Discovery = synapse.Discovery{
Method: "zookeeper",
Path: zkPath + svc.GetNodePath(),
Hosts: zkHosts,
}
log.Printf("Setting synapse service port to %d\n", svc.ServicePort)
ssvc.HAProxy.Port = svc.ServicePort
return ssvc
}

func createNerveService(svc Service, task taskState, zkHosts []string, zkPath, slaveHost string) nerve.Service {
return nerve.Service{
Host: slaveHost,
Port: task.getPort(svc.PortIndex),
ReporterType: "zookeeper",
ZkHosts: zkHosts,
ZkPath: zkPath + "/" + svc.Name,
CheckInterval: svc.CheckInterval,
Checks: svc.Checks,
ZkPath: zkPath + svc.GetNodePath(),
CheckInterval: svc.Nerve.CheckInterval,
Checks: svc.Nerve.Checks,
}
}

Expand Down Expand Up @@ -71,7 +87,22 @@ func filesDiffer(first, second string) (bool, error) {
return (firstSum != secondSum), nil
}

func configureNerve(zkHosts []string, zkPath, slave, nerveCfg *string, _ []string) {
func writeJsonFile(file string, data interface{}) error {
outputFile, err := os.Create(file)
if err != nil {
return err
}

encoder := json.NewEncoder(outputFile)
if err = encoder.Encode(data); err != nil {
outputFile.Close()
return err
}

return outputFile.Close()
}

func configureNerve(zkHosts []string, zkPath, slave, nerveCfg, synapseCfg *string, _ []string) {
slaveState, err := getSlaveState(*slave)
if err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -110,44 +141,82 @@ func configureNerve(zkHosts []string, zkPath, slave, nerveCfg *string, _ []strin
Services: nerveServices,
}

// Copy the current config to a .old file
oldNerveCfg := *nerveCfg + ".old"
if err := copyFile(oldNerveCfg, *nerveCfg); err != nil {
log.Fatal(err)
synapseServices := make(map[string]synapse.Service)
for _, svc := range node.Services {
synapseServices[svc.Name] = createSynapseService(svc, zkHosts, *zkPath)
}

// Write the new nerve config
func() {
outputFile, err := os.Create(*nerveCfg)
// Read in the old synapse config
synapseConfig := func() synapse.Config {
synapseConfigFile, err := os.Open(*synapseCfg)
if err != nil {
log.Fatal(err)
}
defer outputFile.Close()
defer synapseConfigFile.Close()

encoder := json.NewEncoder(outputFile)
if err = encoder.Encode(&nerveConfig); err != nil {
var synapseConfig synapse.Config
decoder := json.NewDecoder(synapseConfigFile)
if err := decoder.Decode(&synapseConfig); err != nil {
log.Fatal(err)
}
return synapseConfig
}()
synapseConfig["services"] = synapseServices

// If the files differ, we need to restart nerve
// Copy the current config to a .old file
oldNerveCfg := *nerveCfg + ".old"
if err := copyFile(oldNerveCfg, *nerveCfg); err != nil {
log.Fatal(err)
}
oldSynapseCfg := *synapseCfg + ".old"
if err := copyFile(oldSynapseCfg, *synapseCfg); err != nil {
log.Fatal(err)
}

// Write the new config
if err := writeJsonFile(*nerveCfg, &nerveConfig); err != nil {
log.Fatal(err)
}
if err := writeJsonFile(*synapseCfg, synapseConfig); err != nil {
log.Fatal(err)
}

// If the nerve files differ, we need to restart nerve
shouldRestart, err := filesDiffer(*nerveCfg, oldNerveCfg)
if err != nil {
log.Fatal(err)
}
if shouldRestart {
nerveRestartCommand := os.Getenv("APHELEIA_NERVE_RESTART_CMD")
cmd := exec.Command("bash", "-c", nerveRestartCommand)
if err := cmd.Start(); err != nil {
if err := performRestart("NERVE"); err != nil {
log.Fatal(err)
}
if err := cmd.Wait(); err != nil {
}

// If the synapse files differ, we need to restart synapse
shouldRestart, err = filesDiffer(*synapseCfg, oldSynapseCfg)
if err != nil {
log.Fatal(err)
}
if shouldRestart {
if err := performRestart("SYNAPSE"); err != nil {
log.Fatal(err)
}
}
}

func updateZk(zkHosts []string, zkPath, slave, _ *string, serviceFiles []string) {
func performRestart(serviceName string) error {
restartCommand := os.Getenv(fmt.Sprintf("APHELEIA_%s_RESTART_CMD", serviceName))
cmd := exec.Command("bash", "-c", restartCommand)
if err := cmd.Start(); err != nil {
return err
}
if err := cmd.Wait(); err != nil {
return err
}
return nil
}

func updateZk(zkHosts []string, zkPath, slave, _, _ *string, serviceFiles []string) {
services := make([]Service, 0)
for _, serviceFile := range serviceFiles {
fileBytes, err := ioutil.ReadFile(serviceFile)
Expand All @@ -159,6 +228,7 @@ func updateZk(zkHosts []string, zkPath, slave, _ *string, serviceFiles []string)
if err = yaml.Unmarshal(fileBytes, &svc); err != nil {
log.Fatal(err)
}
log.Printf("%s should be running on %d\n", svc.Name, svc.ServicePort)
services = append(services, svc)
}

Expand Down Expand Up @@ -196,6 +266,7 @@ func main() {
zkPath := flag.String("zkPath", "/apheleia", "zookeeper path for this service keyspace")
slave := flag.String("slave", "http://localhost:5051", "base URI for mesos slave API")
nerveCfg := flag.String("nerveCfg", "nerve.conf.json", "output location for nerve config")
synapseCfg := flag.String("synapseCfg", "synapse.conf.json", "output location for synapse config")
flag.Parse()
zkHosts := strings.Split(*zkArg, ",")

Expand All @@ -208,9 +279,9 @@ func main() {

switch command {
case "configureNerve":
configureNerve(zkHosts, zkPath, slave, nerveCfg, commandArgs)
configureNerve(zkHosts, zkPath, slave, nerveCfg, synapseCfg, commandArgs)
case "updateZk":
updateZk(zkHosts, zkPath, slave, nerveCfg, commandArgs)
updateZk(zkHosts, zkPath, slave, nerveCfg, synapseCfg, commandArgs)
default:
log.Fatal(fmt.Errorf("Unknown command: %s", command))
}
Expand Down
10 changes: 5 additions & 5 deletions nerve/service.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package nerve

type Config struct {
InstanceId string `json:"instance_id"`
InstanceId string `json:"instance_id" yaml"instance_id"`
Services []Service `json:"services"`
}

type Service struct {
Host string `json:"host"`
Port int `json:"port"`
ReporterType string `json:"reporter_type"`
ZkHosts []string `json:"zk_hosts"`
ZkPath string `json:"zk_path"`
CheckInterval int `json:"check_interval"`
ReporterType string `json:"reporter_type" yaml:"reporter_type"`
ZkHosts []string `json:"zk_hosts" yaml:"zk_hosts"`
ZkPath string `json:"zk_path" yaml:"zk_path"`
CheckInterval int `json:"check_interval" yaml:"check_interval"`
Checks []map[string]interface{} `json:"checks"`
}
17 changes: 13 additions & 4 deletions service.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package main

import (
"github.com/FlukeNetworks/apheleia/nerve"
"github.com/FlukeNetworks/apheleia/synapse"
)

type ApheleiaNode struct {
Services []Service `json:"services"`
}

type Service struct {
Name string `json:"name"`
Patterns ServicePatterns `json:"patterns"`
PortIndex int `json:"port_index"`
ServicePort int `json:"service_port"`
CheckInterval int `json:"check_interval"`
Checks []map[string]interface{} `json:"checks"`
PortIndex int `json:"port_index" yaml:"port_index"`
ServicePort int `json:"service_port" yaml:"service_port"`
Nerve nerve.Service `json:"nerve"`
Synapse synapse.Service `json:"synapse"`
}

func (s *Service) GetNodePath() string {
return "/" + s.Name
}

type ServicePatterns struct {
Expand Down
27 changes: 27 additions & 0 deletions synapse/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package synapse

type Config map[string]interface{}

type Service struct {
DefaultServers []Server `json:"default_servers" yaml:"default_servers"`
Discovery Discovery `json:"discovery"`
HAProxy HAProxyInfo `json:"haproxy" yaml:"haproxy"`
}

type Server struct {
Name string `json:"name"`
Host string `json:"host"`
Port int `json:"port"`
}

type Discovery struct {
Method string `json:"method"`
Path string `json:"path"`
Hosts []string `json:"hosts"`
}

type HAProxyInfo struct {
Port int `json:"port"`
ServerOptions string `json:"server_options" yaml:"server_options"`
Listen []string `json:"listen"`
}

0 comments on commit 992aa3b

Please sign in to comment.