├── .dockerignore ├── .gitignore ├── Dockerfile ├── Dockerfile.dist ├── Dockerfile.ui ├── Godeps ├── Godeps.json ├── Readme └── _workspace │ ├── .gitignore │ └── src │ ├── github.com │ ├── Sirupsen │ │ └── logrus │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── entry.go │ │ │ ├── entry_test.go │ │ │ ├── examples │ │ │ ├── basic │ │ │ │ └── basic.go │ │ │ └── hook │ │ │ │ └── hook.go │ │ │ ├── exported.go │ │ │ ├── formatter.go │ │ │ ├── formatter_bench_test.go │ │ │ ├── formatters │ │ │ └── logstash │ │ │ │ ├── logstash.go │ │ │ │ └── logstash_test.go │ │ │ ├── hook_test.go │ │ │ ├── hooks.go │ │ │ ├── hooks │ │ │ ├── airbrake │ │ │ │ ├── airbrake.go │ │ │ │ └── airbrake_test.go │ │ │ ├── bugsnag │ │ │ │ ├── bugsnag.go │ │ │ │ └── bugsnag_test.go │ │ │ ├── papertrail │ │ │ │ ├── README.md │ │ │ │ ├── papertrail.go │ │ │ │ └── papertrail_test.go │ │ │ ├── sentry │ │ │ │ ├── README.md │ │ │ │ ├── sentry.go │ │ │ │ └── sentry_test.go │ │ │ └── syslog │ │ │ │ ├── README.md │ │ │ │ ├── syslog.go │ │ │ │ └── syslog_test.go │ │ │ ├── json_formatter.go │ │ │ ├── json_formatter_test.go │ │ │ ├── logger.go │ │ │ ├── logrus.go │ │ │ ├── logrus_test.go │ │ │ ├── terminal_darwin.go │ │ │ ├── terminal_freebsd.go │ │ │ ├── terminal_linux.go │ │ │ ├── terminal_notwindows.go │ │ │ ├── terminal_openbsd.go │ │ │ ├── terminal_windows.go │ │ │ ├── text_formatter.go │ │ │ ├── text_formatter_test.go │ │ │ └── writer.go │ ├── cloudnautique │ │ └── go-vol │ │ │ └── volumes │ │ │ └── volume.go │ ├── docker │ │ └── docker │ │ │ └── pkg │ │ │ └── units │ │ │ ├── duration.go │ │ │ ├── duration_test.go │ │ │ ├── size.go │ │ │ └── size_test.go │ ├── elazarl │ │ └── go-bindata-assetfs │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── assetfs.go │ │ │ ├── doc.go │ │ │ └── go-bindata-assetfs │ │ │ └── main.go │ ├── emicklei │ │ └── go-restful │ │ │ ├── .gitignore │ │ │ ├── CHANGES.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── Srcfile │ │ │ ├── bench_curly_test.go │ │ │ ├── bench_test.go │ │ │ ├── bench_test.sh │ │ │ ├── compress.go │ │ │ ├── compress_test.go │ │ │ ├── constants.go │ │ │ ├── container.go │ │ │ ├── container_test.go │ │ │ ├── cors_filter.go │ │ │ ├── cors_filter_test.go │ │ │ ├── coverage.sh │ │ │ ├── curly.go │ │ │ ├── curly_route.go │ │ │ ├── curly_test.go │ │ │ ├── doc.go │ │ │ ├── doc_examples_test.go │ │ │ ├── examples │ │ │ ├── .goconvey │ │ │ ├── google_app_engine │ │ │ │ ├── .goconvey │ │ │ │ ├── app.yaml │ │ │ │ ├── datastore │ │ │ │ │ ├── .goconvey │ │ │ │ │ ├── app.yaml │ │ │ │ │ └── main.go │ │ │ │ ├── restful-appstats-integration.go │ │ │ │ └── restful-user-service.go │ │ │ ├── home.html │ │ │ ├── restful-CORS-filter.go │ │ │ ├── restful-NCSA-logging.go │ │ │ ├── restful-basic-authentication.go │ │ │ ├── restful-cpuprofiler-service.go │ │ │ ├── restful-curly-router.go │ │ │ ├── restful-encoding-filter.go │ │ │ ├── restful-filters.go │ │ │ ├── restful-form-handling.go │ │ │ ├── restful-hello-world.go │ │ │ ├── restful-html-template.go │ │ │ ├── restful-multi-containers.go │ │ │ ├── restful-options-filter.go │ │ │ ├── restful-path-tail.go │ │ │ ├── restful-pre-post-filters.go │ │ │ ├── restful-resource-functions.go │ │ │ ├── restful-route_test.go │ │ │ ├── restful-routefunction_test.go │ │ │ ├── restful-serve-static.go │ │ │ ├── restful-swagger.go │ │ │ ├── restful-user-resource.go │ │ │ └── restful-user-service.go │ │ │ ├── filter.go │ │ │ ├── filter_test.go │ │ │ ├── install.sh │ │ │ ├── jsr311.go │ │ │ ├── jsr311_test.go │ │ │ ├── log │ │ │ └── log.go │ │ │ ├── logger.go │ │ │ ├── options_filter.go │ │ │ ├── options_filter_test.go │ │ │ ├── parameter.go │ │ │ ├── path_expression.go │ │ │ ├── path_expression_test.go │ │ │ ├── request.go │ │ │ ├── request_test.go │ │ │ ├── response.go │ │ │ ├── response_test.go │ │ │ ├── route.go │ │ │ ├── route_builder.go │ │ │ ├── route_builder_test.go │ │ │ ├── route_test.go │ │ │ ├── router.go │ │ │ ├── service_error.go │ │ │ ├── swagger │ │ │ ├── CHANGES.md │ │ │ ├── README.md │ │ │ ├── api_declaration_list.go │ │ │ ├── config.go │ │ │ ├── model_builder.go │ │ │ ├── model_builder_test.go │ │ │ ├── model_list.go │ │ │ ├── model_list_test.go │ │ │ ├── model_property_list.go │ │ │ ├── model_property_list_test.go │ │ │ ├── ordered_route_map.go │ │ │ ├── ordered_route_map_test.go │ │ │ ├── postbuild_model_test.go │ │ │ ├── swagger.go │ │ │ ├── swagger_test.go │ │ │ ├── swagger_webservice.go │ │ │ └── utils_test.go │ │ │ ├── tracer_test.go │ │ │ ├── web_service.go │ │ │ ├── web_service_container.go │ │ │ └── web_service_test.go │ ├── fsouza │ │ └── go-dockerclient │ │ │ ├── .dockerignore │ │ │ ├── .travis.yml │ │ │ ├── AUTHORS │ │ │ ├── DOCKER-LICENSE │ │ │ ├── Dockerfile.1_3 │ │ │ ├── Dockerfile.1_4 │ │ │ ├── LICENSE │ │ │ ├── Makefile │ │ │ ├── README.markdown │ │ │ ├── auth.go │ │ │ ├── auth_test.go │ │ │ ├── build_test.go │ │ │ ├── change.go │ │ │ ├── change_test.go │ │ │ ├── client.go │ │ │ ├── client_test.go │ │ │ ├── codeship-services.yml │ │ │ ├── codeship-steps.yml │ │ │ ├── container.go │ │ │ ├── container_test.go │ │ │ ├── env.go │ │ │ ├── env_test.go │ │ │ ├── event.go │ │ │ ├── event_test.go │ │ │ ├── example_test.go │ │ │ ├── exec.go │ │ │ ├── exec_test.go │ │ │ ├── image.go │ │ │ ├── image_test.go │ │ │ ├── misc.go │ │ │ ├── misc_test.go │ │ │ ├── signal.go │ │ │ ├── tar.go │ │ │ ├── testing │ │ │ ├── bin │ │ │ │ └── fmtpolice │ │ │ ├── data │ │ │ │ ├── .dockerignore │ │ │ │ ├── Dockerfile │ │ │ │ ├── barfile │ │ │ │ ├── ca.pem │ │ │ │ ├── cert.pem │ │ │ │ ├── container.tar │ │ │ │ ├── dockerfile.tar │ │ │ │ ├── foofile │ │ │ │ ├── key.pem │ │ │ │ ├── server.pem │ │ │ │ ├── serverkey.pem │ │ │ │ └── symlink │ │ │ ├── server.go │ │ │ └── server_test.go │ │ │ ├── tls.go │ │ │ └── vendor │ │ │ └── github.com │ │ │ ├── Sirupsen │ │ │ └── logrus │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── entry.go │ │ │ │ ├── entry_test.go │ │ │ │ ├── exported.go │ │ │ │ ├── formatter.go │ │ │ │ ├── formatter_bench_test.go │ │ │ │ ├── hook_test.go │ │ │ │ ├── hooks.go │ │ │ │ ├── json_formatter.go │ │ │ │ ├── json_formatter_test.go │ │ │ │ ├── logger.go │ │ │ │ ├── logrus.go │ │ │ │ ├── logrus_test.go │ │ │ │ ├── terminal_darwin.go │ │ │ │ ├── terminal_freebsd.go │ │ │ │ ├── terminal_linux.go │ │ │ │ ├── terminal_notwindows.go │ │ │ │ ├── terminal_openbsd.go │ │ │ │ ├── terminal_windows.go │ │ │ │ ├── text_formatter.go │ │ │ │ ├── text_formatter_test.go │ │ │ │ └── writer.go │ │ │ ├── docker │ │ │ └── docker │ │ │ │ └── pkg │ │ │ │ ├── archive │ │ │ │ ├── README.md │ │ │ │ ├── archive.go │ │ │ │ ├── archive_test.go │ │ │ │ ├── archive_unix.go │ │ │ │ ├── archive_unix_test.go │ │ │ │ ├── archive_windows.go │ │ │ │ ├── archive_windows_test.go │ │ │ │ ├── changes.go │ │ │ │ ├── changes_linux.go │ │ │ │ ├── changes_other.go │ │ │ │ ├── changes_posix_test.go │ │ │ │ ├── changes_test.go │ │ │ │ ├── changes_unix.go │ │ │ │ ├── changes_windows.go │ │ │ │ ├── diff.go │ │ │ │ ├── diff_test.go │ │ │ │ ├── example_changes.go │ │ │ │ ├── time_linux.go │ │ │ │ ├── time_unsupported.go │ │ │ │ ├── utils_test.go │ │ │ │ ├── wrap.go │ │ │ │ └── wrap_test.go │ │ │ │ ├── fileutils │ │ │ │ ├── fileutils.go │ │ │ │ └── fileutils_test.go │ │ │ │ ├── ioutils │ │ │ │ ├── fmt.go │ │ │ │ ├── fmt_test.go │ │ │ │ ├── readers.go │ │ │ │ ├── readers_test.go │ │ │ │ ├── writeflusher.go │ │ │ │ ├── writers.go │ │ │ │ └── writers_test.go │ │ │ │ ├── pools │ │ │ │ ├── pools.go │ │ │ │ └── pools_test.go │ │ │ │ ├── promise │ │ │ │ └── promise.go │ │ │ │ ├── stdcopy │ │ │ │ ├── stdcopy.go │ │ │ │ └── stdcopy_test.go │ │ │ │ ├── system │ │ │ │ ├── errors.go │ │ │ │ ├── filesys.go │ │ │ │ ├── filesys_windows.go │ │ │ │ ├── lstat.go │ │ │ │ ├── lstat_test.go │ │ │ │ ├── lstat_windows.go │ │ │ │ ├── meminfo.go │ │ │ │ ├── meminfo_linux.go │ │ │ │ ├── meminfo_linux_test.go │ │ │ │ ├── meminfo_unsupported.go │ │ │ │ ├── meminfo_windows.go │ │ │ │ ├── mknod.go │ │ │ │ ├── mknod_windows.go │ │ │ │ ├── stat.go │ │ │ │ ├── stat_linux.go │ │ │ │ ├── stat_test.go │ │ │ │ ├── stat_unsupported.go │ │ │ │ ├── stat_windows.go │ │ │ │ ├── umask.go │ │ │ │ ├── umask_windows.go │ │ │ │ ├── utimes_darwin.go │ │ │ │ ├── utimes_freebsd.go │ │ │ │ ├── utimes_linux.go │ │ │ │ ├── utimes_test.go │ │ │ │ ├── utimes_unsupported.go │ │ │ │ ├── xattrs_linux.go │ │ │ │ └── xattrs_unsupported.go │ │ │ │ └── units │ │ │ │ ├── duration.go │ │ │ │ ├── duration_test.go │ │ │ │ ├── size.go │ │ │ │ └── size_test.go │ │ │ └── gorilla │ │ │ ├── context │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── context.go │ │ │ ├── context_test.go │ │ │ └── doc.go │ │ │ └── mux │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── bench_test.go │ │ │ ├── doc.go │ │ │ ├── mux.go │ │ │ ├── mux_test.go │ │ │ ├── old_test.go │ │ │ ├── regexp.go │ │ │ └── route.go │ ├── hashicorp │ │ └── golang-lru │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── lru.go │ │ │ └── lru_test.go │ └── samalba │ │ └── dockerclient │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── auth.go │ │ ├── auth_test.go │ │ ├── dockerclient.go │ │ ├── dockerclient_test.go │ │ ├── engine_mock_test.go │ │ ├── example_responses.go │ │ ├── examples │ │ ├── events.go │ │ └── stats │ │ │ └── stats.go │ │ ├── interface.go │ │ ├── mockclient │ │ ├── mock.go │ │ └── mock_test.go │ │ ├── types.go │ │ └── utils.go │ └── gopkg.in │ └── yaml.v2 │ ├── LICENSE │ ├── LICENSE.libyaml │ ├── README.md │ ├── apic.go │ ├── decode.go │ ├── decode_test.go │ ├── emitterc.go │ ├── encode.go │ ├── encode_test.go │ ├── parserc.go │ ├── readerc.go │ ├── resolve.go │ ├── scannerc.go │ ├── sorter.go │ ├── suite_test.go │ ├── writerc.go │ ├── yaml.go │ ├── yamlh.go │ └── yamlprivateh.go ├── README.md ├── bindata_assetfs.go ├── config └── config.go ├── containers └── containers.go ├── images ├── gc.go ├── images.go └── update.go ├── logo.png ├── main.go ├── script ├── build-ui ├── package └── run └── sherdock-ember ├── .bowerrc ├── .editorconfig ├── .ember-cli ├── .gitignore ├── .jshintrc ├── .travis.yml ├── Brocfile.js ├── README.md ├── app ├── app.js ├── components │ └── .gitkeep ├── config │ ├── controller.js │ ├── route.js │ └── template.hbs ├── controllers │ └── .gitkeep ├── graph │ ├── route.js │ ├── template.hbs │ └── view.js ├── helpers │ ├── .gitkeep │ ├── display-size.js │ └── short-id.js ├── images │ ├── route.js │ └── template.hbs ├── index.html ├── index │ └── template.hbs ├── initializers │ ├── extend.js │ ├── lookup.js │ └── store.js ├── models │ └── .gitkeep ├── router.js ├── routes │ ├── .gitkeep │ └── application.js ├── styles │ └── app.scss ├── templates │ ├── application.hbs │ └── components │ │ └── .gitkeep ├── views │ └── .gitkeep └── volumes │ ├── controller.js │ ├── route.js │ └── template.hbs ├── bower.json ├── config └── environment.js ├── package.json ├── public ├── assets │ └── images │ │ └── logo.svg ├── crossdomain.xml └── robots.txt ├── server ├── .jshintrc ├── index.js └── proxies │ └── api.js ├── testem.json ├── tests ├── .jshintrc ├── helpers │ ├── resolver.js │ └── start-app.js ├── index.html ├── test-helper.js └── unit │ └── .gitkeep └── vendor └── .gitkeep /.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /sherdock 3 | /config.yml 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /config.yaml 2 | /sherdock 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.4 2 | EXPOSE 8080 3 | RUN go get github.com/tools/godep 4 | COPY . /go/src/github.com/rancher/sherdock 5 | WORKDIR /go/src/github.com/rancher/sherdock 6 | RUN godep go build -ldflags "-linkmode external -extldflags -static" -o /usr/bin/sherdock /go/src/github.com/rancher/sherdock/main.go /go/src/github.com/rancher/sherdock/bindata_assetfs.go 7 | CMD ["sherdock"] 8 | -------------------------------------------------------------------------------- /Dockerfile.dist: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | COPY sherdock / 3 | EXPOSE 8080 4 | CMD ["/sherdock"] 5 | -------------------------------------------------------------------------------- /Dockerfile.ui: -------------------------------------------------------------------------------- 1 | FROM golang:1.4 2 | EXPOSE 8080 3 | RUN go get github.com/tools/godep 4 | RUN apt-get update && apt-get install -y g++ 5 | RUN curl -L http://nodejs.org/dist/v0.12.4/node-v0.12.4-linux-x64.tar.gz | tar xvzf - -C /usr/local --strip-components=1 6 | RUN npm install -g ember-cli 7 | RUN npm install -g bower 8 | RUN go get github.com/jteeuwen/go-bindata/... 9 | RUN go get github.com/elazarl/go-bindata-assetfs/... 10 | COPY sherdock-ember /sherdock-ember 11 | RUN cd /sherdock-ember && \ 12 | npm install 13 | RUN cd /sherdock-ember && \ 14 | bower install --allow-root 15 | RUN cd /sherdock-ember && \ 16 | yes | ember update && \ 17 | ember build 18 | COPY . /go/src/github.com/rancher/sherdock 19 | WORKDIR /go/src/github.com/rancher/sherdock 20 | RUN cp -rf /sherdock-ember/dist /go/src/github.com/rancher/sherdock/data && \ 21 | cd /go/src/github.com/rancher/sherdock && \ 22 | for i in data/images data/graph data/volumes data/config; do mkdir -p $i && cp data/index.html $i; done && \ 23 | go-bindata-assetfs data/... 24 | RUN godep go build -o /usr/bin/sherdock /go/src/github.com/rancher/sherdock/main.go /go/src/github.com/rancher/sherdock/bindata_assetfs.go 25 | CMD sherdock 26 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/rancher/sherdock", 3 | "GoVersion": "go1.4.1", 4 | "Deps": [ 5 | { 6 | "ImportPath": "github.com/Sirupsen/logrus", 7 | "Comment": "v0.8.2-12-g2a0a9a1", 8 | "Rev": "2a0a9a12ae2892ccfa9ab59c1222e9dcd29f9367" 9 | }, 10 | { 11 | "ImportPath": "github.com/cloudnautique/go-vol/volumes", 12 | "Rev": "47d1c87e33bc22bab8966a495ec12df3ec97c1d8" 13 | }, 14 | { 15 | "ImportPath": "github.com/docker/docker/pkg/units", 16 | "Comment": "v1.4.1-4206-g67f9bbc", 17 | "Rev": "67f9bbcbd4d741e22e61b21a411cd904dcd4329c" 18 | }, 19 | { 20 | "ImportPath": "github.com/elazarl/go-bindata-assetfs", 21 | "Rev": "bea323321994103859d60197d229f1a94699dde3" 22 | }, 23 | { 24 | "ImportPath": "github.com/emicklei/go-restful", 25 | "Comment": "v1.1.3-56-g4b8e817", 26 | "Rev": "4b8e81764a23eb740d9066dda581aaf756ecd4b2" 27 | }, 28 | { 29 | "ImportPath": "github.com/fsouza/go-dockerclient", 30 | "Rev": "ef07a30edc7949ee0f420b5640f2da843bce9cce" 31 | }, 32 | { 33 | "ImportPath": "github.com/hashicorp/golang-lru", 34 | "Rev": "995efda3e073b6946b175ed93901d729ad47466a" 35 | }, 36 | { 37 | "ImportPath": "github.com/samalba/dockerclient", 38 | "Rev": "87e11748d2ceba2fcb5b80f1ed5067ff639da0a3" 39 | }, 40 | { 41 | "ImportPath": "gopkg.in/yaml.v2", 42 | "Rev": "c1cd2254a6dd314c9d73c338c12688c9325d85c6" 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/.gitignore: -------------------------------------------------------------------------------- 1 | /pkg 2 | /bin 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore: -------------------------------------------------------------------------------- 1 | logrus 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.2 4 | - 1.3 5 | - 1.4 6 | - tip 7 | install: 8 | - go get -t ./... 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.8.2 2 | 3 | logrus: fix more Fatal family functions 4 | 5 | # 0.8.1 6 | 7 | logrus: fix not exiting on `Fatalf` and `Fatalln` 8 | 9 | # 0.8.0 10 | 11 | logrus: defaults to stderr instead of stdout 12 | hooks/sentry: add special field for `*http.Request` 13 | formatter/text: ignore Windows for colors 14 | 15 | # 0.7.3 16 | 17 | formatter/\*: allow configuration of timestamp layout 18 | 19 | # 0.7.2 20 | 21 | formatter/text: Add configuration option for time format (#158) 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Simon Eskildsen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/entry_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestEntryPanicln(t *testing.T) { 12 | errBoom := fmt.Errorf("boom time") 13 | 14 | defer func() { 15 | p := recover() 16 | assert.NotNil(t, p) 17 | 18 | switch pVal := p.(type) { 19 | case *Entry: 20 | assert.Equal(t, "kaboom", pVal.Message) 21 | assert.Equal(t, errBoom, pVal.Data["err"]) 22 | default: 23 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 24 | } 25 | }() 26 | 27 | logger := New() 28 | logger.Out = &bytes.Buffer{} 29 | entry := NewEntry(logger) 30 | entry.WithField("err", errBoom).Panicln("kaboom") 31 | } 32 | 33 | func TestEntryPanicf(t *testing.T) { 34 | errBoom := fmt.Errorf("boom again") 35 | 36 | defer func() { 37 | p := recover() 38 | assert.NotNil(t, p) 39 | 40 | switch pVal := p.(type) { 41 | case *Entry: 42 | assert.Equal(t, "kaboom true", pVal.Message) 43 | assert.Equal(t, errBoom, pVal.Data["err"]) 44 | default: 45 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 46 | } 47 | }() 48 | 49 | logger := New() 50 | logger.Out = &bytes.Buffer{} 51 | entry := NewEntry(logger) 52 | entry.WithField("err", errBoom).Panicf("kaboom %v", true) 53 | } 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | ) 6 | 7 | var log = logrus.New() 8 | 9 | func init() { 10 | log.Formatter = new(logrus.JSONFormatter) 11 | log.Formatter = new(logrus.TextFormatter) // default 12 | log.Level = logrus.DebugLevel 13 | } 14 | 15 | func main() { 16 | defer func() { 17 | err := recover() 18 | if err != nil { 19 | log.WithFields(logrus.Fields{ 20 | "omg": true, 21 | "err": err, 22 | "number": 100, 23 | }).Fatal("The ice breaks!") 24 | } 25 | }() 26 | 27 | log.WithFields(logrus.Fields{ 28 | "animal": "walrus", 29 | "number": 8, 30 | }).Debug("Started observing beach") 31 | 32 | log.WithFields(logrus.Fields{ 33 | "animal": "walrus", 34 | "size": 10, 35 | }).Info("A group of walrus emerges from the ocean") 36 | 37 | log.WithFields(logrus.Fields{ 38 | "omg": true, 39 | "number": 122, 40 | }).Warn("The group's number increased tremendously!") 41 | 42 | log.WithFields(logrus.Fields{ 43 | "temperature": -4, 44 | }).Debug("Temperature changes") 45 | 46 | log.WithFields(logrus.Fields{ 47 | "animal": "orca", 48 | "size": 9009, 49 | }).Panic("It's over 9000!") 50 | } 51 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | "github.com/Sirupsen/logrus/hooks/airbrake" 6 | ) 7 | 8 | var log = logrus.New() 9 | 10 | func init() { 11 | log.Formatter = new(logrus.TextFormatter) // default 12 | log.Hooks.Add(airbrake.NewHook("https://example.com", "xyz", "development")) 13 | } 14 | 15 | func main() { 16 | log.WithFields(logrus.Fields{ 17 | "animal": "walrus", 18 | "size": 10, 19 | }).Info("A group of walrus emerges from the ocean") 20 | 21 | log.WithFields(logrus.Fields{ 22 | "omg": true, 23 | "number": 122, 24 | }).Warn("The group's number increased tremendously!") 25 | 26 | log.WithFields(logrus.Fields{ 27 | "omg": true, 28 | "number": 100, 29 | }).Fatal("The ice breaks!") 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import "time" 4 | 5 | const DefaultTimestampFormat = time.RFC3339 6 | 7 | // The Formatter interface is used to implement a custom Formatter. It takes an 8 | // `Entry`. It exposes all the fields, including the default ones: 9 | // 10 | // * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. 11 | // * `entry.Data["time"]`. The timestamp. 12 | // * `entry.Data["level"]. The level the entry was logged at. 13 | // 14 | // Any additional fields added with `WithField` or `WithFields` are also in 15 | // `entry.Data`. Format is expected to return an array of bytes which are then 16 | // logged to `logger.Out`. 17 | type Formatter interface { 18 | Format(*Entry) ([]byte, error) 19 | } 20 | 21 | // This is to not silently overwrite `time`, `msg` and `level` fields when 22 | // dumping it. If this code wasn't there doing: 23 | // 24 | // logrus.WithField("level", 1).Info("hello") 25 | // 26 | // Would just silently drop the user provided level. Instead with this code 27 | // it'll logged as: 28 | // 29 | // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} 30 | // 31 | // It's not exported because it's still using Data in an opinionated way. It's to 32 | // avoid code duplication between the two default formatters. 33 | func prefixFieldClashes(data Fields) { 34 | _, ok := data["time"] 35 | if ok { 36 | data["fields.time"] = data["time"] 37 | } 38 | 39 | _, ok = data["msg"] 40 | if ok { 41 | data["fields.msg"] = data["msg"] 42 | } 43 | 44 | _, ok = data["level"] 45 | if ok { 46 | data["fields.level"] = data["level"] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go: -------------------------------------------------------------------------------- 1 | package logstash 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/Sirupsen/logrus" 8 | ) 9 | 10 | // Formatter generates json in logstash format. 11 | // Logstash site: http://logstash.net/ 12 | type LogstashFormatter struct { 13 | Type string // if not empty use for logstash type field. 14 | 15 | // TimestampFormat sets the format used for timestamps. 16 | TimestampFormat string 17 | } 18 | 19 | func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) { 20 | entry.Data["@version"] = 1 21 | 22 | if f.TimestampFormat == "" { 23 | f.TimestampFormat = logrus.DefaultTimestampFormat 24 | } 25 | 26 | entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat) 27 | 28 | // set message field 29 | v, ok := entry.Data["message"] 30 | if ok { 31 | entry.Data["fields.message"] = v 32 | } 33 | entry.Data["message"] = entry.Message 34 | 35 | // set level field 36 | v, ok = entry.Data["level"] 37 | if ok { 38 | entry.Data["fields.level"] = v 39 | } 40 | entry.Data["level"] = entry.Level.String() 41 | 42 | // set type field 43 | if f.Type != "" { 44 | v, ok = entry.Data["type"] 45 | if ok { 46 | entry.Data["fields.type"] = v 47 | } 48 | entry.Data["type"] = f.Type 49 | } 50 | 51 | serialized, err := json.Marshal(entry.Data) 52 | if err != nil { 53 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 54 | } 55 | return append(serialized, '\n'), nil 56 | } 57 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash_test.go: -------------------------------------------------------------------------------- 1 | package logstash 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "github.com/Sirupsen/logrus" 7 | "github.com/stretchr/testify/assert" 8 | "testing" 9 | ) 10 | 11 | func TestLogstashFormatter(t *testing.T) { 12 | assert := assert.New(t) 13 | 14 | lf := LogstashFormatter{Type: "abc"} 15 | 16 | fields := logrus.Fields{ 17 | "message": "def", 18 | "level": "ijk", 19 | "type": "lmn", 20 | "one": 1, 21 | "pi": 3.14, 22 | "bool": true, 23 | } 24 | 25 | entry := logrus.WithFields(fields) 26 | entry.Message = "msg" 27 | entry.Level = logrus.InfoLevel 28 | 29 | b, _ := lf.Format(entry) 30 | 31 | var data map[string]interface{} 32 | dec := json.NewDecoder(bytes.NewReader(b)) 33 | dec.UseNumber() 34 | dec.Decode(&data) 35 | 36 | // base fields 37 | assert.Equal(json.Number("1"), data["@version"]) 38 | assert.NotEmpty(data["@timestamp"]) 39 | assert.Equal("abc", data["type"]) 40 | assert.Equal("msg", data["message"]) 41 | assert.Equal("info", data["level"]) 42 | 43 | // substituted fields 44 | assert.Equal("def", data["fields.message"]) 45 | assert.Equal("ijk", data["fields.level"]) 46 | assert.Equal("lmn", data["fields.type"]) 47 | 48 | // formats 49 | assert.Equal(json.Number("1"), data["one"]) 50 | assert.Equal(json.Number("3.14"), data["pi"]) 51 | assert.Equal(true, data["bool"]) 52 | } 53 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | // A hook to be fired when logging on the logging levels returned from 4 | // `Levels()` on your implementation of the interface. Note that this is not 5 | // fired in a goroutine or a channel with workers, you should handle such 6 | // functionality yourself if your call is non-blocking and you don't wish for 7 | // the logging calls for levels returned from `Levels()` to block. 8 | type Hook interface { 9 | Levels() []Level 10 | Fire(*Entry) error 11 | } 12 | 13 | // Internal type for storing the hooks on a logger instance. 14 | type levelHooks map[Level][]Hook 15 | 16 | // Add a hook to an instance of logger. This is called with 17 | // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. 18 | func (hooks levelHooks) Add(hook Hook) { 19 | for _, level := range hook.Levels() { 20 | hooks[level] = append(hooks[level], hook) 21 | } 22 | } 23 | 24 | // Fire all the hooks for the passed level. Used by `entry.log` to fire 25 | // appropriate hooks for a log entry. 26 | func (hooks levelHooks) Fire(level Level, entry *Entry) error { 27 | for _, hook := range hooks[level] { 28 | if err := hook.Fire(entry); err != nil { 29 | return err 30 | } 31 | } 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go: -------------------------------------------------------------------------------- 1 | package airbrake 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | "github.com/Sirupsen/logrus" 8 | "github.com/tobi/airbrake-go" 9 | ) 10 | 11 | // AirbrakeHook to send exceptions to an exception-tracking service compatible 12 | // with the Airbrake API. 13 | type airbrakeHook struct { 14 | APIKey string 15 | Endpoint string 16 | Environment string 17 | } 18 | 19 | func NewHook(endpoint, apiKey, env string) *airbrakeHook { 20 | return &airbrakeHook{ 21 | APIKey: apiKey, 22 | Endpoint: endpoint, 23 | Environment: env, 24 | } 25 | } 26 | 27 | func (hook *airbrakeHook) Fire(entry *logrus.Entry) error { 28 | airbrake.ApiKey = hook.APIKey 29 | airbrake.Endpoint = hook.Endpoint 30 | airbrake.Environment = hook.Environment 31 | 32 | var notifyErr error 33 | err, ok := entry.Data["error"].(error) 34 | if ok { 35 | notifyErr = err 36 | } else { 37 | notifyErr = errors.New(entry.Message) 38 | } 39 | 40 | airErr := airbrake.Notify(notifyErr) 41 | if airErr != nil { 42 | return fmt.Errorf("Failed to send error to Airbrake: %s", airErr) 43 | } 44 | 45 | return nil 46 | } 47 | 48 | func (hook *airbrakeHook) Levels() []logrus.Level { 49 | return []logrus.Level{ 50 | logrus.ErrorLevel, 51 | logrus.FatalLevel, 52 | logrus.PanicLevel, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag_test.go: -------------------------------------------------------------------------------- 1 | package logrus_bugsnag 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "io/ioutil" 7 | "net/http" 8 | "net/http/httptest" 9 | "testing" 10 | "time" 11 | 12 | "github.com/Sirupsen/logrus" 13 | "github.com/bugsnag/bugsnag-go" 14 | ) 15 | 16 | type notice struct { 17 | Events []struct { 18 | Exceptions []struct { 19 | Message string `json:"message"` 20 | } `json:"exceptions"` 21 | } `json:"events"` 22 | } 23 | 24 | func TestNoticeReceived(t *testing.T) { 25 | msg := make(chan string, 1) 26 | expectedMsg := "foo" 27 | 28 | ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 29 | var notice notice 30 | data, _ := ioutil.ReadAll(r.Body) 31 | if err := json.Unmarshal(data, ¬ice); err != nil { 32 | t.Error(err) 33 | } 34 | _ = r.Body.Close() 35 | 36 | msg <- notice.Events[0].Exceptions[0].Message 37 | })) 38 | defer ts.Close() 39 | 40 | hook := &bugsnagHook{} 41 | 42 | bugsnag.Configure(bugsnag.Configuration{ 43 | Endpoint: ts.URL, 44 | ReleaseStage: "production", 45 | APIKey: "12345678901234567890123456789012", 46 | Synchronous: true, 47 | }) 48 | 49 | log := logrus.New() 50 | log.Hooks.Add(hook) 51 | 52 | log.WithFields(logrus.Fields{ 53 | "error": errors.New(expectedMsg), 54 | }).Error("Bugsnag will not see this string") 55 | 56 | select { 57 | case received := <-msg: 58 | if received != expectedMsg { 59 | t.Errorf("Unexpected message received: %s", received) 60 | } 61 | case <-time.After(time.Second): 62 | t.Error("Timed out; no notice received by Bugsnag API") 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md: -------------------------------------------------------------------------------- 1 | # Papertrail Hook for Logrus :walrus: 2 | 3 | [Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts). 4 | 5 | In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible. 6 | 7 | ## Usage 8 | 9 | You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`. 10 | 11 | For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs. 12 | 13 | ```go 14 | import ( 15 | "log/syslog" 16 | "github.com/Sirupsen/logrus" 17 | "github.com/Sirupsen/logrus/hooks/papertrail" 18 | ) 19 | 20 | func main() { 21 | log := logrus.New() 22 | hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME) 23 | 24 | if err == nil { 25 | log.Hooks.Add(hook) 26 | } 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go: -------------------------------------------------------------------------------- 1 | package logrus_papertrail 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "time" 8 | 9 | "github.com/Sirupsen/logrus" 10 | ) 11 | 12 | const ( 13 | format = "Jan 2 15:04:05" 14 | ) 15 | 16 | // PapertrailHook to send logs to a logging service compatible with the Papertrail API. 17 | type PapertrailHook struct { 18 | Host string 19 | Port int 20 | AppName string 21 | UDPConn net.Conn 22 | } 23 | 24 | // NewPapertrailHook creates a hook to be added to an instance of logger. 25 | func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) { 26 | conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port)) 27 | return &PapertrailHook{host, port, appName, conn}, err 28 | } 29 | 30 | // Fire is called when a log event is fired. 31 | func (hook *PapertrailHook) Fire(entry *logrus.Entry) error { 32 | date := time.Now().Format(format) 33 | msg, _ := entry.String() 34 | payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg) 35 | 36 | bytesWritten, err := hook.UDPConn.Write([]byte(payload)) 37 | if err != nil { 38 | fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err) 39 | return err 40 | } 41 | 42 | return nil 43 | } 44 | 45 | // Levels returns the available logging levels. 46 | func (hook *PapertrailHook) Levels() []logrus.Level { 47 | return []logrus.Level{ 48 | logrus.PanicLevel, 49 | logrus.FatalLevel, 50 | logrus.ErrorLevel, 51 | logrus.WarnLevel, 52 | logrus.InfoLevel, 53 | logrus.DebugLevel, 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go: -------------------------------------------------------------------------------- 1 | package logrus_papertrail 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Sirupsen/logrus" 8 | "github.com/stvp/go-udp-testing" 9 | ) 10 | 11 | func TestWritingToUDP(t *testing.T) { 12 | port := 16661 13 | udp.SetAddr(fmt.Sprintf(":%d", port)) 14 | 15 | hook, err := NewPapertrailHook("localhost", port, "test") 16 | if err != nil { 17 | t.Errorf("Unable to connect to local UDP server.") 18 | } 19 | 20 | log := logrus.New() 21 | log.Hooks.Add(hook) 22 | 23 | udp.ShouldReceive(t, "foo", func() { 24 | log.Info("foo") 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md: -------------------------------------------------------------------------------- 1 | # Syslog Hooks for Logrus :walrus: 2 | 3 | ## Usage 4 | 5 | ```go 6 | import ( 7 | "log/syslog" 8 | "github.com/Sirupsen/logrus" 9 | logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" 10 | ) 11 | 12 | func main() { 13 | log := logrus.New() 14 | hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") 15 | 16 | if err == nil { 17 | log.Hooks.Add(hook) 18 | } 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go: -------------------------------------------------------------------------------- 1 | package logrus_syslog 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Sirupsen/logrus" 6 | "log/syslog" 7 | "os" 8 | ) 9 | 10 | // SyslogHook to send logs via syslog. 11 | type SyslogHook struct { 12 | Writer *syslog.Writer 13 | SyslogNetwork string 14 | SyslogRaddr string 15 | } 16 | 17 | // Creates a hook to be added to an instance of logger. This is called with 18 | // `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")` 19 | // `if err == nil { log.Hooks.Add(hook) }` 20 | func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) { 21 | w, err := syslog.Dial(network, raddr, priority, tag) 22 | return &SyslogHook{w, network, raddr}, err 23 | } 24 | 25 | func (hook *SyslogHook) Fire(entry *logrus.Entry) error { 26 | line, err := entry.String() 27 | if err != nil { 28 | fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err) 29 | return err 30 | } 31 | 32 | switch entry.Level { 33 | case logrus.PanicLevel: 34 | return hook.Writer.Crit(line) 35 | case logrus.FatalLevel: 36 | return hook.Writer.Crit(line) 37 | case logrus.ErrorLevel: 38 | return hook.Writer.Err(line) 39 | case logrus.WarnLevel: 40 | return hook.Writer.Warning(line) 41 | case logrus.InfoLevel: 42 | return hook.Writer.Info(line) 43 | case logrus.DebugLevel: 44 | return hook.Writer.Debug(line) 45 | default: 46 | return nil 47 | } 48 | } 49 | 50 | func (hook *SyslogHook) Levels() []logrus.Level { 51 | return []logrus.Level{ 52 | logrus.PanicLevel, 53 | logrus.FatalLevel, 54 | logrus.ErrorLevel, 55 | logrus.WarnLevel, 56 | logrus.InfoLevel, 57 | logrus.DebugLevel, 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go: -------------------------------------------------------------------------------- 1 | package logrus_syslog 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | "log/syslog" 6 | "testing" 7 | ) 8 | 9 | func TestLocalhostAddAndPrint(t *testing.T) { 10 | log := logrus.New() 11 | hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") 12 | 13 | if err != nil { 14 | t.Errorf("Unable to connect to local syslog.") 15 | } 16 | 17 | log.Hooks.Add(hook) 18 | 19 | for _, level := range hook.Levels() { 20 | if len(log.Hooks[level]) != 1 { 21 | t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level])) 22 | } 23 | } 24 | 25 | log.Info("Congratulations!") 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type JSONFormatter struct { 9 | // TimestampFormat sets the format used for marshaling timestamps. 10 | TimestampFormat string 11 | } 12 | 13 | func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { 14 | data := make(Fields, len(entry.Data)+3) 15 | for k, v := range entry.Data { 16 | switch v := v.(type) { 17 | case error: 18 | // Otherwise errors are ignored by `encoding/json` 19 | // https://github.com/Sirupsen/logrus/issues/137 20 | data[k] = v.Error() 21 | default: 22 | data[k] = v 23 | } 24 | } 25 | prefixFieldClashes(data) 26 | 27 | timestampFormat := f.TimestampFormat 28 | if timestampFormat == "" { 29 | timestampFormat = DefaultTimestampFormat 30 | } 31 | 32 | data["time"] = entry.Time.Format(timestampFormat) 33 | data["msg"] = entry.Message 34 | data["level"] = entry.Level.String() 35 | 36 | serialized, err := json.Marshal(data) 37 | if err != nil { 38 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 39 | } 40 | return append(serialized, '\n'), nil 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2013 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package logrus 7 | 8 | import "syscall" 9 | 10 | const ioctlReadTermios = syscall.TIOCGETA 11 | 12 | type Termios syscall.Termios 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go: -------------------------------------------------------------------------------- 1 | /* 2 | Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin. 3 | */ 4 | package logrus 5 | 6 | import ( 7 | "syscall" 8 | ) 9 | 10 | const ioctlReadTermios = syscall.TIOCGETA 11 | 12 | type Termios struct { 13 | Iflag uint32 14 | Oflag uint32 15 | Cflag uint32 16 | Lflag uint32 17 | Cc [20]uint8 18 | Ispeed uint32 19 | Ospeed uint32 20 | } 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2013 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package logrus 7 | 8 | import "syscall" 9 | 10 | const ioctlReadTermios = syscall.TCGETS 11 | 12 | type Termios syscall.Termios 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build linux darwin freebsd openbsd 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | // IsTerminal returns true if the given file descriptor is a terminal. 16 | func IsTerminal() bool { 17 | fd := syscall.Stdout 18 | var termios Termios 19 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 20 | return err == 0 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_openbsd.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import "syscall" 4 | 5 | const ioctlReadTermios = syscall.TIOCGETA 6 | 7 | type Termios syscall.Termios 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build windows 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 16 | 17 | var ( 18 | procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 19 | ) 20 | 21 | // IsTerminal returns true if the given file descriptor is a terminal. 22 | func IsTerminal() bool { 23 | fd := syscall.Stdout 24 | var st uint32 25 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 26 | return r != 0 && e == 0 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/writer.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "runtime" 7 | ) 8 | 9 | func (logger *Logger) Writer() *io.PipeWriter { 10 | reader, writer := io.Pipe() 11 | 12 | go logger.writerScanner(reader) 13 | runtime.SetFinalizer(writer, writerFinalizer) 14 | 15 | return writer 16 | } 17 | 18 | func (logger *Logger) writerScanner(reader *io.PipeReader) { 19 | scanner := bufio.NewScanner(reader) 20 | for scanner.Scan() { 21 | logger.Print(scanner.Text()) 22 | } 23 | if err := scanner.Err(); err != nil { 24 | logger.Errorf("Error while reading from Writer: %s", err) 25 | } 26 | reader.Close() 27 | } 28 | 29 | func writerFinalizer(writer *io.PipeWriter) { 30 | writer.Close() 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // HumanDuration returns a human-readable approximation of a duration 9 | // (eg. "About a minute", "4 hours ago", etc.) 10 | func HumanDuration(d time.Duration) string { 11 | if seconds := int(d.Seconds()); seconds < 1 { 12 | return "Less than a second" 13 | } else if seconds < 60 { 14 | return fmt.Sprintf("%d seconds", seconds) 15 | } else if minutes := int(d.Minutes()); minutes == 1 { 16 | return "About a minute" 17 | } else if minutes < 60 { 18 | return fmt.Sprintf("%d minutes", minutes) 19 | } else if hours := int(d.Hours()); hours == 1 { 20 | return "About an hour" 21 | } else if hours < 48 { 22 | return fmt.Sprintf("%d hours", hours) 23 | } else if hours < 24*7*2 { 24 | return fmt.Sprintf("%d days", hours/24) 25 | } else if hours < 24*30*3 { 26 | return fmt.Sprintf("%d weeks", hours/24/7) 27 | } else if hours < 24*365*2 { 28 | return fmt.Sprintf("%d months", hours/24/30) 29 | } 30 | return fmt.Sprintf("%d years", int(d.Hours())/24/365) 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/elazarl/go-bindata-assetfs/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Elazar Leibovich 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/elazarl/go-bindata-assetfs/README.md: -------------------------------------------------------------------------------- 1 | # go-bindata-assetfs 2 | 3 | Serve embedded files from [jteeuwen/go-bindata](https://github.com/jteeuwen/go-bindata) with `net/http`. 4 | 5 | [GoDoc](http://godoc.org/github.com/elazarl/go-bindata-assetfs) 6 | 7 | ### Installation 8 | 9 | Install with 10 | 11 | $ go get github.com/jteeuwen/go-bindata/... 12 | $ go get github.com/elazarl/go-bindata-assetfs/... 13 | 14 | ### Creating embedded data 15 | 16 | Usage is identical to [jteeuwen/go-bindata](https://github.com/jteeuwen/go-bindata) usage, 17 | instead of running `go-bindata` run `go-bindata-assetfs`. 18 | 19 | The tool will create a `bindata_assetfs.go` file, which contains the embedded data. 20 | 21 | A typical use case is 22 | 23 | $ go-bindata-assetfs data/... 24 | 25 | ### Using assetFS in your code 26 | 27 | The generated file provides an `assetFS()` function that returns a `http.Filesystem` 28 | wrapping the embedded files. What you usually want to do is: 29 | 30 | http.Handle("/", http.FileServer(assetFS())) 31 | 32 | This would run an HTTP server serving the embedded files. 33 | 34 | ## Without running binary tool 35 | 36 | You can always just run the `go-bindata` tool, and then 37 | 38 | use 39 | 40 | import "github.com/elazarl/go-bindata-assetfs" 41 | ... 42 | http.Handle("/", 43 | http.FileServer( 44 | &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "data"})) 45 | 46 | to serve files embedded from the `data` directory. 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/elazarl/go-bindata-assetfs/doc.go: -------------------------------------------------------------------------------- 1 | // assetfs allows packages to serve static content embedded 2 | // with the go-bindata tool with the standard net/http package. 3 | // 4 | // See https://github.com/jteeuwen/go-bindata for more information 5 | // about embedding binary data with go-bindata. 6 | // 7 | // Usage example, after running 8 | // $ go-bindata data/... 9 | // use: 10 | // http.Handle("/", 11 | // http.FileServer( 12 | // &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "data"})) 13 | package assetfs 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | 24 | restful.html 25 | 26 | *.out 27 | 28 | tmp.prof 29 | 30 | go-restful.test 31 | 32 | examples/restful-basic-authentication 33 | 34 | examples/restful-encoding-filter 35 | 36 | examples/restful-filters 37 | 38 | examples/restful-hello-world 39 | 40 | examples/restful-resource-functions 41 | 42 | examples/restful-serve-static 43 | 44 | examples/restful-user-service 45 | 46 | *.DS_Store 47 | examples/restful-user-resource 48 | 49 | examples/restful-multi-containers 50 | 51 | examples/restful-form-handling 52 | 53 | examples/restful-CORS-filter 54 | 55 | examples/restful-options-filter 56 | 57 | examples/restful-curly-router 58 | 59 | examples/restful-cpuprofiler-service 60 | 61 | examples/restful-pre-post-filters 62 | 63 | curly.prof 64 | 65 | examples/restful-NCSA-logging 66 | 67 | examples/restful-html-template 68 | 69 | s.html 70 | restful-path-tail 71 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012,2013 Ernest Micklei 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/Srcfile: -------------------------------------------------------------------------------- 1 | {"SkipDirs": ["examples"]} 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/bench_curly_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httptest" 7 | "testing" 8 | ) 9 | 10 | func setupCurly(container *Container) []string { 11 | wsCount := 26 12 | rtCount := 26 13 | urisCurly := []string{} 14 | 15 | container.Router(CurlyRouter{}) 16 | for i := 0; i < wsCount; i++ { 17 | root := fmt.Sprintf("/%s/{%s}/", string(i+97), string(i+97)) 18 | ws := new(WebService).Path(root) 19 | for j := 0; j < rtCount; j++ { 20 | sub := fmt.Sprintf("/%s2/{%s2}", string(j+97), string(j+97)) 21 | ws.Route(ws.GET(sub).Consumes("application/xml").Produces("application/xml").To(echoCurly)) 22 | } 23 | container.Add(ws) 24 | for _, each := range ws.Routes() { 25 | urisCurly = append(urisCurly, "http://bench.com"+each.Path) 26 | } 27 | } 28 | return urisCurly 29 | } 30 | 31 | func echoCurly(req *Request, resp *Response) {} 32 | 33 | func BenchmarkManyCurly(b *testing.B) { 34 | container := NewContainer() 35 | urisCurly := setupCurly(container) 36 | b.ResetTimer() 37 | for t := 0; t < b.N; t++ { 38 | for r := 0; r < 1000; r++ { 39 | for _, each := range urisCurly { 40 | sendNoReturnTo(each, container, t) 41 | } 42 | } 43 | } 44 | } 45 | 46 | func sendNoReturnTo(address string, container *Container, t int) { 47 | httpRequest, _ := http.NewRequest("GET", address, nil) 48 | httpRequest.Header.Set("Accept", "application/xml") 49 | httpWriter := httptest.NewRecorder() 50 | container.dispatch(httpWriter, httpRequest) 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/bench_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "testing" 7 | ) 8 | 9 | var uris = []string{} 10 | 11 | func setup(container *Container) { 12 | wsCount := 26 13 | rtCount := 26 14 | 15 | for i := 0; i < wsCount; i++ { 16 | root := fmt.Sprintf("/%s/{%s}/", string(i+97), string(i+97)) 17 | ws := new(WebService).Path(root) 18 | for j := 0; j < rtCount; j++ { 19 | sub := fmt.Sprintf("/%s2/{%s2}", string(j+97), string(j+97)) 20 | ws.Route(ws.GET(sub).To(echo)) 21 | } 22 | container.Add(ws) 23 | for _, each := range ws.Routes() { 24 | uris = append(uris, "http://bench.com"+each.Path) 25 | } 26 | } 27 | } 28 | 29 | func echo(req *Request, resp *Response) { 30 | io.WriteString(resp.ResponseWriter, "echo") 31 | } 32 | 33 | func BenchmarkMany(b *testing.B) { 34 | container := NewContainer() 35 | setup(container) 36 | b.ResetTimer() 37 | for t := 0; t < b.N; t++ { 38 | for _, each := range uris { 39 | // println(each) 40 | sendItTo(each, container) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/bench_test.sh: -------------------------------------------------------------------------------- 1 | #go test -run=none -file bench_test.go -test.bench . -cpuprofile=bench_test.out 2 | 3 | go test -c 4 | ./go-restful.test -test.run=none -test.cpuprofile=tmp.prof -test.bench=BenchmarkMany 5 | ./go-restful.test -test.run=none -test.cpuprofile=curly.prof -test.bench=BenchmarkManyCurly 6 | 7 | #go tool pprof go-restful.test tmp.prof 8 | go tool pprof go-restful.test curly.prof 9 | 10 | 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/compress_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | func TestGzip(t *testing.T) { 10 | EnableContentEncoding = true 11 | httpRequest, _ := http.NewRequest("GET", "/test", nil) 12 | httpRequest.Header.Set("Accept-Encoding", "gzip,deflate") 13 | httpWriter := httptest.NewRecorder() 14 | wanted, encoding := wantsCompressedResponse(httpRequest) 15 | if !wanted { 16 | t.Fatal("should accept gzip") 17 | } 18 | if encoding != "gzip" { 19 | t.Fatal("expected gzip") 20 | } 21 | c, err := NewCompressingResponseWriter(httpWriter, encoding) 22 | if err != nil { 23 | t.Fatal(err.Error()) 24 | } 25 | c.Write([]byte("Hello World")) 26 | c.Close() 27 | if httpWriter.Header().Get("Content-Encoding") != "gzip" { 28 | t.Fatal("Missing gzip header") 29 | } 30 | } 31 | 32 | func TestDeflate(t *testing.T) { 33 | EnableContentEncoding = true 34 | httpRequest, _ := http.NewRequest("GET", "/test", nil) 35 | httpRequest.Header.Set("Accept-Encoding", "deflate,gzip") 36 | httpWriter := httptest.NewRecorder() 37 | wanted, encoding := wantsCompressedResponse(httpRequest) 38 | if !wanted { 39 | t.Fatal("should accept deflate") 40 | } 41 | if encoding != "deflate" { 42 | t.Fatal("expected deflate") 43 | } 44 | c, err := NewCompressingResponseWriter(httpWriter, encoding) 45 | if err != nil { 46 | t.Fatal(err.Error()) 47 | } 48 | c.Write([]byte("Hello World")) 49 | c.Close() 50 | if httpWriter.Header().Get("Content-Encoding") != "deflate" { 51 | t.Fatal("Missing deflate header") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/constants.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | // Copyright 2013 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | 7 | const ( 8 | MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces() 9 | MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces() 10 | MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default 11 | 12 | HEADER_Allow = "Allow" 13 | HEADER_Accept = "Accept" 14 | HEADER_Origin = "Origin" 15 | HEADER_ContentType = "Content-Type" 16 | HEADER_LastModified = "Last-Modified" 17 | HEADER_AcceptEncoding = "Accept-Encoding" 18 | HEADER_ContentEncoding = "Content-Encoding" 19 | HEADER_AccessControlExposeHeaders = "Access-Control-Expose-Headers" 20 | HEADER_AccessControlRequestMethod = "Access-Control-Request-Method" 21 | HEADER_AccessControlRequestHeaders = "Access-Control-Request-Headers" 22 | HEADER_AccessControlAllowMethods = "Access-Control-Allow-Methods" 23 | HEADER_AccessControlAllowOrigin = "Access-Control-Allow-Origin" 24 | HEADER_AccessControlAllowCredentials = "Access-Control-Allow-Credentials" 25 | HEADER_AccessControlAllowHeaders = "Access-Control-Allow-Headers" 26 | HEADER_AccessControlMaxAge = "Access-Control-Max-Age" 27 | 28 | ENCODING_GZIP = "gzip" 29 | ENCODING_DEFLATE = "deflate" 30 | ) 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/container_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | // go test -v -test.run TestContainer_computeAllowedMethods ...restful 9 | func TestContainer_computeAllowedMethods(t *testing.T) { 10 | wc := NewContainer() 11 | ws1 := new(WebService).Path("/users") 12 | ws1.Route(ws1.GET("{i}").To(dummy)) 13 | ws1.Route(ws1.POST("{i}").To(dummy)) 14 | wc.Add(ws1) 15 | httpRequest, _ := http.NewRequest("GET", "http://api.his.com/users/1", nil) 16 | rreq := Request{Request: httpRequest} 17 | m := wc.computeAllowedMethods(&rreq) 18 | if len(m) != 2 { 19 | t.Errorf("got %d expected 2 methods, %v", len(m), m) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/coverage.sh: -------------------------------------------------------------------------------- 1 | go test -coverprofile=coverage.out 2 | go tool cover -html=coverage.out -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/curly_route.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | // Copyright 2013 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | 7 | // curlyRoute exits for sorting Routes by the CurlyRouter based on number of parameters and number of static path elements. 8 | type curlyRoute struct { 9 | route Route 10 | paramCount int 11 | staticCount int 12 | } 13 | 14 | type sortableCurlyRoutes struct { 15 | candidates []*curlyRoute 16 | } 17 | 18 | func (s *sortableCurlyRoutes) add(route *curlyRoute) { 19 | s.candidates = append(s.candidates, route) 20 | } 21 | 22 | func (s *sortableCurlyRoutes) routes() (routes []Route) { 23 | for _, each := range s.candidates { 24 | routes = append(routes, each.route) // TODO change return type 25 | } 26 | return routes 27 | } 28 | 29 | func (s *sortableCurlyRoutes) Len() int { 30 | return len(s.candidates) 31 | } 32 | func (s *sortableCurlyRoutes) Swap(i, j int) { 33 | s.candidates[i], s.candidates[j] = s.candidates[j], s.candidates[i] 34 | } 35 | func (s *sortableCurlyRoutes) Less(i, j int) bool { 36 | ci := s.candidates[i] 37 | cj := s.candidates[j] 38 | 39 | // primary key 40 | if ci.staticCount < cj.staticCount { 41 | return true 42 | } 43 | if ci.staticCount > cj.staticCount { 44 | return false 45 | } 46 | // secundary key 47 | if ci.paramCount < cj.paramCount { 48 | return true 49 | } 50 | if ci.paramCount > cj.paramCount { 51 | return false 52 | } 53 | return ci.route.Path < cj.route.Path 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/doc_examples_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import "net/http" 4 | 5 | func ExampleOPTIONSFilter() { 6 | // Install the OPTIONS filter on the default Container 7 | Filter(OPTIONSFilter()) 8 | } 9 | func ExampleContainer_OPTIONSFilter() { 10 | // Install the OPTIONS filter on a Container 11 | myContainer := new(Container) 12 | myContainer.Filter(myContainer.OPTIONSFilter) 13 | } 14 | 15 | func ExampleContainer() { 16 | // The Default container of go-restful uses the http.DefaultServeMux. 17 | // You can create your own Container using restful.NewContainer() and create a new http.Server for that particular container 18 | 19 | ws := new(WebService) 20 | wsContainer := NewContainer() 21 | wsContainer.Add(ws) 22 | server := &http.Server{Addr: ":8080", Handler: wsContainer} 23 | server.ListenAndServe() 24 | } 25 | 26 | func ExampleCrossOriginResourceSharing() { 27 | // To install this filter on the Default Container use: 28 | cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer} 29 | Filter(cors.Filter) 30 | } 31 | 32 | func ExampleServiceError() { 33 | resp := new(Response) 34 | resp.WriteEntity(NewError(http.StatusBadRequest, "Non-integer {id} path parameter")) 35 | } 36 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/.goconvey: -------------------------------------------------------------------------------- 1 | ignore -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/google_app_engine/.goconvey: -------------------------------------------------------------------------------- 1 | ignore -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/google_app_engine/app.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Include your application ID here 3 | # 4 | application: 5 | version: 1 6 | runtime: go 7 | api_version: go1 8 | 9 | handlers: 10 | # 11 | # Regex for all swagger files to make as static content. 12 | # You should create the folder static/swagger and copy 13 | # swagger-ui into it. 14 | # 15 | - url: /apidocs/(.*?)/(.*\.(js|html|css)) 16 | static_files: static/swagger/\1/\2 17 | upload: static/swagger/(.*?)/(.*\.(js|html|css)) 18 | 19 | - url: /.* 20 | script: _go_app 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/google_app_engine/datastore/.goconvey: -------------------------------------------------------------------------------- 1 | ignore -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/google_app_engine/datastore/app.yaml: -------------------------------------------------------------------------------- 1 | application: datastore-example 2 | version: 1 3 | runtime: go 4 | api_version: go1 5 | 6 | handlers: 7 | # Regex for all swagger files to make as static content. 8 | # You should create the folder static/swagger and copy 9 | # swagger-ui into it. 10 | # 11 | - url: /apidocs/(.*?)/(.*\.(js|html|css)) 12 | static_files: static/swagger/\1/\2 13 | upload: static/swagger/(.*?)/(.*\.(js|html|css)) 14 | 15 | # Catch all. 16 | - url: /.* 17 | script: _go_app 18 | login: required 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/google_app_engine/restful-appstats-integration.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/mjibson/appstats" 5 | ) 6 | 7 | 8 | func stats(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { 9 | c := appstats.NewContext(req.Request) 10 | chain.ProcessFilter(req, resp) 11 | c.Stats.Status = resp.StatusCode() 12 | c.Save() 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

