@@ -148,42 +148,31 @@ def choose_action(machine_config, metrics, dry_run, options, S):
148148 return result
149149
150150
151- def main ():
152- config .initialize ()
153-
154- # Bind locals from config module (set by initialize())
155- options = config .options
156- S = config .S
157- engine = config .engine
158- machine_config = config .machine_config
159- config_updates = config .config_updates
160-
161- # Handle --version flag (before any lock file or database checks)
162- if options .version :
163- print (f"wnm version { __version__ } " )
151+ def _handle_remove_lockfile ():
152+ """Handle --remove_lockfile flag and exit."""
153+ if os .path .exists (LOCK_FILE ):
154+ try :
155+ os .remove (LOCK_FILE )
156+ logging .info (f"Lock file removed: { LOCK_FILE } " )
157+ sys .exit (0 )
158+ except (PermissionError , OSError ) as e :
159+ logging .error (f"Error removing lock file: { e } " )
160+ sys .exit (1 )
161+ else :
162+ logging .info (f"Lock file does not exist: { LOCK_FILE } " )
164163 sys .exit (0 )
165164
166- # Handle --remove_lockfile flag (before normal lock file check)
167- if options .remove_lockfile :
168- if os .path .exists (LOCK_FILE ):
169- try :
170- os .remove (LOCK_FILE )
171- logging .info (f"Lock file removed: { LOCK_FILE } " )
172- sys .exit (0 )
173- except (PermissionError , OSError ) as e :
174- logging .error (f"Error removing lock file: { e } " )
175- sys .exit (1 )
176- else :
177- logging .info (f"Lock file does not exist: { LOCK_FILE } " )
178- sys .exit (0 )
165+
166+ def acquire_lock ():
167+ """Check for existing lock file, create a new one, or exit."""
168+ global _lock_file_created
179169
180170 # Are we already running
181171 if os .path .exists (LOCK_FILE ):
182172 logging .warning ("wnm still running" )
183173 sys .exit (1 )
184174
185175 # We're starting, so lets create a lock file
186- global _lock_file_created
187176 try :
188177 with open (LOCK_FILE , "w" ) as file :
189178 file .write (str (int (time .time ())))
@@ -193,40 +182,51 @@ def main():
193182 logging .error (f"Unable to create lock file: { e } " )
194183 sys .exit (1 )
195184
196- # Handle database migration command first (before any config checks)
197- if options .force_action == "wnm-db-migration" :
198- if not options .confirm :
199- logging .error ("Database migration requires --confirm flag for safety" )
200- logging .info ("Use: wnm --force_action wnm-db-migration --confirm" )
201- sys .exit (1 )
202185
203- # Import migration utilities
204- from wnm .db_migration import has_pending_migrations , run_migrations
186+ def handle_db_migration (engine , options ):
187+ """Handle --force_action wnm-db-migration. Returns if not applicable."""
188+ if options .force_action != "wnm-db-migration" :
189+ return
205190
206- # Check if there are pending migrations
207- pending , current , head = has_pending_migrations (engine , options .dbpath )
191+ if not options .confirm :
192+ logging .error ("Database migration requires --confirm flag for safety" )
193+ logging .info ("Use: wnm --force_action wnm-db-migration --confirm" )
194+ sys .exit (1 )
208195
209- if not pending :
210- logging .info ("Database is already up to date!" )
211- logging .info (f"Current revision: { current } " )
212- sys .exit (0 )
196+ # Import migration utilities
197+ from wnm .db_migration import has_pending_migrations , run_migrations
198+
199+ # Check if there are pending migrations
200+ pending , current , head = has_pending_migrations (engine , options .dbpath )
201+
202+ if not pending :
203+ logging .info ("Database is already up to date!" )
204+ logging .info (f"Current revision: { current } " )
205+ sys .exit (0 )
206+
207+ logging .info ("=" * 70 )
208+ logging .info ("RUNNING DATABASE MIGRATIONS" )
209+ logging .info ("=" * 70 )
210+ logging .info (f"Upgrading database from { current or 'unversioned' } to { head } " )
213211
212+ try :
213+ run_migrations (engine , options .dbpath )
214+ logging .info ("Database migration completed successfully!" )
214215 logging .info ("=" * 70 )
215- logging .info ("RUNNING DATABASE MIGRATIONS" )
216+ sys .exit (0 )
217+ except Exception as e :
218+ logging .error (f"Migration failed: { e } " )
219+ logging .error ("Please restore from backup and report this issue." )
216220 logging .info ("=" * 70 )
217- logging . info ( f"Upgrading database from { current or 'unversioned' } to { head } " )
221+ sys . exit ( 1 )
218222
219- try :
220- run_migrations (engine , options .dbpath )
221- logging .info ("Database migration completed successfully!" )
222- logging .info ("=" * 70 )
223- sys .exit (0 )
224- except Exception as e :
225- logging .error (f"Migration failed: { e } " )
226- logging .error ("Please restore from backup and report this issue." )
227- logging .info ("=" * 70 )
228- sys .exit (1 )
229223
224+ def validate_and_apply_config (options , machine_config , config_updates ):
225+ """Validate machine config, handle config-only actions, apply updates.
226+
227+ Returns:
228+ local_config dict for use by subsequent phases.
229+ """
230230 # Config should have loaded the machine_config
231231 if machine_config :
232232 # Only log machine config at INFO level if --show_machine_config or -v is set
@@ -278,6 +278,15 @@ def main():
278278 else :
279279 local_config = json .loads (json .dumps (machine_config ))
280280
281+ return local_config
282+
283+
284+ def collect_metrics (S , local_config , options ):
285+ """Collect system and node metrics.
286+
287+ Returns:
288+ metrics dict.
289+ """
281290 metrics = get_machine_metrics (
282291 S ,
283292 local_config ["node_storage" ],
@@ -292,6 +301,15 @@ def main():
292301 ):
293302 logging .info (json .dumps (metrics , indent = 2 ))
294303
304+ return metrics
305+
306+
307+ def handle_init_survey (options , S , machine_config , local_config , metrics ):
308+ """Handle node survey/import during --init, then exit if --init is set.
309+
310+ Returns:
311+ Potentially-reloaded metrics dict.
312+ """
295313 # Do we already have nodes
296314 if metrics ["total_nodes" ] == 0 :
297315 # Survey for existing nodes only if explicitly requested:
@@ -380,6 +398,11 @@ def main():
380398 logging .info ("Initialization complete" )
381399 sys .exit (0 )
382400
401+ return metrics
402+
403+
404+ def run_or_report (options , S , local_config , metrics ):
405+ """Handle reports, forced actions, or the normal decision cycle."""
383406 # Check for reports
384407 if options .report :
385408 from wnm .reports import (
@@ -450,11 +473,38 @@ def main():
450473
451474 logging .info ("Action: " + json .dumps (this_action , indent = 2 ))
452475
476+
477+ def main ():
478+ config .initialize ()
479+
480+ # Bind locals from config module (set by initialize())
481+ options = config .options
482+ S = config .S
483+ engine = config .engine
484+ machine_config = config .machine_config
485+ config_updates = config .config_updates
486+
487+ # Handle --version flag (before any lock file or database checks)
488+ if options .version :
489+ print (f"wnm version { __version__ } " )
490+ sys .exit (0 )
491+
492+ # Handle --remove_lockfile flag (before normal lock file check)
493+ if options .remove_lockfile :
494+ _handle_remove_lockfile ()
495+
496+ acquire_lock ()
497+ handle_db_migration (engine , options )
498+
499+ local_config = validate_and_apply_config (options , machine_config , config_updates )
500+ metrics = collect_metrics (S , local_config , options )
501+ metrics = handle_init_survey (options , S , machine_config , local_config , metrics )
502+ run_or_report (options , S , local_config , metrics )
503+
453504 # Exit normally (atexit will clean up lock file)
454505 sys .exit (0 )
455506
456507
457508if __name__ == "__main__" :
458509 main ()
459- # print(options.MemRemove)
460510 logging .debug ("End of program" )
0 commit comments