├── .dockerignore ├── .gitignore ├── Dockerfile ├── Dockerfile.dist ├── 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_bsd.go │ │ ├── terminal_linux.go │ │ ├── terminal_notwindows.go │ │ ├── terminal_windows.go │ │ ├── text_formatter.go │ │ ├── text_formatter_test.go │ │ └── writer.go │ ├── codegangsta │ └── cli │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── app.go │ │ ├── app_test.go │ │ ├── autocomplete │ │ ├── bash_autocomplete │ │ └── zsh_autocomplete │ │ ├── cli.go │ │ ├── cli_test.go │ │ ├── command.go │ │ ├── command_test.go │ │ ├── context.go │ │ ├── context_test.go │ │ ├── flag.go │ │ ├── flag_test.go │ │ ├── help.go │ │ ├── help_test.go │ │ └── helpers_test.go │ └── fsouza │ └── go-dockerclient │ ├── .gitignore │ ├── .travis.yml │ ├── AUTHORS │ ├── DOCKER-LICENSE │ ├── LICENSE │ ├── Makefile │ ├── README.markdown │ ├── auth.go │ ├── auth_test.go │ ├── build_test.go │ ├── change.go │ ├── change_test.go │ ├── client.go │ ├── client_test.go │ ├── container.go │ ├── container_test.go │ ├── env.go │ ├── env_test.go │ ├── event.go │ ├── event_test.go │ ├── example_test.go │ ├── exec.go │ ├── exec_test.go │ ├── external │ └── github.com │ │ ├── Sirupsen │ │ └── logrus │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── doc.go │ │ │ ├── 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_bsd.go │ │ │ ├── terminal_linux.go │ │ │ ├── terminal_notwindows.go │ │ │ ├── terminal_windows.go │ │ │ ├── text_formatter.go │ │ │ ├── text_formatter_test.go │ │ │ └── writer.go │ │ ├── docker │ │ ├── distribution │ │ │ └── registry │ │ │ │ └── api │ │ │ │ └── errcode │ │ │ │ ├── errors.go │ │ │ │ ├── errors_test.go │ │ │ │ ├── handler.go │ │ │ │ └── register.go │ │ ├── docker │ │ │ ├── errors │ │ │ │ ├── README.md │ │ │ │ ├── builder.go │ │ │ │ ├── daemon.go │ │ │ │ ├── error.go │ │ │ │ ├── image.go │ │ │ │ └── server.go │ │ │ ├── opts │ │ │ │ ├── envfile.go │ │ │ │ ├── envfile_test.go │ │ │ │ ├── hosts_unix.go │ │ │ │ ├── hosts_windows.go │ │ │ │ ├── ip.go │ │ │ │ ├── ip_test.go │ │ │ │ ├── opts.go │ │ │ │ ├── opts_test.go │ │ │ │ ├── ulimit.go │ │ │ │ └── ulimit_test.go │ │ │ ├── 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 │ │ │ │ │ ├── copy.go │ │ │ │ │ ├── copy_test.go │ │ │ │ │ ├── copy_unix.go │ │ │ │ │ ├── copy_windows.go │ │ │ │ │ ├── diff.go │ │ │ │ │ ├── diff_test.go │ │ │ │ │ ├── example_changes.go │ │ │ │ │ ├── testdata │ │ │ │ │ │ └── broken.tar │ │ │ │ │ ├── time_linux.go │ │ │ │ │ ├── time_unsupported.go │ │ │ │ │ ├── utils_test.go │ │ │ │ │ ├── whiteouts.go │ │ │ │ │ ├── wrap.go │ │ │ │ │ └── wrap_test.go │ │ │ │ ├── fileutils │ │ │ │ │ ├── fileutils.go │ │ │ │ │ ├── fileutils_test.go │ │ │ │ │ ├── fileutils_unix.go │ │ │ │ │ └── fileutils_windows.go │ │ │ │ ├── homedir │ │ │ │ │ ├── homedir.go │ │ │ │ │ └── homedir_test.go │ │ │ │ ├── idtools │ │ │ │ │ ├── idtools.go │ │ │ │ │ ├── idtools_unix.go │ │ │ │ │ ├── idtools_unix_test.go │ │ │ │ │ ├── idtools_windows.go │ │ │ │ │ ├── usergroupadd_linux.go │ │ │ │ │ └── usergroupadd_unsupported.go │ │ │ │ ├── ioutils │ │ │ │ │ ├── bytespipe.go │ │ │ │ │ ├── bytespipe_test.go │ │ │ │ │ ├── fmt.go │ │ │ │ │ ├── fmt_test.go │ │ │ │ │ ├── multireader.go │ │ │ │ │ ├── multireader_test.go │ │ │ │ │ ├── readers.go │ │ │ │ │ ├── readers_test.go │ │ │ │ │ ├── scheduler.go │ │ │ │ │ ├── scheduler_gccgo.go │ │ │ │ │ ├── temp_unix.go │ │ │ │ │ ├── temp_windows.go │ │ │ │ │ ├── writeflusher.go │ │ │ │ │ ├── writers.go │ │ │ │ │ └── writers_test.go │ │ │ │ ├── longpath │ │ │ │ │ ├── longpath.go │ │ │ │ │ └── longpath_test.go │ │ │ │ ├── mflag │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── README.md │ │ │ │ │ ├── flag.go │ │ │ │ │ └── flag_test.go │ │ │ │ ├── parsers │ │ │ │ │ ├── parsers.go │ │ │ │ │ └── parsers_test.go │ │ │ │ ├── pools │ │ │ │ │ ├── pools.go │ │ │ │ │ └── pools_test.go │ │ │ │ ├── promise │ │ │ │ │ └── promise.go │ │ │ │ ├── stdcopy │ │ │ │ │ ├── stdcopy.go │ │ │ │ │ └── stdcopy_test.go │ │ │ │ ├── system │ │ │ │ │ ├── chtimes.go │ │ │ │ │ ├── chtimes_test.go │ │ │ │ │ ├── chtimes_unix_test.go │ │ │ │ │ ├── chtimes_windows_test.go │ │ │ │ │ ├── errors.go │ │ │ │ │ ├── events_windows.go │ │ │ │ │ ├── filesys.go │ │ │ │ │ ├── filesys_windows.go │ │ │ │ │ ├── lstat.go │ │ │ │ │ ├── lstat_test.go │ │ │ │ │ ├── lstat_unix_test.go │ │ │ │ │ ├── lstat_windows.go │ │ │ │ │ ├── meminfo.go │ │ │ │ │ ├── meminfo_linux.go │ │ │ │ │ ├── meminfo_linux_test.go │ │ │ │ │ ├── meminfo_unix_test.go │ │ │ │ │ ├── meminfo_unsupported.go │ │ │ │ │ ├── meminfo_windows.go │ │ │ │ │ ├── mknod.go │ │ │ │ │ ├── mknod_windows.go │ │ │ │ │ ├── stat.go │ │ │ │ │ ├── stat_freebsd.go │ │ │ │ │ ├── stat_linux.go │ │ │ │ │ ├── stat_test.go │ │ │ │ │ ├── stat_unix_test.go │ │ │ │ │ ├── stat_unsupported.go │ │ │ │ │ ├── stat_windows.go │ │ │ │ │ ├── syscall_unix.go │ │ │ │ │ ├── syscall_windows.go │ │ │ │ │ ├── umask.go │ │ │ │ │ ├── umask_windows.go │ │ │ │ │ ├── utimes_darwin.go │ │ │ │ │ ├── utimes_freebsd.go │ │ │ │ │ ├── utimes_linux.go │ │ │ │ │ ├── utimes_test.go │ │ │ │ │ ├── utimes_unix_test.go │ │ │ │ │ ├── utimes_unsupported.go │ │ │ │ │ ├── xattrs_linux.go │ │ │ │ │ └── xattrs_unsupported.go │ │ │ │ ├── ulimit │ │ │ │ │ ├── ulimit.go │ │ │ │ │ └── ulimit_test.go │ │ │ │ └── units │ │ │ │ │ ├── duration.go │ │ │ │ │ ├── duration_test.go │ │ │ │ │ ├── size.go │ │ │ │ │ └── size_test.go │ │ │ └── volume │ │ │ │ ├── volume.go │ │ │ │ ├── volume_test.go │ │ │ │ ├── volume_unix.go │ │ │ │ └── volume_windows.go │ │ └── libcontainer │ │ │ └── user │ │ │ ├── MAINTAINERS │ │ │ ├── lookup.go │ │ │ ├── lookup_unix.go │ │ │ ├── lookup_unsupported.go │ │ │ ├── user.go │ │ │ └── user_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 │ │ └── go-cleanhttp │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ └── cleanhttp.go │ │ └── opencontainers │ │ └── runc │ │ └── libcontainer │ │ └── user │ │ ├── MAINTAINERS │ │ ├── lookup.go │ │ ├── lookup_unix.go │ │ ├── lookup_unsupported.go │ │ ├── user.go │ │ └── user_test.go │ ├── image.go │ ├── image_test.go │ ├── integration_test.go │ ├── misc.go │ ├── misc_test.go │ ├── network.go │ ├── network_test.go │ ├── signal.go │ ├── tar.go │ ├── testing │ ├── data │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ ├── barfile │ │ ├── ca.pem │ │ ├── cert.pem │ │ ├── container.tar │ │ ├── dockerfile.tar │ │ ├── foofile │ │ ├── key.pem │ │ ├── server.pem │ │ └── serverkey.pem │ ├── server.go │ └── server_test.go │ ├── tls.go │ ├── volume.go │ └── volume_test.go ├── README.md ├── main.go ├── scripts ├── build └── package └── volumes ├── manager.go ├── pre19.go └── vols19.go /.dockerignore: -------------------------------------------------------------------------------- 1 | *.md 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.4 2 | 3 | RUN go get github.com/tools/godep 4 | COPY . /go/src/github.com/cloudnautique/vol-cleanup 5 | WORKDIR /go/src/github.com/cloudnautique/vol-cleanup 6 | RUN godep go build -a -tags "netgo" -installsuffix netgo -ldflags "-extldflags -static" -o /usr/bin/vol-cleanup 7 | CMD ["vol-cleanup", "-h"] 8 | -------------------------------------------------------------------------------- /Dockerfile.dist: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | 3 | ADD ./dist/vol-cleanup / 4 | ENTRYPOINT ["/vol-cleanup"] 5 | CMD ["-h"] 6 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/cloudnautique/vol-cleanup", 3 | "GoVersion": "go1.4.2", 4 | "Deps": [ 5 | { 6 | "ImportPath": "github.com/Sirupsen/logrus", 7 | "Comment": "v0.8.6-7-g9c060de", 8 | "Rev": "9c060de643590dae45da9d7c26276463bfc46fa0" 9 | }, 10 | { 11 | "ImportPath": "github.com/codegangsta/cli", 12 | "Comment": "1.2.0-137-gbca61c4", 13 | "Rev": "bca61c476e3c752594983e4c9bcd5f62fb09f157" 14 | }, 15 | { 16 | "ImportPath": "github.com/fsouza/go-dockerclient", 17 | "Rev": "0f5764b4d2f5b8928a05db1226a508817a9a01dd" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /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.6 2 | 3 | * hooks/raven: allow passing an initialized client 4 | 5 | # 0.8.5 6 | 7 | * logrus/core: revert #208 8 | 9 | # 0.8.4 10 | 11 | * formatter/text: fix data race (#218) 12 | 13 | # 0.8.3 14 | 15 | * logrus/core: fix entry log level (#208) 16 | * logrus/core: improve performance of text formatter by 40% 17 | * logrus/core: expose `LevelHooks` type 18 | * logrus/core: add support for DragonflyBSD and NetBSD 19 | * formatter/text: print structs more verbosely 20 | 21 | # 0.8.2 22 | 23 | * logrus: fix more Fatal family functions 24 | 25 | # 0.8.1 26 | 27 | * logrus: fix not exiting on `Fatalf` and `Fatalln` 28 | 29 | # 0.8.0 30 | 31 | * logrus: defaults to stderr instead of stdout 32 | * hooks/sentry: add special field for `*http.Request` 33 | * formatter/text: ignore Windows for colors 34 | 35 | # 0.7.3 36 | 37 | * formatter/\*: allow configuration of timestamp layout 38 | 39 | # 0.7.2 40 | 41 | * formatter/text: Add configuration option for time format (#158) 42 | -------------------------------------------------------------------------------- /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/formatter_bench_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | // smallFields is a small size data set for benchmarking 10 | var smallFields = Fields{ 11 | "foo": "bar", 12 | "baz": "qux", 13 | "one": "two", 14 | "three": "four", 15 | } 16 | 17 | // largeFields is a large size data set for benchmarking 18 | var largeFields = Fields{ 19 | "foo": "bar", 20 | "baz": "qux", 21 | "one": "two", 22 | "three": "four", 23 | "five": "six", 24 | "seven": "eight", 25 | "nine": "ten", 26 | "eleven": "twelve", 27 | "thirteen": "fourteen", 28 | "fifteen": "sixteen", 29 | "seventeen": "eighteen", 30 | "nineteen": "twenty", 31 | "a": "b", 32 | "c": "d", 33 | "e": "f", 34 | "g": "h", 35 | "i": "j", 36 | "k": "l", 37 | "m": "n", 38 | "o": "p", 39 | "q": "r", 40 | "s": "t", 41 | "u": "v", 42 | "w": "x", 43 | "y": "z", 44 | "this": "will", 45 | "make": "thirty", 46 | "entries": "yeah", 47 | } 48 | 49 | var errorFields = Fields{ 50 | "foo": fmt.Errorf("bar"), 51 | "baz": fmt.Errorf("qux"), 52 | } 53 | 54 | func BenchmarkErrorTextFormatter(b *testing.B) { 55 | doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields) 56 | } 57 | 58 | func BenchmarkSmallTextFormatter(b *testing.B) { 59 | doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields) 60 | } 61 | 62 | func BenchmarkLargeTextFormatter(b *testing.B) { 63 | doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields) 64 | } 65 | 66 | func BenchmarkSmallColoredTextFormatter(b *testing.B) { 67 | doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields) 68 | } 69 | 70 | func BenchmarkLargeColoredTextFormatter(b *testing.B) { 71 | doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields) 72 | } 73 | 74 | func BenchmarkSmallJSONFormatter(b *testing.B) { 75 | doBenchmark(b, &JSONFormatter{}, smallFields) 76 | } 77 | 78 | func BenchmarkLargeJSONFormatter(b *testing.B) { 79 | doBenchmark(b, &JSONFormatter{}, largeFields) 80 | } 81 | 82 | func doBenchmark(b *testing.B, formatter Formatter, fields Fields) { 83 | entry := &Entry{ 84 | Time: time.Time{}, 85 | Level: InfoLevel, 86 | Message: "message", 87 | Data: fields, 88 | } 89 | var d []byte 90 | var err error 91 | for i := 0; i < b.N; i++ { 92 | d, err = formatter.Format(entry) 93 | if err != nil { 94 | b.Fatal(err) 95 | } 96 | b.SetBytes(int64(len(d))) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /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/hook_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | type TestHook struct { 10 | Fired bool 11 | } 12 | 13 | func (hook *TestHook) Fire(entry *Entry) error { 14 | hook.Fired = true 15 | return nil 16 | } 17 | 18 | func (hook *TestHook) Levels() []Level { 19 | return []Level{ 20 | DebugLevel, 21 | InfoLevel, 22 | WarnLevel, 23 | ErrorLevel, 24 | FatalLevel, 25 | PanicLevel, 26 | } 27 | } 28 | 29 | func TestHookFires(t *testing.T) { 30 | hook := new(TestHook) 31 | 32 | LogAndAssertJSON(t, func(log *Logger) { 33 | log.Hooks.Add(hook) 34 | assert.Equal(t, hook.Fired, false) 35 | 36 | log.Print("test") 37 | }, func(fields Fields) { 38 | assert.Equal(t, hook.Fired, true) 39 | }) 40 | } 41 | 42 | type ModifyHook struct { 43 | } 44 | 45 | func (hook *ModifyHook) Fire(entry *Entry) error { 46 | entry.Data["wow"] = "whale" 47 | return nil 48 | } 49 | 50 | func (hook *ModifyHook) Levels() []Level { 51 | return []Level{ 52 | DebugLevel, 53 | InfoLevel, 54 | WarnLevel, 55 | ErrorLevel, 56 | FatalLevel, 57 | PanicLevel, 58 | } 59 | } 60 | 61 | func TestHookCanModifyEntry(t *testing.T) { 62 | hook := new(ModifyHook) 63 | 64 | LogAndAssertJSON(t, func(log *Logger) { 65 | log.Hooks.Add(hook) 66 | log.WithField("wow", "elephant").Print("test") 67 | }, func(fields Fields) { 68 | assert.Equal(t, fields["wow"], "whale") 69 | }) 70 | } 71 | 72 | func TestCanFireMultipleHooks(t *testing.T) { 73 | hook1 := new(ModifyHook) 74 | hook2 := new(TestHook) 75 | 76 | LogAndAssertJSON(t, func(log *Logger) { 77 | log.Hooks.Add(hook1) 78 | log.Hooks.Add(hook2) 79 | 80 | log.WithField("wow", "elephant").Print("test") 81 | }, func(fields Fields) { 82 | assert.Equal(t, fields["wow"], "whale") 83 | assert.Equal(t, hook2.Fired, true) 84 | }) 85 | } 86 | 87 | type ErrorHook struct { 88 | Fired bool 89 | } 90 | 91 | func (hook *ErrorHook) Fire(entry *Entry) error { 92 | hook.Fired = true 93 | return nil 94 | } 95 | 96 | func (hook *ErrorHook) Levels() []Level { 97 | return []Level{ 98 | ErrorLevel, 99 | } 100 | } 101 | 102 | func TestErrorHookShouldntFireOnInfo(t *testing.T) { 103 | hook := new(ErrorHook) 104 | 105 | LogAndAssertJSON(t, func(log *Logger) { 106 | log.Hooks.Add(hook) 107 | log.Info("test") 108 | }, func(fields Fields) { 109 | assert.Equal(t, hook.Fired, false) 110 | }) 111 | } 112 | 113 | func TestErrorHookShouldFireOnError(t *testing.T) { 114 | hook := new(ErrorHook) 115 | 116 | LogAndAssertJSON(t, func(log *Logger) { 117 | log.Hooks.Add(hook) 118 | log.Error("test") 119 | }, func(fields Fields) { 120 | assert.Equal(t, hook.Fired, true) 121 | }) 122 | } 123 | -------------------------------------------------------------------------------- /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.go: -------------------------------------------------------------------------------- 1 | package logrus_bugsnag 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/Sirupsen/logrus" 7 | "github.com/bugsnag/bugsnag-go" 8 | ) 9 | 10 | type bugsnagHook struct{} 11 | 12 | // ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before 13 | // bugsnag.Configure. Bugsnag must be configured before the hook. 14 | var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook") 15 | 16 | // ErrBugsnagSendFailed indicates that the hook failed to submit an error to 17 | // bugsnag. The error was successfully generated, but `bugsnag.Notify()` 18 | // failed. 19 | type ErrBugsnagSendFailed struct { 20 | err error 21 | } 22 | 23 | func (e ErrBugsnagSendFailed) Error() string { 24 | return "failed to send error to Bugsnag: " + e.err.Error() 25 | } 26 | 27 | // NewBugsnagHook initializes a logrus hook which sends exceptions to an 28 | // exception-tracking service compatible with the Bugsnag API. Before using 29 | // this hook, you must call bugsnag.Configure(). The returned object should be 30 | // registered with a log via `AddHook()` 31 | // 32 | // Entries that trigger an Error, Fatal or Panic should now include an "error" 33 | // field to send to Bugsnag. 34 | func NewBugsnagHook() (*bugsnagHook, error) { 35 | if bugsnag.Config.APIKey == "" { 36 | return nil, ErrBugsnagUnconfigured 37 | } 38 | return &bugsnagHook{}, nil 39 | } 40 | 41 | // Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the 42 | // "error" field (or the Message if the error isn't present) and sends it off. 43 | func (hook *bugsnagHook) Fire(entry *logrus.Entry) error { 44 | var notifyErr error 45 | err, ok := entry.Data["error"].(error) 46 | if ok { 47 | notifyErr = err 48 | } else { 49 | notifyErr = errors.New(entry.Message) 50 | } 51 | 52 | bugsnagErr := bugsnag.Notify(notifyErr) 53 | if bugsnagErr != nil { 54 | return ErrBugsnagSendFailed{bugsnagErr} 55 | } 56 | 57 | return nil 58 | } 59 | 60 | // Levels enumerates the log levels on which the error should be forwarded to 61 | // bugsnag: everything at or above the "Error" level. 62 | func (hook *bugsnagHook) Levels() []logrus.Level { 63 | return []logrus.Level{ 64 | logrus.ErrorLevel, 65 | logrus.FatalLevel, 66 | logrus.PanicLevel, 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /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/logrus.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | // Fields type, used to pass to `WithFields`. 9 | type Fields map[string]interface{} 10 | 11 | // Level type 12 | type Level uint8 13 | 14 | // Convert the Level to a string. E.g. PanicLevel becomes "panic". 15 | func (level Level) String() string { 16 | switch level { 17 | case DebugLevel: 18 | return "debug" 19 | case InfoLevel: 20 | return "info" 21 | case WarnLevel: 22 | return "warning" 23 | case ErrorLevel: 24 | return "error" 25 | case FatalLevel: 26 | return "fatal" 27 | case PanicLevel: 28 | return "panic" 29 | } 30 | 31 | return "unknown" 32 | } 33 | 34 | // ParseLevel takes a string level and returns the Logrus log level constant. 35 | func ParseLevel(lvl string) (Level, error) { 36 | switch lvl { 37 | case "panic": 38 | return PanicLevel, nil 39 | case "fatal": 40 | return FatalLevel, nil 41 | case "error": 42 | return ErrorLevel, nil 43 | case "warn", "warning": 44 | return WarnLevel, nil 45 | case "info": 46 | return InfoLevel, nil 47 | case "debug": 48 | return DebugLevel, nil 49 | } 50 | 51 | var l Level 52 | return l, fmt.Errorf("not a valid logrus Level: %q", lvl) 53 | } 54 | 55 | // These are the different logging levels. You can set the logging level to log 56 | // on your instance of logger, obtained with `logrus.New()`. 57 | const ( 58 | // PanicLevel level, highest level of severity. Logs and then calls panic with the 59 | // message passed to Debug, Info, ... 60 | PanicLevel Level = iota 61 | // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the 62 | // logging level is set to Panic. 63 | FatalLevel 64 | // ErrorLevel level. Logs. Used for errors that should definitely be noted. 65 | // Commonly used for hooks to send errors to an error tracking service. 66 | ErrorLevel 67 | // WarnLevel level. Non-critical entries that deserve eyes. 68 | WarnLevel 69 | // InfoLevel level. General operational entries about what's going on inside the 70 | // application. 71 | InfoLevel 72 | // DebugLevel level. Usually only enabled when debugging. Very verbose logging. 73 | DebugLevel 74 | ) 75 | 76 | // Won't compile if StdLogger can't be realized by a log.Logger 77 | var _ StdLogger = &log.Logger{} 78 | 79 | // StdLogger is what your logrus-enabled library should take, that way 80 | // it'll accept a stdlib logger and a logrus logger. There's no standard 81 | // interface, this is the closest we get, unfortunately. 82 | type StdLogger interface { 83 | Print(...interface{}) 84 | Printf(string, ...interface{}) 85 | Println(...interface{}) 86 | 87 | Fatal(...interface{}) 88 | Fatalf(string, ...interface{}) 89 | Fatalln(...interface{}) 90 | 91 | Panic(...interface{}) 92 | Panicf(string, ...interface{}) 93 | Panicln(...interface{}) 94 | } 95 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_bsd.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd openbsd netbsd dragonfly 2 | 3 | package logrus 4 | 5 | import "syscall" 6 | 7 | const ioctlReadTermios = syscall.TIOCGETA 8 | 9 | type Termios syscall.Termios 10 | -------------------------------------------------------------------------------- /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 netbsd dragonfly 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_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/text_formatter_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestQuoting(t *testing.T) { 11 | tf := &TextFormatter{DisableColors: true} 12 | 13 | checkQuoting := func(q bool, value interface{}) { 14 | b, _ := tf.Format(WithField("test", value)) 15 | idx := bytes.Index(b, ([]byte)("test=")) 16 | cont := bytes.Contains(b[idx+5:], []byte{'"'}) 17 | if cont != q { 18 | if q { 19 | t.Errorf("quoting expected for: %#v", value) 20 | } else { 21 | t.Errorf("quoting not expected for: %#v", value) 22 | } 23 | } 24 | } 25 | 26 | checkQuoting(false, "abcd") 27 | checkQuoting(false, "v1.0") 28 | checkQuoting(false, "1234567890") 29 | checkQuoting(true, "/foobar") 30 | checkQuoting(true, "x y") 31 | checkQuoting(true, "x,y") 32 | checkQuoting(false, errors.New("invalid")) 33 | checkQuoting(true, errors.New("invalid argument")) 34 | } 35 | 36 | func TestTimestampFormat(t *testing.T) { 37 | checkTimeStr := func(format string) { 38 | customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format} 39 | customStr, _ := customFormatter.Format(WithField("test", "test")) 40 | timeStart := bytes.Index(customStr, ([]byte)("time=")) 41 | timeEnd := bytes.Index(customStr, ([]byte)("level=")) 42 | timeStr := customStr[timeStart+5 : timeEnd-1] 43 | if timeStr[0] == '"' && timeStr[len(timeStr)-1] == '"' { 44 | timeStr = timeStr[1 : len(timeStr)-1] 45 | } 46 | if format == "" { 47 | format = time.RFC3339 48 | } 49 | _, e := time.Parse(format, (string)(timeStr)) 50 | if e != nil { 51 | t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e) 52 | } 53 | } 54 | 55 | checkTimeStr("2006-01-02T15:04:05.000000000Z07:00") 56 | checkTimeStr("Mon Jan _2 15:04:05 2006") 57 | checkTimeStr("") 58 | } 59 | 60 | // TODO add tests for sorting etc., this requires a parser for the text 61 | // formatter output. 62 | -------------------------------------------------------------------------------- /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/codegangsta/cli/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | 4 | go: 5 | - 1.0.3 6 | - 1.1.2 7 | - 1.2.2 8 | - 1.3.3 9 | - 1.4.2 10 | 11 | script: 12 | - go vet ./... 13 | - go test -v ./... 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Jeremy Saenz 2 | All Rights Reserved. 3 | 4 | MIT LICENSE 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | _cli_bash_autocomplete() { 4 | local cur prev opts base 5 | COMPREPLY=() 6 | cur="${COMP_WORDS[COMP_CWORD]}" 7 | prev="${COMP_WORDS[COMP_CWORD-1]}" 8 | opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) 9 | COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) 10 | return 0 11 | } 12 | 13 | complete -F _cli_bash_autocomplete $PROG -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete: -------------------------------------------------------------------------------- 1 | autoload -U compinit && compinit 2 | autoload -U bashcompinit && bashcompinit 3 | 4 | script_dir=$(dirname $0) 5 | source ${script_dir}/bash_autocomplete 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/cli.go: -------------------------------------------------------------------------------- 1 | // Package cli provides a minimal framework for creating and organizing command line 2 | // Go applications. cli is designed to be easy to understand and write, the most simple 3 | // cli application can be written as follows: 4 | // func main() { 5 | // cli.NewApp().Run(os.Args) 6 | // } 7 | // 8 | // Of course this application does not do much, so let's make this an actual application: 9 | // func main() { 10 | // app := cli.NewApp() 11 | // app.Name = "greet" 12 | // app.Usage = "say a greeting" 13 | // app.Action = func(c *cli.Context) { 14 | // println("Greetings") 15 | // } 16 | // 17 | // app.Run(os.Args) 18 | // } 19 | package cli 20 | 21 | import ( 22 | "strings" 23 | ) 24 | 25 | type MultiError struct { 26 | Errors []error 27 | } 28 | 29 | func NewMultiError(err ...error) MultiError { 30 | return MultiError{Errors: err} 31 | } 32 | 33 | func (m MultiError) Error() string { 34 | errs := make([]string, len(m.Errors)) 35 | for i, err := range m.Errors { 36 | errs[i] = err.Error() 37 | } 38 | 39 | return strings.Join(errs, "\n") 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/codegangsta/cli" 7 | ) 8 | 9 | func Example() { 10 | app := cli.NewApp() 11 | app.Name = "todo" 12 | app.Usage = "task list on the command line" 13 | app.Commands = []cli.Command{ 14 | { 15 | Name: "add", 16 | Aliases: []string{"a"}, 17 | Usage: "add a task to the list", 18 | Action: func(c *cli.Context) { 19 | println("added task: ", c.Args().First()) 20 | }, 21 | }, 22 | { 23 | Name: "complete", 24 | Aliases: []string{"c"}, 25 | Usage: "complete a task on the list", 26 | Action: func(c *cli.Context) { 27 | println("completed task: ", c.Args().First()) 28 | }, 29 | }, 30 | } 31 | 32 | app.Run(os.Args) 33 | } 34 | 35 | func ExampleSubcommand() { 36 | app := cli.NewApp() 37 | app.Name = "say" 38 | app.Commands = []cli.Command{ 39 | { 40 | Name: "hello", 41 | Aliases: []string{"hi"}, 42 | Usage: "use it to see a description", 43 | Description: "This is how we describe hello the function", 44 | Subcommands: []cli.Command{ 45 | { 46 | Name: "english", 47 | Aliases: []string{"en"}, 48 | Usage: "sends a greeting in english", 49 | Description: "greets someone in english", 50 | Flags: []cli.Flag{ 51 | cli.StringFlag{ 52 | Name: "name", 53 | Value: "Bob", 54 | Usage: "Name of the person to greet", 55 | }, 56 | }, 57 | Action: func(c *cli.Context) { 58 | println("Hello, ", c.String("name")) 59 | }, 60 | }, { 61 | Name: "spanish", 62 | Aliases: []string{"sp"}, 63 | Usage: "sends a greeting in spanish", 64 | Flags: []cli.Flag{ 65 | cli.StringFlag{ 66 | Name: "surname", 67 | Value: "Jones", 68 | Usage: "Surname of the person to greet", 69 | }, 70 | }, 71 | Action: func(c *cli.Context) { 72 | println("Hola, ", c.String("surname")) 73 | }, 74 | }, { 75 | Name: "french", 76 | Aliases: []string{"fr"}, 77 | Usage: "sends a greeting in french", 78 | Flags: []cli.Flag{ 79 | cli.StringFlag{ 80 | Name: "nickname", 81 | Value: "Stevie", 82 | Usage: "Nickname of the person to greet", 83 | }, 84 | }, 85 | Action: func(c *cli.Context) { 86 | println("Bonjour, ", c.String("nickname")) 87 | }, 88 | }, 89 | }, 90 | }, { 91 | Name: "bye", 92 | Usage: "says goodbye", 93 | Action: func(c *cli.Context) { 94 | println("bye") 95 | }, 96 | }, 97 | } 98 | 99 | app.Run(os.Args) 100 | } 101 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "flag" 5 | "testing" 6 | 7 | "github.com/codegangsta/cli" 8 | ) 9 | 10 | func TestCommandDoNotIgnoreFlags(t *testing.T) { 11 | app := cli.NewApp() 12 | set := flag.NewFlagSet("test", 0) 13 | test := []string{"blah", "blah", "-break"} 14 | set.Parse(test) 15 | 16 | c := cli.NewContext(app, set, nil) 17 | 18 | command := cli.Command{ 19 | Name: "test-cmd", 20 | Aliases: []string{"tc"}, 21 | Usage: "this is for testing", 22 | Description: "testing", 23 | Action: func(_ *cli.Context) {}, 24 | } 25 | err := command.Run(c) 26 | 27 | expect(t, err.Error(), "flag provided but not defined: -break") 28 | } 29 | 30 | func TestCommandIgnoreFlags(t *testing.T) { 31 | app := cli.NewApp() 32 | set := flag.NewFlagSet("test", 0) 33 | test := []string{"blah", "blah"} 34 | set.Parse(test) 35 | 36 | c := cli.NewContext(app, set, nil) 37 | 38 | command := cli.Command{ 39 | Name: "test-cmd", 40 | Aliases: []string{"tc"}, 41 | Usage: "this is for testing", 42 | Description: "testing", 43 | Action: func(_ *cli.Context) {}, 44 | SkipFlagParsing: true, 45 | } 46 | err := command.Run(c) 47 | 48 | expect(t, err, nil) 49 | } 50 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/help_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/codegangsta/cli" 8 | ) 9 | 10 | func Test_ShowAppHelp_NoAuthor(t *testing.T) { 11 | output := new(bytes.Buffer) 12 | app := cli.NewApp() 13 | app.Writer = output 14 | 15 | c := cli.NewContext(app, nil, nil) 16 | 17 | cli.ShowAppHelp(c) 18 | 19 | if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 { 20 | t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):") 21 | } 22 | } 23 | 24 | func Test_ShowAppHelp_NoVersion(t *testing.T) { 25 | output := new(bytes.Buffer) 26 | app := cli.NewApp() 27 | app.Writer = output 28 | 29 | app.Version = "" 30 | 31 | c := cli.NewContext(app, nil, nil) 32 | 33 | cli.ShowAppHelp(c) 34 | 35 | if bytes.Index(output.Bytes(), []byte("VERSION:")) != -1 { 36 | t.Errorf("expected\n%snot to include %s", output.String(), "VERSION:") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | /* Test Helpers */ 9 | func expect(t *testing.T, a interface{}, b interface{}) { 10 | if a != b { 11 | t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) 12 | } 13 | } 14 | 15 | func refute(t *testing.T, a interface{}, b interface{}) { 16 | if a == b { 17 | t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.gitignore: -------------------------------------------------------------------------------- 1 | # temporary symlink for testing 2 | testing/data/symlink 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: required 3 | go: 4 | - 1.3.3 5 | - 1.4.2 6 | - 1.5.1 7 | - tip 8 | env: 9 | - GOARCH=amd64 10 | - GOARCH=386 11 | script: 12 | - make test 13 | - DOCKER_HOST=tcp://127.0.0.1:2375 make integration 14 | services: 15 | - docker 16 | -------------------------------------------------------------------------------- /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/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 | integration \ 11 | cov \ 12 | clean 13 | 14 | SRCS = $(shell git ls-files '*.go' | grep -v '^external/') 15 | PKGS = ./. ./testing 16 | 17 | all: test 18 | 19 | vendor: 20 | @ go get -v github.com/mjibson/party 21 | party -d external -c -u 22 | 23 | lint: 24 | @ go get -v github.com/golang/lint/golint 25 | $(foreach file,$(SRCS),golint $(file) || exit;) 26 | 27 | vet: 28 | @-go get -v golang.org/x/tools/cmd/vet 29 | $(foreach pkg,$(PKGS),go vet $(pkg);) 30 | 31 | fmt: 32 | gofmt -w $(SRCS) 33 | 34 | fmtcheck: 35 | $(foreach file,$(SRCS),gofmt -d $(file);) 36 | 37 | pretest: lint vet fmtcheck 38 | 39 | test: pretest 40 | $(foreach pkg,$(PKGS),go test $(pkg) || exit;) 41 | 42 | integration: 43 | go test -tags docker_integration -run TestIntegration -v 44 | 45 | cov: 46 | @ go get -v github.com/axw/gocov/gocov 47 | @ go get golang.org/x/tools/cmd/cover 48 | gocov test | gocov report 49 | 50 | clean: 51 | $(foreach pkg,$(PKGS),go clean $(pkg) || exit;) 52 | -------------------------------------------------------------------------------- /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 https://goo.gl/9GsTIF 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 "testing" 8 | 9 | func TestChangeString(t *testing.T) { 10 | var tests = []struct { 11 | change Change 12 | expected string 13 | }{ 14 | {Change{"/etc/passwd", ChangeModify}, "C /etc/passwd"}, 15 | {Change{"/etc/passwd", ChangeAdd}, "A /etc/passwd"}, 16 | {Change{"/etc/passwd", ChangeDelete}, "D /etc/passwd"}, 17 | {Change{"/etc/passwd", 33}, " /etc/passwd"}, 18 | } 19 | for _, tt := range tests { 20 | if got := tt.change.String(); got != tt.expected { 21 | t.Errorf("Change.String(): want %q. Got %q.", tt.expected, got) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/Sirupsen/logrus/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.9.0 (Unreleased) 2 | 3 | * logrus/text_formatter: don't emit empty msg 4 | * logrus/hooks/airbrake: move out of main repository 5 | * logrus/hooks/sentry: move out of main repository 6 | * logrus/hooks/papertrail: move out of main repository 7 | * logrus/hooks/bugsnag: move out of main repository 8 | 9 | # 0.8.7 10 | 11 | * logrus/core: fix possible race (#216) 12 | * logrus/doc: small typo fixes and doc improvements 13 | 14 | 15 | # 0.8.6 16 | 17 | * hooks/raven: allow passing an initialized client 18 | 19 | # 0.8.5 20 | 21 | * logrus/core: revert #208 22 | 23 | # 0.8.4 24 | 25 | * formatter/text: fix data race (#218) 26 | 27 | # 0.8.3 28 | 29 | * logrus/core: fix entry log level (#208) 30 | * logrus/core: improve performance of text formatter by 40% 31 | * logrus/core: expose `LevelHooks` type 32 | * logrus/core: add support for DragonflyBSD and NetBSD 33 | * formatter/text: print structs more verbosely 34 | 35 | # 0.8.2 36 | 37 | * logrus: fix more Fatal family functions 38 | 39 | # 0.8.1 40 | 41 | * logrus: fix not exiting on `Fatalf` and `Fatalln` 42 | 43 | # 0.8.0 44 | 45 | * logrus: defaults to stderr instead of stdout 46 | * hooks/sentry: add special field for `*http.Request` 47 | * formatter/text: ignore Windows for colors 48 | 49 | # 0.7.3 50 | 51 | * formatter/\*: allow configuration of timestamp layout 52 | 53 | # 0.7.2 54 | 55 | * formatter/text: Add configuration option for time format (#158) 56 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/github.com/Sirupsen/logrus/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package logrus is a structured logger for Go, completely API compatible with the standard library logger. 3 | 4 | 5 | The simplest way to use Logrus is simply the package-level exported logger: 6 | 7 | package main 8 | 9 | import ( 10 | log "github.com/Sirupsen/logrus" 11 | ) 12 | 13 | func main() { 14 | log.WithFields(log.Fields{ 15 | "animal": "walrus", 16 | "number": 1, 17 | "size": 10, 18 | }).Info("A walrus appears") 19 | } 20 | 21 | Output: 22 | time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 23 | 24 | For a full guide visit https://github.com/Sirupsen/logrus 25 | */ 26 | package logrus 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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/external/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/external/github.com/Sirupsen/logrus/formatter_bench_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | // smallFields is a small size data set for benchmarking 10 | var smallFields = Fields{ 11 | "foo": "bar", 12 | "baz": "qux", 13 | "one": "two", 14 | "three": "four", 15 | } 16 | 17 | // largeFields is a large size data set for benchmarking 18 | var largeFields = Fields{ 19 | "foo": "bar", 20 | "baz": "qux", 21 | "one": "two", 22 | "three": "four", 23 | "five": "six", 24 | "seven": "eight", 25 | "nine": "ten", 26 | "eleven": "twelve", 27 | "thirteen": "fourteen", 28 | "fifteen": "sixteen", 29 | "seventeen": "eighteen", 30 | "nineteen": "twenty", 31 | "a": "b", 32 | "c": "d", 33 | "e": "f", 34 | "g": "h", 35 | "i": "j", 36 | "k": "l", 37 | "m": "n", 38 | "o": "p", 39 | "q": "r", 40 | "s": "t", 41 | "u": "v", 42 | "w": "x", 43 | "y": "z", 44 | "this": "will", 45 | "make": "thirty", 46 | "entries": "yeah", 47 | } 48 | 49 | var errorFields = Fields{ 50 | "foo": fmt.Errorf("bar"), 51 | "baz": fmt.Errorf("qux"), 52 | } 53 | 54 | func BenchmarkErrorTextFormatter(b *testing.B) { 55 | doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields) 56 | } 57 | 58 | func BenchmarkSmallTextFormatter(b *testing.B) { 59 | doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields) 60 | } 61 | 62 | func BenchmarkLargeTextFormatter(b *testing.B) { 63 | doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields) 64 | } 65 | 66 | func BenchmarkSmallColoredTextFormatter(b *testing.B) { 67 | doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields) 68 | } 69 | 70 | func BenchmarkLargeColoredTextFormatter(b *testing.B) { 71 | doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields) 72 | } 73 | 74 | func BenchmarkSmallJSONFormatter(b *testing.B) { 75 | doBenchmark(b, &JSONFormatter{}, smallFields) 76 | } 77 | 78 | func BenchmarkLargeJSONFormatter(b *testing.B) { 79 | doBenchmark(b, &JSONFormatter{}, largeFields) 80 | } 81 | 82 | func doBenchmark(b *testing.B, formatter Formatter, fields Fields) { 83 | entry := &Entry{ 84 | Time: time.Time{}, 85 | Level: InfoLevel, 86 | Message: "message", 87 | Data: fields, 88 | } 89 | var d []byte 90 | var err error 91 | for i := 0; i < b.N; i++ { 92 | d, err = formatter.Format(entry) 93 | if err != nil { 94 | b.Fatal(err) 95 | } 96 | b.SetBytes(int64(len(d))) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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/external/github.com/Sirupsen/logrus/terminal_bsd.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd openbsd netbsd dragonfly 2 | 3 | package logrus 4 | 5 | import "syscall" 6 | 7 | const ioctlReadTermios = syscall.TIOCGETA 8 | 9 | type Termios syscall.Termios 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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 netbsd dragonfly 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/external/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/external/github.com/Sirupsen/logrus/text_formatter_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestQuoting(t *testing.T) { 11 | tf := &TextFormatter{DisableColors: true} 12 | 13 | checkQuoting := func(q bool, value interface{}) { 14 | b, _ := tf.Format(WithField("test", value)) 15 | idx := bytes.Index(b, ([]byte)("test=")) 16 | cont := bytes.Contains(b[idx+5:], []byte{'"'}) 17 | if cont != q { 18 | if q { 19 | t.Errorf("quoting expected for: %#v", value) 20 | } else { 21 | t.Errorf("quoting not expected for: %#v", value) 22 | } 23 | } 24 | } 25 | 26 | checkQuoting(false, "abcd") 27 | checkQuoting(false, "v1.0") 28 | checkQuoting(false, "1234567890") 29 | checkQuoting(true, "/foobar") 30 | checkQuoting(true, "x y") 31 | checkQuoting(true, "x,y") 32 | checkQuoting(false, errors.New("invalid")) 33 | checkQuoting(true, errors.New("invalid argument")) 34 | } 35 | 36 | func TestTimestampFormat(t *testing.T) { 37 | checkTimeStr := func(format string) { 38 | customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format} 39 | customStr, _ := customFormatter.Format(WithField("test", "test")) 40 | timeStart := bytes.Index(customStr, ([]byte)("time=")) 41 | timeEnd := bytes.Index(customStr, ([]byte)("level=")) 42 | timeStr := customStr[timeStart+5 : timeEnd-1] 43 | if timeStr[0] == '"' && timeStr[len(timeStr)-1] == '"' { 44 | timeStr = timeStr[1 : len(timeStr)-1] 45 | } 46 | if format == "" { 47 | format = time.RFC3339 48 | } 49 | _, e := time.Parse(format, (string)(timeStr)) 50 | if e != nil { 51 | t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e) 52 | } 53 | } 54 | 55 | checkTimeStr("2006-01-02T15:04:05.000000000Z07:00") 56 | checkTimeStr("Mon Jan _2 15:04:05 2006") 57 | checkTimeStr("") 58 | } 59 | 60 | // TODO add tests for sorting etc., this requires a parser for the text 61 | // formatter output. 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/github.com/docker/distribution/registry/api/errcode/handler.go: -------------------------------------------------------------------------------- 1 | package errcode 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | // ServeJSON attempts to serve the errcode in a JSON envelope. It marshals err 9 | // and sets the content-type header to 'application/json'. It will handle 10 | // ErrorCoder and Errors, and if necessary will create an envelope. 11 | func ServeJSON(w http.ResponseWriter, err error) error { 12 | w.Header().Set("Content-Type", "application/json; charset=utf-8") 13 | var sc int 14 | 15 | switch errs := err.(type) { 16 | case Errors: 17 | if len(errs) < 1 { 18 | break 19 | } 20 | 21 | if err, ok := errs[0].(ErrorCoder); ok { 22 | sc = err.ErrorCode().Descriptor().HTTPStatusCode 23 | } 24 | case ErrorCoder: 25 | sc = errs.ErrorCode().Descriptor().HTTPStatusCode 26 | err = Errors{err} // create an envelope. 27 | default: 28 | // We just have an unhandled error type, so just place in an envelope 29 | // and move along. 30 | err = Errors{err} 31 | } 32 | 33 | if sc == 0 { 34 | sc = http.StatusInternalServerError 35 | } 36 | 37 | w.WriteHeader(sc) 38 | 39 | if err := json.NewEncoder(w).Encode(err); err != nil { 40 | return err 41 | } 42 | 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/errors/README.md: -------------------------------------------------------------------------------- 1 | Docker 'errors' package 2 | ======================= 3 | 4 | This package contains all of the error messages generated by the Docker 5 | engine that might be exposed via the Docker engine's REST API. 6 | 7 | Each top-level engine package will have its own file in this directory 8 | so that there's a clear grouping of errors, instead of just one big 9 | file. The errors for each package are defined here instead of within 10 | their respective package structure so that Docker CLI code that may need 11 | to import these error definition files will not need to know or understand 12 | the engine's package/directory structure. In other words, all they should 13 | need to do is import `.../docker/errors` and they will automatically 14 | pick up all Docker engine defined errors. This also gives the engine 15 | developers the freedom to change the engine packaging structure (e.g. to 16 | CRUD packages) without worrying about breaking existing clients. 17 | 18 | These errors are defined using the 'errcode' package. The `errcode` package 19 | allows for each error to be typed and include all information necessary to 20 | have further processing done on them if necessary. In particular, each error 21 | includes: 22 | 23 | * Value - a unique string (in all caps) associated with this error. 24 | Typically, this string is the same name as the variable name of the error 25 | (w/o the `ErrorCode` text) but in all caps. 26 | 27 | * Message - the human readable sentence that will be displayed for this 28 | error. It can contain '%s' substitutions that allows for the code generating 29 | the error to specify values that will be inserted in the string prior to 30 | being displayed to the end-user. The `WithArgs()` function can be used to 31 | specify the insertion strings. Note, the evaluation of the strings will be 32 | done at the time `WithArgs()` is called. 33 | 34 | * Description - additional human readable text to further explain the 35 | circumstances of the error situation. 36 | 37 | * HTTPStatusCode - when the error is returned back to a CLI, this value 38 | will be used to populate the HTTP status code. If not present the default 39 | value will be `StatusInternalServerError`, 500. 40 | 41 | Not all errors generated within the engine's executable will be propagated 42 | back to the engine's API layer. For example, it is expected that errors 43 | generated by vendored code (under `docker/vendor`) and packaged code 44 | (under `docker/pkg`) will be converted into errors defined by this package. 45 | 46 | When processing an errcode error, if you are looking for a particular 47 | error then you can do something like: 48 | 49 | ``` 50 | import derr "github.com/docker/docker/errors" 51 | 52 | ... 53 | 54 | err := someFunc() 55 | if err.ErrorCode() == derr.ErrorCodeNoSuchContainer { 56 | ... 57 | } 58 | ``` 59 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/errors/error.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | // This file contains all of the errors that can be generated from the 4 | // docker engine but are not tied to any specific top-level component. 5 | 6 | const errGroup = "engine" 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/errors/image.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | // This file contains all of the errors that can be generated from the 4 | // docker/image component. 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/fsouza/go-dockerclient/external/github.com/docker/distribution/registry/api/errcode" 10 | ) 11 | 12 | var ( 13 | // ErrorCodeInvalidImageID is generated when image id specified is incorrectly formatted. 14 | ErrorCodeInvalidImageID = errcode.Register(errGroup, errcode.ErrorDescriptor{ 15 | Value: "INVALIDIMAGEID", 16 | Message: "image ID '%s' is invalid ", 17 | Description: "The specified image id is incorrectly formatted", 18 | HTTPStatusCode: http.StatusInternalServerError, 19 | }) 20 | ) 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/errors/server.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/fsouza/go-dockerclient/external/github.com/docker/distribution/registry/api/errcode" 7 | ) 8 | 9 | var ( 10 | // ErrorCodeNewerClientVersion is generated when a request from a client 11 | // specifies a higher version than the server supports. 12 | ErrorCodeNewerClientVersion = errcode.Register(errGroup, errcode.ErrorDescriptor{ 13 | Value: "NEWERCLIENTVERSION", 14 | Message: "client is newer than server (client API version: %s, server API version: %s)", 15 | Description: "The client version is higher than the server version", 16 | HTTPStatusCode: http.StatusBadRequest, 17 | }) 18 | 19 | // ErrorCodeOldClientVersion is generated when a request from a client 20 | // specifies a version lower than the minimum version supported by the server. 21 | ErrorCodeOldClientVersion = errcode.Register(errGroup, errcode.ErrorDescriptor{ 22 | Value: "OLDCLIENTVERSION", 23 | Message: "client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", 24 | Description: "The client version is too old for the server", 25 | HTTPStatusCode: http.StatusBadRequest, 26 | }) 27 | 28 | // ErrorNetworkControllerNotEnabled is generated when the networking stack in not enabled 29 | // for certain platforms, like windows. 30 | ErrorNetworkControllerNotEnabled = errcode.Register(errGroup, errcode.ErrorDescriptor{ 31 | Value: "NETWORK_CONTROLLER_NOT_ENABLED", 32 | Message: "the network controller is not enabled for this platform", 33 | Description: "Docker's networking stack is disabled for this platform", 34 | HTTPStatusCode: http.StatusNotFound, 35 | }) 36 | ) 37 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts/envfile.go: -------------------------------------------------------------------------------- 1 | package opts 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | // ParseEnvFile reads a file with environment variables enumerated by lines 11 | // 12 | // ``Environment variable names used by the utilities in the Shell and 13 | // Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase 14 | // letters, digits, and the '_' (underscore) from the characters defined in 15 | // Portable Character Set and do not begin with a digit. *But*, other 16 | // characters may be permitted by an implementation; applications shall 17 | // tolerate the presence of such names.'' 18 | // -- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html 19 | // 20 | // As of #16585, it's up to application inside docker to validate or not 21 | // environment variables, that's why we just strip leading whitespace and 22 | // nothing more. 23 | func ParseEnvFile(filename string) ([]string, error) { 24 | fh, err := os.Open(filename) 25 | if err != nil { 26 | return []string{}, err 27 | } 28 | defer fh.Close() 29 | 30 | lines := []string{} 31 | scanner := bufio.NewScanner(fh) 32 | for scanner.Scan() { 33 | // trim the line from all leading whitespace first 34 | line := strings.TrimLeft(scanner.Text(), whiteSpaces) 35 | // line is not empty, and not starting with '#' 36 | if len(line) > 0 && !strings.HasPrefix(line, "#") { 37 | data := strings.SplitN(line, "=", 2) 38 | 39 | // trim the front of a variable, but nothing else 40 | variable := strings.TrimLeft(data[0], whiteSpaces) 41 | if strings.ContainsAny(variable, whiteSpaces) { 42 | return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' has white spaces", variable)} 43 | } 44 | 45 | if len(data) > 1 { 46 | 47 | // pass the value through, no trimming 48 | lines = append(lines, fmt.Sprintf("%s=%s", variable, data[1])) 49 | } else { 50 | // if only a pass-through variable is given, clean it up. 51 | lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), os.Getenv(line))) 52 | } 53 | } 54 | } 55 | return lines, scanner.Err() 56 | } 57 | 58 | var whiteSpaces = " \t" 59 | 60 | // ErrBadEnvVariable typed error for bad environment variable 61 | type ErrBadEnvVariable struct { 62 | msg string 63 | } 64 | 65 | func (e ErrBadEnvVariable) Error() string { 66 | return fmt.Sprintf("poorly formatted environment: %s", e.msg) 67 | } 68 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts/hosts_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package opts 4 | 5 | import "fmt" 6 | 7 | // DefaultHost constant defines the default host string used by docker on other hosts than Windows 8 | var DefaultHost = fmt.Sprintf("unix://%s", DefaultUnixSocket) 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts/hosts_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package opts 4 | 5 | // DefaultHost constant defines the default host string used by docker on Windows 6 | var DefaultHost = DefaultTCPHost 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts/ip.go: -------------------------------------------------------------------------------- 1 | package opts 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | // IPOpt holds an IP. It is used to store values from CLI flags. 9 | type IPOpt struct { 10 | *net.IP 11 | } 12 | 13 | // NewIPOpt creates a new IPOpt from a reference net.IP and a 14 | // string representation of an IP. If the string is not a valid 15 | // IP it will fallback to the specified reference. 16 | func NewIPOpt(ref *net.IP, defaultVal string) *IPOpt { 17 | o := &IPOpt{ 18 | IP: ref, 19 | } 20 | o.Set(defaultVal) 21 | return o 22 | } 23 | 24 | // Set sets an IPv4 or IPv6 address from a given string. If the given 25 | // string is not parsable as an IP address it returns an error. 26 | func (o *IPOpt) Set(val string) error { 27 | ip := net.ParseIP(val) 28 | if ip == nil { 29 | return fmt.Errorf("%s is not an ip address", val) 30 | } 31 | *o.IP = ip 32 | return nil 33 | } 34 | 35 | // String returns the IP address stored in the IPOpt. If stored IP is a 36 | // nil pointer, it returns an empty string. 37 | func (o *IPOpt) String() string { 38 | if *o.IP == nil { 39 | return "" 40 | } 41 | return o.IP.String() 42 | } 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts/ip_test.go: -------------------------------------------------------------------------------- 1 | package opts 2 | 3 | import ( 4 | "net" 5 | "testing" 6 | ) 7 | 8 | func TestIpOptString(t *testing.T) { 9 | addresses := []string{"", "0.0.0.0"} 10 | var ip net.IP 11 | 12 | for _, address := range addresses { 13 | stringAddress := NewIPOpt(&ip, address).String() 14 | if stringAddress != address { 15 | t.Fatalf("IpOpt string should be `%s`, not `%s`", address, stringAddress) 16 | } 17 | } 18 | } 19 | 20 | func TestNewIpOptInvalidDefaultVal(t *testing.T) { 21 | ip := net.IPv4(127, 0, 0, 1) 22 | defaultVal := "Not an ip" 23 | 24 | ipOpt := NewIPOpt(&ip, defaultVal) 25 | 26 | expected := "127.0.0.1" 27 | if ipOpt.String() != expected { 28 | t.Fatalf("Expected [%v], got [%v]", expected, ipOpt.String()) 29 | } 30 | } 31 | 32 | func TestNewIpOptValidDefaultVal(t *testing.T) { 33 | ip := net.IPv4(127, 0, 0, 1) 34 | defaultVal := "192.168.1.1" 35 | 36 | ipOpt := NewIPOpt(&ip, defaultVal) 37 | 38 | expected := "192.168.1.1" 39 | if ipOpt.String() != expected { 40 | t.Fatalf("Expected [%v], got [%v]", expected, ipOpt.String()) 41 | } 42 | } 43 | 44 | func TestIpOptSetInvalidVal(t *testing.T) { 45 | ip := net.IPv4(127, 0, 0, 1) 46 | ipOpt := &IPOpt{IP: &ip} 47 | 48 | invalidIP := "invalid ip" 49 | expectedError := "invalid ip is not an ip address" 50 | err := ipOpt.Set(invalidIP) 51 | if err == nil || err.Error() != expectedError { 52 | t.Fatalf("Expected an Error with [%v], got [%v]", expectedError, err.Error()) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts/ulimit.go: -------------------------------------------------------------------------------- 1 | package opts 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ulimit" 7 | ) 8 | 9 | // UlimitOpt defines a map of Ulimits 10 | type UlimitOpt struct { 11 | values *map[string]*ulimit.Ulimit 12 | } 13 | 14 | // NewUlimitOpt creates a new UlimitOpt 15 | func NewUlimitOpt(ref *map[string]*ulimit.Ulimit) *UlimitOpt { 16 | if ref == nil { 17 | ref = &map[string]*ulimit.Ulimit{} 18 | } 19 | return &UlimitOpt{ref} 20 | } 21 | 22 | // Set validates a Ulimit and sets its name as a key in UlimitOpt 23 | func (o *UlimitOpt) Set(val string) error { 24 | l, err := ulimit.Parse(val) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | (*o.values)[l.Name] = l 30 | 31 | return nil 32 | } 33 | 34 | // String returns Ulimit values as a string. 35 | func (o *UlimitOpt) String() string { 36 | var out []string 37 | for _, v := range *o.values { 38 | out = append(out, v.String()) 39 | } 40 | 41 | return fmt.Sprintf("%v", out) 42 | } 43 | 44 | // GetList returns a slice of pointers to Ulimits. 45 | func (o *UlimitOpt) GetList() []*ulimit.Ulimit { 46 | var ulimits []*ulimit.Ulimit 47 | for _, v := range *o.values { 48 | ulimits = append(ulimits, v) 49 | } 50 | 51 | return ulimits 52 | } 53 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/opts/ulimit_test.go: -------------------------------------------------------------------------------- 1 | package opts 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ulimit" 7 | ) 8 | 9 | func TestUlimitOpt(t *testing.T) { 10 | ulimitMap := map[string]*ulimit.Ulimit{ 11 | "nofile": {"nofile", 1024, 512}, 12 | } 13 | 14 | ulimitOpt := NewUlimitOpt(&ulimitMap) 15 | 16 | expected := "[nofile=512:1024]" 17 | if ulimitOpt.String() != expected { 18 | t.Fatalf("Expected %v, got %v", expected, ulimitOpt) 19 | } 20 | 21 | // Valid ulimit append to opts 22 | if err := ulimitOpt.Set("core=1024:1024"); err != nil { 23 | t.Fatal(err) 24 | } 25 | 26 | // Invalid ulimit type returns an error and do not append to opts 27 | if err := ulimitOpt.Set("notavalidtype=1024:1024"); err == nil { 28 | t.Fatalf("Expected error on invalid ulimit type") 29 | } 30 | expected = "[nofile=512:1024 core=1024:1024]" 31 | expected2 := "[core=1024:1024 nofile=512:1024]" 32 | result := ulimitOpt.String() 33 | if result != expected && result != expected2 { 34 | t.Fatalf("Expected %v or %v, got %v", expected, expected2, ulimitOpt) 35 | } 36 | 37 | // And test GetList 38 | ulimits := ulimitOpt.GetList() 39 | if len(ulimits) != 2 { 40 | t.Fatalf("Expected a ulimit list of 2, got %v", ulimits) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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/external/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 | "path/filepath" 10 | "strings" 11 | 12 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/longpath" 13 | ) 14 | 15 | // fixVolumePathPrefix does platform specific processing to ensure that if 16 | // the path being passed in is not in a volume path format, convert it to one. 17 | func fixVolumePathPrefix(srcPath string) string { 18 | return longpath.AddPrefix(srcPath) 19 | } 20 | 21 | // getWalkRoot calculates the root path when performing a TarWithOptions. 22 | // We use a seperate function as this is platform specific. 23 | func getWalkRoot(srcPath string, include string) string { 24 | return filepath.Join(srcPath, include) 25 | } 26 | 27 | // CanonicalTarNameForPath returns platform-specific filepath 28 | // to canonical posix-style path for tar archival. p is relative 29 | // path. 30 | func CanonicalTarNameForPath(p string) (string, error) { 31 | // windows: convert windows style relative path with backslashes 32 | // into forward slashes. Since windows does not allow '/' or '\' 33 | // in file names, it is mostly safe to replace however we must 34 | // check just in case 35 | if strings.Contains(p, "/") { 36 | return "", fmt.Errorf("Windows path contains forward slash: %s", p) 37 | } 38 | return strings.Replace(p, string(os.PathSeparator), "/", -1), nil 39 | 40 | } 41 | 42 | // chmodTarEntry is used to adjust the file permissions used in tar header based 43 | // on the platform the archival is done. 44 | func chmodTarEntry(perm os.FileMode) os.FileMode { 45 | perm &= 0755 46 | // Add the x bit: make everything +x from windows 47 | perm |= 0111 48 | 49 | return perm 50 | } 51 | 52 | func setHeaderForSpecialDevice(hdr *tar.Header, ta *tarAppender, name string, stat interface{}) (inode uint64, err error) { 53 | // do nothing. no notion of Rdev, Inode, Nlink in stat on Windows 54 | return 55 | } 56 | 57 | // handleTarTypeBlockCharFifo is an OS-specific helper function used by 58 | // createTarFile to handle the following types of header: Block; Char; Fifo 59 | func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { 60 | return nil 61 | } 62 | 63 | func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error { 64 | return nil 65 | } 66 | 67 | func getFileUIDGID(stat interface{}) (int, int, error) { 68 | // no notion of file ownership mapping yet on Windows 69 | return 0, 0, nil 70 | } 71 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/archive_windows_test.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package archive 4 | 5 | import ( 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | "testing" 10 | ) 11 | 12 | func TestCopyFileWithInvalidDest(t *testing.T) { 13 | folder, err := ioutil.TempDir("", "docker-archive-test") 14 | if err != nil { 15 | t.Fatal(err) 16 | } 17 | defer os.RemoveAll(folder) 18 | dest := "c:dest" 19 | srcFolder := filepath.Join(folder, "src") 20 | src := filepath.Join(folder, "src", "src") 21 | err = os.MkdirAll(srcFolder, 0740) 22 | if err != nil { 23 | t.Fatal(err) 24 | } 25 | ioutil.WriteFile(src, []byte("content"), 0777) 26 | err = CopyWithTar(src, dest) 27 | if err == nil { 28 | t.Fatalf("archiver.CopyWithTar should throw an error on invalid dest.") 29 | } 30 | } 31 | 32 | func TestCanonicalTarNameForPath(t *testing.T) { 33 | cases := []struct { 34 | in, expected string 35 | shouldFail bool 36 | }{ 37 | {"foo", "foo", false}, 38 | {"foo/bar", "___", true}, // unix-styled windows path must fail 39 | {`foo\bar`, "foo/bar", false}, 40 | } 41 | for _, v := range cases { 42 | if out, err := CanonicalTarNameForPath(v.in); err != nil && !v.shouldFail { 43 | t.Fatalf("cannot get canonical name for path: %s: %v", v.in, err) 44 | } else if v.shouldFail && err == nil { 45 | t.Fatalf("canonical path call should have failed with error. in=%s out=%s", v.in, out) 46 | } else if !v.shouldFail && out != v.expected { 47 | t.Fatalf("wrong canonical tar name. expected:%s got:%s", v.expected, out) 48 | } 49 | } 50 | } 51 | 52 | func TestCanonicalTarName(t *testing.T) { 53 | cases := []struct { 54 | in string 55 | isDir bool 56 | expected string 57 | }{ 58 | {"foo", false, "foo"}, 59 | {"foo", true, "foo/"}, 60 | {`foo\bar`, false, "foo/bar"}, 61 | {`foo\bar`, true, "foo/bar/"}, 62 | } 63 | for _, v := range cases { 64 | if out, err := canonicalTarName(v.in, v.isDir); err != nil { 65 | t.Fatalf("cannot get canonical name for path: %s: %v", v.in, err) 66 | } else if out != v.expected { 67 | t.Fatalf("wrong canonical tar name. expected:%s got:%s", v.expected, out) 68 | } 69 | } 70 | } 71 | 72 | func TestChmodTarEntry(t *testing.T) { 73 | cases := []struct { 74 | in, expected os.FileMode 75 | }{ 76 | {0000, 0111}, 77 | {0777, 0755}, 78 | {0644, 0755}, 79 | {0755, 0755}, 80 | {0444, 0555}, 81 | } 82 | for _, v := range cases { 83 | if out := chmodTarEntry(v.in); out != v.expected { 84 | t.Fatalf("wrong chmod. expected:%v got:%v", v.expected, out) 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/changes_other.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package archive 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | "path/filepath" 9 | "runtime" 10 | "strings" 11 | 12 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system" 13 | ) 14 | 15 | func collectFileInfoForChanges(oldDir, newDir string) (*FileInfo, *FileInfo, error) { 16 | var ( 17 | oldRoot, newRoot *FileInfo 18 | err1, err2 error 19 | errs = make(chan error, 2) 20 | ) 21 | go func() { 22 | oldRoot, err1 = collectFileInfo(oldDir) 23 | errs <- err1 24 | }() 25 | go func() { 26 | newRoot, err2 = collectFileInfo(newDir) 27 | errs <- err2 28 | }() 29 | 30 | // block until both routines have returned 31 | for i := 0; i < 2; i++ { 32 | if err := <-errs; err != nil { 33 | return nil, nil, err 34 | } 35 | } 36 | 37 | return oldRoot, newRoot, nil 38 | } 39 | 40 | func collectFileInfo(sourceDir string) (*FileInfo, error) { 41 | root := newRootFileInfo() 42 | 43 | err := filepath.Walk(sourceDir, func(path string, f os.FileInfo, err error) error { 44 | if err != nil { 45 | return err 46 | } 47 | 48 | // Rebase path 49 | relPath, err := filepath.Rel(sourceDir, path) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | // As this runs on the daemon side, file paths are OS specific. 55 | relPath = filepath.Join(string(os.PathSeparator), relPath) 56 | 57 | // See https://github.com/golang/go/issues/9168 - bug in filepath.Join. 58 | // Temporary workaround. If the returned path starts with two backslashes, 59 | // trim it down to a single backslash. Only relevant on Windows. 60 | if runtime.GOOS == "windows" { 61 | if strings.HasPrefix(relPath, `\\`) { 62 | relPath = relPath[1:] 63 | } 64 | } 65 | 66 | if relPath == string(os.PathSeparator) { 67 | return nil 68 | } 69 | 70 | parent := root.LookUp(filepath.Dir(relPath)) 71 | if parent == nil { 72 | return fmt.Errorf("collectFileInfo: Unexpectedly no parent for %s", relPath) 73 | } 74 | 75 | info := &FileInfo{ 76 | name: filepath.Base(relPath), 77 | children: make(map[string]*FileInfo), 78 | parent: parent, 79 | } 80 | 81 | s, err := system.Lstat(path) 82 | if err != nil { 83 | return err 84 | } 85 | info.stat = s 86 | 87 | info.capability, _ = system.Lgetxattr(path, "security.capability") 88 | 89 | parent.children[info.name] = info 90 | 91 | return nil 92 | }) 93 | if err != nil { 94 | return nil, err 95 | } 96 | return root, nil 97 | } 98 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/changes_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package archive 4 | 5 | import ( 6 | "os" 7 | "syscall" 8 | 9 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system" 10 | ) 11 | 12 | func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool { 13 | // Don't look at size for dirs, its not a good measure of change 14 | if oldStat.Mode() != newStat.Mode() || 15 | oldStat.UID() != newStat.UID() || 16 | oldStat.GID() != newStat.GID() || 17 | oldStat.Rdev() != newStat.Rdev() || 18 | // Don't look at size for dirs, its not a good measure of change 19 | (oldStat.Mode()&syscall.S_IFDIR != syscall.S_IFDIR && 20 | (!sameFsTimeSpec(oldStat.Mtim(), newStat.Mtim()) || (oldStat.Size() != newStat.Size()))) { 21 | return true 22 | } 23 | return false 24 | } 25 | 26 | func (info *FileInfo) isDir() bool { 27 | return info.parent == nil || info.stat.Mode()&syscall.S_IFDIR != 0 28 | } 29 | 30 | func getIno(fi os.FileInfo) uint64 { 31 | return uint64(fi.Sys().(*syscall.Stat_t).Ino) 32 | } 33 | 34 | func hasHardlinks(fi os.FileInfo) bool { 35 | return fi.Sys().(*syscall.Stat_t).Nlink > 1 36 | } 37 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/changes_windows.go: -------------------------------------------------------------------------------- 1 | package archive 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system" 7 | ) 8 | 9 | func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool { 10 | 11 | // Don't look at size for dirs, its not a good measure of change 12 | if oldStat.ModTime() != newStat.ModTime() || 13 | oldStat.Mode() != newStat.Mode() || 14 | oldStat.Size() != newStat.Size() && !oldStat.IsDir() { 15 | return true 16 | } 17 | return false 18 | } 19 | 20 | func (info *FileInfo) isDir() bool { 21 | return info.parent == nil || info.stat.IsDir() 22 | } 23 | 24 | func getIno(fi os.FileInfo) (inode uint64) { 25 | return 26 | } 27 | 28 | func hasHardlinks(fi os.FileInfo) bool { 29 | return false 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/copy_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package archive 4 | 5 | import ( 6 | "path/filepath" 7 | ) 8 | 9 | func normalizePath(path string) string { 10 | return filepath.ToSlash(path) 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/copy_windows.go: -------------------------------------------------------------------------------- 1 | package archive 2 | 3 | import ( 4 | "path/filepath" 5 | ) 6 | 7 | func normalizePath(path string) string { 8 | return filepath.FromSlash(path) 9 | } 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/example_changes.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | // Simple tool to create an archive stream from an old and new directory 4 | // 5 | // By default it will stream the comparison of two temporary directories with junk files 6 | package main 7 | 8 | import ( 9 | "flag" 10 | "fmt" 11 | "io" 12 | "io/ioutil" 13 | "os" 14 | "path" 15 | 16 | "github.com/fsouza/go-dockerclient/external/github.com/Sirupsen/logrus" 17 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive" 18 | ) 19 | 20 | var ( 21 | flDebug = flag.Bool("D", false, "debugging output") 22 | flNewDir = flag.String("newdir", "", "") 23 | flOldDir = flag.String("olddir", "", "") 24 | log = logrus.New() 25 | ) 26 | 27 | func main() { 28 | flag.Usage = func() { 29 | fmt.Println("Produce a tar from comparing two directory paths. By default a demo tar is created of around 200 files (including hardlinks)") 30 | fmt.Printf("%s [OPTIONS]\n", os.Args[0]) 31 | flag.PrintDefaults() 32 | } 33 | flag.Parse() 34 | log.Out = os.Stderr 35 | if (len(os.Getenv("DEBUG")) > 0) || *flDebug { 36 | logrus.SetLevel(logrus.DebugLevel) 37 | } 38 | var newDir, oldDir string 39 | 40 | if len(*flNewDir) == 0 { 41 | var err error 42 | newDir, err = ioutil.TempDir("", "docker-test-newDir") 43 | if err != nil { 44 | log.Fatal(err) 45 | } 46 | defer os.RemoveAll(newDir) 47 | if _, err := prepareUntarSourceDirectory(100, newDir, true); err != nil { 48 | log.Fatal(err) 49 | } 50 | } else { 51 | newDir = *flNewDir 52 | } 53 | 54 | if len(*flOldDir) == 0 { 55 | oldDir, err := ioutil.TempDir("", "docker-test-oldDir") 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | defer os.RemoveAll(oldDir) 60 | } else { 61 | oldDir = *flOldDir 62 | } 63 | 64 | changes, err := archive.ChangesDirs(newDir, oldDir) 65 | if err != nil { 66 | log.Fatal(err) 67 | } 68 | 69 | a, err := archive.ExportChanges(newDir, changes) 70 | if err != nil { 71 | log.Fatal(err) 72 | } 73 | defer a.Close() 74 | 75 | i, err := io.Copy(os.Stdout, a) 76 | if err != nil && err != io.EOF { 77 | log.Fatal(err) 78 | } 79 | fmt.Fprintf(os.Stderr, "wrote archive of %d bytes", i) 80 | } 81 | 82 | func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) { 83 | fileData := []byte("fooo") 84 | for n := 0; n < numberOfFiles; n++ { 85 | fileName := fmt.Sprintf("file-%d", n) 86 | if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil { 87 | return 0, err 88 | } 89 | if makeLinks { 90 | if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil { 91 | return 0, err 92 | } 93 | } 94 | } 95 | totalSize := numberOfFiles * len(fileData) 96 | return totalSize, nil 97 | } 98 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/testdata/broken.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudnautique/vol-cleanup/fe95cff5cd9a5650e3dfc6309e5af8e20f6ddaa6/Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/archive/testdata/broken.tar -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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/external/github.com/docker/docker/pkg/archive/whiteouts.go: -------------------------------------------------------------------------------- 1 | package archive 2 | 3 | // Whiteouts are files with a special meaning for the layered filesystem. 4 | // Docker uses AUFS whiteout files inside exported archives. In other 5 | // filesystems these files are generated/handled on tar creation/extraction. 6 | 7 | // WhiteoutPrefix prefix means file is a whiteout. If this is followed by a 8 | // filename this means that file has been removed from the base layer. 9 | const WhiteoutPrefix = ".wh." 10 | 11 | // WhiteoutMetaPrefix prefix means whiteout has a special meaning and is not 12 | // for remoing an actaul file. Normally these files are excluded from exported 13 | // archives. 14 | const WhiteoutMetaPrefix = WhiteoutPrefix + WhiteoutPrefix 15 | 16 | // WhiteoutLinkDir is a directory AUFS uses for storing hardlink links to other 17 | // layers. Normally these should not go into exported archives and all changed 18 | // hardlinks should be copied to the top layer. 19 | const WhiteoutLinkDir = WhiteoutMetaPrefix + "plnk" 20 | 21 | // WhiteoutOpaqueDir file means directory has been made opaque - meaning 22 | // readdir calls to this directory do not follow to lower layers. 23 | const WhiteoutOpaqueDir = WhiteoutMetaPrefix + ".opq" 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/github.com/docker/docker/pkg/archive/wrap_test.go: -------------------------------------------------------------------------------- 1 | package archive 2 | 3 | import ( 4 | "archive/tar" 5 | "bytes" 6 | "io" 7 | "testing" 8 | ) 9 | 10 | func TestGenerateEmptyFile(t *testing.T) { 11 | archive, err := Generate("emptyFile") 12 | if err != nil { 13 | t.Fatal(err) 14 | } 15 | if archive == nil { 16 | t.Fatal("The generated archive should not be nil.") 17 | } 18 | 19 | expectedFiles := [][]string{ 20 | {"emptyFile", ""}, 21 | } 22 | 23 | tr := tar.NewReader(archive) 24 | actualFiles := make([][]string, 0, 10) 25 | i := 0 26 | for { 27 | hdr, err := tr.Next() 28 | if err == io.EOF { 29 | break 30 | } 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | buf := new(bytes.Buffer) 35 | buf.ReadFrom(tr) 36 | content := buf.String() 37 | actualFiles = append(actualFiles, []string{hdr.Name, content}) 38 | i++ 39 | } 40 | if len(actualFiles) != len(expectedFiles) { 41 | t.Fatalf("Number of expected file %d, got %d.", len(expectedFiles), len(actualFiles)) 42 | } 43 | for i := 0; i < len(expectedFiles); i++ { 44 | actual := actualFiles[i] 45 | expected := expectedFiles[i] 46 | if actual[0] != expected[0] { 47 | t.Fatalf("Expected name '%s', Actual name '%s'", expected[0], actual[0]) 48 | } 49 | if actual[1] != expected[1] { 50 | t.Fatalf("Expected content '%s', Actual content '%s'", expected[1], actual[1]) 51 | } 52 | } 53 | } 54 | 55 | func TestGenerateWithContent(t *testing.T) { 56 | archive, err := Generate("file", "content") 57 | if err != nil { 58 | t.Fatal(err) 59 | } 60 | if archive == nil { 61 | t.Fatal("The generated archive should not be nil.") 62 | } 63 | 64 | expectedFiles := [][]string{ 65 | {"file", "content"}, 66 | } 67 | 68 | tr := tar.NewReader(archive) 69 | actualFiles := make([][]string, 0, 10) 70 | i := 0 71 | for { 72 | hdr, err := tr.Next() 73 | if err == io.EOF { 74 | break 75 | } 76 | if err != nil { 77 | t.Fatal(err) 78 | } 79 | buf := new(bytes.Buffer) 80 | buf.ReadFrom(tr) 81 | content := buf.String() 82 | actualFiles = append(actualFiles, []string{hdr.Name, content}) 83 | i++ 84 | } 85 | if len(actualFiles) != len(expectedFiles) { 86 | t.Fatalf("Number of expected file %d, got %d.", len(expectedFiles), len(actualFiles)) 87 | } 88 | for i := 0; i < len(expectedFiles); i++ { 89 | actual := actualFiles[i] 90 | expected := expectedFiles[i] 91 | if actual[0] != expected[0] { 92 | t.Fatalf("Expected name '%s', Actual name '%s'", expected[0], actual[0]) 93 | } 94 | if actual[1] != expected[1] { 95 | t.Fatalf("Expected content '%s', Actual content '%s'", expected[1], actual[1]) 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/fileutils/fileutils_unix.go: -------------------------------------------------------------------------------- 1 | // +build linux freebsd 2 | 3 | package fileutils 4 | 5 | import ( 6 | "fmt" 7 | "io/ioutil" 8 | "os" 9 | 10 | "github.com/fsouza/go-dockerclient/external/github.com/Sirupsen/logrus" 11 | ) 12 | 13 | // GetTotalUsedFds Returns the number of used File Descriptors by 14 | // reading it via /proc filesystem. 15 | func GetTotalUsedFds() int { 16 | if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { 17 | logrus.Errorf("Error opening /proc/%d/fd: %s", os.Getpid(), err) 18 | } else { 19 | return len(fds) 20 | } 21 | return -1 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/fileutils/fileutils_windows.go: -------------------------------------------------------------------------------- 1 | package fileutils 2 | 3 | // GetTotalUsedFds Returns the number of used File Descriptors. Not supported 4 | // on Windows. 5 | func GetTotalUsedFds() int { 6 | return -1 7 | } 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/homedir/homedir.go: -------------------------------------------------------------------------------- 1 | package homedir 2 | 3 | import ( 4 | "os" 5 | "runtime" 6 | 7 | "github.com/fsouza/go-dockerclient/external/github.com/opencontainers/runc/libcontainer/user" 8 | ) 9 | 10 | // Key returns the env var name for the user's home dir based on 11 | // the platform being run on 12 | func Key() string { 13 | if runtime.GOOS == "windows" { 14 | return "USERPROFILE" 15 | } 16 | return "HOME" 17 | } 18 | 19 | // Get returns the home directory of the current user with the help of 20 | // environment variables depending on the target operating system. 21 | // Returned path should be used with "path/filepath" to form new paths. 22 | func Get() string { 23 | home := os.Getenv(Key()) 24 | if home == "" && runtime.GOOS != "windows" { 25 | if u, err := user.CurrentUser(); err == nil { 26 | return u.Home 27 | } 28 | } 29 | return home 30 | } 31 | 32 | // GetShortcutString returns the string that is shortcut to user's home directory 33 | // in the native shell of the platform running on. 34 | func GetShortcutString() string { 35 | if runtime.GOOS == "windows" { 36 | return "%USERPROFILE%" // be careful while using in format functions 37 | } 38 | return "~" 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/homedir/homedir_test.go: -------------------------------------------------------------------------------- 1 | package homedir 2 | 3 | import ( 4 | "path/filepath" 5 | "testing" 6 | ) 7 | 8 | func TestGet(t *testing.T) { 9 | home := Get() 10 | if home == "" { 11 | t.Fatal("returned home directory is empty") 12 | } 13 | 14 | if !filepath.IsAbs(home) { 15 | t.Fatalf("returned path is not absolute: %s", home) 16 | } 17 | } 18 | 19 | func TestGetShortcutString(t *testing.T) { 20 | shortcut := GetShortcutString() 21 | if shortcut == "" { 22 | t.Fatal("returned shortcut string is empty") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package idtools 4 | 5 | import ( 6 | "os" 7 | "path/filepath" 8 | 9 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system" 10 | ) 11 | 12 | func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error { 13 | // make an array containing the original path asked for, plus (for mkAll == true) 14 | // all path components leading up to the complete path that don't exist before we MkdirAll 15 | // so that we can chown all of them properly at the end. If chownExisting is false, we won't 16 | // chown the full directory path if it exists 17 | var paths []string 18 | if _, err := os.Stat(path); err != nil && os.IsNotExist(err) { 19 | paths = []string{path} 20 | } else if err == nil && chownExisting { 21 | if err := os.Chown(path, ownerUID, ownerGID); err != nil { 22 | return err 23 | } 24 | // short-circuit--we were called with an existing directory and chown was requested 25 | return nil 26 | } else if err == nil { 27 | // nothing to do; directory path fully exists already and chown was NOT requested 28 | return nil 29 | } 30 | 31 | if mkAll { 32 | // walk back to "/" looking for directories which do not exist 33 | // and add them to the paths array for chown after creation 34 | dirPath := path 35 | for { 36 | dirPath = filepath.Dir(dirPath) 37 | if dirPath == "/" { 38 | break 39 | } 40 | if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) { 41 | paths = append(paths, dirPath) 42 | } 43 | } 44 | if err := system.MkdirAll(path, mode); err != nil && !os.IsExist(err) { 45 | return err 46 | } 47 | } else { 48 | if err := os.Mkdir(path, mode); err != nil && !os.IsExist(err) { 49 | return err 50 | } 51 | } 52 | // even if it existed, we will chown the requested path + any subpaths that 53 | // didn't exist when we called MkdirAll 54 | for _, pathComponent := range paths { 55 | if err := os.Chown(pathComponent, ownerUID, ownerGID); err != nil { 56 | return err 57 | } 58 | } 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package idtools 4 | 5 | import ( 6 | "os" 7 | 8 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system" 9 | ) 10 | 11 | // Platforms such as Windows do not support the UID/GID concept. So make this 12 | // just a wrapper around system.MkdirAll. 13 | func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error { 14 | if err := system.MkdirAll(path, mode); err != nil && !os.IsExist(err) { 15 | return err 16 | } 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/usergroupadd_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package idtools 4 | 5 | import "fmt" 6 | 7 | // AddNamespaceRangesUser takes a name and finds an unused uid, gid pair 8 | // and calls the appropriate helper function to add the group and then 9 | // the user to the group in /etc/group and /etc/passwd respectively. 10 | func AddNamespaceRangesUser(name string) (int, int, error) { 11 | return -1, -1, fmt.Errorf("No support for adding users or groups on this OS") 12 | } 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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 | 16 | // FprintfIfTrue prints the boolean value if it's true 17 | func FprintfIfTrue(w io.Writer, format string, ok bool) (int, error) { 18 | if ok { 19 | return fmt.Fprintf(w, format, ok) 20 | } 21 | return 0, nil 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/github.com/docker/docker/pkg/ioutils/scheduler.go: -------------------------------------------------------------------------------- 1 | // +build !gccgo 2 | 3 | package ioutils 4 | 5 | func callSchedulerIfNecessary() { 6 | } 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ioutils/scheduler_gccgo.go: -------------------------------------------------------------------------------- 1 | // +build gccgo 2 | 3 | package ioutils 4 | 5 | import ( 6 | "runtime" 7 | ) 8 | 9 | func callSchedulerIfNecessary() { 10 | //allow or force Go scheduler to switch context, without explicitly 11 | //forcing this will make it hang when using gccgo implementation 12 | runtime.Gosched() 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ioutils/temp_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package ioutils 4 | 5 | import "io/ioutil" 6 | 7 | // TempDir on Unix systems is equivalent to ioutil.TempDir. 8 | func TempDir(dir, prefix string) (string, error) { 9 | return ioutil.TempDir(dir, prefix) 10 | } 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ioutils/temp_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package ioutils 4 | 5 | import ( 6 | "io/ioutil" 7 | 8 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/longpath" 9 | ) 10 | 11 | // TempDir is the equivalent of ioutil.TempDir, except that the result is in Windows longpath format. 12 | func TempDir(dir, prefix string) (string, error) { 13 | tempDir, err := ioutil.TempDir(dir, prefix) 14 | if err != nil { 15 | return "", err 16 | } 17 | return longpath.AddPrefix(tempDir), nil 18 | } 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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/external/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/external/github.com/docker/docker/pkg/longpath/longpath.go: -------------------------------------------------------------------------------- 1 | // longpath introduces some constants and helper functions for handling long paths 2 | // in Windows, which are expected to be prepended with `\\?\` and followed by either 3 | // a drive letter, a UNC server\share, or a volume identifier. 4 | 5 | package longpath 6 | 7 | import ( 8 | "strings" 9 | ) 10 | 11 | // Prefix is the longpath prefix for Windows file paths. 12 | const Prefix = `\\?\` 13 | 14 | // AddPrefix will add the Windows long path prefix to the path provided if 15 | // it does not already have it. 16 | func AddPrefix(path string) string { 17 | if !strings.HasPrefix(path, Prefix) { 18 | if strings.HasPrefix(path, `\\`) { 19 | // This is a UNC path, so we need to add 'UNC' to the path as well. 20 | path = Prefix + `UNC` + path[1:] 21 | } else { 22 | path = Prefix + path 23 | } 24 | } 25 | return path 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/longpath/longpath_test.go: -------------------------------------------------------------------------------- 1 | package longpath 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestStandardLongPath(t *testing.T) { 9 | c := `C:\simple\path` 10 | longC := AddPrefix(c) 11 | if !strings.EqualFold(longC, `\\?\C:\simple\path`) { 12 | t.Errorf("Wrong long path returned. Original = %s ; Long = %s", c, longC) 13 | } 14 | } 15 | 16 | func TestUNCLongPath(t *testing.T) { 17 | c := `\\server\share\path` 18 | longC := AddPrefix(c) 19 | if !strings.EqualFold(longC, `\\?\UNC\server\share\path`) { 20 | t.Errorf("Wrong UNC long path returned. Original = %s ; Long = %s", c, longC) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/mflag/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2015 The Docker & Go Authors. 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/external/github.com/docker/docker/pkg/mflag/README.md: -------------------------------------------------------------------------------- 1 | Package mflag (aka multiple-flag) implements command-line flag parsing. 2 | It's an **hacky** fork of the [official golang package](http://golang.org/pkg/flag/) 3 | 4 | It adds: 5 | 6 | * both short and long flag version 7 | `./example -s red` `./example --string blue` 8 | 9 | * multiple names for the same option 10 | ``` 11 | $>./example -h 12 | Usage of example: 13 | -s, --string="": a simple string 14 | ``` 15 | 16 | ___ 17 | It is very flexible on purpose, so you can do things like: 18 | ``` 19 | $>./example -h 20 | Usage of example: 21 | -s, -string, --string="": a simple string 22 | ``` 23 | 24 | Or: 25 | ``` 26 | $>./example -h 27 | Usage of example: 28 | -oldflag, --newflag="": a simple string 29 | ``` 30 | 31 | You can also hide some flags from the usage, so if we want only `--newflag`: 32 | ``` 33 | $>./example -h 34 | Usage of example: 35 | --newflag="": a simple string 36 | $>./example -oldflag str 37 | str 38 | ``` 39 | 40 | See [example.go](example/example.go) for more details. 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/github.com/docker/docker/pkg/system/chtimes.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "os" 5 | "time" 6 | ) 7 | 8 | // Chtimes changes the access time and modified time of a file at the given path 9 | func Chtimes(name string, atime time.Time, mtime time.Time) error { 10 | unixMinTime := time.Unix(0, 0) 11 | // The max Unix time is 33 bits set 12 | unixMaxTime := unixMinTime.Add((1<<33 - 1) * time.Second) 13 | 14 | // If the modified time is prior to the Unix Epoch, or after the 15 | // end of Unix Time, os.Chtimes has undefined behavior 16 | // default to Unix Epoch in this case, just in case 17 | 18 | if atime.Before(unixMinTime) || atime.After(unixMaxTime) { 19 | atime = unixMinTime 20 | } 21 | 22 | if mtime.Before(unixMinTime) || mtime.After(unixMaxTime) { 23 | mtime = unixMinTime 24 | } 25 | 26 | if err := os.Chtimes(name, atime, mtime); err != nil { 27 | return err 28 | } 29 | 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/errors.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | var ( 8 | // ErrNotSupportedPlatform means the platform is not supported. 9 | ErrNotSupportedPlatform = errors.New("platform and architecture is not supported") 10 | ) 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/events_windows.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | // This file implements syscalls for Win32 events which are not implemented 4 | // in golang. 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | var ( 12 | procCreateEvent = modkernel32.NewProc("CreateEventW") 13 | procOpenEvent = modkernel32.NewProc("OpenEventW") 14 | procSetEvent = modkernel32.NewProc("SetEvent") 15 | procResetEvent = modkernel32.NewProc("ResetEvent") 16 | procPulseEvent = modkernel32.NewProc("PulseEvent") 17 | ) 18 | 19 | // CreateEvent implements win32 CreateEventW func in golang. It will create an event object. 20 | func CreateEvent(eventAttributes *syscall.SecurityAttributes, manualReset bool, initialState bool, name string) (handle syscall.Handle, err error) { 21 | namep, _ := syscall.UTF16PtrFromString(name) 22 | var _p1 uint32 23 | if manualReset { 24 | _p1 = 1 25 | } 26 | var _p2 uint32 27 | if initialState { 28 | _p2 = 1 29 | } 30 | r0, _, e1 := procCreateEvent.Call(uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(namep))) 31 | use(unsafe.Pointer(namep)) 32 | handle = syscall.Handle(r0) 33 | if handle == syscall.InvalidHandle { 34 | err = e1 35 | } 36 | return 37 | } 38 | 39 | // OpenEvent implements win32 OpenEventW func in golang. It opens an event object. 40 | func OpenEvent(desiredAccess uint32, inheritHandle bool, name string) (handle syscall.Handle, err error) { 41 | namep, _ := syscall.UTF16PtrFromString(name) 42 | var _p1 uint32 43 | if inheritHandle { 44 | _p1 = 1 45 | } 46 | r0, _, e1 := procOpenEvent.Call(uintptr(desiredAccess), uintptr(_p1), uintptr(unsafe.Pointer(namep))) 47 | use(unsafe.Pointer(namep)) 48 | handle = syscall.Handle(r0) 49 | if handle == syscall.InvalidHandle { 50 | err = e1 51 | } 52 | return 53 | } 54 | 55 | // SetEvent implements win32 SetEvent func in golang. 56 | func SetEvent(handle syscall.Handle) (err error) { 57 | return setResetPulse(handle, procSetEvent) 58 | } 59 | 60 | // ResetEvent implements win32 ResetEvent func in golang. 61 | func ResetEvent(handle syscall.Handle) (err error) { 62 | return setResetPulse(handle, procResetEvent) 63 | } 64 | 65 | // PulseEvent implements win32 PulseEvent func in golang. 66 | func PulseEvent(handle syscall.Handle) (err error) { 67 | return setResetPulse(handle, procPulseEvent) 68 | } 69 | 70 | func setResetPulse(handle syscall.Handle, proc *syscall.LazyProc) (err error) { 71 | r0, _, _ := proc.Call(uintptr(handle)) 72 | if r0 != 0 { 73 | err = syscall.Errno(r0) 74 | } 75 | return 76 | } 77 | 78 | var temp unsafe.Pointer 79 | 80 | // use ensures a variable is kept alive without the GC freeing while still needed 81 | func use(p unsafe.Pointer) { 82 | temp = p 83 | } 84 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/filesys.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | // MkdirAll creates a directory named path along with any necessary parents, 11 | // with permission specified by attribute perm for all dir created. 12 | func MkdirAll(path string, perm os.FileMode) error { 13 | return os.MkdirAll(path, perm) 14 | } 15 | 16 | // IsAbs is a platform-specific wrapper for filepath.IsAbs. 17 | func IsAbs(path string) bool { 18 | return filepath.IsAbs(path) 19 | } 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/filesys_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | "path/filepath" 8 | "regexp" 9 | "strings" 10 | "syscall" 11 | ) 12 | 13 | // MkdirAll implementation that is volume path aware for Windows. 14 | func MkdirAll(path string, perm os.FileMode) error { 15 | if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) { 16 | return nil 17 | } 18 | 19 | // The rest of this method is copied from os.MkdirAll and should be kept 20 | // as-is to ensure compatibility. 21 | 22 | // Fast path: if we can tell whether path is a directory or file, stop with success or error. 23 | dir, err := os.Stat(path) 24 | if err == nil { 25 | if dir.IsDir() { 26 | return nil 27 | } 28 | return &os.PathError{ 29 | Op: "mkdir", 30 | Path: path, 31 | Err: syscall.ENOTDIR, 32 | } 33 | } 34 | 35 | // Slow path: make sure parent exists and then call Mkdir for path. 36 | i := len(path) 37 | for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator. 38 | i-- 39 | } 40 | 41 | j := i 42 | for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element. 43 | j-- 44 | } 45 | 46 | if j > 1 { 47 | // Create parent 48 | err = MkdirAll(path[0:j-1], perm) 49 | if err != nil { 50 | return err 51 | } 52 | } 53 | 54 | // Parent now exists; invoke Mkdir and use its result. 55 | err = os.Mkdir(path, perm) 56 | if err != nil { 57 | // Handle arguments like "foo/." by 58 | // double-checking that directory doesn't exist. 59 | dir, err1 := os.Lstat(path) 60 | if err1 == nil && dir.IsDir() { 61 | return nil 62 | } 63 | return err 64 | } 65 | return nil 66 | } 67 | 68 | // IsAbs is a platform-specific wrapper for filepath.IsAbs. On Windows, 69 | // golang filepath.IsAbs does not consider a path \windows\system32 as absolute 70 | // as it doesn't start with a drive-letter/colon combination. However, in 71 | // docker we need to verify things such as WORKDIR /windows/system32 in 72 | // a Dockerfile (which gets translated to \windows\system32 when being processed 73 | // by the daemon. This SHOULD be treated as absolute from a docker processing 74 | // perspective. 75 | func IsAbs(path string) bool { 76 | if !filepath.IsAbs(path) { 77 | if !strings.HasPrefix(path, string(os.PathSeparator)) { 78 | return false 79 | } 80 | } 81 | return true 82 | } 83 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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.StatT type pertaining to that file. 11 | // 12 | // Throws an error if the file does not exist 13 | func Lstat(path string) (*StatT, 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/external/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/external/github.com/docker/docker/pkg/system/lstat_unix_test.go: -------------------------------------------------------------------------------- 1 | // +build linux freebsd 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | "testing" 8 | ) 9 | 10 | // TestLstat tests Lstat for existing and non existing files 11 | func TestLstat(t *testing.T) { 12 | file, invalid, _, dir := prepareFiles(t) 13 | defer os.RemoveAll(dir) 14 | 15 | statFile, err := Lstat(file) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | if statFile == nil { 20 | t.Fatal("returned empty stat for existing file") 21 | } 22 | 23 | statInvalid, err := Lstat(invalid) 24 | if err == nil { 25 | t.Fatal("did not return error for non-existing file") 26 | } 27 | if statInvalid != nil { 28 | t.Fatal("returned non-nil stat for non-existing file") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/lstat_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | ) 8 | 9 | // Lstat calls os.Lstat to get a fileinfo interface back. 10 | // This is then copied into our own locally defined structure. 11 | // Note the Linux version uses fromStatT to do the copy back, 12 | // but that not strictly necessary when already in an OS specific module. 13 | func Lstat(path string) (*StatT, error) { 14 | fi, err := os.Lstat(path) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | return &StatT{ 20 | name: fi.Name(), 21 | size: fi.Size(), 22 | mode: fi.Mode(), 23 | modTime: fi.ModTime(), 24 | isDir: fi.IsDir()}, nil 25 | } 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/github.com/docker/docker/pkg/system/meminfo_linux.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "os" 7 | "strconv" 8 | "strings" 9 | 10 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/units" 11 | ) 12 | 13 | // ReadMemInfo retrieves memory statistics of the host system and returns a 14 | // MemInfo type. 15 | func ReadMemInfo() (*MemInfo, error) { 16 | file, err := os.Open("/proc/meminfo") 17 | if err != nil { 18 | return nil, err 19 | } 20 | defer file.Close() 21 | return parseMemInfo(file) 22 | } 23 | 24 | // parseMemInfo parses the /proc/meminfo file into 25 | // a MemInfo object given a io.Reader to the file. 26 | // 27 | // Throws error if there are problems reading from the file 28 | func parseMemInfo(reader io.Reader) (*MemInfo, error) { 29 | meminfo := &MemInfo{} 30 | scanner := bufio.NewScanner(reader) 31 | for scanner.Scan() { 32 | // Expected format: ["MemTotal:", "1234", "kB"] 33 | parts := strings.Fields(scanner.Text()) 34 | 35 | // Sanity checks: Skip malformed entries. 36 | if len(parts) < 3 || parts[2] != "kB" { 37 | continue 38 | } 39 | 40 | // Convert to bytes. 41 | size, err := strconv.Atoi(parts[1]) 42 | if err != nil { 43 | continue 44 | } 45 | bytes := int64(size) * units.KiB 46 | 47 | switch parts[0] { 48 | case "MemTotal:": 49 | meminfo.MemTotal = bytes 50 | case "MemFree:": 51 | meminfo.MemFree = bytes 52 | case "SwapTotal:": 53 | meminfo.SwapTotal = bytes 54 | case "SwapFree:": 55 | meminfo.SwapFree = bytes 56 | } 57 | 58 | } 59 | 60 | // Handle errors that may have occurred during the reading of the file. 61 | if err := scanner.Err(); err != nil { 62 | return nil, err 63 | } 64 | 65 | return meminfo, nil 66 | } 67 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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/external/github.com/docker/docker/pkg/system/meminfo_unix_test.go: -------------------------------------------------------------------------------- 1 | // +build linux freebsd 2 | 3 | package system 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | 9 | "github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/units" 10 | ) 11 | 12 | // TestMemInfo tests parseMemInfo with a static meminfo string 13 | func TestMemInfo(t *testing.T) { 14 | const input = ` 15 | MemTotal: 1 kB 16 | MemFree: 2 kB 17 | SwapTotal: 3 kB 18 | SwapFree: 4 kB 19 | Malformed1: 20 | Malformed2: 1 21 | Malformed3: 2 MB 22 | Malformed4: X kB 23 | ` 24 | meminfo, err := parseMemInfo(strings.NewReader(input)) 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | if meminfo.MemTotal != 1*units.KiB { 29 | t.Fatalf("Unexpected MemTotal: %d", meminfo.MemTotal) 30 | } 31 | if meminfo.MemFree != 2*units.KiB { 32 | t.Fatalf("Unexpected MemFree: %d", meminfo.MemFree) 33 | } 34 | if meminfo.SwapTotal != 3*units.KiB { 35 | t.Fatalf("Unexpected SwapTotal: %d", meminfo.SwapTotal) 36 | } 37 | if meminfo.SwapFree != 4*units.KiB { 38 | t.Fatalf("Unexpected SwapFree: %d", meminfo.SwapFree) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/meminfo_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!windows 2 | 3 | package system 4 | 5 | // ReadMemInfo is not supported on platforms other than linux and windows. 6 | func ReadMemInfo() (*MemInfo, error) { 7 | return nil, ErrNotSupportedPlatform 8 | } 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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 | // Mkdev is used to build the value of linux devices (in /dev/) which specifies major 16 | // and minor number of the newly created device special file. 17 | // Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes. 18 | // They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major, 19 | // then the top 12 bits of the minor. 20 | func Mkdev(major int64, minor int64) uint32 { 21 | return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff)) 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/mknod_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | // Mknod is not implemented on Windows. 6 | func Mknod(path string, mode uint32, dev int) error { 7 | return ErrNotSupportedPlatform 8 | } 9 | 10 | // Mkdev is not implemented on Windows. 11 | func Mkdev(major int64, minor int64) uint32 { 12 | panic("Mkdev not implemented on Windows.") 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/stat.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | // StatT type contains status of a file. It contains metadata 10 | // like permission, owner, group, size, etc about a file. 11 | type StatT struct { 12 | mode uint32 13 | uid uint32 14 | gid uint32 15 | rdev uint64 16 | size int64 17 | mtim syscall.Timespec 18 | } 19 | 20 | // Mode returns file's permission mode. 21 | func (s StatT) Mode() uint32 { 22 | return s.mode 23 | } 24 | 25 | // UID returns file's user id of owner. 26 | func (s StatT) UID() uint32 { 27 | return s.uid 28 | } 29 | 30 | // GID returns file's group id of owner. 31 | func (s StatT) GID() uint32 { 32 | return s.gid 33 | } 34 | 35 | // Rdev returns file's device ID (if it's special file). 36 | func (s StatT) Rdev() uint64 { 37 | return s.rdev 38 | } 39 | 40 | // Size returns file's size. 41 | func (s StatT) Size() int64 { 42 | return s.size 43 | } 44 | 45 | // Mtim returns file's last modification time. 46 | func (s StatT) Mtim() syscall.Timespec { 47 | return s.mtim 48 | } 49 | 50 | // GetLastModification returns file's last modification time. 51 | func (s StatT) GetLastModification() syscall.Timespec { 52 | return s.Mtim() 53 | } 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/stat_freebsd.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) (*StatT, error) { 9 | return &StatT{size: s.Size, 10 | mode: uint32(s.Mode), 11 | uid: s.Uid, 12 | gid: s.Gid, 13 | rdev: uint64(s.Rdev), 14 | mtim: s.Mtimespec}, nil 15 | } 16 | 17 | // Stat takes a path to a file and returns 18 | // a system.Stat_t type pertaining to that file. 19 | // 20 | // Throws an error if the file does not exist 21 | func Stat(path string) (*StatT, error) { 22 | s := &syscall.Stat_t{} 23 | if err := syscall.Stat(path, s); err != nil { 24 | return nil, err 25 | } 26 | return fromStatT(s) 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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) (*StatT, error) { 9 | return &StatT{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.StatT from a 18 | // syscal.Stat_t. 19 | func FromStatT(s *syscall.Stat_t) (*StatT, error) { 20 | return fromStatT(s) 21 | } 22 | 23 | // Stat takes a path to a file and returns 24 | // a system.StatT type pertaining to that file. 25 | // 26 | // Throws an error if the file does not exist 27 | func Stat(path string) (*StatT, 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/external/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/external/github.com/docker/docker/pkg/system/stat_unix_test.go: -------------------------------------------------------------------------------- 1 | // +build linux freebsd 2 | 3 | package system 4 | 5 | import ( 6 | "os" 7 | "syscall" 8 | "testing" 9 | ) 10 | 11 | // TestFromStatT tests fromStatT for a tempfile 12 | func TestFromStatT(t *testing.T) { 13 | file, _, _, dir := prepareFiles(t) 14 | defer os.RemoveAll(dir) 15 | 16 | stat := &syscall.Stat_t{} 17 | err := syscall.Lstat(file, stat) 18 | 19 | s, err := fromStatT(stat) 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | 24 | if stat.Mode != s.Mode() { 25 | t.Fatal("got invalid mode") 26 | } 27 | if stat.Uid != s.UID() { 28 | t.Fatal("got invalid uid") 29 | } 30 | if stat.Gid != s.GID() { 31 | t.Fatal("got invalid gid") 32 | } 33 | if stat.Rdev != s.Rdev() { 34 | t.Fatal("got invalid rdev") 35 | } 36 | if stat.Mtim != s.Mtim() { 37 | t.Fatal("got invalid mtim") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/stat_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!windows,!freebsd 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | // fromStatT creates a system.StatT type from a syscall.Stat_t type 10 | func fromStatT(s *syscall.Stat_t) (*StatT, error) { 11 | return &StatT{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/external/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 | // StatT type contains status of a file. It contains metadata 11 | // like name, permission, size, etc about a file. 12 | type StatT struct { 13 | name string 14 | size int64 15 | mode os.FileMode 16 | modTime time.Time 17 | isDir bool 18 | } 19 | 20 | // Name returns file's name. 21 | func (s StatT) Name() string { 22 | return s.name 23 | } 24 | 25 | // Size returns file's size. 26 | func (s StatT) Size() int64 { 27 | return s.size 28 | } 29 | 30 | // Mode returns file's permission mode. 31 | func (s StatT) Mode() os.FileMode { 32 | return s.mode 33 | } 34 | 35 | // ModTime returns file's last modification time. 36 | func (s StatT) ModTime() time.Time { 37 | return s.modTime 38 | } 39 | 40 | // IsDir returns whether file is actually a directory. 41 | func (s StatT) IsDir() bool { 42 | return s.isDir 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/syscall_unix.go: -------------------------------------------------------------------------------- 1 | // +build linux freebsd 2 | 3 | package system 4 | 5 | import "syscall" 6 | 7 | // Unmount is a platform-specific helper function to call 8 | // the unmount syscall. 9 | func Unmount(dest string) { 10 | syscall.Unmount(dest, 0) 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/syscall_windows.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | // Unmount is a platform-specific helper function to call 4 | // the unmount syscall. Not supported on Windows 5 | func Unmount(dest string) { 6 | } 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/umask.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package system 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | // Umask sets current process's file mode creation mask to newmask 10 | // and return oldmask. 11 | func Umask(newmask int) (oldmask int, err error) { 12 | return syscall.Umask(newmask), nil 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/umask_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package system 4 | 5 | // Umask is not supported on the windows platform. 6 | func Umask(newmask int) (oldmask int, err error) { 7 | // should not be called on cli code path 8 | return 0, ErrNotSupportedPlatform 9 | } 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/utimes_darwin.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import "syscall" 4 | 5 | // LUtimesNano is not supported by darwin platform. 6 | func LUtimesNano(path string, ts []syscall.Timespec) error { 7 | return ErrNotSupportedPlatform 8 | } 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/utimes_freebsd.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // LUtimesNano is used to change access and modification time of the specified path. 9 | // It's used for symbol link file because syscall.UtimesNano doesn't support a NOFOLLOW flag atm. 10 | func LUtimesNano(path string, ts []syscall.Timespec) error { 11 | var _path *byte 12 | _path, err := syscall.BytePtrFromString(path) 13 | if err != nil { 14 | return err 15 | } 16 | 17 | if _, _, err := syscall.Syscall(syscall.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != syscall.ENOSYS { 18 | return err 19 | } 20 | 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/utimes_linux.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // LUtimesNano is used to change access and modification time of the speficied path. 9 | // It's used for symbol link file because syscall.UtimesNano doesn't support a NOFOLLOW flag atm. 10 | func LUtimesNano(path string, ts []syscall.Timespec) error { 11 | // These are not currently available in syscall 12 | atFdCwd := -100 13 | atSymLinkNoFollow := 0x100 14 | 15 | var _path *byte 16 | _path, err := syscall.BytePtrFromString(path) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(atSymLinkNoFollow), 0, 0); err != 0 && err != syscall.ENOSYS { 22 | return err 23 | } 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/github.com/docker/docker/pkg/system/utimes_unix_test.go: -------------------------------------------------------------------------------- 1 | // +build linux freebsd 2 | 3 | package system 4 | 5 | import ( 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | "syscall" 10 | "testing" 11 | ) 12 | 13 | // prepareFiles creates files for testing in the temp directory 14 | func prepareFiles(t *testing.T) (string, string, string, string) { 15 | dir, err := ioutil.TempDir("", "docker-system-test") 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | file := filepath.Join(dir, "exist") 21 | if err := ioutil.WriteFile(file, []byte("hello"), 0644); err != nil { 22 | t.Fatal(err) 23 | } 24 | 25 | invalid := filepath.Join(dir, "doesnt-exist") 26 | 27 | symlink := filepath.Join(dir, "symlink") 28 | if err := os.Symlink(file, symlink); err != nil { 29 | t.Fatal(err) 30 | } 31 | 32 | return file, invalid, symlink, dir 33 | } 34 | 35 | func TestLUtimesNano(t *testing.T) { 36 | file, invalid, symlink, dir := prepareFiles(t) 37 | defer os.RemoveAll(dir) 38 | 39 | before, err := os.Stat(file) 40 | if err != nil { 41 | t.Fatal(err) 42 | } 43 | 44 | ts := []syscall.Timespec{{0, 0}, {0, 0}} 45 | if err := LUtimesNano(symlink, ts); err != nil { 46 | t.Fatal(err) 47 | } 48 | 49 | symlinkInfo, err := os.Lstat(symlink) 50 | if err != nil { 51 | t.Fatal(err) 52 | } 53 | if before.ModTime().Unix() == symlinkInfo.ModTime().Unix() { 54 | t.Fatal("The modification time of the symlink should be different") 55 | } 56 | 57 | fileInfo, err := os.Stat(file) 58 | if err != nil { 59 | t.Fatal(err) 60 | } 61 | if before.ModTime().Unix() != fileInfo.ModTime().Unix() { 62 | t.Fatal("The modification time of the file should be same") 63 | } 64 | 65 | if err := LUtimesNano(invalid, ts); err == nil { 66 | t.Fatal("Doesn't return an error on a non-existing file") 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/utimes_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd,!darwin 2 | 3 | package system 4 | 5 | import "syscall" 6 | 7 | // LUtimesNano is not supported on platforms other than linux, freebsd and darwin. 8 | func LUtimesNano(path string, ts []syscall.Timespec) error { 9 | return ErrNotSupportedPlatform 10 | } 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/xattrs_linux.go: -------------------------------------------------------------------------------- 1 | package system 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // Lgetxattr retrieves the value of the extended attribute identified by attr 9 | // and associated with the given path in the file system. 10 | // It will returns a nil slice and nil error if the xattr is not set. 11 | func Lgetxattr(path string, attr string) ([]byte, error) { 12 | pathBytes, err := syscall.BytePtrFromString(path) 13 | if err != nil { 14 | return nil, err 15 | } 16 | attrBytes, err := syscall.BytePtrFromString(attr) 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | dest := make([]byte, 128) 22 | destBytes := unsafe.Pointer(&dest[0]) 23 | sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) 24 | if errno == syscall.ENODATA { 25 | return nil, nil 26 | } 27 | if errno == syscall.ERANGE { 28 | dest = make([]byte, sz) 29 | destBytes := unsafe.Pointer(&dest[0]) 30 | sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) 31 | } 32 | if errno != 0 { 33 | return nil, errno 34 | } 35 | 36 | return dest[:sz], nil 37 | } 38 | 39 | var _zero uintptr 40 | 41 | // Lsetxattr sets the value of the extended attribute identified by attr 42 | // and associated with the given path in the file system. 43 | func Lsetxattr(path string, attr string, data []byte, flags int) error { 44 | pathBytes, err := syscall.BytePtrFromString(path) 45 | if err != nil { 46 | return err 47 | } 48 | attrBytes, err := syscall.BytePtrFromString(attr) 49 | if err != nil { 50 | return err 51 | } 52 | var dataBytes unsafe.Pointer 53 | if len(data) > 0 { 54 | dataBytes = unsafe.Pointer(&data[0]) 55 | } else { 56 | dataBytes = unsafe.Pointer(&_zero) 57 | } 58 | _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) 59 | if errno != 0 { 60 | return errno 61 | } 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/system/xattrs_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package system 4 | 5 | // Lgetxattr is not supported on platforms other than linux. 6 | func Lgetxattr(path string, attr string) ([]byte, error) { 7 | return nil, ErrNotSupportedPlatform 8 | } 9 | 10 | // Lsetxattr is not supported on platforms other than linux. 11 | func Lsetxattr(path string, attr string, data []byte, flags int) error { 12 | return ErrNotSupportedPlatform 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/ulimit/ulimit_test.go: -------------------------------------------------------------------------------- 1 | package ulimit 2 | 3 | import "testing" 4 | 5 | func TestParseValid(t *testing.T) { 6 | u1 := &Ulimit{"nofile", 1024, 512} 7 | if u2, _ := Parse("nofile=512:1024"); *u1 != *u2 { 8 | t.Fatalf("expected %q, but got %q", u1, u2) 9 | } 10 | } 11 | 12 | func TestParseInvalidLimitType(t *testing.T) { 13 | if _, err := Parse("notarealtype=1024:1024"); err == nil { 14 | t.Fatalf("expected error on invalid ulimit type") 15 | } 16 | } 17 | 18 | func TestParseBadFormat(t *testing.T) { 19 | if _, err := Parse("nofile:1024:1024"); err == nil { 20 | t.Fatal("expected error on bad syntax") 21 | } 22 | 23 | if _, err := Parse("nofile"); err == nil { 24 | t.Fatal("expected error on bad syntax") 25 | } 26 | 27 | if _, err := Parse("nofile="); err == nil { 28 | t.Fatal("expected error on bad syntax") 29 | } 30 | if _, err := Parse("nofile=:"); err == nil { 31 | t.Fatal("expected error on bad syntax") 32 | } 33 | if _, err := Parse("nofile=:1024"); err == nil { 34 | t.Fatal("expected error on bad syntax") 35 | } 36 | } 37 | 38 | func TestParseHardLessThanSoft(t *testing.T) { 39 | if _, err := Parse("nofile:1024:1"); err == nil { 40 | t.Fatal("expected error on hard limit less than soft limit") 41 | } 42 | } 43 | 44 | func TestParseInvalidValueType(t *testing.T) { 45 | if _, err := Parse("nofile:asdf"); err == nil { 46 | t.Fatal("expected error on bad value type") 47 | } 48 | } 49 | 50 | func TestStringOutput(t *testing.T) { 51 | u := &Ulimit{"nofile", 1024, 512} 52 | if s := u.String(); s != "nofile=512:1024" { 53 | t.Fatal("expected String to return nofile=512:1024, but got", s) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/units/duration.go: -------------------------------------------------------------------------------- 1 | // Package units provides helper function to parse and print size and time units 2 | // in human-readable format. 3 | package units 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | // HumanDuration returns a human-readable approximation of a duration 11 | // (eg. "About a minute", "4 hours ago", etc.). 12 | func HumanDuration(d time.Duration) string { 13 | if seconds := int(d.Seconds()); seconds < 1 { 14 | return "Less than a second" 15 | } else if seconds < 60 { 16 | return fmt.Sprintf("%d seconds", seconds) 17 | } else if minutes := int(d.Minutes()); minutes == 1 { 18 | return "About a minute" 19 | } else if minutes < 60 { 20 | return fmt.Sprintf("%d minutes", minutes) 21 | } else if hours := int(d.Hours()); hours == 1 { 22 | return "About an hour" 23 | } else if hours < 48 { 24 | return fmt.Sprintf("%d hours", hours) 25 | } else if hours < 24*7*2 { 26 | return fmt.Sprintf("%d days", hours/24) 27 | } else if hours < 24*30*3 { 28 | return fmt.Sprintf("%d weeks", hours/24/7) 29 | } else if hours < 24*365*2 { 30 | return fmt.Sprintf("%d months", hours/24/30) 31 | } 32 | return fmt.Sprintf("%d years", int(d.Hours())/24/365) 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/units/duration_test.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestHumanDuration(t *testing.T) { 9 | // Useful duration abstractions 10 | day := 24 * time.Hour 11 | week := 7 * day 12 | month := 30 * day 13 | year := 365 * day 14 | 15 | assertEquals(t, "Less than a second", HumanDuration(450*time.Millisecond)) 16 | assertEquals(t, "47 seconds", HumanDuration(47*time.Second)) 17 | assertEquals(t, "About a minute", HumanDuration(1*time.Minute)) 18 | assertEquals(t, "3 minutes", HumanDuration(3*time.Minute)) 19 | assertEquals(t, "35 minutes", HumanDuration(35*time.Minute)) 20 | assertEquals(t, "35 minutes", HumanDuration(35*time.Minute+40*time.Second)) 21 | assertEquals(t, "About an hour", HumanDuration(1*time.Hour)) 22 | assertEquals(t, "About an hour", HumanDuration(1*time.Hour+45*time.Minute)) 23 | assertEquals(t, "3 hours", HumanDuration(3*time.Hour)) 24 | assertEquals(t, "3 hours", HumanDuration(3*time.Hour+59*time.Minute)) 25 | assertEquals(t, "4 hours", HumanDuration(3*time.Hour+60*time.Minute)) 26 | assertEquals(t, "24 hours", HumanDuration(24*time.Hour)) 27 | assertEquals(t, "36 hours", HumanDuration(1*day+12*time.Hour)) 28 | assertEquals(t, "2 days", HumanDuration(2*day)) 29 | assertEquals(t, "7 days", HumanDuration(7*day)) 30 | assertEquals(t, "13 days", HumanDuration(13*day+5*time.Hour)) 31 | assertEquals(t, "2 weeks", HumanDuration(2*week)) 32 | assertEquals(t, "2 weeks", HumanDuration(2*week+4*day)) 33 | assertEquals(t, "3 weeks", HumanDuration(3*week)) 34 | assertEquals(t, "4 weeks", HumanDuration(4*week)) 35 | assertEquals(t, "4 weeks", HumanDuration(4*week+3*day)) 36 | assertEquals(t, "4 weeks", HumanDuration(1*month)) 37 | assertEquals(t, "6 weeks", HumanDuration(1*month+2*week)) 38 | assertEquals(t, "8 weeks", HumanDuration(2*month)) 39 | assertEquals(t, "3 months", HumanDuration(3*month+1*week)) 40 | assertEquals(t, "5 months", HumanDuration(5*month+2*week)) 41 | assertEquals(t, "13 months", HumanDuration(13*month)) 42 | assertEquals(t, "23 months", HumanDuration(23*month)) 43 | assertEquals(t, "24 months", HumanDuration(24*month)) 44 | assertEquals(t, "2 years", HumanDuration(24*month+2*week)) 45 | assertEquals(t, "3 years", HumanDuration(3*year+2*month)) 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/libcontainer/user/MAINTAINERS: -------------------------------------------------------------------------------- 1 | Tianon Gravi (@tianon) 2 | Aleksa Sarai (@cyphar) 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/libcontainer/user/lookup_unix.go: -------------------------------------------------------------------------------- 1 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 2 | 3 | package user 4 | 5 | import ( 6 | "io" 7 | "os" 8 | ) 9 | 10 | // Unix-specific path to the passwd and group formatted files. 11 | const ( 12 | unixPasswdPath = "/etc/passwd" 13 | unixGroupPath = "/etc/group" 14 | ) 15 | 16 | func GetPasswdPath() (string, error) { 17 | return unixPasswdPath, nil 18 | } 19 | 20 | func GetPasswd() (io.ReadCloser, error) { 21 | return os.Open(unixPasswdPath) 22 | } 23 | 24 | func GetGroupPath() (string, error) { 25 | return unixGroupPath, nil 26 | } 27 | 28 | func GetGroup() (io.ReadCloser, error) { 29 | return os.Open(unixGroupPath) 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/docker/libcontainer/user/lookup_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris 2 | 3 | package user 4 | 5 | import "io" 6 | 7 | func GetPasswdPath() (string, error) { 8 | return "", ErrUnsupported 9 | } 10 | 11 | func GetPasswd() (io.ReadCloser, error) { 12 | return nil, ErrUnsupported 13 | } 14 | 15 | func GetGroupPath() (string, error) { 16 | return "", ErrUnsupported 17 | } 18 | 19 | func GetGroup() (io.ReadCloser, error) { 20 | return nil, ErrUnsupported 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/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/external/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/external/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/external/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/fsouza/go-dockerclient/external/github.com/hashicorp/go-cleanhttp/README.md: -------------------------------------------------------------------------------- 1 | # cleanhttp 2 | 3 | Functions for accessing "clean" Go http.Client values 4 | 5 | ------------- 6 | 7 | The Go standard library contains a default `http.Client` called 8 | `http.DefaultClient`. It is a common idiom in Go code to start with 9 | `http.DefaultClient` and tweak it as necessary, and in fact, this is 10 | encouraged; from the `http` package documentation: 11 | 12 | > The Client's Transport typically has internal state (cached TCP connections), 13 | so Clients should be reused instead of created as needed. Clients are safe for 14 | concurrent use by multiple goroutines. 15 | 16 | Unfortunately, this is a shared value, and it is not uncommon for libraries to 17 | assume that they are free to modify it at will. With enough dependencies, it 18 | can be very easy to encounter strange problems and race conditions due to 19 | manipulation of this shared value across libraries and goroutines (clients are 20 | safe for concurrent use, but writing values to the client struct itself is not 21 | protected). 22 | 23 | Making things worse is the fact that a bare `http.Client` will use a default 24 | `http.Transport` called `http.DefaultTransport`, which is another global value 25 | that behaves the same way. So it is not simply enough to replace 26 | `http.DefaultClient` with `&http.Client{}`. 27 | 28 | This repository provides some simple functions to get a "clean" `http.Client` 29 | -- one that uses the same default values as the Go standard library, but 30 | returns a client that does not share any state with other clients. 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/hashicorp/go-cleanhttp/cleanhttp.go: -------------------------------------------------------------------------------- 1 | package cleanhttp 2 | 3 | import ( 4 | "net" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | // DefaultTransport returns a new http.Transport with the same default values 10 | // as http.DefaultTransport 11 | func DefaultTransport() *http.Transport { 12 | return &http.Transport{ 13 | Proxy: http.ProxyFromEnvironment, 14 | Dial: (&net.Dialer{ 15 | Timeout: 30 * time.Second, 16 | KeepAlive: 30 * time.Second, 17 | }).Dial, 18 | TLSHandshakeTimeout: 10 * time.Second, 19 | } 20 | } 21 | 22 | // DefaultClient returns a new http.Client with the same default values as 23 | // http.Client, but with a non-shared Transport 24 | func DefaultClient() *http.Client { 25 | return &http.Client{ 26 | Transport: DefaultTransport(), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS: -------------------------------------------------------------------------------- 1 | Tianon Gravi (@tianon) 2 | Aleksa Sarai (@cyphar) 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go: -------------------------------------------------------------------------------- 1 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 2 | 3 | package user 4 | 5 | import ( 6 | "io" 7 | "os" 8 | ) 9 | 10 | // Unix-specific path to the passwd and group formatted files. 11 | const ( 12 | unixPasswdPath = "/etc/passwd" 13 | unixGroupPath = "/etc/group" 14 | ) 15 | 16 | func GetPasswdPath() (string, error) { 17 | return unixPasswdPath, nil 18 | } 19 | 20 | func GetPasswd() (io.ReadCloser, error) { 21 | return os.Open(unixPasswdPath) 22 | } 23 | 24 | func GetGroupPath() (string, error) { 25 | return unixGroupPath, nil 26 | } 27 | 28 | func GetGroup() (io.ReadCloser, error) { 29 | return os.Open(unixGroupPath) 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/external/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris 2 | 3 | package user 4 | 5 | import "io" 6 | 7 | func GetPasswdPath() (string, error) { 8 | return "", ErrUnsupported 9 | } 10 | 11 | func GetPasswd() (io.ReadCloser, error) { 12 | return nil, ErrUnsupported 13 | } 14 | 15 | func GetGroupPath() (string, error) { 16 | return "", ErrUnsupported 17 | } 18 | 19 | func GetGroup() (io.ReadCloser, error) { 20 | return nil, ErrUnsupported 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/integration_test.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 | // +build docker_integration 6 | 7 | package docker 8 | 9 | import ( 10 | "bytes" 11 | "os" 12 | "testing" 13 | ) 14 | 15 | var dockerEndpoint string 16 | 17 | func init() { 18 | dockerEndpoint = os.Getenv("DOCKER_HOST") 19 | if dockerEndpoint == "" { 20 | dockerEndpoint = "unix:///var/run/docker.sock" 21 | } 22 | } 23 | 24 | func TestIntegrationPullCreateStartLogs(t *testing.T) { 25 | imageName := pullImage(t) 26 | client := getClient() 27 | hostConfig := HostConfig{PublishAllPorts: true} 28 | createOpts := CreateContainerOptions{ 29 | Config: &Config{ 30 | Image: imageName, 31 | Cmd: []string{"cat", "/home/gopher/file.txt"}, 32 | User: "gopher", 33 | }, 34 | HostConfig: &hostConfig, 35 | } 36 | container, err := client.CreateContainer(createOpts) 37 | if err != nil { 38 | t.Fatal(err) 39 | } 40 | err = client.StartContainer(container.ID, &hostConfig) 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | status, err := client.WaitContainer(container.ID) 45 | if err != nil { 46 | t.Error(err) 47 | } 48 | if status != 0 { 49 | t.Error("WaitContainer(%q): wrong status. Want 0. Got %d", container.ID, status) 50 | } 51 | var stdout, stderr bytes.Buffer 52 | logsOpts := LogsOptions{ 53 | Container: container.ID, 54 | OutputStream: &stdout, 55 | ErrorStream: &stderr, 56 | Stdout: true, 57 | Stderr: true, 58 | } 59 | err = client.Logs(logsOpts) 60 | if err != nil { 61 | t.Error(err) 62 | } 63 | if stderr.String() != "" { 64 | t.Errorf("Got unexpected stderr from logs: %q", stderr.String()) 65 | } 66 | expected := `Welcome to reality, wake up and rejoice 67 | Welcome to reality, you've made the right choice 68 | Welcome to reality, and let them hear your voice, shout it out! 69 | ` 70 | if stdout.String() != expected { 71 | t.Errorf("Got wrong stdout from logs.\nWant:\n%#v.\n\nGot:\n%#v.", expected, stdout.String()) 72 | } 73 | } 74 | 75 | func pullImage(t *testing.T) string { 76 | imageName := "fsouza/go-dockerclient-integration" 77 | var buf bytes.Buffer 78 | pullOpts := PullImageOptions{ 79 | Repository: imageName, 80 | OutputStream: &buf, 81 | } 82 | client := getClient() 83 | err := client.PullImage(pullOpts, AuthConfiguration{}) 84 | if err != nil { 85 | t.Logf("Pull output: %s", buf.String()) 86 | t.Fatal(err) 87 | } 88 | return imageName 89 | } 90 | 91 | func getClient() *Client { 92 | client, _ := NewClient(dockerEndpoint) 93 | return client 94 | } 95 | -------------------------------------------------------------------------------- /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 "strings" 8 | 9 | // Version returns version information about the docker server. 10 | // 11 | // See https://goo.gl/ND9R8L for more details. 12 | func (c *Client) Version() (*Env, error) { 13 | resp, err := c.do("GET", "/version", doOptions{}) 14 | if err != nil { 15 | return nil, err 16 | } 17 | defer resp.Body.Close() 18 | var env Env 19 | if err := env.Decode(resp.Body); err != nil { 20 | return nil, err 21 | } 22 | return &env, nil 23 | } 24 | 25 | // Info returns system-wide information about the Docker server. 26 | // 27 | // See https://goo.gl/ElTHi2 for more details. 28 | func (c *Client) Info() (*Env, error) { 29 | resp, err := c.do("GET", "/info", doOptions{}) 30 | if err != nil { 31 | return nil, err 32 | } 33 | defer resp.Body.Close() 34 | var info Env 35 | if err := info.Decode(resp.Body); err != nil { 36 | return nil, err 37 | } 38 | return &info, nil 39 | } 40 | 41 | // ParseRepositoryTag gets the name of the repository and returns it splitted 42 | // in two parts: the repository and the tag. 43 | // 44 | // Some examples: 45 | // 46 | // localhost.localdomain:5000/samalba/hipache:latest -> localhost.localdomain:5000/samalba/hipache, latest 47 | // localhost.localdomain:5000/samalba/hipache -> localhost.localdomain:5000/samalba/hipache, "" 48 | func ParseRepositoryTag(repoTag string) (repository string, tag string) { 49 | n := strings.LastIndex(repoTag, ":") 50 | if n < 0 { 51 | return repoTag, "" 52 | } 53 | if tag := repoTag[n+1:]; !strings.Contains(tag, "/") { 54 | return repoTag[:n], tag 55 | } 56 | return repoTag, "" 57 | } 58 | -------------------------------------------------------------------------------- /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/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/cloudnautique/vol-cleanup/fe95cff5cd9a5650e3dfc6309e5af8e20f6ddaa6/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/container.tar: -------------------------------------------------------------------------------- 1 | fakecontainer000644 000766 000024 00000000065 12210121775 016021 0ustar00flavia.carlettestaff000000 000000 this is supposed to be a fake container in a tar. xD 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/data/dockerfile.tar: -------------------------------------------------------------------------------- 1 | Dockerfile000644 000766 000024 00000001225 12327754570 013535 0ustar00tarsisstaff000000 000000 # 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/foofile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudnautique/vol-cleanup/fe95cff5cd9a5650e3dfc6309e5af8e20f6ddaa6/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/tls.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 | // The content is borrowed from Docker's own source code to provide a simple 6 | // tls based dialer 7 | 8 | package docker 9 | 10 | import ( 11 | "crypto/tls" 12 | "errors" 13 | "net" 14 | "strings" 15 | "time" 16 | ) 17 | 18 | type tlsClientCon struct { 19 | *tls.Conn 20 | rawConn net.Conn 21 | } 22 | 23 | func (c *tlsClientCon) CloseWrite() error { 24 | // Go standard tls.Conn doesn't provide the CloseWrite() method so we do it 25 | // on its underlying connection. 26 | if cwc, ok := c.rawConn.(interface { 27 | CloseWrite() error 28 | }); ok { 29 | return cwc.CloseWrite() 30 | } 31 | return nil 32 | } 33 | 34 | func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) { 35 | // We want the Timeout and Deadline values from dialer to cover the 36 | // whole process: TCP connection and TLS handshake. This means that we 37 | // also need to start our own timers now. 38 | timeout := dialer.Timeout 39 | 40 | if !dialer.Deadline.IsZero() { 41 | deadlineTimeout := dialer.Deadline.Sub(time.Now()) 42 | if timeout == 0 || deadlineTimeout < timeout { 43 | timeout = deadlineTimeout 44 | } 45 | } 46 | 47 | var errChannel chan error 48 | 49 | if timeout != 0 { 50 | errChannel = make(chan error, 2) 51 | time.AfterFunc(timeout, func() { 52 | errChannel <- errors.New("") 53 | }) 54 | } 55 | 56 | rawConn, err := dialer.Dial(network, addr) 57 | if err != nil { 58 | return nil, err 59 | } 60 | 61 | colonPos := strings.LastIndex(addr, ":") 62 | if colonPos == -1 { 63 | colonPos = len(addr) 64 | } 65 | hostname := addr[:colonPos] 66 | 67 | // If no ServerName is set, infer the ServerName 68 | // from the hostname we're connecting to. 69 | if config.ServerName == "" { 70 | // Make a copy to avoid polluting argument or default. 71 | c := *config 72 | c.ServerName = hostname 73 | config = &c 74 | } 75 | 76 | conn := tls.Client(rawConn, config) 77 | 78 | if timeout == 0 { 79 | err = conn.Handshake() 80 | } else { 81 | go func() { 82 | errChannel <- conn.Handshake() 83 | }() 84 | 85 | err = <-errChannel 86 | } 87 | 88 | if err != nil { 89 | rawConn.Close() 90 | return nil, err 91 | } 92 | 93 | // This is Docker difference with standard's crypto/tls package: returned a 94 | // wrapper which holds both the TLS and raw connections. 95 | return &tlsClientCon{conn, rawConn}, nil 96 | } 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Clean Up Orphaned Docker Volumes 2 | 3 | ### Purpose: 4 | This tool is created to periodically remove orphaned volumes where the contents are not going to need future retrieval. In some environments where containers are treated ephemerally and have high turnover there is the potential to generate a lot of space consuming orphaned volumes. It is VERY difficult to track down the origin of a particular volume once the container it was attached to is gone. 5 | 6 | ### Quick Usage 7 | 8 | ``` 9 | docker run -d --privileged -v /var/lib/docker:/var/lib/docker -v /var/run/docker.sock:/var/run/docker.sock cloudnautique/vol-cleanup [-n] -i 5 10 | ``` 11 | 12 | If you run with `-n` it will log what it would delete. 13 | 14 | ### Building 15 | 16 | To generate a statically linked (Linux) go binary 17 | 18 | ```$ ./scripts/build``` 19 | 20 | It will be placed in the `./dist` directory. 21 | 22 | ### Packaging into a container 23 | 24 | To generate a small Busybox container with the binary installed run: 25 | 26 | `$ IMAGE=/vol-cleanup ./scripts/package` 27 | 28 | The default command of the image is to display the help page. Figured it was safer then starting to clean up files. 29 | 30 | ### Command usage 31 | 32 | ``` 33 | NAME: 34 | vol-cleanup - Clean up orphaned Docker volumes 35 | 36 | USAGE: 37 | vol-cleanup [global options] command [command options] [arguments...] 38 | 39 | VERSION: 40 | 0.0.0 41 | 42 | COMMANDS: 43 | help, h Shows a list of commands or help for one command 44 | 45 | GLOBAL OPTIONS: 46 | --noop, -n Run in a noop mode and log to screen 47 | --interval, -i "5" Number of minutes between runs 48 | --help, -h show help 49 | --version, -v print the version 50 | ``` 51 | 52 | 53 | ## License 54 | 55 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 56 | 57 | [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 58 | 59 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 60 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "time" 6 | 7 | log "github.com/Sirupsen/logrus" 8 | "github.com/cloudnautique/vol-cleanup/volumes" 9 | "github.com/codegangsta/cli" 10 | ) 11 | 12 | const ( 13 | dockerVolumeDirectory = "/var/lib/docker/volumes" 14 | ) 15 | 16 | func main() { 17 | app := cli.NewApp() 18 | app.Name = "vol-cleanup" 19 | app.Usage = "Clean up orphaned Docker volumes" 20 | 21 | app.Flags = []cli.Flag{ 22 | cli.BoolFlag{ 23 | Name: "noop, n", 24 | Usage: "Run in a noop mode and log to screen", 25 | }, 26 | cli.IntFlag{ 27 | Name: "interval, i", 28 | Value: 5, 29 | Usage: "Number of minutes between runs", 30 | }, 31 | } 32 | 33 | app.Action = func(c *cli.Context) { 34 | log.Debugf("Noop %v", c.Bool("noop")) 35 | Start(c.Int("interval"), c.Bool("noop")) 36 | } 37 | 38 | app.Run(os.Args) 39 | } 40 | 41 | func Start(interval int, noop bool) error { 42 | if _, err := os.Stat(dockerVolumeDirectory); os.IsNotExist(err) { 43 | log.Fatalf("Could not open Volume directory: %s", dockerVolumeDirectory) 44 | } 45 | 46 | for { 47 | log.Infof("Waking up to check for volumes...") 48 | vols := volumes.NewVolumesManager() 49 | err := vols.GetVolumes(dockerVolumeDirectory) 50 | if err != nil { 51 | log.Fatalf("Could not get volumes: %s", err) 52 | return err 53 | } 54 | 55 | err = vols.DeleteAllOrphans(noop) 56 | if err != nil { 57 | log.Fatalf("Error deleting orphaned vols.", err) 58 | } 59 | 60 | time.Sleep(time.Duration(interval) * time.Minute) 61 | } 62 | 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /scripts/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | IMAGE=vol-cleanup 6 | BUILD=${IMAGE}-build 7 | BIN_TARGET=/usr/bin/vol-cleanup 8 | 9 | cd $(dirname $0)/.. 10 | 11 | mkdir -p ./dist 12 | docker build -t $BUILD . 13 | docker run -v $(pwd)/dist:/target $BUILD cp ${BIN_TARGET} /target 14 | -------------------------------------------------------------------------------- /scripts/package: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | : ${IMAGE:="cloudnautique/vol-cleanup"} 6 | 7 | cd $(dirname $0)/.. 8 | ./scripts/build 9 | 10 | docker build -t $IMAGE -f Dockerfile.dist . 11 | -------------------------------------------------------------------------------- /volumes/manager.go: -------------------------------------------------------------------------------- 1 | package volumes 2 | 3 | import ( 4 | "strconv" 5 | 6 | log "github.com/Sirupsen/logrus" 7 | "github.com/fsouza/go-dockerclient" 8 | ) 9 | 10 | const ( 11 | dockerSocket = "unix:///var/run/docker.sock" 12 | defaultDockerAPIVersion = "1.19" 13 | fallbackDockerAPIVersion = "1.21" 14 | ) 15 | 16 | type Volume struct { 17 | ID string 18 | Attached bool 19 | Path string 20 | DockerPath string 21 | } 22 | 23 | type VolumesManager interface { 24 | GetVolumes(volumeDir string) error 25 | DeleteAllOrphans(noop bool) error 26 | } 27 | 28 | func NewVolumesManager() VolumesManager { 29 | client, defaultDocker := getDockerClient() 30 | if defaultDocker { 31 | return newVolumesPre19(client) 32 | } 33 | return newVolumes19(client) 34 | } 35 | 36 | func getDockerClient() (*docker.Client, bool) { 37 | client, _ := docker.NewVersionedClient(dockerSocket, defaultDockerAPIVersion) 38 | ver, err := client.Version() 39 | if err != nil { 40 | log.Fatalf("Could not get Docker version.") 41 | } 42 | 43 | if getFloat64(ver.Get("ApiVersion")) < getFloat64(fallbackDockerAPIVersion) { 44 | log.Debugf("Using API Version: %s", defaultDockerAPIVersion) 45 | return client, true 46 | } 47 | 48 | client, _ = docker.NewVersionedClient(dockerSocket, fallbackDockerAPIVersion) 49 | log.Debugf("Using API Version: %s", defaultDockerAPIVersion) 50 | return client, false 51 | } 52 | 53 | func getFloat64(val string) float64 { 54 | if val, err := strconv.ParseFloat(val, 64); err == nil { 55 | return val 56 | } 57 | log.Fatalf("Could not convert %s to float", val) 58 | return 0.0 59 | } 60 | -------------------------------------------------------------------------------- /volumes/vols19.go: -------------------------------------------------------------------------------- 1 | package volumes 2 | 3 | import ( 4 | log "github.com/Sirupsen/logrus" 5 | "github.com/fsouza/go-dockerclient" 6 | ) 7 | 8 | type volumes19 struct { 9 | volumes map[string]Volume 10 | dockerClient *docker.Client 11 | } 12 | 13 | func newVolumes19(client *docker.Client) *volumes19 { 14 | vol := &volumes19{ 15 | volumes: make(map[string]Volume), 16 | dockerClient: client, 17 | } 18 | var _ VolumesManager = vol 19 | return vol 20 | } 21 | 22 | func (v volumes19) GetVolumes(volumeDir string) error { 23 | volumes, err := v.dockerClient.ListVolumes(docker.ListVolumesOptions{}) 24 | if err != nil { 25 | return err 26 | } 27 | 28 | for _, volume := range volumes { 29 | log.Infof("Found volume: %v", volume.Name) 30 | vol := &Volume{ 31 | ID: volume.Name, 32 | Path: volume.Mountpoint, 33 | DockerPath: volume.Mountpoint, 34 | Attached: true, 35 | } 36 | v.volumes[vol.ID] = *vol 37 | } 38 | 39 | err = v.setDetachedVolumes() 40 | if err != nil { 41 | return err 42 | } 43 | 44 | return nil 45 | } 46 | 47 | func (v volumes19) DeleteAllOrphans(noop bool) error { 48 | message := "NOOP: Deleting volume: " 49 | if noop == false { 50 | message = "Deleting volume: " 51 | } 52 | 53 | opts := docker.ListVolumesOptions{ 54 | Filters: map[string][]string{ 55 | "dangling": []string{"true"}, 56 | }, 57 | } 58 | 59 | danglingVolumes, err := v.dockerClient.ListVolumes(opts) 60 | if err != nil { 61 | return err 62 | } 63 | 64 | for _, volume := range danglingVolumes { 65 | log.Infof("%v: %v", message, volume.Name) 66 | if volume.Driver == "local" && noop == false { 67 | err = v.dockerClient.RemoveVolume(volume.Name) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | return nil 75 | } 76 | 77 | func (v volumes19) DeleteVolume(id string) error { 78 | return v.dockerClient.RemoveVolume(id) 79 | } 80 | 81 | func (v volumes19) setDetachedVolumes() error { 82 | opts := docker.ListVolumesOptions{ 83 | Filters: map[string][]string{ 84 | "dangling": []string{"true"}, 85 | }, 86 | } 87 | 88 | danglingVolumes, err := v.dockerClient.ListVolumes(opts) 89 | if err != nil { 90 | return err 91 | } 92 | 93 | for _, volume := range danglingVolumes { 94 | vol := v.volumes[volume.Name] 95 | vol.Attached = false 96 | v.volumes[volume.Name] = vol 97 | } 98 | 99 | return nil 100 | } 101 | --------------------------------------------------------------------------------