gifs/api

Paddy 2014-10-17 Parent:eb450538f079 Child:03e846421572

7:21787ed8a185 Browse Files

Create a Dockerfile and binary. Write a Dockerfile that compiles everything and runs it. Start the binary; load a Context from etcd, and start everything running. The binary is pretty useless until we get HTTP handlers, though, obviously.

Dockerfile gifsd/etcd.go gifsd/server.go

     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Dockerfile	Fri Oct 17 07:22:17 2014 -0400
     1.3 @@ -0,0 +1,9 @@
     1.4 +FROM google/golang
     1.5 +
     1.6 +ADD . /gopath/src/code.secondbit.org/gifs/api
     1.7 +WORKDIR /gopath/src/code.secondbit.org/gifs/api
     1.8 +RUN go get -v ./...
     1.9 +WORKDIR /gopath/src/code.secondbit.org/gifs/api/gifsd
    1.10 +RUN go build .
    1.11 +
    1.12 +CMD ["/gopath/src/code.secondbit.org/gifs/api/gifsd/gifsd"]
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/gifsd/etcd.go	Fri Oct 17 07:22:17 2014 -0400
     2.3 @@ -0,0 +1,50 @@
     2.4 +package main
     2.5 +
     2.6 +import (
     2.7 +	"log"
     2.8 +
     2.9 +	"code.secondbit.org/gifs/api"
    2.10 +	"github.com/coreos/go-etcd/etcd"
    2.11 +)
    2.12 +
    2.13 +func getEtcdContext(resp *etcd.Node) (api.Context, error) {
    2.14 +	var context api.Context
    2.15 +	var dsn, bucket, tmpbucket, domain string
    2.16 +	for _, node := range resp.Nodes {
    2.17 +		switch node.Key {
    2.18 +		case "/dsn":
    2.19 +			dsn = node.Value
    2.20 +		case "/bucket":
    2.21 +			bucket = node.Value
    2.22 +		case "/tmpbucket":
    2.23 +			tmpbucket = node.Value
    2.24 +		case "/domain":
    2.25 +			domain = node.Value
    2.26 +		}
    2.27 +	}
    2.28 +	if dsn != "" {
    2.29 +		log.Println("Using PostgreSQL as our datastore.")
    2.30 +		/*datastore, err := api.NewMySQLDatastore(dsn)
    2.31 +		if err != nil {
    2.32 +			return context, err
    2.33 +		}
    2.34 +		context.Datastore = datastore*/
    2.35 +		panic("PostgreSQL not implemented yet.")
    2.36 +	} else {
    2.37 +		log.Println("Using in-memory datastore.")
    2.38 +		context.Datastore = api.NewMemDatastore()
    2.39 +	}
    2.40 +	context.UsageTracker = api.NewMemTracker() // TODO: get this using influx
    2.41 +	context.Bucket = bucket
    2.42 +	context.TmpBucket = tmpbucket
    2.43 +	context.RootDomain = domain
    2.44 +	storage, err := api.NewGCSServiceStorage()
    2.45 +	if err != nil {
    2.46 +		log.Println("Using in-memory blob store.")
    2.47 +		context.Storage = api.NewMemStorage()
    2.48 +	} else {
    2.49 +		log.Println("Using Google Cloud Storage for blob store.")
    2.50 +		context.Storage = storage
    2.51 +	}
    2.52 +	return context, nil
    2.53 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/gifsd/server.go	Fri Oct 17 07:22:17 2014 -0400
     3.3 @@ -0,0 +1,82 @@
     3.4 +package main
     3.5 +
     3.6 +import (
     3.7 +	"flag"
     3.8 +	"fmt"
     3.9 +	"log"
    3.10 +	"os"
    3.11 +	"strings"
    3.12 +
    3.13 +	"github.com/coreos/go-etcd/etcd"
    3.14 +)
    3.15 +
    3.16 +var (
    3.17 +	etcdAddrs = StringArray{}
    3.18 +)
    3.19 +
    3.20 +type StringArray []string
    3.21 +
    3.22 +func (a *StringArray) Set(s string) error {
    3.23 +	*a = append(*a, s)
    3.24 +	return nil
    3.25 +}
    3.26 +
    3.27 +func (a *StringArray) String() string {
    3.28 +	return strings.Join(*a, ",")
    3.29 +}
    3.30 +
    3.31 +func main() {
    3.32 +	flag.Var(&etcdAddrs, "etcd-address", "address to the etcd server (may be specified more than once)")
    3.33 +	flag.Parse()
    3.34 +	if len(etcdAddrs) < 1 {
    3.35 +		if os.Getenv("ETCD_NAME") != "" {
    3.36 +			etcdAddrs = []string{"http://etcd:" + os.Getenv("ETCD_PORT_4001_TCP_PORT") + "/"}
    3.37 +		} else {
    3.38 +			flag.Usage()
    3.39 +			return
    3.40 +		}
    3.41 +	}
    3.42 +	log.Println("Using etcd servers", etcdAddrs)
    3.43 +	client := etcd.NewClient(etcdAddrs)
    3.44 +	resp, err := client.Get("/code.secondbit.org/gifs/api/", false, true)
    3.45 +	if err != nil {
    3.46 +		log.Fatalln(err)
    3.47 +		return
    3.48 +	}
    3.49 +	context, err := getEtcdContext(resp.Node)
    3.50 +	if err != nil {
    3.51 +		log.Fatalln(err)
    3.52 +		return
    3.53 +	}
    3.54 +	err = context.Validate()
    3.55 +	if err != nil {
    3.56 +		log.Fatalln(err)
    3.57 +		return
    3.58 +	}
    3.59 +	listenAddr := ":8080"
    3.60 +	for _, node := range resp.Node.Nodes {
    3.61 +		if node.Key == "/listen_addr" {
    3.62 +			listenAddr = node.Value
    3.63 +			fmt.Println("Set listenAddr to " + node.Value)
    3.64 +			break
    3.65 +		}
    3.66 +	}
    3.67 +	log.Println("Going to listen on", listenAddr)
    3.68 +
    3.69 +	/*
    3.70 +		var router *mux.Router
    3.71 +		if context.RootDomain == "" {
    3.72 +			fmt.Println("Using path muxer")
    3.73 +			router = api.GetPathMuxer(context)
    3.74 +		} else {
    3.75 +			fmt.Println("Using domain muxer")
    3.76 +			router = api.GetDomainMuxer(context)
    3.77 +		}
    3.78 +		http.Handle("/", router)
    3.79 +		fmt.Println("Listening on " + listenAddr)
    3.80 +		err = http.ListenAndServe(listenAddr, nil)
    3.81 +		if err != nil {
    3.82 +			panic(err)
    3.83 +		}
    3.84 +	*/
    3.85 +}