• Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Major Major
    • core, xcode-plugin
    • None

      JENKINS-9399 changed the Jenkins from using LaunchAgents to LaunchDaemons because, at the time, there were problems with running as an agent and using LaunchDaemons seems like the right approach.

      Two years later, it's pretty clear that using LaunchDaemons creates a whole host of problems which (I argue) are worse than using LaunchAgents in the first place. LaunchDaemons cannot launch GUI applications which means you cannot unit test iOS applications or launch with XCode "instructions"... both of which are in high demand.

      Anyway, I believe I discovered a way for us to have the best of both worlds: using LaunchAgents, having it auto-launch on boot, and preventing it from running under other users. I believe this will solve all outstanding problems.

      1. Configure Jenkins to use LaunchAgents (reverse JENKINS-9399).
      2. Install the plist into ~/Library/LaunchAgents instead of /Library/LaunchAgents to prevent it from getting triggered by other users logging in.
      3. Configure the Jenkins user to auto-login on startup, but return to the login menu immediately: http://www.tuaw.com/2011/03/07/terminally-geeky-use-automatic-login-more-securely/

          [JENKINS-21237] Jenkins should use LaunchAgents under OSX

          cowwoc created issue -

          Sami Tikka added a comment -

          It has been years since I last played with PackageMaker but I believe it was possible to build a package that will query if you want to install for all users or for current user only. If all users is chosen, the installer will prompt for admin password. It might be possible to determine which kind of installation happened in a post install script and place the launchd plist file in a location that either makes Jenkins be a launch daemon or launch agent.

          However, I think it would be rude to unconditionally configure the current user's account such that after login he is immediately presented with the login screen again. It should at least be configurable (= ask the user) but how to do that with PackageMaker... I have no idea.

          Actually I am really tired with PackageMaker. I believe a better user experience is achieved by creating an application, a single icon the user drags where he wants and runs by double-clicking. The application can then have a conversation with the user or present a rich UI to configure and run Jenkins. If a launch agent or daemon is needed, the application can set those up.

          So, personally, rather than fight with the limitations of PackageMaker, I would rather improve Jenkins.app. I'm happy to collaborate on it (pull requests are welcome.) Jenkins.app is my own project but if people feel it should be in the official Jenkins git repository, I can renew my request to accept it there.

          I have kept it outside of the official Jenkins tree because I assumed most people were happy with the PackageMaker based installer which runs Jenkins as a launch daemon. It has it's problems but there are workarounds and plugins like the Xcode plugin which should provide some relief.

          Sami Tikka added a comment - It has been years since I last played with PackageMaker but I believe it was possible to build a package that will query if you want to install for all users or for current user only. If all users is chosen, the installer will prompt for admin password. It might be possible to determine which kind of installation happened in a post install script and place the launchd plist file in a location that either makes Jenkins be a launch daemon or launch agent. However, I think it would be rude to unconditionally configure the current user's account such that after login he is immediately presented with the login screen again. It should at least be configurable (= ask the user) but how to do that with PackageMaker... I have no idea. Actually I am really tired with PackageMaker. I believe a better user experience is achieved by creating an application, a single icon the user drags where he wants and runs by double-clicking. The application can then have a conversation with the user or present a rich UI to configure and run Jenkins. If a launch agent or daemon is needed, the application can set those up. So, personally, rather than fight with the limitations of PackageMaker, I would rather improve Jenkins.app . I'm happy to collaborate on it (pull requests are welcome.) Jenkins.app is my own project but if people feel it should be in the official Jenkins git repository, I can renew my request to accept it there. I have kept it outside of the official Jenkins tree because I assumed most people were happy with the PackageMaker based installer which runs Jenkins as a launch daemon. It has it's problems but there are workarounds and plugins like the Xcode plugin which should provide some relief.

          cowwoc added a comment -

          @Sami Tikka, I don't see the point of ever installing Jenkins for all users. You always want to install it for one user, be that the current user or some other user.

          What I'd really like to see Jenkins' official installer install into the current user, and a unification of #jenkinsapp and https://github.com/rhwood/jenkins-slave-osx for installing Jenkins outside the current user.

          cowwoc added a comment - @Sami Tikka, I don't see the point of ever installing Jenkins for all users. You always want to install it for one user, be that the current user or some other user. What I'd really like to see Jenkins' official installer install into the current user, and a unification of #jenkinsapp and https://github.com/rhwood/jenkins-slave-osx for installing Jenkins outside the current user.

          Randall Wood added a comment -

          Using a LaunchAgent introduces a security vulnerability (automatically logged in user at console) on the Mac running the LaunchAgent, so any user installing that should explicitly do so.

          @cowwoc - Installing Jenkins for all users places the Jenkins software in a more controlled space than a User's home directory, where hostile actors are less likely to be able to maliciously modify the Jenkins software to do something bad (provided the user running the LaunchAgent is not a system administrator). Generally you should always prefer to install software for all users, even if only one user will ever use it.

          Randall Wood added a comment - Using a LaunchAgent introduces a security vulnerability (automatically logged in user at console) on the Mac running the LaunchAgent, so any user installing that should explicitly do so. @cowwoc - Installing Jenkins for all users places the Jenkins software in a more controlled space than a User's home directory, where hostile actors are less likely to be able to maliciously modify the Jenkins software to do something bad (provided the user running the LaunchAgent is not a system administrator). Generally you should always prefer to install software for all users, even if only one user will ever use it.

          cowwoc added a comment -

          @randall

          I don't buy the security argument for two reasons:

          1. There will always be security exploits. Security is a bottomless pit. As such, you are chasing more of a theoretical problem than a concrete one.
          2. We know for a fact that using ~/LaunchAgents fixes a much-needed use-case that cannot be run with LaunchDaemons.
          3. I would be more than happy to use a more secure solution if it was possible; but (as far as I can tell) it is not.

          Now, more concretely...

          • The login plist/hook approaches force control back to the login screen immediately after logging in. How would you exploit that?
          • I agree that we should get user consent for installing Jenkins. If anyone chooses to install it on their machine, we can (and should) explain what username will get used and that autologin will take place.
          • Installing for "All Users": I still don't understand how this is more secure, but even if it is ... we'd still need to find a way to ensure that Jenkins doesn't run multiple times per computer. If my wife and I share the same computer, and each has their own profile, we don't want Jenkins to launch dialogs every time we log in.

          cowwoc added a comment - @randall I don't buy the security argument for two reasons: There will always be security exploits. Security is a bottomless pit. As such, you are chasing more of a theoretical problem than a concrete one. We know for a fact that using ~/LaunchAgents fixes a much-needed use-case that cannot be run with LaunchDaemons. I would be more than happy to use a more secure solution if it was possible; but (as far as I can tell) it is not. Now, more concretely... The login plist/hook approaches force control back to the login screen immediately after logging in. How would you exploit that? I agree that we should get user consent for installing Jenkins. If anyone chooses to install it on their machine, we can (and should) explain what username will get used and that autologin will take place. Installing for "All Users": I still don't understand how this is more secure, but even if it is ... we'd still need to find a way to ensure that Jenkins doesn't run multiple times per computer. If my wife and I share the same computer, and each has their own profile, we don't want Jenkins to launch dialogs every time we log in.

          Sami Tikka added a comment -

          When the user requests the Installer to install something for all users, it prompts the user for admin password and elevates permissions to root, making it possible to install Jenkins as a launch daemon. But this is only relevant if we want to keep the possibility of installing as launch daemon.

          But like I said, I do not look forward to tweaking PackageMaker to achieve many different ways of installing Jenkins to suite everyone's needs.

          IMHO the PackageMaker based installer is only suitable for one kind of installation with no options at all. (The current Installer has a few options but I'm sure no-one has found them or uses those.)

          If a more customizable installer is required, it must be based on something else. My favorite is a simple AppleScript application.

          Sami Tikka added a comment - When the user requests the Installer to install something for all users, it prompts the user for admin password and elevates permissions to root, making it possible to install Jenkins as a launch daemon. But this is only relevant if we want to keep the possibility of installing as launch daemon. But like I said, I do not look forward to tweaking PackageMaker to achieve many different ways of installing Jenkins to suite everyone's needs. IMHO the PackageMaker based installer is only suitable for one kind of installation with no options at all. (The current Installer has a few options but I'm sure no-one has found them or uses those.) If a more customizable installer is required, it must be based on something else. My favorite is a simple AppleScript application.

          Sami Tikka added a comment -

          We might want to gather some requirements or user stories for the Jenkins Mac installer.

          My humble opinion is the only people who want to run Jenkins on Mac are iOS developers. (And Mac developers but there are few of those and their needs might be very similar to iOS developers.)

          People who do cross-platform development and need to build their software for multiple platforms need to set up Windows, Mac and Linux build servers. They will probably run Jenkins master either on Windows or Linux and run a slave on Mac. Thus we do not need to worry about these people.

          The iOS developers have some special needs (which I do not know exactly because I haven't done any real development for iOS so feel free to add to the list or set me straight.)

          • Builds must be codesigned. The developer certificate resides in the developer's keychain. The keychain is only accessible within the developer's GUI login session.
          • Automated tests need to execute iOS simulator which is a GUI app. GUI apps can only run in GUI login session.

          It seems to me the most common use cases for Jenkins master on Mac require that Jenkins has access to GUI login session. This means Jenkins master must be executed either as a launch agent (which are meant for background processes) or within a context of a GUI app wrapper (if we want something visible in Dock or menu bar.)

          The security aspect of having a Jenkins master with a logged-in user with a GUI session must be addressed separately. I do not believe we can provide a solution that fits everyone's needs. Maybe we can just give hints on how to solve it: put the Mac in a locked room, set up screensaver with short timeout or the trick mentioned above in the ticket description or maybe something else.

          Sami Tikka added a comment - We might want to gather some requirements or user stories for the Jenkins Mac installer. My humble opinion is the only people who want to run Jenkins on Mac are iOS developers. (And Mac developers but there are few of those and their needs might be very similar to iOS developers.) People who do cross-platform development and need to build their software for multiple platforms need to set up Windows, Mac and Linux build servers. They will probably run Jenkins master either on Windows or Linux and run a slave on Mac. Thus we do not need to worry about these people. The iOS developers have some special needs (which I do not know exactly because I haven't done any real development for iOS so feel free to add to the list or set me straight.) Builds must be codesigned. The developer certificate resides in the developer's keychain. The keychain is only accessible within the developer's GUI login session. Automated tests need to execute iOS simulator which is a GUI app. GUI apps can only run in GUI login session. It seems to me the most common use cases for Jenkins master on Mac require that Jenkins has access to GUI login session. This means Jenkins master must be executed either as a launch agent (which are meant for background processes) or within a context of a GUI app wrapper (if we want something visible in Dock or menu bar.) The security aspect of having a Jenkins master with a logged-in user with a GUI session must be addressed separately. I do not believe we can provide a solution that fits everyone's needs. Maybe we can just give hints on how to solve it: put the Mac in a locked room, set up screensaver with short timeout or the trick mentioned above in the ticket description or maybe something else.

          Randall Wood added a comment -
          • All login plist/hooks can be disabled when accessing the console of a OS X system that is being restarted. I know that a number of users of Jenkins on OS X are using Jenkins on systems that may be installed in areas not under the administrator's physical control. This is a real concern for many OS X developers who are not completely independent.
          • Software that exists in a user's directory is always easier to exploit than software installed using root privileges.

          Randall Wood added a comment - All login plist/hooks can be disabled when accessing the console of a OS X system that is being restarted. I know that a number of users of Jenkins on OS X are using Jenkins on systems that may be installed in areas not under the administrator's physical control. This is a real concern for many OS X developers who are not completely independent. Software that exists in a user's directory is always easier to exploit than software installed using root privileges.

          Randall Wood added a comment -

          @Sami Tikka:

          The only need addressed by running Jenkins in a GUI login session is running automated tests in the iOS simulator.
          Code signing for iOS and OS X builds can be done entirely from the CLI, even remotely over SSH.

          Randall Wood added a comment - @Sami Tikka: The only need addressed by running Jenkins in a GUI login session is running automated tests in the iOS simulator. Code signing for iOS and OS X builds can be done entirely from the CLI, even remotely over SSH.

          Sami Tikka added a comment -

          @Randall: OK, so it can be done, but is it well documented and supported by Xcode? If it's not, lots of programmers are going to try building their iOS projects on Jenkins and will be unhappy. If it just works, then we should be good with the existing installer that sets up a launch daemon. Apparently there are complications because there used to be lots of people asking how to get signing to work when building under Jenkins. (There might still be but I have been away from Jenkins community for a while.)

          Well, there's the iOS simulator... What do we do about that?

          Sami Tikka added a comment - @Randall: OK, so it can be done, but is it well documented and supported by Xcode? If it's not, lots of programmers are going to try building their iOS projects on Jenkins and will be unhappy. If it just works, then we should be good with the existing installer that sets up a launch daemon. Apparently there are complications because there used to be lots of people asking how to get signing to work when building under Jenkins. (There might still be but I have been away from Jenkins community for a while.) Well, there's the iOS simulator... What do we do about that?

            Unassigned Unassigned
            cowwoc cowwoc
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated: