Skip to content

Commit df1de16

Browse files
authored
Merge pull request #5 from michalskrivanek/servicesystemdtemplate
add optional serviceSystemdTemplate
2 parents 3c80e81 + 91ed5ea commit df1de16

File tree

4 files changed

+51
-11
lines changed

4 files changed

+51
-11
lines changed

api/v1alpha1/exporterconfigtemplate_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ type ExporterConfigTemplateSpec struct {
4343
// +kubebuilder:validation:Optional
4444
// +kubebuilder:validation:MinLength=1
4545
SystemdContainerTemplate string `json:"systemdContainerTemplate"`
46+
47+
// SystemdServiceTemplate is the raw YAML string content for the systemd service config template.
48+
// +kubebuilder:validation:Optional
49+
// +kubebuilder:validation:MinLength=1
50+
SystemdServiceTemplate string `json:"systemdServiceTemplate"`
4651
}
4752

4853
// ExporterMeta defines metadata for the exporter.

config/crd/bases/meta.jumpstarter.dev_exporterconfigtemplates.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ spec:
7070
for the systemd container config template.
7171
minLength: 1
7272
type: string
73+
systemdServiceTemplate:
74+
description: SystemdServiceTemplate is the raw YAML string content
75+
for the systemd service config template.
76+
minLength: 1
77+
type: string
7378
required:
7479
- configTemplate
7580
- containerImage

internal/exporter/host/host.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,14 @@ func (e *ExporterHostSyncer) SyncExporterHosts() error {
9494
if e.debugConfigs {
9595
fmt.Printf("--- 📄 Config Template %s\n", strings.Repeat("─", 40))
9696
fmt.Printf("%s\n", tcfg.Spec.ConfigTemplate)
97-
fmt.Printf(" - ⚙️ Systemd Container Template %s\n", strings.Repeat("─", 30))
98-
fmt.Printf("%s\n", tcfg.Spec.SystemdContainerTemplate)
97+
if tcfg.Spec.SystemdContainerTemplate != "" {
98+
fmt.Printf(" - ⚙️ Systemd Container Template %s\n", strings.Repeat("─", 30))
99+
fmt.Printf("%s\n", tcfg.Spec.SystemdContainerTemplate)
100+
}
101+
if tcfg.Spec.SystemdServiceTemplate != "" {
102+
fmt.Printf(" - 🔧 Systemd Service Template %s\n", strings.Repeat("─", 31))
103+
fmt.Printf("%s\n", tcfg.Spec.SystemdServiceTemplate)
104+
}
99105
fmt.Println(strings.Repeat("─", 60))
100106
}
101107

internal/exporter/ssh/ssh.go

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,20 +161,24 @@ func (m *SSHHostManager) Diff() (string, error) {
161161
}
162162

163163
func (m *SSHHostManager) Apply(exporterConfig *v1alpha1.ExporterConfigTemplate, dryRun bool) error {
164+
// Validate mutual exclusivity: both templates cannot be specified simultaneously
165+
if exporterConfig.Spec.SystemdContainerTemplate != "" && exporterConfig.Spec.SystemdServiceTemplate != "" {
166+
return fmt.Errorf("both SystemdContainerTemplate and SystemdServiceTemplate specified - only one should be used")
167+
}
164168

165169
svcName := exporterConfig.Spec.ExporterMetadata.Name
166170
containerSystemdFile := "/etc/containers/systemd/" + svcName + ".container"
171+
serviceSystemdFile := "/etc/systemd/system/" + svcName + ".service"
167172
exporterConfigFile := "/etc/jumpstarter/exporters/" + svcName + ".yaml"
168173

169-
// if running docker let's use a traditional systemd service instead of podman quadlet
170-
result, _ := m.runCommand("systemctl status docker")
171-
if result.ExitCode == 0 {
172-
containerSystemdFile = "/etc/systemd/system/" + svcName + ".service"
174+
changedContainer, err := m.reconcileFile(containerSystemdFile, exporterConfig.Spec.SystemdContainerTemplate, dryRun)
175+
if err != nil {
176+
return fmt.Errorf("failed to reconcile container systemd file: %w", err)
173177
}
174178

175-
changedSystemd, err := m.reconcileFile(containerSystemdFile, exporterConfig.Spec.SystemdContainerTemplate, dryRun)
179+
changedService, err := m.reconcileFile(serviceSystemdFile, exporterConfig.Spec.SystemdServiceTemplate, dryRun)
176180
if err != nil {
177-
return fmt.Errorf("failed to reconcile container systemd file: %w", err)
181+
return fmt.Errorf("failed to reconcile service systemd file: %w", err)
178182
}
179183

180184
changedExporterConfig, err := m.reconcileFile(exporterConfigFile, exporterConfig.Spec.ConfigTemplate, dryRun)
@@ -183,7 +187,7 @@ func (m *SSHHostManager) Apply(exporterConfig *v1alpha1.ExporterConfigTemplate,
183187
}
184188

185189
// if any of the files changed, reload systemd, enable service and restart the exporter
186-
if (changedExporterConfig || changedSystemd) && !dryRun {
190+
if (changedExporterConfig || changedContainer || changedService) && !dryRun {
187191
_, err := m.runCommand("systemctl daemon-reload")
188192
if err != nil {
189193
return fmt.Errorf("failed to reload systemd: %w", err)
@@ -232,7 +236,13 @@ func (m *SSHHostManager) reconcileFile(path string, content string, dryRun bool)
232236
// Check if file exists and read its content
233237
file, err := m.sftpClient.Open(path)
234238
if err != nil {
235-
// File doesn't exist, we need to create it
239+
// File doesn't exist
240+
if content == "" {
241+
// File doesn't exist and content is empty - nothing to do
242+
return false, nil
243+
}
244+
245+
// File doesn't exist and content is not empty - create it
236246
if dryRun {
237247
fmt.Printf(" 📄 Would create file: %s\n", path)
238248
return true, nil
@@ -261,7 +271,7 @@ func (m *SSHHostManager) reconcileFile(path string, content string, dryRun bool)
261271
return false, fmt.Errorf("failed to write content to %s: %w", path, err)
262272
}
263273

264-
fmt.Printf("Created file: %s\n", path)
274+
fmt.Printf(" 📄 Created file: %s\n", path)
265275
return true, nil
266276
}
267277

@@ -273,6 +283,20 @@ func (m *SSHHostManager) reconcileFile(path string, content string, dryRun bool)
273283
return false, fmt.Errorf("failed to read existing file %s: %w", path, err)
274284
}
275285

286+
// If content is empty, delete the file
287+
if content == "" {
288+
if dryRun {
289+
fmt.Printf(" 🗑️ Would delete file: %s\n", path)
290+
return true, nil
291+
}
292+
err = m.sftpClient.Remove(path)
293+
if err != nil {
294+
return false, fmt.Errorf("failed to delete file %s: %w", path, err)
295+
}
296+
fmt.Printf(" 🗑️ Deleted file: %s\n", path)
297+
return true, nil
298+
}
299+
276300
// Check if content matches
277301
if string(existingContent) == content {
278302
// Content matches, no change needed

0 commit comments

Comments
 (0)