From 26f29a399e7d7c44ec3883c4813ba3062e2681f4 Mon Sep 17 00:00:00 2001 From: Dheyay Date: Thu, 3 Oct 2024 13:51:33 -0700 Subject: [PATCH] Add service to detect clones on boot Fixes: #3068 --- debian/rules | 1 + features/cli/collect_logs.feature | 2 ++ lib/timer.py | 22 ++++++++++++++++++--- systemd/ua-activity-ping-on-boot.service | 16 +++++++++++++++ uaclient/actions.py | 1 + uaclient/cli/tests/test_cli_collect_logs.py | 6 ++++++ 6 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 systemd/ua-activity-ping-on-boot.service diff --git a/debian/rules b/debian/rules index abec2feed0..b172d1680e 100755 --- a/debian/rules +++ b/debian/rules @@ -58,6 +58,7 @@ override_dh_systemd_enable: dh_systemd_enable -pubuntu-pro-client ua-reboot-cmds.service dh_systemd_enable -pubuntu-pro-client ua-timer.timer dh_systemd_enable -pubuntu-pro-client ua-timer.service + dh_systemd_enable -pubuntu-pro-client ua-activity-ping-on-boot.service dh_systemd_enable -pubuntu-pro-client ubuntu-advantage.service ifeq (${VERSION_ID},"16.04") # Only enable cloud-id-shim on Xenial diff --git a/features/cli/collect_logs.feature b/features/cli/collect_logs.feature index 58141a631c..3a95cfeb6a 100644 --- a/features/cli/collect_logs.feature +++ b/features/cli/collect_logs.feature @@ -27,6 +27,7 @@ Feature: CLI collect-logs command pro-journal.txt pro-status.json systemd-timers.txt + ua-activity-ping-on-boot.service.txt ua-auto-attach.path.txt(-error)? ua-auto-attach.service.txt(-error)? uaclient.conf @@ -76,6 +77,7 @@ Feature: CLI collect-logs command pro-journal.txt pro-status.json systemd-timers.txt + ua-activity-ping-on-boot.service.txt ua-auto-attach.path.txt(-error)? ua-auto-attach.service.txt(-error)? uaclient.conf diff --git a/lib/timer.py b/lib/timer.py index 9b7ff18695..e1fece10d8 100644 --- a/lib/timer.py +++ b/lib/timer.py @@ -2,6 +2,7 @@ Timer used to run all jobs that need to be frequently run on the system """ +import argparse import logging from datetime import datetime, timedelta, timezone from typing import Callable, Optional @@ -27,6 +28,17 @@ CHECK_RELEASE_SERIES_INTERVAL = 86400 # 24 hours +def parse_arguments(): + """Parse command line arguments for the timer file""" + parser = argparse.ArgumentParser(description="Run timer jobs") + parser.add_argument( + "--run-on-boot", + action="store_true", + help="Run the metering job on boot, bypassing the normal schedule to ping the server", # noqa + ) + return parser.parse_args() + + class TimedJob: def __init__( self, @@ -124,10 +136,11 @@ def run_job( job: TimedJob, current_time: datetime, job_status: Optional[TimerJobState], + ignore_interval: bool = False, ) -> Optional[TimerJobState]: if job_status: next_run = job_status.next_run - if next_run and next_run > current_time: + if next_run and next_run > current_time and not ignore_interval: return job_status if job.run(cfg): # Persist last_run and next_run UTC-based times on job success. @@ -136,7 +149,6 @@ def run_job( seconds=job.run_interval_seconds(cfg) ) job_status = TimerJobState(next_run=next_run, last_run=last_run) - return job_status @@ -180,10 +192,14 @@ def run_jobs(cfg: UAConfig, current_time: datetime): if __name__ == "__main__": log.setup_journald_logging() + args = parse_arguments() cfg = UAConfig() current_time = datetime.now(timezone.utc) http.configure_web_proxy(cfg.http_proxy, cfg.https_proxy) - run_jobs(cfg=cfg, current_time=current_time) + if args.run_on_boot: + run_job(cfg, metering_job, current_time, None, ignore_interval=True) + else: + run_jobs(cfg=cfg, current_time=current_time) diff --git a/systemd/ua-activity-ping-on-boot.service b/systemd/ua-activity-ping-on-boot.service new file mode 100644 index 0000000000..ec84547ab4 --- /dev/null +++ b/systemd/ua-activity-ping-on-boot.service @@ -0,0 +1,16 @@ +# On clones of machines that are currently attached, an activity ping +# is required on boot to detect the clones +# This requires using the ua-timer to update the activity id immediately + +[Unit] +Description=Ubuntu Pro clone detection activity ping on boot +After=network.target network-online.target systemd-networkd.service ua-auto-attach.service +Wants=network-online.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/python3 /usr/lib/ubuntu-advantage/timer.py --run-on-boot +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target diff --git a/uaclient/actions.py b/uaclient/actions.py index e6b18f2878..fd2a86203b 100644 --- a/uaclient/actions.py +++ b/uaclient/actions.py @@ -43,6 +43,7 @@ UA_SERVICES = ( "apt-news.service", "esm-cache.service", + "ua-activity-ping-on-boot.service", "ua-timer.service", "ua-timer.timer", "ua-auto-attach.path", diff --git a/uaclient/cli/tests/test_cli_collect_logs.py b/uaclient/cli/tests/test_cli_collect_logs.py index 865e11917c..d64320fa1c 100644 --- a/uaclient/cli/tests/test_cli_collect_logs.py +++ b/uaclient/cli/tests/test_cli_collect_logs.py @@ -107,6 +107,8 @@ def test_collect_logs( "-u", "esm-cache.service", "-u", + "ua-activity-ping-on-boot.service", + "-u", "ua-timer.service", "-u", "ua-auto-attach.service", @@ -121,6 +123,10 @@ def test_collect_logs( mock.call( ["systemctl", "status", "esm-cache.service"], rcs=[0, 3] ), + mock.call( + ["systemctl", "status", "ua-activity-ping-on-boot.service"], + rcs=[0, 3], # noqa + ), mock.call(["systemctl", "status", "ua-timer.service"], rcs=[0, 3]), mock.call(["systemctl", "status", "ua-timer.timer"], rcs=[0, 3]), mock.call(