From a27f8aecadcc2df8c3675967b247eb5a27b63d9b Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 15 Feb 2022 19:19:30 +0100 Subject: [PATCH 1/3] daemon: SystemInfo() extract container counts to a helper function This makes it more inline with other data we collect, and can be used to make some info optional at some point. Signed-off-by: Sebastiaan van Stijn --- daemon/info.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/daemon/info.go b/daemon/info.go index 22afbfafac..4be6ec0c80 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -30,14 +30,9 @@ func (daemon *Daemon) SystemInfo() *types.Info { defer metrics.StartTimer(hostInfoFunctions.WithValues("system_info"))() sysInfo := daemon.RawSysInfo() - cRunning, cPaused, cStopped := stateCtr.get() v := &types.Info{ ID: daemon.ID, - Containers: cRunning + cPaused + cStopped, - ContainersRunning: cRunning, - ContainersPaused: cPaused, - ContainersStopped: cStopped, Images: daemon.imageService.CountImages(), IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled, BridgeNfIptables: !sysInfo.BridgeNFCallIPTablesDisabled, @@ -70,6 +65,7 @@ func (daemon *Daemon) SystemInfo() *types.Info { Isolation: daemon.defaultIsolation, } + daemon.fillContainerStates(v) daemon.fillAPIInfo(v) // Retrieve platform specific info daemon.fillPlatformInfo(v, sysInfo) @@ -181,6 +177,14 @@ func (daemon *Daemon) fillSecurityOptions(v *types.Info, sysInfo *sysinfo.SysInf v.SecurityOptions = securityOptions } +func (daemon *Daemon) fillContainerStates(v *types.Info) { + cRunning, cPaused, cStopped := stateCtr.get() + v.Containers = cRunning + cPaused + cStopped + v.ContainersPaused = cPaused + v.ContainersRunning = cRunning + v.ContainersStopped = cStopped +} + func (daemon *Daemon) fillAPIInfo(v *types.Info) { const warn string = ` Access to the remote API is equivalent to root access on the host. Refer From ac2cd5a8f2d70c9c46e09d0b33c66f28bacce91c Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 2 Mar 2022 11:43:33 +0100 Subject: [PATCH 2/3] daemon: unexport Daemon.ID and Daemon.RegistryService These are used internally only, and set by daemon.NewDaemon(). If they're used externally, we should add an accessor added (which may be something we want to do for daemon.registryService (which should be its own backend) Signed-off-by: Sebastiaan van Stijn --- daemon/auth.go | 2 +- daemon/daemon.go | 8 ++++---- daemon/events.go | 2 +- daemon/info.go | 4 ++-- daemon/reload.go | 6 +++--- daemon/reload_test.go | 12 ++++++------ 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/daemon/auth.go b/daemon/auth.go index d32c28b8dd..e97d888371 100644 --- a/daemon/auth.go +++ b/daemon/auth.go @@ -9,5 +9,5 @@ import ( // AuthenticateToRegistry checks the validity of credentials in authConfig func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error) { - return daemon.RegistryService.Auth(ctx, authConfig, dockerversion.DockerUserAgent(ctx)) + return daemon.registryService.Auth(ctx, authConfig, dockerversion.DockerUserAgent(ctx)) } diff --git a/daemon/daemon.go b/daemon/daemon.go index 126b78f55f..f0ca5d8503 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -78,7 +78,7 @@ var ( // Daemon holds information about the Docker daemon. type Daemon struct { - ID string + id string repository string containers container.Store containersReplica container.ViewDB @@ -88,7 +88,7 @@ type Daemon struct { configStore *config.Config statsCollector *stats.Collector defaultLogConfig containertypes.LogConfig - RegistryService registry.Service + registryService registry.Service EventsService *events.Events netController libnetwork.NetworkController volumes *volumesservice.VolumesService @@ -852,7 +852,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S } } - d.RegistryService = registryService + d.registryService = registryService logger.RegisterPluginGetter(d.PluginStore) metricsSockPath, err := d.listenMetricsSock() @@ -1021,7 +1021,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S return nil, errors.New("Devices cgroup isn't mounted") } - d.ID = trustKey.PublicKey().KeyID() + d.id = trustKey.PublicKey().KeyID() d.repository = daemonRepo d.containers = container.NewMemoryStore() if d.containersReplica, err = container.NewViewDB(); err != nil { diff --git a/daemon/events.go b/daemon/events.go index 9b76fdbb97..169b7348a1 100644 --- a/daemon/events.go +++ b/daemon/events.go @@ -91,7 +91,7 @@ func (daemon *Daemon) LogDaemonEventWithAttributes(action string, attributes map attributes["name"] = info.Name } actor := events.Actor{ - ID: daemon.ID, + ID: daemon.id, Attributes: attributes, } daemon.EventsService.Log(action, events.DaemonEventType, actor) diff --git a/daemon/info.go b/daemon/info.go index 4be6ec0c80..b294eaab01 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -32,7 +32,7 @@ func (daemon *Daemon) SystemInfo() *types.Info { sysInfo := daemon.RawSysInfo() v := &types.Info{ - ID: daemon.ID, + ID: daemon.id, Images: daemon.imageService.CountImages(), IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled, BridgeNfIptables: !sysInfo.BridgeNFCallIPTablesDisabled, @@ -50,7 +50,7 @@ func (daemon *Daemon) SystemInfo() *types.Info { IndexServerAddress: registry.IndexServer, OSType: platform.OSType, Architecture: platform.Architecture, - RegistryConfig: daemon.RegistryService.ServiceConfig(), + RegistryConfig: daemon.registryService.ServiceConfig(), NCPU: sysinfo.NumCPU(), MemTotal: memInfo().MemTotal, GenericResources: daemon.genericResources, diff --git a/daemon/reload.go b/daemon/reload.go index cabcf16266..55454bab5b 100644 --- a/daemon/reload.go +++ b/daemon/reload.go @@ -184,7 +184,7 @@ func (daemon *Daemon) reloadAllowNondistributableArtifacts(conf *config.Config, // Update corresponding configuration. if conf.IsValueSet("allow-nondistributable-artifacts") { daemon.configStore.AllowNondistributableArtifacts = conf.AllowNondistributableArtifacts - if err := daemon.RegistryService.LoadAllowNondistributableArtifacts(conf.AllowNondistributableArtifacts); err != nil { + if err := daemon.registryService.LoadAllowNondistributableArtifacts(conf.AllowNondistributableArtifacts); err != nil { return err } } @@ -209,7 +209,7 @@ func (daemon *Daemon) reloadInsecureRegistries(conf *config.Config, attributes m // update corresponding configuration if conf.IsValueSet("insecure-registries") { daemon.configStore.InsecureRegistries = conf.InsecureRegistries - if err := daemon.RegistryService.LoadInsecureRegistries(conf.InsecureRegistries); err != nil { + if err := daemon.registryService.LoadInsecureRegistries(conf.InsecureRegistries); err != nil { return err } } @@ -234,7 +234,7 @@ func (daemon *Daemon) reloadRegistryMirrors(conf *config.Config, attributes map[ // update corresponding configuration if conf.IsValueSet("registry-mirrors") { daemon.configStore.Mirrors = conf.Mirrors - if err := daemon.RegistryService.LoadMirrors(conf.Mirrors); err != nil { + if err := daemon.registryService.LoadMirrors(conf.Mirrors); err != nil { return err } } diff --git a/daemon/reload_test.go b/daemon/reload_test.go index 96124b36fa..0683f53788 100644 --- a/daemon/reload_test.go +++ b/daemon/reload_test.go @@ -58,7 +58,7 @@ func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) { var err error // Initialize daemon with some registries. - daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{ + daemon.registryService, err = registry.NewService(registry.ServiceOptions{ AllowNondistributableArtifacts: []string{ "127.0.0.0/8", "10.10.1.11:5000", @@ -95,7 +95,7 @@ func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) { } var actual []string - serviceConfig := daemon.RegistryService.ServiceConfig() + serviceConfig := daemon.registryService.ServiceConfig() for _, value := range serviceConfig.AllowNondistributableArtifactsCIDRs { actual = append(actual, value.String()) } @@ -113,7 +113,7 @@ func TestDaemonReloadMirrors(t *testing.T) { muteLogs() var err error - daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{ + daemon.registryService, err = registry.NewService(registry.ServiceOptions{ InsecureRegistries: []string{}, Mirrors: []string{ "https://mirror.test1.example.com", @@ -180,7 +180,7 @@ func TestDaemonReloadMirrors(t *testing.T) { // mirrors should be valid, should be no error t.Fatal(err) } - registryService := daemon.RegistryService.ServiceConfig() + registryService := daemon.registryService.ServiceConfig() if len(registryService.Mirrors) != len(value.after) { t.Fatalf("Expected %d daemon mirrors %s while get %d with %s", @@ -215,7 +215,7 @@ func TestDaemonReloadInsecureRegistries(t *testing.T) { var err error // initialize daemon with existing insecure registries: "127.0.0.0/8", "10.10.1.11:5000", "10.10.1.22:5000" - daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{ + daemon.registryService, err = registry.NewService(registry.ServiceOptions{ InsecureRegistries: []string{ "127.0.0.0/8", "10.10.1.11:5000", @@ -256,7 +256,7 @@ func TestDaemonReloadInsecureRegistries(t *testing.T) { // After Reload, daemon.RegistryService will be changed which is useful // for registry communication in daemon. - registries := daemon.RegistryService.ServiceConfig() + registries := daemon.registryService.ServiceConfig() // After Reload(), newConfig has come to registries.InsecureRegistryCIDRs and registries.IndexConfigs in daemon. // Then collect registries.InsecureRegistryCIDRs in dataMap. From d492101172f9992d1f084d486b5b4af81aa037c1 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 2 Mar 2022 12:52:29 +0100 Subject: [PATCH 3/3] daemon: SystemInfo() extract collecting debugging information to a helper This makes it more inline with other data we collect, and can be used to make some info optional at some point. fillDebugInfo sets the current debugging state of the daemon, and additional debugging information, such as the number of Go-routines, and file descriptors. Note that this currently always collects the information, but the CLI only prints it if the daemon has debug enabled. We should consider to either make this information optional (cli to request "with debugging information"), or only collect it if the daemon has debug enabled. For the CLI code, see https://github.com/docker/cli/blob/v20.10.12/cli/command/system/info.go#L239-L244 Additional note: the CLI considers info.SystemTime debugging information. This felt a bit "odd" (daemon time could be useful for standard use), so I left this out of this function. Signed-off-by: Sebastiaan van Stijn --- daemon/info.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/daemon/info.go b/daemon/info.go index b294eaab01..367e670055 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -37,13 +37,9 @@ func (daemon *Daemon) SystemInfo() *types.Info { IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled, BridgeNfIptables: !sysInfo.BridgeNFCallIPTablesDisabled, BridgeNfIP6tables: !sysInfo.BridgeNFCallIP6TablesDisabled, - Debug: debug.IsEnabled(), Name: hostName(), - NFd: fileutils.GetTotalUsedFds(), - NGoroutines: runtime.NumGoroutine(), SystemTime: time.Now().Format(time.RFC3339Nano), LoggingDriver: daemon.defaultLogConfig.Type, - NEventsListener: daemon.EventsService.SubscribersCount(), KernelVersion: kernelVersion(), OperatingSystem: operatingSystem(), OSVersion: osVersion(), @@ -66,6 +62,7 @@ func (daemon *Daemon) SystemInfo() *types.Info { } daemon.fillContainerStates(v) + daemon.fillDebugInfo(v) daemon.fillAPIInfo(v) // Retrieve platform specific info daemon.fillPlatformInfo(v, sysInfo) @@ -185,6 +182,21 @@ func (daemon *Daemon) fillContainerStates(v *types.Info) { v.ContainersStopped = cStopped } +// fillDebugInfo sets the current debugging state of the daemon, and additional +// debugging information, such as the number of Go-routines, and file descriptors. +// +// Note that this currently always collects the information, but the CLI only +// prints it if the daemon has debug enabled. We should consider to either make +// this information optional (cli to request "with debugging information"), or +// only collect it if the daemon has debug enabled. For the CLI code, see +// https://github.com/docker/cli/blob/v20.10.12/cli/command/system/info.go#L239-L244 +func (daemon *Daemon) fillDebugInfo(v *types.Info) { + v.Debug = debug.IsEnabled() + v.NFd = fileutils.GetTotalUsedFds() + v.NGoroutines = runtime.NumGoroutine() + v.NEventsListener = daemon.EventsService.SubscribersCount() +} + func (daemon *Daemon) fillAPIInfo(v *types.Info) { const warn string = ` Access to the remote API is equivalent to root access on the host. Refer