From f46d64bff1ce4fa8f2e423e39acd757a61c2d8bc Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 15:08:32 -0800 Subject: [PATCH 01/14] fix(boot.go,src/healthsrv): add health check server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and a single health check endpoint ‘/healthz’ --- boot.go | 53 +++++++++++++++++++++++++++++--- src/healthsrv/healthz_handler.go | 11 +++++++ src/healthsrv/server.go | 20 ++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 src/healthsrv/healthz_handler.go create mode 100644 src/healthsrv/server.go diff --git a/boot.go b/boot.go index 5b1cdfb..706cf18 100644 --- a/boot.go +++ b/boot.go @@ -2,18 +2,26 @@ 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" ) +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 type Secret struct { Host string @@ -67,7 +75,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 +86,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) { @@ -115,7 +122,43 @@ func main() { checkError(err) os.Args[0] = "minio" mc := strings.Join(os.Args, " ") - run(mc) + runErrCh := make(chan error) + 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); 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/src/healthsrv/healthz_handler.go b/src/healthsrv/healthz_handler.go new file mode 100644 index 0000000..2a954df --- /dev/null +++ b/src/healthsrv/healthz_handler.go @@ -0,0 +1,11 @@ +package healthsrv + +import ( + "net/http" +) + +func healthZHandler() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) +} diff --git a/src/healthsrv/server.go b/src/healthsrv/server.go new file mode 100644 index 0000000..9ea009a --- /dev/null +++ b/src/healthsrv/server.go @@ -0,0 +1,20 @@ +package healthsrv + +import ( + "fmt" + "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) error { + mux := http.NewServeMux() + mux.Handle("/healthz", healthZHandler()) + + hostStr := fmt.Sprintf("%s:%d", host, port) + return http.ListenAndServe(hostStr, mux) +} From 040206bfe673f5368578a0b9e86771e15fc1286d Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 15:10:59 -0800 Subject: [PATCH 02/14] fix(boot.go): add log line to indicate starting the minio server --- boot.go | 1 + 1 file changed, 1 insertion(+) diff --git a/boot.go b/boot.go index 706cf18..24587de 100644 --- a/boot.go +++ b/boot.go @@ -123,6 +123,7 @@ func main() { os.Args[0] = "minio" mc := strings.Join(os.Args, " ") runErrCh := make(chan error) + log.Printf("starting Minio server") go func() { if err := run(mc); err != nil { runErrCh <- err From abdbcc15d38c466e92735321773fd0d78eda3dc7 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 16:06:08 -0800 Subject: [PATCH 03/14] fix(glide.lock,glide.yaml): add minio-go dependency so that the health check server can use it to check the health of the minio server --- glide.lock | 61 +++++++++++++++++++++++++++--------------------------- glide.yaml | 9 +++++--- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/glide.lock b/glide.lock index 0d50d29..cd5bd33 100644 --- a/glide.lock +++ b/glide.lock @@ -1,36 +1,39 @@ hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -updated: 2015-12-17T18:01:39.396613315-07:00 +updated: 2016-02-04T23:58:05.077980188Z 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 + version: "" + repo: https://code.google.com/p/go.text - name: code.google.com/p/goauth2 - version: 222e66a2882e + version: "" + repo: https://code.google.com/p/goauth2 - name: code.google.com/p/google-api-go-client - version: e1c259484b49 + version: "" subpackages: - bigquery/v2 - googleapi - name: code.google.com/p/goprotobuf version: 68415e7123da32b07eab49c96d2c4d6158360e9b - repo: https://github.com/golang/protobuf - 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 @@ -86,8 +89,6 @@ 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 @@ -130,8 +131,6 @@ imports: - registry - schema - unit -- name: github.com/coreos/gexpect - version: 5173270e159f5aa8fbc999dc7e3dcb50f4098a69 - name: github.com/coreos/go-etcd version: 4cceaf7283b76f27c4a732b20730dcdb61053bf5 subpackages: @@ -216,8 +215,6 @@ imports: 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 @@ -229,7 +226,7 @@ imports: - name: github.com/feyeleanor/slices version: bb44bb2e4817fe71ba7082d351fd582e7d40e3ea - name: github.com/fsouza/go-dockerclient - version: 76fd6c68cf24c48ee6a2b25def997182a29f940e + version: "" - name: github.com/garyburd/redigo version: 535138d7bcd717d6531c701ef5933d98b1866257 subpackages: @@ -266,7 +263,7 @@ imports: - name: github.com/google/btree version: cc6329d4279e3f025a53a83c397d2339b5705c45 - name: github.com/google/cadvisor - version: a8085bf9276c22f16dbcd7aa56f0d4d0626a0b2e + version: aa6f80814bc6fdb43a0ed12719658225420ffb7d subpackages: - api - cache/memory @@ -304,6 +301,9 @@ imports: version: 14c555599c2a4f493c1e13fd1ea6fdf721739028 - name: github.com/gorilla/websocket version: 3986be78bf859e01f01af631ad76da5b269d270c +- name: github.com/Graylog2/go-gelf + version: 06974fc6689396066f6ebf5bab951d41979e3386 + repo: https://github.com/Graylog2/go-gelf - name: github.com/hashicorp/consul version: 954aec66231b79c161a4122b023fbcad13047f79 subpackages: @@ -346,8 +346,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 @@ -370,8 +368,6 @@ imports: version: f30ab90cccbd5171771d26b6557d3c2f49e047a6 - 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 @@ -389,7 +385,7 @@ imports: subpackages: - pbutil - name: github.com/mesos/mesos-go - version: ed907b10717e66325cf2894eb90a0553a89fcb11 + version: b164c06f346af1e93aecb6502f83d31dbacdbb91 subpackages: - auth - detector @@ -401,6 +397,11 @@ 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 + repo: https://github.com/mistifyio/go-zfs - name: github.com/mitchellh/cli version: 8102d0ed5ea2709ade1243798785888175f6e415 - name: github.com/mitchellh/mapstructure @@ -494,9 +495,6 @@ imports: version: 8e7dc108ab3a1ab6ce6d922bbaff5657b88e8e49 - name: github.com/stathat/go version: 01d012b9ee2ecc107cb28b6dd32d9019ed5c1d77 -- name: github.com/steveeJ/gexpect - version: 5173270e159f5aa8fbc999dc7e3dcb50f4098a69 - repo: https://github.com/coreos/gexpect - name: github.com/stevvooe/resumable version: 51ad44105773cafcbe91927f70ac68e1bf78f8b4 - name: github.com/stretchr/objx @@ -597,10 +595,11 @@ 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: "" - name: speter.net/go/exp/math/dec/inf version: 42ca6cd68aa922bc3f32f1e056e61b65945d9ad7 devImports: [] diff --git a/glide.yaml b/glide.yaml index 19571e3..1d5b377 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 + subpackages: + - aboutme - package: github.com/google/protobuf version: b640f216a56ae25aab9a1fc6f21aa1a56c304494 -ignore: - - appengine +- package: github.com/minio/minio-go From a0c231a7cb489641fed94f1f6909944e9c387716 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 16:06:58 -0800 Subject: [PATCH 04/14] fix(boot.go,src/healthsrv): use the minio client to test minio on health checks --- boot.go | 28 +++++++++++++++++++++++++--- src/healthsrv/healthz_handler.go | 19 +++++++++++++++++-- src/healthsrv/server.go | 5 +++-- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/boot.go b/boot.go index 24587de..b268db6 100644 --- a/boot.go +++ b/boot.go @@ -15,6 +15,13 @@ import ( "github.com/deis/minio/src/healthsrv" "github.com/deis/pkg/aboutme" "github.com/deis/pkg/utils" + minio "github.com/minio/minio-go" +) + +const ( + localMinioScheme = "http" + localMinioHost = "localhost" + localMinioPort = 9000 ) var ( @@ -103,6 +110,22 @@ func main() { pod, err := aboutme.FromEnv() checkError(err) key, access := readSecrets() + + insecure := true + if localMinioScheme == "https" { + insecure = false + } + minioClient, err := minio.New( + fmt.Sprintf("%s://%s:%d", localMinioScheme, localMinioHost, localMinioPort), + key, + access, + insecure, + ) + if err != nil { + log.Printf("Error creating minio client (%s)", err) + os.Exit(1) + } + secrets := []Secret{ { Host: pod.IP, @@ -111,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") @@ -145,7 +167,7 @@ func main() { healthSrvErrCh := make(chan error) go func() { - if err := healthsrv.Start(healthSrvHost, healthSrvPort); err != nil { + if err := healthsrv.Start(healthSrvHost, healthSrvPort, minioClient); err != nil { healthSrvErrCh <- err } else { healthSrvErrCh <- errHealthSrvExited diff --git a/src/healthsrv/healthz_handler.go b/src/healthsrv/healthz_handler.go index 2a954df..4bf45d6 100644 --- a/src/healthsrv/healthz_handler.go +++ b/src/healthsrv/healthz_handler.go @@ -1,11 +1,26 @@ package healthsrv import ( + "encoding/json" + "fmt" "net/http" + + minio "github.com/minio/minio-go" ) -func healthZHandler() http.Handler { +func healthZHandler(minioClient minio.CloudStorageClient) http.Handler { + type resp struct { + Buckets []minio.BucketInfo `json:"buckets"` + } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) + buckets, err := minioClient.ListBuckets() + if err != nil { + http.Error(w, fmt.Sprintf("Error listing buckets (%s)", err), http.StatusInternalServerError) + return + } + if err := json.NewEncoder(w).Encode(resp{Buckets: buckets}); err != nil { + http.Error(w, fmt.Sprintf("Error encoding buckets json (%s)", err), http.StatusInternalServerError) + return + } }) } diff --git a/src/healthsrv/server.go b/src/healthsrv/server.go index 9ea009a..541dde4 100644 --- a/src/healthsrv/server.go +++ b/src/healthsrv/server.go @@ -2,6 +2,7 @@ package healthsrv import ( "fmt" + minio "github.com/minio/minio-go" "net/http" ) @@ -11,9 +12,9 @@ const ( ) // 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) error { +func Start(host string, port int, minioClient minio.CloudStorageClient) error { mux := http.NewServeMux() - mux.Handle("/healthz", healthZHandler()) + mux.Handle("/healthz", healthZHandler(minioClient)) hostStr := fmt.Sprintf("%s:%d", host, port) return http.ListenAndServe(hostStr, mux) From 7597cb8768e909dfd6022f428d49a1bc2e3bed1e Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 16:20:14 -0800 Subject: [PATCH 05/14] fix(src/healthsrv/healthz_handler.go): add logging for health check errors --- src/healthsrv/healthz_handler.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/healthsrv/healthz_handler.go b/src/healthsrv/healthz_handler.go index 4bf45d6..5ca0d81 100644 --- a/src/healthsrv/healthz_handler.go +++ b/src/healthsrv/healthz_handler.go @@ -3,6 +3,7 @@ package healthsrv import ( "encoding/json" "fmt" + "log" "net/http" minio "github.com/minio/minio-go" @@ -15,11 +16,15 @@ func healthZHandler(minioClient minio.CloudStorageClient) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { buckets, err := minioClient.ListBuckets() if err != nil { - http.Error(w, fmt.Sprintf("Error listing buckets (%s)", err), http.StatusInternalServerError) + 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(resp{Buckets: buckets}); err != nil { - http.Error(w, fmt.Sprintf("Error encoding buckets json (%s)", err), http.StatusInternalServerError) + str := fmt.Sprintf("Probe error: encoding buckets json (%s)", err) + log.Println(str) + http.Error(w, str, http.StatusInternalServerError) return } }) From e4376bd667801dce5da6bff50655d5cfc33d7817 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 16:20:44 -0800 Subject: [PATCH 06/14] fix(Makefile): add ability to run go unit tests --- Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 From ed3bc6192bf09682dd4aab62ef18ccceedf217b3 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 16:23:24 -0800 Subject: [PATCH 07/14] fix(boot.go,boot_test.go): move minio client creation logic out and add a test for it --- boot.go | 26 +++++++++++++------------- boot_test.go | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 boot_test.go diff --git a/boot.go b/boot.go index b268db6..764ee50 100644 --- a/boot.go +++ b/boot.go @@ -19,9 +19,9 @@ import ( ) const ( - localMinioScheme = "http" - localMinioHost = "localhost" - localMinioPort = 9000 + localMinioInsecure = true + localMinioHost = "localhost" + localMinioPort = 9000 ) var ( @@ -106,21 +106,21 @@ 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() - insecure := true - if localMinioScheme == "https" { - insecure = false - } - minioClient, err := minio.New( - fmt.Sprintf("%s://%s:%d", localMinioScheme, localMinioHost, localMinioPort), - key, - access, - insecure, - ) + minioClient, err := newMinioClient(localMinioHost, localMinioPort, key, access, localMinioInsecure) if err != nil { log.Printf("Error creating minio client (%s)", err) os.Exit(1) 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") + } +} From 566a81e84bbb27125cd8168ee49bf7e768729c35 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Thu, 4 Feb 2016 16:24:14 -0800 Subject: [PATCH 08/14] fix(manifests/deis-minio-rc.yaml): add liveness and readiness probes also specify the health check server port --- manifests/deis-minio-rc.yaml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/manifests/deis-minio-rc.yaml b/manifests/deis-minio-rc.yaml index a4a6b13..99f20b1 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: "8095" ports: - containerPort: 9000 + - containerPort: 8095 + livenessProbe: + httpGet: + path: /healthz + port: 8095 + initialDelaySeconds: 30 + timeoutSeconds: 1 + readinessProbe: + httpGet: + path: /healthz + port: 8095 + initialDelaySeconds: 30 + timeoutSeconds: 1 command: - boot args: From acdbcf7aef10b5a2611df9eac225085186ff72a1 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Fri, 5 Feb 2016 09:18:54 -0800 Subject: [PATCH 09/14] fix(manifests/deis-minio-rc.yaml): change the health check port to match the default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …while still keeping it explicitly defined --- manifests/deis-minio-rc.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manifests/deis-minio-rc.yaml b/manifests/deis-minio-rc.yaml index 99f20b1..90bc2af 100644 --- a/manifests/deis-minio-rc.yaml +++ b/manifests/deis-minio-rc.yaml @@ -20,20 +20,20 @@ spec: imagePullPolicy: Always env: - name: HEALTH_SERVER_PORT - value: "8095" + value: "8082" ports: - containerPort: 9000 - containerPort: 8095 livenessProbe: httpGet: path: /healthz - port: 8095 + port: 8092 initialDelaySeconds: 30 timeoutSeconds: 1 readinessProbe: httpGet: path: /healthz - port: 8095 + port: 8092 initialDelaySeconds: 30 timeoutSeconds: 1 command: From eef0711a2a3a0c3afff63445ddb5d4c4d522d6f8 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Fri, 5 Feb 2016 09:40:35 -0800 Subject: [PATCH 10/14] fix(src/healthsrv/healtz_handler.go,src/storage): create a new interface for listing buckets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Go minio client adheres to it, and it will be used for more easily testing the healthz endpoint handler. The alternative was to use this interface: https://godoc.org/github.com/minio/minio-go#CloudStorageClient … --- src/healthsrv/healthz_handler.go | 14 ++++++++------ src/storage/bucket_lister.go | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 src/storage/bucket_lister.go diff --git a/src/healthsrv/healthz_handler.go b/src/healthsrv/healthz_handler.go index 5ca0d81..80700a9 100644 --- a/src/healthsrv/healthz_handler.go +++ b/src/healthsrv/healthz_handler.go @@ -6,22 +6,24 @@ import ( "log" "net/http" + "github.com/deis/minio/src/storage" minio "github.com/minio/minio-go" ) -func healthZHandler(minioClient minio.CloudStorageClient) http.Handler { - type resp struct { - Buckets []minio.BucketInfo `json:"buckets"` - } +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 := minioClient.ListBuckets() + 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(resp{Buckets: buckets}); err != nil { + 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) 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 +} From 4e774e9ab3db0b2867a470e7e0803ee5f3f47a9e Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Fri, 5 Feb 2016 09:40:49 -0800 Subject: [PATCH 11/14] fix(src/healthsrv/healthz_handler_test.go): add test for the healthz handler --- src/healthsrv/healthz_handler_test.go | 50 +++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/healthsrv/healthz_handler_test.go 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) + } + } +} From 08099c9503ea2908b00df85b422fd4eeee27dab8 Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Fri, 5 Feb 2016 10:00:19 -0800 Subject: [PATCH 12/14] fix(glide.lock): re-run glide up gets a version back for launchpad --- glide.lock | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/glide.lock b/glide.lock index cd5bd33..66ced82 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -updated: 2016-02-04T23:58:05.077980188Z +updated: 2016-02-05T17:57:29.826338601Z imports: - name: bitbucket.org/bertimus9/systemstat version: 1468fd0db20598383c9393cccaa547de6ad99e5e @@ -303,7 +303,6 @@ imports: version: 3986be78bf859e01f01af631ad76da5b269d270c - name: github.com/Graylog2/go-gelf version: 06974fc6689396066f6ebf5bab951d41979e3386 - repo: https://github.com/Graylog2/go-gelf - name: github.com/hashicorp/consul version: 954aec66231b79c161a4122b023fbcad13047f79 subpackages: @@ -401,7 +400,6 @@ imports: version: c5884ce9ce3ac73b025d0bc58c4d3d72870edc0b - name: github.com/mistifyio/go-zfs version: 1b4ae6fb4e77b095934d4430860ff202060169f8 - repo: https://github.com/mistifyio/go-zfs - name: github.com/mitchellh/cli version: 8102d0ed5ea2709ade1243798785888175f6e415 - name: github.com/mitchellh/mapstructure @@ -599,7 +597,7 @@ imports: subpackages: - pkg - name: launchpad.net/gocheck - version: "" + version: "87" - name: speter.net/go/exp/math/dec/inf version: 42ca6cd68aa922bc3f32f1e056e61b65945d9ad7 devImports: [] From 9b7d68b38ea040921f91c3c7f30e404efddfc77c Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Fri, 5 Feb 2016 10:59:49 -0800 Subject: [PATCH 13/14] fix(glide.yaml): add version to minio-go dependency --- glide.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/glide.yaml b/glide.yaml index 1d5b377..fef1881 100644 --- a/glide.yaml +++ b/glide.yaml @@ -19,3 +19,4 @@ import: - package: github.com/google/protobuf version: b640f216a56ae25aab9a1fc6f21aa1a56c304494 - package: github.com/minio/minio-go + version: 0.2.5 From c2353e4fdebb3df2ba2d9acb5cbd00e6f2751b4f Mon Sep 17 00:00:00 2001 From: Aaron Schlesinger Date: Fri, 5 Feb 2016 13:15:10 -0800 Subject: [PATCH 14/14] fix(glide.yaml,glide.lock): add utils and aboutme sub-packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit also re-run ‘glide up’, which adds versions back in for github repositories. finally, set the minio version to latest (as of this writing) --- glide.lock | 87 +++++++++++++++++++++++++++++------------------------- glide.yaml | 7 ++--- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/glide.lock b/glide.lock index 66ced82..d45cc9a 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -updated: 2016-02-05T17:57:29.826338601Z +updated: 2016-02-05T21:14:28.15941846Z imports: - name: bitbucket.org/bertimus9/systemstat version: 1468fd0db20598383c9393cccaa547de6ad99e5e @@ -18,16 +18,12 @@ imports: - name: code.google.com/p/go.text version: "" repo: https://code.google.com/p/go.text -- name: code.google.com/p/goauth2 - version: "" - repo: https://code.google.com/p/goauth2 - name: code.google.com/p/google-api-go-client version: "" - subpackages: - - bigquery/v2 - - googleapi + repo: https://code.google.com/p/google-api-go-client - name: code.google.com/p/goprotobuf - version: 68415e7123da32b07eab49c96d2c4d6158360e9b + version: "" + repo: https://code.google.com/p/goprotobuf - name: code.google.com/p/gosqlite version: "" repo: https://code.google.com/p/gosqlite @@ -36,12 +32,6 @@ imports: 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 @@ -59,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 @@ -79,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 @@ -94,7 +86,7 @@ imports: - 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 @@ -102,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 @@ -183,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: @@ -203,12 +197,20 @@ 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 @@ -226,7 +228,7 @@ imports: - name: github.com/feyeleanor/slices version: bb44bb2e4817fe71ba7082d351fd582e7d40e3ea - name: github.com/fsouza/go-dockerclient - version: "" + version: 76fd6c68cf24c48ee6a2b25def997182a29f940e - name: github.com/garyburd/redigo version: 535138d7bcd717d6531c701ef5933d98b1866257 subpackages: @@ -235,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 @@ -285,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: @@ -300,7 +300,7 @@ 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 @@ -320,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 @@ -330,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 @@ -364,7 +364,7 @@ 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/kimor79/gollectd @@ -376,9 +376,11 @@ 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: @@ -401,7 +403,7 @@ imports: - 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 @@ -421,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 @@ -456,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 @@ -477,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 @@ -492,7 +496,7 @@ imports: - name: github.com/spf13/pflag version: 8e7dc108ab3a1ab6ce6d922bbaff5657b88e8e49 - name: github.com/stathat/go - version: 01d012b9ee2ecc107cb28b6dd32d9019ed5c1d77 + version: cf69b0bcb80478755dc0ea1120b36000e35dcbbb - name: github.com/stevvooe/resumable version: 51ad44105773cafcbe91927f70ac68e1bf78f8b4 - name: github.com/stretchr/objx @@ -550,7 +554,7 @@ imports: subpackages: - unix - name: golang.org/x/text - version: cf4986612c83df6c55578ba198316d1684a9a287 + version: db2353fc1b663d79d1001e206afc02a5ec9f4291 - name: golang.org/x/tools version: 4f50f44d7a3206e9e28b984e023efce2a4a75369 subpackages: @@ -564,7 +568,7 @@ imports: - container/v1beta1 - googleapi - name: google.golang.org/appengine - version: 58c0e2a2044a8d1abd8dd1d97939cd74497d0806 + version: 6a436539be38c296a8075a871cc536686b458371 - name: google.golang.org/cloud version: 2e43671e4ad874a7bca65746ff3edb38e6e93762 subpackages: @@ -575,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,7 +601,8 @@ imports: subpackages: - pkg - name: launchpad.net/gocheck - version: "87" + 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 fef1881..0f48a18 100644 --- a/glide.yaml +++ b/glide.yaml @@ -15,8 +15,7 @@ import: - package: github.com/deis/pkg version: f63d9718b86f17c9320f838fb3eb6039cadb9691 subpackages: - - aboutme -- package: github.com/google/protobuf - version: b640f216a56ae25aab9a1fc6f21aa1a56c304494 + - /aboutme + - /utils - package: github.com/minio/minio-go - version: 0.2.5 + version: c5884ce9ce3ac73b025d0bc58c4d3d72870edc0b