From 7c4b0837b6fae674fbfdd56853a226592df820e6 Mon Sep 17 00:00:00 2001 From: gad0lin Date: Wed, 17 May 2017 21:59:19 -0700 Subject: [PATCH 01/13] Add build information in README.md (#41) Add build information in README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b9d0f79..bc2349e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ clair: # Building the latest binaries -**clairctl** requires at least Go 1.7. +**clairctl** requires Go 1.7+. Install Glide: ``` @@ -65,7 +65,9 @@ curl https://glide.sh/get | sh Clone and build: ``` git clone github.com/jgsqware/clairctl $GOPATH/src/github.com/jgsqware/clairctl +cd $GOPATH/src/github.com/jgsqware/clairctl glide install -v +go generate ./clair go build ``` From 5a8ce864512621d2d32419aeb6e59bb203c172c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?JG=C2=B2?= Date: Thu, 18 May 2017 16:21:24 +0200 Subject: [PATCH 02/13] Use authorization header (#40) * use authorization header from clair * disable local server if not local push * to rerun ci * fix layering for local images * fix go-bindata * add upload artifact --- .travis.yml | 7 +++++++ clair/layering.go | 8 ++++--- clair/push.go | 37 ++++++++++++++++++++++++++++++++- clair/templates.go | 4 ++-- cmd/analyze.go | 5 ++++- cmd/push.go | 4 +++- contrib/README.md | 2 +- contrib/docker-compose.yml | 4 ++++ docker/dockerdist/dockerdist.go | 4 ++-- 9 files changed, 64 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 78602d1..8d265e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,15 @@ install: - go get -v github.com/Masterminds/glide - cd $GOPATH/src/github.com/Masterminds/glide && git checkout tags/v0.12.3 && go install && cd - - glide install -v + - go get -u github.com/jteeuwen/go-bindata/... +addons: + artifacts: true + paths: + - ./clairctl + script: +- go generate ./clair - go build -ldflags "-X github.com/jgsqware/clairctl/cmd.version=$(cat VERSION)" -v deploy: diff --git a/clair/layering.go b/clair/layering.go index 6301025..f64e042 100644 --- a/clair/layering.go +++ b/clair/layering.go @@ -8,6 +8,7 @@ import ( "github.com/coreos/clair/api/v1" "github.com/docker/docker/reference" "github.com/jgsqware/clairctl/config" + "github.com/jgsqware/clairctl/docker/dockerdist" "github.com/jgsqware/clairctl/xstrings" ) @@ -49,20 +50,21 @@ func (layers *layering) pushAll() error { lUID := xstrings.Substr(digest, 0, 12) log.Infof("Pushing Layer %d/%d [%v]", index+1, layerCount, lUID) - insertRegistryMapping(digest, layers.image.Hostname()) + u, _ := dockerdist.GetPushURL(layers.image.Hostname()) payload := v1.LayerEnvelope{Layer: &v1.Layer{ Name: digest, - Path: blobsURI(layers.image.Hostname(), layers.image.RemoteName(), digest), + Path: blobsURI(u.String(), layers.image.RemoteName(), digest), ParentName: layers.parentID, Format: "Docker", }} //FIXME Update to TLS if config.IsLocal { + payload.Layer.Path = strings.Replace(payload.Layer.Path, u.String(), layers.hURL, 1) payload.Layer.Path += "/layer.tar" } - payload.Layer.Path = strings.Replace(payload.Layer.Path, layers.image.Hostname(), layers.hURL, 1) + if err := pushLayer(payload); err != nil { log.Infof("adding layer %d/%d [%v]: %v", index+1, layerCount, lUID, err) if err != ErrUnanalizedLayer { diff --git a/clair/push.go b/clair/push.go index c1cca5f..d8f2160 100644 --- a/clair/push.go +++ b/clair/push.go @@ -2,10 +2,12 @@ package clair import ( "bytes" + "crypto/tls" "encoding/json" "errors" "fmt" "net/http" + "net/url" "strings" "github.com/coreos/clair/api/v1" @@ -13,7 +15,9 @@ import ( "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" "github.com/docker/docker/reference" + "github.com/jgsqware/clairctl/config" "github.com/jgsqware/clairctl/docker/dockerdist" + "github.com/spf13/viper" ) // ErrUnanalizedLayer is returned when the layer was not correctly analyzed @@ -49,11 +53,15 @@ func Push(image reference.NamedTagged, manifest distribution.Manifest) error { } return layers.pushAll() default: - return errors.New("Unsupported Schema version.") + return errors.New("unsupported Schema version") } } func pushLayer(layer v1.LayerEnvelope) error { + if config.IsLocal { + layer = auth(layer) + } + lJSON, err := json.Marshal(layer) if err != nil { return fmt.Errorf("marshalling layer: %v", err) @@ -83,6 +91,33 @@ func pushLayer(layer v1.LayerEnvelope) error { return nil } +func auth(layer v1.LayerEnvelope) v1.LayerEnvelope { + + out, _ := url.Parse(layer.Layer.Path) + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: viper.GetBool("auth.insecureSkipVerify")}, + DisableCompression: true, + }} + + log.Debugf("auth.insecureSkipVerify: %v", viper.GetBool("auth.insecureSkipVerify")) + log.Debugf("request.URL.String(): %v", out) + req, _ := http.NewRequest("HEAD", out.String(), nil) + + resp, err := client.Do(req) + if err != nil { + log.Errorf("response error: %v", err) + return v1.LayerEnvelope{} + } + + if resp.StatusCode == http.StatusUnauthorized { + log.Info("pull from clair is unauthorized") + dockerdist.AuthenticateResponse(client, resp, req) + } + layer.Layer.Headers = make(map[string]string) + layer.Layer.Headers["Authorization"] = req.Header.Get("Authorization") + return layer +} + func blobsURI(registry string, name string, digest string) string { return strings.Join([]string{registry, name, "blobs", digest}, "/") } diff --git a/clair/templates.go b/clair/templates.go index 98343d2..3664f11 100644 --- a/clair/templates.go +++ b/clair/templates.go @@ -68,7 +68,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templatesAnalysisTemplateHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xdc\x5c\x7d\x6f\xe3\xb6\x19\xff\x3f\x9f\x82\x75\xae\x70\xae\x8b\xe5\xd8\xc9\xa5\xa9\xcf\xf6\xd0\xe5\x2e\xe8\x80\xac\x1d\x76\x5d\x81\xa1\x38\x14\xb4\x45\xcb\x44\x64\x51\x93\xe8\xbc\x2c\xf0\x77\xdf\x43\x52\x92\x25\x92\x92\x28\x27\xc1\x80\xe9\x9a\xb3\x23\x92\xbf\xe7\x8d\xcf\x1b\xa5\xeb\xf4\x9b\x4f\xbf\x5c\xff\xfa\xaf\xbf\x7f\x46\x6b\xbe\x09\xe7\x47\x53\xf1\x81\x42\x1c\x05\xb3\x1e\x89\x7a\xf3\x23\xb8\x43\xb0\x3f\x3f\x42\x70\x4d\x39\xe5\x21\x99\x5f\x87\x98\x26\xe8\x9a\x45\x3c\x61\x21\x4a\x48\xcc\x12\x8e\x26\xe8\xf9\xd9\xfb\xeb\x06\x07\xe4\x67\xbc\x21\xbb\xdd\x74\xa8\x26\x1f\xa9\x95\x21\x8d\xee\xd0\x3a\x21\xab\x59\x7f\xcd\x79\x9c\x4e\x86\xc3\x15\x00\xa4\x5e\xc0\x58\x10\x12\x1c\xd3\xd4\x5b\xb2\xcd\x70\x99\xa6\x7f\x5e\xe1\x0d\x0d\x9f\x66\xbf\xc4\x24\xfa\xd3\x17\x1c\xa5\x93\x8b\xb3\xb3\xd3\x4b\xf5\x43\x39\x0e\xe9\xf2\xf4\xa2\xf8\x76\x5e\xfe\xd6\x07\x6e\xc2\x59\x3f\xe5\x4f\x21\x49\xd7\x84\xf0\x3e\xe2\x4f\x31\x99\xf5\x39\x79\xe4\x02\xbb\x3f\x2f\xb1\x23\xe6\xf6\xf6\x73\x7b\x8a\xbf\x5e\xce\xdf\x06\x3f\x2e\xfd\xc8\x5b\x30\xc6\x53\x9e\xe0\x58\xfc\x22\x58\x14\x7c\x0f\xf0\x03\x49\xd9\x86\x0c\x2f\xbc\x4b\x6f\x24\x90\x2b\xb7\xbd\x0d\x85\xb9\x69\xda\xcb\xc5\x97\x54\x14\x6d\x71\x2d\x98\xff\x84\x9e\x8b\x5f\xc5\x25\x97\x2b\xc9\x27\xa8\x2f\x64\x47\x42\xf6\xfe\x29\x4a\xe1\x63\x90\x92\x84\xae\x3e\x56\x56\x6c\x70\x12\xd0\x68\x82\xce\xaa\xb7\x63\xec\xfb\x34\x0a\x8c\xfb\x0b\xbc\xbc\x0b\x12\xb6\x8d\xfc\x09\x0a\xd6\x2c\xe5\x0f\x6b\xca\x89\x75\xed\x60\xc1\x38\x67\x9b\x09\x1a\x93\xcd\x7e\xc2\xae\xf8\x36\xfc\x0e\xfd\xfa\x14\xb3\x00\x94\xb2\x7e\x42\xdf\x0d\x8b\x81\xe2\x8b\x07\x26\xf5\x6d\x12\xa6\xf4\x3f\x64\x82\x46\xde\x45\x2d\x72\x10\xb2\x05\x16\x5b\xf0\x89\x6d\xb9\x1d\x7c\x09\x48\x98\x46\x24\xd1\x28\xec\x45\x2f\x0b\xbf\xb3\x21\x00\x7f\xc9\x8a\x3e\x4e\xf0\x8a\x1b\x30\x02\x9e\x44\x7c\x82\x7a\xbd\xaa\x7a\x7c\x9a\xc6\xc0\xd7\x04\x2d\x42\xb6\xbc\xab\x8e\x49\x44\x18\x61\x7c\xdd\x4c\x3a\x61\x0f\x1a\xbd\xc2\x90\x68\x30\x3e\x8b\x1f\x5b\x97\x5b\x99\x7e\x0d\xde\x7e\x5f\x86\x38\x4d\xbf\x9b\xf5\x96\x2c\x1c\xf4\xbe\xd6\x6b\xb7\xca\xa6\xb8\x56\x21\xc3\xa0\xb1\x90\xac\xb8\xb6\xed\xd8\xa3\x30\xba\x5c\xb8\x60\x89\x4f\x12\xd8\x5d\x2d\x32\x0a\xf2\x97\x1a\xf5\x07\xea\xf3\xf5\x04\x7d\x38\xfb\xb6\x79\x6d\x8c\x23\x12\x6a\x6b\x61\x57\x15\xcc\x8f\x60\xe3\x95\x77\x95\xe2\x51\xf2\x95\x60\x9f\x6e\xd3\x09\xba\xd0\x85\x2b\xbb\x8e\xc5\x6b\xa4\x88\x6b\xec\x83\x65\x10\x28\x06\x8d\xe0\x67\x0c\x3f\xc7\x64\x2c\xfe\xb8\xf0\xbb\x1e\x5b\xf7\xc4\x80\xb3\xb8\xce\xc1\x0b\x27\xf5\x2a\x5e\x5a\x92\x27\x9f\x90\xb2\x90\xfa\x92\xab\x00\xbc\x26\x85\x51\xe6\xc0\xd3\x04\xf6\x02\x1f\x2c\xd7\x34\xd4\x1d\x39\xe3\x2d\x87\xb7\xba\x1a\xa8\xfc\x27\x08\x01\xb0\x4d\xad\x1e\x8c\xe3\x78\xb0\x56\xe3\xcf\xb5\xaa\x3e\x1e\x8f\x7e\xb8\xbc\x39\xd7\xf6\x32\x0b\x59\x62\x35\xc3\xde\x8d\x84\x11\xb2\x9f\x9a\xd8\x38\xba\x14\x36\x32\xc6\x2b\x96\x04\x6f\x14\xc6\x14\x33\x8f\xc7\x97\xe7\xe3\xf3\x2b\x0d\x8c\xa5\x94\x53\x06\x14\x21\x91\x60\x4e\xef\x49\xb3\x56\x4b\x32\xaf\x47\x75\x21\xe0\xa3\x19\x32\x1f\x08\x0d\xd6\xc2\xb7\xc4\x07\x49\xaa\x33\x44\x62\x1b\x40\x76\x8a\xd2\x15\x4b\xc0\x18\xdb\x38\x26\xc9\x12\xa7\x0e\xbc\x50\x91\xbf\xeb\x7c\xdc\xd4\x8d\xa4\x04\x89\x36\x00\x36\x97\x10\x1e\x75\x4e\x32\xc3\x58\x55\x55\xb6\x6a\x12\x2c\xf0\xc9\xf8\xc3\x87\x53\xb4\xff\xcb\xbb\x7a\xef\xb8\x83\x8f\x3f\x5f\x7f\xbe\xb9\x19\xb9\x4a\x67\xf8\x55\x29\x09\x19\x6e\xd3\xac\x6d\x1b\xa1\x74\xbb\x01\xcb\xe9\xa9\x1c\x8a\x0b\x02\x96\x56\x38\xde\x65\x6d\xa6\xcb\x2a\x27\xab\x83\x64\x63\xf5\x41\xa1\x3d\x53\xc8\xf4\x5c\x9b\x6a\xf0\x96\x33\xdd\x7f\x1e\x07\x59\x94\xfd\xe1\xd2\x30\x7f\x99\xf6\x79\x0d\x6d\x90\xe9\x8b\x28\x74\x10\x5b\x21\xbe\x26\x48\x71\x60\x95\x4f\x0d\x79\x11\xf3\x89\xbe\x05\x1b\xdc\x4a\x5c\x45\xa2\xa3\x91\x54\xb4\x25\xdf\xe5\xba\x1f\x1b\x91\x3c\x93\xcf\x1c\xc8\x15\x33\x76\xd3\xaa\x62\xdc\xf3\x99\x6e\xa2\x36\xee\x0f\x60\x4d\xcb\x4e\xe6\x84\xfa\xdc\x5b\x2e\xf9\x12\xfc\xf4\x51\xcf\x8a\xd5\x78\x97\xe7\x2d\xe9\xa1\x67\xa7\x48\xfd\xe7\x8d\x4b\xbe\xa9\x78\x29\x3b\xa4\xd5\x9d\x61\x49\xd9\xec\x2d\x7a\xf4\x3e\x91\x15\xd4\x5c\x23\x9b\x3e\xcb\x22\x2c\x42\x5c\xb6\x74\x1b\xea\x75\x02\x96\x58\x42\x29\xd9\x02\x7b\x4c\xae\x46\x64\xd4\x12\x30\xcb\xc0\x3f\x81\x09\x5b\x41\x3f\xff\x30\xfa\x7c\x79\xee\x0e\xfa\x37\x02\xe6\xdd\xb4\xc2\xde\xdc\xfc\xf8\xfd\xf8\xd2\x1d\xf6\x16\xaa\xcd\x36\xcc\xab\xbf\x5c\x9f\x5f\xfc\xe8\x8e\xf9\x33\x09\x20\x3a\xd2\x45\x68\xf5\x80\x0a\xf4\xf9\xf7\x17\xdf\x5f\xdc\xb8\x43\xff\x33\xba\x8b\xd8\x43\xf4\xda\xb8\x50\xd2\xb0\x78\x1b\xd7\x95\xcc\x11\x8b\x88\xd5\x19\xa1\xa5\x34\x4a\x88\xc2\xc1\xf1\x02\xbc\x60\x6b\x16\x83\x2a\x65\x8d\xce\xca\x95\xaa\xb8\xb4\xb2\xc9\xcc\xb0\xd9\x04\xe1\xc7\x13\x34\x18\x7d\x30\x26\xa8\x91\xf1\x2b\x95\xa7\x0d\x6e\x2e\x05\x2d\x6a\x25\x4b\x99\xd4\x5c\x2f\xcb\xc8\xa2\x07\x8a\xbc\x1a\xd6\x8b\x6f\x59\x57\xec\x83\x90\xf8\x23\xeb\x99\x18\x27\x50\x65\x74\x35\x71\x73\x43\xd7\xef\x77\x33\xa6\xcc\x76\xa6\x25\x95\x1d\x3e\xd4\x18\x38\xb7\x9f\xa1\xb6\xa6\x16\x2d\xdb\x70\x67\xf6\x6c\xa1\xb7\xf2\x4a\xff\xd9\x9a\x91\x34\xaa\xac\x77\xeb\x6d\x55\x2e\x9b\xcb\xfa\xad\xfb\x6e\x05\x91\xa7\x18\x99\x4d\x3b\x1b\x66\x41\xa0\x42\xd5\x93\xfd\xff\xb9\x65\xc4\xbe\x97\x7f\xb5\x5b\xc6\xf0\xc6\xff\x89\x95\xd0\x1c\x74\x71\xaf\x19\x89\xdd\x93\x04\x6a\x0c\x70\xcf\x35\xf5\x7d\x12\x59\xfa\x82\xfd\x14\x12\x86\x34\x4e\x69\xea\x4c\x79\xb2\x16\x8b\x6d\x11\x9f\xc5\x78\x49\x39\x58\xc5\xbb\xea\x8c\xd6\x18\xef\x2d\x56\x16\xc5\x6f\x6e\xd3\xd1\x95\x61\xab\xcc\x48\x3e\xdd\x54\xeb\xa8\x4a\xed\xbb\xc0\x49\x6a\xaf\x76\x61\x64\xb0\x08\xea\xd8\xa9\x2f\x64\x8b\x9a\xd0\x60\x28\xe7\xf5\xb2\x3e\x3f\xb9\x75\xa5\x92\x35\xdc\xe5\x34\xc9\xc9\x35\x0d\xbf\x30\xce\x0a\xc4\xa5\x1c\xb2\xe1\xa0\xd2\x28\xa3\x14\x58\xb5\x20\x6e\x2b\xd9\x33\x11\x8b\x32\xf3\x45\x15\x66\x0e\x56\x54\x97\x2f\x2c\x2c\x73\x3c\x59\x54\xbe\xb0\x9e\xcc\xb1\xb2\x5a\xf2\x85\x65\x64\x8e\x76\x6b\x1c\x58\x76\xae\x1e\x73\xa8\x52\xe5\xf8\xc2\xe2\x2e\x47\xcc\x0b\xc6\x83\xe0\xc0\x67\xef\xb7\x61\x44\x12\xbc\xa0\x21\x98\x93\xd4\xb8\x6f\x43\x33\x2e\xa2\x05\xc4\xf7\x2e\xdd\xb4\xf5\x54\x57\x51\xf0\x34\x76\x4e\xcd\x19\x2b\x82\xf9\x36\x01\x4e\xe7\x68\xab\x6f\xbe\x0e\x4f\x04\x9a\x98\x68\x22\x11\xd2\x94\xe7\x19\xa6\x5a\x36\xdb\x10\x33\x24\xdd\x3a\x2f\x3a\xdc\xc9\x30\xeb\x8f\x27\xab\x79\xf5\xf8\xfa\xe6\xd3\xd5\xa7\x6b\x27\xcc\x3f\xfe\x90\xcf\xac\xea\xce\xc4\x46\xf6\x93\x9c\x3d\x8c\xbe\x99\xac\x38\x59\x15\x32\x16\x07\x43\xe8\x1b\xba\x11\x3a\xc7\x6d\x85\x6e\x19\x59\x3f\x6e\x32\xce\x83\xaf\xf4\x83\xad\x7c\x46\x92\x9d\x3d\x78\x35\xcf\x75\xea\x25\xd9\xb7\xe8\x11\xde\x98\x45\x9c\xd4\xb4\x43\xf0\x34\x60\xf7\x3d\x7a\x3d\xae\x53\x18\x35\x90\x55\x93\xde\x80\xea\x12\x50\x0d\xd4\xbc\x4b\x6f\xc0\x75\x09\xad\x06\xae\x6c\xd3\x1b\x40\x5d\x82\xac\x01\x5a\xee\xd3\x1b\xb0\x5d\xc2\xad\x81\x5d\x34\xea\x07\x01\x43\xe0\x85\xea\x82\xd4\x95\x4b\x72\x2c\xfb\xb0\xfb\xe4\x72\x9b\xa4\x82\x46\xcc\xa8\x79\x12\x6d\x77\x58\x71\xd5\x47\x1e\x3d\x4a\x34\xc9\x21\x2e\x4b\xa8\xb5\xe9\xcd\x22\x49\x56\xa1\x36\xa5\x7a\x87\x28\x28\x11\xbd\x65\xc8\x52\xe2\x97\x22\xb6\xd3\x01\x47\xc3\x49\xf6\x40\x54\xf3\x75\x28\xab\x90\x18\x27\x16\xfb\x24\x67\xd6\xa8\xcd\x87\xcd\x95\xc3\x10\xc3\x52\x95\xe3\xe6\xb6\x68\x55\x61\xde\x76\xa6\xdc\xf6\xec\x42\x48\x06\x4c\x74\xa5\xd2\xb1\xa7\xed\x70\x72\x6d\x76\x8b\xa5\x66\xbf\xb1\x1a\x36\x7a\xdf\xd6\x27\x6a\x99\xaa\x13\x1b\x65\x37\x3d\xe4\xd9\xc1\xae\x8f\x8e\x05\xb6\x05\x3e\xcf\x12\xed\xf8\x4e\xb9\xc2\x42\x41\x64\x0b\x07\x74\x97\x9c\x61\x41\x57\x59\xc3\x01\xdf\x25\x77\x58\xf0\x21\x7b\x38\x80\xbb\xe4\x10\x0b\xf8\x3e\x8b\x38\xd0\x70\xc9\x25\x16\x1a\x59\x36\x79\x25\x02\x79\xe3\x3b\xb0\x3d\x01\x7b\x93\x68\xd6\xea\x63\x82\xd8\xc0\xa7\x09\x59\x66\xbd\x39\x7b\x18\x24\x04\xf2\x40\x6a\x1c\xd6\x56\xbc\xf9\x5c\xe7\xa2\xfe\x2c\xc6\x41\x13\x87\x84\xc6\x3c\x22\x5d\x35\x9d\x3a\x1b\x32\xbb\x32\xf3\x3a\x3d\xb9\x15\xf9\xb5\x1a\x74\x2b\xf8\x6b\x74\xeb\x56\xe0\xd7\x69\xdd\xad\xd0\xaf\xd0\xc7\x5b\x71\x5f\xaf\xa9\xb7\xc2\x1f\xdc\xe1\x4f\x87\xd9\x5b\x77\xd3\xa1\x7a\x85\xf1\x68\x2a\xde\xbb\xcb\xde\x00\x14\xc7\x9c\xf2\x75\x27\xf1\xb6\x53\xf6\x3a\x59\x6f\xff\x86\xde\x34\x7b\x53\x23\x9b\xb2\x7f\x77\xa3\x34\x47\xcd\x1b\x59\xdf\x87\x04\x9a\xa3\x12\xda\x50\x2d\xce\x5e\x07\xd4\x19\xd8\xbf\xaf\x90\xbf\x97\x66\x50\x19\xcf\xe5\xbb\x95\xe6\x5b\x96\x30\x52\x99\xfa\xfc\x8c\xde\x51\x8c\x26\x33\xe4\xed\x76\x47\x55\x94\x54\x85\x9f\x9c\x6c\x16\x88\x35\x5a\x39\x73\xe6\x5d\x05\xff\x40\xf9\x1a\xbd\xd3\x1a\x82\x6b\xb0\x04\x17\x44\x71\x18\xfe\xa6\xf5\x0a\xc0\xce\x6e\x67\x05\x9b\xc6\xf3\x69\x1a\xe3\x82\x21\xf1\xd2\x60\x0f\x6e\x81\x26\xa2\x60\xfe\x2b\xe3\xe0\xbd\x42\x62\x2b\x35\x4f\x8e\xef\x76\xfa\x11\x8e\x30\xbb\x5c\x0f\x5f\x00\x1b\x3e\x62\xbb\x28\xf5\x03\x25\xd3\x94\x93\x95\x45\x51\x7b\xb5\xd0\x15\x0a\x38\x3a\xb1\xb3\xaa\xd4\xd3\xcb\xb6\x72\xef\x3d\x3a\xab\xd1\x88\x4e\x5e\x06\xec\x7c\xd9\x3c\x77\x85\x09\xca\x75\x54\xa7\x1b\x8d\xa0\xd8\x28\x85\x56\x6a\x6d\xab\x04\x21\x91\x0f\x4a\x75\x13\x68\xef\xfa\x5d\x65\x2a\xad\x9c\x97\x02\x88\xb3\x64\xa5\xf5\x6f\x25\x1c\xc4\xcb\xae\x52\x89\x25\x73\x11\x67\x9d\xe5\x10\x2b\xde\x4a\x00\x95\x4b\xba\xca\x90\xad\x9a\x67\x99\xc8\x59\x92\x6c\xdd\x5b\x09\x23\x32\x6e\x57\x51\xe4\x9a\xb9\xcc\xd5\xce\x62\xc8\x35\x6f\x25\x44\x5e\x93\x74\x15\xa4\x58\x37\x2f\xaa\x1a\x67\x81\x8a\xb5\x6f\x25\x54\x56\xc2\x75\x95\x29\x5f\x36\xcf\x4b\x40\x67\x89\xf2\x95\x9d\x05\xaa\x49\x03\xb5\x4b\xcb\x3c\x57\x6b\x93\x86\x54\x50\x2b\x28\x92\xe5\xc8\xac\x97\xb5\x18\x75\x42\xfe\x23\x23\x64\x08\xfb\x6d\xaf\x4d\xcc\xfa\x7d\x73\x18\xed\xd2\xd6\x39\x80\xb8\xf4\xa4\xc3\x08\x67\x4e\x78\x00\xd1\x2c\x0a\x1d\x46\xb6\x08\x61\x07\x10\x16\x81\xfc\x30\xaa\x2a\x05\x1c\x40\xb2\x94\x03\x0f\xa3\x5c\x49\xa2\x07\x30\x90\x97\x17\x87\x51\xdf\x17\x27\xcd\xa4\x1b\x86\xea\xfc\xda\xb2\x04\x42\x85\xaa\x7e\xab\xb7\x8f\xea\x04\xac\x73\xf3\xe7\xe7\x04\x47\x01\x41\xef\xee\x4e\xdf\xdd\x8b\x8a\x57\x3f\x1a\xb7\x97\xbb\xc5\xb2\x7b\x1b\xbb\xb8\xa2\x56\x28\xf1\xbf\x88\xb3\x01\xca\x9f\x76\xbb\xfc\x5f\x25\x1d\x43\x61\xef\x89\xa2\x1f\xc1\xbd\xf6\x70\xe5\x33\xde\xac\xd4\xd2\x5c\xf9\xae\x44\x4b\x44\x9b\xef\x63\xb3\x97\xb7\x1e\x6e\xb1\x57\xae\xae\x88\xe4\xb8\xe0\x46\x1d\x6a\x37\xce\xaf\x19\x9a\x0e\xb1\xcd\x72\xf6\xcd\x62\xbb\xaf\xe1\x66\xbf\xee\x7f\xd7\x3a\x29\xd5\xf3\xe9\x4d\x9b\x9d\xb5\xb2\xe2\xc5\xbf\xb3\x70\x30\xa6\x7a\x56\xd2\x96\x73\xa8\x3f\xeb\x81\xda\x6e\x71\xca\x6f\xe5\xd3\x01\x65\xa7\x5e\x05\xa5\x01\x44\x02\xad\xcf\x2b\xd3\xb3\x67\x16\x3d\xe4\x63\x8e\x07\x9c\x05\x41\x48\x06\x72\xc4\x4e\x6b\x6e\xb9\x09\x3d\xea\x79\x0b\xd5\x92\xac\xf9\xa3\x8c\x16\x46\xe5\xb2\x6d\xd8\x3e\x49\x5c\xe0\x3a\xca\xfb\x52\xb0\x12\xf1\xdd\x1b\x54\x83\x62\x48\x35\x3e\x1d\xd8\x2c\x16\x9b\x52\xe6\xea\x75\x07\x41\xa8\x54\x25\x15\x01\xa1\xf0\x45\x24\xfb\x69\x39\xf4\x1b\x6c\x19\xb1\x45\xe5\xa8\xb8\x89\x06\xa8\xd2\x6d\xaf\x30\x5a\xe1\x01\x79\x84\x5f\x37\x58\xec\xe6\x01\x4f\x28\xa8\x49\x98\x1b\xc3\xb7\x81\x3a\x61\x9c\xf5\x78\xb2\x25\xbd\xbc\x9d\x76\x17\xb7\xd9\xcb\xf5\xab\xb0\x91\xa7\x99\xc7\xd1\x34\x92\xe4\x36\xcc\x85\xd3\xa2\x72\x37\x0d\x97\xed\xac\x3d\x79\x07\xc5\xe6\x81\xac\x3e\x10\x37\x42\x63\x2b\x72\xe1\x68\xe2\x79\xaa\xf0\xad\x52\xb0\xb7\x46\xb3\x56\x3a\x6a\x47\x14\x89\x05\xc0\x7a\xd6\x2d\xd3\x1d\x59\xc5\x67\xf1\x4e\x40\xba\x4c\x68\xcc\xf3\x5d\xd6\xc9\xde\x05\x1a\xce\x12\x9c\x40\xbc\x15\xff\x2c\x57\x84\x2c\x8e\x93\x80\xf0\x59\x6f\x11\xe2\xe8\x0e\x5a\x6a\xb8\xdf\x59\x0b\xd3\x61\x48\xbb\x6c\x57\xd7\x68\xe2\x8e\xdb\xd4\x76\x1c\x3a\xb7\x9d\xcf\xb6\xf4\x7a\x40\x36\xb5\xdf\x5e\x24\x68\xa8\x17\x59\xc5\xcc\xca\xd7\x4a\xe9\x55\x4e\xa6\x53\xb5\x83\xf6\x28\x27\xab\x6d\x24\xe7\x9e\xbc\x37\x1f\xab\xa6\x1c\xa9\x14\x94\xa4\x68\x86\x7c\xb6\xdc\x6e\x08\xd4\x95\xff\xde\x92\xe4\xe9\x0b\x09\x81\x08\x4b\x7e\x0c\xc3\x93\xfe\xef\x46\xba\xfa\xda\x7f\xaf\x3f\xdc\x8f\x52\x16\x12\x2f\x64\xc1\x49\x0e\x0a\x53\x2a\x73\x56\x2c\x41\x27\xf7\x38\x41\x14\xc8\xe5\x93\xbc\x90\x44\x01\x5f\x43\x34\x1d\x7d\x84\x81\xf9\x0c\x9d\xc1\xe7\x60\xa0\xf3\x2b\xae\x7c\xcd\xef\xf4\xab\xc7\xa2\x65\x48\x97\x77\x80\x54\x88\x48\x6c\x6b\xc4\x45\x3c\xe5\x00\x9e\x7a\xcd\xf7\x67\x71\x0e\x2e\x1d\xf9\x96\xa6\xdc\x53\xa8\x27\x7d\xf5\xf4\x5f\x17\x4c\x5c\xbb\xea\xad\xfd\xae\xda\xbd\x3f\xc9\xa6\x83\x51\x32\xd5\x4f\x87\xea\x58\x5c\x9c\x93\x8b\xff\x07\xc0\x7f\x03\x00\x00\xff\xff\xb3\xfc\x2e\xd8\x13\x40\x00\x00") +var _templatesAnalysisTemplateHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x5c\x7d\x6f\xe3\xb6\x19\xff\x3f\x9f\xe2\xa9\x73\x45\x5e\x16\xc9\xb1\x93\x4b\x53\xc5\xf6\xd0\xe5\x2e\xe8\x80\xb4\x1d\x7a\x5d\x81\xa1\x38\x14\xb4\x44\x4b\x44\x68\x51\xa3\xe8\x24\x9e\xe1\xef\x3e\x90\x7a\xb1\x24\x52\x12\xed\xcb\x61\xc0\x9c\x4b\x62\x4b\xe4\xef\x79\xe3\xf3\x46\x31\x37\xf9\xe6\xc3\x2f\xf7\xbf\xfd\xeb\x1f\x1f\x21\x12\x4b\x3a\x3b\x9a\xc8\x5f\x40\x51\x1c\x4e\x07\x38\x1e\xcc\x8e\x8e\x26\x11\x46\xc1\xec\x08\x00\x60\x22\x88\xa0\x78\x76\x4f\x11\xe1\x70\xcf\x62\xc1\x19\x05\x8e\x13\xc6\x05\x78\xb0\xd9\xb8\x7f\x5f\xa2\x10\xff\x8c\x96\x78\xbb\x9d\x0c\xb3\xc1\x47\xd9\x4c\x4a\xe2\x27\x88\x38\x5e\x4c\x4f\x22\x21\x92\xd4\x1b\x0e\x17\x2c\x16\xa9\x1b\x32\x16\x52\x8c\x12\x92\xba\x3e\x5b\x0e\xfd\x34\xfd\xeb\x02\x2d\x09\x5d\x4f\x7f\x49\x70\xfc\x97\x4f\x28\x4e\xbd\xeb\xcb\xcb\x8b\x9b\xec\x9b\x08\x44\x89\x7f\x71\x5d\xbe\xbb\xaa\xbe\x3b\x01\x8e\xe9\xf4\x24\x15\x6b\x8a\xd3\x08\x63\x71\x02\x62\x9d\xe0\xe9\x89\xc0\xaf\x42\x62\x9f\xcc\x2a\xec\xc8\xb1\x83\xdd\xd8\x41\xc6\xdf\xa0\xe0\x6f\x89\x5e\xfd\x20\x76\xe7\x8c\x89\x54\x70\x94\xc8\x0f\x92\x45\xc9\xb7\x83\x5e\x70\xca\x96\x78\x78\xed\xde\xb8\x23\x89\x5c\xbb\xec\x2e\x49\xec\xfa\x69\x3a\x28\xc4\x57\x54\x32\xda\xf2\x35\x67\xc1\x1a\x36\xe5\x47\xf9\x52\xd3\x33\xc9\x3d\x38\x91\xb2\x83\x94\xfd\xe4\x02\x52\x14\xa7\x4e\x8a\x39\x59\xdc\xd5\x66\x2c\x11\x0f\x49\xec\xc1\x65\xfd\x72\x82\x82\x80\xc4\xa1\x76\x7d\x8e\xfc\xa7\x90\xb3\x55\x1c\x78\x10\x46\x2c\x15\x2f\x11\x11\xd8\x38\xd7\x99\x33\x21\xd8\xd2\x83\x31\x5e\xee\x06\x6c\xcb\x77\xc3\x73\xf8\x6d\x9d\xb0\x90\xa3\x24\x5a\xc3\xf9\xb0\xbc\x51\xbe\x71\x29\x46\x81\x49\xc2\x94\xfc\x07\x7b\x30\x72\xaf\x5b\x91\x43\xca\xe6\x48\x2e\xc1\x35\x5b\x09\x33\xb8\xcf\x62\x81\x48\x8c\x79\x83\xc2\x4e\xf4\xaa\xf0\x5b\x13\x02\xc5\x88\x2f\xc8\xab\x87\x16\x42\x83\x91\xf0\x38\x16\x1e\x0c\x06\x75\xf5\x04\x24\x4d\x28\x5a\x7b\x30\xa7\xcc\x7f\xaa\xdf\x53\x88\x1e\xcc\x99\x88\xba\x49\x73\xf6\xd2\xa0\x57\x1a\x12\x9c\xf1\x65\xf2\xda\x3b\xdd\xc8\xf4\x5b\xf0\xf6\x87\x4f\x51\x9a\x9e\x4f\x07\x3e\xa3\xce\xe0\x73\xbb\x76\xeb\x6c\xca\xd7\x82\x32\x24\x3c\xa0\x78\x21\x1a\xcb\x8e\xbd\x4a\xa3\xab\x89\x73\xc6\x03\xcc\x9d\x39\xeb\x91\x51\x92\xbf\x69\x50\x7f\x21\x81\x88\x3c\x78\x7f\xf9\x6d\xf7\xdc\x04\xc5\x98\x36\xe6\x0e\xcf\x77\xcc\x8f\xf0\xf2\xae\xba\xaa\x32\x1e\x15\x5f\x1c\x05\x64\x95\x7a\x70\xdd\x14\xae\xea\x3a\x06\xaf\x51\x22\x46\x28\x60\x2f\x1e\x5c\x26\xaf\x30\x4a\x5e\x61\x9c\xbc\xc2\x31\x1e\xcb\x2f\x1b\x7e\xa3\xb1\x71\x4d\x38\x82\x25\x6d\x0e\x5e\x3a\xa9\x5b\xf3\xd2\x8a\x3c\xc5\x80\x94\x51\x12\x28\xae\x42\x44\xe2\x74\xce\x38\xb3\xe0\xc9\xa3\x28\x15\x8e\x1f\x11\xda\x74\xe4\x9c\xb7\x02\xde\xe8\x6a\xc3\x73\xf8\x11\xa3\x00\x73\xb3\x07\xa3\x24\x71\xa2\xec\xfe\xa6\x55\xd5\xc7\xe3\xd1\xf7\x37\x0f\x57\x8d\xb5\xcc\x28\xe3\x46\x33\xec\xdc\x48\x1a\x21\xff\x6e\x89\x8d\xa3\x1b\x69\x23\xed\x7e\xcd\x92\xe0\x48\x23\xaa\x91\xc7\xe3\x9b\xab\xf1\xd5\x6d\x03\x8c\xa5\x44\x10\x16\x7b\x32\x91\x20\x41\x9e\x71\xb7\x56\x2b\x32\x47\xa3\xb6\x10\x70\xa7\x87\xcc\x17\x4c\xc2\x48\xfa\x96\xfc\x85\x79\x7d\x84\x4c\x6c\x8e\xe0\x28\x4e\x17\x8c\x2f\x3d\x58\x25\x09\xe6\x3e\x4a\x2d\x78\x21\x32\x7f\xb7\xf9\xb8\xae\x1b\x45\x09\x51\x12\xc6\x1e\xf8\x38\xd6\x38\xc9\x0d\x63\x54\x55\xd5\xaa\x3c\x9c\xa3\xd3\xf1\xfb\xf7\x17\xb0\xfb\xe1\xde\x9e\x59\xae\xe0\xe3\x8f\xf7\x1f\x1f\x1e\x46\xb6\xd2\x69\x7e\x55\x49\x42\x9a\xdb\x74\x6b\xdb\x44\x28\x5d\x2d\x97\x88\x37\x53\x39\x25\x31\x76\xa2\x1c\xc7\xbd\x69\xcd\x74\x79\xe5\x64\x74\x90\xfc\x5e\x7b\x50\xe8\xcf\x14\x2a\x3d\xb7\xa6\x1a\xb4\x12\xac\xe9\x3f\xaf\x4e\x1e\x65\xbf\xbf\xd1\xcc\x5f\xa5\x7d\xd5\x42\x7b\x78\x0e\x9f\x64\xa1\x03\x6c\x01\x22\xc2\x90\x71\x60\x94\x2f\xbb\xe5\xc6\x2c\xc0\xcd\x25\xd8\xe1\x56\x50\x4d\x74\x24\x56\x8a\x36\xe4\xbb\x42\xf7\x63\x2d\x92\xe7\xf2\xe9\x37\x0a\xc5\x8c\xed\xb4\x9a\x31\xee\x06\xac\x69\xa2\x3e\xee\x0f\x60\xad\x91\x9d\xf4\x01\xed\xb9\xb7\x5a\xf2\x71\xb4\xbe\x6b\x66\xc5\x7a\xbc\x2b\xf2\x96\xf2\xd0\xcb\x0b\xc8\xfe\xb9\xe3\x8a\x6f\x66\xbc\x54\x1d\xd2\xe8\xce\xe3\xb3\x5a\x8e\xed\xd1\xa3\xfb\x01\x2f\x7c\x16\x8f\x4c\xfa\xac\x8a\x30\xa7\xa8\x6a\xe9\x3e\xd4\x7b\x4e\x04\xf1\x11\xed\x83\x3d\xc6\xb7\x23\x3c\xea\x09\x98\x55\xe0\x1f\x49\x18\xf5\x82\x7e\xfc\x7e\xf4\xf1\xe6\xca\x1e\xf4\x27\x1c\x90\xd5\xb2\x17\xf6\xe1\xe1\x87\xef\xc6\x37\xf6\xb0\x8f\xec\xa5\x17\xf3\xf6\x6f\xf7\x57\xd7\x3f\xd8\x63\xfe\x8c\x43\x4a\x42\x32\xa7\x46\x0f\xa8\x41\x5f\x7d\x77\xfd\xdd\xf5\x83\x3d\xf4\x3f\xe3\xa7\x98\xbd\xc4\x6f\x8d\x0b\x6e\xc2\x92\x55\xd2\x56\x32\xc7\x2c\xc6\x46\x67\xbc\xba\xd4\x4b\x88\xd2\xc1\xd1\x3c\x65\x74\xa5\x17\x83\x59\xca\x1a\x5d\x56\x2b\x55\xd0\xcb\x26\x3d\xc3\xe6\x03\xa4\x1f\x7b\xe0\x8c\xde\x6b\x03\xb2\x3b\xe3\x37\x2a\x4f\x3b\xdc\x1c\x6a\xb5\x92\xa1\x4c\xea\xae\x97\x55\x64\x69\x06\x8a\xa2\x1a\x6e\x16\xdf\xaa\xae\xd8\x05\x21\xf9\xa5\xea\x99\x04\x71\x1c\x8b\x7d\x4d\xdc\xdd\xd0\x9d\x9c\xec\x67\x4c\x95\xed\x74\x4b\x66\x76\x78\xdf\x62\xe0\xc2\x7e\x9a\xda\xba\x5a\xb4\x7c\xc1\x5d\x9a\xb3\x45\xb3\x95\xcf\xf4\x9f\xcf\x19\x29\xa3\xaa\x7a\xb7\xdd\x56\xd5\xb2\xb9\xaa\xdf\xb6\xf7\x46\x10\xb5\x8b\x91\xdb\x74\x6f\xc3\xcc\xf1\x82\xf1\x66\xb2\xff\x3f\xb7\x8c\x5c\xf7\xea\x47\xbf\x65\x34\x6f\xfc\x9f\x58\x09\x66\x10\x90\xe7\x86\x91\xd8\x33\xe6\x0b\x2a\xdd\x33\x22\x41\x80\x63\x43\x5f\xb0\x1b\x82\x29\x25\x49\x4a\x52\x6b\xca\x5e\x24\x27\x9b\x22\x3e\x4b\x90\x4f\xc4\xda\x03\xf7\x76\x6f\xb4\xce\x78\x6f\xb0\xb2\x2c\x7e\x0b\x9b\x8e\x6e\x35\x5b\xe5\x46\x0a\xc8\xb2\x5e\x47\xd5\x6a\xdf\x39\xe2\xa9\xb9\xda\x9d\x23\xee\xcc\xc3\x36\x76\xda\x0b\xd9\xb2\x26\xd4\x18\x2a\x78\xbd\x69\xcf\x4f\x76\x5d\xa9\x62\x0d\xed\xb3\x9b\x64\xe5\x9a\x9a\x5f\x68\x7b\x05\x50\xba\x6b\xc7\x46\xa5\x56\x46\x81\xa1\x20\xee\x2b\xd9\x73\x11\xcb\x32\xf3\x8b\x2a\xcc\x02\xac\xac\x2e\xbf\xb0\xb0\x2c\xf0\x54\x51\xf9\x85\xf5\x64\x81\x95\xd7\x92\x5f\x58\x46\x16\x68\x8f\xda\x86\xe5\xde\xd5\x63\x01\x55\xa9\x1c\xbf\xb0\xb8\x2b\x10\x8b\x82\xf1\x20\xb8\xe1\x39\x3c\xaf\x68\x8c\x39\x9a\x13\x4a\x04\xc1\x2d\xee\xdb\xd1\x8c\xcb\x68\x91\xbc\xee\xd5\x4d\x1b\x77\x75\x33\x0a\x6e\x83\x9d\x0b\x7d\xc4\x02\x23\xb1\xe2\x38\x85\x19\xac\x9a\x8b\x6f\x8f\x27\x02\x5d\x4c\x74\x91\xa0\x24\x15\x45\x86\xa9\x97\xcd\x26\xc4\x1c\xa9\x69\x9d\x2f\xda\xdc\xc9\x31\xdb\xb7\x27\xeb\x79\xf5\xf8\xfe\xe1\xc3\xed\x87\x7b\x2b\xcc\x3f\xff\x54\xcf\xac\xda\xf6\xc4\x46\xe6\x9d\x9c\x1d\x4c\x73\x31\x19\x71\xf2\x2a\x64\xec\xde\xe0\x25\x7c\x43\x96\x52\xe7\xa8\xaf\xd0\xad\x22\x37\xb7\x9b\xb4\xfd\xe0\xdb\xe6\xc6\x56\x31\x82\xe7\x7b\x0f\x6e\xcb\x73\x9d\x76\x49\x76\x2d\x7a\x8c\x96\x7a\x11\xa7\x34\x6d\x11\x3c\x35\xd8\x5d\x8f\xde\x8e\x6b\x15\x46\x35\xe4\xac\x49\xef\x40\xb5\x09\xa8\x1a\x6a\xd1\xa5\x77\xe0\xda\x84\x56\x0d\x57\xb5\xe9\x1d\xa0\x36\x41\x56\x03\xad\xf6\xe9\x1d\xd8\x36\xe1\x56\xc3\x2e\x1b\xf5\x83\x80\x87\xe7\x40\xd1\x1a\xb7\x95\x4b\xea\x5e\xfe\xcb\xec\x93\xfe\x8a\xa7\x92\x46\xc2\x88\xbe\x13\x6d\x76\x58\xe8\x8c\x3c\xcd\x28\xd1\x25\x07\x98\x43\xad\x49\x6f\x06\x49\xf2\x0a\xb5\x2b\xd5\x5b\x44\x41\x85\xe8\xfa\x94\xa5\x38\xa8\x44\x6c\xab\x0d\x8e\x8e\x9d\x6c\x47\x56\xf3\x6d\x28\x0b\x8a\xb5\x1d\x8b\x5d\x92\xd3\x6b\xd4\xee\xcd\xe6\xda\x66\x88\x66\xa9\xda\x76\x73\x5f\xb4\xaa\x31\x6f\xda\x53\xee\x7b\x76\x21\x25\xf3\xa0\x47\xe5\x3a\x95\x3d\x7b\xda\x3d\x76\xae\xf5\x6e\xb1\xd2\xec\x77\x56\xc3\x5a\xef\xdb\xfb\x44\x2d\x57\x35\x37\x51\xb6\xd3\x43\x91\x1d\xcc\xfa\xd8\xb3\xc0\x36\xc0\x17\x59\xa2\x1f\xdf\x2a\x57\x18\x28\xc8\x6c\x61\x81\x6e\x93\x33\x0c\xe8\x59\xd6\xb0\xc0\xb7\xc9\x1d\x06\xfc\x47\xf6\x62\x01\x6e\x93\x43\x0c\xe0\xbb\x2c\x62\x41\xc3\x26\x97\x18\x68\xe4\xd9\xe4\x8d\x08\x14\x8d\xaf\x63\x7a\x02\xf6\x55\xa2\x59\xaf\x8f\x49\x62\x4e\x40\x38\xf6\xf3\xde\x9c\xbd\x38\x1c\x3f\x63\x9e\x6a\x9b\xb5\x35\x6f\xbe\x6a\x72\xd1\xbe\x17\x63\xa1\x89\x43\x42\x63\x11\x91\x6e\xbb\x76\x9d\x35\x99\x6d\x99\x79\x9b\x9e\xdc\x88\xfc\x56\x0d\xba\x11\xfc\x2d\xba\x75\x23\xf0\xdb\xb4\xee\x46\xe8\x37\xe8\xe3\x8d\xb8\x6f\xd7\xd4\x1b\xe1\x0f\xee\xf0\x27\xc3\xfc\xd4\xdd\x64\x98\x1d\x61\x3c\x9a\xcc\x59\xb0\xce\x4f\x00\x06\xe4\x19\xd4\x71\xa7\xe9\xa0\x3c\x4e\x36\xd8\x9d\xd0\x9b\xe4\x27\x35\xf2\x21\xbb\xb3\x1b\x95\x31\xd9\xb8\x91\xf1\x3c\xe4\x64\x18\x8d\x2a\x68\xc3\x6c\x72\x7e\x1c\xb0\xc9\xc0\xee\xbc\x42\x71\x2e\x4d\xa3\x32\x9e\xa9\xb3\x95\xfa\x29\xcb\x68\x5c\x1f\xba\xd9\xc0\x3b\x82\xc0\x9b\x82\xbb\xdd\x1e\xd5\x51\xd2\x2c\xfc\x14\x64\xf3\x40\xdc\xa0\x55\x30\xa7\x5f\xcd\xe0\x5f\x88\x88\xe0\x5d\xa3\x21\xb8\x67\xab\x58\x48\xa2\x88\xd2\xdf\x1b\xbd\xc2\x3b\x82\xb6\x5b\x23\xd8\x24\x99\x4d\xd2\x04\x95\x0c\x51\x8c\x82\xc1\x6c\x92\x0a\xce\xe2\x70\xf6\x1b\x13\x88\xaa\x73\xa5\x46\x6a\xae\xba\xbf\xdd\x36\xb7\x70\xa4\xd9\xd5\xfc\xc9\x50\x62\xcf\x26\xc3\xc4\x2c\x4a\xfb\x8d\x8a\x69\xaa\xc9\xca\xa0\xa8\x9d\x5a\xc8\x02\x42\x01\xa7\x66\x56\x33\xf5\x0c\xf2\xa5\x3c\x38\x83\xcb\x16\x8d\x34\xc9\xab\x80\x5d\x4c\x9b\x15\xae\xe0\x41\xa1\xa3\x36\xdd\x34\x08\xca\x85\x52\x6a\xa5\xd5\xb6\x99\x20\x38\x0e\xb6\x5b\x4b\x81\x76\xae\xbf\xaf\x4c\x95\x99\xb3\x4a\x00\xb1\x96\xac\x32\xff\x6b\x09\xf7\xc8\x5e\xf6\x95\x4a\x4e\x99\xc9\x38\x6b\x2d\x87\x9c\xf1\xb5\x04\xc8\x72\xc9\xbe\x32\xe4\xb3\x66\x79\x26\xb2\x96\x24\x9f\xf7\xb5\x84\x91\x19\x77\x5f\x51\xd4\x9c\x99\xca\xd5\xd6\x62\xa8\x39\x5f\x4b\x88\xa2\x26\xd9\x57\x90\x72\xde\xac\xac\x6a\xac\x05\x2a\xe7\x7e\x2d\xa1\xf2\x12\x6e\x5f\x99\x8a\x69\xb3\xa2\x04\xb4\x96\xa8\x98\xb9\xb7\x40\x2d\x69\xa0\x75\x6a\x95\xe7\x7a\x6d\xd2\x91\x0a\x5a\x05\x05\x55\x8e\x4c\x07\x79\x8b\xd1\x26\xe4\xaf\x39\x21\x4d\xd8\x6f\x07\x7d\x62\xb6\xaf\x9b\xc3\x68\x57\x96\xce\x01\xc4\x95\x27\x1d\x46\x38\x77\xc2\x03\x88\xe6\x51\xe8\x30\xb2\x65\x08\x3b\x80\xb0\x0c\xe4\x87\x51\xcd\x52\xc0\x01\x24\x2b\x39\xf0\x30\xca\xb5\x24\x7a\x00\x03\x45\x79\x71\x18\xf5\x5d\x71\xd2\x4d\xba\xe3\x56\x9b\x5f\x1b\xa6\x4c\x86\x79\xf5\x5b\xbf\x7c\xd4\x26\x60\x9b\x9b\x6f\x36\x1c\xc5\x21\x86\x77\x4f\x17\xef\x9e\x65\xc5\xdb\xdc\x1a\x37\x97\xbb\xe5\xb4\x67\x13\xbb\xa8\xa6\xd6\xcd\xc6\xfd\x84\x9f\x31\x27\x62\xbd\xdd\x16\x7f\x95\x74\xbc\xd9\x80\x2b\x8b\x7e\xd8\x6e\x5b\xa2\x4f\x95\xfd\x80\x89\x6e\xa5\x56\xc6\xaa\xb3\x12\x3d\x11\x6d\xb6\x8b\xcd\x6e\xd1\x7a\xd8\xc5\x5e\x35\xbb\x26\x92\xe5\x84\x87\x6c\x53\xbb\x73\x7c\xcb\xad\xc9\x10\x99\x2c\x67\x5e\x2c\xa6\xeb\x0d\xdc\xfc\xe3\xee\x73\xa3\x93\xca\x7a\xbe\x66\xd3\x66\x66\xad\xaa\x78\x14\x63\x6a\x61\xcc\xec\x59\x49\x5f\xce\x21\xc1\x74\xb0\xd9\xb8\x3f\xb1\x54\xfc\x8a\x7d\x1c\x8b\x47\xf5\x8c\x20\xfb\x99\xd9\x6c\x50\x43\xec\x00\x54\xa0\xd1\x55\x6d\x78\xfe\xfc\x62\x00\x01\x12\xc8\x11\x2c\x0c\x29\x76\xd4\x9d\x7e\xba\xb3\x9e\x01\x93\x61\x74\xd5\xc3\x4d\x45\x1f\xc5\xe3\x8e\x1e\x01\xd4\xb4\x15\xed\x1f\x04\x59\xdf\x9c\x79\x68\xca\xb8\xc0\x81\x7d\x13\xab\x51\xa4\xa4\xc1\xa7\x05\x9b\xe5\x64\x5d\xca\x42\xed\xf6\x20\xd9\x1f\x1c\xe6\xde\x5a\x06\x8d\xd2\x5f\x41\xf5\xdc\xea\xd6\xef\x98\xa7\x72\x19\xab\xbb\xf2\x22\x38\x50\xeb\xc8\x17\x08\x16\xc8\xc1\xaf\x3e\x45\x4b\x24\x57\xbc\x23\x38\x41\x71\x28\x97\x01\xe2\x04\x39\xd9\x2e\xe4\x74\x20\xf8\x0a\x0f\x8a\x96\xdb\x5e\xdc\xee\x48\xd0\x7c\x95\x36\x72\x1b\xe6\xb1\x34\x0d\x64\x0b\xa2\x10\xae\x11\xb9\xf7\xd3\x70\xd5\xce\x8d\xa7\xf3\x1b\x28\x83\x5d\x7b\xb0\xee\x84\x46\x46\xe4\xd2\x01\x63\xb4\xc4\xd2\xe7\x2a\x09\xc1\x18\xf1\x7a\xe9\x64\x2b\xa2\x4c\x3e\x68\x89\x07\xc6\x25\xb3\x3f\x72\x16\xc3\xc1\xfd\x80\x53\x9f\x93\x44\x14\xab\x6c\x2f\x7b\x97\x68\x28\x4f\x82\x12\xf1\x91\xc4\x4f\x52\x64\x10\x88\x87\x58\x4c\x07\x73\x8a\xe2\xa7\xc1\x4c\x5e\xdf\x5b\x0b\x93\x21\x25\xfb\x2c\x57\xdb\x68\x62\x8f\xdb\xd5\x9a\x1c\x3a\xb6\x9f\xcf\xbe\x14\x7c\x40\xc6\x35\x5f\x9e\x73\x18\x36\x0b\xb1\x72\x64\xed\x6d\xad\x3c\xab\x26\xdc\x49\xb6\x82\x76\x28\xa7\x8b\x55\xac\xc6\x9e\x9e\xe9\x8f\x5e\x53\x01\x59\x6a\xe2\x29\x4c\x21\x60\xfe\x6a\x89\x63\xe1\xfe\x7b\x85\xf9\xfa\x13\xa6\xd8\x17\x8c\xff\x40\xe9\xe9\xc9\x1f\x5a\x1a\xfb\x7c\x72\xd6\x3c\x00\x10\xa7\x8c\x62\x97\xb2\xf0\xb4\x00\x3d\xbb\xab\x6f\xaa\x2e\x18\x87\xd3\x67\xc4\x81\xc0\xb4\xa4\xec\x52\x1c\x87\x22\x02\x07\x46\x77\x40\x60\x36\x85\xcb\x3b\x20\x8e\xd3\xe4\x17\xd4\x71\xc9\x6c\xce\x1f\xe4\xb3\xcb\x62\x9f\x12\xff\x09\xa6\x50\x8a\x88\x4d\x73\xe4\x0b\xbb\x99\x03\xb8\xd9\x51\xe0\x9f\x59\x80\x5d\xe5\xc8\x8f\x24\x15\x6e\x86\x7a\x7a\x92\x9d\x10\x68\x0a\x26\x5f\xdb\xfa\xa5\xdd\xaa\xda\x9e\x9d\xe6\xc3\x27\xc3\x42\xf5\x93\x61\xb6\x75\x7e\x34\x19\xaa\xff\x27\xe0\xbf\x01\x00\x00\xff\xff\xbc\x30\xfb\x2c\x37\x40\x00\x00") func templatesAnalysisTemplateHtmlBytes() ([]byte, error) { return bindataRead( @@ -83,7 +83,7 @@ func templatesAnalysisTemplateHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/analysis-template.html", size: 16403, mode: os.FileMode(420), modTime: time.Unix(1466557241, 0)} + info := bindataFileInfo{name: "templates/analysis-template.html", size: 16439, mode: os.FileMode(420), modTime: time.Unix(1494508002, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/cmd/analyze.go b/cmd/analyze.go index 48f7106..f99da9d 100644 --- a/cmd/analyze.go +++ b/cmd/analyze.go @@ -37,7 +37,10 @@ var analyzeCmd = &cobra.Command{ log.Fatalf("retrieving manifest for %q: %v", config.ImageName, err) } - startLocalServer() + if config.IsLocal { + startLocalServer() + } + if err := clair.Push(image, manifest); err != nil { if err != nil { fmt.Println(errInternalError) diff --git a/cmd/push.go b/cmd/push.go index b85d38f..dee716a 100644 --- a/cmd/push.go +++ b/cmd/push.go @@ -21,7 +21,9 @@ var pushCmd = &cobra.Command{ os.Exit(1) } - startLocalServer() + if config.IsLocal { + startLocalServer() + } config.ImageName = args[0] image, manifest, err := docker.RetrieveManifest(config.ImageName, true) if err != nil { diff --git a/contrib/README.md b/contrib/README.md index ee37c11..b7095fa 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -1,7 +1,7 @@ CONTRIBUTION ----------------- -# Running full dev environnement +# Running a development environnement ```bash # Running Authentication server, Registry, Clair diff --git a/contrib/docker-compose.yml b/contrib/docker-compose.yml index b70cacc..b9dcf54 100644 --- a/contrib/docker-compose.yml +++ b/contrib/docker-compose.yml @@ -44,9 +44,13 @@ services: container_name: "postgres" environment: - POSTGRES_PASSWORD=root + volumes: + - db-data:/var/lib/postgresql/data volumes: clair-data: driver: local registry-data: driver: local + db-data: + driver: local diff --git a/docker/dockerdist/dockerdist.go b/docker/dockerdist/dockerdist.go index 673f257..5c1de20 100644 --- a/docker/dockerdist/dockerdist.go +++ b/docker/dockerdist/dockerdist.go @@ -91,7 +91,6 @@ func getRepositoryClient(image reference.Named, insecure bool, scopes ...string) } metaHeaders := map[string][]string{} - endpoints, err := service.LookupPullEndpoints(image.Hostname()) if err != nil { log.Debugf("registry.LookupPullEndpoints error: %v", err) @@ -139,7 +138,8 @@ func GetPushURL(hostname string) (*url.URL, error) { if isInsecureRegistry(endpoint.URL.Host) { endpoint.URL.Scheme = "http" } - return endpoint.URL, nil + + return url.Parse(endpoint.URL.String() + "/v2") } return nil, errors.New("No endpoints found") From 36b725ce3982d99a2523883ab6e9ae9b83e5833b Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Thu, 25 May 2017 10:11:54 +0200 Subject: [PATCH 03/13] Bump version 1.2.6 --- .travis.yml | 5 +++-- README.md | 4 +++- VERSION | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8d265e6..48dfbfc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: go go: - - 1.7 + - 1.8 install: - go get -v github.com/Masterminds/glide @@ -20,13 +20,14 @@ script: deploy: provider: releases api_key: - secure: SPeZzw212p/0iYPLVWUkLq226j19oWHBogHIlbKzkp8zNk7tdJEHMthAhka1zxS5afr+JWu3BBdduPHbnvvpXtv2axsrCXVsW7jPEcxXgfM3m/YSxQwjsGojMG318nX/E5ApY8eDhiZuHoTAP67DJZEoLteV5GKvNk7np74bMNexBxCPDIbXepBbjrEqxrUG/uVDFrmFf0LlCKVGxALK42uriaDM1tPGDy0+7zX7a3RqG9J4ROmZCQNzd9+rcur4DndrxYPCvJK3awUwXL5XzdRed24m5S8IG6Q/gMMUhUVECMNZ6/Z+KZ4CKqcQ9e9NvOtHYvO0OtPNrd4/HajZpUpfO008imSj6/g9NxdC6hJYvyK/HuRv5DsLgZukyvwroVSM5rC77FJeOmoLXfEBHo7E16I5XKGcp31NoCv5kdQuaHLxkBZk43CcnT/rraQ8cjCQAERQEh6u0fidyOvZ4vkTW30/c6H25zDejCzDcx1oHL4O8QwJwMfRSifSA8vk81saOurmQeviZK1UkpeWLxMYLpFZ8vN9kK/2Nn24ud9DN7N8bqGob13I8lJ69j9xcXuq/86vITziESZCHaYs2Hw1vSHD8vpkQxu8aSYqPXgwAKDwV9JkGV1/kcUdwpOlD/xkKunluu8Mf5K2JSm9G8xWr6foOibKsuHDn0nH+jY= + secure: HgOSNmBsqtA3CutTWnRNp2LNROeoPYyU+zO6ZzFH+tkG8Bif+KEtQx9fRv2YNB7+TSYUkaoT3v0XqkHhKe7GmhTD9mZ2v5isKHhD/FhP/qRDAxugzf66+mJJBhQ5tS9gz2hVK1E+tnHK1L3IVIh47zeXEd2VpciuxPaTwC2zAWi97EHFivjClD3uE2cc1HztDF95cq+eZzo5hfJn4mYuaMfnIGdPD3yKZY1+hQ7aby/+MxNyIbVwefgxV/fNPiVmM9u07+uzHWHKTikp8UyHvdKOyJp31S20i22velRC0xf6g4/d9rwfaw1zFMnjeA4ClRGwNief0cfKVtB7/KMwGC8UNiHvtDEIJn5yelSpqatde96eK7NJ58uTYsWRHM5RPW9MphpxhHPzBNXiz2m9sfZ7Frf3NeA94nZT1WAkoF4jjgWPNbPjOJzpz80dzzbNFUSWSrJFrJSaleLQwdPMi0fwTh2VG6gvhqYcLqW0GMVIUHFA905SuJwXje+IPh74RtjDmyMrwaONZQDqDfldXvY04kmoUsEkWPQkI3gQivp8Ep+IGpz+L8LPG5GR3whCu+OQqto1yIAFFdveFuD1VBgVvqJQwODkDkYux1UJNek1vbgtuGxuThWILZ16WcrxBl0l/FhFqxQ76tsH5A+57euVc5SFHDN6f7c5K2rzLcU= file: clairctl skip_cleanup: true on: repo: jgsqware/clairctl tags: true branch: master + env: global: secure: QpHC0r/d3sUNZ4Tisu7IjRnE+exzUUdTRlWUvvepWA2/wdsvsh9IFKmPgHvmt/V46RtByc52HVwE/uE6gF8eVhRs4L4DP/gSi0TxmfNi2m+6EdL1MmFvdIVGfPZDDbFnNNXpWcNJGv5/UDJ8eke003Mtm7/qQfJqH3UzxoWnTrvsA7IHbhxomgsHOFqHU+e6fmaQ3q7neUJEci2HSPLehl11yBwMcsYyFjeW+33GVQeI0m2j1TrcldG3KN63tszIx7tHXTUrIK369nrndLjYWnc7Hi+k6Uc8vPh111/hLBG4UtxffP+/DTkhEtzxDNn3hn4zSKTMIyeKA/UhnySYchzDYOdVZoM0oVxAkbTcdTPWCxS75W1u3AW3QAGxScNEqmy5enrW+kGyRpd1zIRJ1qS2tHAVmos8N6bl5Rp9UJF5UITr9/DyQS93O9DOSY5Z6UVGI5J+MlG89Nr4XJ5NW4ak5yC5fc+9IwM58VMk8ULS3I0g/YBWsWRWHGZrHurnvcGbiXHk5S+anQsiYUV8n3OUa67ai7Duil3qiPklEhHeFZzmXrJMvLdeVxywfvIfKzSEGqDrUYw3hO9pkMzLxDQfvaNzAHWZGJ970N7apX2pnAUgPDsNb8cOnbDSjX36FICAiUZlrkpsz6O6h3Fm/2t/HDCyYH7gf6eJXypUOYc= diff --git a/README.md b/README.md index bc2349e..8538bea 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Clairctl is a lightweight command-line tool doing the bridge between Registries as Docker Hub, Docker Registry or Quay.io, and the CoreOS vulnerability tracker, Clair. Clairctl will play as reverse proxy for authentication. +Clairctl version is align with the [CoreOS Clair](https://github.com/coreos/clair) supported version. + # Usage [![asciicast](https://asciinema.org/a/41461.png)](https://asciinema.org/a/41461) @@ -55,7 +57,7 @@ clair: # Building the latest binaries -**clairctl** requires Go 1.7+. +**clairctl** requires Go 1.8+. Install Glide: ``` diff --git a/VERSION b/VERSION index d2d61a7..7e099ec 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.2 \ No newline at end of file +1.2.6 \ No newline at end of file From bba5d65cb28f2a9c195dd0a73224c53d38043357 Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Thu, 25 May 2017 10:11:54 +0200 Subject: [PATCH 04/13] Bump version 1.2.6 --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 48dfbfc..f819831 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,13 +15,18 @@ addons: script: - go generate ./clair -- go build -ldflags "-X github.com/jgsqware/clairctl/cmd.version=$(cat VERSION)" -v +- go get github.com/mitchellh/gox +- gox -os="linux" -os="darwin" -arch="amd64 386" -output="out/{{.Dir}}-{{.OS}}-{{.Arch}}" -ldflags "-X github.com/jgsqware/clairctl/cmd.version=$(cat VERSION)" -v deploy: provider: releases api_key: secure: HgOSNmBsqtA3CutTWnRNp2LNROeoPYyU+zO6ZzFH+tkG8Bif+KEtQx9fRv2YNB7+TSYUkaoT3v0XqkHhKe7GmhTD9mZ2v5isKHhD/FhP/qRDAxugzf66+mJJBhQ5tS9gz2hVK1E+tnHK1L3IVIh47zeXEd2VpciuxPaTwC2zAWi97EHFivjClD3uE2cc1HztDF95cq+eZzo5hfJn4mYuaMfnIGdPD3yKZY1+hQ7aby/+MxNyIbVwefgxV/fNPiVmM9u07+uzHWHKTikp8UyHvdKOyJp31S20i22velRC0xf6g4/d9rwfaw1zFMnjeA4ClRGwNief0cfKVtB7/KMwGC8UNiHvtDEIJn5yelSpqatde96eK7NJ58uTYsWRHM5RPW9MphpxhHPzBNXiz2m9sfZ7Frf3NeA94nZT1WAkoF4jjgWPNbPjOJzpz80dzzbNFUSWSrJFrJSaleLQwdPMi0fwTh2VG6gvhqYcLqW0GMVIUHFA905SuJwXje+IPh74RtjDmyMrwaONZQDqDfldXvY04kmoUsEkWPQkI3gQivp8Ep+IGpz+L8LPG5GR3whCu+OQqto1yIAFFdveFuD1VBgVvqJQwODkDkYux1UJNek1vbgtuGxuThWILZ16WcrxBl0l/FhFqxQ76tsH5A+57euVc5SFHDN6f7c5K2rzLcU= - file: clairctl + file: + - out/clairctl-darwin-386 + - out/clairctl-darwin-amd64 + - out/clairctl-linux-386 + - out/clairctl-linux-amd64 skip_cleanup: true on: repo: jgsqware/clairctl From a795fcfe5cd9e2e28435e688ef1df3794331a826 Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Thu, 25 May 2017 10:11:54 +0200 Subject: [PATCH 05/13] Bump version 1.2.6 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f819831..e22ed42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ addons: script: - go generate ./clair - go get github.com/mitchellh/gox -- gox -os="linux" -os="darwin" -arch="amd64 386" -output="out/{{.Dir}}-{{.OS}}-{{.Arch}}" -ldflags "-X github.com/jgsqware/clairctl/cmd.version=$(cat VERSION)" -v +- gox -os="linux" -os="darwin" -arch="amd64 386" -output="out/{{.Dir}}-{{.OS}}-{{.Arch}}" -ldflags "-X github.com/jgsqware/clairctl/cmd.version=$(cat VERSION)" deploy: provider: releases From 0fadb60b464cd60091ef18e5483a75b3443f4700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hussenot?= Date: Sun, 28 May 2017 08:19:02 +0200 Subject: [PATCH 06/13] Update README.md (#46) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8538bea..dc59b2b 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ curl https://glide.sh/get | sh Clone and build: ``` -git clone github.com/jgsqware/clairctl $GOPATH/src/github.com/jgsqware/clairctl +git clone git@github.com:jgsqware/clairctl.git $GOPATH/src/github.com/jgsqware/clairctl cd $GOPATH/src/github.com/jgsqware/clairctl glide install -v go generate ./clair From 29a19257d8729832359cdd3be3a5804f1a5c057b Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Mon, 29 May 2017 10:59:10 +0200 Subject: [PATCH 07/13] update travis for artefact upload --- .travis.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e22ed42..0324e77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,14 @@ install: - go get -u github.com/jteeuwen/go-bindata/... addons: - artifacts: true - paths: - - ./clairctl + artifacts: + paths: + - out/clairctl-darwin-386 + - out/clairctl-darwin-amd64 + - out/clairctl-linux-386 + - out/clairctl-linux-amd64 + target_paths: latest + working_dir: out script: - go generate ./clair From 04ead92a0058d03ce6c286ce5818c13c9d6457e1 Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Mon, 29 May 2017 11:39:32 +0200 Subject: [PATCH 08/13] add install script --- install.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 install.sh diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..9c4e532 --- /dev/null +++ b/install.sh @@ -0,0 +1,9 @@ +#!/bin/bash -ue +PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]') +ARCH=$(uname -m) +if [[ "$(uname -m)" == *"64"* ]]; then ARCH="amd64"; else ARCH="386"; fi +echo $PLATFORM +echo $ARCH + +curl -o /usr/local/bin/clairctl "https://s3.amazonaws.com/clairctl/latest/clairctl-$PLATFORM-$ARCH" +chmod +x /usr/local/bin/clairctl \ No newline at end of file From c47dcb8176f2fcf6668248a8e2837a6b460ebfd5 Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Mon, 29 May 2017 11:42:46 +0200 Subject: [PATCH 09/13] update doc for installation --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index dc59b2b..bffc24d 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,17 @@ Clairctl will play as reverse proxy for authentication. Clairctl version is align with the [CoreOS Clair](https://github.com/coreos/clair) supported version. +# Installation + + ## Released version: + Go to [Release](https://github.com/jgsqware/clairctl/releases) and download your corresponding version + + ## Master branch version + + ``` + curl -L https://raw.githubusercontent.com/jgsqware/clairctl/master/install.sh | sh + ``` + # Usage [![asciicast](https://asciinema.org/a/41461.png)](https://asciinema.org/a/41461) From b80f4ec44769d008c78303ce9be675a9094f796f Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Mon, 29 May 2017 11:45:04 +0200 Subject: [PATCH 10/13] Fix #7 - Add log with missing ref --- README.md | 5 ++--- clair/push.go | 2 +- docker/dockercli/dockercli.go | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bffc24d..4fe725c 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,12 @@ Clairctl version is align with the [CoreOS Clair](https://github.com/coreos/clai # Installation ## Released version: - Go to [Release](https://github.com/jgsqware/clairctl/releases) and download your corresponding version + Go to [Release](https://github.com/jgsqware/clairctl/releases) and download your corresponding version ## Master branch version - ``` curl -L https://raw.githubusercontent.com/jgsqware/clairctl/master/install.sh | sh - ``` + # Usage diff --git a/clair/push.go b/clair/push.go index d8f2160..3843bf9 100644 --- a/clair/push.go +++ b/clair/push.go @@ -58,7 +58,7 @@ func Push(image reference.NamedTagged, manifest distribution.Manifest) error { } func pushLayer(layer v1.LayerEnvelope) error { - if config.IsLocal { + if !config.IsLocal { layer = auth(layer) } diff --git a/docker/dockercli/dockercli.go b/docker/dockercli/dockercli.go index 4edde6a..8b69dda 100644 --- a/docker/dockercli/dockercli.go +++ b/docker/dockercli/dockercli.go @@ -5,6 +5,7 @@ import ( "compress/gzip" "context" "encoding/json" + "fmt" "io" "io/ioutil" "os" @@ -96,7 +97,7 @@ func save(imageName string) (distribution.Manifest, error) { img, err := cli.ImageSave(context.Background(), []string{imageName}) if err != nil { - panic(err) + return nil, fmt.Errorf("cannot save image %s: %s", imageName, err) } all, err := ioutil.ReadAll(img) if err != nil { From b2094f15ecd7d3e7d172a46dec571acc86dad6fa Mon Sep 17 00:00:00 2001 From: Julien Garcia Gonzalez Date: Mon, 29 May 2017 13:37:35 +0200 Subject: [PATCH 11/13] add gitter chat --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4fe725c..7eb8c6d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # clairctl [![Build Status](https://travis-ci.org/jgsqware/clairctl.svg?branch=master)](https://travis-ci.org/jgsqware/clairctl) +[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/clairctl/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link) > Tracking container vulnerabilities with Clair Control From 27f34d68ee4cb32490fa7cd5c647a52519140a08 Mon Sep 17 00:00:00 2001 From: Julien Del-Piccolo Date: Tue, 13 Jun 2017 09:55:47 +0200 Subject: [PATCH 12/13] Dockerfile + build hooks (#47) * Add Dockerfile and build hook * Add docker-compose for easy setup and test --- Dockerfile | 51 +++++++++++++++++++++ docker-compose-data/clair-config/config.yml | 15 ++++++ docker-compose.yml | 33 +++++++++++++ hooks/build | 18 ++++++++ 4 files changed, 117 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose-data/clair-config/config.yml create mode 100644 docker-compose.yml create mode 100755 hooks/build diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..af97ad4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,51 @@ +FROM alpine:3.5 + +ENV GOPATH=/go +ENV PATH=${GOPATH}/bin:${PATH} +ENV DOCKER_API_VERSION=1.24 +ARG DOCKER_VERSION=${DOCKER_VERSION:-latest} +ARG CLAIRCTL_VERSION=${CLAIRCTL_VERSION:-master} +ARG CLAIRCTL_COMMIT= + +RUN apk add --update curl \ + && apk add --virtual build-dependencies go gcc build-base glide git \ + && adduser clairctl -D \ + && curl https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz -o docker.tgz \ + && tar xfvz docker.tgz --strip 1 -C /usr/bin/ docker/docker \ + && rm -f docker.tgz \ + && go get -u github.com/jteeuwen/go-bindata/... \ + && curl -sL https://github.com/jgsqware/clairctl/archive/${CLAIRCTL_VERSION}.zip -o clairctl.zip \ + && mkdir -p ${GOPATH}/src/github.com/jgsqware/ \ + && unzip clairctl.zip -d ${GOPATH}/src/github.com/jgsqware/ \ + && rm -f clairctl.zip \ + && mv ${GOPATH}/src/github.com/jgsqware/clairctl-* ${GOPATH}/src/github.com/jgsqware/clairctl \ + && cd ${GOPATH}/src/github.com/jgsqware/clairctl \ + && glide install -v \ + && go generate ./clair \ + && go build -o /usr/local/bin/clairctl -ldflags "-X github.com/jgsqware/clairctl/cmd.version=${CLAIRCTL_VERSION}-${CLAIRCTL_COMMIT}" \ + && apk del build-dependencies \ + && rm -rf /var/cache/apk/* \ + && rm -rf /root/.glide/ \ + && rm -rf /go \ + && echo $'clair:\n\ + port: 6060\n\ + healthPort: 6061\n\ + uri: http://clair\n\ + priority: Low\n\ + report:\n\ + path: /reports\n\ + format: html\n\ +clairctl:\n\ + port: 44480\n\ + tempfolder: /tmp'\ + > /home/clairctl/clairctl.yml + +USER clairctl + +WORKDIR /home/clairctl/ + +EXPOSE 44480 + +VOLUME ["/tmp/", "/reports/"] + +CMD ["/usr/sbin/crond", "-f"] \ No newline at end of file diff --git a/docker-compose-data/clair-config/config.yml b/docker-compose-data/clair-config/config.yml new file mode 100644 index 0000000..368531a --- /dev/null +++ b/docker-compose-data/clair-config/config.yml @@ -0,0 +1,15 @@ +clair: + database: + type: pgsql + options: + source: postgresql://clair:ChangeMe@postgres:5432/clair?sslmode=disable + cachesize: 16384 + api: + port: 6060 + healthport: 6061 + timeout: 900s + updater: + interval: 2h + notifier: + attempts: 3 + renotifyinterval: 2h diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f6ba00e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +version: '2' + +services: + postgres: + image: postgres:9.6 + restart: unless-stopped + volumes: + - ./docker-compose-data/postgres-data/:/var/lib/postgresql/data:rw + environment: + - POSTGRES_PASSWORD=ChangeMe + - POSTGRES_USER=clair + - POSTGRES_DB=clair + + clair: + image: quay.io/coreos/clair:v2.0.0 + restart: unless-stopped + volumes: + - ./docker-compose-data/clair-config/:/config/:ro + - ./docker-compose-data/clair-tmp/:/tmp/:rw + ports: + - '6060-6061:6060-6061' + command: [--log-level=debug, --config, /config/config.yml] + + clairctl: + image: jgsqware/clairctl:latest + restart: unless-stopped + environment: + - DOCKER_API_VERSION=1.24 + volumes: + - ./docker-compose-data/clairctl-reports/:/reports/:rw + - /var/run/docker.sock:/var/run/docker.sock:ro + ports: + - '44480:44480' \ No newline at end of file diff --git a/hooks/build b/hooks/build new file mode 100755 index 0000000..5e6ae64 --- /dev/null +++ b/hooks/build @@ -0,0 +1,18 @@ +#!/usr/bin/env sh +export DOCKER_VERSION=17.05.0-ce +export GIT_REV_PARSE=$(git rev-parse --short HEAD) + +echo "=-=-=-=-=-=-=- DEBUG INFO =-=-=-=-=-=-=-" +echo "SOURCE_BRANCH: ${SOURCE_BRANCH}" +echo "SOURCE_COMMIT: ${SOURCE_COMMIT}" +echo "COMMIT_MSG: ${COMMIT_MSG}" +echo "DOCKER_REPO: ${DOCKER_REPO}" +echo "DOCKER_TAG: ${DOCKER_TAG}" +echo "IMAGE_NAME: ${IMAGE_NAME}" +echo "GIT_REV_PARSE: ${GIT_REV_PARSE}" +echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" + +docker build --build-arg CLAIRCTL_VERSION=${DOCKER_TAG} \ + --build-arg CLAIRCTL_COMMIT=${GIT_REV_PARSE} \ + --build-arg DOCKER_VERSION=${DOCKER_VERSION} \ + -t $IMAGE_NAME . \ No newline at end of file From 8169b9eb9e1e00bd97c88e95d8c50d1085817724 Mon Sep 17 00:00:00 2001 From: Julien Del-Piccolo Date: Tue, 13 Jun 2017 10:27:55 +0200 Subject: [PATCH 13/13] Fix permissions --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index af97ad4..c12d59e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,8 @@ ARG CLAIRCTL_COMMIT= RUN apk add --update curl \ && apk add --virtual build-dependencies go gcc build-base glide git \ && adduser clairctl -D \ + && mkdir -p /reports \ + && chown -R clairctl:clairctl /reports /tmp \ && curl https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz -o docker.tgz \ && tar xfvz docker.tgz --strip 1 -C /usr/bin/ docker/docker \ && rm -f docker.tgz \