Skip to content

Commit 99644c4

Browse files
committed
add supervisor support
1 parent 987376f commit 99644c4

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed

src/robot_upstart/install_script.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def get_argument_parser():
6262
help="Specify an a value for ROS_LOG_DIR in the job launch context.")
6363
p.add_argument("--augment", action='store_true',
6464
help="Bypass creating the job, and only copy user files. Assumes the job was previously created.")
65-
p.add_argument("--provider", type=str, metavar="[upstart|systemd]",
65+
p.add_argument("--provider", type=str, metavar="[upstart|systemd|supervisor]",
6666
help="Specify provider if the autodetect fails to identify the correct provider")
6767
p.add_argument("--symlink", action='store_true',
6868
help="Create symbolic link to job launch files instead of copying them.")
@@ -71,6 +71,9 @@ def get_argument_parser():
7171
p.add_argument("--systemd-after", type=str, metavar="After=",
7272
help="Set the string of the After= section"
7373
"of the generated Systemd service file")
74+
p.add_argument("--supervisor-priority", type=int, metavar="Priority=",
75+
help="Set the value of the priority= section"
76+
"of the generated Supervisor conf file")
7477

7578
return p
7679

@@ -89,7 +92,8 @@ def main():
8992
name=job_name, interface=args.interface, user=args.user,
9093
workspace_setup=args.setup, rosdistro=args.rosdistro,
9194
master_uri=args.master, log_path=args.logdir,
92-
systemd_after=args.systemd_after)
95+
systemd_after=args.systemd_after,
96+
supervisor_priority=args.supervisor_priority)
9397

9498
for this_pkgpath in args.pkgpath:
9599
pkg, pkgpath = this_pkgpath.split('/', 1)
@@ -121,6 +125,8 @@ def main():
121125
provider = providers.Upstart
122126
if args.provider == 'systemd':
123127
provider = providers.Systemd
128+
if args.provider == 'supervisor':
129+
provider = providers.Supervisor
124130
if args.symlink:
125131
j.symlink = True
126132

src/robot_upstart/job.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class Job(object):
4141

4242
def __init__(self, name="ros", interface=None, user=None, workspace_setup=None,
4343
rosdistro=None, master_uri=None, log_path=None,
44-
systemd_after=None):
44+
systemd_after=None, supervisor_priority=None):
4545
"""Construct a new Job definition.
4646
4747
:param name: Name of job to create. Defaults to "ros", but you might
@@ -105,6 +105,10 @@ def __init__(self, name="ros", interface=None, user=None, workspace_setup=None,
105105
# of the generated Systemd service file
106106
self.systemd_after = systemd_after or "network.target"
107107

108+
# Set the value of the "priority=" section
109+
# of the generated Supservisor conf file
110+
self.supervisor_priority = supervisor_priority or 200
111+
108112
# Set of files to be installed for the job. This is only launchers
109113
# and other user-specified configs--- nothing related to the system
110114
# startup job itself. List of strs.

src/robot_upstart/providers.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ def detect_provider():
4040
print(os.path.realpath(cmd))
4141
if b'systemd' in os.path.realpath(cmd):
4242
return Systemd
43+
if b'supervisor' in os.path.realpath(cmd):
44+
return Supervisor
4345
return Upstart
4446

4547

@@ -228,3 +230,78 @@ def _fill_template(self, template):
228230
self.interpreter.file(f)
229231
return self.interpreter.output.getvalue()
230232
self.set_job_path()
233+
234+
235+
class Supervisor(Generic):
236+
""" The Supervisor implementation places the user-specified files in ``/etc/ros/DISTRO/NAME.d``,
237+
and creates an systemd job configuration in ``/lib/systemd/system/NAME.d``. Two additional
238+
helper scripts are created for starting and stopping the job, places in
239+
``/usr/sbin``.
240+
To detect which system you're using run: ps -p1 | grep systemd && echo systemd || echo upstart
241+
"""
242+
243+
def generate_install(self):
244+
# Default is /etc/ros/DISTRO/JOBNAME.d
245+
self._set_job_path()
246+
247+
# User-specified launch files.
248+
self._add_job_files()
249+
250+
# This is optional to support the old --augment flag where a "job" only adds
251+
# launch files to an existing configuration.
252+
if self.job.generate_system_files:
253+
# Share a single instance of the EmPy interpreter.
254+
self.interpreter = em.Interpreter(globals=self.job.__dict__.copy())
255+
256+
self.installation_files[os.path.join(self.root, "etc/supervisor/conf.d", self.job.name + ".conf")] = {
257+
"content": self._fill_template("templates/supervisor_job.conf.em"), "mode": 0o644}
258+
self.installation_files[os.path.join(self.root, "usr/sbin", self.job.name + "-start")] = {
259+
"content": self._fill_template("templates/job-start.em"), "mode": 0o755}
260+
self.installation_files[os.path.join(self.root, "usr/sbin", self.job.name + "-stop")] = {
261+
"content": self._fill_template("templates/job-stop.em"), "mode": 0o755}
262+
self.interpreter.shutdown()
263+
264+
# Add an annotation file listing what has been installed. This is a union of what's being
265+
# installed now with what has been installed previously, so that an uninstall should remove
266+
# all of it. A more sophisticated future implementation could track contents or hashes and
267+
# thereby warn users when a new installation is stomping a change they have made.
268+
self._load_installed_files_set()
269+
self.installed_files_set.update(list(self.installation_files.keys()))
270+
271+
# Remove the job directory. This will fail if it is not empty, and notify the user.
272+
self.installed_files_set.add(self.job.job_path)
273+
274+
# Remove the annotation file itself.
275+
self.installed_files_set.add(self.installed_files_set_location)
276+
277+
self.installation_files[self.installed_files_set_location] = {
278+
"content": "\n".join(self.installed_files_set)}
279+
280+
return self.installation_files
281+
282+
def post_install(self):
283+
print("** To complete installation please run the following command:")
284+
print(" sudo supervisorctl reload" +
285+
" && sudo supervisorctl status" +
286+
" ; browse https://localhost:9001")
287+
288+
def generate_uninstall(self):
289+
self._set_job_path()
290+
self._load_installed_files_set()
291+
292+
for filename in self.installed_files_set:
293+
self.installation_files[filename] = {"remove": True}
294+
295+
return self.installation_files
296+
297+
def _set_job_path(self):
298+
self.job.job_path = os.path.join(
299+
self.root, "etc/ros", self.job.rosdistro, self.job.name + ".d")
300+
301+
def _fill_template(self, template):
302+
self.interpreter.output = io.StringIO()
303+
self.interpreter.reset()
304+
with open(find_in_workspaces(project="robot_upstart", path=template)[0]) as f:
305+
self.interpreter.file(f)
306+
return self.interpreter.output.getvalue()
307+
self.set_job_path()

0 commit comments

Comments
 (0)