github.com/rvaralda/deis@v1.4.1/cache/main.go (about)

     1  package main
     2  
     3  import (
     4  	"io/ioutil"
     5  	"log"
     6  	"net"
     7  	"os"
     8  	"os/exec"
     9  	"os/signal"
    10  	"strings"
    11  	"syscall"
    12  	"time"
    13  
    14  	"github.com/coreos/go-etcd/etcd"
    15  )
    16  
    17  const (
    18  	timeout         time.Duration = 10 * time.Second
    19  	ttl             time.Duration = timeout * 2
    20  	redisWait       time.Duration = 5 * time.Second
    21  	redisConf       string        = "/app/redis.conf"
    22  	ectdKeyNotFound int           = 100
    23  	defaultMemory   string        = "50mb"
    24  )
    25  
    26  func main() {
    27  	host := getopt("HOST", "127.0.0.1")
    28  
    29  	etcdPort := getopt("ETCD_PORT", "4001")
    30  	etcdPath := getopt("ETCD_PATH", "/deis/cache")
    31  
    32  	externalPort := getopt("EXTERNAL_PORT", "6379")
    33  
    34  	client := etcd.NewClient([]string{"http://" + host + ":" + etcdPort})
    35  
    36  	var maxmemory string
    37  	result, err := client.Get("/deis/cache/maxmemory", false, false)
    38  	if err != nil {
    39  		if e, ok := err.(*etcd.EtcdError); ok && e.ErrorCode == ectdKeyNotFound {
    40  			maxmemory = defaultMemory
    41  		} else {
    42  			log.Fatalln(err)
    43  		}
    44  	} else {
    45  		maxmemory = result.Node.Key
    46  	}
    47  	replaceMaxmemoryInConfig(maxmemory)
    48  
    49  	go launchRedis()
    50  
    51  	go publishService(client, host, etcdPath, externalPort, uint64(ttl.Seconds()))
    52  
    53  	// Wait for terminating signal
    54  	exitChan := make(chan os.Signal, 2)
    55  	signal.Notify(exitChan, syscall.SIGTERM, syscall.SIGINT)
    56  	<-exitChan
    57  }
    58  
    59  func replaceMaxmemoryInConfig(maxmemory string) {
    60  	input, err := ioutil.ReadFile(redisConf)
    61  	if err != nil {
    62  		log.Fatalln(err)
    63  	}
    64  	output := strings.Replace(string(input), "# maxmemory <bytes>", "maxmemory "+maxmemory, 1)
    65  	err = ioutil.WriteFile(redisConf, []byte(output), 0644)
    66  	if err != nil {
    67  		log.Fatalln(err)
    68  	}
    69  }
    70  
    71  func launchRedis() {
    72  	cmd := exec.Command("/app/bin/redis-server", redisConf)
    73  	cmd.Stdout = os.Stdout
    74  	cmd.Stderr = os.Stderr
    75  
    76  	err := cmd.Start()
    77  
    78  	if err != nil {
    79  		log.Printf("Error starting Redis: %v", err)
    80  		os.Exit(1)
    81  	}
    82  
    83  	// Wait until the redis server is available
    84  	for {
    85  		_, err := net.DialTimeout("tcp", "127.0.0.1:6379", redisWait)
    86  		if err == nil {
    87  			log.Println("deis-cache running...")
    88  			break
    89  		}
    90  	}
    91  
    92  	err = cmd.Wait()
    93  	log.Printf("Redis finished by error: %v", err)
    94  }
    95  
    96  func publishService(client *etcd.Client, host string, etcdPath string,
    97  	externalPort string, ttl uint64) {
    98  
    99  	for {
   100  		setEtcd(client, etcdPath+"/host", host, ttl)
   101  		setEtcd(client, etcdPath+"/port", externalPort, ttl)
   102  		time.Sleep(timeout)
   103  	}
   104  }
   105  
   106  func setEtcd(client *etcd.Client, key, value string, ttl uint64) {
   107  	_, err := client.Set(key, value, ttl)
   108  	if err != nil {
   109  		log.Println(err)
   110  	}
   111  }
   112  
   113  func getopt(name, dfault string) string {
   114  	value := os.Getenv(name)
   115  	if value == "" {
   116  		value = dfault
   117  	}
   118  	return value
   119  }