Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ var applyCmd = &cobra.Command{
}

config_lint.Validate(cfg)
if err := config_lint.ValidateWithError(cfg); err != nil {
return fmt.Errorf("config validation failed: %w", err)
}

tapplier, err := templating.NewTemplateApplier(cfg, nil)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions internal/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ func retrieveContainerVersionsFromExporters(loaded *LoadedLabConfig) map[string]

// Retrieve version information for each unique image
for imageURL := range uniqueImages {
fmt.Printf("🔍 Checking container version for %s...\n", imageURL)

imageLabels, err := container.GetImageLabelsFromRegistry(imageURL)
if err != nil {
fmt.Printf("Latest container version of %s: unavailable (%v)\n", imageURL, err)
Expand Down
31 changes: 20 additions & 11 deletions internal/exporter/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,17 @@ func (m *SSHHostManager) Apply(exporterConfig *v1alpha1.ExporterConfigTemplate,
return fmt.Errorf("both SystemdContainerTemplate and SystemdServiceTemplate specified - only one should be used")
}

// Helper function to restart service
restartService := func(serviceName string, dryRun bool) {
// Helper function to restart service, gracefully wating on lease exit
restartGracefully := func(serviceName string, dryRun bool) {
if !dryRun {
_, enableErr := m.runCommand("systemctl restart " + fmt.Sprintf("%q", serviceName))
_, enableErr := m.runCommand(fmt.Sprintf("command -v podman >/dev/null 2>&1 && podman kill -s SIGHUP %q || systemctl kill -s SIGHUP %q", serviceName, serviceName))
if enableErr != nil {
fmt.Printf(" ❌ Failed to start service %s: %v\n", serviceName, enableErr)
fmt.Printf(" ❌ Failed to signal %s: %v\n", serviceName, enableErr)
} else {
fmt.Printf(" ✅ Service %s started\n", serviceName)
fmt.Printf(" ✅ %s signalled to restart when not leased\n", serviceName)
}
} else {
fmt.Printf(" 📄 Would restart service %s\n", serviceName)
fmt.Printf(" 📄 Would trigger restart of %s\n", serviceName)
}
}

Expand Down Expand Up @@ -245,7 +245,7 @@ func (m *SSHHostManager) Apply(exporterConfig *v1alpha1.ExporterConfigTemplate,
return fmt.Errorf("failed to enable exporter: %w", err)
}
}
restartService(svcName, dryRun)
restartGracefully(svcName, dryRun)
}
} else {
// Check if service is running and start if needed
Expand All @@ -254,10 +254,19 @@ func (m *SSHHostManager) Apply(exporterConfig *v1alpha1.ExporterConfigTemplate,

if !serviceRunning {
fmt.Printf(" ⚠️ Service %s is not running...\n", svcName)
restartService(svcName, dryRun)
if !dryRun {
_, enableErr := m.runCommand("systemctl restart " + fmt.Sprintf("%q", svcName))
if enableErr != nil {
fmt.Printf(" ❌ Failed to restart service %s: %v\n", svcName, enableErr)
} else {
fmt.Printf(" ✅ Service %s restarted\n", svcName)
}
} else {
fmt.Printf(" 📄 Would restart service %s\n", svcName)
}
} else {
// Only check container version if service is running
err = m.checkContainerVersion(exporterConfig, svcName, dryRun, restartService)
err = m.checkContainerVersion(exporterConfig, svcName, dryRun, restartGracefully)
if err != nil {
return fmt.Errorf("container version check failed: %w", err)
}
Expand Down Expand Up @@ -327,12 +336,12 @@ func (m *SSHHostManager) checkDetailedContainerVersion(containerImage, svcName s
// getRunningContainerLabels gets container labels from running container
func (m *SSHHostManager) getRunningContainerLabels(serviceName string) (*container.ImageLabels, error) {
// Try jumpstarter labels first, then fall back to OCI standard labels
result, err := m.runCommand(fmt.Sprintf("podman inspect --format '{{index .Config.Labels \"jumpstarter.version\"}}\n{{index .Config.Labels \"jumpstarter.revision\"}}\n{{index .Config.Labels \"org.opencontainers.image.version\"}}\n{{index .Config.Labels \"org.opencontainers.image.revision\"}}' %s", serviceName))
result, err := m.runCommand(fmt.Sprintf("podman inspect --format '{{index .Config.Labels \"jumpstarter.version\"}} {{index .Config.Labels \"jumpstarter.revision\"}} {{index .Config.Labels \"org.opencontainers.image.version\"}} {{index .Config.Labels \"org.opencontainers.image.revision\"}}' %s", serviceName))
if err != nil {
return nil, fmt.Errorf("failed to inspect container %s: %w", serviceName, err)
}

parts := strings.Split(strings.TrimSpace(result.Stdout), "\n")
parts := strings.Fields(strings.TrimSpace(result.Stdout))
// Pad with empty strings if we got fewer parts
for len(parts) < 4 {
parts = append(parts, "")
Expand Down