diff --git a/Makefile b/Makefile index fec2542..91d103d 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,8 @@ IMAGE := ${DEIS_REGISTRY}${IMAGE_PREFIX}/${SHORT_NAME}:${VERSION} MC_IMAGE := ${DEIS_REGISTRY}${IMAGE_PREFIX}/mc:${VERSION} MC_INTEGRATION_IMAGE := ${DEIS_REGISTRY}${IMAGE_PREFIX}/mc-integration:${VERSION} +TEST_PACKAGES := $(shell ${DEV_ENV_CMD} glide nv) + all: build docker-build docker-push bootstrap: @@ -39,6 +41,9 @@ build: mkdir -p ${BINDIR} ${DEV_ENV_PREFIX} -e CGO_ENABLED=0 ${DEV_ENV_IMAGE} go build -a -installsuffix cgo -ldflags '-s' -o $(BINDIR)/boot boot.go || exit 1 +test: + ${DEV_ENV_CMD} go test ${TEST_PACKAGES} + docker-build: build-server # copy the server binary from where it was built to the final image's file system. # note that the minio server is built as a dependency of this build target. @@ -114,7 +119,4 @@ mc-integration-docker-build: mc-integration-docker-push: make -C mc/integration docker-push -test: - @echo "Implement functional tests in _tests directory" - .PHONY: all build docker-compile kube-up kube-down deploy mc kube-mc diff --git a/boot.go b/boot.go index 5b1cdfb..764ee50 100644 --- a/boot.go +++ b/boot.go @@ -2,16 +2,31 @@ package main import ( "bytes" + "errors" "fmt" "io/ioutil" "log" "os" "os/exec" + "strconv" "strings" "text/template" + "github.com/deis/minio/src/healthsrv" "github.com/deis/pkg/aboutme" "github.com/deis/pkg/utils" + minio "github.com/minio/minio-go" +) + +const ( + localMinioInsecure = true + localMinioHost = "localhost" + localMinioPort = 9000 +) + +var ( + errHealthSrvExited = errors.New("healthcheck server exited with unknown status") + errMinioExited = errors.New("Minio server exited with unknown status") ) // Secret is a secret for the remote object storage @@ -67,7 +82,7 @@ const templv2 = `{ } }` -func run(cmd string) { +func run(cmd string) error { var cmdBuf bytes.Buffer tmpl := template.Must(template.New("cmd").Parse(cmd)) if err := tmpl.Execute(&cmdBuf, nil); err != nil { @@ -78,10 +93,9 @@ func run(cmd string) { var cmdl *exec.Cmd cmdl = exec.Command("sh", "-c", cmdString) if _, _, err := utils.RunCommandWithStdoutStderr(cmdl); err != nil { - log.Fatal(err) - } else { - fmt.Println("ok") + return err } + return nil } func readSecrets() (string, string) { @@ -92,10 +106,26 @@ func readSecrets() (string, string) { return strings.TrimSpace(string(keyID)), strings.TrimSpace(string(accessKey)) } +func newMinioClient(host string, port int, accessKey, accessSecret string, insecure bool) (minio.CloudStorageClient, error) { + return minio.New( + fmt.Sprintf("%s:%d", host, port), + accessKey, + accessSecret, + insecure, + ) +} + func main() { pod, err := aboutme.FromEnv() checkError(err) key, access := readSecrets() + + minioClient, err := newMinioClient(localMinioHost, localMinioPort, key, access, localMinioInsecure) + if err != nil { + log.Printf("Error creating minio client (%s)", err) + os.Exit(1) + } + secrets := []Secret{ { Host: pod.IP, @@ -104,10 +134,9 @@ func main() { }, } t := template.New("MinioTpl") - t, err = t.Parse(templv2) - checkError(err) + err = os.MkdirAll(configdir, 0755) checkError(err) output, err := os.Create(configdir + "config.json") @@ -115,7 +144,44 @@ func main() { checkError(err) os.Args[0] = "minio" mc := strings.Join(os.Args, " ") - run(mc) + runErrCh := make(chan error) + log.Printf("starting Minio server") + go func() { + if err := run(mc); err != nil { + runErrCh <- err + } else { + runErrCh <- errMinioExited + } + }() + + healthSrvHost := os.Getenv("HEALTH_SERVER_HOST") + if healthSrvHost == "" { + healthSrvHost = healthsrv.DefaultHost + } + healthSrvPort, err := strconv.Atoi(os.Getenv("HEALTH_SERVER_PORT")) + if err != nil { + healthSrvPort = healthsrv.DefaultPort + } + + log.Printf("starting health check server on %s:%d", healthSrvHost, healthSrvPort) + + healthSrvErrCh := make(chan error) + go func() { + if err := healthsrv.Start(healthSrvHost, healthSrvPort, minioClient); err != nil { + healthSrvErrCh <- err + } else { + healthSrvErrCh <- errHealthSrvExited + } + }() + + select { + case err := <-runErrCh: + log.Printf("Minio server error (%s)", err) + os.Exit(1) + case err := <-healthSrvErrCh: + log.Printf("Healthcheck server error (%s)", err) + os.Exit(1) + } } func checkError(err error) { diff --git a/boot_test.go b/boot_test.go new file mode 100644 index 0000000..6e2f053 --- /dev/null +++ b/boot_test.go @@ -0,0 +1,15 @@ +package main + +import ( + "testing" +) + +func TestNewMinioClient(t *testing.T) { + client, err := newMinioClient("localhost", 8095, "access_key", "access_secret_key", false) + if err != nil { + t.Fatalf("unexpected error creating minio client (%s)", err) + } + if client == nil { + t.Fatalf("returned client was nil but not expected to be") + } +} diff --git a/glide.lock b/glide.lock index 0d50d29..d45cc9a 100644 --- a/glide.lock +++ b/glide.lock @@ -1,44 +1,37 @@ hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -updated: 2015-12-17T18:01:39.396613315-07:00 +updated: 2016-02-05T21:14:28.15941846Z imports: - name: bitbucket.org/bertimus9/systemstat version: 1468fd0db20598383c9393cccaa547de6ad99e5e - name: bitbucket.org/ww/goautoneg version: 75cd24fc2f2c -- name: code.google.com/p/go-charset - version: ebbeafdc430e - name: code.google.com/p/go-uuid - version: 7dda39b2e7d5 + version: "" subpackages: - uuid - name: code.google.com/p/go.crypto - version: 69e2a90ed92d + version: "" + repo: https://code.google.com/p/go.crypto - name: code.google.com/p/go.net - version: 937a34c9de13 + version: "" + repo: https://code.google.com/p/go.net - name: code.google.com/p/go.text - version: 5b2527008a4c -- name: code.google.com/p/goauth2 - version: 222e66a2882e + version: "" + repo: https://code.google.com/p/go.text - name: code.google.com/p/google-api-go-client - version: e1c259484b49 - subpackages: - - bigquery/v2 - - googleapi + version: "" + repo: https://code.google.com/p/google-api-go-client - name: code.google.com/p/goprotobuf - version: 68415e7123da32b07eab49c96d2c4d6158360e9b - repo: https://github.com/golang/protobuf + version: "" + repo: https://code.google.com/p/goprotobuf - name: code.google.com/p/gosqlite - version: 74691fb6f837 + version: "" + repo: https://code.google.com/p/gosqlite - name: code.google.com/p/log4go - version: c3294304d93f + version: "" + repo: https://code.google.com/p/log4go - name: github.com/abbot/go-http-auth version: c0ef4539dfab4d21c8ef20ba2924f9fc6f186d35 -- name: github.com/AdRoll/goamz - version: aa6e716d710a0c7941cb2075cfbb9661f16d21f1 - subpackages: - - aws - - cloudfront - - s3 - name: github.com/agtorre/gocolorize version: f42b554bf7f006936130c9bb4f971afd2d87f671 - name: github.com/appc/cni @@ -56,7 +49,7 @@ imports: - name: github.com/armon/go-metrics version: eb0af217e5e9747e41dd5303755356b62d28e3ec - name: github.com/armon/go-radix - version: fbd82e84e2b13651f3abc5ffd26b65ba71bc8f93 + version: 4239b77079c7b5d1243b7b4736304ce8ddb6f0f2 - name: github.com/armon/gomdb version: 151f2e08ef45cb0e57d694b2562f351955dff572 - name: github.com/aws/aws-sdk-go @@ -76,6 +69,8 @@ imports: version: 97d9593768bbbbd316f9c055dfc5f780933cd7fc subpackages: - storage +- name: github.com/Azure/go-ansiterm + version: 70b2c90b260171e829f1ebd7c17f600c11858dbe - name: github.com/Azure/go-pkcs12 version: 40102598fec19246e36fb595018ce387dbd7b3cc - name: github.com/beorn7/perks @@ -86,14 +81,12 @@ imports: version: 36e9cfdd690967f4f690c6edcc9ffacd006014a0 - name: github.com/bitly/go-simplejson version: aabad6e819789e569bd6aabf444c935aa9ba1e44 -- name: github.com/blang/semver - version: 31b736133b98f26d5e078ec9eb591666edfd091f - name: github.com/bmizerany/pat version: b8a35001b773c267eb260a691f4e5499a3531600 - name: github.com/boltdb/bolt version: 0f053fabc06119583d61937a0a06ef0ba0f1b301 - name: github.com/bradfitz/gomemcache - version: 72a68649ba712ee7c4b5b4a943a626bcd7d90eb8 + version: fb1f79c6b65acda83063cbc69f6bba1522558bfc - name: github.com/bradfitz/http2 version: 3e36af6d3af0e56fa3da71099f864933dea3d9fb - name: github.com/bugsnag/bugsnag-go @@ -101,7 +94,7 @@ imports: - name: github.com/bugsnag/osext version: 0dd3f918b21bec95ace9dc86c7e70266cfc5c702 - name: github.com/bugsnag/panicwrap - version: e5f9854865b9778a45169fc249e99e338d4d6f27 + version: e2c28503fcd0675329da73bf48b33404db873782 - name: github.com/BurntSushi/toml version: f706d00e3de6abe700c994cdd545a1a4915af060 - name: github.com/cbroglie/mapstructure @@ -130,8 +123,6 @@ imports: - registry - schema - unit -- name: github.com/coreos/gexpect - version: 5173270e159f5aa8fbc999dc7e3dcb50f4098a69 - name: github.com/coreos/go-etcd version: 4cceaf7283b76f27c4a732b20730dcdb61053bf5 subpackages: @@ -184,16 +175,18 @@ imports: - name: github.com/deis/pkg version: f63d9718b86f17c9320f838fb3eb6039cadb9691 subpackages: - - aboutme + - /aboutme + - /utils - name: github.com/denverdino/aliyungo - version: 0e0f322d0a54b994dea9d32541050d177edf6aa3 + version: 6ffb587da9da6d029d0ce517b85fecc82172d502 subpackages: - oss - util + - common - name: github.com/dgrijalva/jwt-go version: 5ca80149b9d3f8b863af0e2bb6742e608603bd99 - name: github.com/docker/distribution - version: 7f41cd7587fb4c3e21fccfe72420eef8ed7bba89 + version: dd58349b355f346a020a08b2fd9306549293c4ef - name: github.com/docker/docker version: 2b27fe17a1b3fb8472fde96d768fa70996adf201 subpackages: @@ -204,20 +197,26 @@ imports: - pkg/term - pkg/timeutils - pkg/units +- name: github.com/docker/go-units + version: 8e2d4523730c73120e10d4652f36ad6010998f4e +- name: github.com/docker/goamz + version: 29510ec7eba995a3750f6b38128c5318f8b71592 + subpackages: + - aws + - cloudfront + - s3 - name: github.com/docker/libcontainer version: 5dc7ba0f24332273461e45bc49edcb4d5aa6c44c - name: github.com/docker/libkv version: c2aac5dbbaa5c872211edea7c0f32b3bd67e7410 - name: github.com/docker/libnetwork - version: e1a75ce71826cac66e107f6c06d6f2e34e1c2e41 + version: 6cd5d90eb6b25d9e1ba41c45ad39f7df36d981b3 - name: github.com/docker/libtrust version: fa567046d9b14f6aa788882a950d69651d230b21 - name: github.com/docker/spdystream version: b2c3287865f3ad6aa22821ddb7b4692b896ac207 - name: github.com/elazarl/go-bindata-assetfs version: 3dcc96556217539f50599357fb481ac0dc7439b9 -- name: github.com/elazarl/goproxy - version: 07b16b6e30fcac0ad8c0435548e743bcf2ca7e92 - name: github.com/emicklei/go-restful version: 1f9a0ee00ff93717a275e15b30cf7df356255877 - name: github.com/evanphx/json-patch @@ -238,11 +237,11 @@ imports: - name: github.com/gedex/inflector version: 8c0e57904488c554ab26caec525db5c92b23f051 - name: github.com/getsentry/raven-go - version: 3966f3ab8333308d76b6cc83a29776a266bbdd92 + version: 1cc47a9463b90f246a0503d4c2e9a55c9459ced3 - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee - name: github.com/go-check/check - version: 11d3bc7aa68e238947792f30573146a3231fc0f1 + version: 4f90aeace3a26ad7021961c297b22c42160c7b25 - name: github.com/godbus/dbus version: 939230d2086a4f1870e04c52e0a376c25bae0ec4 - name: github.com/gogo/protobuf @@ -266,7 +265,7 @@ imports: - name: github.com/google/btree version: cc6329d4279e3f025a53a83c397d2339b5705c45 - name: github.com/google/cadvisor - version: a8085bf9276c22f16dbcd7aa56f0d4d0626a0b2e + version: aa6f80814bc6fdb43a0ed12719658225420ffb7d subpackages: - api - cache/memory @@ -288,8 +287,6 @@ imports: - version - name: github.com/google/gofuzz version: bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5 -- name: github.com/google/protobuf - version: b640f216a56ae25aab9a1fc6f21aa1a56c304494 - name: github.com/GoogleCloudPlatform/gcloud-golang version: 542bfb014d8e28df6e27be847dfdc40c510dab1a subpackages: @@ -303,7 +300,9 @@ imports: - name: github.com/gorilla/schema version: 14c555599c2a4f493c1e13fd1ea6fdf721739028 - name: github.com/gorilla/websocket - version: 3986be78bf859e01f01af631ad76da5b269d270c + version: 234959944d9cf05229b02e8b386e5cffe1e4e04a +- name: github.com/Graylog2/go-gelf + version: 06974fc6689396066f6ebf5bab951d41979e3386 - name: github.com/hashicorp/consul version: 954aec66231b79c161a4122b023fbcad13047f79 subpackages: @@ -321,9 +320,9 @@ imports: - name: github.com/hashicorp/go.net version: 104dcad90073cd8d1e6828b2af19185b60cf3e29 - name: github.com/hashicorp/golang-lru - version: b361c4c189a958f7d0ad435952611c140751afe2 + version: ce7dece472ba96dab1807940f0614f3254f883e7 - name: github.com/hashicorp/hcl - version: 5af5025c48e8bf0e03551b8757d92a774b9f0694 + version: e96d23138c76470c808bf6586bdaf981bbd25cae - name: github.com/hashicorp/logutils version: 0dc08b1671f34c4250ce212759ebd880f743d883 - name: github.com/hashicorp/mdns @@ -331,7 +330,7 @@ imports: - name: github.com/hashicorp/memberlist version: 9a1e242e454d2443df330bdd51a436d5a9058fc4 - name: github.com/hashicorp/raft - version: d136cd15dfb7876fd7c89cad1995bc4f19ceb294 + version: 057b893fd996696719e98b6c44649ea14968c811 - name: github.com/hashicorp/raft-mdb version: 55f29473b9e604b3678b93a8433a6cf089e70f76 - name: github.com/hashicorp/serf @@ -346,8 +345,6 @@ imports: - metrics - name: github.com/imdario/mergo version: 6633656539c1639d9d78127b7d47c622b5d7b6dc -- name: github.com/inconshreveable/go-vhost - version: 8cbc5089df5ba3e44644d39e8d1ec375d6d842f9 - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 - name: github.com/inconshreveable/muxado @@ -367,11 +364,9 @@ imports: - name: github.com/juju/ratelimit version: 772f5c38e468398c4511514f4f6aa9a4185bc0a0 - name: github.com/julienschmidt/httprouter - version: f30ab90cccbd5171771d26b6557d3c2f49e047a6 + version: 5273944025bdfe8df6c10f286ce7742b83673033 - name: github.com/kardianos/osext version: 8fef92e41e22a70e700a96b29f066cda30ea24ef -- name: github.com/kballard/go-shellquote - version: d8ec1a69a250a17bb0e419c386eac1f3711dc142 - name: github.com/kimor79/gollectd version: 61d0deeb4ffcc167b2a1baa8efd72365692811bc - name: github.com/kr/pretty @@ -381,15 +376,17 @@ imports: - name: github.com/kr/text version: 6807e777504f54ad073ecef66747de158294b639 - name: github.com/lsegal/gucumber - version: e8116c9c66e641e9f81fc0a79fac923dfc646378 + version: 44a4d7eb3b14a88cf82b073dfb7e06277afdc549 - name: github.com/Masterminds/cookoo version: 78aa11ce75e257c51be7ea945edb84cf19c4a6de +- name: github.com/mattn/go-isatty + version: 56b76bdf51f7708750eac80fa38b952bb9f32639 - name: github.com/matttproud/golang_protobuf_extensions version: fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a subpackages: - pbutil - name: github.com/mesos/mesos-go - version: ed907b10717e66325cf2894eb90a0553a89fcb11 + version: b164c06f346af1e93aecb6502f83d31dbacdbb91 subpackages: - auth - detector @@ -401,8 +398,12 @@ imports: - upid - name: github.com/miekg/dns version: 3f504e8dabd5d562e997d19ce0200aa41973e1b2 +- name: github.com/minio/minio-go + version: c5884ce9ce3ac73b025d0bc58c4d3d72870edc0b +- name: github.com/mistifyio/go-zfs + version: 1b4ae6fb4e77b095934d4430860ff202060169f8 - name: github.com/mitchellh/cli - version: 8102d0ed5ea2709ade1243798785888175f6e415 + version: 5c87c51cedf76a1737bf5ca3979e8644871598a6 - name: github.com/mitchellh/mapstructure version: 740c764bc6149d3f1806231418adb9f52c11bcbf - name: github.com/mjibson/appstats @@ -422,11 +423,11 @@ imports: - name: github.com/onsi/gomega version: 8adf9e1730c55cdc590de7d49766cb2acc88d8f2 - name: github.com/opencontainers/runc - version: 072fa6fdccaba49b11ba91ad4265b1ec1043787e + version: ba1568de399395774ad84c2ace65937814c542ed subpackages: - libcontainer - name: github.com/opencontainers/specs - version: 5b31bb2b7771e5074a4eb14eca432da1ca5182d6 + version: cf8dd120937acc3593708f99304c51cfd0f73240 - name: github.com/pborman/uuid version: ca53cad383cad2479bbba7f7a1a05797ec1386e4 - name: github.com/progrium/go-extpoints @@ -457,7 +458,7 @@ imports: - name: github.com/rakyll/statik version: 274df120e9065bdd08eb1120e0375e3dc1ae8465 - name: github.com/rcrowley/go-metrics - version: 7839c01b09d2b1d7068034e5fe6e423f6ac5be22 + version: 51425a2415d21afadfd55cd93432c0bc69e9598d - name: github.com/revel/revel version: a9a2ff45fae4330ef4116b257bcf9c82e53350c2 - name: github.com/robfig/config @@ -478,6 +479,8 @@ imports: version: 37aabad69cfd3d20b8390d902a8b10e245c615ff - name: github.com/SeanDolphin/bqschema version: f92a08f515e1bf718e995076a37c2f534b1deb08 +- name: github.com/seccomp/libseccomp-golang + version: 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1 - name: github.com/shiena/ansicolor version: a422bbe96644373c5753384a59d678f7d261ff10 - name: github.com/shurcooL/sanitized_anchor_name @@ -493,10 +496,7 @@ imports: - name: github.com/spf13/pflag version: 8e7dc108ab3a1ab6ce6d922bbaff5657b88e8e49 - name: github.com/stathat/go - version: 01d012b9ee2ecc107cb28b6dd32d9019ed5c1d77 -- name: github.com/steveeJ/gexpect - version: 5173270e159f5aa8fbc999dc7e3dcb50f4098a69 - repo: https://github.com/coreos/gexpect + version: cf69b0bcb80478755dc0ea1120b36000e35dcbbb - name: github.com/stevvooe/resumable version: 51ad44105773cafcbe91927f70ac68e1bf78f8b4 - name: github.com/stretchr/objx @@ -554,7 +554,7 @@ imports: subpackages: - unix - name: golang.org/x/text - version: cf4986612c83df6c55578ba198316d1684a9a287 + version: db2353fc1b663d79d1001e206afc02a5ec9f4291 - name: golang.org/x/tools version: 4f50f44d7a3206e9e28b984e023efce2a4a75369 subpackages: @@ -568,7 +568,7 @@ imports: - container/v1beta1 - googleapi - name: google.golang.org/appengine - version: 58c0e2a2044a8d1abd8dd1d97939cd74497d0806 + version: 6a436539be38c296a8075a871cc536686b458371 - name: google.golang.org/cloud version: 2e43671e4ad874a7bca65746ff3edb38e6e93762 subpackages: @@ -579,7 +579,7 @@ imports: - name: gopkg.in/check.v1 version: 64131543e7896d5bcc6bd5a76287eb75ea96c673 - name: gopkg.in/fsnotify.v1 - version: 508915b7500b6e42a87132e4afeb4729cebc7cbb + version: 8611c35ab31c1c28aa903d33cf8b6e44a399b09e - name: gopkg.in/natefinch/lumberjack.v2 version: 600ceb4523e5b7ff745f91083c8a023c2bf73af5 - name: gopkg.in/olivere/elastic.v2 @@ -597,10 +597,12 @@ imports: subpackages: - api/v1/types - name: k8s.io/kubernetes - version: 8dec957e4bba8b1260995d525a8260e03acbc181 + version: 92635e23dfafb2ddc828c8ac6c03c7a7205a84d8 + subpackages: + - pkg - name: launchpad.net/gocheck - version: 11d3bc7aa68e238947792f30573146a3231fc0f1 - repo: https://github.com/go-check/check + version: "" + repo: https://launchpad.net/gocheck - name: speter.net/go/exp/math/dec/inf version: 42ca6cd68aa922bc3f32f1e056e61b65945d9ad7 devImports: [] diff --git a/glide.yaml b/glide.yaml index 19571e3..0f48a18 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,4 +1,6 @@ package: main +ignore: +- appengine import: - package: gopkg.in/natefinch/lumberjack.v2 version: 600ceb4523e5b7ff745f91083c8a023c2bf73af5 @@ -10,9 +12,10 @@ import: version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 - package: gopkg.in/yaml.v2 version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 -- package: github.com/deis/pkg/aboutme +- package: github.com/deis/pkg version: f63d9718b86f17c9320f838fb3eb6039cadb9691 -- package: github.com/google/protobuf - version: b640f216a56ae25aab9a1fc6f21aa1a56c304494 -ignore: - - appengine + subpackages: + - /aboutme + - /utils +- package: github.com/minio/minio-go + version: c5884ce9ce3ac73b025d0bc58c4d3d72870edc0b diff --git a/manifests/deis-minio-rc.yaml b/manifests/deis-minio-rc.yaml index a4a6b13..90bc2af 100644 --- a/manifests/deis-minio-rc.yaml +++ b/manifests/deis-minio-rc.yaml @@ -15,11 +15,27 @@ spec: app: deis-minio spec: containers: - - imagePullPolicy: Always - name: deis-minio - image: quay.io/deisci/minio:v2-beta + - name: deis-minio + image: quay.io/arschles/minio:devel + imagePullPolicy: Always + env: + - name: HEALTH_SERVER_PORT + value: "8082" ports: - containerPort: 9000 + - containerPort: 8095 + livenessProbe: + httpGet: + path: /healthz + port: 8092 + initialDelaySeconds: 30 + timeoutSeconds: 1 + readinessProbe: + httpGet: + path: /healthz + port: 8092 + initialDelaySeconds: 30 + timeoutSeconds: 1 command: - boot args: diff --git a/src/healthsrv/healthz_handler.go b/src/healthsrv/healthz_handler.go new file mode 100644 index 0000000..80700a9 --- /dev/null +++ b/src/healthsrv/healthz_handler.go @@ -0,0 +1,33 @@ +package healthsrv + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + + "github.com/deis/minio/src/storage" + minio "github.com/minio/minio-go" +) + +type healthZResp struct { + Buckets []minio.BucketInfo `json:"buckets"` +} + +func healthZHandler(bucketLister storage.BucketLister) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + buckets, err := bucketLister.ListBuckets() + if err != nil { + str := fmt.Sprintf("Probe error: listing buckets (%s)", err) + log.Println(str) + http.Error(w, str, http.StatusInternalServerError) + return + } + if err := json.NewEncoder(w).Encode(healthZResp{Buckets: buckets}); err != nil { + str := fmt.Sprintf("Probe error: encoding buckets json (%s)", err) + log.Println(str) + http.Error(w, str, http.StatusInternalServerError) + return + } + }) +} diff --git a/src/healthsrv/healthz_handler_test.go b/src/healthsrv/healthz_handler_test.go new file mode 100644 index 0000000..81ce147 --- /dev/null +++ b/src/healthsrv/healthz_handler_test.go @@ -0,0 +1,50 @@ +package healthsrv + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/deis/minio/src/storage" + minio "github.com/minio/minio-go" +) + +func TestHealthzHandler(t *testing.T) { + buckets := []minio.BucketInfo{ + minio.BucketInfo{Name: "bucket1", CreationDate: time.Now()}, + minio.BucketInfo{Name: "bucket2", CreationDate: time.Now()}, + } + bucketLister := storage.NewFakeBucketLister(buckets) + handler := healthZHandler(bucketLister) + + w := httptest.NewRecorder() + r, err := http.NewRequest("GET", "/healthz", bytes.NewReader(nil)) + if err != nil { + t.Fatalf("unexpected error creating request (%s)", err) + } + handler.ServeHTTP(w, r) + if w.Code != http.StatusOK { + t.Fatalf("unexpected response code %d", w.Code) + } + + rsp := new(healthZResp) + if err := json.NewDecoder(w.Body).Decode(rsp); err != nil { + t.Fatalf("error decoding json (%s)", err) + } + if len(rsp.Buckets) != len(buckets) { + t.Fatalf("received %d bucket(s), expected %d", len(rsp.Buckets), len(buckets)) + } + + for i, bucket := range buckets { + actual := rsp.Buckets[i] + if actual.Name != bucket.Name { + t.Fatalf("expected name %s for bucket %d, got %s", bucket.Name, i, actual.Name) + } + if !actual.CreationDate.Equal(bucket.CreationDate) { + t.Fatalf("expected creation date %s for bucket %d, got %s", bucket.CreationDate, i, actual.CreationDate) + } + } +} diff --git a/src/healthsrv/server.go b/src/healthsrv/server.go new file mode 100644 index 0000000..541dde4 --- /dev/null +++ b/src/healthsrv/server.go @@ -0,0 +1,21 @@ +package healthsrv + +import ( + "fmt" + minio "github.com/minio/minio-go" + "net/http" +) + +const ( + DefaultHost = "0.0.0.0" + DefaultPort = 8082 +) + +// Start starts the healthcheck server on $host:$port and blocks. It only returns if the server fails, with the indicative error +func Start(host string, port int, minioClient minio.CloudStorageClient) error { + mux := http.NewServeMux() + mux.Handle("/healthz", healthZHandler(minioClient)) + + hostStr := fmt.Sprintf("%s:%d", host, port) + return http.ListenAndServe(hostStr, mux) +} diff --git a/src/storage/bucket_lister.go b/src/storage/bucket_lister.go new file mode 100644 index 0000000..903248e --- /dev/null +++ b/src/storage/bucket_lister.go @@ -0,0 +1,22 @@ +package storage + +import ( + minio "github.com/minio/minio-go" +) + +// BucketLister is an interface that knows how to list buckets on object storage +type BucketLister interface { + ListBuckets() ([]minio.BucketInfo, error) +} + +type fakeBucketLister struct { + bucketInfos []minio.BucketInfo +} + +func NewFakeBucketLister(buckets []minio.BucketInfo) BucketLister { + return &fakeBucketLister{bucketInfos: buckets} +} + +func (b *fakeBucketLister) ListBuckets() ([]minio.BucketInfo, error) { + return b.bucketInfos, nil +}