Skip to content
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

Mac: Enable daemon service to run as soon as user login #3095

Merged
merged 1 commit into from
Apr 11, 2022

Conversation

praveenkumar
Copy link
Member

Without this PR following scenario happen

  • User installed the crc first time and do the setup
  • As part of the setup crc daemon is started by launchd
  • User reboot
  • Tray autostart with reboot but crc setup --check-only fails
    because launchd agent 'com.redhat.crc.daemon' is not running.

With this PR, check for daemon task running should first validate
if an existing process of crc daemon is running and the version
it get from the api should be same as the binary then task running
check succeed. So this PR will makes crc setup --check-only work
again with tray autostart.

@openshift-ci openshift-ci bot requested review from cfergeau and gbraad March 31, 2022 12:16
@cfergeau
Copy link
Contributor

I thought launchd would ensure the daemon is started when the user opens a session on their mac? The launchd changes don't guarantee the daemon will be running during startup?

@praveenkumar
Copy link
Member Author

I thought launchd would ensure the daemon is started when the user opens a session on their mac? The launchd changes don't guarantee the daemon will be running during startup?

@cfergeau As of now launchd is working same way as we are doing in linux except the socket activation part (in linux our socket activation service is enabled but that doesn't start daemon until something query to that socket) here also I think we don't want to start the daemon by default by launchd, right now it is required because of tray but in future tray is not part of crc.

@praveenkumar
Copy link
Member Author

/retest

@cfergeau
Copy link
Contributor

@cfergeau As of now launchd is working same way as we are doing in linux except the socket activation part (in linux our socket activation service is enabled but that doesn't start daemon until something query to that socket) here also I think we don't want to start the daemon by default by launchd, right now it is required because of tray but in future tray is not part of crc.

On linux, the daemon is not automatically started on login because we can avoid it thanks to the socket activation files. If socket activation did not exist, we would have to start the daemon automatically on login.
If the daemon is not autostarted, I don't understand what launchd is used for? What does this bring over just running crc daemon manually?

@praveenkumar
Copy link
Member Author

If the daemon is not autostarted, I don't understand what launchd is used for? What does this bring over just running crc daemon manually.

Running daemon manually means you have to keep that terminal always open or manually run it in background, as user you have to make sure stop it when not required crc cleanup not remove that process also, so even with current state it is better than running manually but our plan is to have it auto start every restart that we can improve over time.

@cfergeau
Copy link
Contributor

cfergeau commented Mar 31, 2022

even with current state it is better than running manually but our plan is to have it auto start every restart that we can improve over time.

I am really unclear on what "the current state" is. I'm totally lost as to what happens if I run crc setup, and then reboot the machine. How will the daemon be started?
Isn't autostarting the daemon on session logging one or 2 lines to change in the launchd plist file?

@praveenkumar praveenkumar changed the title Mac: Check if daemon process is already running Mac: Enable daemon service to run as soon as user login Apr 1, 2022
@praveenkumar
Copy link
Member Author

even with current state it is better than running manually but our plan is to have it auto start every restart that we can improve over time.

I am really unclear on what "the current state" is. I'm totally lost as to what happens if I run crc setup, and then reboot the machine. How will the daemon be started? Isn't autostarting the daemon on session logging one or 2 lines to change in the launchd plist file?

@cfergeau I thought we don't want that but yes it is easy and I updated the PR accordingly.

@cfergeau
Copy link
Contributor

cfergeau commented Apr 4, 2022

One limitation to the current approach is if the daemon was started by the tray in a previous version. Starting the daemon with launchd will silently fail, and nothing detects this old daemon version.
One way to solve this is to check the version of the running daemon as was done in an earlier iteration of this code, and kill any old version before restarting it in the proper version.

"github.com/pkg/errors"
)

// This make sure golint doesn't error out because not
// using it on all the platforms
var _ = isDaemonRunningWithReleasedVersion()
Copy link
Contributor

@cfergeau cfergeau Apr 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isDaemonRunningWithReleasedVersion is almost the same code as checkDaemonStarted which is used on all platforms, so this could be factored if you want to avoid this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line causes crc to freeze on startup on linux.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cfergeau Handled in #3099 , will hold this until that merge and then rebase it

@@ -158,7 +161,57 @@ func isDaemonRunningWithReleasedVersion() bool {
}
if ver.CrcVersion != version.GetCRCVersion() {
logging.Debugf("Daemon is running with %s version but binary version is %s", ver.CrcVersion, version.GetCRCVersion())
if err := killExistingDaemonProcess(); err != nil {
logging.Debugf("Failed to kill the existing crc daemon process: %v", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is called isDaemonRunningWithReleasedVersion, it's not supposed to stop/kill the daemon as a side effect.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The killing of the existing daemon process can be part of the fix function for this check?

return nil
}

// isDaemonProcess return true if following conditions met
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if any of the following conditions are met? if all of the following conditions are met? if none of the following conditions are met?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cfergeau updated to any of the following.

if !isDaemonRunningWithReleasedVersion() {
if !launchd.AgentRunning(daemonConfig.Label) {
return fmt.Errorf("launchd agent '%s' is not running", daemonConfig.Label)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about writing it like this? This seems clearer regarding what the code wants to do.

if olderDaemonVersionRunning() {
   if err := killDaemonProcess(); err != nil {
       return err
   }
}
if !launchd.AgentRunning(daemonConfig.Label) {
			return fmt.Errorf("launchd agent '%s' is not running", daemonConfig.Label)
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be also easy as once #3099 in.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cfergeau It is now suggested way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anjan had a good point though that the killing fits better in a fix method rather than in check.

@praveenkumar
Copy link
Member Author

/hold

@praveenkumar
Copy link
Member Author

/unhold

@praveenkumar praveenkumar added the has-to-be-in-release This PR need to go in coming release. label Apr 8, 2022
return err
}
}
return nil
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In linux I have to add it in this socket file check otherwise cross-lint error out not using killDaemonProcess function to linux. If we don't want to do that then might be we need to create a different file preflight_check_nonlinux and move this there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linux is already taking care of stopping the daemon if needed, I'd rather not add code which is going to mess with the preeexisting code which is working fine.

@gbraad
Copy link
Contributor

gbraad commented Apr 8, 2022

praveenkumar added the has-to-be-in-release label 4 hours ago

Why was this tag added? Is everything lined up correctly to allow this?
Which issue does this solve or related to?

@praveenkumar
Copy link
Member Author

praveenkumar added the has-to-be-in-release label 4 hours ago

Why was this tag added?

@gbraad because I want this to be part of 2.1.0 release (upcoming one).

Is everything lined up correctly to allow this?

Yes, tray side changes were already there, when I filed this PR initially I thought it would be a trival but @cfergeau suggestions around having launchd service as auto reload and also detecting the old version of daemon and kill it, took
some time to implement and getting it reviewed.

Which issue does this solve or related to?

This will solve the issue for a user who just want to do crc setup and crc start on mac with or without tray.

@gbraad
Copy link
Contributor

gbraad commented Apr 8, 2022

I am just concerned about how this was planned. Feels a little last minute.

We have to better describe dependency to merge, or accept a known issue?

@anjannath
Copy link
Member

anjannath commented Apr 8, 2022

I am just concerned about how this was planned. Feels a little last minute.
We have to better describe dependency to merge, or accept a known issue?

The review comments are mostly addressed, i'll test this now e2e with the tray and upgrade scenario

func daemonNotRunningMessage() string {
return genericDaemonNotRunningMessage
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, I would have moved these to start.go in the previous commit

return err
}
}
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linux is already taking care of stopping the daemon if needed, I'd rather not add code which is going to mess with the preeexisting code which is working fine.

if err := daemonclient.CheckIfOlderVersion(v); err != nil {
return true
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be written the usual go way?

v, err := dosomething()
if err != nil {
    return err
}
err = dosomethingelse(v)
if err != nil {
    return err
}

This removes the extra indentation, construct is familiar so it's easier to read.

if !isDaemonRunningWithReleasedVersion() {
if !launchd.AgentRunning(daemonConfig.Label) {
return fmt.Errorf("launchd agent '%s' is not running", daemonConfig.Label)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anjan had a good point though that the killing fits better in a fix method rather than in check.

@openshift-ci
Copy link

openshift-ci bot commented Apr 8, 2022

@praveenkumar: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-crc 19b4b50 link true /test e2e-crc

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

Copy link
Contributor

@cfergeau cfergeau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a description of the bug this fixes, or a link to the relevant issue? Apart from this, looks good to me.

@openshift-ci
Copy link

openshift-ci bot commented Apr 11, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cfergeau, praveenkumar

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [cfergeau,praveenkumar]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

This PR enable the daemon service to run user session basis, if system
reboot and user logs in then this service now auto started.

- User installs crc first time and do crc setup
- As part of the setup crc daemon is started by launchd
- User reboots
- Tray autostart with reboot but crc setup --check-only fails because launchd agent 'com.redhat.crc.daemon' is not running which triggers the on-boarding

fixes: crc-org#3104
@openshift-ci
Copy link

openshift-ci bot commented Apr 11, 2022

New changes are detected. LGTM label has been removed.

@praveenkumar praveenkumar merged commit 2af42b9 into crc-org:main Apr 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved has-to-be-in-release This PR need to go in coming release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants