maintenance: add custom config to background jobs

At the moment, some background jobs are getting blocked on credentials during the 'prefetch' task. This leads to other tasks, such as incremental repacks, getting blocked. Further, if a user manages to fix their credentials, then they still need to cancel the background process before their background maintenance can continue working. Update the background schedules for our four scheduler integrations to include these config options via '-c' options: * 'credential.interactive=false' will stop Git and some credential helpers from prompting in the UI (assuming the '-c' parameters are carried through and respected by GCM). * 'core.askPass=true' will replace the text fallback for a username and password into the 'true' command, which will return a success in its exit code, but Git will treat the empty string returned as an invalid password and move on. We can do some testing that the credentials are passed, at least in the systemd case due to writing the service files. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Sep 20, 2024 at 00:00 UTC 4f5551957ddd6c679fc8499d4e1e110d43a49071
2 files changed +49 -7
builtin/gc.c
+46 -7
@@ -1664,6 +1664,42 @@ static const char *get_frequency(enum schedule_priority schedule)
1664 }
1665 }
1666
1667 +static const char *extraconfig[] = {
1668 + "credential.interactive=false",
1669 + "core.askPass=true", /* 'true' returns success, but no output. */
1670 + NULL
1671 +};
1672 +
1673 +static const char *get_extra_config_parameters(void) {
1674 + static const char *result = NULL;
1675 + struct strbuf builder = STRBUF_INIT;
1676 +
1677 + if (result)
1678 + return result;
1679 +
1680 + for (const char **s = extraconfig; s && *s; s++)
1681 + strbuf_addf(&builder, "-c %s ", *s);
1682 +
1683 + result = strbuf_detach(&builder, NULL);
1684 + return result;
1685 +}
1686 +
1687 +static const char *get_extra_launchctl_strings(void) {
1688 + static const char *result = NULL;
1689 + struct strbuf builder = STRBUF_INIT;
1690 +
1691 + if (result)
1692 + return result;
1693 +
1694 + for (const char **s = extraconfig; s && *s; s++) {
1695 + strbuf_addstr(&builder, "<string>-c</string>\n");
1696 + strbuf_addf(&builder, "<string>%s</string>\n", *s);
1697 + }
1698 +
1699 + result = strbuf_detach(&builder, NULL);
1700 + return result;
1701 +}
1702 +
1703 /*
1704 * get_schedule_cmd` reads the GIT_TEST_MAINT_SCHEDULER environment variable
1705 * to mock the schedulers that `git maintenance start` rely on.
@@ -1870,6 +1906,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
1906 "<array>\n"
1907 "<string>%s/git</string>\n"
1908 "<string>--exec-path=%s</string>\n"
1909 + "%s" /* For extra config parameters. */
1910 "<string>for-each-repo</string>\n"
1911 "<string>--keep-going</string>\n"
1912 "<string>--config=maintenance.repo</string>\n"
@@ -1879,7 +1916,8 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
1916 "</array>\n"
1917 "<key>StartCalendarInterval</key>\n"
1918 "<array>\n";
1882 - strbuf_addf(&plist, preamble, name, exec_path, exec_path, frequency);
1919 + strbuf_addf(&plist, preamble, name, exec_path, exec_path,
1920 + get_extra_launchctl_strings(), frequency);
1921
1922 switch (schedule) {
1923 case SCHEDULE_HOURLY:
@@ -2114,11 +2152,12 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
2152 "<Actions Context=\"Author\">\n"
2153 "<Exec>\n"
2154 "<Command>\"%s\\headless-git.exe\"</Command>\n"
2117 - "<Arguments>--exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n"
2155 + "<Arguments>--exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n"
2156 "</Exec>\n"
2157 "</Actions>\n"
2158 "</Task>\n";
2121 - fprintf(tfile->fp, xml, exec_path, exec_path, frequency);
2159 + fprintf(tfile->fp, xml, exec_path, exec_path,
2160 + get_extra_config_parameters(), frequency);
2161 strvec_split(&child.args, cmd);
2162 strvec_pushl(&child.args, "/create", "/tn", name, "/f", "/xml",
2163 get_tempfile_path(tfile), NULL);
@@ -2259,8 +2298,8 @@ static int crontab_update_schedule(int run_maintenance, int fd)
2298 "# replaced in the future by a Git command.\n\n");
2299
2300 strbuf_addf(&line_format,
2262 - "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%s\n",
2263 - exec_path, exec_path);
2301 + "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%s\n",
2302 + exec_path, exec_path, get_extra_config_parameters());
2303 fprintf(cron_in, line_format.buf, minute, "1-23", "*", "hourly");
2304 fprintf(cron_in, line_format.buf, minute, "0", "1-6", "daily");
2305 fprintf(cron_in, line_format.buf, minute, "0", "0", "weekly");
@@ -2460,7 +2499,7 @@ static int systemd_timer_write_service_template(const char *exec_path)
2499 "\n"
2500 "[Service]\n"
2501 "Type=oneshot\n"
2463 - "ExecStart=\"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%i\n"
2502 + "ExecStart=\"%s/git\" --exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%i\n"
2503 "LockPersonality=yes\n"
2504 "MemoryDenyWriteExecute=yes\n"
2505 "NoNewPrivileges=yes\n"
@@ -2470,7 +2509,7 @@ static int systemd_timer_write_service_template(const char *exec_path)
2509 "RestrictSUIDSGID=yes\n"
2510 "SystemCallArchitectures=native\n"
2511 "SystemCallFilter=@system-service\n";
2473 - if (fprintf(file, unit, exec_path, exec_path) < 0) {
2512 + if (fprintf(file, unit, exec_path, exec_path, get_extra_config_parameters()) < 0) {
2513 error(_("failed to write to '%s'"), filename);
2514 fclose(file);
2515 goto error;
t/t7900-maintenance.sh
+3
@@ -800,6 +800,9 @@ test_expect_success 'start and stop Linux/systemd maintenance' '
800 test_systemd_analyze_verify "systemd/user/git-maintenance@daily.service" &&
801 test_systemd_analyze_verify "systemd/user/git-maintenance@weekly.service" &&
802
803 + grep "core.askPass=true" "systemd/user/git-maintenance@.service" &&
804 + grep "credential.interactive=false" "systemd/user/git-maintenance@.service" &&
805 +
806 printf -- "--user enable --now git-maintenance@%s.timer\n" hourly daily weekly >expect &&
807 test_cmp expect args &&
808