{{.Text}}

6 | 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-NCSA-logging.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/emicklei/go-restful" 5 | "io" 6 | "log" 7 | "net/http" 8 | "os" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | // This example shows how to create a filter that produces log lines 14 | // according to the Common Log Format, also known as the NCSA standard. 15 | // 16 | // kindly contributed by leehambley 17 | // 18 | // GET http://localhost:8080/ping 19 | 20 | var logger *log.Logger = log.New(os.Stdout, "", 0) 21 | 22 | func NCSACommonLogFormatLogger() restful.FilterFunction { 23 | return func(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { 24 | var username = "-" 25 | if req.Request.URL.User != nil { 26 | if name := req.Request.URL.User.Username(); name != "" { 27 | username = name 28 | } 29 | } 30 | chain.ProcessFilter(req, resp) 31 | logger.Printf("%s - %s [%s] \"%s %s %s\" %d %d", 32 | strings.Split(req.Request.RemoteAddr, ":")[0], 33 | username, 34 | time.Now().Format("02/Jan/2006:15:04:05 -0700"), 35 | req.Request.Method, 36 | req.Request.URL.RequestURI(), 37 | req.Request.Proto, 38 | resp.StatusCode(), 39 | resp.ContentLength(), 40 | ) 41 | } 42 | } 43 | 44 | func main() { 45 | ws := new(restful.WebService) 46 | ws.Filter(NCSACommonLogFormatLogger()) 47 | ws.Route(ws.GET("/ping").To(hello)) 48 | restful.Add(ws) 49 | http.ListenAndServe(":8080", nil) 50 | } 51 | 52 | func hello(req *restful.Request, resp *restful.Response) { 53 | io.WriteString(resp, "pong") 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-basic-authentication.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/emicklei/go-restful" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | // This example shows how to create a (Route) Filter that performs Basic Authentication on the Http request. 10 | // 11 | // GET http://localhost:8080/secret 12 | // and use admin,admin for the credentials 13 | 14 | func main() { 15 | ws := new(restful.WebService) 16 | ws.Route(ws.GET("/secret").Filter(basicAuthenticate).To(secret)) 17 | restful.Add(ws) 18 | http.ListenAndServe(":8080", nil) 19 | } 20 | 21 | func basicAuthenticate(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { 22 | encoded := req.Request.Header.Get("Authorization") 23 | // usr/pwd = admin/admin 24 | // real code does some decoding 25 | if len(encoded) == 0 || "Basic YWRtaW46YWRtaW4=" != encoded { 26 | resp.AddHeader("WWW-Authenticate", "Basic realm=Protected Area") 27 | resp.WriteErrorString(401, "401: Not Authorized") 28 | return 29 | } 30 | chain.ProcessFilter(req, resp) 31 | } 32 | 33 | func secret(req *restful.Request, resp *restful.Response) { 34 | io.WriteString(resp, "42") 35 | } 36 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-form-handling.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/emicklei/go-restful" 6 | "github.com/gorilla/schema" 7 | "io" 8 | "net/http" 9 | ) 10 | 11 | // This example shows how to handle a POST of a HTML form that uses the standard x-www-form-urlencoded content-type. 12 | // It uses the gorilla web tool kit schema package to decode the form data into a struct. 13 | // 14 | // GET http://localhost:8080/profiles 15 | // 16 | 17 | type Profile struct { 18 | Name string 19 | Age int 20 | } 21 | 22 | var decoder *schema.Decoder 23 | 24 | func main() { 25 | decoder = schema.NewDecoder() 26 | ws := new(restful.WebService) 27 | ws.Route(ws.POST("/profiles").Consumes("application/x-www-form-urlencoded").To(postAdddress)) 28 | ws.Route(ws.GET("/profiles").To(addresssForm)) 29 | restful.Add(ws) 30 | http.ListenAndServe(":8080", nil) 31 | } 32 | 33 | func postAdddress(req *restful.Request, resp *restful.Response) { 34 | err := req.Request.ParseForm() 35 | if err != nil { 36 | resp.WriteErrorString(http.StatusBadRequest, err.Error()) 37 | return 38 | } 39 | p := new(Profile) 40 | err = decoder.Decode(p, req.Request.PostForm) 41 | if err != nil { 42 | resp.WriteErrorString(http.StatusBadRequest, err.Error()) 43 | return 44 | } 45 | io.WriteString(resp.ResponseWriter, fmt.Sprintf("Name=%s, Age=%d", p.Name, p.Age)) 46 | } 47 | 48 | func addresssForm(req *restful.Request, resp *restful.Response) { 49 | io.WriteString(resp.ResponseWriter, 50 | ` 51 | 52 |

Enter Profile

53 |
54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | `) 62 | } 63 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-hello-world.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/emicklei/go-restful" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | // This example shows the minimal code needed to get a restful.WebService working. 10 | // 11 | // GET http://localhost:8080/hello 12 | 13 | func main() { 14 | ws := new(restful.WebService) 15 | ws.Route(ws.GET("/hello").To(hello)) 16 | restful.Add(ws) 17 | http.ListenAndServe(":8080", nil) 18 | } 19 | 20 | func hello(req *restful.Request, resp *restful.Response) { 21 | io.WriteString(resp, "world") 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-html-template.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "text/template" 7 | 8 | "github.com/emicklei/go-restful" 9 | ) 10 | 11 | // This example shows how to serve a HTML page using the standard Go template engine. 12 | // 13 | // GET http://localhost:8080/ 14 | 15 | func main() { 16 | ws := new(restful.WebService) 17 | ws.Route(ws.GET("/").To(home)) 18 | restful.Add(ws) 19 | print("open browser on http://localhost:8080/\n") 20 | http.ListenAndServe(":8080", nil) 21 | } 22 | 23 | type Message struct { 24 | Text string 25 | } 26 | 27 | func home(req *restful.Request, resp *restful.Response) { 28 | p := &Message{"restful-html-template demo"} 29 | // you might want to cache compiled templates 30 | t, err := template.ParseFiles("home.html") 31 | if err != nil { 32 | log.Fatalf("Template gave: %s", err) 33 | } 34 | t.Execute(resp.ResponseWriter, p) 35 | } 36 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-multi-containers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/emicklei/go-restful" 5 | "io" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | // This example shows how to have a program with 2 WebServices containers 11 | // each having a http server listening on its own port. 12 | // 13 | // The first "hello" is added to the restful.DefaultContainer (and uses DefaultServeMux) 14 | // For the second "hello", a new container and ServeMux is created 15 | // and requires a new http.Server with the container being the Handler. 16 | // This first server is spawn in its own go-routine such that the program proceeds to create the second. 17 | // 18 | // GET http://localhost:8080/hello 19 | // GET http://localhost:8081/hello 20 | 21 | func main() { 22 | ws := new(restful.WebService) 23 | ws.Route(ws.GET("/hello").To(hello)) 24 | restful.Add(ws) 25 | go func() { 26 | http.ListenAndServe(":8080", nil) 27 | }() 28 | 29 | container2 := restful.NewContainer() 30 | ws2 := new(restful.WebService) 31 | ws2.Route(ws2.GET("/hello").To(hello2)) 32 | container2.Add(ws2) 33 | server := &http.Server{Addr: ":8081", Handler: container2} 34 | log.Fatal(server.ListenAndServe()) 35 | } 36 | 37 | func hello(req *restful.Request, resp *restful.Response) { 38 | io.WriteString(resp, "default world") 39 | } 40 | 41 | func hello2(req *restful.Request, resp *restful.Response) { 42 | io.WriteString(resp, "second world") 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-options-filter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/emicklei/go-restful" 5 | "io" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | // This example shows how to use the OPTIONSFilter on a Container 11 | // 12 | // OPTIONS http://localhost:8080/users 13 | // 14 | // OPTIONS http://localhost:8080/users/1 15 | 16 | type UserResource struct{} 17 | 18 | func (u UserResource) RegisterTo(container *restful.Container) { 19 | ws := new(restful.WebService) 20 | ws. 21 | Path("/users"). 22 | Consumes("*/*"). 23 | Produces("*/*") 24 | 25 | ws.Route(ws.GET("/{user-id}").To(u.nop)) 26 | ws.Route(ws.POST("").To(u.nop)) 27 | ws.Route(ws.PUT("/{user-id}").To(u.nop)) 28 | ws.Route(ws.DELETE("/{user-id}").To(u.nop)) 29 | 30 | container.Add(ws) 31 | } 32 | 33 | func (u UserResource) nop(request *restful.Request, response *restful.Response) { 34 | io.WriteString(response.ResponseWriter, "this would be a normal response") 35 | } 36 | 37 | func main() { 38 | wsContainer := restful.NewContainer() 39 | u := UserResource{} 40 | u.RegisterTo(wsContainer) 41 | 42 | // Add container filter to respond to OPTIONS 43 | wsContainer.Filter(wsContainer.OPTIONSFilter) 44 | 45 | // For use on the default container, you can write 46 | // restful.Filter(restful.OPTIONSFilter()) 47 | 48 | log.Printf("start listening on localhost:8080") 49 | server := &http.Server{Addr: ":8080", Handler: wsContainer} 50 | log.Fatal(server.ListenAndServe()) 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-path-tail.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | . "github.com/emicklei/go-restful" 7 | ) 8 | 9 | // This example shows how to a Route that matches the "tail" of a path. 10 | // Requires the use of a CurlyRouter and the star "*" path parameter pattern. 11 | // 12 | // GET http://localhost:8080/basepath/some/other/location/test.xml 13 | 14 | func main() { 15 | DefaultContainer.Router(CurlyRouter{}) 16 | ws := new(WebService) 17 | ws.Route(ws.GET("/basepath/{resource:*}").To(staticFromPathParam)) 18 | Add(ws) 19 | 20 | println("[go-restful] serve path tails from http://localhost:8080/basepath") 21 | http.ListenAndServe(":8080", nil) 22 | } 23 | 24 | func staticFromPathParam(req *Request, resp *Response) { 25 | io.WriteString(resp, "Tail="+req.PathParameter("resource")) 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-route_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "strings" 7 | "testing" 8 | 9 | "github.com/emicklei/go-restful" 10 | ) 11 | 12 | var ( 13 | Result string 14 | ) 15 | 16 | func TestRouteExtractParameter(t *testing.T) { 17 | // setup service 18 | ws := new(restful.WebService) 19 | ws.Consumes(restful.MIME_XML) 20 | ws.Route(ws.GET("/test/{param}").To(DummyHandler)) 21 | restful.Add(ws) 22 | 23 | // setup request + writer 24 | bodyReader := strings.NewReader("42") 25 | httpRequest, _ := http.NewRequest("GET", "/test/THIS", bodyReader) 26 | httpRequest.Header.Set("Content-Type", restful.MIME_XML) 27 | httpWriter := httptest.NewRecorder() 28 | 29 | // run 30 | restful.DefaultContainer.ServeHTTP(httpWriter, httpRequest) 31 | 32 | if Result != "THIS" { 33 | t.Fatalf("Result is actually: %s", Result) 34 | } 35 | } 36 | 37 | func DummyHandler(rq *restful.Request, rp *restful.Response) { 38 | Result = rq.PathParameter("param") 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-routefunction_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | 8 | "github.com/emicklei/go-restful" 9 | ) 10 | 11 | // This example show how to test one particular RouteFunction (getIt) 12 | // It uses the httptest.ResponseRecorder to capture output 13 | 14 | func getIt(req *restful.Request, resp *restful.Response) { 15 | resp.WriteHeader(204) 16 | } 17 | 18 | func TestCallFunction(t *testing.T) { 19 | httpReq, _ := http.NewRequest("GET", "/", nil) 20 | req := restful.NewRequest(httpReq) 21 | 22 | recorder := new(httptest.ResponseRecorder) 23 | resp := restful.NewResponse(recorder) 24 | 25 | getIt(req, resp) 26 | if recorder.Code != 204 { 27 | t.Fatalf("Missing or wrong status code:%d", recorder.Code) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/examples/restful-serve-static.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "path" 7 | 8 | "github.com/emicklei/go-restful" 9 | ) 10 | 11 | // This example shows how to define methods that serve static files 12 | // It uses the standard http.ServeFile method 13 | // 14 | // GET http://localhost:8080/static/test.xml 15 | // GET http://localhost:8080/static/ 16 | // 17 | // GET http://localhost:8080/static?resource=subdir/test.xml 18 | 19 | var rootdir = "/tmp" 20 | 21 | func main() { 22 | restful.DefaultContainer.Router(restful.CurlyRouter{}) 23 | 24 | ws := new(restful.WebService) 25 | ws.Route(ws.GET("/static/{subpath:*}").To(staticFromPathParam)) 26 | ws.Route(ws.GET("/static").To(staticFromQueryParam)) 27 | restful.Add(ws) 28 | 29 | println("[go-restful] serving files on http://localhost:8080/static from local /tmp") 30 | http.ListenAndServe(":8080", nil) 31 | } 32 | 33 | func staticFromPathParam(req *restful.Request, resp *restful.Response) { 34 | actual := path.Join(rootdir, req.PathParameter("subpath")) 35 | fmt.Printf("serving %s ... (from %s)\n", actual, req.PathParameter("subpath")) 36 | http.ServeFile( 37 | resp.ResponseWriter, 38 | req.Request, 39 | actual) 40 | } 41 | 42 | func staticFromQueryParam(req *restful.Request, resp *restful.Response) { 43 | http.ServeFile( 44 | resp.ResponseWriter, 45 | req.Request, 46 | path.Join(rootdir, req.QueryParameter("resource"))) 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/filter.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | // Copyright 2013 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | 7 | // FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction. 8 | type FilterChain struct { 9 | Filters []FilterFunction // ordered list of FilterFunction 10 | Index int // index into filters that is currently in progress 11 | Target RouteFunction // function to call after passing all filters 12 | } 13 | 14 | // ProcessFilter passes the request,response pair through the next of Filters. 15 | // Each filter can decide to proceed to the next Filter or handle the Response itself. 16 | func (f *FilterChain) ProcessFilter(request *Request, response *Response) { 17 | if f.Index < len(f.Filters) { 18 | f.Index++ 19 | f.Filters[f.Index-1](request, response, f) 20 | } else { 21 | f.Target(request, response) 22 | } 23 | } 24 | 25 | // FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction 26 | type FilterFunction func(*Request, *Response, *FilterChain) 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/install.sh: -------------------------------------------------------------------------------- 1 | cd examples 2 | ls *.go | xargs -I {} go build {} 3 | cd .. 4 | go fmt ...swagger && \ 5 | go test -test.v ...swagger && \ 6 | go install ...swagger && \ 7 | go fmt ...restful && \ 8 | go test -test.v ...restful && \ 9 | go install ...restful -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | stdlog "log" 5 | "os" 6 | ) 7 | 8 | // Logger corresponds to a minimal subset of the interface satisfied by stdlib log.Logger 9 | type StdLogger interface { 10 | Print(v ...interface{}) 11 | Printf(format string, v ...interface{}) 12 | } 13 | 14 | var Logger StdLogger 15 | 16 | func init() { 17 | // default Logger 18 | SetLogger(stdlog.New(os.Stdout, "[restful] ", stdlog.LstdFlags|stdlog.Lshortfile)) 19 | } 20 | 21 | func SetLogger(customLogger StdLogger) { 22 | Logger = customLogger 23 | } 24 | 25 | func Print(v ...interface{}) { 26 | Logger.Print(v...) 27 | } 28 | 29 | func Printf(format string, v ...interface{}) { 30 | Logger.Printf(format, v...) 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/logger.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | // Copyright 2014 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | import ( 7 | "github.com/emicklei/go-restful/log" 8 | ) 9 | 10 | var trace bool = false 11 | var traceLogger log.StdLogger 12 | 13 | func init() { 14 | traceLogger = log.Logger // use the package logger by default 15 | } 16 | 17 | // TraceLogger enables detailed logging of Http request matching and filter invocation. Default no logger is set. 18 | // You may call EnableTracing() directly to enable trace logging to the package-wide logger. 19 | func TraceLogger(logger log.StdLogger) { 20 | traceLogger = logger 21 | EnableTracing(logger != nil) 22 | } 23 | 24 | // expose the setter for the global logger on the top-level package 25 | func SetLogger(customLogger log.StdLogger) { 26 | log.SetLogger(customLogger) 27 | } 28 | 29 | // EnableTracing can be used to Trace logging on and off. 30 | func EnableTracing(enabled bool) { 31 | trace = enabled 32 | } 33 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/options_filter.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import "strings" 4 | 5 | // Copyright 2013 Ernest Micklei. All rights reserved. 6 | // Use of this source code is governed by a license 7 | // that can be found in the LICENSE file. 8 | 9 | // OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method 10 | // and provides the response with a set of allowed methods for the request URL Path. 11 | // As for any filter, you can also install it for a particular WebService within a Container 12 | func (c *Container) OPTIONSFilter(req *Request, resp *Response, chain *FilterChain) { 13 | if "OPTIONS" != req.Request.Method { 14 | chain.ProcessFilter(req, resp) 15 | return 16 | } 17 | resp.AddHeader(HEADER_Allow, strings.Join(c.computeAllowedMethods(req), ",")) 18 | } 19 | 20 | // OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method 21 | // and provides the response with a set of allowed methods for the request URL Path. 22 | func OPTIONSFilter() FilterFunction { 23 | return DefaultContainer.OPTIONSFilter 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/options_filter_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | // go test -v -test.run TestOptionsFilter ...restful 10 | func TestOptionsFilter(t *testing.T) { 11 | tearDown() 12 | ws := new(WebService) 13 | ws.Route(ws.GET("/candy/{kind}").To(dummy)) 14 | ws.Route(ws.DELETE("/candy/{kind}").To(dummy)) 15 | ws.Route(ws.POST("/candies").To(dummy)) 16 | Add(ws) 17 | Filter(OPTIONSFilter()) 18 | 19 | httpRequest, _ := http.NewRequest("OPTIONS", "http://here.io/candy/gum", nil) 20 | httpWriter := httptest.NewRecorder() 21 | DefaultContainer.dispatch(httpWriter, httpRequest) 22 | actual := httpWriter.Header().Get(HEADER_Allow) 23 | if "GET,DELETE" != actual { 24 | t.Fatal("expected: GET,DELETE but got:" + actual) 25 | } 26 | 27 | httpRequest, _ = http.NewRequest("OPTIONS", "http://here.io/candies", nil) 28 | httpWriter = httptest.NewRecorder() 29 | DefaultContainer.dispatch(httpWriter, httpRequest) 30 | actual = httpWriter.Header().Get(HEADER_Allow) 31 | if "POST" != actual { 32 | t.Fatal("expected: POST but got:" + actual) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/path_expression_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import "testing" 4 | 5 | var tempregexs = []struct { 6 | template, regex string 7 | literalCount, varCount int 8 | }{ 9 | {"", "^(/.*)?$", 0, 0}, 10 | {"/a/{b}/c/", "^/a/([^/]+?)/c(/.*)?$", 2, 1}, 11 | {"/{a}/{b}/{c-d-e}/", "^/([^/]+?)/([^/]+?)/([^/]+?)(/.*)?$", 0, 3}, 12 | {"/{p}/abcde", "^/([^/]+?)/abcde(/.*)?$", 5, 1}, 13 | {"/a/{b:*}", "^/a/(.*)(/.*)?$", 1, 1}, 14 | {"/a/{b:[a-z]+}", "^/a/([a-z]+)(/.*)?$", 1, 1}, 15 | } 16 | 17 | func TestTemplateToRegularExpression(t *testing.T) { 18 | ok := true 19 | for i, fixture := range tempregexs { 20 | actual, lCount, vCount, _ := templateToRegularExpression(fixture.template) 21 | if actual != fixture.regex { 22 | t.Logf("regex mismatch, expected:%v , actual:%v, line:%v\n", fixture.regex, actual, i) // 11 = where the data starts 23 | ok = false 24 | } 25 | if lCount != fixture.literalCount { 26 | t.Logf("literal count mismatch, expected:%v , actual:%v, line:%v\n", fixture.literalCount, lCount, i) 27 | ok = false 28 | } 29 | if vCount != fixture.varCount { 30 | t.Logf("variable count mismatch, expected:%v , actual:%v, line:%v\n", fixture.varCount, vCount, i) 31 | ok = false 32 | } 33 | } 34 | if !ok { 35 | t.Fatal("one or more expression did not match") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/route_builder_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestRouteBuilder_PathParameter(t *testing.T) { 8 | p := &Parameter{&ParameterData{Name: "name", Description: "desc"}} 9 | p.AllowMultiple(true) 10 | p.DataType("int") 11 | p.Required(true) 12 | values := map[string]string{"a": "b"} 13 | p.AllowableValues(values) 14 | p.bePath() 15 | 16 | b := new(RouteBuilder) 17 | b.function = dummy 18 | b.Param(p) 19 | r := b.Build() 20 | if !r.ParameterDocs[0].Data().AllowMultiple { 21 | t.Error("AllowMultiple invalid") 22 | } 23 | if r.ParameterDocs[0].Data().DataType != "int" { 24 | t.Error("dataType invalid") 25 | } 26 | if !r.ParameterDocs[0].Data().Required { 27 | t.Error("required invalid") 28 | } 29 | if r.ParameterDocs[0].Data().Kind != PathParameterKind { 30 | t.Error("kind invalid") 31 | } 32 | if r.ParameterDocs[0].Data().AllowableValues["a"] != "b" { 33 | t.Error("allowableValues invalid") 34 | } 35 | if b.ParameterNamed("name") == nil { 36 | t.Error("access to parameter failed") 37 | } 38 | } 39 | 40 | func TestRouteBuilder(t *testing.T) { 41 | json := "application/json" 42 | b := new(RouteBuilder) 43 | b.To(dummy) 44 | b.Path("/routes").Method("HEAD").Consumes(json).Produces(json) 45 | r := b.Build() 46 | if r.Path != "/routes" { 47 | t.Error("path invalid") 48 | } 49 | if r.Produces[0] != json { 50 | t.Error("produces invalid") 51 | } 52 | if r.Consumes[0] != json { 53 | t.Error("consumes invalid") 54 | } 55 | if r.Operation != "dummy" { 56 | t.Error("Operation not set") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/router.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | // Copyright 2013 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | 7 | import "net/http" 8 | 9 | // A RouteSelector finds the best matching Route given the input HTTP Request 10 | type RouteSelector interface { 11 | 12 | // SelectRoute finds a Route given the input HTTP Request and a list of WebServices. 13 | // It returns a selected Route and its containing WebService or an error indicating 14 | // a problem. 15 | SelectRoute( 16 | webServices []*WebService, 17 | httpRequest *http.Request) (selectedService *WebService, selected *Route, err error) 18 | } 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/service_error.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | // Copyright 2013 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | 7 | import "fmt" 8 | 9 | // ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request. 10 | type ServiceError struct { 11 | Code int 12 | Message string 13 | } 14 | 15 | // NewError returns a ServiceError using the code and reason 16 | func NewError(code int, message string) ServiceError { 17 | return ServiceError{Code: code, Message: message} 18 | } 19 | 20 | // Error returns a text representation of the service error 21 | func (s ServiceError) Error() string { 22 | return fmt.Sprintf("[ServiceError:%v] %v", s.Code, s.Message) 23 | } 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/CHANGES.md: -------------------------------------------------------------------------------- 1 | Change history of swagger 2 | = 3 | 2015-05-25 4 | - (api break) changed the type of Properties in Model 5 | - (api break) changed the type of Models in ApiDeclaration 6 | - (api break) changed the parameter type of PostBuildDeclarationMapFunc 7 | 8 | 2015-04-09 9 | - add ModelBuildable interface for customization of Model 10 | 11 | 2015-03-17 12 | - preserve order of Routes per WebService in Swagger listing 13 | - fix use of $ref and type in Swagger models 14 | - add api version to listing 15 | 16 | 2014-11-14 17 | - operation parameters are now sorted using ordering path,query,form,header,body 18 | 19 | 2014-11-12 20 | - respect omitempty tag value for embedded structs 21 | - expose ApiVersion of WebService to Swagger ApiDeclaration 22 | 23 | 2014-05-29 24 | - (api add) Ability to define custom http.Handler to serve swagger-ui static files 25 | 26 | 2014-05-04 27 | - (fix) include model for array element type of response 28 | 29 | 2014-01-03 30 | - (fix) do not add primitive type to the Api models 31 | 32 | 2013-11-27 33 | - (fix) make Swagger work for WebServices with root ("/" or "") paths 34 | 35 | 2013-10-29 36 | - (api add) package variable LogInfo to customize logging function 37 | 38 | 2013-10-15 39 | - upgraded to spec version 1.2 (https://github.com/wordnik/swagger-core/wiki/1.2-transition) -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/README.md: -------------------------------------------------------------------------------- 1 | How to use Swagger UI with go-restful 2 | = 3 | 4 | Get the Swagger UI sources (version 1.2 only) 5 | 6 | git clone https://github.com/wordnik/swagger-ui.git 7 | 8 | The project contains a "dist" folder. 9 | Its contents has all the Swagger UI files you need. 10 | 11 | The `index.html` has an `url` set to `http://petstore.swagger.wordnik.com/api/api-docs`. 12 | You need to change that to match your WebService JSON endpoint e.g. `http://localhost:8080/apidocs.json` 13 | 14 | Now, you can install the Swagger WebService for serving the Swagger specification in JSON. 15 | 16 | config := swagger.Config{ 17 | WebServices: restful.RegisteredWebServices(), 18 | ApiPath: "/apidocs.json", 19 | SwaggerPath: "/apidocs/", 20 | SwaggerFilePath: "/Users/emicklei/Projects/swagger-ui/dist"} 21 | swagger.InstallSwaggerService(config) 22 | 23 | 24 | Notes 25 | -- 26 | - The Nickname of an Operation is automatically set by finding the name of the function. You can override it using RouteBuilder.Operation(..) 27 | - The WebServices field of swagger.Config can be used to control which service you want to expose and document ; you can have multiple configs and therefore multiple endpoints. 28 | - Use tag "description" to annotate a struct field with a description to show in the UI -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/config.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/emicklei/go-restful" 7 | ) 8 | 9 | // PostBuildDeclarationMapFunc can be used to modify the api declaration map. 10 | type PostBuildDeclarationMapFunc func(apiDeclarationMap *ApiDeclarationList) 11 | 12 | type Config struct { 13 | // url where the services are available, e.g. http://localhost:8080 14 | // if left empty then the basePath of Swagger is taken from the actual request 15 | WebServicesUrl string 16 | // path where the JSON api is avaiable , e.g. /apidocs 17 | ApiPath string 18 | // [optional] path where the swagger UI will be served, e.g. /swagger 19 | SwaggerPath string 20 | // [optional] location of folder containing Swagger HTML5 application index.html 21 | SwaggerFilePath string 22 | // api listing is constructed from this list of restful WebServices. 23 | WebServices []*restful.WebService 24 | // will serve all static content (scripts,pages,images) 25 | StaticHandler http.Handler 26 | // [optional] on default CORS (Cross-Origin-Resource-Sharing) is enabled. 27 | DisableCORS bool 28 | // Top-level API version. Is reflected in the resource listing. 29 | ApiVersion string 30 | // If set then call this handler after building the complete ApiDeclaration Map 31 | PostBuildHandler PostBuildDeclarationMapFunc 32 | } 33 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/model_list_test.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | ) 7 | 8 | func TestModelList(t *testing.T) { 9 | m := Model{} 10 | m.Id = "m" 11 | l := ModelList{} 12 | l.Put("m", m) 13 | k, ok := l.At("m") 14 | if !ok { 15 | t.Error("want model back") 16 | } 17 | if got, want := k.Id, "m"; got != want { 18 | t.Errorf("got %v want %v", got, want) 19 | } 20 | } 21 | 22 | func TestModelList_Marshal(t *testing.T) { 23 | l := ModelList{} 24 | m := Model{Id: "myid"} 25 | l.Put("myid", m) 26 | data, err := json.Marshal(l) 27 | if err != nil { 28 | t.Error(err) 29 | } 30 | if got, want := string(data), `{"myid":{"id":"myid","properties":{}}}`; got != want { 31 | t.Errorf("got %v want %v", got, want) 32 | } 33 | } 34 | 35 | func TestModelList_Unmarshal(t *testing.T) { 36 | data := `{"myid":{"id":"myid","properties":{}}}` 37 | l := ModelList{} 38 | if err := json.Unmarshal([]byte(data), &l); err != nil { 39 | t.Error(err) 40 | } 41 | m, ok := l.At("myid") 42 | if !ok { 43 | t.Error("expected myid") 44 | } 45 | if got, want := m.Id, "myid"; got != want { 46 | t.Errorf("got %v want %v", got, want) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/model_property_list_test.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | ) 7 | 8 | func TestModelPropertyList(t *testing.T) { 9 | l := ModelPropertyList{} 10 | p := ModelProperty{Description: "d"} 11 | l.Put("p", p) 12 | q, ok := l.At("p") 13 | if !ok { 14 | t.Error("expected p") 15 | } 16 | if got, want := q.Description, "d"; got != want { 17 | t.Errorf("got %v want %v", got, want) 18 | } 19 | } 20 | 21 | func TestModelPropertyList_Marshal(t *testing.T) { 22 | l := ModelPropertyList{} 23 | p := ModelProperty{Description: "d"} 24 | l.Put("p", p) 25 | data, err := json.Marshal(l) 26 | if err != nil { 27 | t.Error(err) 28 | } 29 | if got, want := string(data), `{"p":{"description":"d"}}`; got != want { 30 | t.Errorf("got %v want %v", got, want) 31 | } 32 | } 33 | 34 | func TestModelPropertyList_Unmarshal(t *testing.T) { 35 | data := `{"p":{"description":"d"}}` 36 | l := ModelPropertyList{} 37 | if err := json.Unmarshal([]byte(data), &l); err != nil { 38 | t.Error(err) 39 | } 40 | m, ok := l.At("p") 41 | if !ok { 42 | t.Error("expected p") 43 | } 44 | if got, want := m.Description, "d"; got != want { 45 | t.Errorf("got %v want %v", got, want) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/ordered_route_map.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | // Copyright 2015 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | 7 | import "github.com/emicklei/go-restful" 8 | 9 | type orderedRouteMap struct { 10 | elements map[string][]restful.Route 11 | keys []string 12 | } 13 | 14 | func newOrderedRouteMap() *orderedRouteMap { 15 | return &orderedRouteMap{ 16 | elements: map[string][]restful.Route{}, 17 | keys: []string{}, 18 | } 19 | } 20 | 21 | func (o *orderedRouteMap) Add(key string, route restful.Route) { 22 | routes, ok := o.elements[key] 23 | if ok { 24 | routes = append(routes, route) 25 | o.elements[key] = routes 26 | return 27 | } 28 | o.elements[key] = []restful.Route{route} 29 | o.keys = append(o.keys, key) 30 | } 31 | 32 | func (o *orderedRouteMap) Do(block func(key string, routes []restful.Route)) { 33 | for _, k := range o.keys { 34 | block(k, o.elements[k]) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/ordered_route_map_test.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/emicklei/go-restful" 7 | ) 8 | 9 | // go test -v -test.run TestOrderedRouteMap ...swagger 10 | func TestOrderedRouteMap(t *testing.T) { 11 | m := newOrderedRouteMap() 12 | r1 := restful.Route{Path: "/r1"} 13 | r2 := restful.Route{Path: "/r2"} 14 | m.Add("a", r1) 15 | m.Add("b", r2) 16 | m.Add("b", r1) 17 | m.Add("d", r2) 18 | m.Add("c", r2) 19 | order := "" 20 | m.Do(func(k string, routes []restful.Route) { 21 | order += k 22 | if len(routes) == 0 { 23 | t.Fail() 24 | } 25 | }) 26 | if order != "abdc" { 27 | t.Fail() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/postbuild_model_test.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import "testing" 4 | 5 | type Boat struct { 6 | Length int `json:"-"` // on default, this makes the fields not required 7 | Weight int `json:"-"` 8 | } 9 | 10 | // PostBuildModel is from swagger.ModelBuildable 11 | func (b Boat) PostBuildModel(m *Model) *Model { 12 | // override required 13 | m.Required = []string{"Length", "Weight"} 14 | 15 | // add model property (just to test is can be added; is this a real usecase?) 16 | extraType := "string" 17 | m.Properties.Put("extra", ModelProperty{ 18 | Description: "extra description", 19 | DataTypeFields: DataTypeFields{ 20 | Type: &extraType, 21 | }, 22 | }) 23 | return m 24 | } 25 | 26 | func TestCustomPostModelBuilde(t *testing.T) { 27 | testJsonFromStruct(t, Boat{}, `{ 28 | "swagger.Boat": { 29 | "id": "swagger.Boat", 30 | "required": [ 31 | "Length", 32 | "Weight" 33 | ], 34 | "properties": { 35 | "extra": { 36 | "type": "string", 37 | "description": "extra description" 38 | } 39 | } 40 | } 41 | }`) 42 | } 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/tracer_test.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import "testing" 4 | 5 | // Use like this: 6 | // 7 | // TraceLogger(testLogger{t}) 8 | type testLogger struct { 9 | t *testing.T 10 | } 11 | 12 | func (l testLogger) Print(v ...interface{}) { 13 | l.t.Log(v...) 14 | } 15 | 16 | func (l testLogger) Printf(format string, v ...interface{}) { 17 | l.t.Logf(format, v...) 18 | } 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/emicklei/go-restful/web_service_container.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | // Copyright 2013 Ernest Micklei. All rights reserved. 4 | // Use of this source code is governed by a license 5 | // that can be found in the LICENSE file. 6 | 7 | import ( 8 | "net/http" 9 | ) 10 | 11 | // DefaultContainer is a restful.Container that uses http.DefaultServeMux 12 | var DefaultContainer *Container 13 | 14 | func init() { 15 | DefaultContainer = NewContainer() 16 | DefaultContainer.ServeMux = http.DefaultServeMux 17 | } 18 | 19 | // If set the true then panics will not be caught to return HTTP 500. 20 | // In that case, Route functions are responsible for handling any error situation. 21 | // Default value is false = recover from panics. This has performance implications. 22 | // OBSOLETE ; use restful.DefaultContainer.DoNotRecover(true) 23 | var DoNotRecover = false 24 | 25 | // Add registers a new WebService add it to the DefaultContainer. 26 | func Add(service *WebService) { 27 | DefaultContainer.Add(service) 28 | } 29 | 30 | // Filter appends a container FilterFunction from the DefaultContainer. 31 | // These are called before dispatching a http.Request to a WebService. 32 | func Filter(filter FilterFunction) { 33 | DefaultContainer.Filter(filter) 34 | } 35 | 36 | // RegisteredWebServices returns the collections of WebServices from the DefaultContainer 37 | func RegisteredWebServices() []*WebService { 38 | return DefaultContainer.RegisteredWebServices() 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | README.markdown 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.3.1 4 | - 1.4 5 | - tip 6 | env: 7 | - GOARCH=amd64 8 | - GOARCH=386 9 | script: 10 | - make test 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/DOCKER-LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | You can find the Docker license at the following link: 6 | https://raw.githubusercontent.com/docker/docker/master/LICENSE 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/Dockerfile.1_3: -------------------------------------------------------------------------------- 1 | FROM golang:1.3.3-cross 2 | MAINTAINER peter.edge@gmail.com 3 | 4 | RUN \ 5 | go get -v code.google.com/p/go.tools/cmd/vet && \ 6 | go get -v github.com/golang/lint/golint 7 | 8 | RUN mkdir -p /go/src/github.com/fsouza/go-dockerclient 9 | ADD . /go/src/github.com/fsouza/go-dockerclient 10 | WORKDIR /go/src/github.com/fsouza/go-dockerclient 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/Dockerfile.1_4: -------------------------------------------------------------------------------- 1 | FROM golang:1.4.2-cross 2 | MAINTAINER peter.edge@gmail.com 3 | 4 | RUN \ 5 | go get -v golang.org/x/tools/cmd/vet && \ 6 | go get -v github.com/golang/lint/golint 7 | 8 | RUN mkdir -p /go/src/github.com/fsouza/go-dockerclient 9 | ADD . /go/src/github.com/fsouza/go-dockerclient 10 | WORKDIR /go/src/github.com/fsouza/go-dockerclient 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, go-dockerclient authors 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: \ 2 | all \ 3 | vendor \ 4 | lint \ 5 | vet \ 6 | fmt \ 7 | fmtcheck \ 8 | pretest \ 9 | test \ 10 | cov \ 11 | clean 12 | 13 | all: test 14 | 15 | vendor: 16 | go get -v github.com/mjibson/party 17 | party -d vendor -c -u 18 | 19 | lint: 20 | go get -v github.com/golang/lint/golint 21 | for file in $(shell git ls-files '*.go' | grep -v '^vendor/'); do \ 22 | golint $$file; \ 23 | done 24 | 25 | vet: 26 | @ go get -v golang.org/x/tools/cmd/vet 27 | go vet ./... 28 | 29 | fmt: 30 | gofmt -w $(shell git ls-files '*.go' | grep -v '^vendor/') 31 | 32 | fmtcheck: 33 | for file in $(shell git ls-files '*.go' | grep -v '^vendor/'); do \ 34 | gofmt $$file | diff -u $$file -; \ 35 | if [ -n "$$(gofmt $$file | diff -u $$file -)" ]; then\ 36 | exit 1; \ 37 | fi; \ 38 | done 39 | 40 | pretest: lint vet fmtcheck 41 | 42 | test: pretest 43 | go test 44 | go test ./testing 45 | 46 | cov: 47 | go get -v github.com/axw/gocov/gocov 48 | go get golang.org/x/tools/cmd/cover 49 | gocov test | gocov report 50 | 51 | clean: 52 | go clean ./... 53 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/change.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 go-dockerclient authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package docker 6 | 7 | import "fmt" 8 | 9 | // ChangeType is a type for constants indicating the type of change 10 | // in a container 11 | type ChangeType int 12 | 13 | const ( 14 | // ChangeModify is the ChangeType for container modifications 15 | ChangeModify ChangeType = iota 16 | 17 | // ChangeAdd is the ChangeType for additions to a container 18 | ChangeAdd 19 | 20 | // ChangeDelete is the ChangeType for deletions from a container 21 | ChangeDelete 22 | ) 23 | 24 | // Change represents a change in a container. 25 | // 26 | // See http://goo.gl/QkW9sH for more details. 27 | type Change struct { 28 | Path string 29 | Kind ChangeType 30 | } 31 | 32 | func (change *Change) String() string { 33 | var kind string 34 | switch change.Kind { 35 | case ChangeModify: 36 | kind = "C" 37 | case ChangeAdd: 38 | kind = "A" 39 | case ChangeDelete: 40 | kind = "D" 41 | } 42 | return fmt.Sprintf("%s %s", kind, change.Path) 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/change_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 go-dockerclient authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package docker 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | func TestChangeString(t *testing.T) { 12 | var tests = []struct { 13 | change Change 14 | expected string 15 | }{ 16 | {Change{"/etc/passwd", ChangeModify}, "C /etc/passwd"}, 17 | {Change{"/etc/passwd", ChangeAdd}, "A /etc/passwd"}, 18 | {Change{"/etc/passwd", ChangeDelete}, "D /etc/passwd"}, 19 | {Change{"/etc/passwd", 33}, " /etc/passwd"}, 20 | } 21 | for _, tt := range tests { 22 | if got := tt.change.String(); got != tt.expected { 23 | t.Errorf("Change.String(): want %q. Got %q.", tt.expected, got) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/codeship-services.yml: -------------------------------------------------------------------------------- 1 | "1_3_386": 2 | build: 3 | image: fsouza/godockerclient:1.3 4 | dockerfile: Dockerfile.1_3 5 | environment: 6 | - GOARCH=386 7 | "1_3_amd64": 8 | build: 9 | image: fsouza/godockerclient:1.3 10 | dockerfile: Dockerfile.1_3 11 | environment: 12 | - GOARCH=amd64 13 | "1_4_386": 14 | build: 15 | image: fsouza/godockerclient:1.4 16 | dockerfile: Dockerfile.1_4 17 | environment: 18 | - GOARCH=386 19 | "1_4_amd64": 20 | build: 21 | image: fsouza/godockerclient:1.4 22 | dockerfile: Dockerfile.1_4 23 | environment: 24 | - GOARCH=amd64 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/codeship-steps.yml: -------------------------------------------------------------------------------- 1 | - type: parallel 2 | services: 3 | - 1_3_386 4 | - 1_3_amd64 5 | - 1_4_386 6 | - 1_4_amd64 7 | steps: 8 | - command: make test 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 go-dockerclient authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package docker 6 | 7 | import ( 8 | "bytes" 9 | "strings" 10 | ) 11 | 12 | // Version returns version information about the docker server. 13 | // 14 | // See http://goo.gl/BOZrF5 for more details. 15 | func (c *Client) Version() (*Env, error) { 16 | body, _, err := c.do("GET", "/version", doOptions{}) 17 | if err != nil { 18 | return nil, err 19 | } 20 | var env Env 21 | if err := env.Decode(bytes.NewReader(body)); err != nil { 22 | return nil, err 23 | } 24 | return &env, nil 25 | } 26 | 27 | // Info returns system-wide information about the Docker server. 28 | // 29 | // See http://goo.gl/wmqZsW for more details. 30 | func (c *Client) Info() (*Env, error) { 31 | body, _, err := c.do("GET", "/info", doOptions{}) 32 | if err != nil { 33 | return nil, err 34 | } 35 | var info Env 36 | err = info.Decode(bytes.NewReader(body)) 37 | if err != nil { 38 | return nil, err 39 | } 40 | return &info, nil 41 | } 42 | 43 | // ParseRepositoryTag gets the name of the repository and returns it splitted 44 | // in two parts: the repository and the tag. 45 | // 46 | // Some examples: 47 | // 48 | // localhost.localdomain:5000/samalba/hipache:latest -> localhost.localdomain:5000/samalba/hipache, latest 49 | // localhost.localdomain:5000/samalba/hipache -> localhost.localdomain:5000/samalba/hipache, "" 50 | func ParseRepositoryTag(repoTag string) (repository string, tag string) { 51 | n := strings.LastIndex(repoTag, ":") 52 | if n < 0 { 53 | return repoTag, "" 54 | } 55 | if tag := repoTag[n+1:]; !strings.Contains(tag, "/") { 56 | return repoTag[:n], tag 57 | } 58 | return repoTag, "" 59 | } 60 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/signal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 go-dockerclient authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package docker 6 | 7 | // Signal represents a signal that can be send to the container on 8 | // KillContainer call. 9 | type Signal int 10 | 11 | // These values represent all signals available on Linux, where containers will 12 | // be running. 13 | const ( 14 | SIGABRT = Signal(0x6) 15 | SIGALRM = Signal(0xe) 16 | SIGBUS = Signal(0x7) 17 | SIGCHLD = Signal(0x11) 18 | SIGCLD = Signal(0x11) 19 | SIGCONT = Signal(0x12) 20 | SIGFPE = Signal(0x8) 21 | SIGHUP = Signal(0x1) 22 | SIGILL = Signal(0x4) 23 | SIGINT = Signal(0x2) 24 | SIGIO = Signal(0x1d) 25 | SIGIOT = Signal(0x6) 26 | SIGKILL = Signal(0x9) 27 | SIGPIPE = Signal(0xd) 28 | SIGPOLL = Signal(0x1d) 29 | SIGPROF = Signal(0x1b) 30 | SIGPWR = Signal(0x1e) 31 | SIGQUIT = Signal(0x3) 32 | SIGSEGV = Signal(0xb) 33 | SIGSTKFLT = Signal(0x10) 34 | SIGSTOP = Signal(0x13) 35 | SIGSYS = Signal(0x1f) 36 | SIGTERM = Signal(0xf) 37 | SIGTRAP = Signal(0x5) 38 | SIGTSTP = Signal(0x14) 39 | SIGTTIN = Signal(0x15) 40 | SIGTTOU = Signal(0x16) 41 | SIGUNUSED = Signal(0x1f) 42 | SIGURG = Signal(0x17) 43 | SIGUSR1 = Signal(0xa) 44 | SIGUSR2 = Signal(0xc) 45 | SIGVTALRM = Signal(0x1a) 46 | SIGWINCH = Signal(0x1c) 47 | SIGXCPU = Signal(0x18) 48 | SIGXFSZ = Signal(0x19) 49 | ) 50 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/bin/fmtpolice: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | readonly GOPATH="${GOPATH%%:*}" 4 | 5 | main() { 6 | check_fmt 7 | check_lint 8 | } 9 | 10 | check_fmt() { 11 | eval "set -e" 12 | for file in $(_list_go_files) ; do 13 | gofmt $file | diff -u $file - 14 | done 15 | eval "set +e" 16 | } 17 | 18 | check_lint() { 19 | _install_linter 20 | 21 | for file in $(_list_go_files) ; do 22 | if [[ ! "$(${GOPATH}/bin/golint $file)" =~ ^[[:blank:]]*$ ]] ; then 23 | _lint_verbose && exit 1 24 | fi 25 | done 26 | } 27 | 28 | _lint_verbose() { 29 | for file in $(_list_go_files) ; do $GOPATH/bin/golint $file ; done 30 | } 31 | 32 | _install_linter() { 33 | if [[ ! -x "${GOPATH}/bin/golint" ]] ; then 34 | go get -u -f github.com/golang/lint/golint 35 | fi 36 | } 37 | 38 | _list_go_files() { 39 | git ls-files '*.go' | grep -v '^vendor/' 40 | } 41 | 42 | main "$@" 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/.dockerignore: -------------------------------------------------------------------------------- 1 | container.tar 2 | dockerfile.tar 3 | foofile 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/Dockerfile: -------------------------------------------------------------------------------- 1 | # this file describes how to build tsuru python image 2 | # to run it: 3 | # 1- install docker 4 | # 2- run: $ docker build -t tsuru/python https://raw.github.com/tsuru/basebuilder/master/python/Dockerfile 5 | 6 | from base:ubuntu-quantal 7 | run apt-get install wget -y --force-yes 8 | run wget http://github.com/tsuru/basebuilder/tarball/master -O basebuilder.tar.gz --no-check-certificate 9 | run mkdir /var/lib/tsuru 10 | run tar -xvf basebuilder.tar.gz -C /var/lib/tsuru --strip 1 11 | run cp /var/lib/tsuru/python/deploy /var/lib/tsuru 12 | run cp /var/lib/tsuru/base/restart /var/lib/tsuru 13 | run cp /var/lib/tsuru/base/start /var/lib/tsuru 14 | run /var/lib/tsuru/base/install 15 | run /var/lib/tsuru/base/setup 16 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/barfile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/barfile -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC1TCCAb+gAwIBAgIQJ9MsNxrUxumNbAytGi3GEDALBgkqhkiG9w0BAQswFjEU 3 | MBIGA1UEChMLQm9vdDJEb2NrZXIwHhcNMTQxMDE2MjAyMTM4WhcNMTcwOTMwMjAy 4 | MTM4WjAWMRQwEgYDVQQKEwtCb290MkRvY2tlcjCCASIwDQYJKoZIhvcNAQEBBQAD 5 | ggEPADCCAQoCggEBALpFCSARjG+5yXoqr7UMzuE0df7RRZfeRZI06lJ02ZqV4Iii 6 | rgL7ML9yPxX50NbLnjiilSDTUhnyocYFItokzUzz8qpX/nlYhuN2Iqwh4d0aWS8z 7 | f5y248F+H1z+HY2W8NPl/6DVlVwYaNW1/k+RPMlHS0INLR6j+3Ievew7RNE0NnM2 8 | znELW6NetekDt3GUcz0Z95vDUDfdPnIk1eIFMmYvLxZh23xOca4Q37a3S8F3d+dN 9 | +OOpwjdgY9Qme0NQUaXpgp58jWuQfB8q7mZrdnLlLqRa8gx1HeDSotX7UmWtWPkb 10 | vd9EdlKLYw5PVpxMV1rkwf2t4TdgD5NfkpXlXkkCAwEAAaMjMCEwDgYDVR0PAQH/ 11 | BAQDAgCkMA8GA1UdEwEB/wQFMAMBAf8wCwYJKoZIhvcNAQELA4IBAQBxYjHVSKqE 12 | MJw7CW0GddesULtXXVWGJuZdWJLQlPvPMfIfjIvlcZyS4cdVNiQ3sREFIZz8TpII 13 | CT0/Pg3sgv/FcOQe1CN0xZYZcyiAZHK1z0fJQq2qVpdv7+tJcjI2vvU6NI24iQCo 14 | W1wz25trJz9QbdB2MRLMjyz7TSWuafztIvcfEzaIdQ0Whqund/cSuPGQx5IwF83F 15 | rvlkOyJSH2+VIEBTCIuykJeL0DLTt8cePBQR5L1ISXb4RUMK9ZtqRscBRv8sn7o2 16 | ixG3wtL0gYF4xLtsQWVxI3iFVrU3WzOH/3c5shVRkWBd+AQRSwCJI4mKH7penJCF 17 | i3/zzlkvOnjV 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC6DCCAdKgAwIBAgIRANO6ymxQAjp66KmEka1G6b0wCwYJKoZIhvcNAQELMBYx 3 | FDASBgNVBAoTC0Jvb3QyRG9ja2VyMB4XDTE0MTAxNjIwMjE1MloXDTE3MDkzMDIw 4 | MjE1MlowFjEUMBIGA1UEChMLQm9vdDJEb2NrZXIwggEiMA0GCSqGSIb3DQEBAQUA 5 | A4IBDwAwggEKAoIBAQDGA1mAhSOpZspD1dpZ7qVEQrIJw4Xo8252jHaORnEdDiFm 6 | b6brEmr6jw8t4P3IGxbqBc/TqRV+SSXxwYEVvfpeQKH+SmqStoMNtD3Ura161az4 7 | V0BcxMtSlsUGpoz+//QCAq8qiaxMwgiyc5253mkQm88anj2cNt7xbewiu/KFWuf7 8 | BVpNK1+ltpJmlukfcj/G+I1bw7j1KxBjDrFqe5cyDuuZcDL2tmUXP/ZWDyXwSv+H 9 | AOckqn44z6aXlBkVvOXDBZJqY76d/vWVDNCuZeXRnqlhP3t1kH4V0RQXo+JD2tgt 10 | JgdU0unzyoFOSWNUBPm73tqmjUGGAmGHBmeegJr/AgMBAAGjNTAzMA4GA1UdDwEB 11 | /wQEAwIAgDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMAsGCSqG 12 | SIb3DQEBCwOCAQEABVTWl5SmBP+j5He5bQsgnIXjviSKqe40/10V4LJAOmilycRF 13 | zLrzM+YMwfjg6PLIs8CldAMWHw9y9ktZY4MxkgCktaiaN/QmMTMwFWEcN4wy5IpM 14 | U5l93eAg7xsnY430h3QBBADujX4wdF3fs8rSL8zAAQFL0ihurwU124K3yXKsrwpb 15 | CiVUGfIN4sPwjy8Ws9oxHFDC9/P8lgjHZ1nBIf8KSHnMzlxDGj7isQfhtH+7mcCL 16 | cM1qO2NirS2v7uaEPPY+MJstAz+W7EJCW9dfMSmHna2SDC37Xkin7uEY9z+qaKFL 17 | 8d/XxOB/L8Ucy8VZhdsv0dsBq5KfJntITM0ksQ== 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/foofile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/foofile -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAxgNZgIUjqWbKQ9XaWe6lREKyCcOF6PNudox2jkZxHQ4hZm+m 3 | 6xJq+o8PLeD9yBsW6gXP06kVfkkl8cGBFb36XkCh/kpqkraDDbQ91K2tetWs+FdA 4 | XMTLUpbFBqaM/v/0AgKvKomsTMIIsnOdud5pEJvPGp49nDbe8W3sIrvyhVrn+wVa 5 | TStfpbaSZpbpH3I/xviNW8O49SsQYw6xanuXMg7rmXAy9rZlFz/2Vg8l8Er/hwDn 6 | JKp+OM+ml5QZFbzlwwWSamO+nf71lQzQrmXl0Z6pYT97dZB+FdEUF6PiQ9rYLSYH 7 | VNLp88qBTkljVAT5u97apo1BhgJhhwZnnoCa/wIDAQABAoIBAQCaGy9EC9pmU95l 8 | DwGh7k5nIrUnTilg1FwLHWSDdCVCZKXv8ENrPelOWZqJrUo1u4eI2L8XTsewgkNq 9 | tJu/DRzWz9yDaO0qg6rZNobMh+K076lvmZA44twOydJLS8H+D7ua+PXU2FLlZjmY 10 | kMyXRJZmW6zCXZc7haTbJx6ZJccoquk/DkS4FcFurJP177u1YrWS9TTw9kensUtU 11 | jQ63uf56UTN1i+0+Rxl7OW1TZlqwlri5I4njg5249+FxwwHzIq8+l7zD7K9pl8c/ 12 | nG1HuulvU2bVlDlRdyslMPAH34vw9Sku1BD8furrJLr1na5lRSLKJODEaIPEsLwv 13 | CdEUwP9JAoGBAO76ZW80RyNB2fA+wbTq70Sr8CwrXxYemXrez5LKDC7SsohKFCPE 14 | IedpO/n+nmymiiJvMm874EExoG6BVrbkWkeb+2vinEfOQNlDMsDx7WLjPekP3t6i 15 | rXHO3CjFooVFq2z3mZa/Nc5NZqu8fNWNCKJxZDJphdoj6sORNJIUvZVjAoGBANQd 16 | ++J+ITcu3/+A6JrGcgLunBFQYPqkiItk0J4QKYKuX5ik9rWcQDN8TTtfW2mDuiQ4 17 | NrCwuVPq1V1kB16JzH017SsYLo9g8I20YjnBZge9pKTeUaLVTb3C50LW8FBylop0 18 | Bnm597dNbtSjphjoTMg0XyC19o3Esf2YeWG0QNS1AoGAWWDfFRNJU99qIldmXULM 19 | 0DM6NVrXSk+ReYnhunXEzrJQwXZrR+EwCPurydk36Uz0NuK9yypquhdUeF/5TZfk 20 | SAoHo5byekyipl9imRUigqyY2BTudvgCxKDoaHtaSFwBPFTyZZYICquaLbrmOXxw 21 | 8UhVgCFFRYvPXuts7QHC0h8CgYBWEvy9gfU0kV7wLX02IUTuj6jhFb7ktpN6DSTi 22 | nyhZES1VoctDEu6ydcRZTW6ouH12aSE4Pd5WgTqntQmQgVZrkNB25k8ue2Xh+srJ 23 | KQOgLIJ9LIHwE6KCWG7DnrjRzE3uTPq7to0g4tkQjH/AJ7PQof/gJDayfJjFkXPg 24 | A+cy6QKBgEPbKpiqscm03gT2QanBut5pg4dqPOxp0SlErA3kSFNTRK3oYBQPC+LH 25 | qA5nD5brdkeNBB58Rll8Zpzxiff50bcvLP/7/Sb3NjaXFTEY0gVbdRof3n6N0YP3 26 | Hu5XDNJ9RNkNzE5RIG1g86KE+aKlcrKMaigqAiuIy2PSnjkQeGk8 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC/DCCAeagAwIBAgIQMUILcXtvmSOK63zEBo0VXzALBgkqhkiG9w0BAQswFjEU 3 | MBIGA1UEChMLQm9vdDJEb2NrZXIwHhcNMTQxMDE2MjAyMTQ2WhcNMTcwOTMwMjAy 4 | MTQ2WjAWMRQwEgYDVQQKEwtCb290MkRvY2tlcjCCASIwDQYJKoZIhvcNAQEBBQAD 5 | ggEPADCCAQoCggEBANxUOUhNnqFnrTlLsBYzfFRZWQo268l+4K4lOJCVbfDonP3g 6 | Mz0vGi9fcyFqEWSA8Y+ShXna625HTnReCwFdsu0861qCIq7v95hFFCyOe0iIxpd0 7 | AKLnl90d+1vonE7andgFgoobbTiMly4UK4H6z8D148fFNIihoteOG3PIF89TFxP7 8 | CJ/3wXnx/IKpdlO8PAnub3tBPJHvGDj7KORLy4IBxRX5VBAdfGNybE66fcrehEva 9 | rLA4m9pgiaR/Nnr9FdKhPyqYdjflLNvzydxNvMIV4M0hFlhXmYvpMjA5/XsTnsyV 10 | t9JHJa5Upwqsbne08t7rsm7liZNxZlko8xPOTQcCAwEAAaNKMEgwDgYDVR0PAQH/ 11 | BAQDAgCgMAwGA1UdEwEB/wQCMAAwKAYDVR0RBCEwH4ILYm9vdDJkb2NrZXKHBH8A 12 | AAGHBAoAAg+HBMCoO2cwCwYJKoZIhvcNAQELA4IBAQAYoYcDkDWkl73FZ0WnPmAj 13 | LiF7HU95Qg3KyEpFsAJeShSLPPbQntmwhdekEzY4tQ3eKQB/+zHFjzsCr/lmDUmH 14 | Ea/ryQ17C+jyH+Ykg0IWW6L6veZhvRDg6Z9focVtPVBRxPTqC/Qhb54blWRASV+W 15 | UreMuXQ5+1dQptAM7ixOeLVHjBi/bd9TL3jvwBVCr9QedteMjjK4TCF9Tbcou+MF 16 | 2w3OJJZMDhcD+YwoK9uJDqlKmcTm/vVMbSsp/pTMcnQ7jxCeR8/XyX+VwTZwaHAa 17 | o92Q/eg3THAiWhvyT/SzyH9dHHBAyXynUwGCggKawHktfvW4QXRPuLxLrJ7iB5cy 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/serverkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEoAIBAAKCAQEA3FQ5SE2eoWetOUuwFjN8VFlZCjbryX7griU4kJVt8Oic/eAz 3 | PS8aL19zIWoRZIDxj5KFedrrbkdOdF4LAV2y7TzrWoIiru/3mEUULI57SIjGl3QA 4 | oueX3R37W+icTtqd2AWCihttOIyXLhQrgfrPwPXjx8U0iKGi144bc8gXz1MXE/sI 5 | n/fBefH8gql2U7w8Ce5ve0E8ke8YOPso5EvLggHFFflUEB18Y3JsTrp9yt6ES9qs 6 | sDib2mCJpH82ev0V0qE/Kph2N+Us2/PJ3E28whXgzSEWWFeZi+kyMDn9exOezJW3 7 | 0kclrlSnCqxud7Ty3uuybuWJk3FmWSjzE85NBwIDAQABAoIBAG0ak+cW8LeShHf7 8 | 3+2Of0GxoOLrAWWdG5uAuPr31CJYve0FybnBimDtDjD8ujIfm/7xmoEWBEFutA3x 9 | x9dcU88gvJbsHEqub9gKVQwfXjMz78tt2SbSMiR/xUnk7QorPcCMMfE71aEMFYzu 10 | 1gCed6Rg3vO81t/V0rKVH0j9S7UQz5v/oX15eVDV5LOqyCHwAi6K0eXXbqnbI0TH 11 | SOQ/nexM2msVXWbO9t6ra6f5V7FXziDK5Xi+rPxRbX9mkrDzxDAevfuRqYBx5vtL 12 | W2Q2hKjUAHFgXFniNSZBS7dCdAtz0el/3ct+cNmpuTMhhs7M6wC1CuYiZ/DxLiFh 13 | Si73VckCgYEA+/ceh3+VjtQ0rgEw8sD9bqYEA8IaBiObjneIoFnKBYRG7yZd8JMm 14 | HD4M/aQ1qhcRLPN7GR03YQULgQJURbKSjJHnhfTXHyeHC3NN4gMVHQXewu2MHCh6 15 | 7FCQ9CfK0KcYLgegVVvL3PrF3hyWGnmTu+G0UkDQRYVnaNrB7snrW6UCgYEA39tq 16 | +MCQdu0moJ5szSZf02undg9EeW6isk9qzi7TId3/MLci2eH7PEnipipPUK3+DERq 17 | aba0y0TKgBR2EXvXLFJA/+kfdo2loIEHOfox85HVfxgUaFRti63ZI0uF8D0QT2Yy 18 | oJal+RFghVoSnv4LjhRKEPbIkScTXGjdK+7wFjsCfz79iKRXQQx0ALd/lL0bgkAn 19 | QNmvrNHcFQeI2p8700WNzC39aX67SsvEt3qxkrjzC1gxhpTAuReIK1gVPPwvqHN8 20 | BmV20FD5kMlMCix2mNCopwgUWvKvLAvoGFTxncKMA39+aJbuXAjiqJTekKgNvOE7 21 | i9kEWw0GTNPp3JHV6QECgYAPwb0M11kT1euDIMOdyRazpf86kyaJuZzgGjD1ZFxe 22 | JOcigbGFTp/FhZnbglzk2+pm6KXo3QBq0mPCki4hWusxZnTGzpz1VlETNCHTFeZQ 23 | M7KoaIR/N3oie9Et59H8r/+m5xWnMhNqratyl316DX24uXrhKM3DUdHODl+LCR2D 24 | IwKBgE1MbHuwolUPEw3HeO4R7NMFVTFei7E/fpUsimPfArGg8UydwvloNT1myJos 25 | N2JzfGGjN2KPVcBk9fOs71mJ6VcK3C3g5JIccplk6h9VNaw55+zdQvKPTzoBoTvy 26 | A+Fwx2AlF61KeRF87DL2YTRJ6B9MHmWgf7+GVZOxomLgEAcZ 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/symlink: -------------------------------------------------------------------------------- 1 | doesnotexist -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.8.2 2 | 3 | logrus: fix more Fatal family functions 4 | 5 | # 0.8.1 6 | 7 | logrus: fix not exiting on `Fatalf` and `Fatalln` 8 | 9 | # 0.8.0 10 | 11 | logrus: defaults to stderr instead of stdout 12 | hooks/sentry: add special field for `*http.Request` 13 | formatter/text: ignore Windows for colors 14 | 15 | # 0.7.3 16 | 17 | formatter/\*: allow configuration of timestamp layout 18 | 19 | # 0.7.2 20 | 21 | formatter/text: Add configuration option for time format (#158) 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Simon Eskildsen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/entry_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/fsouza/go-dockerclient/vendor/github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestEntryPanicln(t *testing.T) { 12 | errBoom := fmt.Errorf("boom time") 13 | 14 | defer func() { 15 | p := recover() 16 | assert.NotNil(t, p) 17 | 18 | switch pVal := p.(type) { 19 | case *Entry: 20 | assert.Equal(t, "kaboom", pVal.Message) 21 | assert.Equal(t, errBoom, pVal.Data["err"]) 22 | default: 23 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 24 | } 25 | }() 26 | 27 | logger := New() 28 | logger.Out = &bytes.Buffer{} 29 | entry := NewEntry(logger) 30 | entry.WithField("err", errBoom).Panicln("kaboom") 31 | } 32 | 33 | func TestEntryPanicf(t *testing.T) { 34 | errBoom := fmt.Errorf("boom again") 35 | 36 | defer func() { 37 | p := recover() 38 | assert.NotNil(t, p) 39 | 40 | switch pVal := p.(type) { 41 | case *Entry: 42 | assert.Equal(t, "kaboom true", pVal.Message) 43 | assert.Equal(t, errBoom, pVal.Data["err"]) 44 | default: 45 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 46 | } 47 | }() 48 | 49 | logger := New() 50 | logger.Out = &bytes.Buffer{} 51 | entry := NewEntry(logger) 52 | entry.WithField("err", errBoom).Panicf("kaboom %v", true) 53 | } 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import "time" 4 | 5 | const DefaultTimestampFormat = time.RFC3339 6 | 7 | // The Formatter interface is used to implement a custom Formatter. It takes an 8 | // `Entry`. It exposes all the fields, including the default ones: 9 | // 10 | // * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. 11 | // * `entry.Data["time"]`. The timestamp. 12 | // * `entry.Data["level"]. The level the entry was logged at. 13 | // 14 | // Any additional fields added with `WithField` or `WithFields` are also in 15 | // `entry.Data`. Format is expected to return an array of bytes which are then 16 | // logged to `logger.Out`. 17 | type Formatter interface { 18 | Format(*Entry) ([]byte, error) 19 | } 20 | 21 | // This is to not silently overwrite `time`, `msg` and `level` fields when 22 | // dumping it. If this code wasn't there doing: 23 | // 24 | // logrus.WithField("level", 1).Info("hello") 25 | // 26 | // Would just silently drop the user provided level. Instead with this code 27 | // it'll logged as: 28 | // 29 | // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} 30 | // 31 | // It's not exported because it's still using Data in an opinionated way. It's to 32 | // avoid code duplication between the two default formatters. 33 | func prefixFieldClashes(data Fields) { 34 | _, ok := data["time"] 35 | if ok { 36 | data["fields.time"] = data["time"] 37 | } 38 | 39 | _, ok = data["msg"] 40 | if ok { 41 | data["fields.msg"] = data["msg"] 42 | } 43 | 44 | _, ok = data["level"] 45 | if ok { 46 | data["fields.level"] = data["level"] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/hooks.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | // A hook to be fired when logging on the logging levels returned from 4 | // `Levels()` on your implementation of the interface. Note that this is not 5 | // fired in a goroutine or a channel with workers, you should handle such 6 | // functionality yourself if your call is non-blocking and you don't wish for 7 | // the logging calls for levels returned from `Levels()` to block. 8 | type Hook interface { 9 | Levels() []Level 10 | Fire(*Entry) error 11 | } 12 | 13 | // Internal type for storing the hooks on a logger instance. 14 | type levelHooks map[Level][]Hook 15 | 16 | // Add a hook to an instance of logger. This is called with 17 | // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. 18 | func (hooks levelHooks) Add(hook Hook) { 19 | for _, level := range hook.Levels() { 20 | hooks[level] = append(hooks[level], hook) 21 | } 22 | } 23 | 24 | // Fire all the hooks for the passed level. Used by `entry.log` to fire 25 | // appropriate hooks for a log entry. 26 | func (hooks levelHooks) Fire(level Level, entry *Entry) error { 27 | for _, hook := range hooks[level] { 28 | if err := hook.Fire(entry); err != nil { 29 | return err 30 | } 31 | } 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/json_formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type JSONFormatter struct { 9 | // TimestampFormat sets the format used for marshaling timestamps. 10 | TimestampFormat string 11 | } 12 | 13 | func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { 14 | data := make(Fields, len(entry.Data)+3) 15 | for k, v := range entry.Data { 16 | switch v := v.(type) { 17 | case error: 18 | // Otherwise errors are ignored by `encoding/json` 19 | // https://github.com/Sirupsen/logrus/issues/137 20 | data[k] = v.Error() 21 | default: 22 | data[k] = v 23 | } 24 | } 25 | prefixFieldClashes(data) 26 | 27 | timestampFormat := f.TimestampFormat 28 | if timestampFormat == "" { 29 | timestampFormat = DefaultTimestampFormat 30 | } 31 | 32 | data["time"] = entry.Time.Format(timestampFormat) 33 | data["msg"] = entry.Message 34 | data["level"] = entry.Level.String() 35 | 36 | serialized, err := json.Marshal(data) 37 | if err != nil { 38 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 39 | } 40 | return append(serialized, '\n'), nil 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/terminal_darwin.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2013 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package logrus 7 | 8 | import "syscall" 9 | 10 | const ioctlReadTermios = syscall.TIOCGETA 11 | 12 | type Termios syscall.Termios 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/terminal_freebsd.go: -------------------------------------------------------------------------------- 1 | /* 2 | Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin. 3 | */ 4 | package logrus 5 | 6 | import ( 7 | "syscall" 8 | ) 9 | 10 | const ioctlReadTermios = syscall.TIOCGETA 11 | 12 | type Termios struct { 13 | Iflag uint32 14 | Oflag uint32 15 | Cflag uint32 16 | Lflag uint32 17 | Cc [20]uint8 18 | Ispeed uint32 19 | Ospeed uint32 20 | } 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/terminal_linux.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2013 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package logrus 7 | 8 | import "syscall" 9 | 10 | const ioctlReadTermios = syscall.TCGETS 11 | 12 | type Termios syscall.Termios 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build linux darwin freebsd openbsd 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | // IsTerminal returns true if the given file descriptor is a terminal. 16 | func IsTerminal() bool { 17 | fd := syscall.Stdout 18 | var termios Termios 19 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 20 | return err == 0 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/terminal_openbsd.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import "syscall" 4 | 5 | const ioctlReadTermios = syscall.TIOCGETA 6 | 7 | type Termios syscall.Termios 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/terminal_windows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build windows 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 16 | 17 | var ( 18 | procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 19 | ) 20 | 21 | // IsTerminal returns true if the given file descriptor is a terminal. 22 | func IsTerminal() bool { 23 | fd := syscall.Stdout 24 | var st uint32 25 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 26 | return r != 0 && e == 0 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/Sirupsen/logrus/writer.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "runtime" 7 | ) 8 | 9 | func (logger *Logger) Writer() *io.PipeWriter { 10 | reader, writer := io.Pipe() 11 | 12 | go logger.writerScanner(reader) 13 | runtime.SetFinalizer(writer, writerFinalizer) 14 | 15 | return writer 16 | } 17 | 18 | func (logger *Logger) writerScanner(reader *io.PipeReader) { 19 | scanner := bufio.NewScanner(reader) 20 | for scanner.Scan() { 21 | logger.Print(scanner.Text()) 22 | } 23 | if err := scanner.Err(); err != nil { 24 | logger.Errorf("Error while reading from Writer: %s", err) 25 | } 26 | reader.Close() 27 | } 28 | 29 | func writerFinalizer(writer *io.PipeWriter) { 30 | writer.Close() 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/README.md: -------------------------------------------------------------------------------- 1 | This code provides helper functions for dealing with archive files. 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/archive_unix_test.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package archive 4 | 5 | import ( 6 | "os" 7 | "testing" 8 | ) 9 | 10 | func TestCanonicalTarNameForPath(t *testing.T) { 11 | cases := []struct{ in, expected string }{ 12 | {"foo", "foo"}, 13 | {"foo/bar", "foo/bar"}, 14 | {"foo/dir/", "foo/dir/"}, 15 | } 16 | for _, v := range cases { 17 | if out, err := CanonicalTarNameForPath(v.in); err != nil { 18 | t.Fatalf("cannot get canonical name for path: %s: %v", v.in, err) 19 | } else if out != v.expected { 20 | t.Fatalf("wrong canonical tar name. expected:%s got:%s", v.expected, out) 21 | } 22 | } 23 | } 24 | 25 | func TestCanonicalTarName(t *testing.T) { 26 | cases := []struct { 27 | in string 28 | isDir bool 29 | expected string 30 | }{ 31 | {"foo", false, "foo"}, 32 | {"foo", true, "foo/"}, 33 | {"foo/bar", false, "foo/bar"}, 34 | {"foo/bar", true, "foo/bar/"}, 35 | } 36 | for _, v := range cases { 37 | if out, err := canonicalTarName(v.in, v.isDir); err != nil { 38 | t.Fatalf("cannot get canonical name for path: %s: %v", v.in, err) 39 | } else if out != v.expected { 40 | t.Fatalf("wrong canonical tar name. expected:%s got:%s", v.expected, out) 41 | } 42 | } 43 | } 44 | 45 | func TestChmodTarEntry(t *testing.T) { 46 | cases := []struct { 47 | in, expected os.FileMode 48 | }{ 49 | {0000, 0000}, 50 | {0777, 0777}, 51 | {0644, 0644}, 52 | {0755, 0755}, 53 | {0444, 0444}, 54 | } 55 | for _, v := range cases { 56 | if out := chmodTarEntry(v.in); out != v.expected { 57 | t.Fatalf("wrong chmod. expected:%v got:%v", v.expected, out) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/archive_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package archive 4 | 5 | import ( 6 | "archive/tar" 7 | "fmt" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | // canonicalTarNameForPath returns platform-specific filepath 13 | // to canonical posix-style path for tar archival. p is relative 14 | // path. 15 | func CanonicalTarNameForPath(p string) (string, error) { 16 | // windows: convert windows style relative path with backslashes 17 | // into forward slashes. Since windows does not allow '/' or '\' 18 | // in file names, it is mostly safe to replace however we must 19 | // check just in case 20 | if strings.Contains(p, "/") { 21 | return "", fmt.Errorf("Windows path contains forward slash: %s", p) 22 | } 23 | return strings.Replace(p, string(os.PathSeparator), "/", -1), nil 24 | 25 | } 26 | 27 | // chmodTarEntry is used to adjust the file permissions used in tar header based 28 | // on the platform the archival is done. 29 | func chmodTarEntry(perm os.FileMode) os.FileMode { 30 | perm &= 0755 31 | // Add the x bit: make everything +x from windows 32 | perm |= 0111 33 | 34 | return perm 35 | } 36 | 37 | func setHeaderForSpecialDevice(hdr *tar.Header, ta *tarAppender, name string, stat interface{}) (nlink uint32, inode uint64, err error) { 38 | // do nothing. no notion of Rdev, Inode, Nlink in stat on Windows 39 | return 40 | } 41 | 42 | // handleTarTypeBlockCharFifo is an OS-specific helper function used by 43 | // createTarFile to handle the following types of header: Block; Char; Fifo 44 | func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { 45 | return nil 46 | } 47 | 48 | func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error { 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/changes_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package archive 4 | 5 | import ( 6 | "syscall" 7 | 8 | "github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system" 9 | ) 10 | 11 | func statDifferent(oldStat *system.Stat_t, newStat *system.Stat_t) bool { 12 | // Don't look at size for dirs, its not a good measure of change 13 | if oldStat.Mode() != newStat.Mode() || 14 | oldStat.Uid() != newStat.Uid() || 15 | oldStat.Gid() != newStat.Gid() || 16 | oldStat.Rdev() != newStat.Rdev() || 17 | // Don't look at size for dirs, its not a good measure of change 18 | (oldStat.Mode()&syscall.S_IFDIR != syscall.S_IFDIR && 19 | (!sameFsTimeSpec(oldStat.Mtim(), newStat.Mtim()) || (oldStat.Size() != newStat.Size()))) { 20 | return true 21 | } 22 | return false 23 | } 24 | 25 | func (info *FileInfo) isDir() bool { 26 | return info.parent == nil || info.stat.Mode()&syscall.S_IFDIR != 0 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/changes_windows.go: -------------------------------------------------------------------------------- 1 | package archive 2 | 3 | import ( 4 | "github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system" 5 | ) 6 | 7 | func statDifferent(oldStat *system.Stat_t, newStat *system.Stat_t) bool { 8 | 9 | // Don't look at size for dirs, its not a good measure of change 10 | if oldStat.ModTime() != newStat.ModTime() || 11 | oldStat.Mode() != newStat.Mode() || 12 | oldStat.Size() != newStat.Size() && !oldStat.IsDir() { 13 | return true 14 | } 15 | return false 16 | } 17 | 18 | func (info *FileInfo) isDir() bool { 19 | return info.parent == nil || info.stat.IsDir() 20 | } 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/time_linux.go: -------------------------------------------------------------------------------- 1 | package archive 2 | 3 | import ( 4 | "syscall" 5 | "time" 6 | ) 7 | 8 | func timeToTimespec(time time.Time) (ts syscall.Timespec) { 9 | if time.IsZero() { 10 | // Return UTIME_OMIT special value 11 | ts.Sec = 0 12 | ts.Nsec = ((1 << 30) - 2) 13 | return 14 | } 15 | return syscall.NsecToTimespec(time.UnixNano()) 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/time_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package archive 4 | 5 | import ( 6 | "syscall" 7 | "time" 8 | ) 9 | 10 | func timeToTimespec(time time.Time) (ts syscall.Timespec) { 11 | nsec := int64(0) 12 | if !time.IsZero() { 13 | nsec = time.UnixNano() 14 | } 15 | return syscall.NsecToTimespec(nsec) 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/archive/wrap.go: -------------------------------------------------------------------------------- 1 | package archive 2 | 3 | import ( 4 | "archive/tar" 5 | "bytes" 6 | "io/ioutil" 7 | ) 8 | 9 | // Generate generates a new archive from the content provided 10 | // as input. 11 | // 12 | // `files` is a sequence of path/content pairs. A new file is 13 | // added to the archive for each pair. 14 | // If the last pair is incomplete, the file is created with an 15 | // empty content. For example: 16 | // 17 | // Generate("foo.txt", "hello world", "emptyfile") 18 | // 19 | // The above call will return an archive with 2 files: 20 | // * ./foo.txt with content "hello world" 21 | // * ./empty with empty content 22 | // 23 | // FIXME: stream content instead of buffering 24 | // FIXME: specify permissions and other archive metadata 25 | func Generate(input ...string) (Archive, error) { 26 | files := parseStringPairs(input...) 27 | buf := new(bytes.Buffer) 28 | tw := tar.NewWriter(buf) 29 | for _, file := range files { 30 | name, content := file[0], file[1] 31 | hdr := &tar.Header{ 32 | Name: name, 33 | Size: int64(len(content)), 34 | } 35 | if err := tw.WriteHeader(hdr); err != nil { 36 | return nil, err 37 | } 38 | if _, err := tw.Write([]byte(content)); err != nil { 39 | return nil, err 40 | } 41 | } 42 | if err := tw.Close(); err != nil { 43 | return nil, err 44 | } 45 | return ioutil.NopCloser(buf), nil 46 | } 47 | 48 | func parseStringPairs(input ...string) (output [][2]string) { 49 | output = make([][2]string, 0, len(input)/2+1) 50 | for i := 0; i < len(input); i += 2 { 51 | var pair [2]string 52 | pair[0] = input[i] 53 | if i+1 < len(input) { 54 | pair[1] = input[i+1] 55 | } 56 | output = append(output, pair) 57 | } 58 | return 59 | } 60 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/ioutils/fmt.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | 8 | // FprintfIfNotEmpty prints the string value if it's not empty 9 | func FprintfIfNotEmpty(w io.Writer, format, value string) (int, error) { 10 | if value != "" { 11 | return fmt.Fprintf(w, format, value) 12 | } 13 | return 0, nil 14 | } 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/ioutils/fmt_test.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import "testing" 4 | 5 | func TestFprintfIfNotEmpty(t *testing.T) { 6 | wc := NewWriteCounter(&NopWriter{}) 7 | n, _ := FprintfIfNotEmpty(wc, "foo%s", "") 8 | 9 | if wc.Count != 0 || n != 0 { 10 | t.Errorf("Wrong count: %v vs. %v vs. 0", wc.Count, n) 11 | } 12 | 13 | n, _ = FprintfIfNotEmpty(wc, "foo%s", "bar") 14 | if wc.Count != 6 || n != 6 { 15 | t.Errorf("Wrong count: %v vs. %v vs. 6", wc.Count, n) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/ioutils/writeflusher.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | "sync" 7 | ) 8 | 9 | type WriteFlusher struct { 10 | sync.Mutex 11 | w io.Writer 12 | flusher http.Flusher 13 | flushed bool 14 | } 15 | 16 | func (wf *WriteFlusher) Write(b []byte) (n int, err error) { 17 | wf.Lock() 18 | defer wf.Unlock() 19 | n, err = wf.w.Write(b) 20 | wf.flushed = true 21 | wf.flusher.Flush() 22 | return n, err 23 | } 24 | 25 | // Flush the stream immediately. 26 | func (wf *WriteFlusher) Flush() { 27 | wf.Lock() 28 | defer wf.Unlock() 29 | wf.flushed = true 30 | wf.flusher.Flush() 31 | } 32 | 33 | func (wf *WriteFlusher) Flushed() bool { 34 | wf.Lock() 35 | defer wf.Unlock() 36 | return wf.flushed 37 | } 38 | 39 | func NewWriteFlusher(w io.Writer) *WriteFlusher { 40 | var flusher http.Flusher 41 | if f, ok := w.(http.Flusher); ok { 42 | flusher = f 43 | } else { 44 | flusher = &NopFlusher{} 45 | } 46 | return &WriteFlusher{w: w, flusher: flusher} 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/ioutils/writers.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import "io" 4 | 5 | type NopWriter struct{} 6 | 7 | func (*NopWriter) Write(buf []byte) (int, error) { 8 | return len(buf), nil 9 | } 10 | 11 | type nopWriteCloser struct { 12 | io.Writer 13 | } 14 | 15 | func (w *nopWriteCloser) Close() error { return nil } 16 | 17 | func NopWriteCloser(w io.Writer) io.WriteCloser { 18 | return &nopWriteCloser{w} 19 | } 20 | 21 | type NopFlusher struct{} 22 | 23 | func (f *NopFlusher) Flush() {} 24 | 25 | type writeCloserWrapper struct { 26 | io.Writer 27 | closer func() error 28 | } 29 | 30 | func (r *writeCloserWrapper) Close() error { 31 | return r.closer() 32 | } 33 | 34 | func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser { 35 | return &writeCloserWrapper{ 36 | Writer: r, 37 | closer: closer, 38 | } 39 | } 40 | 41 | // Wrap a concrete io.Writer and hold a count of the number 42 | // of bytes written to the writer during a "session". 43 | // This can be convenient when write return is masked 44 | // (e.g., json.Encoder.Encode()) 45 | type WriteCounter struct { 46 | Count int64 47 | Writer io.Writer 48 | } 49 | 50 | func NewWriteCounter(w io.Writer) *WriteCounter { 51 | return &WriteCounter{ 52 | Writer: w, 53 | } 54 | } 55 | 56 | func (wc *WriteCounter) Write(p []byte) (count int, err error) { 57 | count, err = wc.Writer.Write(p) 58 | wc.Count += int64(count) 59 | return 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/ioutils/writers_test.go: -------------------------------------------------------------------------------- 1 | package ioutils 2 | 3 | import ( 4 | "bytes" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestWriteCloserWrapperClose(t *testing.T) { 10 | called := false 11 | writer := bytes.NewBuffer([]byte{}) 12 | wrapper := NewWriteCloserWrapper(writer, func() error { 13 | called = true 14 | return nil 15 | }) 16 | if err := wrapper.Close(); err != nil { 17 | t.Fatal(err) 18 | } 19 | if !called { 20 | t.Fatalf("writeCloserWrapper should have call the anonymous function.") 21 | } 22 | } 23 | 24 | func TestNopWriteCloser(t *testing.T) { 25 | writer := bytes.NewBuffer([]byte{}) 26 | wrapper := NopWriteCloser(writer) 27 | if err := wrapper.Close(); err != nil { 28 | t.Fatal("NopWriteCloser always return nil on Close.") 29 | } 30 | 31 | } 32 | 33 | func TestNopWriter(t *testing.T) { 34 | nw := &NopWriter{} 35 | l, err := nw.Write([]byte{'c'}) 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | if l != 1 { 40 | t.Fatalf("Expected 1 got %d", l) 41 | } 42 | } 43 | 44 | func TestWriteCounter(t *testing.T) { 45 | dummy1 := "This is a dummy string." 46 | dummy2 := "This is another dummy string." 47 | totalLength := int64(len(dummy1) + len(dummy2)) 48 | 49 | reader1 := strings.NewReader(dummy1) 50 | reader2 := strings.NewReader(dummy2) 51 | 52 | var buffer bytes.Buffer 53 | wc := NewWriteCounter(&buffer) 54 | 55 | reader1.WriteTo(wc) 56 | reader2.WriteTo(wc) 57 | 58 | if wc.Count != totalLength { 59 | t.Errorf("Wrong count: %d vs. %d", wc.Count, totalLength) 60 | } 61 | 62 | if buffer.String() != dummy1+dummy2 { 63 | t.Error("Wrong message written") 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/promise/promise.go: -------------------------------------------------------------------------------- 1 | package promise 2 | 3 | // Go is a basic promise implementation: it wraps calls a function in a goroutine, 4 | // and returns a channel which will later return the function's return value. 5 | func Go(f func() error) chan error { 6 | ch := make(chan error, 1) 7 | go func() { 8 | ch <- f() 9 | }() 10 | return ch 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/errors.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | var ( 8 | ErrNotSupportedPlatform = errors.New("platform and architecture is not supported") 9 | ) 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/filesys.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | ) 8 | 9 | func MkdirAll(path string, perm os.FileMode) error { 10 | return os.MkdirAll(path, perm) 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/filesys_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | "regexp" 8 | "syscall" 9 | ) 10 | 11 | // MkdirAll implementation that is volume path aware for Windows. 12 | func MkdirAll(path string, perm os.FileMode) error { 13 | if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) { 14 | return nil 15 | } 16 | 17 | // The rest of this method is copied from os.MkdirAll and should be kept 18 | // as-is to ensure compatibility. 19 | 20 | // Fast path: if we can tell whether path is a directory or file, stop with success or error. 21 | dir, err := os.Stat(path) 22 | if err == nil { 23 | if dir.IsDir() { 24 | return nil 25 | } 26 | return &os.PathError{ 27 | Op: "mkdir", 28 | Path: path, 29 | Err: syscall.ENOTDIR, 30 | } 31 | } 32 | 33 | // Slow path: make sure parent exists and then call Mkdir for path. 34 | i := len(path) 35 | for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator. 36 | i-- 37 | } 38 | 39 | j := i 40 | for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element. 41 | j-- 42 | } 43 | 44 | if j > 1 { 45 | // Create parent 46 | err = MkdirAll(path[0:j-1], perm) 47 | if err != nil { 48 | return err 49 | } 50 | } 51 | 52 | // Parent now exists; invoke Mkdir and use its result. 53 | err = os.Mkdir(path, perm) 54 | if err != nil { 55 | // Handle arguments like "foo/." by 56 | // double-checking that directory doesn't exist. 57 | dir, err1 := os.Lstat(path) 58 | if err1 == nil && dir.IsDir() { 59 | return nil 60 | } 61 | return err 62 | } 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/lstat.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | // Lstat takes a path to a file and returns 10 | // a system.Stat_t type pertaining to that file. 11 | // 12 | // Throws an error if the file does not exist 13 | func Lstat(path string) (*Stat_t, error) { 14 | s := &syscall.Stat_t{} 15 | if err := syscall.Lstat(path, s); err != nil { 16 | return nil, err 17 | } 18 | return fromStatT(s) 19 | } 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/lstat_test.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | // TestLstat tests Lstat for existing and non existing files 9 | func TestLstat(t *testing.T) { 10 | file, invalid, _, dir := prepareFiles(t) 11 | defer os.RemoveAll(dir) 12 | 13 | statFile, err := Lstat(file) 14 | if err != nil { 15 | t.Fatal(err) 16 | } 17 | if statFile == nil { 18 | t.Fatal("returned empty stat for existing file") 19 | } 20 | 21 | statInvalid, err := Lstat(invalid) 22 | if err == nil { 23 | t.Fatal("did not return error for non-existing file") 24 | } 25 | if statInvalid != nil { 26 | t.Fatal("returned non-nil stat for non-existing file") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/lstat_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | ) 8 | 9 | // Some explanation for my own sanity, and hopefully maintainers in the 10 | // future. 11 | // 12 | // Lstat calls os.Lstat to get a fileinfo interface back. 13 | // This is then copied into our own locally defined structure. 14 | // Note the Linux version uses fromStatT to do the copy back, 15 | // but that not strictly necessary when already in an OS specific module. 16 | 17 | func Lstat(path string) (*Stat_t, error) { 18 | fi, err := os.Lstat(path) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | return &Stat_t{ 24 | name: fi.Name(), 25 | size: fi.Size(), 26 | mode: fi.Mode(), 27 | modTime: fi.ModTime(), 28 | isDir: fi.IsDir()}, nil 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/meminfo.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | // MemInfo contains memory statistics of the host system. 4 | type MemInfo struct { 5 | // Total usable RAM (i.e. physical RAM minus a few reserved bits and the 6 | // kernel binary code). 7 | MemTotal int64 8 | 9 | // Amount of free memory. 10 | MemFree int64 11 | 12 | // Total amount of swap space available. 13 | SwapTotal int64 14 | 15 | // Amount of swap space that is currently unused. 16 | SwapFree int64 17 | } 18 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/meminfo_linux.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "bufio" 5 | "errors" 6 | "io" 7 | "os" 8 | "strconv" 9 | "strings" 10 | 11 | "github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/units" 12 | ) 13 | 14 | var ( 15 | ErrMalformed = errors.New("malformed file") 16 | ) 17 | 18 | // ReadMemInfo retrieves memory statistics of the host system and returns a 19 | // MemInfo type. 20 | func ReadMemInfo() (*MemInfo, error) { 21 | file, err := os.Open("/proc/meminfo") 22 | if err != nil { 23 | return nil, err 24 | } 25 | defer file.Close() 26 | return parseMemInfo(file) 27 | } 28 | 29 | // parseMemInfo parses the /proc/meminfo file into 30 | // a MemInfo object given a io.Reader to the file. 31 | // 32 | // Throws error if there are problems reading from the file 33 | func parseMemInfo(reader io.Reader) (*MemInfo, error) { 34 | meminfo := &MemInfo{} 35 | scanner := bufio.NewScanner(reader) 36 | for scanner.Scan() { 37 | // Expected format: ["MemTotal:", "1234", "kB"] 38 | parts := strings.Fields(scanner.Text()) 39 | 40 | // Sanity checks: Skip malformed entries. 41 | if len(parts) < 3 || parts[2] != "kB" { 42 | continue 43 | } 44 | 45 | // Convert to bytes. 46 | size, err := strconv.Atoi(parts[1]) 47 | if err != nil { 48 | continue 49 | } 50 | bytes := int64(size) * units.KiB 51 | 52 | switch parts[0] { 53 | case "MemTotal:": 54 | meminfo.MemTotal = bytes 55 | case "MemFree:": 56 | meminfo.MemFree = bytes 57 | case "SwapTotal:": 58 | meminfo.SwapTotal = bytes 59 | case "SwapFree:": 60 | meminfo.SwapFree = bytes 61 | } 62 | 63 | } 64 | 65 | // Handle errors that may have occurred during the reading of the file. 66 | if err := scanner.Err(); err != nil { 67 | return nil, err 68 | } 69 | 70 | return meminfo, nil 71 | } 72 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/meminfo_linux_test.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/units" 8 | ) 9 | 10 | // TestMemInfo tests parseMemInfo with a static meminfo string 11 | func TestMemInfo(t *testing.T) { 12 | const input = ` 13 | MemTotal: 1 kB 14 | MemFree: 2 kB 15 | SwapTotal: 3 kB 16 | SwapFree: 4 kB 17 | Malformed1: 18 | Malformed2: 1 19 | Malformed3: 2 MB 20 | Malformed4: X kB 21 | ` 22 | meminfo, err := parseMemInfo(strings.NewReader(input)) 23 | if err != nil { 24 | t.Fatal(err) 25 | } 26 | if meminfo.MemTotal != 1*units.KiB { 27 | t.Fatalf("Unexpected MemTotal: %d", meminfo.MemTotal) 28 | } 29 | if meminfo.MemFree != 2*units.KiB { 30 | t.Fatalf("Unexpected MemFree: %d", meminfo.MemFree) 31 | } 32 | if meminfo.SwapTotal != 3*units.KiB { 33 | t.Fatalf("Unexpected SwapTotal: %d", meminfo.SwapTotal) 34 | } 35 | if meminfo.SwapFree != 4*units.KiB { 36 | t.Fatalf("Unexpected SwapFree: %d", meminfo.SwapFree) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/meminfo_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!windows 2 | 3 | package system 4 | 5 | func ReadMemInfo() (*MemInfo, error) { 6 | return nil, ErrNotSupportedPlatform 7 | } 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/meminfo_windows.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | var ( 9 | modkernel32 = syscall.NewLazyDLL("kernel32.dll") 10 | 11 | procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") 12 | ) 13 | 14 | // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx 15 | // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770(v=vs.85).aspx 16 | type memorystatusex struct { 17 | dwLength uint32 18 | dwMemoryLoad uint32 19 | ullTotalPhys uint64 20 | ullAvailPhys uint64 21 | ullTotalPageFile uint64 22 | ullAvailPageFile uint64 23 | ullTotalVirtual uint64 24 | ullAvailVirtual uint64 25 | ullAvailExtendedVirtual uint64 26 | } 27 | 28 | // ReadMemInfo retrieves memory statistics of the host system and returns a 29 | // MemInfo type. 30 | func ReadMemInfo() (*MemInfo, error) { 31 | msi := &memorystatusex{ 32 | dwLength: 64, 33 | } 34 | r1, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msi))) 35 | if r1 == 0 { 36 | return &MemInfo{}, nil 37 | } 38 | return &MemInfo{ 39 | MemTotal: int64(msi.ullTotalPhys), 40 | MemFree: int64(msi.ullAvailPhys), 41 | SwapTotal: int64(msi.ullTotalPageFile), 42 | SwapFree: int64(msi.ullAvailPageFile), 43 | }, nil 44 | } 45 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/mknod.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | // Mknod creates a filesystem node (file, device special file or named pipe) named path 10 | // with attributes specified by mode and dev 11 | func Mknod(path string, mode uint32, dev int) error { 12 | return syscall.Mknod(path, mode, dev) 13 | } 14 | 15 | // Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes. 16 | // They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major, 17 | // then the top 12 bits of the minor 18 | func Mkdev(major int64, minor int64) uint32 { 19 | return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff)) 20 | } 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/mknod_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | func Mknod(path string, mode uint32, dev int) error { 6 | return ErrNotSupportedPlatform 7 | } 8 | 9 | func Mkdev(major int64, minor int64) uint32 { 10 | panic("Mkdev not implemented on Windows.") 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/stat.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | // Stat_t type contains status of a file. It contains metadata 10 | // like permission, owner, group, size, etc about a file 11 | type Stat_t struct { 12 | mode uint32 13 | uid uint32 14 | gid uint32 15 | rdev uint64 16 | size int64 17 | mtim syscall.Timespec 18 | } 19 | 20 | func (s Stat_t) Mode() uint32 { 21 | return s.mode 22 | } 23 | 24 | func (s Stat_t) Uid() uint32 { 25 | return s.uid 26 | } 27 | 28 | func (s Stat_t) Gid() uint32 { 29 | return s.gid 30 | } 31 | 32 | func (s Stat_t) Rdev() uint64 { 33 | return s.rdev 34 | } 35 | 36 | func (s Stat_t) Size() int64 { 37 | return s.size 38 | } 39 | 40 | func (s Stat_t) Mtim() syscall.Timespec { 41 | return s.mtim 42 | } 43 | 44 | func (s Stat_t) GetLastModification() syscall.Timespec { 45 | return s.Mtim() 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/stat_linux.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | // fromStatT converts a syscall.Stat_t type to a system.Stat_t type 8 | func fromStatT(s *syscall.Stat_t) (*Stat_t, error) { 9 | return &Stat_t{size: s.Size, 10 | mode: s.Mode, 11 | uid: s.Uid, 12 | gid: s.Gid, 13 | rdev: s.Rdev, 14 | mtim: s.Mtim}, nil 15 | } 16 | 17 | // FromStatT exists only on linux, and loads a system.Stat_t from a 18 | // syscal.Stat_t. 19 | func FromStatT(s *syscall.Stat_t) (*Stat_t, error) { 20 | return fromStatT(s) 21 | } 22 | 23 | // Stat takes a path to a file and returns 24 | // a system.Stat_t type pertaining to that file. 25 | // 26 | // Throws an error if the file does not exist 27 | func Stat(path string) (*Stat_t, error) { 28 | s := &syscall.Stat_t{} 29 | if err := syscall.Stat(path, s); err != nil { 30 | return nil, err 31 | } 32 | return fromStatT(s) 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/stat_test.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "os" 5 | "syscall" 6 | "testing" 7 | ) 8 | 9 | // TestFromStatT tests fromStatT for a tempfile 10 | func TestFromStatT(t *testing.T) { 11 | file, _, _, dir := prepareFiles(t) 12 | defer os.RemoveAll(dir) 13 | 14 | stat := &syscall.Stat_t{} 15 | err := syscall.Lstat(file, stat) 16 | 17 | s, err := fromStatT(stat) 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | 22 | if stat.Mode != s.Mode() { 23 | t.Fatal("got invalid mode") 24 | } 25 | if stat.Uid != s.Uid() { 26 | t.Fatal("got invalid uid") 27 | } 28 | if stat.Gid != s.Gid() { 29 | t.Fatal("got invalid gid") 30 | } 31 | if stat.Rdev != s.Rdev() { 32 | t.Fatal("got invalid rdev") 33 | } 34 | if stat.Mtim != s.Mtim() { 35 | t.Fatal("got invalid mtim") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/stat_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!windows 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | // fromStatT creates a system.Stat_t type from a syscall.Stat_t type 10 | func fromStatT(s *syscall.Stat_t) (*Stat_t, error) { 11 | return &Stat_t{size: s.Size, 12 | mode: uint32(s.Mode), 13 | uid: s.Uid, 14 | gid: s.Gid, 15 | rdev: uint64(s.Rdev), 16 | mtim: s.Mtimespec}, nil 17 | } 18 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/stat_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | "time" 8 | ) 9 | 10 | type Stat_t struct { 11 | name string 12 | size int64 13 | mode os.FileMode 14 | modTime time.Time 15 | isDir bool 16 | } 17 | 18 | func (s Stat_t) Name() string { 19 | return s.name 20 | } 21 | 22 | func (s Stat_t) Size() int64 { 23 | return s.size 24 | } 25 | 26 | func (s Stat_t) Mode() os.FileMode { 27 | return s.mode 28 | } 29 | 30 | func (s Stat_t) ModTime() time.Time { 31 | return s.modTime 32 | } 33 | 34 | func (s Stat_t) IsDir() bool { 35 | return s.isDir 36 | } 37 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/umask.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | func Umask(newmask int) (oldmask int, err error) { 10 | return syscall.Umask(newmask), nil 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/umask_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | func Umask(newmask int) (oldmask int, err error) { 6 | // should not be called on cli code path 7 | return 0, ErrNotSupportedPlatform 8 | } 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/utimes_darwin.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import "syscall" 4 | 5 | func LUtimesNano(path string, ts []syscall.Timespec) error { 6 | return ErrNotSupportedPlatform 7 | } 8 | 9 | func UtimesNano(path string, ts []syscall.Timespec) error { 10 | return syscall.UtimesNano(path, ts) 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | func LUtimesNano(path string, ts []syscall.Timespec) error { 9 | var _path *byte 10 | _path, err := syscall.BytePtrFromString(path) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | if _, _, err := syscall.Syscall(syscall.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != syscall.ENOSYS { 16 | return err 17 | } 18 | 19 | return nil 20 | } 21 | 22 | func UtimesNano(path string, ts []syscall.Timespec) error { 23 | return syscall.UtimesNano(path, ts) 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/utimes_linux.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | func LUtimesNano(path string, ts []syscall.Timespec) error { 9 | // These are not currently available in syscall 10 | AT_FDCWD := -100 11 | AT_SYMLINK_NOFOLLOW := 0x100 12 | 13 | var _path *byte 14 | _path, err := syscall.BytePtrFromString(path) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(AT_FDCWD), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(AT_SYMLINK_NOFOLLOW), 0, 0); err != 0 && err != syscall.ENOSYS { 20 | return err 21 | } 22 | 23 | return nil 24 | } 25 | 26 | func UtimesNano(path string, ts []syscall.Timespec) error { 27 | return syscall.UtimesNano(path, ts) 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/utimes_test.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "path/filepath" 7 | "syscall" 8 | "testing" 9 | ) 10 | 11 | // prepareFiles creates files for testing in the temp directory 12 | func prepareFiles(t *testing.T) (string, string, string, string) { 13 | dir, err := ioutil.TempDir("", "docker-system-test") 14 | if err != nil { 15 | t.Fatal(err) 16 | } 17 | 18 | file := filepath.Join(dir, "exist") 19 | if err := ioutil.WriteFile(file, []byte("hello"), 0644); err != nil { 20 | t.Fatal(err) 21 | } 22 | 23 | invalid := filepath.Join(dir, "doesnt-exist") 24 | 25 | symlink := filepath.Join(dir, "symlink") 26 | if err := os.Symlink(file, symlink); err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | return file, invalid, symlink, dir 31 | } 32 | 33 | func TestLUtimesNano(t *testing.T) { 34 | file, invalid, symlink, dir := prepareFiles(t) 35 | defer os.RemoveAll(dir) 36 | 37 | before, err := os.Stat(file) 38 | if err != nil { 39 | t.Fatal(err) 40 | } 41 | 42 | ts := []syscall.Timespec{{0, 0}, {0, 0}} 43 | if err := LUtimesNano(symlink, ts); err != nil { 44 | t.Fatal(err) 45 | } 46 | 47 | symlinkInfo, err := os.Lstat(symlink) 48 | if err != nil { 49 | t.Fatal(err) 50 | } 51 | if before.ModTime().Unix() == symlinkInfo.ModTime().Unix() { 52 | t.Fatal("The modification time of the symlink should be different") 53 | } 54 | 55 | fileInfo, err := os.Stat(file) 56 | if err != nil { 57 | t.Fatal(err) 58 | } 59 | if before.ModTime().Unix() != fileInfo.ModTime().Unix() { 60 | t.Fatal("The modification time of the file should be same") 61 | } 62 | 63 | if err := LUtimesNano(invalid, ts); err == nil { 64 | t.Fatal("Doesn't return an error on a non-existing file") 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/utimes_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd,!darwin 2 | 3 | package system 4 | 5 | import "syscall" 6 | 7 | func LUtimesNano(path string, ts []syscall.Timespec) error { 8 | return ErrNotSupportedPlatform 9 | } 10 | 11 | func UtimesNano(path string, ts []syscall.Timespec) error { 12 | return ErrNotSupportedPlatform 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/system/xattrs_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package system 4 | 5 | func Lgetxattr(path string, attr string) ([]byte, error) { 6 | return nil, ErrNotSupportedPlatform 7 | } 8 | 9 | func Lsetxattr(path string, attr string, data []byte, flags int) error { 10 | return ErrNotSupportedPlatform 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/docker/docker/pkg/units/duration.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // HumanDuration returns a human-readable approximation of a duration 9 | // (eg. "About a minute", "4 hours ago", etc.) 10 | func HumanDuration(d time.Duration) string { 11 | if seconds := int(d.Seconds()); seconds < 1 { 12 | return "Less than a second" 13 | } else if seconds < 60 { 14 | return fmt.Sprintf("%d seconds", seconds) 15 | } else if minutes := int(d.Minutes()); minutes == 1 { 16 | return "About a minute" 17 | } else if minutes < 60 { 18 | return fmt.Sprintf("%d minutes", minutes) 19 | } else if hours := int(d.Hours()); hours == 1 { 20 | return "About an hour" 21 | } else if hours < 48 { 22 | return fmt.Sprintf("%d hours", hours) 23 | } else if hours < 24*7*2 { 24 | return fmt.Sprintf("%d days", hours/24) 25 | } else if hours < 24*30*3 { 26 | return fmt.Sprintf("%d weeks", hours/24/7) 27 | } else if hours < 24*365*2 { 28 | return fmt.Sprintf("%d months", hours/24/30) 29 | } 30 | return fmt.Sprintf("%d years", int(d.Hours())/24/365) 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/gorilla/context/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/gorilla/context/README.md: -------------------------------------------------------------------------------- 1 | context 2 | ======= 3 | [![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context) 4 | 5 | gorilla/context is a general purpose registry for global request variables. 6 | 7 | Read the full documentation here: http://www.gorillatoolkit.org/pkg/context 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/gorilla/mux/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/gorilla/mux/README.md: -------------------------------------------------------------------------------- 1 | mux 2 | === 3 | [![Build Status](https://travis-ci.org/gorilla/mux.png?branch=master)](https://travis-ci.org/gorilla/mux) 4 | 5 | gorilla/mux is a powerful URL router and dispatcher. 6 | 7 | Read the full documentation here: http://www.gorillatoolkit.org/pkg/mux 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/vendor/github.com/gorilla/mux/bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Gorilla Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mux 6 | 7 | import ( 8 | "net/http" 9 | "testing" 10 | ) 11 | 12 | func BenchmarkMux(b *testing.B) { 13 | router := new(Router) 14 | handler := func(w http.ResponseWriter, r *http.Request) {} 15 | router.HandleFunc("/v1/{v1}", handler) 16 | 17 | request, _ := http.NewRequest("GET", "/v1/anything", nil) 18 | for i := 0; i < b.N; i++ { 19 | router.ServeHTTP(nil, request) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/hashicorp/golang-lru/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/hashicorp/golang-lru/README.md: -------------------------------------------------------------------------------- 1 | golang-lru 2 | ========== 3 | 4 | This provides the `lru` package which implements a fixed-size 5 | thread safe LRU cache. It is based on the cache in Groupcache. 6 | 7 | Documentation 8 | ============= 9 | 10 | Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru) 11 | 12 | Example 13 | ======= 14 | 15 | Using the LRU is very simple: 16 | 17 | ```go 18 | l, _ := New(128) 19 | for i := 0; i < 256; i++ { 20 | l.Add(i, nil) 21 | } 22 | if l.Len() != 128 { 23 | panic(fmt.Sprintf("bad len: %v", l.Len())) 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/samalba/dockerclient/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/samalba/dockerclient/auth.go: -------------------------------------------------------------------------------- 1 | package dockerclient 2 | 3 | import ( 4 | "bytes" 5 | "encoding/base64" 6 | "encoding/json" 7 | ) 8 | 9 | // AuthConfig hold parameters for authenticating with the docker registry 10 | type AuthConfig struct { 11 | Username string `json:"username,omitempty"` 12 | Password string `json:"password,omitempty"` 13 | Email string `json:"email,omitempty"` 14 | } 15 | 16 | // encode the auth configuration struct into base64 for the X-Registry-Auth header 17 | func (c *AuthConfig) encode() string { 18 | var buf bytes.Buffer 19 | json.NewEncoder(&buf).Encode(c) 20 | return base64.URLEncoding.EncodeToString(buf.Bytes()) 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/samalba/dockerclient/auth_test.go: -------------------------------------------------------------------------------- 1 | package dockerclient 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAuthEncode(t *testing.T) { 8 | a := AuthConfig{Username: "foo", Password: "password", Email: "bar@baz.com"} 9 | expected := "eyJ1c2VybmFtZSI6ImZvbyIsInBhc3N3b3JkIjoicGFzc3dvcmQiLCJlbWFpbCI6ImJhckBiYXouY29tIn0K" 10 | got := a.encode() 11 | 12 | if expected != got { 13 | t.Errorf("testAuthEncode failed. Expected [%s] got [%s]", expected, got) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/samalba/dockerclient/examples/events.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/samalba/dockerclient" 5 | "log" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | ) 10 | 11 | func eventCallback(e *dockerclient.Event, ec chan error, args ...interface{}) { 12 | log.Println(e) 13 | } 14 | 15 | var ( 16 | client *dockerclient.DockerClient 17 | ) 18 | 19 | func waitForInterrupt() { 20 | sigChan := make(chan os.Signal, 1) 21 | signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT) 22 | for _ = range sigChan { 23 | client.StopAllMonitorEvents() 24 | os.Exit(0) 25 | } 26 | } 27 | 28 | func main() { 29 | docker, err := dockerclient.NewDockerClient(os.Getenv("DOCKER_HOST"), nil) 30 | if err != nil { 31 | log.Fatal(err) 32 | } 33 | 34 | client = docker 35 | 36 | client.StartMonitorEvents(eventCallback, nil) 37 | 38 | waitForInterrupt() 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/samalba/dockerclient/examples/stats/stats.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/samalba/dockerclient" 5 | "log" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | ) 10 | 11 | func statCallback(id string, stat *dockerclient.Stats, ec chan error, args ...interface{}) { 12 | log.Println(stat) 13 | } 14 | 15 | func waitForInterrupt() { 16 | sigChan := make(chan os.Signal, 1) 17 | signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT) 18 | for _ = range sigChan { 19 | os.Exit(0) 20 | } 21 | } 22 | 23 | func main() { 24 | docker, err := dockerclient.NewDockerClient(os.Getenv("DOCKER_HOST"), nil) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | 29 | containerConfig := &dockerclient.ContainerConfig{Image: "busybox", Cmd: []string{"sh"}} 30 | containerId, err := docker.CreateContainer(containerConfig, "") 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | 35 | // Start the container 36 | err = docker.StartContainer(containerId, nil) 37 | if err != nil { 38 | log.Fatal(err) 39 | } 40 | docker.StartMonitorStats(containerId, statCallback, nil) 41 | 42 | waitForInterrupt() 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/samalba/dockerclient/mockclient/mock_test.go: -------------------------------------------------------------------------------- 1 | package mockclient 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/samalba/dockerclient" 8 | ) 9 | 10 | func TestMock(t *testing.T) { 11 | mock := NewMockClient() 12 | mock.On("Version").Return(&dockerclient.Version{Version: "foo"}, nil).Once() 13 | 14 | v, err := mock.Version() 15 | if err != nil { 16 | t.Fatal(err) 17 | } 18 | if v.Version != "foo" { 19 | t.Fatal(v) 20 | } 21 | 22 | mock.Mock.AssertExpectations(t) 23 | } 24 | 25 | func TestMockInterface(t *testing.T) { 26 | iface := reflect.TypeOf((*dockerclient.Client)(nil)).Elem() 27 | mock := NewMockClient() 28 | 29 | if !reflect.TypeOf(mock).Implements(iface) { 30 | t.Fatalf("Mock does not implement the Client interface") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/samalba/dockerclient/utils.go: -------------------------------------------------------------------------------- 1 | package dockerclient 2 | 3 | import ( 4 | "crypto/tls" 5 | "net" 6 | "net/http" 7 | "net/url" 8 | "time" 9 | ) 10 | 11 | func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *http.Client { 12 | httpTransport := &http.Transport{ 13 | TLSClientConfig: tlsConfig, 14 | } 15 | 16 | switch u.Scheme { 17 | default: 18 | httpTransport.Dial = func(proto, addr string) (net.Conn, error) { 19 | return net.DialTimeout(proto, addr, timeout) 20 | } 21 | case "unix": 22 | socketPath := u.Path 23 | unixDial := func(proto, addr string) (net.Conn, error) { 24 | return net.DialTimeout("unix", socketPath, timeout) 25 | } 26 | httpTransport.Dial = unixDial 27 | // Override the main URL object so the HTTP lib won't complain 28 | u.Scheme = "http" 29 | u.Host = "unix.sock" 30 | u.Path = "" 31 | } 32 | return &http.Client{Transport: httpTransport} 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/yaml.v2/LICENSE.libyaml: -------------------------------------------------------------------------------- 1 | The following files were ported to Go from C files of libyaml, and thus 2 | are still covered by their original copyright and license: 3 | 4 | apic.go 5 | emitterc.go 6 | parserc.go 7 | readerc.go 8 | scannerc.go 9 | writerc.go 10 | yamlh.go 11 | yamlprivateh.go 12 | 13 | Copyright (c) 2006 Kirill Simonov 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of 16 | this software and associated documentation files (the "Software"), to deal in 17 | the Software without restriction, including without limitation the rights to 18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 19 | of the Software, and to permit persons to whom the Software is furnished to do 20 | so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/yaml.v2/suite_test.go: -------------------------------------------------------------------------------- 1 | package yaml_test 2 | 3 | import ( 4 | . "gopkg.in/check.v1" 5 | "testing" 6 | ) 7 | 8 | func Test(t *testing.T) { TestingT(t) } 9 | 10 | type S struct{} 11 | 12 | var _ = Suite(&S{}) 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sherdock 2 | ======== 3 | 4 | ![sherdock](logo.png "SherDock") 5 | 6 | DockerCon 2015 Hackathon Project 7 | 8 | ## Features 9 | 10 | * Automatic GC of images based on regexp 11 | * Find and delete orphan Docker volumes (requires Docker 1.7) 12 | * UI 13 | 14 | ## Running 15 | 16 | docker run -d -v /var/lib/docker:/var/lib/docker -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 rancher/sherdock 17 | 18 | UI at http://localhost:8080 19 | 20 | ## Warning 21 | 22 | Sherdock is a Work in Progress and running sherdock might lead to docker images being deleted on the host. The default 23 | configuration will not GC anything. Please change the default configuration from ".*" to just the images you want to save. 24 | 25 | ## Developing 26 | 27 | ```bash 28 | 29 | # Update UI 30 | ./script/build-ui 31 | 32 | # Run 33 | ./script/run 34 | ``` 35 | 36 | ## Release 37 | 38 | ./script/package 39 | -------------------------------------------------------------------------------- /config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | 8 | yaml "gopkg.in/yaml.v2" 9 | ) 10 | 11 | type Config struct { 12 | GCIntervalMinutes int 13 | PullIntervalMinutes int 14 | ImagesToPull []string 15 | ImagesToNotGC []string 16 | } 17 | 18 | var Conf Config 19 | 20 | func configFileName(name string) string { 21 | if name == "" { 22 | name = "config.yml" 23 | } 24 | return name 25 | } 26 | 27 | func defaultConfig() *Config { 28 | config := Config{ 29 | GCIntervalMinutes: 5, 30 | PullIntervalMinutes: 60, 31 | ImagesToPull: []string{"ubuntu:latest", "busybox:latest"}, 32 | ImagesToNotGC: []string{".*"}, 33 | } 34 | 35 | return &config 36 | } 37 | 38 | func GetConfig(name string) (*Config, error) { 39 | config := Config{} 40 | data, err := ioutil.ReadFile(configFileName(name)) 41 | if os.IsNotExist(err) { 42 | a := defaultConfig() 43 | SaveConfig(a, "") 44 | return a, nil 45 | } 46 | if err != nil { 47 | return nil, err 48 | } 49 | err = yaml.Unmarshal(data, &config) 50 | return &config, err 51 | } 52 | 53 | func SaveConfig(config *Config, name string) error { 54 | data, err := yaml.Marshal(&config) 55 | if err != nil { 56 | fmt.Println("Failed to marshal the config.") 57 | return err 58 | } 59 | ioutil.WriteFile(configFileName(name), data, 0644) 60 | return err 61 | } 62 | 63 | func LoadGlobalConfig() error { 64 | config, err := GetConfig(os.Getenv("SHERDOCK_CONFIG")) 65 | if err != nil { 66 | return err 67 | } 68 | Conf = *config 69 | 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /containers/containers.go: -------------------------------------------------------------------------------- 1 | package containers 2 | 3 | import ( 4 | "github.com/samalba/dockerclient" 5 | ) 6 | 7 | func ListContainersDetailed(dockerClient *dockerclient.DockerClient) ([]*dockerclient.ContainerInfo, error) { 8 | containers, err := dockerClient.ListContainers(true, false, "") 9 | if err != nil { 10 | return nil, err 11 | } 12 | var result = make([]*dockerclient.ContainerInfo, len(containers)) 13 | for i, container := range containers { 14 | containerInfo, err := dockerClient.InspectContainer(container.Id) 15 | if err != nil { 16 | return nil, err 17 | } 18 | result[i] = containerInfo 19 | } 20 | return result, nil 21 | } 22 | -------------------------------------------------------------------------------- /images/update.go: -------------------------------------------------------------------------------- 1 | package images 2 | 3 | import ( 4 | "fmt" 5 | "github.com/rancher/sherdock/config" 6 | "github.com/samalba/dockerclient" 7 | "time" 8 | ) 9 | 10 | var url = "unix:///var/run/docker.sock" 11 | 12 | func pullImages() error { 13 | dockerClient, err := dockerclient.NewDockerClient(url, nil) 14 | if err != nil { 15 | fmt.Printf("%#v\n", err) 16 | return err 17 | } 18 | for { 19 | for _, element := range config.Conf.ImagesToPull { 20 | fmt.Printf("Pulling: %v\n", element) 21 | err := dockerClient.PullImage(element, nil) 22 | if err != nil { 23 | fmt.Printf("Error While Pulling: %#v\n", err) 24 | } 25 | fmt.Printf("Pulled: %v\n", element) 26 | } 27 | fmt.Println("All images pulled.\n") 28 | time.Sleep(time.Duration(config.Conf.GCIntervalMinutes) * time.Minute) 29 | } 30 | return nil 31 | } 32 | 33 | func StartImageUpdate() { 34 | go pullImages() 35 | } 36 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/logo.png -------------------------------------------------------------------------------- /script/build-ui: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | IMAGE=sherdock-ui 5 | 6 | cd $(dirname $0)/.. 7 | docker build -t $IMAGE -f Dockerfile.ui . 8 | docker run -u $(id -u) -v $(pwd):/target $IMAGE cp /go/src/github.com/rancher/sherdock/bindata_assetfs.go /target 9 | -------------------------------------------------------------------------------- /script/package: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | IMAGE=rancher/sherdock 5 | BUILD=${IMAGE}-build 6 | 7 | cd $(dirname $0)/.. 8 | 9 | ./script/build-ui 10 | 11 | docker build -t $BUILD . 12 | docker run -u $(id -u) -v $(pwd):/target $BUILD cp /usr/bin/sherdock /target 13 | docker build -t $IMAGE -f Dockerfile.dist . 14 | -------------------------------------------------------------------------------- /script/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | IMAGE=sherdock-dev 5 | PORT=${PORT:-8080} 6 | 7 | cd $(dirname $0)/.. 8 | docker build -t $IMAGE . 9 | docker run -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker -it -p ${PORT}:8080 $IMAGE 10 | -------------------------------------------------------------------------------- /sherdock-ember/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /sherdock-ember/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.js] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.hbs] 21 | indent_style = space 22 | indent_size = 2 23 | 24 | [*.css] 25 | indent_style = space 26 | indent_size = 2 27 | 28 | [*.html] 29 | indent_style = space 30 | indent_size = 2 31 | 32 | [*.{diff,md}] 33 | trim_trailing_whitespace = false 34 | -------------------------------------------------------------------------------- /sherdock-ember/.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /sherdock-ember/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | 7 | # dependencies 8 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log 17 | testem.log 18 | .DS_Store 19 | -------------------------------------------------------------------------------- /sherdock-ember/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise", 6 | "cy", 7 | "cytoscape", 8 | "$" 9 | ], 10 | "browser": true, 11 | "boss": true, 12 | "curly": true, 13 | "debug": false, 14 | "devel": true, 15 | "eqeqeq": true, 16 | "evil": true, 17 | "forin": false, 18 | "immed": false, 19 | "laxbreak": false, 20 | "newcap": true, 21 | "noarg": true, 22 | "noempty": false, 23 | "nonew": false, 24 | "nomen": false, 25 | "onevar": false, 26 | "plusplus": false, 27 | "regexp": false, 28 | "undef": true, 29 | "sub": true, 30 | "strict": false, 31 | "white": false, 32 | "eqnull": true, 33 | "esnext": true, 34 | "unused": true 35 | } 36 | -------------------------------------------------------------------------------- /sherdock-ember/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | 4 | sudo: false 5 | 6 | cache: 7 | directories: 8 | - node_modules 9 | 10 | before_install: 11 | - "npm config set spin false" 12 | - "npm install -g npm@^2" 13 | 14 | install: 15 | - npm install -g bower 16 | - npm install 17 | - bower install 18 | 19 | script: 20 | - npm test 21 | -------------------------------------------------------------------------------- /sherdock-ember/Brocfile.js: -------------------------------------------------------------------------------- 1 | /* global require, module */ 2 | 3 | var EmberApp = require('ember-cli/lib/broccoli/ember-app'); 4 | 5 | var app = new EmberApp({ 6 | storeConfigInMeta: false, 7 | 8 | // Disable fingerprinting.. 9 | fingerprint: { 10 | extensions: [], 11 | }, 12 | 13 | /* 14 | gzip: { 15 | enabled: true, 16 | keepUncompressed: true 17 | }, 18 | */ 19 | 20 | sourcemaps: { 21 | enabled: true, 22 | extensions: ['js'] 23 | } 24 | }); 25 | 26 | // Use `app.import` to add additional libraries to the generated 27 | // output files. 28 | // 29 | // If you need to use different assets in different 30 | // environments, specify an object as the first parameter. That 31 | // object's keys should be the environment name and the values 32 | // should be the asset to use in that environment. 33 | // 34 | // If the library that you are including contains AMD or ES6 35 | // modules that you would like to import into your application 36 | // please specify an object with the list of modules as keys 37 | // along with the exports of each module as its value. 38 | app.import('bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js'); 39 | 40 | app.import('bower_components/d3/d3.js'); 41 | app.import('bower_components/cytoscape/dist/cytoscape.js'); 42 | 43 | module.exports = app.toTree(); 44 | -------------------------------------------------------------------------------- /sherdock-ember/README.md: -------------------------------------------------------------------------------- 1 | # Sherdock-ember 2 | 3 | This README outlines the details of collaborating on this Ember application. 4 | A short introduction of this app could easily go here. 5 | 6 | ## Prerequisites 7 | 8 | You will need the following things properly installed on your computer. 9 | 10 | * [Git](http://git-scm.com/) 11 | * [Node.js](http://nodejs.org/) (with NPM) 12 | * [Bower](http://bower.io/) 13 | * [Ember CLI](http://www.ember-cli.com/) 14 | * [PhantomJS](http://phantomjs.org/) 15 | 16 | ## Installation 17 | 18 | * `git clone ` this repository 19 | * change into the new directory 20 | * `npm install` 21 | * `bower install` 22 | 23 | ## Running / Development 24 | 25 | * `ember server` 26 | * Visit your app at [http://localhost:4200](http://localhost:4200). 27 | 28 | ### Code Generators 29 | 30 | Make use of the many generators for code, try `ember help generate` for more details 31 | 32 | ### Running Tests 33 | 34 | * `ember test` 35 | * `ember test --server` 36 | 37 | ### Building 38 | 39 | * `ember build` (development) 40 | * `ember build --environment production` (production) 41 | 42 | ### Deploying 43 | 44 | Specify what it takes to deploy your app. 45 | 46 | ## Further Reading / Useful Links 47 | 48 | * [ember.js](http://emberjs.com/) 49 | * [ember-cli](http://www.ember-cli.com/) 50 | * Development Browser Extensions 51 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) 52 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) 53 | 54 | -------------------------------------------------------------------------------- /sherdock-ember/app/app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Resolver from 'ember/resolver'; 3 | import loadInitializers from 'ember/load-initializers'; 4 | import config from './config/environment'; 5 | 6 | Ember.MODEL_FACTORY_INJECTIONS = true; 7 | 8 | var App = Ember.Application.extend({ 9 | modulePrefix: config.modulePrefix, 10 | podModulePrefix: config.podModulePrefix, 11 | Resolver: Resolver 12 | }); 13 | 14 | loadInitializers(App, config.modulePrefix); 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /sherdock-ember/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/app/components/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/app/config/controller.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Controller.extend({ 4 | gcRegex: null, 5 | images: null, 6 | 7 | actions: { 8 | save: function() { 9 | this.get('store').rawRequest({ 10 | url: 'config', 11 | method: 'POST', 12 | data: { 13 | GCIntervalMinutes: parseInt(this.get('model.GCIntervalMinutes'),10), 14 | PullIntervalMinutes: parseInt(this.get('model.PullIntervalMinutes'),10), 15 | ImagesToNotGC: this.get('gcRegex').map((entry) => {return entry.value; }).filter((entry) => {return !!entry;}), 16 | ImagesToPull: this.get('images').map((entry) => {return entry.value; }).filter((entry) => {return !!entry;}), 17 | } 18 | }); 19 | } 20 | }, 21 | 22 | gcRegexDidChange: function() { 23 | var vals = this.get('gcRegex'); 24 | for ( var i = 0 ; i < vals.get('length')-1 ; i++ ) 25 | { 26 | var val = (vals.objectAt(i).value||'').trim(); 27 | if ( !val ) 28 | { 29 | vals.removeAt(i); 30 | i--; 31 | } 32 | } 33 | 34 | var last = vals.objectAt(vals.get('length')-1); 35 | if ( !last || (last && last.value) ) 36 | { 37 | vals.pushObject({value: ''}); 38 | } 39 | }.observes('gcRegex.@each.value'), 40 | 41 | imagesDidChange: function() { 42 | var vals = this.get('images'); 43 | for ( var i = 0 ; i < vals.get('length')-1 ; i++ ) 44 | { 45 | var val = (vals.objectAt(i).value||'').trim(); 46 | if ( !val ) 47 | { 48 | vals.removeAt(i); 49 | i--; 50 | } 51 | } 52 | 53 | var last = vals.objectAt(vals.get('length')-1); 54 | if ( !last || (last && last.value) ) 55 | { 56 | vals.pushObject({value: ''}); 57 | } 58 | }.observes('images.@each.value'), 59 | 60 | }); 61 | -------------------------------------------------------------------------------- /sherdock-ember/app/config/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | actions: { 5 | refresh: function() { 6 | this.refresh(); 7 | }, 8 | }, 9 | 10 | model: function() { 11 | return this.get('store').rawRequest({url: 'config'}); 12 | }, 13 | 14 | setupController: function(controller, model) { 15 | controller.set('model', model); 16 | controller.set('gcRegex', (model.ImagesToNotGC||[]).map((val) => { 17 | return {value: val}; 18 | })); 19 | controller.set('images', (model.ImagesToPull||[]).map((val) => { 20 | return {value: val}; 21 | })); 22 | controller.gcRegexDidChange(); 23 | controller.imagesDidChange(); 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /sherdock-ember/app/config/template.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

