Skip to content

Commit a091e4a

Browse files
authored
Merge pull request #10 from michalskrivanek/latest
check if running latest containers
2 parents 579b823 + 41ff3dd commit a091e4a

File tree

2 files changed

+87
-9
lines changed

2 files changed

+87
-9
lines changed

internal/exporter/host/host.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,41 @@ func (e *ExporterHostSyncer) SyncExporterHosts() error {
8686
if err != nil {
8787
return fmt.Errorf("error getting status for %s: %w", host.Name, err)
8888
}
89-
fmt.Printf(" Connection status: %s\n", status)
89+
if e.dryRun {
90+
fmt.Printf(" ✅ Connection: %s\n", status)
91+
}
92+
93+
// Check if bootc upgrade service is already running
94+
serviceStatus, _ := hostSsh.RunHostCommand("systemctl is-active bootc-fetch-apply-updates.service")
95+
if serviceStatus != nil {
96+
status := strings.TrimSpace(serviceStatus.Stdout)
97+
if status == "active" || status == "activating" {
98+
fmt.Printf(" ⚠️ Bootc upgrade in progress, skipping exporter instances for this host\n")
99+
continue
100+
}
101+
}
102+
103+
// Check booted image
104+
bootcStdout, err := hostSsh.RunHostCommand("[ -f /run/ostree-booted ] && bootc upgrade --check")
105+
if err == nil && bootcStdout != nil && bootcStdout.ExitCode == 0 && bootcStdout.Stdout != "" {
106+
if strings.HasPrefix(bootcStdout.Stdout, "No changes") {
107+
if e.dryRun {
108+
fmt.Printf(" ✅ Bootc image is up to date\n")
109+
}
110+
} else if e.dryRun {
111+
fmt.Printf(" 📄 Would upgrade bootc image\n")
112+
} else {
113+
// Trigger bootc upgrade service now
114+
_, err := hostSsh.RunHostCommand("systemctl start --no-block bootc-fetch-apply-updates.service")
115+
if err != nil {
116+
return fmt.Errorf("error triggering bootc upgrade service: %w", err)
117+
}
118+
fmt.Printf(" ✅ Bootc upgrade started, skipping exporter instances for this host\n")
119+
continue
120+
}
121+
} else {
122+
fmt.Printf(" ℹ️ Not a bootc managed host\n")
123+
}
90124

91125
for _, exporterInstance := range exporterInstances {
92126
fmt.Printf(" 📟 Exporter instance: %s\n", exporterInstance.Name)

internal/exporter/ssh/ssh.go

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os"
99
"path/filepath"
1010
"regexp"
11+
"strings"
1112
"sync"
1213
"time"
1314

@@ -23,6 +24,7 @@ type HostManager interface {
2324
NeedsUpdate() (bool, error)
2425
Diff() (string, error)
2526
Apply(exporterConfig *v1alpha1.ExporterConfigTemplate, dryRun bool) error
27+
RunHostCommand(command string) (*CommandResult, error)
2628
}
2729

2830
// CommandResult represents the result of running a command via SSH
@@ -166,6 +168,20 @@ func (m *SSHHostManager) Apply(exporterConfig *v1alpha1.ExporterConfigTemplate,
166168
return fmt.Errorf("both SystemdContainerTemplate and SystemdServiceTemplate specified - only one should be used")
167169
}
168170

171+
// Helper function to restart service
172+
restartService := func(serviceName string, dryRun bool) {
173+
if !dryRun {
174+
_, enableErr := m.runCommand("systemctl restart " + fmt.Sprintf("%q", serviceName))
175+
if enableErr != nil {
176+
fmt.Printf(" ❌ Failed to start service %s: %v\n", serviceName, enableErr)
177+
} else {
178+
fmt.Printf(" ✅ Service %s started\n", serviceName)
179+
}
180+
} else {
181+
fmt.Printf(" 📄 Would restart service %s\n", serviceName)
182+
}
183+
}
184+
169185
svcName := exporterConfig.Spec.ExporterMetadata.Name
170186
containerSystemdFile := "/etc/containers/systemd/" + svcName + ".container"
171187
serviceSystemdFile := "/etc/systemd/system/" + svcName + ".service"
@@ -194,26 +210,54 @@ func (m *SSHHostManager) Apply(exporterConfig *v1alpha1.ExporterConfigTemplate,
194210
return fmt.Errorf("failed to reload systemd: %w", err)
195211
}
196212
if changedService {
197-
_, err = m.runCommand("systemctl enable " + svcName)
213+
_, err = m.runCommand("systemctl enable " + fmt.Sprintf("%q", svcName))
198214
if err != nil {
199215
return fmt.Errorf("failed to enable exporter: %w", err)
200216
}
201217
}
202-
_, err = m.runCommand("systemctl restart " + svcName)
203-
if err != nil {
204-
return fmt.Errorf("failed to restart exporter: %w", err)
205-
}
206-
fmt.Printf(" ✅ Exporter service started\n")
218+
restartService(svcName, dryRun)
207219
}
208220
} else {
209-
if dryRun {
210-
fmt.Printf(" ✅ dry run: No changes needed\n")
221+
// Check if service is running and start if needed
222+
statusResult, err := m.runCommand("systemctl is-active " + fmt.Sprintf("%q", svcName))
223+
if err != nil || statusResult.Stdout != "active\n" {
224+
fmt.Printf(" ⚠️ Service %s is not running...\n", svcName)
225+
restartService(svcName, dryRun)
226+
}
227+
228+
// Check if container needs updating using podman auto-update (if podman exists)
229+
autoUpdateResult, err := m.runCommand(fmt.Sprintf("command -v podman >/dev/null 2>&1 && podman auto-update --dry-run --format json | jq -r '.[] | select(.ContainerName == %q) | .Updated'", svcName))
230+
if err != nil {
231+
fmt.Printf(" ℹ️ Podman not available, skipping auto-update check\n")
232+
} else {
233+
updatedOutput := strings.TrimSpace(autoUpdateResult.Stdout)
234+
switch updatedOutput {
235+
case "":
236+
fmt.Printf(" ⚠️ Container %s not found in auto-update check\n", svcName)
237+
case "false":
238+
if dryRun {
239+
fmt.Printf(" ✅ Exporter container image is up to date\n")
240+
}
241+
case "true":
242+
if dryRun {
243+
fmt.Printf(" 📄 Would update container %s\n", svcName)
244+
} else {
245+
restartService(svcName, dryRun)
246+
}
247+
default:
248+
return fmt.Errorf("unexpected auto-update result: %s", updatedOutput)
249+
}
211250
}
212251
}
213252

214253
return nil
215254
}
216255

256+
// RunHostCommand implements the HostManager interface by exposing runCommand
257+
func (m *SSHHostManager) RunHostCommand(command string) (*CommandResult, error) {
258+
return m.runCommand(command)
259+
}
260+
217261
// sanitizeDiff removes sensitive information from diff output
218262
func sanitizeDiff(diff string) string {
219263
// Regex patterns to match sensitive fields

0 commit comments

Comments
 (0)