Start docker-machine On Boot - macos

I have a docker-machine called default. I am trying to get it to start upon boot. I can do it upon log in but I need it without having to log in.
I have put the following file in both /LaunchAgents/com.docker.machine.default.plist and /LaunchDaemons/com.docker.machine.default.plist, both of which aren't working.
/Library/LaunchDaemons/com.docker.machine.default.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>RunAtLoad</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
</dict>
<key>Label</key>
<string>com.docker.machine.default</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/docker-machine</string>
<string>start</string>
<string>default</string>
</array>
</dict>
</plist>
I have also run sudo chmod 640 on both files in case there was a permission issue as described here.
When I run, sudo launchctl load -w com.docker.machine.default.plist as described in the tutorial I get "service already loaded".
The service is definitely not running as I have checked using docker-machine ls and docker-machine status default and the machine is stopped on start up.
Update
I have added logging into my LaunchDaemon and get the following output.
Host does not exist: "default"
I then run docker-machine ls and I get:
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default - virtualbox Stopped Unknown
As you can see the machine is there. If I run docker-machine start default manually, it starts up fine...
Starting "default"...
(default) Check network to re-create if needed...
(default) Waiting for an IP...
Machine "default" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

Services from /Library/LaunchDaemons by default run as root user. root have no any docker machines. You can specify user (jenkins in my case) as
<key>UserName</key>
<string>jenkins</string>
For more documentation you can use man launchd.plist.
Full org.vovkasm.docker-machine.plist that I'am use for jenkins user:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
</dict>
<key>Label</key>
<string>org.vovkasm.docker-machine</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/opt/docker-machine/bin/docker-machine</string>
<string>start</string>
<string>default</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>/usr/local</string>
<key>UserName</key>
<string>jenkins</string>
</dict>
</plist>

Related

How to start a launch agent on demand after the installation?

I've coded my launch daemon and a launch agent for macOS. When the app is installed, I need to run both the daemon and the agent. I place the .plist for the deamon into /Library/LaunchDaemons and then run (as admin):
launchctl load /Library/LaunchDaemons/com.example.MyDaemon.plist
and since the plist has:
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
the daemon starts up right away.
But I'm struggling to do the same with my launch agent. Here's it's plist that I place into /Library/LaunchAgents directory for it to start for every user and also in the login screen:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
<string>LoginWindow</string>
</array>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>com.example.MyAgent.plist</string>
<key>Program</key>
<string>/Library/PrivilegedHelperTools/com.example/MyAgent</string>
<key>ProgramArguments</key>
<array>
<string>-d</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
when I try to run it as:
launchctl load /Library/LaunchAgents/com.example.MyAgent.plist
I get an error:
Warning: Expecting a LaunchDaemons path since the command was ran as
root. Got LaunchAgents instead. launchctl bootstrap is a recommended
alternative. /Library/LaunchAgents/com.example.MyAgent.plist:
Path had bad ownership/permissions Load failed: 122: Path had bad
ownership/permissions
what am I doing wrong?

Launch daemon in MacOs only once on boot

I cant make daemon launches only one time on startup.
I created file /Library/LaunchDaemons/local.gz.startup.plist
Then I run loaded it with launchd command
<?xml version="1.0" encoding=="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
“http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.gz.startup</string>
<key>ProgramArguments</key>
<array>
<string>/etc/rc.local</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
rc.local:
#!/bin/bash
sudo mkdir /Volumes/ESP
sudo mount -t msdos /dev/disk0s1 /Volumes/ESP/
....
sudo umount -f /Volumes/ESP/
exit
This works only when I load it manually with launchd command, not at startup.
I have tried another parameters, but it (rc.local) begins work continuously, it mounts and unmounts /dev/disk0s1.
How can I make it start only once on boot?

Luanchd not starting mopidy & UDP listener

I'm trying to write a Launchd script to execute a simple sh script that will 1) launch mopidy 2) mkfifo /tmp/mopidy.fifo 3) pass data from port 5555 into this file using socat.
I've tried setting up a mopidy.plist LaunchAgent that executes a mopidy.sh script file at login. I've verified that the LaunchAgent gets started correctly and that the script has execution permissions. I've also tried the Program Arguments approach by passing the script as a one-liner to /bin/bash, but when I try that I get errors logged saying that its unable to find socat.
mopidy.sh
nohup mopidy;
mkfifo /tmp/mopidy.fifo;
while :; do
socat -d -d -T 1 -u UDP4-LISTEN:5555 OPEN:/tmp/mopidy.fifo;
done
mopidy.plist
<!-- Starts mopidy server -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.me.mopidy.plist</string>
<key>Program</key>
<string>/Users/me/.config/scripts/mopidy.sh</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/me/logfile.log</string>
<key>StandardErrorPath</key>
<string>/Users/me/error_logfile.log</string>
</dict>
</plist>
I am able to execute the bash script normally without error from the command line, however it doesn't seem like the service is able to because the /tmp/modipy.fifo file never gets created and the listener is never made. The logfile and error_logfile are never populated either.
I was able to get it working by including environment variables. I don't fully understand this, but everything works now with the following:
<!-- Starts mopidy server -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.me.mopidy.plist</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/me/.config/scripts/mopidy.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/me/logfile.log</string>
<key>StandardErrorPath</key>
<string>/Users/me/error_logfile.log</string>
</dict>
</plist>

Launch Agent Not Starting

I’m trying to make a launch agent that starts a Python script. It should run when there’s a network connection but it doesn’t do that. launchctl list says it’s loaded:
launchctl list | grep test.Flopsey.DiscordMusicBot
- 0 test.Flopsey.DiscordMusicBot
When I start it with launchctl start test.Flopsey.DiscordMusicBot it works fine. The .plist file (which is stored under ~/Library/LaunchAgents) looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>test.Flopsey.DiscordMusicBot</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5</string>
<string>/path/to/MusicBot/run.py</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/bin:/usr/bin:/usr/local/bin</string>
</dict>
<key>StandardOutPath</key>
<string>/path/to/MusicBot/log.log</string>
<key>StandardErrorPath</key>
<string>/path/to/MusicBot/log.log</string>
<key>WorkingDirectory</key>
<string>/path/to/MusicBot</string>
<key>KeepAlive</key>
<dict>
<key>NetworkState</key>
<true/>
</dict>
</dict>
</plist>
I’m new to launchd and I followed this tutorial. I think the solution to my problem is very basic but I have no idea what it could be. I’ve also made another similar agent and it works fine (unlike the music bot it’s only one file).
Update
Thanks to #LCC’s comment I realised that using NetworkState doesn’t work anymore on OS X 10.10 and higher. Since the script exits when it can’t connect to the Internet I can just set KeepAlive to <true/> and set up a ThrottleInterval so launchd restarts the script after a cooldown if it couldn’t connect.

Mac launch daemon keeps loading the firewall shell script

Launch daemon worked as it should but now the problem is it keeps loading the same shell script and I can see multiple entries for the same rule. sudo ipfw list. How can this be prevented?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.ipfw</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/local/ipfw.apple.startup.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceDescription</key>
<string>Apple IPFW Filter Rules</string>
<key>StandardErrorPath</key>
<string>/var/log/ipfw.apple.stderr</string>
<key>StandardOutPath</key>
<string>/var/log/ipfw.apple.stdout</string>
<key>UserName</key>
<string>root</string>
</dict>
Use LaunchOnlyOnce key in plist file.
LaunchOnlyOnce :
This optional key specifies whether the job can only be run once and only once. In other words, if the
job cannot be safely respawned without a full machine reboot, then set this key to be true.

Resources