Garbage Collection

5 | Every {{input value=model.GCIntervalMinutes class="form-control" style="display: inline-block; width: 100px;"}} minutes, delete images that do not match regular expressions: 6 |

7 | {{#each obj in gcRegex}} 8 |
9 | / 10 | {{input value=obj.value class="form-control"}} 11 | / 12 |
13 | {{/each}} 14 |
15 |
16 |

Image Pull

17 |

18 | Every {{input value=model.PullIntervalMinutes class="form-control" style="display: inline-block; width: 100px;"}} minutes, pull the latest version of these images: 19 |

20 | {{#each obj in images}} 21 | {{input value=obj.value class="form-control"}} 22 | {{/each}} 23 |
24 |
25 | 26 |
27 |
28 |
29 | 30 |
31 | -------------------------------------------------------------------------------- /sherdock-ember/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/app/controllers/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/app/graph/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model: function() { 5 | return this.get('store').rawRequest({url: 'images?detailed=true'}); 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /sherdock-ember/app/graph/template.hbs: -------------------------------------------------------------------------------- 1 |

Image Graph

2 | 3 |
4 |
5 | -------------------------------------------------------------------------------- /sherdock-ember/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/app/helpers/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/app/helpers/display-size.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | var suffixes = ['B','KiB','MiB','GiB','TiB']; 4 | 5 | export default Ember.Handlebars.makeBoundHelper(function(bytes) { 6 | var i = 0; 7 | var val = bytes; 8 | 9 | while ( val > 1024 && i < suffixes.length ) 10 | { 11 | val /= 1024; 12 | i++; 13 | } 14 | 15 | return Math.round(val*10)/10 +' '+ suffixes[i]; 16 | }); 17 | -------------------------------------------------------------------------------- /sherdock-ember/app/helpers/short-id.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Handlebars.makeBoundHelper(function(str) { 4 | return (str||'').substr(0,8); 5 | }); 6 | -------------------------------------------------------------------------------- /sherdock-ember/app/images/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model: function() { 5 | return this.get('store').rawRequest({url: 'images?detailed=false'}); 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /sherdock-ember/app/images/template.hbs: -------------------------------------------------------------------------------- 1 |

Images

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {{#each image in this}} 15 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | {{/each}} 29 | 30 |
IDParentTagsSizeVirtual Size
{{short-id image.Id}}…{{short-id image.ParentId}}… 19 | {{#each tag in image.RepoTags}} 20 | {{#unless (eq tag ":")}} 21 | {{tag}} 22 | {{/unless}} 23 | {{/each}} 24 | {{display-size image.Size}}{{display-size image.VirtualSize}}
31 | -------------------------------------------------------------------------------- /sherdock-ember/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sherdock 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | 12 | 13 | 14 | 15 | 16 | {{content-for 'head-footer'}} 17 | 18 | 19 | {{content-for 'body'}} 20 | 21 | 22 | 23 | 24 | {{content-for 'body-footer'}} 25 | 26 | 27 | -------------------------------------------------------------------------------- /sherdock-ember/app/index/template.hbs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sherdock-ember/app/initializers/extend.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export function initialize(/*container, application*/) { 4 | Ember.TextField.reopen({ 5 | attributeBindings: ['style'], 6 | }); 7 | } 8 | 9 | export default { 10 | name: 'extend', 11 | initialize: initialize 12 | }; 13 | -------------------------------------------------------------------------------- /sherdock-ember/app/initializers/lookup.js: -------------------------------------------------------------------------------- 1 | export function initialize(container/*, application*/) { 2 | // Shortcuts for debugging. These should never be used in code. 3 | window.l = function(name) { 4 | return container.lookup(name); 5 | }; 6 | 7 | window.lc = function(name) { 8 | return container.lookup('controller:'+name); 9 | }; 10 | 11 | window.s = container.lookup('store:main'); 12 | } 13 | 14 | export default { 15 | name: 'lookup', 16 | initialize: initialize 17 | }; 18 | -------------------------------------------------------------------------------- /sherdock-ember/app/initializers/store.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | function ajaxPromise(opt) { 4 | var promise = new Ember.RSVP.Promise(function(resolve,reject) { 5 | Ember.$.ajax(opt).then(success,fail); 6 | 7 | function success(body, textStatus, xhr) { 8 | Ember.run(function() { 9 | resolve(body, 'AJAX Response: '+ opt.url + '(' + xhr.status + ')'); 10 | }); 11 | } 12 | 13 | function fail(xhr, textStatus, err) { 14 | Ember.run(function() { 15 | reject({xhr: xhr, textStatus: textStatus, err: err}, 'AJAX Error:' + opt.url + '(' + xhr.status + ')'); 16 | }); 17 | } 18 | },'Raw AJAX Request: '+ opt.url); 19 | 20 | return promise; 21 | } 22 | 23 | var Store = Ember.Object.extend({ 24 | //baseUrl: 'http://192.168.59.104:8080/api', 25 | baseUrl: '/api', 26 | 27 | rawRequest: function(opt) { 28 | var url = opt.url; 29 | if ( url.indexOf('http') !== 0 && url.indexOf('/') !== 0 ) 30 | { 31 | url = this.get('baseUrl').replace(/\/\+$/,'') + '/' + url; 32 | } 33 | 34 | opt.url = url; 35 | 36 | if ( opt.data ) 37 | { 38 | opt.contentType = 'application/json'; 39 | opt.data = JSON.stringify(opt.data); 40 | } 41 | 42 | var promise = ajaxPromise(opt); 43 | return promise; 44 | }, 45 | }); 46 | 47 | export function initialize(container, application) { 48 | var store = Store.create({}); 49 | 50 | container.register('store:main', store, {instantiate: false}); 51 | application.inject('controller', 'store', 'store:main'); 52 | application.inject('route', 'store', 'store:main'); 53 | } 54 | 55 | export default { 56 | name: 'store', 57 | initialize: initialize 58 | }; 59 | -------------------------------------------------------------------------------- /sherdock-ember/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/app/models/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/app/router.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import config from './config/environment'; 3 | 4 | var Router = Ember.Router.extend({ 5 | location: config.locationType 6 | }); 7 | 8 | Router.map(function() { 9 | this.resource('images'); 10 | this.resource('graph'); 11 | this.resource('containers'); 12 | this.resource('volumes'); 13 | this.route('config'); 14 | }); 15 | 16 | export default Router; 17 | -------------------------------------------------------------------------------- /sherdock-ember/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/app/routes/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/app/routes/application.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /sherdock-ember/app/styles/app.scss: -------------------------------------------------------------------------------- 1 | @import "bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap"; 2 | 3 | .logo { 4 | background-image: url('images/logo.svg'); 5 | height: 600px; 6 | background-size: contain; 7 | background-position: center center; 8 | background-repeat: no-repeat; 9 | } 10 | 11 | .node rect, 12 | .node circle, 13 | .node ellipse, 14 | .node polygon { 15 | stroke: #333; 16 | fill: #fff; 17 | stroke-width: 1.5px; 18 | } 19 | 20 | .edgePath path { 21 | stroke: #333; 22 | fill: #333; 23 | stroke-width: 1.5px; 24 | } 25 | -------------------------------------------------------------------------------- /sherdock-ember/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 | 25 | 26 |
27 | {{outlet}} 28 |
29 | -------------------------------------------------------------------------------- /sherdock-ember/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/app/views/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/app/views/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/app/volumes/controller.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.ArrayController.extend({ 4 | actions: { 5 | removeAll: function() { 6 | this.get('store').rawRequest({ 7 | url: 'volumes', 8 | method: 'DELETE', 9 | }).then(() => { 10 | this.send('refresh'); 11 | }); 12 | }, 13 | 14 | remove: function(volumeId) { 15 | this.get('store').rawRequest({ 16 | url: 'volumes/'+volumeId, 17 | method: 'DELETE', 18 | }).then(() => { 19 | this.send('refresh'); 20 | }); 21 | } 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /sherdock-ember/app/volumes/route.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | actions: { 5 | refresh: function() { 6 | this.refresh(); 7 | }, 8 | }, 9 | 10 | model: function() { 11 | return this.get('store').rawRequest({url: 'volumes'}).then((volumes) => { 12 | var keys = Object.keys(volumes); 13 | var out = []; 14 | 15 | keys.forEach((key) => { 16 | out.push(volumes[key]); 17 | }); 18 | 19 | return out.sort(function(a,b) { 20 | if ( a.Attached && !b.Attached ) 21 | { 22 | return 1; 23 | } 24 | else if ( !a.Attached && b.Attached ) 25 | { 26 | return -1; 27 | } 28 | 29 | return 0; 30 | }); 31 | }); 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /sherdock-ember/app/volumes/template.hbs: -------------------------------------------------------------------------------- 1 |

2 | Volumes 3 | 4 |

5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {{#each volume in this}} 18 | 19 | 20 | 21 | 22 | 25 | 26 | 31 | 32 | 33 | 34 | 37 | 38 | {{/each}} 39 | 40 |
IDContainerPathIn Use 
{{short-id volume.ID}}…{{short-id volume.ContainerID}}…Host: 23 | {{volume.DockerPath}} 24 | {{#if volume.Attached}}Yes{{else}}No{{/if}} 27 | {{#unless volume.Attached}} 28 | 29 | {{/unless}} 30 |
Container: 35 | {{volume.ContainerPath}} 36 |
41 | -------------------------------------------------------------------------------- /sherdock-ember/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sherdock-ember", 3 | "dependencies": { 4 | "jquery": "^1.11.1", 5 | "ember": "1.10.0", 6 | "ember-data": "1.0.0-beta.15", 7 | "ember-resolver": "~0.1.12", 8 | "loader.js": "ember-cli/loader.js#3.2.0", 9 | "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3", 10 | "ember-cli-test-loader": "ember-cli-test-loader#0.1.3", 11 | "ember-load-initializers": "ember-cli/ember-load-initializers#0.0.2", 12 | "ember-qunit": "0.2.8", 13 | "ember-qunit-notifications": "0.0.7", 14 | "qunit": "~1.17.1", 15 | "bootstrap": "~3.3", 16 | "ember-addons.bs_for_ember": "~0.7.0", 17 | "dagre": "~0.7.1", 18 | "dagre-d3": "~0.4.3", 19 | "bootstrap-sass-official": "~3.3.5", 20 | "cytoscape": "~2.4.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /sherdock-ember/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sherdock-ember", 3 | "version": "0.0.0", 4 | "description": "Small description for sherdock-ember goes here", 5 | "private": true, 6 | "directories": { 7 | "doc": "doc", 8 | "test": "tests" 9 | }, 10 | "scripts": { 11 | "start": "ember server", 12 | "build": "ember build", 13 | "test": "ember test" 14 | }, 15 | "repository": "", 16 | "engines": { 17 | "node": ">= 0.10.0" 18 | }, 19 | "author": "", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "broccoli-asset-rev": "^2.0.0", 23 | "broccoli-sass": "^0.6.6", 24 | "ember-cli": "0.2.0", 25 | "ember-cli-app-version": "0.3.2", 26 | "ember-cli-babel": "^4.0.0", 27 | "ember-cli-content-security-policy": "0.3.0", 28 | "ember-cli-dependency-checker": "0.0.8", 29 | "ember-cli-htmlbars": "0.7.4", 30 | "ember-cli-ic-ajax": "0.1.1", 31 | "ember-cli-inject-live-reload": "^1.3.0", 32 | "ember-cli-qunit": "0.3.9", 33 | "ember-cli-uglify": "1.0.1", 34 | "ember-export-application-global": "^1.0.2", 35 | "ember-truth-helpers": "0.0.5", 36 | "forever-agent": "^0.6.1", 37 | "glob": "^5.0.10", 38 | "http-proxy": "^1.11.1" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sherdock-ember/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /sherdock-ember/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /sherdock-ember/server/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true 3 | } 4 | -------------------------------------------------------------------------------- /sherdock-ember/server/index.js: -------------------------------------------------------------------------------- 1 | // To use it create some files under `routes/` 2 | // e.g. `server/routes/ember-hamsters.js` 3 | // 4 | // module.exports = function(app) { 5 | // app.get('/ember-hamsters', function(req, res) { 6 | // res.send('hello'); 7 | // }); 8 | // }; 9 | 10 | module.exports = function(app, options) { 11 | var globSync = require('glob').sync; 12 | var mocks = globSync('./mocks/**/*.js', { cwd: __dirname }).map(require); 13 | var proxies = globSync('./proxies/**/*.js', { cwd: __dirname }).map(require); 14 | 15 | mocks.forEach(function(route) { route(app, options); }); 16 | proxies.forEach(function(route) { route(app, options); }); 17 | }; 18 | -------------------------------------------------------------------------------- /sherdock-ember/server/proxies/api.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app, options) { 2 | var path = require('path'); 3 | var ForeverAgent = require('forever-agent'); 4 | var HttpProxy = require('http-proxy'); 5 | var httpServer = options.httpServer; 6 | 7 | var config = require('../../config/environment')().APP; 8 | var proxy = HttpProxy.createProxyServer({ 9 | ws: true, 10 | xfwd: true, 11 | agent: new ForeverAgent({}) 12 | }); 13 | 14 | console.log('Proxying to', config.endpoint); 15 | 16 | var apiPath = '/api'; 17 | app.use(apiPath, function(req, res, next) { 18 | // include root path in proxied request 19 | req.url = path.join(apiPath, req.url); 20 | 21 | console.log('API Proxy', req.method, 'to', req.url); 22 | proxy.web(req, res, {target: config.endpoint}); 23 | }); 24 | 25 | proxy.on('error', function onProxyError(err, req, res) { 26 | console.log('Proxy Error: on', req.method,'to', req.url,':', err); 27 | var error = { 28 | type: 'error', 29 | status: 500, 30 | code: 'ProxyError', 31 | message: 'Error connecting to proxy', 32 | detail: err.toString() 33 | } 34 | 35 | if ( req.upgrade ) 36 | { 37 | res.end(); 38 | } 39 | else 40 | { 41 | res.writeHead(500, {'Content-Type': 'application/json'}); 42 | res.end(JSON.stringify(error)); 43 | } 44 | }); 45 | 46 | httpServer.on('upgrade', function proxyWsRequest(req, socket, head) { 47 | proxy.ws(req, socket, head, {target: config.endpoint}); 48 | }); 49 | }; 50 | -------------------------------------------------------------------------------- /sherdock-ember/testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "test_page": "tests/index.html?hidepassed", 4 | "launch_in_ci": [ 5 | "PhantomJS" 6 | ], 7 | "launch_in_dev": [ 8 | "PhantomJS", 9 | "Chrome" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /sherdock-ember/tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "define", 10 | "console", 11 | "visit", 12 | "exists", 13 | "fillIn", 14 | "click", 15 | "keyEvent", 16 | "triggerEvent", 17 | "find", 18 | "findWithAssert", 19 | "wait", 20 | "DS", 21 | "andThen", 22 | "currentURL", 23 | "currentPath", 24 | "currentRouteName" 25 | ], 26 | "node": false, 27 | "browser": false, 28 | "boss": true, 29 | "curly": false, 30 | "debug": false, 31 | "devel": false, 32 | "eqeqeq": true, 33 | "evil": true, 34 | "forin": false, 35 | "immed": false, 36 | "laxbreak": false, 37 | "newcap": true, 38 | "noarg": true, 39 | "noempty": false, 40 | "nonew": false, 41 | "nomen": false, 42 | "onevar": false, 43 | "plusplus": false, 44 | "regexp": false, 45 | "undef": true, 46 | "sub": true, 47 | "strict": false, 48 | "white": false, 49 | "eqnull": true, 50 | "esnext": true 51 | } 52 | -------------------------------------------------------------------------------- /sherdock-ember/tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember/resolver'; 2 | import config from '../../config/environment'; 3 | 4 | var resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /sherdock-ember/tests/helpers/start-app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Application from '../../app'; 3 | import Router from '../../router'; 4 | import config from '../../config/environment'; 5 | 6 | export default function startApp(attrs) { 7 | var application; 8 | 9 | var attributes = Ember.merge({}, config.APP); 10 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; 11 | 12 | Ember.run(function() { 13 | application = Application.create(attributes); 14 | application.setupForTesting(); 15 | application.injectTestHelpers(); 16 | }); 17 | 18 | return application; 19 | } 20 | -------------------------------------------------------------------------------- /sherdock-ember/tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SherdockEmber Tests 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | {{content-for 'test-head'}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for 'head-footer'}} 18 | {{content-for 'test-head-footer'}} 19 | 20 | 21 | 22 | {{content-for 'body'}} 23 | {{content-for 'test-body'}} 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for 'body-footer'}} 31 | {{content-for 'test-body-footer'}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /sherdock-ember/tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import resolver from './helpers/resolver'; 2 | import { 3 | setResolver 4 | } from 'ember-qunit'; 5 | 6 | setResolver(resolver); 7 | -------------------------------------------------------------------------------- /sherdock-ember/tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/tests/unit/.gitkeep -------------------------------------------------------------------------------- /sherdock-ember/vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rancher/sherdock/2afc9279209c0c6fb57f98a3750a599664ef9243/sherdock-ember/vendor/.gitkeep --------------------------------------------------------------------------------