-
-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for running services fully backgrounded on macOS #485
Added support for running services fully backgrounded on macOS #485
Conversation
lib/service/services_cli.rb
Outdated
service.service_file.read | ||
else | ||
file.read | ||
end | ||
|
||
if System.launchctl? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this addition should happen when generating the file, not here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean def generate_plist
? I tried that initially but it doesn't even seem to get called (at least for Apache). :>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean in brew itself, in the Service
class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only see 1 candidate in /opt/homebrew/Library/Homebrew/service.rb
(def to_plist
), but that too doesn't seem to get called. I even made sure to stop
and start
instead of restart
, or simply remove the plist beforehand. The place where it currently makes the changes gets called every time, even when doing restart
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It gets called when you install a formula, there's no real benefits in rewriting the plist at every start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But wouldn't that mean everyone who wants to use the new feature would have to reinstall all their services? I'm not entirely sure if it might even remove some config files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would slowly propagate with software updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright that works, plus reinstalling doesn't seem to remove configs so that should be fine too. I checked with redis because I noticed that your GitHub CI reported an error about it:
==>Successfully stopped `redis` (label: homebrew.mxcl.redis)
Bootstrap failed: 5: Input/output error
Error: Failure while executing; `/bin/launchctl bootstrap user/501 /usr/local/opt/redis/homebrew.mxcl.redis.plist` exited with 5.
Error: Process completed with exit code 1.
However, I can start/stop/restart without errors and even the exact commands being used in the test work fine:
brew services stop redis
sleep 5
brew services run redis
brew services restart redis
Anyways, the only thing this PR now changes is gui/$UID
=> user/$UID
. :>
I thing "recommended" is a bit strong here given it says "if you need".
I think this behaviour should be opt-in |
Did you try:
by any chance? |
I'm speaking from the perspective of a multi-user system there though.
The problem I noticed with doing it detection-based is that a plist with an outdated session type might linger around. E.g. you use SSH to initially start the service, so Homebrew will generate a plist with either the @RandomDSdevel I just tried it and although the session type is properly |
Hmm, interesting/surprising. Passing ' |
Yeah both exist just to be sure. =] I think the reason is that |
Ok, thanks for explaining. Given this and your other explanations above: I'm cautiously in favour. |
CI is failing on macOS I'm afraid. |
Yeah that's what I mentioned in the comment thread a bit above. I can't reproduce the error on my end so it might be specific to how the tests are run. |
@GottemHams Not sure what to say here beyond:
Sorry! |
@MikeMcQuaid So I added some stuff to the GitHub CI, such as printing the service plist file. It doesn't even contain the |
@GottemHams So does Homebrew/brew#13510 need merged before this PR can have green CI? If so, is there a way to scope this PR down so it can be merged first? |
Actually no, this PR literally only changes The PR over at
Since that PR only changes the plist and it also/still includes the |
Have restarted jobs post-Homebrew/brew PR merge. Let's see if they pass now. |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
Thanks again @GottemHams, let's see how this goes 🤞🏻! |
Fail to work on macOS Monterey 12.5, after revert this PR, it return to normal. ─▪ brew services start percona-server
Bootstrap failed: 5: Input/output error
Try re-running the command as root for richer errors.
Error: Failure while executing; `/bin/launchctl bootstrap user/502 /Users/guochunzhong/Library/LaunchAgents/homebrew.mxcl.percona-server.plist` exited with 5. |
Reverting in #498 |
3 reports within 30m of merging. Yup, this was pretty broken I'm afraid @GottemHams. |
@MikeMcQuaid Nothing is broken, it seems nobody has been paying attention.
So what's going to happen if someone (like @Eric-Guo) has a pre-existing plist, which also doesn't get rewritten? The exact same thing. ;] I figured you kept this PR open for a while to deliberate (internally) how to deal with this, since @SMillerDev previously said he didn't really want the plist to be rewritten on every start. |
@GottemHams I really don't appreciate your tone here. Please re-read our Code of Conduct: https://github.com/Homebrew/.github/blob/HEAD/CODE_OF_CONDUCT.md#code-of-conduct
Your communication did not at all make it clear that you knew this PR would break things once it was merged. If you'd still like to: please reopen a PR with a CI test that fails in this known-broken case. If you'd rather leave it: that's fine and we can revert the Homebrew/brew change. |
I dunno, I thought it was pretty clear; doesn't contain |
Not to me, sorry.
We'll need a way to ensure that plists are rewritten as expected in this case.
Both, please. Need to have a fix for this issue above and a test for this before we can merge again. Thanks! |
Sure, will take some time though since I have a tonne of other things to do at the moment. :> The change already merged for
Well my original proposal was to rewrite the plist on Alternatively, we could keep only the current on-install change and use the default/previous |
This seems like a good idea 👍🏻. @SMillerDev any thoughts? |
Sounds good to me. |
This PR is the product of a discussion on the main Homebrew repo. In short: it aims to improve working with
brew services
on multi-user systems when sharing a global HB instance, although there is also some benefit for single-user systems (see the next section).Besides changing the
gui/*
domain touser/*
stuff, HB now also modifies every plist it installs (or checks if it has to, at least). I've explained that last part in comments next to the relevant code, so I'm not going to repeat it here. It's not a very large patch anyway. :> Theuser
domain seems to always be present as long as some form of login occurred, it can also co-exist withgui
. And sincehomebrew-services
is specifically meant for background services it also makes the most sense to just useuser
domains.The session types aren't explained there, but I found them here:
Just for reference, if you wanted to check the current session type, just run
launchctl managername
and it'll print any of those names.Some important usage/background information
Although it requires a specific setup, many parts are already recommended for/relevant to multi-user systems even without this patch:
brew
as a non-HB user, you'll need an alias/shell function, which you'd already need without the patch too. In my case I also want to be able to runbrew
without having to type the other account's password every time. An example:Then
/etc/sudoers.d/homebrew
contains simplymyuser ALL=NOPASSWD: /usr/bin/su -l mybrew -c *
, meaning my own account can run any commands asmybrew
no prob.Note how I'm doing
sudo su
instead of justsudo
orsu
, the latter of which doesn't even pass through sudoers config so using it stand-alone would always require typing a password. Furthermore, there's a major problem with just usingsudo
because it either doesn't set up the environment for the target user, or (and this is the important part relevant for this patch) launchctl detects the wrong login session type and the service won't even start.brew
will report it did but it's actually hanging on thebootstrap
command and you have tolaunchctl bootout user/<UID> <service name>
to get it unstuck. Like I'm doing in the example you can't actually pass multiple commands directly tosudo
without using e.g.sudo -u mybrew bash -c "multiple; commands; here"
. Usingsudo
with any shell like that will cause launchctl to detect anAqua
session, although I've only checked withbash
andsh
there might be shell-specific overrides. Finally, I'm usingsu -l
to discard the current environment, which again is needed to get it detected as aBackground
session. That also means I have to manuallysource
the target user's shell config, since I have some HB-related environment variables in there and I need them exported for thebrew
command. Pretty suresudo
simply overrides the "interactivity" ofsu
's shell and causes it to no longer read profiles automatically, but instead goes looking for an environment variableBASH_ENV
(orENV
forsh
). May as well just source the file directly then. =]With this setup you can run
brew services
commands as any user and the service will be able to start regardless of whether you're in an actual GUI/Aqua session or doing somesu(do)
magic. It also doesn't break things for anyone with a single-user setup; if anything it also improves it for them, e.g. starting a service purely through SSH should also be possible now.And a final note: keep in mind that although HB installs a LaunchAgent that would normally autostart the service when rebooting, it won't actually trigger if you're not logging on to an Aqua session for the dedicated user. So you'll always have to manually run a
start
command, or write a LaunchAgent for your own user that runs the necessarybrew
commands. It probably could autostart if you were to put the plist in the system/Library
and have it run inLoginWindow
or evenSystem
context. But thenbrew
itself needs tosudo
up and that goes against Homebrew's ideas. :D