From patchwork Fri Mar 22 22:11:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Gautier X-Patchwork-Id: 13600435 Received: from taslin.fdn.fr (taslin.fdn.fr [80.67.169.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77484627FC for ; Fri, 22 Mar 2024 22:14:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.67.169.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145645; cv=none; b=dXtJztVB7AUTsbAuKFG8WgT/KRo3a1rPVzDD1qT4TGCE6K3fbONGN90mMOlkGAJqbsETggLQac1646llONUPPVv+/gFnpvmDsRzZCtCWyVDGooDHzNRr7RYXQa/b4YNTKy42NfrgbDRI2kuGJZsqH5ukfOt/Lo9VdMzkSKZ1qEY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145645; c=relaxed/simple; bh=dd/cdCy/iEyphH3D8yhFqdQeh1mVkEmKgW9oo9D2Kpw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PCrz23d4D4U1r2gbNLPJwRDQe6jngrrRg3GiMimSkoh72rYCBSrdq6TYsySsSMRQ3hyjgbqZD04bVM/IN6qgm8RrjoEaiDGW6QARaBTrV6R8sQfhu/9/y7BPVB/6iEA9vm/5VabkM0U8YRq8BhTi3HG8PGxQWROHlINhBQH5qzg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name; spf=pass smtp.mailfrom=max.gautier.name; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b=rgOz4WR0; arc=none smtp.client-ip=80.67.169.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b="rgOz4WR0" Received: from localhost (reverse-238.fdn.fr [80.67.176.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by taslin.fdn.fr (Postfix) with ESMTPSA id 5946260377; Fri, 22 Mar 2024 23:13:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=max.gautier.name; s=fdn; t=1711145633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ICpdFnDFUZiXKsyGQBKm+LbC8i8XiowDzYRx58Os4PQ=; b=rgOz4WR0hbClfKtj+3aYO+RfT0nhr4eG/ZmT7tqlVtOxiykAvnpUJPudCqdjLb2WZuZFJ9 WaoJfbBSOcN4z5ZOwkSfKBux2BFzSTgk60eOz4jDcnerc+RsOWjOvp0ffkkZb5zA2rUBkJ GiZ0DgxAC/SvfDumwsrEFtizRQcdfWHBb3K8pIyaFa6k6q6WS4qr7xPWktDwYbx3VMheEf ZL6g8UW7ixba4KTT4EguHLakQa5f16ZCEcY4a8MW9Wqjua91uRMoeuB6ePMvKhKFtvNCiD 6KQlrUonj95Umfm+zUKqM/pVLmoMhWgcpg1YN6gk2yEOZsFln2mV1PKxTmmhYg== From: Max Gautier To: git@vger.kernel.org Cc: Max Gautier , =?utf-8?b?TMOpbmHDr2MgSHVhcmQ=?= , Derrick Stolee , Patrick Steinhardt , Junio C Hamano Subject: [PATCH v2 1/6] maintenance: use systemd timers builtin randomization Date: Fri, 22 Mar 2024 23:11:06 +0100 Message-ID: <20240322221327.12204-2-mg@max.gautier.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240322221327.12204-1-mg@max.gautier.name> References: <20240322221327.12204-1-mg@max.gautier.name> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Commit daa787010c (maintenance: use random minute in systemd scheduler, 2023-08-10) hooked the systemd timers with the get_random_minute() function, which is used to spread the load generated by clients, while keeping one hour between each run (for the hourly run). There is two problems with this approach: 1. The random minute is the same for all timers, which can lead to overlapping execution, and in practice skipped execution for some of the timers. 2. The timers are overwritten on each execution of `git maintenance start`, with a new random minute, which can lead to missing a daily or weekly timer. Consider this (unlikely) sequence of events: - weekly timer schedule is "Mon 0:52:00". - user run `git maintenance start` Monday, at 0:30:00. - the random minute happens to be 22, making the new weekly timer schedule "Mon 0:22:00". - the weekly timer does not fire until the next Monday. Commit c97ec0378b (maintenance: fix systemd schedule overlaps, 2023-08-10) resolve problem 1 by skipping some executions of the timers to avoid overlap, but not problem 2. Revert both commits to instead use two native systemd timers properties: - RandomizedDelaySec: as the name suggest, this adds a random offset to each timer execution. Use 3540 seconds (59 minutes) to spread execution as much as possible. - FixedRandomDelay: this makes the offset from the previous setting deterministic, depending on machine ID, timer name and user identifier. (For more details on these settings, see man 5 systemd.timer) This give us timers which: - don't overlap (schedule depend on timer name) - are spread out by user (schedule depend on machine ID and user ID) - happen at fixed intervals This also restore the ability to use the systemd templating system, and keep the systemd unit strings embedded in the C code simpler, with no need for format strings. Signed-off-by: Max Gautier --- builtin/gc.c | 154 +++++++---------------------------------- t/t7900-maintenance.sh | 15 +--- 2 files changed, 27 insertions(+), 142 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index cb80ced6cb..dac59414f0 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -2308,54 +2308,29 @@ static char *xdg_config_home_systemd(const char *filename) return xdg_config_home_for("systemd/user", filename); } -#define SYSTEMD_UNIT_FORMAT "git-maintenance@%s.%s" - -static int systemd_timer_delete_timer_file(enum schedule_priority priority) +static int systemd_timer_delete_unit_templates(void) { int ret = 0; - const char *frequency = get_frequency(priority); - char *local_timer_name = xstrfmt(SYSTEMD_UNIT_FORMAT, frequency, "timer"); - char *filename = xdg_config_home_systemd(local_timer_name); - + char *filename = xdg_config_home_systemd("git-maintenance@.timer"); if (unlink(filename) && !is_missing_file_error(errno)) ret = error_errno(_("failed to delete '%s'"), filename); + FREE_AND_NULL(filename); - free(filename); - free(local_timer_name); - return ret; -} - -static int systemd_timer_delete_service_template(void) -{ - int ret = 0; - char *local_service_name = xstrfmt(SYSTEMD_UNIT_FORMAT, "", "service"); - char *filename = xdg_config_home_systemd(local_service_name); + filename = xdg_config_home_systemd("git-maintenance@.service"); if (unlink(filename) && !is_missing_file_error(errno)) ret = error_errno(_("failed to delete '%s'"), filename); free(filename); - free(local_service_name); return ret; } -/* - * Write the schedule information into a git-maintenance@.timer - * file using a custom minute. This timer file cannot use the templating - * system, so we generate a specific file for each. - */ -static int systemd_timer_write_timer_file(enum schedule_priority schedule, - int minute) +static int systemd_timer_write_unit_templates(const char *exec_path) { - int res = -1; char *filename; FILE *file; const char *unit; - char *schedule_pattern = NULL; - const char *frequency = get_frequency(schedule); - char *local_timer_name = xstrfmt(SYSTEMD_UNIT_FORMAT, frequency, "timer"); - - filename = xdg_config_home_systemd(local_timer_name); + filename = xdg_config_home_systemd("git-maintenance@.timer"); if (safe_create_leading_directories(filename)) { error(_("failed to create directories for '%s'"), filename); goto error; @@ -2364,23 +2339,6 @@ static int systemd_timer_write_timer_file(enum schedule_priority schedule, if (!file) goto error; - switch (schedule) { - case SCHEDULE_HOURLY: - schedule_pattern = xstrfmt("*-*-* 1..23:%02d:00", minute); - break; - - case SCHEDULE_DAILY: - schedule_pattern = xstrfmt("Tue..Sun *-*-* 0:%02d:00", minute); - break; - - case SCHEDULE_WEEKLY: - schedule_pattern = xstrfmt("Mon 0:%02d:00", minute); - break; - - default: - BUG("Unhandled schedule_priority"); - } - unit = "# This file was created and is maintained by Git.\n" "# Any edits made in this file might be replaced in the future\n" "# by a Git command.\n" @@ -2389,12 +2347,14 @@ static int systemd_timer_write_timer_file(enum schedule_priority schedule, "Description=Optimize Git repositories data\n" "\n" "[Timer]\n" - "OnCalendar=%s\n" + "OnCalendar=%i\n" "Persistent=true\n" + "RandomizedDelaySecond=3540\n" + "FixedRandomDelay=true\n" "\n" "[Install]\n" "WantedBy=timers.target\n"; - if (fprintf(file, unit, schedule_pattern) < 0) { + if (fputs(unit, file) == EOF) { error(_("failed to write to '%s'"), filename); fclose(file); goto error; @@ -2403,36 +2363,9 @@ static int systemd_timer_write_timer_file(enum schedule_priority schedule, error_errno(_("failed to flush '%s'"), filename); goto error; } - - res = 0; - -error: - free(schedule_pattern); - free(local_timer_name); free(filename); - return res; -} -/* - * No matter the schedule, we use the same service and can make use of the - * templating system. When installing git-maintenance@.timer, - * systemd will notice that git-maintenance@.service exists as a template - * and will use this file and insert the into the template at - * the position of "%i". - */ -static int systemd_timer_write_service_template(const char *exec_path) -{ - int res = -1; - char *filename; - FILE *file; - const char *unit; - char *local_service_name = xstrfmt(SYSTEMD_UNIT_FORMAT, "", "service"); - - filename = xdg_config_home_systemd(local_service_name); - if (safe_create_leading_directories(filename)) { - error(_("failed to create directories for '%s'"), filename); - goto error; - } + filename = xdg_config_home_systemd("git-maintenance@.service"); file = fopen_or_warn(filename, "w"); if (!file) goto error; @@ -2465,18 +2398,17 @@ static int systemd_timer_write_service_template(const char *exec_path) error_errno(_("failed to flush '%s'"), filename); goto error; } - - res = 0; + free(filename); + return 0; error: - free(local_service_name); free(filename); - return res; + systemd_timer_delete_unit_templates(); + return -1; } static int systemd_timer_enable_unit(int enable, - enum schedule_priority schedule, - int minute) + enum schedule_priority schedule) { const char *cmd = "systemctl"; struct child_process child = CHILD_PROCESS_INIT; @@ -2493,14 +2425,12 @@ static int systemd_timer_enable_unit(int enable, */ if (!enable) child.no_stderr = 1; - else if (systemd_timer_write_timer_file(schedule, minute)) - return -1; get_schedule_cmd(&cmd, NULL); strvec_split(&child.args, cmd); strvec_pushl(&child.args, "--user", enable ? "enable" : "disable", "--now", NULL); - strvec_pushf(&child.args, SYSTEMD_UNIT_FORMAT, frequency, "timer"); + strvec_pushf(&child.args, "git-maintenance@%s.timer", frequency); if (start_command(&child)) return error(_("failed to start systemctl")); @@ -2517,58 +2447,24 @@ static int systemd_timer_enable_unit(int enable, return 0; } -/* - * A previous version of Git wrote the timer units as template files. - * Clean these up, if they exist. - */ -static void systemd_timer_delete_stale_timer_templates(void) -{ - char *timer_template_name = xstrfmt(SYSTEMD_UNIT_FORMAT, "", "timer"); - char *filename = xdg_config_home_systemd(timer_template_name); - - if (unlink(filename) && !is_missing_file_error(errno)) - warning(_("failed to delete '%s'"), filename); - - free(filename); - free(timer_template_name); -} - -static int systemd_timer_delete_unit_files(void) -{ - systemd_timer_delete_stale_timer_templates(); - - /* Purposefully not short-circuited to make sure all are called. */ - return systemd_timer_delete_timer_file(SCHEDULE_HOURLY) | - systemd_timer_delete_timer_file(SCHEDULE_DAILY) | - systemd_timer_delete_timer_file(SCHEDULE_WEEKLY) | - systemd_timer_delete_service_template(); -} - static int systemd_timer_delete_units(void) { - int minute = get_random_minute(); - /* Purposefully not short-circuited to make sure all are called. */ - return systemd_timer_enable_unit(0, SCHEDULE_HOURLY, minute) | - systemd_timer_enable_unit(0, SCHEDULE_DAILY, minute) | - systemd_timer_enable_unit(0, SCHEDULE_WEEKLY, minute) | - systemd_timer_delete_unit_files(); + return systemd_timer_enable_unit(0, SCHEDULE_HOURLY) || + systemd_timer_enable_unit(0, SCHEDULE_DAILY) || + systemd_timer_enable_unit(0, SCHEDULE_WEEKLY) || + systemd_timer_delete_unit_templates(); } static int systemd_timer_setup_units(void) { - int minute = get_random_minute(); const char *exec_path = git_exec_path(); - int ret = systemd_timer_write_service_template(exec_path) || - systemd_timer_enable_unit(1, SCHEDULE_HOURLY, minute) || - systemd_timer_enable_unit(1, SCHEDULE_DAILY, minute) || - systemd_timer_enable_unit(1, SCHEDULE_WEEKLY, minute); - + int ret = systemd_timer_write_unit_templates(exec_path) || + systemd_timer_enable_unit(1, SCHEDULE_HOURLY) || + systemd_timer_enable_unit(1, SCHEDULE_DAILY) || + systemd_timer_enable_unit(1, SCHEDULE_WEEKLY); if (ret) systemd_timer_delete_units(); - else - systemd_timer_delete_stale_timer_templates(); - return ret; } diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 0943dfa18a..37aa408d26 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -790,15 +790,7 @@ test_expect_success 'start and stop Linux/systemd maintenance' ' # start registers the repo git config --get --global --fixed-value maintenance.repo "$(pwd)" && - for schedule in hourly daily weekly - do - test_path_is_file "systemd/user/git-maintenance@$schedule.timer" || return 1 - done && - test_path_is_file "systemd/user/git-maintenance@.service" && - - test_systemd_analyze_verify "systemd/user/git-maintenance@hourly.service" && - test_systemd_analyze_verify "systemd/user/git-maintenance@daily.service" && - test_systemd_analyze_verify "systemd/user/git-maintenance@weekly.service" && + test_systemd_analyze_verify "systemd/user/git-maintenance@.service" && printf -- "--user enable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && test_cmp expect args && @@ -809,10 +801,7 @@ test_expect_success 'start and stop Linux/systemd maintenance' ' # stop does not unregister the repo git config --get --global --fixed-value maintenance.repo "$(pwd)" && - for schedule in hourly daily weekly - do - test_path_is_missing "systemd/user/git-maintenance@$schedule.timer" || return 1 - done && + test_path_is_missing "systemd/user/git-maintenance@.timer" && test_path_is_missing "systemd/user/git-maintenance@.service" && printf -- "--user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && From patchwork Fri Mar 22 22:11:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Gautier X-Patchwork-Id: 13600433 Received: from taslin.fdn.fr (taslin.fdn.fr [80.67.169.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7743F43AB5 for ; Fri, 22 Mar 2024 22:14:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.67.169.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145644; cv=none; b=lH2BaIEwnXLz1xjRIaq16OdfCybQZSq5YjytGkkNnAQRHFwlJcz5njp5tMuyYcEnHU3AIxokpMVw+dLrHmFLDRV+1MZNaslqRhwQpkooJ+nccqY4HgT36WNeV1e8yhyiXFmsDuviw3xBz5dj1tQFkHmCwrj6f2wR19PpLxvklx4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145644; c=relaxed/simple; bh=KBnJjcNeQ8HdBzKlNznQaZxCYjl2eESCO6RL1y5LSnY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fc/7E3rH1FSw1ggeRdGzuj4YwdKsQF29Yq27k/KpuV9jimZWTedVCRzQ3e8UvZuCneCAD/k9Fqt2pYO0PWUxJnL672tI2+KTIMC6GE/iKkCXikhCia4PNuVT45jxhOneTbS4AM5eqEjgI5eFbnVxDW7X+L6qWAMkjVy6H4sVUe8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name; spf=pass smtp.mailfrom=max.gautier.name; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b=z446zH/M; arc=none smtp.client-ip=80.67.169.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b="z446zH/M" Received: from localhost (reverse-238.fdn.fr [80.67.176.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by taslin.fdn.fr (Postfix) with ESMTPSA id B8DC460378; Fri, 22 Mar 2024 23:13:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=max.gautier.name; s=fdn; t=1711145633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=coSFnLM/k7UrOljaS9qVSC5W2bhn+aE42EoWJNx/dhI=; b=z446zH/M7rt4EDtfmRaGvUjJmXEtMRdaISP4HR/2N9KMu4qJPCkHfdj3X5httkfBS5nqV4 rpnuiB2Deu7f86l3ARDOeKGm7Keo62NtEYjkkdvB3yDZnkeZK0eXdhgyW5ugpUe/hWyV63 A5cQyRNLoGJfUJLA57V4wtMxAzcQvFlXkU/yKhk224WjzjbY1kmqMDc9PuSidM8qgSV+9m J0Fl5dwl3suduGCzzGyCVGF4zuErAzdO4vkPjg9hm6vsQ9fcymoVe8TrCV4ZGO6fbXJyQu 4gLMJc6NjWkgKX0vsjbe8b/Rpl8g8ZLgpseKSlcZ973sG1O4Wza1AdMw5aYCyQ== From: Max Gautier To: git@vger.kernel.org Cc: Max Gautier , =?utf-8?b?TMOpbmHDr2MgSHVhcmQ=?= , Derrick Stolee , Patrick Steinhardt , Johannes Schindelin , Junio C Hamano Subject: [PATCH v2 2/6] maintenance: use packaged systemd units Date: Fri, 22 Mar 2024 23:11:07 +0100 Message-ID: <20240322221327.12204-3-mg@max.gautier.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240322221327.12204-1-mg@max.gautier.name> References: <20240322221327.12204-1-mg@max.gautier.name> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently, `git maintenance start`, if it uses the systemd scheduler, will create systemd user units in $XDG_CONFIG_HOME, and overwrite the files on each invocation. Conversely, `git maintenance stop` will remove the unit files. This is problematic mostly because it steps on user toes (and their configuration, also). You can't mask the git maintenance systemd units, because they are in $XDG_CONFIG_HOME and you can only mask "vendor" units (see man systemctl), you can't override them either. Additionally, it necessitates creating, modifying and removing files from builtin/gc.c, which adds code and some avoidable complexity. Package the systemd user units (timer and service) with git in $(prefix)/lib/systemd/user (or $XDG_DATA_HOME for $HOME installation), and remove code for writing and deleting the units from builtin/gc.c. Determine the correct git path at install time by for the service unit. Detect systemd timers support (at install time) by relying on systemctl presence, since we use it as the control interface for the systemd scheduler. Signed-off-by: Max Gautier --- Notes: I'm not completely sure if it's ok to do install time templating like this, but I couldn't find a similar enough example in the Makefile. Any suggestion for a better way ? Makefile | 5 + builtin/gc.c | 117 +---------------------- config.mak.uname | 10 ++ systemd/user/git-maintenance@.service.in | 17 ++++ systemd/user/git-maintenance@.timer | 12 +++ 5 files changed, 49 insertions(+), 112 deletions(-) create mode 100644 systemd/user/git-maintenance@.service.in create mode 100644 systemd/user/git-maintenance@.timer diff --git a/Makefile b/Makefile index 4e255c81f2..4fb015478e 100644 --- a/Makefile +++ b/Makefile @@ -3469,6 +3469,11 @@ install: all $(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' $(INSTALL) $(INSTALL_STRIP) $(install_bindir_xprograms) '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(BINDIR_PROGRAMS_NO_X) '$(DESTDIR_SQ)$(bindir_SQ)' +ifdef SYSTEMD_USER_UNIT_DIR + $(INSTALL) -Dm 644 -t '$(DESTDIR_SQ)$(SYSTEMD_USER_UNIT_DIR)' systemd/user/git-maintenance@.timer + sed 's+@BINDIR@+$(bindir_SQ)+' systemd/user/git-maintenance@.service.in | \ + $(INSTALL) -Dm 644 /dev/stdin '$(DESTDIR_SQ)$(SYSTEMD_USER_UNIT_DIR)/git-maintenance@.service' +endif ifdef MSVC # We DO NOT install the individual foo.o.pdb files because they diff --git a/builtin/gc.c b/builtin/gc.c index dac59414f0..199c8e6240 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -2303,110 +2303,6 @@ static int is_systemd_timer_available(void) return real_is_systemd_timer_available(); } -static char *xdg_config_home_systemd(const char *filename) -{ - return xdg_config_home_for("systemd/user", filename); -} - -static int systemd_timer_delete_unit_templates(void) -{ - int ret = 0; - char *filename = xdg_config_home_systemd("git-maintenance@.timer"); - if (unlink(filename) && !is_missing_file_error(errno)) - ret = error_errno(_("failed to delete '%s'"), filename); - FREE_AND_NULL(filename); - - filename = xdg_config_home_systemd("git-maintenance@.service"); - if (unlink(filename) && !is_missing_file_error(errno)) - ret = error_errno(_("failed to delete '%s'"), filename); - - free(filename); - return ret; -} - -static int systemd_timer_write_unit_templates(const char *exec_path) -{ - char *filename; - FILE *file; - const char *unit; - - filename = xdg_config_home_systemd("git-maintenance@.timer"); - if (safe_create_leading_directories(filename)) { - error(_("failed to create directories for '%s'"), filename); - goto error; - } - file = fopen_or_warn(filename, "w"); - if (!file) - goto error; - - unit = "# This file was created and is maintained by Git.\n" - "# Any edits made in this file might be replaced in the future\n" - "# by a Git command.\n" - "\n" - "[Unit]\n" - "Description=Optimize Git repositories data\n" - "\n" - "[Timer]\n" - "OnCalendar=%i\n" - "Persistent=true\n" - "RandomizedDelaySecond=3540\n" - "FixedRandomDelay=true\n" - "\n" - "[Install]\n" - "WantedBy=timers.target\n"; - if (fputs(unit, file) == EOF) { - error(_("failed to write to '%s'"), filename); - fclose(file); - goto error; - } - if (fclose(file) == EOF) { - error_errno(_("failed to flush '%s'"), filename); - goto error; - } - free(filename); - - filename = xdg_config_home_systemd("git-maintenance@.service"); - file = fopen_or_warn(filename, "w"); - if (!file) - goto error; - - unit = "# This file was created and is maintained by Git.\n" - "# Any edits made in this file might be replaced in the future\n" - "# by a Git command.\n" - "\n" - "[Unit]\n" - "Description=Optimize Git repositories data\n" - "\n" - "[Service]\n" - "Type=oneshot\n" - "ExecStart=\"%s/git\" --exec-path=\"%s\" for-each-repo --config=maintenance.repo maintenance run --schedule=%%i\n" - "LockPersonality=yes\n" - "MemoryDenyWriteExecute=yes\n" - "NoNewPrivileges=yes\n" - "RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_VSOCK\n" - "RestrictNamespaces=yes\n" - "RestrictRealtime=yes\n" - "RestrictSUIDSGID=yes\n" - "SystemCallArchitectures=native\n" - "SystemCallFilter=@system-service\n"; - if (fprintf(file, unit, exec_path, exec_path) < 0) { - error(_("failed to write to '%s'"), filename); - fclose(file); - goto error; - } - if (fclose(file) == EOF) { - error_errno(_("failed to flush '%s'"), filename); - goto error; - } - free(filename); - return 0; - -error: - free(filename); - systemd_timer_delete_unit_templates(); - return -1; -} - static int systemd_timer_enable_unit(int enable, enum schedule_priority schedule) { @@ -2447,24 +2343,21 @@ static int systemd_timer_enable_unit(int enable, return 0; } -static int systemd_timer_delete_units(void) +static int systemd_timer_disable_units(void) { return systemd_timer_enable_unit(0, SCHEDULE_HOURLY) || systemd_timer_enable_unit(0, SCHEDULE_DAILY) || - systemd_timer_enable_unit(0, SCHEDULE_WEEKLY) || - systemd_timer_delete_unit_templates(); + systemd_timer_enable_unit(0, SCHEDULE_WEEKLY); } static int systemd_timer_setup_units(void) { - const char *exec_path = git_exec_path(); - int ret = systemd_timer_write_unit_templates(exec_path) || - systemd_timer_enable_unit(1, SCHEDULE_HOURLY) || + int ret = systemd_timer_enable_unit(1, SCHEDULE_HOURLY) || systemd_timer_enable_unit(1, SCHEDULE_DAILY) || systemd_timer_enable_unit(1, SCHEDULE_WEEKLY); if (ret) - systemd_timer_delete_units(); + systemd_timer_disable_units(); return ret; } @@ -2473,7 +2366,7 @@ static int systemd_timer_update_schedule(int run_maintenance, int fd UNUSED) if (run_maintenance) return systemd_timer_setup_units(); else - return systemd_timer_delete_units(); + return systemd_timer_disable_units(); } enum scheduler { diff --git a/config.mak.uname b/config.mak.uname index d0dcca2ec5..35ca236874 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -68,6 +68,16 @@ ifeq ($(uname_S),Linux) ifneq ($(findstring .el7.,$(uname_R)),) BASIC_CFLAGS += -std=c99 endif + ifeq ($(shell command -v systemctl >/dev/null ?&& echo y),y) + XDG_DATA_HOME ?= $(HOME)/.local/share + # systemd user units of programm installed in the home directory + # (meaning prefix == $HOME) shall go in XDG_DATA_HOME + # (from man 5 systemd.unit) + SYSTEMD_USER_UNIT_DIR = $(strip $(if $(and \ + $(findstring $(prefix),$(HOME)),\ + $(findstring $(HOME),$(prefix))),\ + $(XDG_DATA_HOME),$(prefix)/$(lib)))/systemd/user + endif endif ifeq ($(uname_S),GNU/kFreeBSD) HAVE_ALLOCA_H = YesPlease diff --git a/systemd/user/git-maintenance@.service.in b/systemd/user/git-maintenance@.service.in new file mode 100644 index 0000000000..649ba87e7e --- /dev/null +++ b/systemd/user/git-maintenance@.service.in @@ -0,0 +1,17 @@ +[Unit] +Description=Optimize Git repositories data +Documentation=man:git-maintenance(1) + +[Service] +Type=oneshot +ExecStart=@BINDIR@/git for-each-repo --config=maintenance.repo \ + maintenance run --schedule=%i +LockPersonality=yes +MemoryDenyWriteExecute=yes +NoNewPrivileges=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_VSOCK +RestrictNamespaces=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service diff --git a/systemd/user/git-maintenance@.timer b/systemd/user/git-maintenance@.timer new file mode 100644 index 0000000000..2834bac365 --- /dev/null +++ b/systemd/user/git-maintenance@.timer @@ -0,0 +1,12 @@ +[Unit] +Description=Optimize Git repositories data +Documentation=man:git-maintenance(1) + +[Timer] +OnCalendar=%i +Persistent=true +RandomizedDelaySec=3540 +FixedRandomDelay=true + +[Install] +WantedBy=timers.target From patchwork Fri Mar 22 22:11:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Gautier X-Patchwork-Id: 13600434 Received: from taslin.fdn.fr (taslin.fdn.fr [80.67.169.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 774BC80C03 for ; Fri, 22 Mar 2024 22:14:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.67.169.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145645; cv=none; b=O6oivLpEjxI+zjN9qT762aOYlmtp/wYr2flHBrFcZEOpZM9HjO5kYUYYZY0BWAANmOEhsB31MhJ7b7Na85gOkg1DVsjvVIvlZgmp+BIyPJQja7TBctXKxvq4T4SHArhcC8N4LhAf/S7qr2Ztnc70SbQ1Wke4vh15UXuq9GgNyXg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145645; c=relaxed/simple; bh=mUP/g8fzBtTUk2XWm2E3wzy38DpT3pDvY8yNAtZiclA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lkt2u9CokAGax/rRkVSyF0w3B2cal6RiaNHuUAMsnOk0mYU9N9N760ZbEEQRViOMoLHXc+/qx8D/g8cEwszTRunjRt6JddlIkBnbbxwa2WAnW2Ouy1ZtlfJuZ9v6VOov0VnQXp0bmtLrjHrb+QppNatmi90fRnbWPO3LtfTCZfk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name; spf=pass smtp.mailfrom=max.gautier.name; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b=Qb9wdEDJ; arc=none smtp.client-ip=80.67.169.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b="Qb9wdEDJ" Received: from localhost (reverse-238.fdn.fr [80.67.176.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by taslin.fdn.fr (Postfix) with ESMTPSA id 1F6E560379; Fri, 22 Mar 2024 23:13:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=max.gautier.name; s=fdn; t=1711145634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gPiJPiGolYaJh6ma4zzZgwHwJBI2dPrwAFYxApcigjg=; b=Qb9wdEDJX8ltLDhWeDQZd1W8GfF5YPNaZnem3NRovrt5C9rAWSKRhmONOqRLULdi0GjIdF 4sBMGmwRvjULUqBeMjIwVt40RrQv9PtLwJkcGEW2whzLeG+pJs/91B/xYsnIS4tNTDLGGM ZlCP8pE7MxuKrugegLjVQmndxvnkxCJSXjJxy/YcEWcOwlOTNIyOvZcXNxFhzECihv81mz 9LvhiDlgP8tJFp5QrBSX0+DW0qeklIkM6XkaCp8UytFpEf4QF94HhtisPVC4sweKT7m1oi f3DMgH2puPtLruhIO7dDfOD5qnCcO5BgZWjz3uufghr6DfzO6cBJx2uALGi2hQ== From: Max Gautier To: git@vger.kernel.org Cc: Max Gautier , =?utf-8?b?TMOpbmHDr2MgSHVhcmQ=?= , Derrick Stolee , Patrick Steinhardt , Junio C Hamano , Eric Sunshine , Jeff King Subject: [PATCH v2 3/6] maintenance: simplify systemctl calls Date: Fri, 22 Mar 2024 23:11:08 +0100 Message-ID: <20240322221327.12204-4-mg@max.gautier.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240322221327.12204-1-mg@max.gautier.name> References: <20240322221327.12204-1-mg@max.gautier.name> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The systemctl invocation to enable or disable the git maintenance timers is needlessly complicated: - systemctl does not mind at all enabling already enabled units, nor disabling already disabled units. - it can act on several units at once instead of only one. Use only one systemctl invocation per `git maintenance start/stop`. Transparently pass its status and output. Add the --force option to override conflicting symlinks to previous instances of our units files which lived in $XDG_CONFIG_HOME. Signed-off-by: Max Gautier --- builtin/gc.c | 63 ++++++++++++---------------------------------------- 1 file changed, 14 insertions(+), 49 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index 199c8e6240..aaee91451a 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -2303,70 +2303,35 @@ static int is_systemd_timer_available(void) return real_is_systemd_timer_available(); } -static int systemd_timer_enable_unit(int enable, - enum schedule_priority schedule) +static int systemd_set_units_state(int enable) { const char *cmd = "systemctl"; struct child_process child = CHILD_PROCESS_INIT; - const char *frequency = get_frequency(schedule); - - /* - * Disabling the systemd unit while it is already disabled makes - * systemctl print an error. - * Let's ignore it since it means we already are in the expected state: - * the unit is disabled. - * - * On the other hand, enabling a systemd unit which is already enabled - * produces no error. - */ - if (!enable) - child.no_stderr = 1; get_schedule_cmd(&cmd, NULL); strvec_split(&child.args, cmd); - strvec_pushl(&child.args, "--user", enable ? "enable" : "disable", - "--now", NULL); - strvec_pushf(&child.args, "git-maintenance@%s.timer", frequency); + + strvec_pushl(&child.args, "--user", "--force", "--now", + enable ? "enable" : "disable", + "git-maintenance@hourly.timer", + "git-maintenance@daily.timer", + "git-maintenance@weekly.timer", NULL); + /* + * --force override existing conflicting symlinks + * We need it because the units have changed location (~/.config -> + * /usr/lib) + */ if (start_command(&child)) return error(_("failed to start systemctl")); if (finish_command(&child)) - /* - * Disabling an already disabled systemd unit makes - * systemctl fail. - * Let's ignore this failure. - * - * Enabling an enabled systemd unit doesn't fail. - */ - if (enable) - return error(_("failed to run systemctl")); + return error(_("failed to run systemctl")); return 0; } -static int systemd_timer_disable_units(void) -{ - return systemd_timer_enable_unit(0, SCHEDULE_HOURLY) || - systemd_timer_enable_unit(0, SCHEDULE_DAILY) || - systemd_timer_enable_unit(0, SCHEDULE_WEEKLY); -} - -static int systemd_timer_setup_units(void) -{ - - int ret = systemd_timer_enable_unit(1, SCHEDULE_HOURLY) || - systemd_timer_enable_unit(1, SCHEDULE_DAILY) || - systemd_timer_enable_unit(1, SCHEDULE_WEEKLY); - if (ret) - systemd_timer_disable_units(); - return ret; -} - static int systemd_timer_update_schedule(int run_maintenance, int fd UNUSED) { - if (run_maintenance) - return systemd_timer_setup_units(); - else - return systemd_timer_disable_units(); + return systemd_set_units_state(run_maintenance); } enum scheduler { From patchwork Fri Mar 22 22:11:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Gautier X-Patchwork-Id: 13600431 Received: from taslin.fdn.fr (taslin.fdn.fr [80.67.169.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 774F481207 for ; Fri, 22 Mar 2024 22:14:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.67.169.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145644; cv=none; b=FRQClsfT3KZ8rMiI1nsmeZhUZDv0Mnutx5FJGUr4dohOAnlbrKfqJIos5NTbsJ4MfKa/MjGgg0YKrHJCp2WAfh88DAn9fcL/wvoZWjCMI4djq7MY7c9s+sX3VGI6Kr6vNQufrrmmDN5srAmKtft3SWt+E3yLq2n73EfHrCYUvJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145644; c=relaxed/simple; bh=GPddT3vuYv8b96rYYXfMppXzyC8w0K5sxVMWjjcT5IU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NUfUzEUqYXs2DKcdMq/NPl9WDRiH05PkkNekHTfzGWvwyZ//UB/hIzZTgoppKzsqDjTz7ASFVbNmoZE1XLwMrFFtkeEASMroqp28kJc2Np2J/E5avT7H5YEEkrMVrYFWXhUzpGkqnntg9zWquo+QaahBbRghVqKAP7M2R7XzA64= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name; spf=pass smtp.mailfrom=max.gautier.name; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b=lxmQxCQO; arc=none smtp.client-ip=80.67.169.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b="lxmQxCQO" Received: from localhost (reverse-238.fdn.fr [80.67.176.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by taslin.fdn.fr (Postfix) with ESMTPSA id 75A3C6037A; Fri, 22 Mar 2024 23:13:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=max.gautier.name; s=fdn; t=1711145634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3JvtaAHuIsinpNSxPVRMAdnASiq8hhGWGMnbjt/Z9j4=; b=lxmQxCQO2OgJgRu+uqxNII50lbCMOLTIvxE2spibxtK7NZfI2rz+HDALioaPqfSxbB1WWs QsSYs/F4YYCjYJ5YLhnUXlLc4z6SadTMN56CHXcI3B5janEuqYZH7sovaR3cGJwbpxAT5P euTSxEZcOMQREfJFYHnNqR8/MZkQCx8owFD1gHfAAG9MTBEkwFBkrie5SDlA5PUZvKAKEV ESK45VRDELVglqytT3AkR9pSeZ3U8h7QLG72vrd7LA6P26ipehQRcOqODU9yMN21oKyVxT ki0jh5QrB/K23Ggtn2US49bX2RlQw3TWcZksQ8MTmvwu7nFAWQ2PEHgnisFAxg== From: Max Gautier To: git@vger.kernel.org Cc: Max Gautier , =?utf-8?b?TMOpbmHDr2MgSHVhcmQ=?= , Derrick Stolee , Patrick Steinhardt , Jeff King , Junio C Hamano Subject: [PATCH v2 4/6] maintenance: cleanup $XDG_CONFIG_HOME/systemd/user Date: Fri, 22 Mar 2024 23:11:09 +0100 Message-ID: <20240322221327.12204-5-mg@max.gautier.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240322221327.12204-1-mg@max.gautier.name> References: <20240322221327.12204-1-mg@max.gautier.name> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Before commit 976640edbb (maintenance: use packaged systemd units, 2024-03-21), we we're putting systemd unit files in $XDG_CONFIG_HOME ; these could mask those we are now distributing as part of git. Remove all the systemd units possibly created by previous version of git when running `git maintenance start/stop`. Avoid overwriting units we didn't write, by comparing the first line with the start of the comment we added to our unit files previously. Signed-off-by: Max Gautier --- Notes: How should I refer to a commit which is part of the same patch series ? The commit id will change so the message won't be correct anymore, right ? builtin/gc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/builtin/gc.c b/builtin/gc.c index aaee91451a..99b158e481 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -2329,8 +2329,50 @@ static int systemd_set_units_state(int enable) return 0; } +/* + * TODO: in the future (~2026 ?) remove this cleanup code + */ +static void systemd_delete_user_unit(char const *unit) +{ + char const file_start_stale[] = "# This file was created and is" + " maintained by Git."; + char file_start_user[sizeof(file_start_stale)] = {'\0'}; + + char *filename = xdg_config_home_for("systemd/user", unit); + int handle = open(filename, O_RDONLY); + + /* + * Check this is actually our file and we're not removing a legitimate + * user override. + */ + if (handle == -1 && !is_missing_file_error(errno)) + warning(_("failed to delete '%s'"), filename); + else { + read(handle, file_start_user, sizeof(file_start_stale) - 1); + close(handle); + if (strcmp(file_start_stale, file_start_user) == 0) { + if (unlink(filename) == 0) + warning(_("deleted stale unit file '%s'"), filename); + else if (!is_missing_file_error(errno)) + warning(_("failed to delete '%s'"), filename); + } + } + + free(filename); +} + static int systemd_timer_update_schedule(int run_maintenance, int fd UNUSED) { + /* + * A previous version of Git wrote the units in the user configuration + * directory. Clean these up, if they exist. + * TODO: in the future (~2026 ?) remove this cleanup code + */ + systemd_delete_user_unit("git-maintenance@hourly.timer"); + systemd_delete_user_unit("git-maintenance@daily.timer"); + systemd_delete_user_unit("git-maintenance@weekly.timer"); + systemd_delete_user_unit("git-maintenance@.timer"); + systemd_delete_user_unit("git-maintenance@.service"); return systemd_set_units_state(run_maintenance); } From patchwork Fri Mar 22 22:11:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Gautier X-Patchwork-Id: 13600436 Received: from taslin.fdn.fr (taslin.fdn.fr [80.67.169.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFE07823A2 for ; Fri, 22 Mar 2024 22:14:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.67.169.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145647; cv=none; b=dRgLv9WDuGHSi2OqnfWfogOVftl7lkOOXXPMkRwbVjfnTBTs/6idFPhFztH+WdYy7SP9gSQ6+WoXV6Oy9zGmAEv3G087lH89fQ7v3Q2E8HlwRKWH4Uzu534L2Hold81AYOKANgcG0qRXQBFVRMIWixS0/I7//avntbEiM/sw6e0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145647; c=relaxed/simple; bh=TdF/9CKV905jeZejVMA0JaQa2xwurmqwh6eRFgDyuAA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y8AG/Z8v2GI6B9bK8j9/7fz1RUAX2upBjFouB+IfpcXsBLqFsUlkuiUugy62X/v0BSww8g8WYPlThjOwJ/hanGe6Ef7avT8McYzujFbXNFUX3kYacPyEuz0B8EFKZUxRwiOO0RCAz3fGBBkEmxly3F0a/X8meRhk7K/QIKG8xpU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name; spf=pass smtp.mailfrom=max.gautier.name; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b=na/r2H1W; arc=none smtp.client-ip=80.67.169.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b="na/r2H1W" Received: from localhost (reverse-238.fdn.fr [80.67.176.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by taslin.fdn.fr (Postfix) with ESMTPSA id CD3E66037C; Fri, 22 Mar 2024 23:13:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=max.gautier.name; s=fdn; t=1711145634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9E9Vqsc7YN7dc53i7cQRKPf/0DHrozMmdUpC296HWxM=; b=na/r2H1WoUwGwzhJbu/UHMhq9UT896ggyr7joJhmEw+nFD1y9UQZUYLR2eZaOtPHqydgt6 KewBfConZKGXuntRzmR6/6O1A4fZ8SxoxG+YsCDOQCRB/muLnQh2qnsQ+qSoKtmKcpsAel jXIrWxKju6Am+hIy4LT4/3nn/W6B6QVSJh4YAg70ySZVKesCym/YPMNleh1YD+yCd/HfNp eZwrkNREEKJU/ifv0xq1Z5m+jJXYZXbR9pCkl1HEHZFIUCqvOgKzvUKQ2SUjamDr9hFukg oHqZkL+qaVVDzbtkSpCQraTVjtjxwEIlevd+88/etFbswpzynHPPmDu+v0ylBQ== From: Max Gautier To: git@vger.kernel.org Cc: Max Gautier , =?utf-8?b?TMOpbmHDr2MgSHVhcmQ=?= , Derrick Stolee , Patrick Steinhardt , Junio C Hamano Subject: [PATCH v2 5/6] maintenance: update systemd scheduler docs Date: Fri, 22 Mar 2024 23:11:10 +0100 Message-ID: <20240322221327.12204-6-mg@max.gautier.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240322221327.12204-1-mg@max.gautier.name> References: <20240322221327.12204-1-mg@max.gautier.name> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The `git maintenance` systemd scheduler no longer writes units in $XDG_CONFIG_HOME. Describe the new behavior. Instead of explaining manual ways to modify the timer, suggest the systemd standard tool: `systemctl edit`. Signed-off-by: Max Gautier --- Documentation/git-maintenance.txt | 33 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Documentation/git-maintenance.txt b/Documentation/git-maintenance.txt index 51d0f7e94b..6511c3f3f1 100644 --- a/Documentation/git-maintenance.txt +++ b/Documentation/git-maintenance.txt @@ -304,10 +304,9 @@ distributions, systemd timers are superseding it. If user systemd timers are available, they will be used as a replacement of `cron`. -In this case, `git maintenance start` will create user systemd timer units -and start the timers. The current list of user-scheduled tasks can be found -by running `systemctl --user list-timers`. The timers written by `git -maintenance start` are similar to this: +In this case, `git maintenance start` will enable user systemd timer units +and start them. The current list of user-scheduled tasks can be found by +running `systemctl --user list-timers`. These timers are similar to this: ----------------------------------------------------------------------- $ systemctl --user list-timers @@ -317,25 +316,25 @@ Fri 2021-04-30 00:00:00 CEST 5h 42min left Thu 2021-04-29 00:00:11 CEST 18h ago Mon 2021-05-03 00:00:00 CEST 3 days left Mon 2021-04-26 00:00:11 CEST 3 days ago git-maintenance@weekly.timer git-maintenance@weekly.service ----------------------------------------------------------------------- -One timer is registered for each `--schedule=` option. +One timer instance is enabled for each `--schedule=` option. -The definition of the systemd units can be inspected in the following files: +The definition of the systemd units can be inspected this way: ----------------------------------------------------------------------- -~/.config/systemd/user/git-maintenance@.timer -~/.config/systemd/user/git-maintenance@.service -~/.config/systemd/user/timers.target.wants/git-maintenance@hourly.timer -~/.config/systemd/user/timers.target.wants/git-maintenance@daily.timer -~/.config/systemd/user/timers.target.wants/git-maintenance@weekly.timer +$ systemctl cat --user git-maintenance@.timer +$ systemctl cat --user git-maintenance@.service ----------------------------------------------------------------------- -`git maintenance start` will overwrite these files and start the timer -again with `systemctl --user`, so any customization should be done by -creating a drop-in file, i.e. a `.conf` suffixed file in the -`~/.config/systemd/user/git-maintenance@.service.d` directory. +Customization of the timer or service can be performed with the usual systemd +tooling: +----------------------------------------------------------------------- +$ systemctl edit --user git-maintenance@.timer # all the timers +$ systemctl edit --user git-maintenance@hourly.timer # the hourly timer +$ systemctl edit --user git-maintenance@.service # all the services +$ systemctl edit --user git-maintenance@hourly.service # the hourly run +----------------------------------------------------------------------- -`git maintenance stop` will stop the user systemd timers and delete -the above mentioned files. +`git maintenance stop` will disable and stop the user systemd timers. For more details, see `systemd.timer(5)`. From patchwork Fri Mar 22 22:11:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Gautier X-Patchwork-Id: 13600437 Received: from taslin.fdn.fr (taslin.fdn.fr [80.67.169.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFE40823A4 for ; Fri, 22 Mar 2024 22:14:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.67.169.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145648; cv=none; b=uzcaR1ybfAs1Ty1+hissceiMMf610G7+rgh8UNzXJPbPViRxuY5TurEz51KznM/bglazxe9qHsS5581NkJEWIUknbCHDIIqG+gb312yxS3l5653Mm+Jurey0ko9HBWFH6HqncdTLUfoyQHufOBWBEAXwISbR76IKfSWN+6uSDR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711145648; c=relaxed/simple; bh=trBhGdehN0Wt/SXG9bQuxMyUinyhaZ5MtTv3rs9BWXQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Dwdb6o37uDu9uLQPP9g3E6ss6WeQpq6viHpptD2sy5/zdBMecmm3HpimenvNRAZFa1AEAm32KQVxXS600V7owcdWDpCc5Z5DvIMGkIKH/5P+qVwpoJ1s4DcM1y0XVYW6WwAp6YkcwCFLQM0I2Z4H4amfo4aXeHUBWe6FwPxkne4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name; spf=pass smtp.mailfrom=max.gautier.name; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b=zIPKeWBW; arc=none smtp.client-ip=80.67.169.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=max.gautier.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=max.gautier.name header.i=@max.gautier.name header.b="zIPKeWBW" Received: from localhost (reverse-238.fdn.fr [80.67.176.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by taslin.fdn.fr (Postfix) with ESMTPSA id 3406F6037D; Fri, 22 Mar 2024 23:13:55 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=max.gautier.name; s=fdn; t=1711145635; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AXrpPHLZFaKXcQPNpkAahZyZz/rn+FU0YFVbXIQKhAY=; b=zIPKeWBWSnMMEnwrfo+O+70pfB2PUym/1CliF7qgVel10crOaGi2CXTM6HmiJK1IEKBUg9 uST2CPfr/N10wDS7OjMD9p4Ga/Vj6hF1gtm0/LBNypi5URKlAxKgiF5dMJsAaxrSEgUBWV G8AKmSJDqhMqXfKjO9TuogHkBqjc+6rF9bvnx97q8TlqDQsI9xWDyKYcJhmbn308JLa3O4 sF7UQ+djk8pwERom7/4LfB0DZRqpt4jPcRhxMRDZvsGJbV7W/iAvZxcKDTN/x+or3LPvKV W1ro4ntG0mL68oQzKCqjv/iE1OwqZ8xKGGucyvttRSjX2qSnzeGDndVe/qWlHQ== From: Max Gautier To: git@vger.kernel.org Cc: Max Gautier , =?utf-8?b?TMOpbmHDr2MgSHVhcmQ=?= , Derrick Stolee , Patrick Steinhardt , Eric Sunshine , Junio C Hamano Subject: [PATCH v2 6/6] maintenance: update tests for systemd scheduler Date: Fri, 22 Mar 2024 23:11:11 +0100 Message-ID: <20240322221327.12204-7-mg@max.gautier.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240322221327.12204-1-mg@max.gautier.name> References: <20240322221327.12204-1-mg@max.gautier.name> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The systemd units are now in the source tree, rather than produced when running git maitenance start. There is no need anymore to couple validating the units and testing `git maintenance start`. Adjust the test to verify the new `systemctl` command used, discard checks for presence/absence of unit files in $XDG_CONFIG_HOME. Validate the systemd units in the source tree, with one test per unit to have more distinct failures. Helped-by: Eric Sunshine Signed-off-by: Max Gautier --- Notes: I encountered the same issue that cover.1697319294.git.code@khaugsbakk.name tried to solve; I was expecting multiples tests to be independent while they weren't (in particular the MacOS ones). Cc: Kristoffer Haugsbakk t/t7900-maintenance.sh | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 37aa408d26..dc0bf39250 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -24,13 +24,6 @@ test_lazy_prereq SYSTEMD_ANALYZE ' systemd-analyze verify /lib/systemd/system/basic.target ' -test_systemd_analyze_verify () { - if test_have_prereq SYSTEMD_ANALYZE - then - systemd-analyze verify "$@" - fi -} - test_expect_success 'help text' ' test_expect_code 129 git maintenance -h >actual && test_grep "usage: git maintenance " actual && @@ -776,23 +769,32 @@ test_expect_success 'start and stop Windows maintenance' ' hourly daily weekly >expect && test_cmp expect args ' +test_expect_success SYSTEMD_ANALYZE 'validate maintenance systemd service unit' ' + git_path=$(command -v git) && + sed "s+@BINDIR@/git+${git_path}+" "$TEST_DIRECTORY"/../systemd/user/git-maintenance@.service.in > git-maintenance@.service && + systemd-analyze verify git-maintenance@hourly.service git-maintenance@daily.service git-maintenance@weekly.service && + rm git-maintenance@.service && + unset git_path +' + +test_expect_success SYSTEMD_ANALYZE 'validate maintenance systemd timer unit' ' + SYSTEMD_UNIT_PATH="$TEST_DIRECTORY"/../systemd/user/: systemd-analyze verify git-maintenance@hourly.timer git-maintenance@daily.timer git-maintenance@weekly.timer + # ':' at the end of SYSTEMD_UNIT_PATH appends the default systemd search path + # This is needed because analyze tries to load implicit / default unit dependencies +' test_expect_success 'start and stop Linux/systemd maintenance' ' write_script print-args <<-\EOF && printf "%s\n" "$*" >>args EOF - XDG_CONFIG_HOME="$PWD" && - export XDG_CONFIG_HOME && rm -f args && GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args" git maintenance start --scheduler=systemd-timer && # start registers the repo git config --get --global --fixed-value maintenance.repo "$(pwd)" && - test_systemd_analyze_verify "systemd/user/git-maintenance@.service" && - - printf -- "--user enable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && + echo "--user --force --now enable" git-maintenance@hourly.timer git-maintenance@daily.timer git-maintenance@weekly.timer >expect && test_cmp expect args && rm -f args && @@ -801,10 +803,7 @@ test_expect_success 'start and stop Linux/systemd maintenance' ' # stop does not unregister the repo git config --get --global --fixed-value maintenance.repo "$(pwd)" && - test_path_is_missing "systemd/user/git-maintenance@.timer" && - test_path_is_missing "systemd/user/git-maintenance@.service" && - - printf -- "--user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && + echo "--user --force --now disable" git-maintenance@hourly.timer git-maintenance@daily.timer git-maintenance@weekly.timer >expect && test_cmp expect args ' @@ -819,12 +818,12 @@ test_expect_success 'start and stop when several schedulers are available' ' hourly daily weekly >expect && printf "schtasks /delete /tn Git Maintenance (%s) /f\n" \ hourly daily weekly >>expect && - printf -- "systemctl --user enable --now git-maintenance@%s.timer\n" hourly daily weekly >>expect && + echo "systemctl --user --force --now enable" git-maintenance@hourly.timer git-maintenance@daily.timer git-maintenance@weekly.timer >>expect && test_cmp expect args && rm -f args && GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args systemctl,launchctl:./print-args launchctl,schtasks:./print-args schtasks" git maintenance start --scheduler=launchctl && - printf -- "systemctl --user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && + echo "systemctl --user --force --now disable" git-maintenance@hourly.timer git-maintenance@daily.timer git-maintenance@weekly.timer >expect && printf "schtasks /delete /tn Git Maintenance (%s) /f\n" \ hourly daily weekly >>expect && for frequency in hourly daily weekly @@ -837,7 +836,7 @@ test_expect_success 'start and stop when several schedulers are available' ' rm -f args && GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args systemctl,launchctl:./print-args launchctl,schtasks:./print-args schtasks" git maintenance start --scheduler=schtasks && - printf -- "systemctl --user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && + echo "systemctl --user --force --now disable" git-maintenance@hourly.timer git-maintenance@daily.timer git-maintenance@weekly.timer >expect && printf "launchctl bootout gui/[UID] $pfx/Library/LaunchAgents/org.git-scm.git.%s.plist\n" \ hourly daily weekly >>expect && printf "schtasks /create /tn Git Maintenance (%s) /f /xml\n" \ @@ -846,7 +845,7 @@ test_expect_success 'start and stop when several schedulers are available' ' rm -f args && GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args systemctl,launchctl:./print-args launchctl,schtasks:./print-args schtasks" git maintenance stop && - printf -- "systemctl --user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && + echo "systemctl --user --force --now disable" git-maintenance@hourly.timer git-maintenance@daily.timer git-maintenance@weekly.timer >expect && printf "launchctl bootout gui/[UID] $pfx/Library/LaunchAgents/org.git-scm.git.%s.plist\n" \ hourly daily weekly >>expect && printf "schtasks /delete /tn Git Maintenance (%s) /f\n" \