@@ -161,20 +161,24 @@ func (m *SSHHostManager) Diff() (string, error) {
161161}
162162
163163func (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