Launch User App with GUI from Launch Daemon - xcode

I've got a Launch Daemon that runs as root outside of the user context. This Daemon is always running and monitoring a server. On occasion, my Daemon will get a command from the server telling it to display something to the user. Obviously I can't do this from a Launch Daemon since it's not running in a "WindowsServer" environment - so the other option is to spawn a separate process for each user that has access to be able to display a GUI.
One option I have is to make a Launch Agent and have the OS start it up for me. The launch agent could then communicate with the Launch Daemon to determine when something needs to be displayed.
The problem is this though: the server will sometimes provide updates of the actual binary files. So the server would send the Launch Daemon a series of files which it is expected to copy out on top of the existing files. If I have a Launch Agent running, how can I shut it down so that the agent itself can be updated? Likewise, how could I start the Agent back up after the update is done?

Off the cuff, I would say that you should arrange a way for your daemon to request the launch agent to exit on demand, the same way you would arrange for it to launch on demand. Once you know the agent has exited, your daemon can proceed with the update.
Note that your agent probably should not live forever, and it should definitely not be polling the daemon for work. Instead, you should rig it up so that, when the daemon tries to connect to the agent, launchd launches the agent. You could do this by having the daemon connect to a Unix domain socket registered on behalf of the agent by launchd, for example.
You might do better to look at how Google's UpdateEngine handles software updates. I believe it too has a launch daemon perform the app updates. Since this is already working on many computers, its solution to software update problems is a proven one. (Sparkle's solution is thoroughly proven, as well, but it relies on user interaction, which you seem to want to avoid.)

Related

Launchd flow of spawning new processes

I'm doing some research about the way launchd load it's services from plist files under /Library/LaunchDaemons/ or via the command launchctl load
So far I've managed to gather some various sources and compose the following vague picture as I understand it:
Upon Service loading (launchctl load) The process launchctl send the launchd an appropriate XPC message, and then the launchd is forked into new process with the context of xpcproxy.
This generic process, is waiting for another XPC call from the launchd to run it's real process context according to the launchDaemon plst.
Is this explanation sounds right ? perhaps anybody can help me make it more accurate ?
thanks
This is actually a bit more complicated. The kernel is composed of two parts, BSD and the mach kernel; the latter being responsible for management of memory and process scheduling.
Each mach process has one or more mach tasks (really task port rights!). When an application is first launched, it has just one right, the bootstrap port, allowing communication with launchd. Note that a task port right is uni-directional, so a launching process that has the right to communicate with launchd must give a right for launchd to communicate back to it.
When an XPC message is received by launchd, it depends upon the Launch Daemon as to what action it takes. It's possible that the message is for a service that runs with a network port that may or may not be running. If running, it forwards any arguments from the calling process to the running service. If not running, it can provide the service on demand by launching the process first.
More specifically you asked about launchctl load. Since the source code for launchd is no longer open source, the next best resource is the reverse engineering work by Jonathan Levin; Author of Mac OS X and iOS Internals and more recently, his newer self-published books on *OS Internals.
You'll find his slides about launchd here, but probably more useful to you is his version of launchctl, jlaunchctl which is open source.
Finally, if you want to view content of XPC messages between processes, disable SIP and use Jonathan's invaluable XPoCe tool.

How to prevent my process from being killed on logout in Windows?

How can I allow my process to persist after logout and not be killed, preferably without requiring the process to have administrator privileges? I am unable to use a service/scheduled task due to some peculiarities in the program.
The correct way to achieve this is through a Windows service. They are designed to run while the machine is on, independent of any interactive user logins.
You state in an edit that you aren't able to use a service. If that really is true then your task is not viable. My guess is that if you design your service correctly, perhaps interacting with a companion desktop app, then a service is perfectly feasible.

Automating TestStack.White UI Testing in Windows Slave using Jenkins

First of all, I apologize if I am wasting your time, because it looks like a simple step which I am not able to figure out even after some research.
Ok, here is what I am trying to achieve, I have written some UI tests using TestStack.White, I would like to execute this on a Jenkins Slave as different user, since the application behaves differently based on the roles that are assigned to them in Active Directory.
So after doing a bit of lookup on google I found the following links which are relevant to what I am trying to achieve.
http://teststackwhite.readthedocs.io/en/latest/AdvancedTopics/ContinuousIntegration/
How to get Sikuli working in headless mode
Jenkins on Windows and GUI Tests without RDC
It looks like that I have to install TightVNC on Jenkins slave and should connect to slave from Jenkins Master and execute tests on slave.
Which brings me to my first question, how do I exactly achieve this from a Jenkins job?
About logging in as different users, I understand I can use to "autologon.exe" to achieve this. So just wondering how I can do this on the Windows Slave from Jenkins Master. My company doesn't allow SSH to Windows instances (slave machines), I cannot remotely execute SSH from Jenkins Master.
I understand that I may not be looking at this correctly, so any help would be much appreciated.
Thanks in advance for your time and advice.
I am getting ready to do something similar to this but I am building a communication layer into our UI Automation application so that our build machine (our company rolled our own build machine) can send TCP request back and forth. I am going to deploy the UI Automation and the build to a share then start a virtual machine. The build machines template will have a startup script that launches both our applications from the share. Once the virtual machine is started then I am going to communicate with the UI Automation application to tell it to start and it will tell me when its done so I can tear down the VM. I am going to save all the test results out to a share for reporting purposes.
I know this doesn't directly answer your question but this approach is one I have heard about from multiple people working in various automation frameworks.
If I was going to do this in Jenkins I would look into Jenkins plugin system. The plugin system as far as I know uses Java so you should be able to create some type of communication layer and interface with some type of VM. If you don't have the option to start and stop a VM you will need to look into start and stopping processes on a remote machine while masquerading as a user. I know this can be done in C# but I have never looked into it in Java.
Thanks all for your comments and answers, basically this is what I did to get it working for me,
Establish VNC connection with a VNC Client on Jenkins slave, this was done manually not through Jenkins.
Use an app called "Caffeine" to prevent windows from locking out, it simulates a key up event on F15 (every xx seconds) so there is no interruption with testing task in my project.
Launch JNLP connection to the Jenkins Master and "Caffeine" app as a part of windows logon through VNC Connection.
Close out of the VNC connection (not logging off), this was done manually not through Jenkins.
Let the build run as different users using PSExec on the slaves.
This seems to be working fine so far, I didn't reply sooner since I wanted to monitor the jobs for a few days before posting my reply here.

Can Kernel Control API support multiple, simultaneous client connections?

I'm using the Kernel Control API (SYSPROTO_CONTROL) for a user-land application to request information from a kernel extension, based on the code in Apple's documentation.
All works as expected with a single connected client. If a 2nd client tries to connect whilst the first is connected, it fails with the message: -
Error 16 (Resource busy).
The first client is then automatically disconnected.
Is it possible for two clients to be connected using the Kernel Control API and if not, is the best solution to keep trying to connect if the resource is busy?
I don't know if it is possible but the recommend way is to always only have one user space client that talks to one kernel extension, usually a background daemon running in user space and started by launchd. If you want multiple other apps or processes to access data from your kernel extension or somehow interact with it, then these would talk to the user space daemon and not directly to the kernel extension, which can also cache data in user space as crossing the users space/kernel space bridge is always expensive for data, so when 10 processes all want the same data, it would be better to just pull it once from the kernel and then distribute it 10 times in user space using any IPC mechanism of your choice.
This setup is recommend as you should limit kernel control to root processes (using the CTL_FLAG_PRIVILEGED flag), so your daemon would run as such a root process, whereas normal apps and processes run with the privileges of the current user. Such a root helper daemon can be bundled inside an app bundle and using the SMJobBless API, the daemon is automatically copied to /Library/PrivilegedHelperTools and it's embedded plist (see SMJobBless documentation, which is only available in its header file AFAIK) is copied to /Library/LaunchDaemons and registered with launchd. Within such a plist you can use various triggers when the daemon shall be started by launchd, e.g. when your application tries to connect to a specific IPC UNIX socket. Then all you have to do in your app is trying to open that socket, what launchd will detect and start the daemon for you, which can then use launchd's API to get hold of that connected socket and immediately start talking with your app. So the whole thing is only installed once and then brings up itself each time your app is launched.
For a SMJobBless sample project, see here.

In Windows 7, how to send a Ctrl-C or Ctrl-Break to a separate process

Our group has long running processes which run daily. The processes are typically started at 9pm on any given day and run until 7pm the next day. Thus they typically run 22hrs/day. They are started by scheduled tasks on servers under a particular generic user ID, and they start and run regardless of whether or not that user ID is logged on. Thus, they are windowless console executables.
The tasks orchestrate computations running on a large server farm. Generally these controlling tasks run uninterrupted for the full 22hrs/day. However, we often have a need to stop and restart these processes. Because they control a multitude of tasks running on our server farm, it is important that they be shut down cleanly, so that they can stop and shut down all the server farm processes. Which brings me to our problem.
The controlling process has been programmed to respond to ctrl-C and ctrl-break signals. This works fine when the process is manually started in a console where we have access to the console and can "type" ctrl-c or ctrl-break in the console window. However, as mentioned, the processes typically run as windowless scheduled tasks. Hence we cannot "type" anything into a non-existent console window. Because they are console processes that execute without a logon process, the also must be able to execute in a completely windowless environment. So, how do we set up the process to listen for a shut-down signal?
While the process does indeed listen for a ctrl-C and ctrl-break signal, I can see no way to send that signal to a process. This seems to be a fundamental problem in Windows, or am I wrong? I am aware of SendSignal.exe, but so far have been unable to get it to work. It fails as follows:
>SendSignal 26320
Sending signal to process 26320...
CreateRemoteThread failed with 0x00000005.
StartRemoteThread failed with 0x00000005.
0x00000005 == Access is denied.
Trying "taskkill" without -F results in:
>taskkill /PID 24840
ERROR: The process with PID 24840 could not be terminated.
Reason: This process can only be terminated forcefully (with /F option).
All other "kill" functions kill the process immediately rather than sending a signal.
One possible solution would be a file-watch based solution: create a watch for some modification of a specific file. But this is a hack and we would prefer to do it with appropriate signaling. Has anyone solved this issue? It seems to be so very basic a functionality, and it is certainly trivial to do it in a Unix environment. Surely Microsoft has provided SOME mechanism to allow clean shut down of a windowless executable?
I am aware of the thread below, whose question is virtually identical (save for the specification of why the answer is necessary, i.e. why one needs to be able to do this for a windowless, console-less process), but there is no answer there excpet for "use SendSignal", which, as I said, does not work for us:
Can I send a ctrl-C (SIGINT) to an application on Windows?
There are other similar questions, but no answers as yet.
Any help appreciated.
[Upgrading #Anon's comment to an answer for visibility]
windows-kill worked perfectly and managed to resolve access denial issues faced with SendSignal. A privileged user would have to run it as well of course.
windows-kill also supports both ctrl-c and ctrl-break signals.

Resources