Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dd1bf971d | ||
|
|
66262869b7 | ||
|
|
a7e71687ba | ||
|
|
137c71e50d | ||
|
|
7c27dde94c | ||
|
|
6b432803ff | ||
|
|
6394fcea39 | ||
|
|
ace93d5e73 | ||
|
|
6d3fafb8d3 | ||
|
|
875aede316 | ||
|
|
667c096ef5 | ||
|
|
e06d6a111a | ||
|
|
537e1a1b5b | ||
|
|
b49d391e73 | ||
|
|
0ab4f7ab51 | ||
|
|
b41f20ecf2 | ||
|
|
9a0e1571c5 | ||
|
|
d50282a9ed | ||
|
|
169d5e88f9 | ||
|
|
488d1aa532 | ||
|
|
26a1367cae | ||
|
|
0cb83dc4c8 | ||
|
|
c9428ae749 | ||
|
|
804c0e6971 | ||
|
|
fd06872223 | ||
|
|
7a3f0cade2 | ||
|
|
eb622b5408 | ||
|
|
8812f80bb8 | ||
|
|
c479121bc6 | ||
|
|
bcdba14302 | ||
|
|
21674ef7d8 | ||
|
|
efb03b2840 | ||
|
|
716e8c6db5 | ||
|
|
4f7598ada6 | ||
|
|
5dcde91936 | ||
|
|
64ba618188 | ||
|
|
b2ac37c322 | ||
|
|
72839fea10 | ||
|
|
262ba5e9f4 | ||
|
|
d0e1614e08 | ||
|
|
da62f2543f | ||
|
|
9462adaae2 | ||
|
|
952c38e7b3 | ||
|
|
00615f5ffa | ||
|
|
38f90f396f | ||
|
|
4a2f757754 | ||
|
|
2016a4c59c | ||
|
|
09a8ace624 | ||
|
|
8c2ad64439 | ||
|
|
e0c6244d54 | ||
|
|
2a837762ed | ||
|
|
19ce377ee9 | ||
|
|
b4532bf9f7 | ||
|
|
033636dd46 | ||
|
|
769de61657 | ||
|
|
9d59278035 | ||
|
|
1f510cdd4e | ||
|
|
52bfda2ab2 | ||
|
|
b92de8a508 | ||
|
|
957a5104b8 | ||
|
|
a4981f1b2c | ||
|
|
beaeecd457 | ||
|
|
dcc9088e31 | ||
|
|
27e8129caa | ||
|
|
7d801379db | ||
|
|
420da8c363 | ||
|
|
917384a2d9 | ||
|
|
e97e69a0e1 | ||
|
|
87d51409ff | ||
|
|
551b1f04c7 | ||
|
|
a35f4ef32e | ||
|
|
441f234398 | ||
|
|
dc452e2847 | ||
|
|
b9ee28ca8d | ||
|
|
474ce714db | ||
|
|
988afbe1c0 | ||
|
|
f9a0d4e881 | ||
|
|
78dd5b1d8b | ||
|
|
ede15194a1 | ||
|
|
88838ec63d | ||
|
|
66b902a5e0 | ||
|
|
e4d4d5251b | ||
|
|
0c50ff7c91 | ||
|
|
427edaa1ef | ||
|
|
b8c82af838 | ||
|
|
57ad1b98ff | ||
|
|
9d2bdb6a53 | ||
|
|
d97f7c5c6f | ||
|
|
abd334f3b8 | ||
|
|
33de8a4f07 | ||
|
|
93cfd0e597 | ||
|
|
537f7c0a01 | ||
|
|
e114f877c1 | ||
|
|
55bc51c9c2 | ||
|
|
d93b662907 | ||
|
|
3eec6cdd14 | ||
|
|
3b9adf8260 | ||
|
|
dde707a97a | ||
|
|
50ccf6311b | ||
|
|
705a339e49 | ||
|
|
f81c240a47 | ||
|
|
262095e5bb | ||
|
|
ba900c4374 | ||
|
|
9dc6b3790d | ||
|
|
b96785f2be | ||
|
|
dd6f4b1e31 | ||
|
|
651291ecad | ||
|
|
a5bcec68cb | ||
|
|
77d6a22122 | ||
|
|
40f97073e8 | ||
|
|
75339ffba1 | ||
|
|
2fdfba5a42 | ||
|
|
5987330cdc | ||
|
|
14c7c21f9f | ||
|
|
fc9fdaf8b6 | ||
|
|
5979a6d0e5 | ||
|
|
ca2c46ffce | ||
|
|
1cc7e92466 | ||
|
|
cfc3e81820 | ||
|
|
67ab2ab170 | ||
|
|
e1ce378421 | ||
|
|
f083ea028d | ||
|
|
063a82198c | ||
|
|
d03c3440de | ||
|
|
f7b28ad1e0 | ||
|
|
52a95757ce | ||
|
|
efc725dadc |
@@ -10,10 +10,8 @@ trim_trailing_whitespace = true
|
|||||||
max_line_length = 120
|
max_line_length = 120
|
||||||
|
|
||||||
[*.go]
|
[*.go]
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[Makefile]
|
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
[package.json]
|
[package.json]
|
||||||
indent_size = 1
|
indent_size = 1
|
||||||
|
|||||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.snapshot binary
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,4 +4,5 @@ node_modules
|
|||||||
.cache
|
.cache
|
||||||
static
|
static
|
||||||
a_main-packr.go
|
a_main-packr.go
|
||||||
dozzle
|
dozzle
|
||||||
|
gin-bin
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
- rm -rf static
|
- npm run clean
|
||||||
- npm run build
|
- npm run build
|
||||||
- packr
|
- packr
|
||||||
builds:
|
builds:
|
||||||
|
|||||||
1
.reflex
Normal file
1
.reflex
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-r '\.go$' -R '^node_modules/' -R '^static/' -R '^.cache/' -G '*_test.go' -s -- go run main.go --level debug
|
||||||
@@ -3,6 +3,10 @@ language: go
|
|||||||
go:
|
go:
|
||||||
- "1.11"
|
- "1.11"
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- GO111MODULE=on
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
|
|||||||
28
README.md
28
README.md
@@ -1,16 +1,22 @@
|
|||||||
|
[](https://goreportcard.com/report/github.com/amir20/dozzle)
|
||||||
|
[](https://travis-ci.org/amir20/dozzle)
|
||||||
|
[](https://hub.docker.com/r/amir20/dozzle/)
|
||||||
|
[](https://hub.docker.com/r/amir20/dozzle/)
|
||||||
|
[](https://hub.docker.com/r/amir20/dozzle/)
|
||||||
|
|
||||||
# dozzle
|
# dozzle
|
||||||
|
|
||||||
Dozzle is a log viewer for Docker. It's free. It's small. And it's right in your browser. Oh, did I mention it is also real-time?
|
Dozzle is a log viewer for Docker. It's free. It's small. And it's right in your browser. Oh, did I mention it is also real-time?
|
||||||
|
|
||||||
While dozzle should work for most, it is not meant to be a full logging solution. For enterprise use, I recommend you look at [Loggly](https://www.loggly.com), [Papertrail](https://papertrailapp.com) or [Kibana](https://www.elastic.co/products/kibana).
|
While dozzle should work for most, it is not meant to be a full logging solution. For enterprise use, I recommend you look at [Loggly](https://www.loggly.com), [Papertrail](https://papertrailapp.com) or [Kibana](https://www.elastic.co/products/kibana).
|
||||||
|
|
||||||
But if you don't want to pay for those service, then you are in luck! Dozzle will be able capture all logs from your containers and send them in real-time to your browser. Installation is also very easy.
|
But if you don't want to pay for those services, then you are in luck! Dozzle will be able to capture all logs from your containers and send them in real-time to your browser. Installation is also very easy.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Getting dozzle
|
## Getting dozzle
|
||||||
|
|
||||||
Dozzle is a very small Docker container (8.6MB virtual). Pull the latest release from the index:
|
Dozzle is a very small Docker container (4 MB compressed). Pull the latest release from the index:
|
||||||
|
|
||||||
$ docker pull amir20/dozzle:latest
|
$ docker pull amir20/dozzle:latest
|
||||||
|
|
||||||
@@ -24,11 +30,21 @@ dozzle will be available at [http://localhost:8888/](http://localhost:8888/). Yo
|
|||||||
|
|
||||||
#### Security
|
#### Security
|
||||||
|
|
||||||
dozzle doesn't support authentication out of the box. You can control the device dozzle binds to by passing `-addr` parameter. For example,
|
dozzle doesn't support authentication out of the box. You can control the device dozzle binds to by passing `--addr` parameter. For example,
|
||||||
|
|
||||||
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8888:1224 amir20/dozzle:latest -addr localhost:1224
|
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8888:1224 amir20/dozzle:latest --addr localhost:1224
|
||||||
|
|
||||||
|
will bind to `localhost` on port `1224`. You can then use a reverse proxy to control who can see dozzle.
|
||||||
|
|
||||||
|
#### Changing base URL
|
||||||
|
|
||||||
|
dozzle by default mounts to "/". If you want to control the base path you can use the `--base` option. For example, if you want to mount at "/foobar",
|
||||||
|
then you can override by using `--base /foobar`.
|
||||||
|
|
||||||
|
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8080:8080 amir20/dozzle:latest --base /foobar
|
||||||
|
|
||||||
|
dozzle will be available at [http://localhost:8080/foobar/](http://localhost:8080/foobar/).
|
||||||
|
|
||||||
will bind to `localhost` on port `1224`. You can then use use reverse proxy to control who can see dozzle.
|
|
||||||
|
|
||||||
#### Environment variable, DOCKER_API_VERSION
|
#### Environment variable, DOCKER_API_VERSION
|
||||||
|
|
||||||
@@ -36,7 +52,7 @@ If you see
|
|||||||
|
|
||||||
2018/10/31 08:53:17 Error response from daemon: client version 1.40 is too new. Maximum supported API version is 1.38
|
2018/10/31 08:53:17 Error response from daemon: client version 1.40 is too new. Maximum supported API version is 1.38
|
||||||
|
|
||||||
Then you need to modify `DOCKER_API_VERSION` to let dozzle know which version of the API is supported. By default, `DOCKER_API_VERSION=1.38` and you can change it to by passing `-e` flag. For example, this would change the `DOCKER_API_VERSION` to `1.20`
|
Then you need to modify `DOCKER_API_VERSION` to let dozzle know which version of the API is supported. By default, `DOCKER_API_VERSION=1.38` and you can change it by passing `-e` flag. For example, this would change the `DOCKER_API_VERSION` to `1.20`
|
||||||
|
|
||||||
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -e DOCKER_API_VERSION=1.20 -p 8888:8080 amir20/dozzle:latest
|
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -e DOCKER_API_VERSION=1.20 -p 8888:8080 amir20/dozzle:latest
|
||||||
|
|
||||||
|
|||||||
77
__snapshots__/dozzle.snapshot
Normal file
77
__snapshots__/dozzle.snapshot
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/* snapshot: Test_createRoutes_foobar */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
|
||||||
|
foo page
|
||||||
|
|
||||||
|
/* snapshot: Test_createRoutes_index */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
|
||||||
|
index page
|
||||||
|
|
||||||
|
/* snapshot: Test_createRoutes_redirect */
|
||||||
|
HTTP/1.1 301 Moved Permanently
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html; charset=utf-8
|
||||||
|
Location: /foobar/
|
||||||
|
|
||||||
|
<a href="/foobar/">Moved Permanently</a>.
|
||||||
|
|
||||||
|
/* snapshot: Test_createRoutes_version */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
|
||||||
|
dev
|
||||||
|
none
|
||||||
|
unknown
|
||||||
|
|
||||||
|
/* snapshot: Test_handler_listContainers_happy */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
|
||||||
|
[{"id":"1234567890","names":null,"name":"test","image":"image","imageId":"image_id","command":"command","created":0,"state":"state","status":"status"}]
|
||||||
|
|
||||||
|
/* snapshot: Test_handler_streamEvents_error */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Cache-Control: no-cache
|
||||||
|
Connection: keep-alive
|
||||||
|
Content-Type: text/event-stream
|
||||||
|
|
||||||
|
/* snapshot: Test_handler_streamEvents_error_request */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Cache-Control: no-cache
|
||||||
|
Connection: keep-alive
|
||||||
|
Content-Type: text/event-stream
|
||||||
|
|
||||||
|
/* snapshot: Test_handler_streamEvents_happy */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Cache-Control: no-cache
|
||||||
|
Connection: keep-alive
|
||||||
|
Content-Type: text/event-stream
|
||||||
|
|
||||||
|
event: containers-changed
|
||||||
|
data: start
|
||||||
|
|
||||||
|
/* snapshot: Test_handler_streamLogs_error_reading */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Cache-Control: no-cache
|
||||||
|
Connection: keep-alive
|
||||||
|
Content-Type: text/event-stream
|
||||||
|
|
||||||
|
/* snapshot: Test_handler_streamLogs_happy */
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Cache-Control: no-cache
|
||||||
|
Connection: keep-alive
|
||||||
|
Content-Type: text/event-stream
|
||||||
|
|
||||||
|
data: INFO Testing logs...
|
||||||
@@ -1,43 +1,98 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div class="columns is-marginless">
|
<div class="columns is-marginless">
|
||||||
<aside class="column menu is-2 section">
|
<aside class="column menu is-2-desktop is-3-tablet">
|
||||||
<h1 class="title has-text-warning">Dozzle</h1>
|
<a
|
||||||
<p class="menu-label">Containers</p>
|
role="button"
|
||||||
<ul class="menu-list">
|
class="navbar-burger burger is-white is-hidden-tablet is-pulled-right"
|
||||||
|
@click="showNav = !showNav"
|
||||||
|
:class="{ 'is-active': showNav }"
|
||||||
|
>
|
||||||
|
<span></span> <span></span> <span></span>
|
||||||
|
</a>
|
||||||
|
<h1 class="title has-text-warning is-marginless">Dozzle</h1>
|
||||||
|
<p class="menu-label is-hidden-mobile" :class="{ 'is-active': showNav }">Containers</p>
|
||||||
|
<ul class="menu-list is-hidden-mobile" :class="{ 'is-active': showNav }">
|
||||||
<li v-for="item in containers">
|
<li v-for="item in containers">
|
||||||
<router-link
|
<router-link :to="{ name: 'container', params: { id: item.id, name: item.name } }" active-class="is-active">
|
||||||
:to="{ name: 'container', params: { id: item.Id } }"
|
<div class="hide-overflow">{{ item.name }}</div>
|
||||||
active-class="is-active"
|
|
||||||
class="tooltip is-tooltip-right is-tooltip-info"
|
|
||||||
:data-tooltip="item.Names[0]"
|
|
||||||
>
|
|
||||||
<div class="hide-overflow">{{ item.Names[0] }}</div>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</aside>
|
</aside>
|
||||||
<div class="column is-offset-2"><router-view></router-view></div>
|
<div class="column is-offset-2-desktop is-offset-3-tablet"><router-view></router-view></div>
|
||||||
|
<vue-headful :title="title" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
let es;
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
containers: []
|
title: "Dozzle",
|
||||||
|
containers: [],
|
||||||
|
showNav: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
this.containers = await (await fetch(`/api/containers.json`)).json();
|
await this.fetchContainerList();
|
||||||
|
this.title = `${this.containers.length} containers - Dozzle`;
|
||||||
|
es = new EventSource(`${BASE_PATH}/api/events/stream`);
|
||||||
|
es.addEventListener("containers-changed", e => setTimeout(this.fetchContainerList, 1000), false);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (es) {
|
||||||
|
es.close();
|
||||||
|
es = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async fetchContainerList() {
|
||||||
|
this.containers = await (await fetch(`${BASE_PATH}/api/containers.json`)).json();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(to, from) {
|
||||||
|
this.showNav = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
|
.is-hidden-mobile.is-active {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-burger {
|
||||||
|
height: 2.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
aside {
|
aside {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding-right: 0;
|
z-index: 2;
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
@media screen and (min-width: 769px) {
|
||||||
|
& {
|
||||||
|
height: 100vh;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
& {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-label {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hide-overflow {
|
.hide-overflow {
|
||||||
@@ -45,4 +100,8 @@ aside {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.burger.is-white {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Dozzle</title>
|
<title>Dozzle</title>
|
||||||
<link href="https://fonts.googleapis.com/css?family=Roboto|Roboto+Mono|Gafata" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Roboto|Roboto+Mono|Gafata" rel="stylesheet" />
|
||||||
<link href="./styles.scss" rel="stylesheet">
|
<link rel="manifest" href="manifest.webmanifest" />
|
||||||
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
|
<link href="styles.scss" rel="stylesheet" />
|
||||||
</head>
|
<script>
|
||||||
|
window["BASE_PATH"] = "{{ .Base }}";
|
||||||
|
</script>
|
||||||
|
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
<body class="is-dark">
|
<body class="is-dark">
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script src="/main.js"></script>
|
<script src="main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import VueRouter from "vue-router";
|
import VueRouter from "vue-router";
|
||||||
|
import vueHeadful from "vue-headful";
|
||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import Container from "./pages/Container.vue";
|
import Container from "./pages/Container.vue";
|
||||||
import Index from "./pages/Index.vue";
|
import Index from "./pages/Index.vue";
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
Vue.component("vue-headful", vueHeadful);
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@@ -22,6 +24,7 @@ const routes = [
|
|||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
mode: "history",
|
mode: "history",
|
||||||
|
base: BASE_PATH + "/",
|
||||||
routes
|
routes
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
9
assets/manifest.webmanifest
Normal file
9
assets/manifest.webmanifest
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "Dozzle Log Viewer",
|
||||||
|
"short_name": "Dozzle",
|
||||||
|
"theme_color": "#111111",
|
||||||
|
"background_color": "#111111",
|
||||||
|
"display": "standalone",
|
||||||
|
"scope": "/",
|
||||||
|
"start_url": "/"
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<scrollbar-notification :messages="messages"></scrollbar-notification>
|
<scrollbar-notification :messages="messages"></scrollbar-notification>
|
||||||
|
<vue-headful :title="title" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
import { formatRelative } from "date-fns";
|
import { formatRelative } from "date-fns";
|
||||||
import ScrollbarNotification from "../components/ScrollbarNotification";
|
import ScrollbarNotification from "../components/ScrollbarNotification";
|
||||||
|
|
||||||
let ws = null;
|
let es = null;
|
||||||
let nextId = 0;
|
let nextId = 0;
|
||||||
const parseMessage = data => {
|
const parseMessage = data => {
|
||||||
const date = new Date(data.substring(0, 30));
|
const date = new Date(data.substring(0, 30));
|
||||||
@@ -29,22 +30,25 @@ const parseMessage = data => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["id"],
|
props: ["id", "name"],
|
||||||
name: "Container",
|
name: "Container",
|
||||||
components: {
|
components: {
|
||||||
ScrollbarNotification
|
ScrollbarNotification
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
messages: []
|
messages: [],
|
||||||
|
title: ""
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadLogs(this.id);
|
this.loadLogs(this.id);
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
ws.close();
|
if (es) {
|
||||||
ws = null;
|
es.close();
|
||||||
|
es = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
id(newValue, oldValue) {
|
id(newValue, oldValue) {
|
||||||
@@ -55,19 +59,14 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadLogs(id) {
|
loadLogs(id) {
|
||||||
if (ws) {
|
if (es) {
|
||||||
ws.close();
|
es.close();
|
||||||
ws = null;
|
es = null;
|
||||||
this.messages = [];
|
this.messages = [];
|
||||||
}
|
}
|
||||||
ws = new WebSocket(`ws://${window.location.host}/api/logs?id=${this.id}`);
|
es = new EventSource(`${BASE_PATH}/api/logs/stream?id=${id}`);
|
||||||
ws.onopen = e => console.log("Connection opened.");
|
es.onmessage = e => this.messages.push(parseMessage(e.data));
|
||||||
ws.onclose = e => console.log("Connection closed.");
|
this.title = `${this.name} - Dozzle`;
|
||||||
ws.onerror = e => console.error("Connection error: " + e.data);
|
|
||||||
ws.onmessage = e => {
|
|
||||||
const message = parseMessage(e.data);
|
|
||||||
this.messages.push(message);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -92,4 +91,8 @@ export default {
|
|||||||
.is-fullheight {
|
.is-fullheight {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ $menu-item-active-background-color: hsl(171, 100%, 41%);
|
|||||||
$menu-item-color: hsl(0, 6%, 87%);
|
$menu-item-color: hsl(0, 6%, 87%);
|
||||||
|
|
||||||
@import "../node_modules/bulma/bulma.sass";
|
@import "../node_modules/bulma/bulma.sass";
|
||||||
@import "../node_modules/bulma-tooltip/src/sass";
|
|
||||||
|
|
||||||
.is-dark {
|
.is-dark {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
|
|||||||
BIN
demo.gif
BIN
demo.gif
Binary file not shown.
|
Before Width: | Height: | Size: 41 MiB After Width: | Height: | Size: 24 MiB |
130
docker/client.go
Normal file
130
docker/client.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/events"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type dockerClient struct {
|
||||||
|
cli dockerProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
type dockerProxy interface {
|
||||||
|
ContainerList(context.Context, types.ContainerListOptions) ([]types.Container, error)
|
||||||
|
ContainerLogs(context.Context, string, types.ContainerLogsOptions) (io.ReadCloser, error)
|
||||||
|
Events(context.Context, types.EventsOptions) (<-chan events.Message, <-chan error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client is a proxy around the docker client
|
||||||
|
type Client interface {
|
||||||
|
ListContainers() ([]Container, error)
|
||||||
|
ContainerLogs(ctx context.Context, id string) (<-chan string, <-chan error)
|
||||||
|
Events(ctx context.Context) (<-chan events.Message, <-chan error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new instance of Client
|
||||||
|
func NewClient() Client {
|
||||||
|
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return &dockerClient{cli}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dockerClient) ListContainers() ([]Container, error) {
|
||||||
|
list, err := d.cli.ContainerList(context.Background(), types.ContainerListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var containers []Container
|
||||||
|
for _, c := range list {
|
||||||
|
|
||||||
|
container := Container{
|
||||||
|
ID: c.ID[:12],
|
||||||
|
Names: c.Names,
|
||||||
|
Name: strings.TrimPrefix(c.Names[0], "/"),
|
||||||
|
Image: c.Image,
|
||||||
|
ImageID: c.ImageID,
|
||||||
|
Command: c.Command,
|
||||||
|
Created: c.Created,
|
||||||
|
State: c.State,
|
||||||
|
Status: c.Status,
|
||||||
|
}
|
||||||
|
containers = append(containers, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(containers, func(i, j int) bool {
|
||||||
|
return containers[i].Name < containers[j].Name
|
||||||
|
})
|
||||||
|
|
||||||
|
if containers == nil {
|
||||||
|
containers = []Container{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return containers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dockerClient) ContainerLogs(ctx context.Context, id string) (<-chan string, <-chan error) {
|
||||||
|
tail := "300"
|
||||||
|
if value, ok := os.LookupEnv("TAIL_SIZE"); ok {
|
||||||
|
tail = value
|
||||||
|
}
|
||||||
|
options := types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: tail, Timestamps: true}
|
||||||
|
reader, err := d.cli.ContainerLogs(ctx, id, options)
|
||||||
|
errChannel := make(chan error, 1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
errChannel <- err
|
||||||
|
close(errChannel)
|
||||||
|
return nil, errChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
messages := make(chan string)
|
||||||
|
go func() {
|
||||||
|
<-ctx.Done()
|
||||||
|
reader.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(messages)
|
||||||
|
defer close(errChannel)
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
hdr := make([]byte, 8)
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
for {
|
||||||
|
_, err := reader.Read(hdr)
|
||||||
|
if err != nil {
|
||||||
|
errChannel <- err
|
||||||
|
break
|
||||||
|
}
|
||||||
|
count := binary.BigEndian.Uint32(hdr[4:])
|
||||||
|
_, err = io.CopyN(&buffer, reader, int64(count))
|
||||||
|
if err != nil {
|
||||||
|
errChannel <- err
|
||||||
|
break
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case messages <- buffer.String():
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
buffer.Reset()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return messages, errChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dockerClient) Events(ctx context.Context) (<-chan events.Message, <-chan error) {
|
||||||
|
return d.cli.Events(ctx, types.EventsOptions{})
|
||||||
|
}
|
||||||
140
docker/client_test.go
Normal file
140
docker/client_test.go
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockedProxy struct {
|
||||||
|
mock.Mock
|
||||||
|
dockerProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockedProxy) ContainerList(context.Context, types.ContainerListOptions) ([]types.Container, error) {
|
||||||
|
args := m.Called()
|
||||||
|
containers, ok := args.Get(0).([]types.Container)
|
||||||
|
if !ok && args.Get(0) != nil {
|
||||||
|
panic("containers is not of type []types.Container")
|
||||||
|
}
|
||||||
|
return containers, args.Error(1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockedProxy) ContainerLogs(ctx context.Context, id string, options types.ContainerLogsOptions) (io.ReadCloser, error) {
|
||||||
|
args := m.Called(ctx, id)
|
||||||
|
reader, ok := args.Get(0).(io.ReadCloser)
|
||||||
|
if !ok && args.Get(0) != nil {
|
||||||
|
panic("reader is not of type io.ReadCloser")
|
||||||
|
}
|
||||||
|
return reader, args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_dockerClient_ListContainers_null(t *testing.T) {
|
||||||
|
proxy := new(mockedProxy)
|
||||||
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(nil, nil)
|
||||||
|
client := &dockerClient{proxy}
|
||||||
|
|
||||||
|
list, err := client.ListContainers()
|
||||||
|
assert.Empty(t, list, "list should be empty")
|
||||||
|
require.NoError(t, err, "error should not return an error.")
|
||||||
|
|
||||||
|
proxy.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_dockerClient_ListContainers_error(t *testing.T) {
|
||||||
|
proxy := new(mockedProxy)
|
||||||
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(nil, errors.New("test"))
|
||||||
|
client := &dockerClient{proxy}
|
||||||
|
|
||||||
|
list, err := client.ListContainers()
|
||||||
|
assert.Nil(t, list, "list should be nil")
|
||||||
|
require.Error(t, err, "test.")
|
||||||
|
|
||||||
|
proxy.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_dockerClient_ListContainers_happy(t *testing.T) {
|
||||||
|
containers := []types.Container{
|
||||||
|
{
|
||||||
|
ID: "abcdefghijklmnopqrst",
|
||||||
|
Names: []string{"/z_test_container"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "1234567890_abcxyzdef",
|
||||||
|
Names: []string{"/a_test_container"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy := new(mockedProxy)
|
||||||
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
||||||
|
client := &dockerClient{proxy}
|
||||||
|
|
||||||
|
list, err := client.ListContainers()
|
||||||
|
require.NoError(t, err, "error should not return an error.")
|
||||||
|
|
||||||
|
assert.Equal(t, list, []Container{
|
||||||
|
{
|
||||||
|
ID: "1234567890_a",
|
||||||
|
Name: "a_test_container",
|
||||||
|
Names: []string{"/a_test_container"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "abcdefghijkl",
|
||||||
|
Name: "z_test_container",
|
||||||
|
Names: []string{"/z_test_container"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
proxy.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_dockerClient_ContainerLogs_happy(t *testing.T) {
|
||||||
|
id := "123456"
|
||||||
|
|
||||||
|
proxy := new(mockedProxy)
|
||||||
|
expected := "INFO Testing logs..."
|
||||||
|
b := make([]byte, 8)
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint32(b[4:], uint32(len(expected)))
|
||||||
|
b = append(b, []byte(expected)...)
|
||||||
|
|
||||||
|
var reader io.ReadCloser
|
||||||
|
reader = ioutil.NopCloser(bytes.NewReader(b))
|
||||||
|
proxy.On("ContainerLogs", mock.Anything, id, mock.Anything).Return(reader, nil)
|
||||||
|
|
||||||
|
client := &dockerClient{proxy}
|
||||||
|
messages, _ := client.ContainerLogs(context.Background(), id)
|
||||||
|
|
||||||
|
actual, _ := <-messages
|
||||||
|
assert.Equal(t, expected, actual, "message doesn't match expected")
|
||||||
|
|
||||||
|
_, ok := <-messages
|
||||||
|
assert.False(t, ok, "channel should have been closed")
|
||||||
|
proxy.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_dockerClient_ContainerLogs_error(t *testing.T) {
|
||||||
|
id := "123456"
|
||||||
|
proxy := new(mockedProxy)
|
||||||
|
proxy.On("ContainerLogs", mock.Anything, id, mock.Anything).Return(nil, errors.New("test"))
|
||||||
|
|
||||||
|
client := &dockerClient{proxy}
|
||||||
|
messages, err := client.ContainerLogs(context.Background(), id)
|
||||||
|
|
||||||
|
assert.Nil(t, messages, "messages should be nil")
|
||||||
|
|
||||||
|
e, _ := <-err
|
||||||
|
assert.Error(t, e, "error should have been returned")
|
||||||
|
_, ok := <-err
|
||||||
|
assert.False(t, ok, "error channel should have been closed")
|
||||||
|
proxy.AssertExpectations(t)
|
||||||
|
}
|
||||||
14
docker/types.go
Normal file
14
docker/types.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
// Container represents an internal representation of docker containers
|
||||||
|
type Container struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Names []string `json:"names"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Image string `json:"image"`
|
||||||
|
ImageID string `json:"imageId"`
|
||||||
|
Command string `json:"command"`
|
||||||
|
Created int64 `json:"created"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
48
go.mod
Normal file
48
go.mod
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
module github.com/amir20/dozzle
|
||||||
|
|
||||||
|
replace github.com/docker/docker v0.0.0-20170601211448-f5ec1e2936dc => github.com/docker/engine v0.0.0-20180718150940-a3ef7e9a9bda
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||||
|
github.com/Microsoft/go-winio v0.4.12 // indirect
|
||||||
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||||
|
github.com/beme/abide v0.0.0-20181227202223-4c487ef9d895
|
||||||
|
github.com/cespare/reflex v0.2.0 // indirect
|
||||||
|
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||||
|
github.com/docker/docker v1.13.1
|
||||||
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
|
github.com/docker/go-units v0.3.3 // indirect
|
||||||
|
github.com/gobuffalo/envy v1.6.15 // indirect
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20190224160250-d04dd98aca5b // indirect
|
||||||
|
github.com/gobuffalo/packr v1.22.0
|
||||||
|
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754 // indirect
|
||||||
|
github.com/gogo/protobuf v1.2.1 // indirect
|
||||||
|
github.com/golang/protobuf v1.3.0 // indirect
|
||||||
|
github.com/google/go-cmp v0.2.0 // indirect
|
||||||
|
github.com/gorilla/mux v1.7.0
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.0
|
||||||
|
github.com/ogier/pflag v0.0.1 // indirect
|
||||||
|
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
|
||||||
|
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.2.2 // indirect
|
||||||
|
github.com/sirupsen/logrus v1.3.0
|
||||||
|
github.com/spf13/pflag v1.0.3
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20190309122539-980fc434d28e // indirect
|
||||||
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 // indirect
|
||||||
|
gotest.tools v2.2.0+incompatible // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
// github.com/docker/engine v18.06.1-ce
|
||||||
|
replace github.com/docker/docker => github.com/docker/engine v0.0.0-20180816081446-320063a2ad06
|
||||||
|
|
||||||
|
// github.com/docker/distribution master
|
||||||
|
// a proper tagged release is expected in early fall(September 2018)
|
||||||
|
// see; https://github.com/docker/distribution/issues/2693
|
||||||
|
replace github.com/docker/distribution => github.com/docker/distribution v2.6.0-rc.1.0.20180820212402-02bf4a2887a4+incompatible
|
||||||
474
go.sum
Normal file
474
go.sum
Normal file
@@ -0,0 +1,474 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
|
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
|
||||||
|
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||||
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||||
|
github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
github.com/beme/abide v0.0.0-20181227202223-4c487ef9d895 h1:gKYojZRR5Nko2XJrcAEiQpBQbir/wzsNqGqtOjKJU6g=
|
||||||
|
github.com/beme/abide v0.0.0-20181227202223-4c487ef9d895/go.mod h1:6+8gCKsZnxzhGTmKRh4BSkLos9CbWRJNcrp55We4SqQ=
|
||||||
|
github.com/cespare/reflex v0.2.0 h1:6d9WpWJseKjJvZEevKP7Pk42nPx2+BUTqmhNk8wZPwM=
|
||||||
|
github.com/cespare/reflex v0.2.0/go.mod h1:ooqOLJ4algvHP/oYvKWfWJ9tFUzCLDk5qkIJduMYrgI=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
|
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||||
|
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/docker/distribution v2.6.0-rc.1.0.20180820212402-02bf4a2887a4+incompatible h1:x3ZXVm6ovZmIA+s9MEdSXjdyd5Zbd5VPBcda2KrSuWk=
|
||||||
|
github.com/docker/distribution v2.6.0-rc.1.0.20180820212402-02bf4a2887a4+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
|
github.com/docker/engine v0.0.0-20180816081446-320063a2ad06 h1:CcxlLWAS/9b46iqHDTBlALJZF9atXVNjeymdCNrUfnY=
|
||||||
|
github.com/docker/engine v0.0.0-20180816081446-320063a2ad06/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY=
|
||||||
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
|
github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
|
||||||
|
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
|
github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/gobuffalo/buffalo v0.12.8-0.20181004233540-fac9bb505aa8/go.mod h1:sLyT7/dceRXJUxSsE813JTQtA3Eb1vjxWfo/N//vXIY=
|
||||||
|
github.com/gobuffalo/buffalo v0.13.0/go.mod h1:Mjn1Ba9wpIbpbrD+lIDMy99pQ0H0LiddMIIDGse7qT4=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.0.2/go.mod h1:pOp/uF7X3IShFHyobahTkTLZaeUXwb0GrUTb9ngJWTs=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.0.4/go.mod h1:pWS1vjtQ6uD17MVFWf7i3zfThrEKWlI5+PYLw/NaDB4=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.4.3/go.mod h1:uCzTY0woez4nDMdQjkcOYKanngeUVRO2HZi7ezmAjWY=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.5.1/go.mod h1:jbmwSZK5+PiAP9cC09VQOrGMZFCa/P0UMlIS3O12r5w=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.6.4/go.mod h1:/+N1aophkA2jZ1ifB2O3Y9yGwu6gKOVMtUmJnbg+OZI=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.6.5/go.mod h1:0HVkbgrVs/MnPZ/FOseDMVanCTm2RNcdM0PuXcL1NNI=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.6.7/go.mod h1:ZGZRkzz2PiKWHs0z7QsPBOTo2EpcGRArMEym6ghKYgk=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.6.9/go.mod h1:yYlYTrPdMCz+6/+UaXg5Jm4gN3xhsvsQ2ygVatZV5vw=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.6.11/go.mod h1:eAA6xJIL8OuynJZ8amXjRmHND6YiusVAaJdHDN1Lu8Q=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.8.2/go.mod h1:9te6/VjEQ7pKp7lXlDIMqzxgGpjlKoAcAANdCgoR960=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.8.3/go.mod h1:IAWq6vjZJVXebIq2qGTLOdlXzmpyTZ5iJG5b59fza5U=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.9.4/go.mod h1:grCV6DGsQlVzQwk6XdgcL3ZPgLm9BVxlBmXPMF8oBHI=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.10.0/go.mod h1:4osg8d9s60txLuGwXnqH+RCjPHj9K466cDFRl3PErHI=
|
||||||
|
github.com/gobuffalo/buffalo-plugins v1.11.0/go.mod h1:rtIvAYRjYibgmWhnjKmo7OadtnxuMG5ZQLr25ozAzjg=
|
||||||
|
github.com/gobuffalo/buffalo-pop v1.0.5/go.mod h1:Fw/LfFDnSmB/vvQXPvcXEjzP98Tc+AudyNWUBWKCwQ8=
|
||||||
|
github.com/gobuffalo/envy v1.6.4/go.mod h1:Abh+Jfw475/NWtYMEt+hnJWRiC8INKWibIMyNt1w2Mc=
|
||||||
|
github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||||
|
github.com/gobuffalo/envy v1.6.6/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||||
|
github.com/gobuffalo/envy v1.6.7/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||||
|
github.com/gobuffalo/envy v1.6.8/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||||
|
github.com/gobuffalo/envy v1.6.9/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||||
|
github.com/gobuffalo/envy v1.6.10/go.mod h1:X0CFllQjTV5ogsnUrg+Oks2yTI+PU2dGYBJOEI2D1Uo=
|
||||||
|
github.com/gobuffalo/envy v1.6.11/go.mod h1:Fiq52W7nrHGDggFPhn2ZCcHw4u/rqXkqo+i7FB6EAcg=
|
||||||
|
github.com/gobuffalo/envy v1.6.12/go.mod h1:qJNrJhKkZpEW0glh5xP2syQHH5kgdmgsKss2Kk8PTP0=
|
||||||
|
github.com/gobuffalo/envy v1.6.15 h1:OsV5vOpHYUpP7ZLS6sem1y40/lNX1BZj+ynMiRi21lQ=
|
||||||
|
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||||
|
github.com/gobuffalo/events v1.0.3/go.mod h1:Txo8WmqScapa7zimEQIwgiJBvMECMe9gJjsKNPN3uZw=
|
||||||
|
github.com/gobuffalo/events v1.0.7/go.mod h1:z8txf6H9jWhQ5Scr7YPLWg/cgXBRj8Q4uYI+rsVCCSQ=
|
||||||
|
github.com/gobuffalo/events v1.0.8/go.mod h1:A5KyqT1sA+3GJiBE4QKZibse9mtOcI9nw8gGrDdqYGs=
|
||||||
|
github.com/gobuffalo/events v1.1.3/go.mod h1:9yPGWYv11GENtzrIRApwQRMYSbUgCsZ1w6R503fCfrk=
|
||||||
|
github.com/gobuffalo/events v1.1.4/go.mod h1:09/YRRgZHEOts5Isov+g9X2xajxdvOAcUuAHIX/O//A=
|
||||||
|
github.com/gobuffalo/events v1.1.5/go.mod h1:3YUSzgHfYctSjEjLCWbkXP6djH2M+MLaVRzb4ymbAK0=
|
||||||
|
github.com/gobuffalo/events v1.1.7/go.mod h1:6fGqxH2ing5XMb3EYRq9LEkVlyPGs4oO/eLzh+S8CxY=
|
||||||
|
github.com/gobuffalo/events v1.1.8/go.mod h1:UFy+W6X6VbCWS8k2iT81HYX65dMtiuVycMy04cplt/8=
|
||||||
|
github.com/gobuffalo/events v1.1.9/go.mod h1:/0nf8lMtP5TkgNbzYxR6Bl4GzBy5s5TebgNTdRfRbPM=
|
||||||
|
github.com/gobuffalo/fizz v1.0.12/go.mod h1:C0sltPxpYK8Ftvf64kbsQa2yiCZY4RZviurNxXdAKwc=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20180907193754-dc14d8acaf9f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181002182613-4571df4b1daf/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181007231023-ae7ed6bfe683/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181018182602-fd24a256709f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181019110701-3d6f0b585514/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181024204909-8f6be1a8c6c2/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181104133451-1f6e9779237a/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181114183036-47375f6d8328/go.mod h1:0HvNbHdfh+WOvDSIASqJOSxTOWSxCCUF++k/Y53v9rI=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20181210151238-24a2b68e0316/go.mod h1:en58vff74S9b99Eg42Dr+/9yPu437QjlNsO/hBYPuOk=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20190104192022-4af577e09bf2/go.mod h1:en58vff74S9b99Eg42Dr+/9yPu437QjlNsO/hBYPuOk=
|
||||||
|
github.com/gobuffalo/flect v0.0.0-20190117212819-a62e61d96794/go.mod h1:397QT6v05LkZkn07oJXXT6y9FCfwC8Pug0WA2/2mE9k=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20180924032338-7af3a40f2252/go.mod h1:tUTQOogrr7tAQnhajMSH6rv1BVev34H2sa1xNHMy94g=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181003150629-3786a0744c5d/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181005145118-318a41a134cc/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181007153042-b8de7d566757/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181012161047-33e5f43d83a6/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181017160347-90a774534246/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181024195656-51392254bf53/go.mod h1:o9GEH5gn5sCKLVB5rHFC4tq40rQ3VRUzmx6WwmaqISE=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181025145300-af3f81d526b8/go.mod h1:uZ1fFYvdcP8mu0B/Ynarf6dsGvp7QFIpk/QACUuFUVI=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181027191429-94d6cfb5c7fc/go.mod h1:x7SkrQQBx204Y+O9EwRXeszLJDTaWN0GnEasxgLrQTA=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181027195209-3887b7171c4f/go.mod h1:JbKx8HSWICu5zyqWOa0dVV1pbbXOHusrSzQUprW6g+w=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181106193839-7dcb0924caf1/go.mod h1:x61yHxvbDCgQ/7cOAbJCacZQuHgB0KMSzoYcw5debjU=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181107223128-f18346459dbe/go.mod h1:utQD3aKKEsdb03oR+Vi/6ztQb1j7pO10N3OBoowRcSU=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181114215459-0a4decd77f5d/go.mod h1:kN2KZ8VgXF9VIIOj/GM0Eo7YK+un4Q3tTreKOf0q1ng=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181119162812-e8ff4adce8bb/go.mod h1:BA9htSe4bZwBDJLe8CUkoqkypq3hn3+CkoHqVOW718E=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181127225641-2d959acc795b/go.mod h1:l54xLXNkteX/PdZ+HlgPk1qtcrgeOr3XUBBPDbH+7CQ=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181128191930-77e34f71ba2a/go.mod h1:FW/D9p7cEEOqxYA71/hnrkOWm62JZ5ZNxcNIVJEaWBU=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181203165245-fda8bcce96b1/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181203201232-849d2c9534ea/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181206121324-d6fb8a0dbe36/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181207164119-84844398a37d/go.mod h1:y0ysCHGGQf2T3vOhCrGHheYN54Y/REj0ayd0Suf4C/8=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20181211165820-e26c8466f14d/go.mod h1:sHnK+ZSU4e2feXP3PA29ouij6PUEiN+RCwECjCTB3yM=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20190104222617-a71664fc38e7/go.mod h1:QPsQ1FnhEsiU8f+O0qKWXz2RE4TiDqLVChWkBuh1WaY=
|
||||||
|
github.com/gobuffalo/genny v0.0.0-20190112155932-f31a84fcacf5/go.mod h1:CIaHCrSIuJ4il6ka3Hub4DR4adDrGoXGEEt2FbBxoIo=
|
||||||
|
github.com/gobuffalo/github_flavored_markdown v1.0.4/go.mod h1:uRowCdK+q8d/RF0Kt3/DSalaIXbb0De/dmTqMQdkQ4I=
|
||||||
|
github.com/gobuffalo/github_flavored_markdown v1.0.5/go.mod h1:U0643QShPF+OF2tJvYNiYDLDGDuQmJZXsf/bHOJPsMY=
|
||||||
|
github.com/gobuffalo/github_flavored_markdown v1.0.7/go.mod h1:w93Pd9Lz6LvyQXEG6DktTPHkOtCbr+arAD5mkwMzXLI=
|
||||||
|
github.com/gobuffalo/httptest v1.0.2/go.mod h1:7T1IbSrg60ankme0aDLVnEY0h056g9M1/ZvpVThtB7E=
|
||||||
|
github.com/gobuffalo/licenser v0.0.0-20180924033006-eae28e638a42/go.mod h1:Ubo90Np8gpsSZqNScZZkVXXAo5DGhTb+WYFIjlnog8w=
|
||||||
|
github.com/gobuffalo/licenser v0.0.0-20181025145548-437d89de4f75/go.mod h1:x3lEpYxkRG/XtGCUNkio+6RZ/dlOvLzTI9M1auIwFcw=
|
||||||
|
github.com/gobuffalo/licenser v0.0.0-20181027200154-58051a75da95/go.mod h1:BzhaaxGd1tq1+OLKObzgdCV9kqVhbTulxOpYbvMQWS0=
|
||||||
|
github.com/gobuffalo/licenser v0.0.0-20181109171355-91a2a7aac9a7/go.mod h1:m+Ygox92pi9bdg+gVaycvqE8RVSjZp7mWw75+K5NPHk=
|
||||||
|
github.com/gobuffalo/licenser v0.0.0-20181128165715-cc7305f8abed/go.mod h1:oU9F9UCE+AzI/MueCKZamsezGOOHfSirltllOVeRTAE=
|
||||||
|
github.com/gobuffalo/licenser v0.0.0-20181203160806-fe900bbede07/go.mod h1:ph6VDNvOzt1CdfaWC+9XwcBnlSTBz2j49PBwum6RFaU=
|
||||||
|
github.com/gobuffalo/licenser v0.0.0-20181211173111-f8a311c51159/go.mod h1:ve/Ue99DRuvnTaLq2zKa6F4KtHiYf7W046tDjuGYPfM=
|
||||||
|
github.com/gobuffalo/logger v0.0.0-20181022175615-46cfb361fc27/go.mod h1:8sQkgyhWipz1mIctHF4jTxmJh1Vxhp7mP8IqbljgJZo=
|
||||||
|
github.com/gobuffalo/logger v0.0.0-20181027144941-73d08d2bb969/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8=
|
||||||
|
github.com/gobuffalo/logger v0.0.0-20181027193913-9cf4dd0efe46/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8=
|
||||||
|
github.com/gobuffalo/logger v0.0.0-20181109185836-3feeab578c17/go.mod h1:oNErH0xLe+utO+OW8ptXMSA5DkiSEDW1u3zGIt8F9Ew=
|
||||||
|
github.com/gobuffalo/logger v0.0.0-20181117211126-8e9b89b7c264/go.mod h1:5etB91IE0uBlw9k756fVKZJdS+7M7ejVhmpXXiSFj0I=
|
||||||
|
github.com/gobuffalo/logger v0.0.0-20181127160119-5b956e21995c/go.mod h1:+HxKANrR9VGw9yN3aOAppJKvhO05ctDi63w4mDnKv2U=
|
||||||
|
github.com/gobuffalo/makr v1.1.5/go.mod h1:Y+o0btAH1kYAMDJW/TX3+oAXEu0bmSLLoC9mIFxtzOw=
|
||||||
|
github.com/gobuffalo/mapi v1.0.0/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||||
|
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||||
|
github.com/gobuffalo/meta v0.0.0-20181018155829-df62557efcd3/go.mod h1:XTTOhwMNryif3x9LkTTBO/Llrveezd71u3quLd0u7CM=
|
||||||
|
github.com/gobuffalo/meta v0.0.0-20181018192820-8c6cef77dab3/go.mod h1:E94EPzx9NERGCY69UWlcj6Hipf2uK/vnfrF4QD0plVE=
|
||||||
|
github.com/gobuffalo/meta v0.0.0-20181025145500-3a985a084b0a/go.mod h1:YDAKBud2FP7NZdruCSlmTmDOZbVSa6bpK7LJ/A/nlKg=
|
||||||
|
github.com/gobuffalo/meta v0.0.0-20181114191255-b130ebedd2f7/go.mod h1:K6cRZ29ozr4Btvsqkjvg5nDFTLOgTqf03KA70Ks0ypE=
|
||||||
|
github.com/gobuffalo/meta v0.0.0-20181127070345-0d7e59dd540b/go.mod h1:RLO7tMvE0IAKAM8wny1aN12pvEKn7EtkBLkUZR00Qf8=
|
||||||
|
github.com/gobuffalo/meta v0.0.0-20190120163247-50bbb1fa260d/go.mod h1:KKsH44nIK2gA8p0PJmRT9GvWJUdphkDUA8AJEvFWiqM=
|
||||||
|
github.com/gobuffalo/mw-basicauth v1.0.3/go.mod h1:dg7+ilMZOKnQFHDefUzUHufNyTswVUviCBgF244C1+0=
|
||||||
|
github.com/gobuffalo/mw-contenttype v0.0.0-20180802152300-74f5a47f4d56/go.mod h1:7EvcmzBbeCvFtQm5GqF9ys6QnCxz2UM1x0moiWLq1No=
|
||||||
|
github.com/gobuffalo/mw-csrf v0.0.0-20180802151833-446ff26e108b/go.mod h1:sbGtb8DmDZuDUQoxjr8hG1ZbLtZboD9xsn6p77ppcHo=
|
||||||
|
github.com/gobuffalo/mw-forcessl v0.0.0-20180802152810-73921ae7a130/go.mod h1:JvNHRj7bYNAMUr/5XMkZaDcw3jZhUZpsmzhd//FFWmQ=
|
||||||
|
github.com/gobuffalo/mw-i18n v0.0.0-20180802152014-e3060b7e13d6/go.mod h1:91AQfukc52A6hdfIfkxzyr+kpVYDodgAeT5cjX1UIj4=
|
||||||
|
github.com/gobuffalo/mw-paramlogger v0.0.0-20181005191442-d6ee392ec72e/go.mod h1:6OJr6VwSzgJMqWMj7TYmRUqzNe2LXu/W1rRW4MAz/ME=
|
||||||
|
github.com/gobuffalo/mw-tokenauth v0.0.0-20181001105134-8545f626c189/go.mod h1:UqBF00IfKvd39ni5+yI5MLMjAf4gX7cDKN/26zDOD6c=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181027182251-01ad393492c8/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181027190505-aafc0d02c411/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181027194105-7ae579e6d213/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181031195726-c82734870264/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181104210303-d376b15f8e96/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181111195323-b2e760a5f0ff/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181114190715-f25c5d2471d7/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181124090624-311c6248e5fb/go.mod h1:Foenia9ZvITEvG05ab6XpiD5EfBHPL8A6hush8SJ0o8=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181207120301-c49825f8f6f4/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20181212173646-eca3b8fd6687/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20190224160250-d04dd98aca5b h1:QlU2UkP7c/XJ994sM1Z8YN9tHsKeIOp7dyMqiLvyNt0=
|
||||||
|
github.com/gobuffalo/packd v0.0.0-20190224160250-d04dd98aca5b/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA=
|
||||||
|
github.com/gobuffalo/packr v1.13.7/go.mod h1:KkinLIn/n6+3tVXMwg6KkNvWwVsrRAz4ph+jgpk3Z24=
|
||||||
|
github.com/gobuffalo/packr v1.15.0/go.mod h1:t5gXzEhIviQwVlNx/+3SfS07GS+cZ2hn76WLzPp6MGI=
|
||||||
|
github.com/gobuffalo/packr v1.15.1/go.mod h1:IeqicJ7jm8182yrVmNbM6PR4g79SjN9tZLH8KduZZwE=
|
||||||
|
github.com/gobuffalo/packr v1.19.0/go.mod h1:MstrNkfCQhd5o+Ct4IJ0skWlxN8emOq8DsoT1G98VIU=
|
||||||
|
github.com/gobuffalo/packr v1.20.0/go.mod h1:JDytk1t2gP+my1ig7iI4NcVaXr886+N0ecUga6884zw=
|
||||||
|
github.com/gobuffalo/packr v1.21.0/go.mod h1:H00jGfj1qFKxscFJSw8wcL4hpQtPe1PfU2wa6sg/SR0=
|
||||||
|
github.com/gobuffalo/packr v1.22.0 h1:/YVd/GRGsu0QuoCJtlcWSVllobs4q3Xvx3nqxTvPyN0=
|
||||||
|
github.com/gobuffalo/packr v1.22.0/go.mod h1:Qr3Wtxr3+HuQEwWqlLnNW4t1oTvK+7Gc/Rnoi/lDFvA=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.8/go.mod h1:y60QCdzwuMwO2R49fdQhsjCPv7tLQFR0ayzxxla9zes=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.9/go.mod h1:fQqADRfZpEsgkc7c/K7aMew3n4aF1Kji7+lIZeR98Fc=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.10/go.mod h1:4CWWn4I5T3v4c1OsJ55HbHlUEKNWMITG5iIkdr4Px4w=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.11/go.mod h1:JoieH/3h3U4UmatmV93QmqyPUdf4wVM9HELaHEu+3fk=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.12/go.mod h1:FV1zZTsVFi1DSCboO36Xgs4pzCZBjB/tDV9Cz/lSaR8=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.13/go.mod h1:2Mp7GhBFMdJlOK8vGfl7SYtfMP3+5roE39ejlfjw0rA=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.14/go.mod h1:06otbrNvDKO1eNQ3b8hst+1010UooI2MFg+B2Ze4MV8=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.0.0-rc.15/go.mod h1:IMe7H2nJvcKXSF90y4X1rjYIRlNMJYCxEhssBXNZwWs=
|
||||||
|
github.com/gobuffalo/plush v3.7.16+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plush v3.7.20+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plush v3.7.21+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plush v3.7.22+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plush v3.7.23+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plush v3.7.30+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plush v3.7.31+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plush v3.7.32+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||||
|
github.com/gobuffalo/plushgen v0.0.0-20181128164830-d29dcb966cb2/go.mod h1:r9QwptTFnuvSaSRjpSp4S2/4e2D3tJhARYbvEBcKSb4=
|
||||||
|
github.com/gobuffalo/plushgen v0.0.0-20181203163832-9fc4964505c2/go.mod h1:opEdT33AA2HdrIwK1aibqnTJDVVKXC02Bar/GT1YRVs=
|
||||||
|
github.com/gobuffalo/plushgen v0.0.0-20181207152837-eedb135bd51b/go.mod h1:Lcw7HQbEVm09sAQrCLzIxuhFbB3nAgp4c55E+UlynR0=
|
||||||
|
github.com/gobuffalo/plushgen v0.0.0-20190104222512-177cd2b872b3/go.mod h1:tYxCozi8X62bpZyKXYHw1ncx2ZtT2nFvG42kuLwYjoc=
|
||||||
|
github.com/gobuffalo/pop v4.8.2+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg=
|
||||||
|
github.com/gobuffalo/pop v4.8.3+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg=
|
||||||
|
github.com/gobuffalo/pop v4.8.4+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg=
|
||||||
|
github.com/gobuffalo/release v1.0.35/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4=
|
||||||
|
github.com/gobuffalo/release v1.0.38/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4=
|
||||||
|
github.com/gobuffalo/release v1.0.42/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug=
|
||||||
|
github.com/gobuffalo/release v1.0.52/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug=
|
||||||
|
github.com/gobuffalo/release v1.0.53/go.mod h1:FdF257nd8rqhNaqtDWFGhxdJ/Ig4J7VcS3KL7n/a+aA=
|
||||||
|
github.com/gobuffalo/release v1.0.54/go.mod h1:Pe5/RxRa/BE8whDpGfRqSI7D1a0evGK1T4JDm339tJc=
|
||||||
|
github.com/gobuffalo/release v1.0.61/go.mod h1:mfIO38ujUNVDlBziIYqXquYfBF+8FDHUjKZgYC1Hj24=
|
||||||
|
github.com/gobuffalo/release v1.0.72/go.mod h1:NP5NXgg/IX3M5XmHmWR99D687/3Dt9qZtTK/Lbwc1hU=
|
||||||
|
github.com/gobuffalo/release v1.1.1/go.mod h1:Sluak1Xd6kcp6snkluR1jeXAogdJZpFFRzTYRs/2uwg=
|
||||||
|
github.com/gobuffalo/release v1.1.3/go.mod h1:CuXc5/m+4zuq8idoDt1l4va0AXAn/OSs08uHOfMVr8E=
|
||||||
|
github.com/gobuffalo/release v1.1.6/go.mod h1:18naWa3kBsqO0cItXZNJuefCKOENpbbUIqRL1g+p6z0=
|
||||||
|
github.com/gobuffalo/shoulders v1.0.1/go.mod h1:V33CcVmaQ4gRUmHKwq1fiTXuf8Gp/qjQBUL5tHPmvbA=
|
||||||
|
github.com/gobuffalo/syncx v0.0.0-20181120191700-98333ab04150/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||||
|
github.com/gobuffalo/syncx v0.0.0-20181120194010-558ac7de985f/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||||
|
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754 h1:tpom+2CJmpzAWj5/VEHync2rJGi+epHNIeRSWjzGA+4=
|
||||||
|
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||||
|
github.com/gobuffalo/tags v2.0.11+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY=
|
||||||
|
github.com/gobuffalo/tags v2.0.14+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY=
|
||||||
|
github.com/gobuffalo/tags v2.0.15+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY=
|
||||||
|
github.com/gobuffalo/uuid v2.0.3+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE=
|
||||||
|
github.com/gobuffalo/uuid v2.0.4+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE=
|
||||||
|
github.com/gobuffalo/uuid v2.0.5+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE=
|
||||||
|
github.com/gobuffalo/validate v2.0.3+incompatible/go.mod h1:N+EtDe0J8252BgfzQUChBgfd6L93m9weay53EWFVsMM=
|
||||||
|
github.com/gobuffalo/x v0.0.0-20181003152136-452098b06085/go.mod h1:WevpGD+5YOreDJznWevcn8NTmQEW5STSBgIkpkjzqXc=
|
||||||
|
github.com/gobuffalo/x v0.0.0-20181007152206-913e47c59ca7/go.mod h1:9rDPXaB3kXdKWzMc4odGQQdG2e2DIEmANy5aSJ9yesY=
|
||||||
|
github.com/gofrs/uuid v3.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||||
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||||
|
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||||
|
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
|
||||||
|
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
|
github.com/gorilla/sessions v1.1.2/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||||
|
github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||||
|
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||||
|
github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU=
|
||||||
|
github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||||
|
github.com/karrick/godirwalk v1.7.7/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||||
|
github.com/karrick/godirwalk v1.7.8/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/pty v1.1.3 h1:/Um6a/ZmD5tF7peoOJ5oN5KMQ0DrGVQSXLNwyckutPk=
|
||||||
|
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||||
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/markbates/deplist v1.0.4/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM=
|
||||||
|
github.com/markbates/deplist v1.0.5/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM=
|
||||||
|
github.com/markbates/going v1.0.2/go.mod h1:UWCk3zm0UKefHZ7l8BNqi26UyiEMniznk8naLdTcy6c=
|
||||||
|
github.com/markbates/grift v1.0.4/go.mod h1:wbmtW74veyx+cgfwFhlnnMWqhoz55rnHR47oMXzsyVs=
|
||||||
|
github.com/markbates/hmax v1.0.0/go.mod h1:cOkR9dktiESxIMu+65oc/r/bdY4bE8zZw3OLhLx0X2c=
|
||||||
|
github.com/markbates/inflect v1.0.0/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88=
|
||||||
|
github.com/markbates/inflect v1.0.1/go.mod h1:uv3UVNBe5qBIfCm8O8Q+DW+S1EopeyINj+Ikhc7rnCk=
|
||||||
|
github.com/markbates/inflect v1.0.3/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs=
|
||||||
|
github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs=
|
||||||
|
github.com/markbates/oncer v0.0.0-20180924031910-e862a676800b/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||||
|
github.com/markbates/oncer v0.0.0-20180924034138-723ad0170a46/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||||
|
github.com/markbates/oncer v0.0.0-20181014194634-05fccaae8fc4/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||||
|
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||||
|
github.com/markbates/refresh v1.4.10/go.mod h1:NDPHvotuZmTmesXxr95C9bjlw1/0frJwtME2dzcVKhc=
|
||||||
|
github.com/markbates/safe v1.0.0/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||||
|
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||||
|
github.com/markbates/sigtx v1.0.0/go.mod h1:QF1Hv6Ic6Ca6W+T+DL0Y/ypborFKyvUY9HmuCD4VeTc=
|
||||||
|
github.com/markbates/willie v1.0.9/go.mod h1:fsrFVWl91+gXpx/6dv715j7i11fYPfZ9ZGfH0DQzY7w=
|
||||||
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
|
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||||
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/monoculum/formam v0.0.0-20180901015400-4e68be1d79ba/go.mod h1:RKgILGEJq24YyJ2ban8EO0RUVSJlF1pGsEvoLEACr/Q=
|
||||||
|
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||||
|
github.com/ogier/pflag v0.0.1 h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750=
|
||||||
|
github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
|
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||||
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
|
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||||
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.0.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rogpeppe/go-internal v1.2.2 h1:J7U/N7eRtzjhs26d6GqMh2HBuXP8/Z64Densiiieafo=
|
||||||
|
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs=
|
||||||
|
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
|
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||||
|
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||||
|
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||||
|
github.com/shurcooL/highlight_go v0.0.0-20170515013102-78fb10f4a5f8/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||||
|
github.com/shurcooL/octicon v0.0.0-20180602230221-c42b0e3b24d9/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||||
|
github.com/sirupsen/logrus v1.1.0/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A=
|
||||||
|
github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
||||||
|
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||||
|
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
|
github.com/spf13/afero v1.2.0/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
|
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
|
||||||
|
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
|
github.com/unrolled/secure v0.0.0-20180918153822-f340ee86eb8b/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA=
|
||||||
|
github.com/unrolled/secure v0.0.0-20181005190816-ff9db2ff917f/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA=
|
||||||
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181024171144-74cb1d3d52f4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181025113841-85e1b3f9139a/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190102171810-8d7daa0c54b3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180816102801-aaf60122140d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181017193950-04a2e542c03f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181207154023-610586996380/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 h1:fY7Dsw114eJN4boqzVSbpVHO6rTdhq6/GnXeu+PKnzU=
|
||||||
|
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||||
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180921163948-d47a0f339242/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180927150500-dad3d9fb7b6e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181011152604-fa43e7bc11ba/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181022134430-8a28ead16f52/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181024145615-5cd93ef61a7c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181025063200-d989b31c8746/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181026064943-731415f00dce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181106135930-3a76605856fd/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190309122539-980fc434d28e h1:eFmUCjqCNXZTydmJBXWeJOHCWGd2My0J+jleBc2ntI0=
|
||||||
|
golang.org/x/sys v0.0.0-20190309122539-980fc434d28e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
|
||||||
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181003024731-2f84ea8ef872/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181006002542-f60d9635b16a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181013182035-5e66757b835f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181017214349-06f26fdaaa28/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181024171208-a2dc47679d30/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181105230042-78dc5bac0cac/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181107215632-34b416bd17b3/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181114190951-94339b83286c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181119130350-139d099f6620/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181127195227-b4e97c0ed882/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181127232545-e782529d0ddd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181203210056-e5f3ab76ea4b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181205224935-3576414c54a4/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181206194817-bcd4e47d0288/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181207183836-8bc39b988060/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181212172921-837e80568c09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190102213336-ca9055ed7d04/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190104182027-498d95493402/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190111214448-fc1d57b08d7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190118193359-16909d206f00/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk=
|
||||||
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
|
gopkg.in/mail.v2 v2.0.0-20180731213649-a0242b2233b4/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
280
main.go
280
main.go
@@ -2,102 +2,224 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"github.com/amir20/dozzle/docker"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/client"
|
|
||||||
"github.com/gobuffalo/packr"
|
"github.com/gobuffalo/packr"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/mux"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cli *client.Client
|
addr = ""
|
||||||
addr = flag.String("addr", ":8080", "http service address")
|
base = ""
|
||||||
upgrader = websocket.Upgrader{}
|
level = ""
|
||||||
version = "dev"
|
version = "dev"
|
||||||
commit = "none"
|
commit = "none"
|
||||||
date = "unknown"
|
date = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type handler struct {
|
||||||
|
client docker.Client
|
||||||
|
box packr.Box
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var err error
|
flag.StringVar(&addr, "addr", ":8080", "http service address")
|
||||||
cli, err = client.NewClientWithOpts(client.FromEnv)
|
flag.StringVar(&base, "base", "/", "base address of the application to mount")
|
||||||
if err != nil {
|
flag.StringVar(&level, "level", "info", "logging level")
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
l, _ := log.ParseLevel(level)
|
||||||
|
log.SetLevel(l)
|
||||||
|
|
||||||
|
log.SetFormatter(&log.TextFormatter{
|
||||||
|
DisableTimestamp: true,
|
||||||
|
DisableLevelTruncation: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func createRoutes(base string, h *handler) *mux.Router {
|
||||||
|
r := mux.NewRouter()
|
||||||
|
if base != "/" {
|
||||||
|
r.HandleFunc(base, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
http.Redirect(w, req, base+"/", http.StatusMovedPermanently)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
s := r.PathPrefix(base).Subrouter()
|
||||||
|
s.HandleFunc("/api/containers.json", h.listContainers)
|
||||||
|
s.HandleFunc("/api/logs/stream", h.streamLogs)
|
||||||
|
s.HandleFunc("/api/events/stream", h.streamEvents)
|
||||||
|
s.HandleFunc("/version", h.version)
|
||||||
|
s.PathPrefix("/").Handler(http.StripPrefix(base, http.HandlerFunc(h.index)))
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
box := packr.NewBox("./static")
|
log.Infof("Dozzle version %s", version)
|
||||||
http.HandleFunc("/api/containers.json", listContainers)
|
dockerClient := docker.NewClient()
|
||||||
http.HandleFunc("/api/logs", logs)
|
_, err := dockerClient.ListContainers()
|
||||||
http.HandleFunc("/version", versionHandler)
|
|
||||||
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
||||||
fileServer := http.FileServer(box)
|
|
||||||
if box.Has(req.URL.Path) {
|
|
||||||
fileServer.ServeHTTP(w, req)
|
|
||||||
} else {
|
|
||||||
bytes, _ := box.Find("index.html")
|
|
||||||
w.Write(bytes)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(*addr, nil))
|
if err != nil {
|
||||||
|
log.Fatalf("Could not connect to Docker Engine: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
box := packr.NewBox("./static")
|
||||||
|
r := createRoutes(base, &handler{dockerClient, box})
|
||||||
|
srv := &http.Server{Addr: addr, Handler: r}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
log.Infof("Accepting connections on %s", srv.Addr)
|
||||||
|
if err := srv.ListenAndServe(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(c, os.Interrupt)
|
||||||
|
signal.Notify(c, os.Kill)
|
||||||
|
<-c
|
||||||
|
log.Infof("Shutting down...")
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
srv.Shutdown(ctx)
|
||||||
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func versionHandler(w http.ResponseWriter, r *http.Request) {
|
func (h *handler) index(w http.ResponseWriter, req *http.Request) {
|
||||||
|
fileServer := http.FileServer(h.box)
|
||||||
|
if h.box.Has(req.URL.Path) && req.URL.Path != "" && req.URL.Path != "/" {
|
||||||
|
fileServer.ServeHTTP(w, req)
|
||||||
|
} else {
|
||||||
|
text, _ := h.box.FindString("index.html")
|
||||||
|
text = strings.Replace(text, "__BASE__", "{{ .Base }}", -1)
|
||||||
|
tmpl, err := template.New("index.html").Parse(text)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
path := ""
|
||||||
|
if base != "/" {
|
||||||
|
path = base
|
||||||
|
}
|
||||||
|
|
||||||
|
data := struct{ Base string }{path}
|
||||||
|
err = tmpl.Execute(w, data)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) listContainers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
containers, err := h.client.ListContainers()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = json.NewEncoder(w).Encode(containers)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) streamLogs(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id := r.URL.Query().Get("id")
|
||||||
|
if id == "" {
|
||||||
|
http.Error(w, "id is required", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f, ok := w.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
messages, err := h.client.ContainerLogs(r.Context(), id)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "text/event-stream")
|
||||||
|
w.Header().Set("Cache-Control", "no-cache")
|
||||||
|
w.Header().Set("Connection", "keep-alive")
|
||||||
|
w.Header().Set("Transfer-Encoding", "chunked")
|
||||||
|
|
||||||
|
log.Debugf("Starting to stream logs for %s", id)
|
||||||
|
Loop:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case message, ok := <-messages:
|
||||||
|
if !ok {
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
_, e := fmt.Fprintf(w, "data: %s\n\n", message)
|
||||||
|
if e != nil {
|
||||||
|
log.Debugf("Error while writing to log stream: %v", e)
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
f.Flush()
|
||||||
|
case e := <-err:
|
||||||
|
log.Debugf("Error while reading from log stream: %v", e)
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.WithField("NumGoroutine", runtime.NumGoroutine()).Debug("runtime stats")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
|
||||||
|
f, ok := w.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "text/event-stream")
|
||||||
|
w.Header().Set("Cache-Control", "no-cache")
|
||||||
|
w.Header().Set("Connection", "keep-alive")
|
||||||
|
w.Header().Set("Transfer-Encoding", "chunked")
|
||||||
|
|
||||||
|
ctx := r.Context()
|
||||||
|
messages, err := h.client.Events(ctx)
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case message, ok := <-messages:
|
||||||
|
if !ok {
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
switch message.Action {
|
||||||
|
case "connect", "disconnect", "create", "destroy", "start", "stop":
|
||||||
|
log.Debugf("Triggering docker event: %v", message.Action)
|
||||||
|
_, err := fmt.Fprintf(w, "event: containers-changed\ndata: %s\n\n", message.Action)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("Error while writing to event stream: %v", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
f.Flush()
|
||||||
|
default:
|
||||||
|
log.Debugf("Ignoring docker event: %v", message.Action)
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
break Loop
|
||||||
|
case <-err:
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) version(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintln(w, version)
|
fmt.Fprintln(w, version)
|
||||||
fmt.Fprintln(w, commit)
|
fmt.Fprintln(w, commit)
|
||||||
fmt.Fprintln(w, date)
|
fmt.Fprintln(w, date)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listContainers(w http.ResponseWriter, r *http.Request) {
|
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
json.NewEncoder(w).Encode(containers)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logs(w http.ResponseWriter, r *http.Request) {
|
|
||||||
id := r.URL.Query().Get("id")
|
|
||||||
c, err := upgrader.Upgrade(w, r, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
options := types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: "300", Timestamps: true}
|
|
||||||
reader, err := cli.ContainerLogs(context.Background(), id, options)
|
|
||||||
defer reader.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr := make([]byte, 8)
|
|
||||||
content := make([]byte, 1024, 1024*1024)
|
|
||||||
for {
|
|
||||||
_, err := reader.Read(hdr)
|
|
||||||
if err != nil {
|
|
||||||
log.Panicln(err)
|
|
||||||
}
|
|
||||||
count := binary.BigEndian.Uint32(hdr[4:])
|
|
||||||
n, err := reader.Read(content[:count])
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
err = c.WriteMessage(websocket.TextMessage, content[:n])
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
287
main_test.go
Normal file
287
main_test.go
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/magiconair/properties/assert"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/amir20/dozzle/docker"
|
||||||
|
"github.com/beme/abide"
|
||||||
|
"github.com/docker/docker/api/types/events"
|
||||||
|
"github.com/gobuffalo/packr"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MockedClient struct {
|
||||||
|
mock.Mock
|
||||||
|
docker.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockedClient) ListContainers() ([]docker.Container, error) {
|
||||||
|
args := m.Called()
|
||||||
|
containers, ok := args.Get(0).([]docker.Container)
|
||||||
|
if !ok {
|
||||||
|
panic("containers is not of type []docker.Container")
|
||||||
|
}
|
||||||
|
return containers, args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockedClient) ContainerLogs(ctx context.Context, id string) (<-chan string, <-chan error) {
|
||||||
|
args := m.Called(ctx, id)
|
||||||
|
channel, ok := args.Get(0).(chan string)
|
||||||
|
if !ok {
|
||||||
|
panic("channel is not of type chan string")
|
||||||
|
}
|
||||||
|
|
||||||
|
err, ok := args.Get(1).(chan error)
|
||||||
|
if !ok {
|
||||||
|
panic("error is not of type chan error")
|
||||||
|
}
|
||||||
|
return channel, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockedClient) Events(ctx context.Context) (<-chan events.Message, <-chan error) {
|
||||||
|
args := m.Called(ctx)
|
||||||
|
channel, ok := args.Get(0).(chan events.Message)
|
||||||
|
if !ok {
|
||||||
|
panic("channel is not of type chan events.Message")
|
||||||
|
}
|
||||||
|
|
||||||
|
err, ok := args.Get(1).(chan error)
|
||||||
|
if !ok {
|
||||||
|
panic("error is not of type chan error")
|
||||||
|
}
|
||||||
|
return channel, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_handler_listContainers_happy(t *testing.T) {
|
||||||
|
req, err := http.NewRequest("GET", "/api/containers.json", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
containers := []docker.Container{
|
||||||
|
{
|
||||||
|
ID: "1234567890",
|
||||||
|
Status: "status",
|
||||||
|
State: "state",
|
||||||
|
Name: "test",
|
||||||
|
Created: 0,
|
||||||
|
Command: "command",
|
||||||
|
ImageID: "image_id",
|
||||||
|
Image: "image",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mockedClient.On("ListContainers", mock.Anything).Return(containers, nil)
|
||||||
|
|
||||||
|
h := handler{client: mockedClient}
|
||||||
|
handler := http.HandlerFunc(h.listContainers)
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
mockedClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_handler_streamLogs_happy(t *testing.T) {
|
||||||
|
id := "123456"
|
||||||
|
req, err := http.NewRequest("GET", "/api/logs/stream", nil)
|
||||||
|
q := req.URL.Query()
|
||||||
|
q.Add("id", "123456")
|
||||||
|
req.URL.RawQuery = q.Encode()
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
|
||||||
|
messages := make(chan string)
|
||||||
|
errChannel := make(chan error)
|
||||||
|
mockedClient.On("ContainerLogs", mock.Anything, id).Return(messages, errChannel)
|
||||||
|
go func() {
|
||||||
|
messages <- "INFO Testing logs..."
|
||||||
|
close(messages)
|
||||||
|
}()
|
||||||
|
|
||||||
|
h := handler{client: mockedClient}
|
||||||
|
handler := http.HandlerFunc(h.streamLogs)
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
mockedClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_handler_streamLogs_error_reading(t *testing.T) {
|
||||||
|
id := "123456"
|
||||||
|
req, err := http.NewRequest("GET", "/api/logs/stream", nil)
|
||||||
|
q := req.URL.Query()
|
||||||
|
q.Add("id", "123456")
|
||||||
|
req.URL.RawQuery = q.Encode()
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
messages := make(chan string)
|
||||||
|
errChannel := make(chan error)
|
||||||
|
mockedClient.On("ContainerLogs", mock.Anything, id).Return(messages, errChannel)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
errChannel <- errors.New("test error")
|
||||||
|
}()
|
||||||
|
|
||||||
|
h := handler{client: mockedClient}
|
||||||
|
handler := http.HandlerFunc(h.streamLogs)
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
mockedClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_handler_streamEvents_happy(t *testing.T) {
|
||||||
|
req, err := http.NewRequest("GET", "/api/events/stream", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
messages := make(chan events.Message)
|
||||||
|
errChannel := make(chan error)
|
||||||
|
mockedClient.On("Events", mock.Anything).Return(messages, errChannel)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
messages <- events.Message{
|
||||||
|
Action: "start",
|
||||||
|
}
|
||||||
|
messages <- events.Message{
|
||||||
|
Action: "something-random",
|
||||||
|
}
|
||||||
|
close(messages)
|
||||||
|
}()
|
||||||
|
|
||||||
|
h := handler{client: mockedClient}
|
||||||
|
handler := http.HandlerFunc(h.streamEvents)
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
mockedClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_handler_streamEvents_error(t *testing.T) {
|
||||||
|
req, err := http.NewRequest("GET", "/api/events/stream", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
messages := make(chan events.Message)
|
||||||
|
errChannel := make(chan error)
|
||||||
|
mockedClient.On("Events", mock.Anything).Return(messages, errChannel)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
errChannel <- errors.New("fake error")
|
||||||
|
close(messages)
|
||||||
|
}()
|
||||||
|
|
||||||
|
h := handler{client: mockedClient}
|
||||||
|
handler := http.HandlerFunc(h.streamEvents)
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
mockedClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_handler_streamEvents_error_request(t *testing.T) {
|
||||||
|
req, err := http.NewRequest("GET", "/api/events/stream", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
|
||||||
|
messages := make(chan events.Message)
|
||||||
|
errChannel := make(chan error)
|
||||||
|
mockedClient.On("Events", mock.Anything).Return(messages, errChannel)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
cancel()
|
||||||
|
}()
|
||||||
|
|
||||||
|
h := handler{client: mockedClient}
|
||||||
|
handler := http.HandlerFunc(h.streamEvents)
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
mockedClient.AssertExpectations(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_createRoutes_index(t *testing.T) {
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
box := packr.NewBox("./virtual")
|
||||||
|
require.NoError(t, box.AddString("index.html", "index page"), "AddString should have no error.")
|
||||||
|
|
||||||
|
handler := createRoutes("/", &handler{mockedClient, box})
|
||||||
|
req, err := http.NewRequest("GET", "/", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_createRoutes_redirect(t *testing.T) {
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
box := packr.NewBox("./virtual")
|
||||||
|
|
||||||
|
handler := createRoutes("/foobar", &handler{mockedClient, box})
|
||||||
|
req, err := http.NewRequest("GET", "/foobar", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_createRoutes_foobar(t *testing.T) {
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
box := packr.NewBox("./virtual")
|
||||||
|
require.NoError(t, box.AddString("index.html", "foo page"), "AddString should have no error.")
|
||||||
|
|
||||||
|
handler := createRoutes("/foobar", &handler{mockedClient, box})
|
||||||
|
req, err := http.NewRequest("GET", "/foobar/", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_createRoutes_foobar_file(t *testing.T) {
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
box := packr.NewBox("./virtual")
|
||||||
|
require.NoError(t, box.AddString("/test", "test page"), "AddString should have no error.")
|
||||||
|
|
||||||
|
handler := createRoutes("/foobar", &handler{mockedClient, box})
|
||||||
|
req, err := http.NewRequest("GET", "/foobar/test", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
assert.Equal(t, rr.Body.String(), "test page", "page doesn't match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_createRoutes_version(t *testing.T) {
|
||||||
|
mockedClient := new(MockedClient)
|
||||||
|
box := packr.NewBox("./virtual")
|
||||||
|
|
||||||
|
handler := createRoutes("/", &handler{mockedClient, box})
|
||||||
|
req, err := http.NewRequest("GET", "/version", nil)
|
||||||
|
require.NoError(t, err, "NewRequest should not return an error.")
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
handler.ServeHTTP(rr, req)
|
||||||
|
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
exit := m.Run()
|
||||||
|
abide.Cleanup()
|
||||||
|
os.Exit(exit)
|
||||||
|
}
|
||||||
4761
package-lock.json
generated
4761
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
47
package.json
47
package.json
@@ -1,13 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "dozzle",
|
"name": "dozzle",
|
||||||
"version": "1.1.1",
|
"version": "1.6.2",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "concurrently 'go run main.go' 'npm run watch-assets'",
|
"prestart": "npm run clean",
|
||||||
"watch-assets": "parcel watch assets/index.html -d static",
|
"start": "DOCKER_API_VERSION=1.38 concurrently 'npm run watch-server' 'npm run watch-assets'",
|
||||||
"build": "parcel build assets/index.html -d static",
|
"watch-assets": "npx parcel watch --public-url '__BASE__' assets/index.html -d static",
|
||||||
"clean": "rm -rf static"
|
"watch-server": "reflex -c .reflex",
|
||||||
|
"prebuild": "npm run clean",
|
||||||
|
"build": "npx parcel build --no-source-maps --public-url '__BASE__' assets/index.html -d static",
|
||||||
|
"clean": "rm -rf static/ a_main-packr.go",
|
||||||
|
"release": "goreleaser --rm-dist"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -20,24 +24,24 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/amir20/dozzle#readme",
|
"homepage": "https://github.com/amir20/dozzle#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bulma": "^0.7.2",
|
"bulma": "^0.7.4",
|
||||||
"bulma-tooltip": "^2.0.2",
|
|
||||||
"date-fns": "^2.0.0-alpha.25",
|
"date-fns": "^2.0.0-alpha.25",
|
||||||
"vue": "^2.5.17",
|
"vue": "^2.6.9",
|
||||||
"vue-router": "^3.0.1"
|
"vue-headful": "^2.0.1",
|
||||||
|
"vue-router": "^3.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.1.6",
|
"@babel/core": "^7.3.4",
|
||||||
"@babel/plugin-transform-runtime": "^7.1.0",
|
"@babel/plugin-transform-runtime": "^7.3.4",
|
||||||
"@vue/component-compiler-utils": "^2.3.0",
|
"@vue/component-compiler-utils": "^2.6.0",
|
||||||
"concurrently": "^4.1.0",
|
"concurrently": "^4.1.0",
|
||||||
"husky": "^1.1.4",
|
"husky": "^1.3.1",
|
||||||
"lint-staged": "^8.0.5",
|
"lint-staged": "^8.1.5",
|
||||||
"parcel-bundler": "^1.10.3",
|
"parcel-bundler": "^1.12.2",
|
||||||
"prettier": "^1.15.2",
|
"prettier": "^1.16.4",
|
||||||
"sass": "^1.15.1",
|
"sass": "^1.17.2",
|
||||||
"vue-hot-reload-api": "^2.3.1",
|
"vue-hot-reload-api": "^2.3.3",
|
||||||
"vue-template-compiler": "^2.5.17"
|
"vue-template-compiler": "^2.6.9"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
@@ -53,5 +57,8 @@
|
|||||||
"browserslist": [
|
"browserslist": [
|
||||||
">5%",
|
">5%",
|
||||||
"not ie <= 8"
|
"not ie <= 8"
|
||||||
]
|
],
|
||||||
|
"alias": {
|
||||||
|
"vue": "./node_modules/vue/dist/vue.esm.js"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user