mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-21 21:33:18 +01:00
chore: logs swarm mode to beacon (#2918)
This commit is contained in:
@@ -1,73 +0,0 @@
|
|||||||
package analytics
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httputil"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SendStartEvent(se StartEvent) error {
|
|
||||||
postBody := map[string]interface{}{
|
|
||||||
"client_id": se.ClientId,
|
|
||||||
"events": []map[string]interface{}{
|
|
||||||
{
|
|
||||||
"name": "start",
|
|
||||||
"params": se,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return doRequest(postBody)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SendRequestEvent(re RequestEvent) error {
|
|
||||||
postBody := map[string]interface{}{
|
|
||||||
"client_id": re.ClientId,
|
|
||||||
"events": []map[string]interface{}{
|
|
||||||
{
|
|
||||||
"name": "request",
|
|
||||||
"params": re,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return doRequest(postBody)
|
|
||||||
}
|
|
||||||
|
|
||||||
func doRequest(body map[string]interface{}) error {
|
|
||||||
jsonValue, err := json.Marshal(body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "https://www.google-analytics.com/mp/collect", bytes.NewBuffer(jsonValue))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
q := req.URL.Query()
|
|
||||||
q.Add("measurement_id", "G-S6NT05VXK9")
|
|
||||||
q.Add("api_secret", "7FFhe65HQK-bXvujpQMquQ")
|
|
||||||
req.URL.RawQuery = q.Encode()
|
|
||||||
|
|
||||||
response, err := http.DefaultClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer response.Body.Close()
|
|
||||||
|
|
||||||
if response.StatusCode/100 != 2 {
|
|
||||||
dump, err := httputil.DumpResponse(response, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Debugf("%v", string(dump))
|
|
||||||
return fmt.Errorf("google analytics returned non-2xx status code: %v", response.Status)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SendBeacon(e BeaconEvent) error {
|
func SendBeacon(e BeaconEvent) error {
|
||||||
|
log.Tracef("sending beacon: %+v", e)
|
||||||
jsonValue, err := json.Marshal(e)
|
jsonValue, err := json.Marshal(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -1,22 +1,5 @@
|
|||||||
package analytics
|
package analytics
|
||||||
|
|
||||||
type StartEvent struct {
|
|
||||||
ClientId string `json:"-"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
FilterLength int `json:"filterLength"`
|
|
||||||
RemoteHostLength int `json:"remoteHostLength"`
|
|
||||||
CustomAddress bool `json:"customAddress"`
|
|
||||||
CustomBase bool `json:"customBase"`
|
|
||||||
Protected bool `json:"protected"`
|
|
||||||
HasHostname bool `json:"hasHostname"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestEvent struct {
|
|
||||||
ClientId string `json:"-"`
|
|
||||||
TotalContainers int `json:"totalContainers"`
|
|
||||||
RunningContainers int `json:"runningContainers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type BeaconEvent struct {
|
type BeaconEvent struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
@@ -24,10 +7,10 @@ type BeaconEvent struct {
|
|||||||
AuthProvider string `json:"authProvider"`
|
AuthProvider string `json:"authProvider"`
|
||||||
FilterLength int `json:"filterLength"`
|
FilterLength int `json:"filterLength"`
|
||||||
Clients int `json:"clients"`
|
Clients int `json:"clients"`
|
||||||
HasDocumentation bool `json:"hasDocumentation"`
|
|
||||||
HasCustomAddress bool `json:"hasCustomAddress"`
|
HasCustomAddress bool `json:"hasCustomAddress"`
|
||||||
HasCustomBase bool `json:"hasCustomBase"`
|
HasCustomBase bool `json:"hasCustomBase"`
|
||||||
HasHostname bool `json:"hasHostname"`
|
HasHostname bool `json:"hasHostname"`
|
||||||
RunningContainers int `json:"runningContainers"`
|
RunningContainers int `json:"runningContainers"`
|
||||||
HasActions bool `json:"hasActions"`
|
HasActions bool `json:"hasActions"`
|
||||||
|
IsSwarmMode bool `json:"isSwarmMode"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"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/client"
|
"github.com/docker/docker/client"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -67,16 +68,18 @@ type Client interface {
|
|||||||
Ping(context.Context) (types.Ping, error)
|
Ping(context.Context) (types.Ping, error)
|
||||||
Host() *Host
|
Host() *Host
|
||||||
ContainerActions(action string, containerID string) error
|
ContainerActions(action string, containerID string) error
|
||||||
|
IsSwarmMode() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type _client struct {
|
type httpClient struct {
|
||||||
cli DockerCLI
|
cli DockerCLI
|
||||||
filters filters.Args
|
filters filters.Args
|
||||||
host *Host
|
host *Host
|
||||||
|
SwarmMode bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(cli DockerCLI, filters filters.Args, host *Host) Client {
|
func NewClient(cli DockerCLI, filters filters.Args, host *Host, swarm bool) Client {
|
||||||
return &_client{cli, filters, host}
|
return &httpClient{cli, filters, host, swarm}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientWithFilters creates a new instance of Client with docker filters
|
// NewClientWithFilters creates a new instance of Client with docker filters
|
||||||
@@ -96,7 +99,10 @@ func NewClientWithFilters(f map[string][]string) (Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewClient(cli, filterArgs, &Host{Name: "localhost", ID: "localhost"}), nil
|
info, _ := cli.Info(context.Background())
|
||||||
|
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) {
|
||||||
@@ -132,10 +138,13 @@ func NewClientWithTlsAndFilter(f map[string][]string, host Host) (Client, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewClient(cli, filterArgs, &host), nil
|
info, _ := cli.Info(context.Background())
|
||||||
|
swarm := info.Swarm.LocalNodeState != swarm.LocalNodeStateInactive
|
||||||
|
|
||||||
|
return NewClient(cli, filterArgs, &host, swarm), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) FindContainer(id string) (Container, error) {
|
func (d *httpClient) FindContainer(id string) (Container, error) {
|
||||||
var container Container
|
var container Container
|
||||||
containers, err := d.ListContainers()
|
containers, err := d.ListContainers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -163,7 +172,7 @@ func (d *_client) FindContainer(id string) (Container, error) {
|
|||||||
return container, nil
|
return container, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) ContainerActions(action string, containerID string) error {
|
func (d *httpClient) ContainerActions(action string, containerID string) error {
|
||||||
switch action {
|
switch action {
|
||||||
case "start":
|
case "start":
|
||||||
return d.cli.ContainerStart(context.Background(), containerID, container.StartOptions{})
|
return d.cli.ContainerStart(context.Background(), containerID, container.StartOptions{})
|
||||||
@@ -176,7 +185,7 @@ func (d *_client) ContainerActions(action string, containerID string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) ListContainers() ([]Container, error) {
|
func (d *httpClient) ListContainers() ([]Container, error) {
|
||||||
containerListOptions := container.ListOptions{
|
containerListOptions := container.ListOptions{
|
||||||
Filters: d.filters,
|
Filters: d.filters,
|
||||||
All: true,
|
All: true,
|
||||||
@@ -217,7 +226,7 @@ func (d *_client) ListContainers() ([]Container, error) {
|
|||||||
return containers, nil
|
return containers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) ContainerStats(ctx context.Context, id string, stats chan<- ContainerStat) error {
|
func (d *httpClient) ContainerStats(ctx context.Context, id string, stats chan<- ContainerStat) error {
|
||||||
response, err := d.cli.ContainerStats(ctx, id, true)
|
response, err := d.cli.ContainerStats(ctx, id, true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -252,8 +261,6 @@ func (d *_client) ContainerStats(ctx context.Context, id string, stats chan<- Co
|
|||||||
mem = float64(v.MemoryStats.PrivateWorkingSet)
|
mem = float64(v.MemoryStats.PrivateWorkingSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Tracef("containerId = %s, cpuPercent = %f, memPercent = %f, memUsage = %f, daemonOSType = %s", id, cpuPercent, memPercent, mem, daemonOSType)
|
|
||||||
|
|
||||||
if cpuPercent > 0 || mem > 0 {
|
if cpuPercent > 0 || mem > 0 {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@@ -269,7 +276,7 @@ func (d *_client) ContainerStats(ctx context.Context, id string, stats chan<- Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) ContainerLogs(ctx context.Context, id string, since string, stdType StdType) (io.ReadCloser, error) {
|
func (d *httpClient) ContainerLogs(ctx context.Context, id string, since string, stdType StdType) (io.ReadCloser, error) {
|
||||||
log.WithField("id", id).WithField("since", since).WithField("stdType", stdType).Debug("streaming logs for container")
|
log.WithField("id", id).WithField("since", since).WithField("stdType", stdType).Debug("streaming logs for container")
|
||||||
|
|
||||||
if since != "" {
|
if since != "" {
|
||||||
@@ -297,7 +304,7 @@ func (d *_client) ContainerLogs(ctx context.Context, id string, since string, st
|
|||||||
return reader, nil
|
return reader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) Events(ctx context.Context, messages chan<- ContainerEvent) error {
|
func (d *httpClient) Events(ctx context.Context, messages chan<- ContainerEvent) error {
|
||||||
dockerMessages, err := d.cli.Events(ctx, types.EventsOptions{})
|
dockerMessages, err := d.cli.Events(ctx, types.EventsOptions{})
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@@ -320,7 +327,7 @@ func (d *_client) Events(ctx context.Context, messages chan<- ContainerEvent) er
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) ContainerLogsBetweenDates(ctx context.Context, id string, from time.Time, to time.Time, stdType StdType) (io.ReadCloser, error) {
|
func (d *httpClient) ContainerLogsBetweenDates(ctx context.Context, id string, from time.Time, to time.Time, stdType StdType) (io.ReadCloser, error) {
|
||||||
options := container.LogsOptions{
|
options := container.LogsOptions{
|
||||||
ShowStdout: stdType&STDOUT != 0,
|
ShowStdout: stdType&STDOUT != 0,
|
||||||
ShowStderr: stdType&STDERR != 0,
|
ShowStderr: stdType&STDERR != 0,
|
||||||
@@ -339,14 +346,18 @@ func (d *_client) ContainerLogsBetweenDates(ctx context.Context, id string, from
|
|||||||
return reader, nil
|
return reader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) Ping(ctx context.Context) (types.Ping, error) {
|
func (d *httpClient) Ping(ctx context.Context) (types.Ping, error) {
|
||||||
return d.cli.Ping(ctx)
|
return d.cli.Ping(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *_client) Host() *Host {
|
func (d *httpClient) Host() *Host {
|
||||||
return d.host
|
return d.host
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *httpClient) IsSwarmMode() bool {
|
||||||
|
return d.SwarmMode
|
||||||
|
}
|
||||||
|
|
||||||
var PARENTHESIS_RE = regexp.MustCompile(`\(([a-zA-Z]+)\)`)
|
var PARENTHESIS_RE = regexp.MustCompile(`\(([a-zA-Z]+)\)`)
|
||||||
|
|
||||||
func findBetweenParentheses(s string) string {
|
func findBetweenParentheses(s string) string {
|
||||||
|
|||||||
@@ -89,7 +89,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 := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
|
|
||||||
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 +101,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 := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
|
|
||||||
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 +124,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 := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
|
|
||||||
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 +151,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 := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
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 +165,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 := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
|
|
||||||
reader, err := client.ContainerLogs(context.Background(), id, "", STDALL)
|
reader, err := client.ContainerLogs(context.Background(), id, "", STDALL)
|
||||||
|
|
||||||
@@ -192,7 +192,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 := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
|
|
||||||
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 +215,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 := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
|
|
||||||
_, 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 +236,7 @@ func Test_dockerClient_ContainerActions_happy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
client := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
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 +272,7 @@ func Test_dockerClient_ContainerActions_error(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxy := new(mockedProxy)
|
proxy := new(mockedProxy)
|
||||||
client := &_client{proxy, filters.NewArgs(), &Host{ID: "localhost"}}
|
client := &httpClient{proxy, filters.NewArgs(), &Host{ID: "localhost"}, false}
|
||||||
|
|
||||||
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"))
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
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 {
|
||||||
@@ -55,6 +56,10 @@ 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() {
|
||||||
@@ -67,6 +72,8 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
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.RunningContainers = len(allContainers)
|
||||||
|
b.IsSwarmMode = hasSwarm
|
||||||
|
|
||||||
f.Flush()
|
f.Flush()
|
||||||
|
|
||||||
if !h.config.NoAnalytics {
|
if !h.config.NoAnalytics {
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ func (m *MockedClient) Host() *docker.Host {
|
|||||||
return args.Get(0).(*docker.Host)
|
return args.Get(0).(*docker.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MockedClient) IsSwarmMode() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
16
main_test.go
16
main_test.go
@@ -29,7 +29,7 @@ func Test_valid_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",
|
||||||
}), nil
|
}, false), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{}
|
args := args{}
|
||||||
@@ -46,7 +46,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",
|
||||||
}), nil
|
}, false), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{}
|
args := args{}
|
||||||
@@ -63,7 +63,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",
|
||||||
}), nil
|
}, false), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
remote := new(fakeCLI)
|
remote := new(fakeCLI)
|
||||||
@@ -71,7 +71,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",
|
||||||
}), nil
|
}, false), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{
|
args := args{
|
||||||
@@ -93,7 +93,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",
|
||||||
}), nil
|
}, false), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
remote := new(fakeCLI)
|
remote := new(fakeCLI)
|
||||||
@@ -101,7 +101,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",
|
||||||
}), nil
|
}, false), nil
|
||||||
}
|
}
|
||||||
args := args{
|
args := args{
|
||||||
RemoteHost: []string{"tcp://test:2375"},
|
RemoteHost: []string{"tcp://test:2375"},
|
||||||
@@ -123,13 +123,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",
|
||||||
}), nil
|
}, false), 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",
|
||||||
}), nil
|
}, false), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
args := args{}
|
args := args{}
|
||||||
|
|||||||
Reference in New Issue
Block a user