Re: [PATCH v2 3/4] maintenance: use launchctl on macOS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/11/2020 3:12 AM, Eric Sunshine wrote:
> On Wed, Nov 4, 2020 at 3:06 PM Derrick Stolee via GitGitGadget
> <gitgitgadget@xxxxxxxxx> wrote:
>> [...]
>> The solution is to switch from cron to the Apple-recommended [1]
>> 'launchd' tool.
>> [...]
>> Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx>
>> ---
>> diff --git a/Documentation/git-maintenance.txt b/Documentation/git-maintenance.txt
>> +While macOS technically supports `cron`, using `crontab -e` requires
>> +elevated privileges and the executed process do not have a full user
> 
> Either s/process/processes/ or s/do/does/
> 
>> +context. Without a full user context, Git and its credential helpers
>> +cannot access stored credentials, so some maintenance tasks are not
>> +functional.
> 
> Nicely explained.
> 
>> +Instead, `git maintenance start` interacts with the `launchctl` tool,
>> +which is the recommended way to
>> +https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/ScheduledJobs.html[schedule timed jobs in macOS].
> 
> Nit: I worry a bit about links to Apple documentation becoming
> outdated. It might not hurt to omit this link altogether, or perhaps
> demote it to a footnote (which might allow it to be somewhat usable
> even when Git documentation is rendered into something other than
> HTML).
> 
>> +Scheduling maintenance through `git maintenance (start|stop)` requires
>> +some `launchctl` features available only in macOS 10.11 or later.
> 
> Nit: This leaves the reader wondering what modern features are needed.
> Would it make sense to mention that "bootstrap" is used in place of
> "load" in older versions of 'launchctl'?
> 
>> +Your user-specific scheduled tasks are stored as XML-formatted `.plist`
>> +files in `~/Library/LaunchAgents/`. You can see the currently-registered
>> +tasks using the following command:
>> +
>> +-----------------------------------------------------------------------
>> +$ ls ~/Library/LaunchAgents/ | grep org.git-scm.git
> 
> Alternately (unimportant):
> 
>     ls ~/Library/LaunchAgents/org.git-scm.git.*
> 
> although that would emit "No such file" if you don't have any
> registered, which might suggest:
> 
>     find ~/Library/LaunchAgents -name 'org.git-scm.git.*'
> 
>> +To create more advanced customizations to your background tasks, see
>> +https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/TP40001762-104142[the `launchctl` documentation]
>> +for more information.
> 
> I really worry about this sort of URL becoming outdated. Would it make
> sense instead to just point the user at the man page,
> launchd.plist(5)? It's not quite the same, as it doesn't provide the
> range of examples as the URL you cite, but it should get the user
> started.

I shared similar concerns. I'll use the man page references instead.
All of the information should be a short web search away after the
user is given the right terminology.

>> diff --git a/builtin/gc.c b/builtin/gc.c
>> @@ -1491,6 +1491,214 @@ static int maintenance_unregister(void)
>> +static int remove_plist(enum schedule_priority schedule)
>> +{
>> +       const char *frequency = get_frequency(schedule);
>> +       char *name = get_service_name(frequency);
>> +       char *filename = get_service_filename(name);
>> +       int result = bootout(filename);
>> +       free(filename);
>> +       free(name);
>> +       return result;
>> +}
>>
>> +static int remove_plists(void)
>> +{
>> +       return remove_plist(SCHEDULE_HOURLY) ||
>> +               remove_plist(SCHEDULE_DAILY) ||
>> +               remove_plist(SCHEDULE_WEEKLY);
>> +}
> 
> The new documentation you added says that the plist files will be
> deleted after they are deregistered using launchctl, but I don't see
> anything actually deleting them. Am I missing something obvious?

As mentioned below, this was a change that I made but somehow lost
while juggling multiple copies of my branch.

>> +static int schedule_plist(const char *exec_path, enum schedule_priority schedule)
>> +{
>> +       plist = fopen(filename, "w");
>> +       if (!plist)
>> +               die(_("failed to open '%s'"), filename);
> 
> As mentioned previously, these could be replaced with a simple xfopen().
> 
> In fact, I'm having trouble seeing changes in this re-roll which you
> had planned on making, such as consolidating the repeated code in
> bootout() and bootstrap(), and ensuring that bootout() doesn't
> complain if the plist files are already missing, and so forth. Did you
> opt to not make those changes? (Which would be fine; they were minor
> suggestions.)

No, I definitely made those changes _somewhere_ but I must have
gotten confused as to which of my machines had those changes. I
guess that's part of the risk of testing across three platforms.

Thank you for noticing, and I'll be more careful from now on.

>> +test_expect_success MACOS_MAINTENANCE 'start and stop macOS maintenance' '
>> +       echo "#!/bin/sh\necho \$@ >>args" >print-args &&
>> +       chmod a+x print-args &&
> 
> Earlier review already mentioned write_script() and "$@". (Not
> necessarily worth a re-roll.)

I'm going to go back to all of your earlier comments to make sure
they are _actually_ applied in v3.
 
>> +       for frequency in hourly daily weekly
>> +       do
>> +               PLIST="$HOME/Library/LaunchAgents/org.git-scm.git.$frequency.plist" &&
>> +               xmllint "$PLIST" >/dev/null &&
> 
> Do we really need to suppress xmllint's stdout?

It outputs the XML itself. Maybe there is a command to stop that from
happening, but nulling stdout keeps the test log clean.

Thanks,
-Stolee



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux