@@ -35,13 +35,50 @@ import (
35
35
"github.com/containerd/nerdctl/v2/pkg/rootlessutil"
36
36
)
37
37
38
+ // IsDbusFunctional tests if DBUS connections actually work in the current environment.
39
+ // This is more reliable than just checking if DBUS tools are installed.
40
+ func IsDbusFunctional (ctx context.Context ) bool {
41
+ // Create timeout context to prevent hanging on DBUS connection attempts
42
+ timeoutCtx , cancel := context .WithTimeout (ctx , 2 * time .Second )
43
+ defer cancel ()
44
+
45
+ var conn * dbus.Conn
46
+ var err error
47
+
48
+ if rootlessutil .IsRootless () {
49
+ // Test user DBUS connection for rootless environments
50
+ conn , err = dbus .NewUserConnectionContext (timeoutCtx )
51
+ } else {
52
+ // Test system DBUS connection for rootful environments
53
+ conn , err = dbus .NewSystemConnectionContext (timeoutCtx )
54
+ }
55
+
56
+ if err != nil {
57
+ return false
58
+ }
59
+ defer conn .Close ()
60
+ return true
61
+ }
62
+
38
63
// CreateTimer sets up the transient systemd timer and service for healthchecks.
39
64
func CreateTimer (ctx context.Context , container containerd.Container ) error {
40
65
hc := extractHealthcheck (ctx , container )
41
66
if hc == nil {
67
+ log .G (ctx ).Debugf ("No healthcheck configuration found for container %s" , container .ID ())
42
68
return nil
43
69
}
44
- if shouldSkipHealthCheckSystemd (hc ) {
70
+
71
+ if shouldSkipHealthCheckSystemd (ctx , hc ) {
72
+ // Log specific reason for skipping to help with troubleshooting
73
+ if ! defaults .IsSystemdAvailable () {
74
+ log .G (ctx ).Infof ("Skipping healthcheck timer for container %s: systemd not available" , container .ID ())
75
+ } else if ! IsDbusFunctional (ctx ) {
76
+ log .G (ctx ).Infof ("Skipping healthcheck timer for container %s: DBUS connection unavailable (likely containerized environment)" , container .ID ())
77
+ } else if os .Getenv ("DISABLE_HC_SYSTEMD" ) == "true" {
78
+ log .G (ctx ).Infof ("Skipping healthcheck timer for container %s: disabled by DISABLE_HC_SYSTEMD" , container .ID ())
79
+ } else if hc == nil || len (hc .Test ) == 0 || hc .Test [0 ] == "NONE" || hc .Interval == 0 {
80
+ log .G (ctx ).Debugf ("Skipping healthcheck timer for container %s: invalid healthcheck configuration" , container .ID ())
81
+ }
45
82
return nil
46
83
}
47
84
@@ -91,7 +128,7 @@ func StartTimer(ctx context.Context, container containerd.Container) error {
91
128
log .G (ctx ).Infof ("DEBUG: No healthcheck found, skipping StartTimer" )
92
129
return nil
93
130
}
94
- if shouldSkipHealthCheckSystemd (hc ) {
131
+ if shouldSkipHealthCheckSystemd (ctx , hc ) {
95
132
log .G (ctx ).Infof ("DEBUG: Skipping healthcheck systemd, shouldSkip=true" )
96
133
return nil
97
134
}
@@ -291,16 +328,16 @@ func extractHealthcheck(ctx context.Context, container containerd.Container) *He
291
328
}
292
329
293
330
// shouldSkipHealthCheckSystemd determines if healthcheck timers should be skipped.
294
- func shouldSkipHealthCheckSystemd (hc * Healthcheck ) bool {
331
+ func shouldSkipHealthCheckSystemd (ctx context. Context , hc * Healthcheck ) bool {
295
332
// Don't proceed if systemd is unavailable or disabled
296
333
if ! defaults .IsSystemdAvailable () || os .Getenv ("DISABLE_HC_SYSTEMD" ) == "true" {
297
334
return true
298
335
}
299
336
300
- // Skip healthchecks in environments without dbus-launch to avoid permission issues
301
- // if _, err := exec.LookPath("dbus-launch"); err != nil {
302
- // return true
303
- // }
337
+ // Test actual DBUS connectivity - this is more reliable than checking for tools
338
+ if ! IsDbusFunctional ( ctx ) {
339
+ return true
340
+ }
304
341
305
342
// Don't proceed if health check is nil, empty, explicitly NONE or interval is 0.
306
343
if hc == nil || len (hc .Test ) == 0 || hc .Test [0 ] == "NONE" || hc .Interval == 0 {
0 commit comments