mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-24 06:28:42 +01:00
chore: send server id by loading system info (#2936)
This commit is contained in:
2
assets/components.d.ts
vendored
2
assets/components.d.ts
vendored
@@ -1,10 +1,10 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/* prettier-ignore */
|
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// Generated by unplugin-vue-components
|
// Generated by unplugin-vue-components
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
export {}
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
BarChart: typeof import('./components/BarChart.vue')['default']
|
BarChart: typeof import('./components/BarChart.vue')['default']
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ type BeaconEvent struct {
|
|||||||
RunningContainers int `json:"runningContainers"`
|
RunningContainers int `json:"runningContainers"`
|
||||||
HasActions bool `json:"hasActions"`
|
HasActions bool `json:"hasActions"`
|
||||||
IsSwarmMode bool `json:"isSwarmMode"`
|
IsSwarmMode bool `json:"isSwarmMode"`
|
||||||
|
ServerVersion string `json:"serverVersion"`
|
||||||
|
ServerID string `json:"serverID"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/docker/docker/api/types/events"
|
"github.com/docker/docker/api/types/events"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -56,6 +57,7 @@ type DockerCLI interface {
|
|||||||
ContainerStart(ctx context.Context, containerID string, options container.StartOptions) error
|
ContainerStart(ctx context.Context, containerID string, options container.StartOptions) error
|
||||||
ContainerStop(ctx context.Context, containerID string, options container.StopOptions) error
|
ContainerStop(ctx context.Context, containerID string, options container.StopOptions) error
|
||||||
ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error
|
ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error
|
||||||
|
Info(ctx context.Context) (system.Info, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client interface {
|
type Client interface {
|
||||||
@@ -69,17 +71,33 @@ type Client interface {
|
|||||||
Host() *Host
|
Host() *Host
|
||||||
ContainerActions(action string, containerID string) error
|
ContainerActions(action string, containerID string) error
|
||||||
IsSwarmMode() bool
|
IsSwarmMode() bool
|
||||||
|
SystemInfo() system.Info
|
||||||
}
|
}
|
||||||
|
|
||||||
type httpClient struct {
|
type httpClient struct {
|
||||||
cli DockerCLI
|
cli DockerCLI
|
||||||
filters filters.Args
|
filters filters.Args
|
||||||
host *Host
|
host *Host
|
||||||
SwarmMode bool
|
info system.Info
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(cli DockerCLI, filters filters.Args, host *Host, swarm bool) Client {
|
func NewClient(cli DockerCLI, filters filters.Args, host *Host) Client {
|
||||||
return &httpClient{cli, filters, host, swarm}
|
client := &httpClient{
|
||||||
|
cli: cli,
|
||||||
|
filters: filters,
|
||||||
|
host: host,
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
client.info, err = cli.Info(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("unable to get docker info: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
host.NCPU = client.info.NCPU
|
||||||
|
host.MemTotal = client.info.MemTotal
|
||||||
|
|
||||||
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientWithFilters creates a new instance of Client with docker filters
|
// NewClientWithFilters creates a new instance of Client with docker filters
|
||||||
@@ -99,10 +117,7 @@ func NewClientWithFilters(f map[string][]string) (Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info, _ := cli.Info(context.Background())
|
return NewClient(cli, filterArgs, &Host{Name: "localhost", ID: "localhost"}), nil
|
||||||
swarm := info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive
|
|
||||||
|
|
||||||
return NewClient(cli, filterArgs, &Host{Name: "localhost", ID: "localhost"}, swarm), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClientWithTlsAndFilter(f map[string][]string, host Host) (Client, error) {
|
func NewClientWithTlsAndFilter(f map[string][]string, host Host) (Client, error) {
|
||||||
@@ -138,10 +153,7 @@ func NewClientWithTlsAndFilter(f map[string][]string, host Host) (Client, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info, _ := cli.Info(context.Background())
|
return NewClient(cli, filterArgs, &host), nil
|
||||||
swarm := info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive
|
|
||||||
|
|
||||||
return NewClient(cli, filterArgs, &host, swarm), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *httpClient) FindContainer(id string) (Container, error) {
|
func (d *httpClient) FindContainer(id string) (Container, error) {
|
||||||
@@ -355,7 +367,11 @@ func (d *httpClient) Host() *Host {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *httpClient) IsSwarmMode() bool {
|
func (d *httpClient) IsSwarmMode() bool {
|
||||||
return d.SwarmMode
|
return d.info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *httpClient) SystemInfo() system.Info {
|
||||||
|
return d.info
|
||||||
}
|
}
|
||||||
|
|
||||||
var PARENTHESIS_RE = regexp.MustCompile(`\(([a-zA-Z]+)\)`)
|
var PARENTHESIS_RE = regexp.MustCompile(`\(([a-zA-Z]+)\)`)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@@ -89,7 +90,7 @@ func (m *mockedProxy) ContainerRestart(ctx context.Context, containerID string,
|
|||||||
func Test_dockerClient_ListContainers_null(t *testing.T) {
|
func Test_dockerClient_ListContainers_null(t *testing.T) {
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(nil, nil)
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(nil, nil)
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
|
|
||||||
list, err := client.ListContainers()
|
list, err := client.ListContainers()
|
||||||
assert.Empty(t, list, "list should be empty")
|
assert.Empty(t, list, "list should be empty")
|
||||||
@@ -101,7 +102,7 @@ func Test_dockerClient_ListContainers_null(t *testing.T) {
|
|||||||
func Test_dockerClient_ListContainers_error(t *testing.T) {
|
func Test_dockerClient_ListContainers_error(t *testing.T) {
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(nil, errors.New("test"))
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(nil, errors.New("test"))
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
|
|
||||||
list, err := client.ListContainers()
|
list, err := client.ListContainers()
|
||||||
assert.Nil(t, list, "list should be nil")
|
assert.Nil(t, list, "list should be nil")
|
||||||
@@ -124,7 +125,7 @@ func Test_dockerClient_ListContainers_happy(t *testing.T) {
|
|||||||
|
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
|
|
||||||
list, err := client.ListContainers()
|
list, err := client.ListContainers()
|
||||||
require.NoError(t, err, "error should not return an error.")
|
require.NoError(t, err, "error should not return an error.")
|
||||||
@@ -151,7 +152,7 @@ func Test_dockerClient_ContainerLogs_happy(t *testing.T) {
|
|||||||
options := container.LogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: "300", Timestamps: true, Since: "since"}
|
options := container.LogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: "300", Timestamps: true, Since: "since"}
|
||||||
proxy.On("ContainerLogs", mock.Anything, id, options).Return(reader, nil)
|
proxy.On("ContainerLogs", mock.Anything, id, options).Return(reader, nil)
|
||||||
|
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
logReader, _ := client.ContainerLogs(context.Background(), id, "since", STDALL)
|
logReader, _ := client.ContainerLogs(context.Background(), id, "since", STDALL)
|
||||||
|
|
||||||
actual, _ := io.ReadAll(logReader)
|
actual, _ := io.ReadAll(logReader)
|
||||||
@@ -165,7 +166,7 @@ func Test_dockerClient_ContainerLogs_error(t *testing.T) {
|
|||||||
|
|
||||||
proxy.On("ContainerLogs", mock.Anything, id, mock.Anything).Return(nil, errors.New("test"))
|
proxy.On("ContainerLogs", mock.Anything, id, mock.Anything).Return(nil, errors.New("test"))
|
||||||
|
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
|
|
||||||
reader, err := client.ContainerLogs(context.Background(), id, "", STDALL)
|
reader, err := client.ContainerLogs(context.Background(), id, "", STDALL)
|
||||||
|
|
||||||
@@ -192,7 +193,7 @@ func Test_dockerClient_FindContainer_happy(t *testing.T) {
|
|||||||
json := types.ContainerJSON{Config: &container.Config{Tty: false}}
|
json := types.ContainerJSON{Config: &container.Config{Tty: false}}
|
||||||
proxy.On("ContainerInspect", mock.Anything, "abcdefghijkl").Return(json, nil)
|
proxy.On("ContainerInspect", mock.Anything, "abcdefghijkl").Return(json, nil)
|
||||||
|
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
|
|
||||||
container, err := client.FindContainer("abcdefghijkl")
|
container, err := client.FindContainer("abcdefghijkl")
|
||||||
require.NoError(t, err, "error should not be thrown")
|
require.NoError(t, err, "error should not be thrown")
|
||||||
@@ -215,7 +216,7 @@ func Test_dockerClient_FindContainer_error(t *testing.T) {
|
|||||||
|
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
|
|
||||||
_, err := client.FindContainer("not_valid")
|
_, err := client.FindContainer("not_valid")
|
||||||
require.Error(t, err, "error should be thrown")
|
require.Error(t, err, "error should be thrown")
|
||||||
@@ -236,7 +237,7 @@ func Test_dockerClient_ContainerActions_happy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
json := types.ContainerJSON{Config: &container.Config{Tty: false}}
|
json := types.ContainerJSON{Config: &container.Config{Tty: false}}
|
||||||
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
||||||
proxy.On("ContainerInspect", mock.Anything, "abcdefghijkl").Return(json, nil)
|
proxy.On("ContainerInspect", mock.Anything, "abcdefghijkl").Return(json, nil)
|
||||||
@@ -272,7 +273,7 @@ func Test_dockerClient_ContainerActions_error(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, system.Info{}}
|
||||||
|
|
||||||
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
proxy.On("ContainerList", mock.Anything, mock.Anything).Return(containers, nil)
|
||||||
proxy.On("ContainerStart", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("test"))
|
proxy.On("ContainerStart", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("test"))
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ type Host struct {
|
|||||||
CACertPath string `json:"-"`
|
CACertPath string `json:"-"`
|
||||||
KeyPath string `json:"-"`
|
KeyPath string `json:"-"`
|
||||||
ValidCerts bool `json:"-"`
|
ValidCerts bool `json:"-"`
|
||||||
|
NCPU int `json:"nCPU"`
|
||||||
|
MemTotal int64 `json:"memTotal"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Host) String() string {
|
func (h *Host) String() string {
|
||||||
|
|||||||
@@ -27,22 +27,9 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
b := analytics.BeaconEvent{
|
|
||||||
Name: "events",
|
|
||||||
Version: h.config.Version,
|
|
||||||
Browser: r.Header.Get("User-Agent"),
|
|
||||||
AuthProvider: string(h.config.Authorization.Provider),
|
|
||||||
HasHostname: h.config.Hostname != "",
|
|
||||||
HasCustomBase: h.config.Base != "/",
|
|
||||||
HasCustomAddress: h.config.Addr != ":8080",
|
|
||||||
Clients: len(h.clients),
|
|
||||||
HasActions: h.config.EnableActions,
|
|
||||||
}
|
|
||||||
|
|
||||||
allContainers := make([]docker.Container, 0)
|
allContainers := make([]docker.Container, 0)
|
||||||
events := make(chan docker.ContainerEvent)
|
events := make(chan docker.ContainerEvent)
|
||||||
stats := make(chan docker.ContainerStat)
|
stats := make(chan docker.ContainerStat)
|
||||||
hasSwarm := false
|
|
||||||
|
|
||||||
for _, store := range h.stores {
|
for _, store := range h.stores {
|
||||||
if containers, err := store.List(); err == nil {
|
if containers, err := store.List(); err == nil {
|
||||||
@@ -57,9 +44,6 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
store.SubscribeStats(ctx, stats)
|
store.SubscribeStats(ctx, stats)
|
||||||
store.Subscribe(ctx, events)
|
store.Subscribe(ctx, events)
|
||||||
|
|
||||||
if store.Client().IsSwarmMode() {
|
|
||||||
hasSwarm = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -71,18 +55,10 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
if err := sendContainersJSON(allContainers, w); err != nil {
|
if err := sendContainersJSON(allContainers, w); err != nil {
|
||||||
log.Errorf("error writing containers to event stream: %v", err)
|
log.Errorf("error writing containers to event stream: %v", err)
|
||||||
}
|
}
|
||||||
b.RunningContainers = len(allContainers)
|
|
||||||
b.IsSwarmMode = hasSwarm
|
|
||||||
|
|
||||||
f.Flush()
|
f.Flush()
|
||||||
|
|
||||||
if !h.config.NoAnalytics {
|
go sendBeaconEvent(h, r, len(allContainers))
|
||||||
go func() {
|
|
||||||
if err := analytics.SendBeacon(b); err != nil {
|
|
||||||
log.Debugf("error sending beacon: %v", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -141,6 +117,44 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendBeaconEvent(h *handler, r *http.Request, runningContainers int) {
|
||||||
|
b := analytics.BeaconEvent{
|
||||||
|
Name: "events",
|
||||||
|
Version: h.config.Version,
|
||||||
|
Browser: r.Header.Get("User-Agent"),
|
||||||
|
AuthProvider: string(h.config.Authorization.Provider),
|
||||||
|
HasHostname: h.config.Hostname != "",
|
||||||
|
HasCustomBase: h.config.Base != "/",
|
||||||
|
HasCustomAddress: h.config.Addr != ":8080",
|
||||||
|
Clients: len(h.clients),
|
||||||
|
HasActions: h.config.EnableActions,
|
||||||
|
RunningContainers: runningContainers,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, store := range h.stores {
|
||||||
|
if store.Client().IsSwarmMode() {
|
||||||
|
b.IsSwarmMode = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if client, ok := h.clients["localhost"]; ok {
|
||||||
|
b.ServerID = client.SystemInfo().ID
|
||||||
|
} else {
|
||||||
|
for _, client := range h.clients {
|
||||||
|
b.ServerID = client.SystemInfo().ID
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !h.config.NoAnalytics {
|
||||||
|
if err := analytics.SendBeacon(b); err != nil {
|
||||||
|
log.Debugf("error sending beacon: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func sendContainersJSON(containers []docker.Container, w http.ResponseWriter) error {
|
func sendContainersJSON(containers []docker.Container, w http.ResponseWriter) error {
|
||||||
if _, err := fmt.Fprint(w, "event: containers-changed\ndata: "); err != nil {
|
if _, err := fmt.Fprint(w, "event: containers-changed\ndata: "); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
|
|
||||||
"github.com/amir20/dozzle/internal/docker"
|
"github.com/amir20/dozzle/internal/docker"
|
||||||
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
@@ -63,6 +64,10 @@ func (m *MockedClient) IsSwarmMode() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MockedClient) SystemInfo() system.Info {
|
||||||
|
return system.Info{ID: "123"}
|
||||||
|
}
|
||||||
|
|
||||||
func createHandler(client docker.Client, content fs.FS, config Config) *chi.Mux {
|
func createHandler(client docker.Client, content fs.FS, config Config) *chi.Mux {
|
||||||
if client == nil {
|
if client == nil {
|
||||||
client = new(MockedClient)
|
client = new(MockedClient)
|
||||||
|
|||||||
15
main.go
15
main.go
@@ -83,7 +83,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
srv := createServer(args, clients)
|
srv := createServer(args, clients)
|
||||||
go doStartEvent(args)
|
go doStartEvent(args, clients)
|
||||||
go func() {
|
go func() {
|
||||||
log.Infof("Accepting connections on %s", srv.Addr)
|
log.Infof("Accepting connections on %s", srv.Addr)
|
||||||
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
||||||
@@ -104,7 +104,7 @@ func main() {
|
|||||||
log.Debug("shutdown complete")
|
log.Debug("shutdown complete")
|
||||||
}
|
}
|
||||||
|
|
||||||
func doStartEvent(arg args) {
|
func doStartEvent(arg args, clients map[string]docker.Client) {
|
||||||
if arg.NoAnalytics {
|
if arg.NoAnalytics {
|
||||||
log.Debug("Analytics disabled.")
|
log.Debug("Analytics disabled.")
|
||||||
return
|
return
|
||||||
@@ -115,6 +115,17 @@ func doStartEvent(arg args) {
|
|||||||
Version: version,
|
Version: version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if client, ok := clients["localhost"]; ok {
|
||||||
|
event.ServerID = client.SystemInfo().ID
|
||||||
|
event.ServerVersion = client.SystemInfo().ServerVersion
|
||||||
|
} else {
|
||||||
|
for _, client := range clients {
|
||||||
|
event.ServerID = client.SystemInfo().ID
|
||||||
|
event.ServerVersion = client.SystemInfo().ServerVersion
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := analytics.SendBeacon(event); err != nil {
|
if err := analytics.SendBeacon(event); err != nil {
|
||||||
log.Debug(err)
|
log.Debug(err)
|
||||||
}
|
}
|
||||||
|
|||||||
21
main_test.go
21
main_test.go
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
)
|
)
|
||||||
@@ -23,13 +24,17 @@ func (f *fakeCLI) ContainerList(context.Context, container.ListOptions) ([]types
|
|||||||
return args.Get(0).([]types.Container), args.Error(1)
|
return args.Get(0).([]types.Container), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *fakeCLI) Info(context.Context) (system.Info, error) {
|
||||||
|
return system.Info{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func Test_valid_localhost(t *testing.T) {
|
func Test_valid_localhost(t *testing.T) {
|
||||||
client := new(fakeCLI)
|
client := new(fakeCLI)
|
||||||
client.On("ContainerList").Return([]types.Container{}, nil)
|
client.On("ContainerList").Return([]types.Container{}, nil)
|
||||||
fakeClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
fakeClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
||||||
return docker.NewClient(client, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(client, filters.NewArgs(), &docker.Host{
|
||||||
ID: "localhost",
|
ID: "localhost",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{}
|
args := args{}
|
||||||
@@ -46,7 +51,7 @@ func Test_invalid_localhost(t *testing.T) {
|
|||||||
fakeClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
fakeClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
||||||
return docker.NewClient(client, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(client, filters.NewArgs(), &docker.Host{
|
||||||
ID: "localhost",
|
ID: "localhost",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{}
|
args := args{}
|
||||||
@@ -63,7 +68,7 @@ func Test_valid_remote(t *testing.T) {
|
|||||||
fakeLocalClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
fakeLocalClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
||||||
return docker.NewClient(local, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(local, filters.NewArgs(), &docker.Host{
|
||||||
ID: "localhost",
|
ID: "localhost",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
remote := new(fakeCLI)
|
remote := new(fakeCLI)
|
||||||
@@ -71,7 +76,7 @@ func Test_valid_remote(t *testing.T) {
|
|||||||
fakeRemoteClientFactory := func(filter map[string][]string, host docker.Host) (docker.Client, error) {
|
fakeRemoteClientFactory := func(filter map[string][]string, host docker.Host) (docker.Client, error) {
|
||||||
return docker.NewClient(remote, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(remote, filters.NewArgs(), &docker.Host{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{
|
args := args{
|
||||||
@@ -93,7 +98,7 @@ func Test_valid_remote_and_local(t *testing.T) {
|
|||||||
fakeLocalClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
fakeLocalClientFactory := func(filter map[string][]string) (docker.Client, error) {
|
||||||
return docker.NewClient(local, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(local, filters.NewArgs(), &docker.Host{
|
||||||
ID: "localhost",
|
ID: "localhost",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
remote := new(fakeCLI)
|
remote := new(fakeCLI)
|
||||||
@@ -101,7 +106,7 @@ func Test_valid_remote_and_local(t *testing.T) {
|
|||||||
fakeRemoteClientFactory := func(filter map[string][]string, host docker.Host) (docker.Client, error) {
|
fakeRemoteClientFactory := func(filter map[string][]string, host docker.Host) (docker.Client, error) {
|
||||||
return docker.NewClient(remote, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(remote, filters.NewArgs(), &docker.Host{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
args := args{
|
args := args{
|
||||||
RemoteHost: []string{"tcp://test:2375"},
|
RemoteHost: []string{"tcp://test:2375"},
|
||||||
@@ -123,13 +128,13 @@ func Test_no_clients(t *testing.T) {
|
|||||||
|
|
||||||
return docker.NewClient(local, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(local, filters.NewArgs(), &docker.Host{
|
||||||
ID: "localhost",
|
ID: "localhost",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
fakeRemoteClientFactory := func(filter map[string][]string, host docker.Host) (docker.Client, error) {
|
fakeRemoteClientFactory := func(filter map[string][]string, host docker.Host) (docker.Client, error) {
|
||||||
client := new(fakeCLI)
|
client := new(fakeCLI)
|
||||||
return docker.NewClient(client, filters.NewArgs(), &docker.Host{
|
return docker.NewClient(client, filters.NewArgs(), &docker.Host{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
}, false), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{}
|
args := args{}
|
||||||
|
|||||||
Reference in New Issue
Block a user