344 r"""
345 Creates and installs systemd service based on YAML config.
346 """
347 yaml_path = CONFIG_DIR / yaml_file
348 yaml_type = detect_yaml_type(yaml_path)
349 if yaml_type == 'server':
350 is_server = True
351 elif yaml_type == 'client':
352 is_server = False
353 else:
354 logging.error(t("unknown_yaml_type").format(yaml_file))
355 return
356
357 service_name = f"bw3_{Path(yaml_file).stem}.service"
358 service_path = SERVICE_DIR / service_name
359
360 if is_server:
361 exec_line = f"/usr/bin/python3 {BW_DIR}/bw_server.py -c {yaml_file}"
362 description = "BOSWatch Server"
363 after = "network-online.target"
364 wants = "Wants=network-online.target"
365 else:
366 exec_line = f"/usr/bin/python3 {BW_DIR}/bw_client.py -c {yaml_file}"
367 description = "BOSWatch Client"
368 after = "network.target"
369 wants = ""
370
371 service_content = f"""[Unit]
372Description={description}
373After={after}
374{wants}
375
376[Service]
377Type=simple
378WorkingDirectory={BW_DIR}
379ExecStart={exec_line}
380Restart=on-abort
381
382[Install]
383WantedBy=multi-user.target
384"""
385
386 logging.info(t("creating_service_file").format(yaml_file, service_name))
387
388 if not dry_run:
389 try:
390 with open(service_path, 'w', encoding='utf-8') as f:
391 f.write(service_content)
392 except IOError as e:
393 logging.error(t("file_write_error").format(service_path, e))
394 return
395 verify_service(service_path)
396
397 execute("systemctl daemon-reload", dry_run=dry_run)
398 execute(f"systemctl enable {service_name}", dry_run=dry_run)
399 execute(f"systemctl start {service_name}", dry_run=dry_run)
400
401 if not dry_run:
402 try:
403 subprocess.run(
404 ["systemctl", "is-active", "--quiet", service_name],
405 check=True,
406 timeout=5
407 )
408 logging.info(t("service_active").format(service_name))
409 except subprocess.CalledProcessError:
410 logging.warning(t("service_inactive").format(service_name))
411 except subprocess.TimeoutExpired:
412 logging.warning(t("status_timeout").format(service_name))
413 else:
414 logging.info(t("dryrun_status_check").format(service_name))
415
416
Definition install_service.py:1