1313from asimov.scheduler_utils import get_configured_scheduler, create_job_from_dict, get_job_list
1414from asimov.monitor_helpers import monitor_analysis
1515
16+ # Try to import crontab for Slurm cron support
17+ try:
18+ from crontab import CronTab
19+ CRONTAB_AVAILABLE = True
20+ except ImportError:
21+ CRONTAB_AVAILABLE = False
22+
1623logger = logger.getChild("cli").getChild("monitor")
1724logger.setLevel(LOGGER_LEVEL)
1825
@@ -109,8 +116,10 @@ def _start_htcondor_monitor(dry_run, use_scheduler_api):
109116
110117def _start_slurm_monitor():
111118 """Start monitoring using system cron job for Slurm."""
112- import subprocess
113- from crontab import CronTab
119+ if not CRONTAB_AVAILABLE:
120+ # python-crontab not available, provide manual instructions
121+ _start_slurm_monitor_manual()
122+ return
114123
115124 try:
116125 minute_expression = config.get("slurm", "cron_minute")
@@ -125,7 +134,6 @@ def _start_slurm_monitor():
125134 click.secho(" \t ● Error: asimov executable not found in PATH", fg="red")
126135 return
127136
128- # Create a cron job using python-crontab
129137 try:
130138 # Use the user's crontab
131139 cron = CronTab(user=True)
@@ -158,25 +166,39 @@ def _start_slurm_monitor():
158166 click.secho(f" \t ● Asimov is running via cron ({job_comment})", fg="green")
159167 logger.info(f"Running asimov cronjob via cron: {job_comment}")
160168
161- except ImportError:
162- # If python-crontab is not available, provide manual instructions
163- click.secho(" \t ● python-crontab not installed. Setting up cron manually...", fg="yellow")
164-
165- # Create a shell script as an alternative
166- script_path = os.path.join(".asimov", "asimov_monitor.sh")
167- with open(script_path, 'w') as f:
168- f.write("#!/bin/bash\n")
169- f.write(f"cd {project_root}\n")
170- f.write(f"{asimov_executable} monitor --chain >> {os.path.join('.asimov', 'asimov_cron.out')} 2>> {os.path.join('.asimov', 'asimov_cron.err')}\n")
171-
172- os.chmod(script_path, 0o755)
173-
174- click.echo(f"\nPlease add the following line to your crontab (crontab -e):")
175- click.echo(f"{minute_expression} * * * * {script_path}")
176-
177- # Save a marker in the ledger
178- ledger.data["cronjob"] = "manual-cron"
179- ledger.save()
169+ except Exception as e:
170+ logger.error(f"Failed to create cron job: {e}")
171+ click.secho(f" \t ● Error creating cron job: {e}", fg="red")
172+ _start_slurm_monitor_manual()
173+
174+
175+ def _start_slurm_monitor_manual():
176+ """Provide manual instructions for setting up Slurm monitoring."""
177+ try:
178+ minute_expression = config.get("slurm", "cron_minute")
179+ except (configparser.NoOptionError, configparser.NoSectionError):
180+ minute_expression = "*/15"
181+
182+ project_root = os.getcwd()
183+ asimov_executable = shutil.which("asimov") or "asimov"
184+
185+ click.secho(" \t ● python-crontab not installed. Setting up cron manually...", fg="yellow")
186+
187+ # Create a shell script as an alternative
188+ script_path = os.path.join(".asimov", "asimov_monitor.sh")
189+ with open(script_path, 'w') as f:
190+ f.write("#!/bin/bash\n")
191+ f.write(f"cd {project_root}\n")
192+ f.write(f"{asimov_executable} monitor --chain >> {os.path.join('.asimov', 'asimov_cron.out')} 2>> {os.path.join('.asimov', 'asimov_cron.err')}\n")
193+
194+ os.chmod(script_path, 0o755)
195+
196+ click.echo(f"\nPlease add the following line to your crontab (crontab -e):")
197+ click.echo(f"{minute_expression} * * * * {script_path}")
198+
199+ # Save a marker in the ledger
200+ ledger.data["cronjob"] = "manual-cron"
201+ ledger.save()
180202
181203
182204@click.option("--dry-run", "-n", "dry_run", is_flag=True)
@@ -226,7 +248,9 @@ def _stop_htcondor_monitor(dry_run, use_scheduler_api):
226248
227249def _stop_slurm_monitor():
228250 """Stop monitoring by removing cron job for Slurm."""
229- from crontab import CronTab
251+ if not CRONTAB_AVAILABLE:
252+ _stop_slurm_monitor_manual()
253+ return
230254
231255 cronjob_id = ledger.data.get("cronjob", None)
232256
@@ -235,8 +259,7 @@ def _stop_slurm_monitor():
235259 return
236260
237261 if cronjob_id == "manual-cron":
238- click.secho(" \t ● Manual cron setup detected. Please remove from crontab manually.", fg="yellow")
239- click.echo("Run 'crontab -e' and remove the line containing 'asimov_monitor.sh'")
262+ _stop_slurm_monitor_manual()
240263 return
241264
242265 try:
@@ -253,9 +276,17 @@ def _stop_slurm_monitor():
253276 else:
254277 click.secho(f" \t ● No cron job found with identifier: {cronjob_id}", fg="yellow")
255278
256- except ImportError:
257- click.secho(" \t ● python-crontab not installed. Please remove cron job manually.", fg="yellow")
258- click.echo(f"Run 'crontab -e' and remove the line with comment: {cronjob_id}")
279+ except Exception as e:
280+ logger.error(f"Failed to remove cron job: {e}")
281+ click.secho(f" \t ● Error removing cron job: {e}", fg="red")
282+ _stop_slurm_monitor_manual()
283+
284+
285+ def _stop_slurm_monitor_manual():
286+ """Provide manual instructions for removing Slurm monitoring."""
287+ cronjob_id = ledger.data.get("cronjob", "asimov_monitor.sh")
288+ click.secho(" \t ● Manual cron setup detected or python-crontab not installed.", fg="yellow")
289+ click.echo(f"Run 'crontab -e' and remove the line containing '{cronjob_id}'")
259290
260291
261292@click.argument("event", default=None, required=False)
0 commit comments