#!/usr/bin/perl -w use v5.10.1; use strict; use Debian::Debhelper::Dh_Lib; use File::Find; use File::stat; use feature 'signatures'; no warnings 'experimental'; sub parse_options($opts) { my $conf = { enable => 1 }; for my $opt (split(/,/, $opts)) { given($opt) { when (/^disable$/) { $conf->{enable} = 0; }; when (/^name=(.*)$/) { $conf->{name} = $1; }; when (/^logscript$/) { $conf->{logscript} = 1}; when (/^defaults$/) { "do nothing"; }; default { error("unknown option `$opt'"); } } } return $conf; } sub ensure_executable($directory) { for my $f ('run', 'finish', 'log/run', 'log/finish') { my $file = "$directory/$f"; doit('chmod', '+x', $file) if (-e $file); } } sub runit_autoscript($pkg, $script, $sed) { autoscript($pkg, $script, "$script-runit", $sed); } init(); PKG: foreach my $pkg (@{$dh{DOPACKAGES}}) { next if is_udeb($pkg); my @entries = (); if (my $pkgfile = pkgfile($pkg, 'runit')) { @entries = filedoublearray($pkgfile); } while (@ARGV) { (my $path, my $opts) = splice(@ARGV, 0, 2); push @entries, [$path, $opts]; } my $tmp = tmpdir($pkg); my $sv_dir = "$tmp/etc/sv"; install_dir($sv_dir); for (@entries) { (my $path, my $opts) = @$_; error("can't read `$path'") unless -r $path; my $conf = parse_options($opts); my $name = $conf->{name} || basename($path); if ( -f $path) { install_dir("$sv_dir/$name"); install_prog($path, "$sv_dir/$name/run"); } elsif ( -d $path) { doit('cp', '-r', $path, "$sv_dir/$name"); # Unfortunately, dh_fixperms does not handle executable bit here. ensure_executable("$sv_dir/$name"); } make_symlink("/etc/sv/$name/supervise", "/var/lib/runit/supervise/$name", $tmp); install_dir("$tmp/var/lib/runit/supervise/$name"); if ($conf->{enable}) { make_symlink("/etc/runit/runsvdir/default/$name", "/etc/sv/$name", $tmp); } runit_autoscript($pkg, 'postrm', "s/#NAME#/$name/"); if ($conf->{logscript}) { my $logdir = "/var/log/runit/$name"; install_dir("$sv_dir/$name/log"); install_dir($tmp . $logdir); my $run_log = "$sv_dir/$name/log/run"; my $log_user = "_log-". $name; open(RUN_LOG, ">$run_log") || die $!; print RUN_LOG << "HERE"; #!/bin/sh chown -R '$log_user' '$logdir' exec chpst -u '$log_user' svlogd -tt '$logdir' HERE close(RUN_LOG); chmod(0755, $run_log); doit('dh_sysuser', '-p', $pkg, $log_user, 'defaults'); make_symlink("/etc/sv/$name/log/supervise", "/var/lib/runit/log/supervise/$name", $tmp); install_dir("$tmp/var/lib/runit/log/supervise/$name"); } } addsubstvar($pkg, 'misc:Depends', 'runit', '>= 2.1.2-7'); addsubstvar($pkg, 'misc:Depends', 'runit-helper'); } # PROMISE: DH NOOP WITHOUT runit =head1 NAME dh_runit - install/enable runit runscripts =head1 SYNOPSIS B [S>] [I I] ... =head1 DESCRIPTION B is a debhelper program that is responsible for installing and enabling I runscripts. If file named F.runit> exists, then different actions are performed, depending on its format. For runit, every unit of supervision, simply speaking program, is represented by directory under F, containing at least F executable file. Every enabled program is represented by symbolic link under F (which itself is symbolic link to F) pointing to some directory under F. B reads it's arguments from command line and F.runit> by two, with first one being an file/directory and second one is options. If first argument is file, it is considered 'run' script, and it is installed under F, executable bit is added. If first argument is directory, it is copied as whole under F. Options are comma-separated, like to mount. Unsupported option is error, following are supported: =over =item I With this option, runscript is installed, but not enabled by default. It means that corresponding service will not be started. System administrator can always do it manually or via update-service(8). =item I=preferred-name By default, name of directory under F for given runscript is basename of first argument of pair. This option allows you to be explicit about it. =item I Install standard F script, which invokes svlogd(8) with rights of dedicated user. It is error, if first argument in pair is directory, which already contains F script. =item I If you need no other options, put this one. =back =head1 EXAMPLES This section contains several example snippets from F.runit> # In this case file is installed as 'run' script. Directory name under # /etc/sv is derived from file basename path/to/file/to/be/installed/as/run/script defaults # Same, but install directory as whole. It is your responsibility # to ensure is contains everything required. path/to/directory defaults # Same as above, but do not create symlink under /etc/service path/to/directory disable # You can explicitly specify name of directory under /etc/sv. # Standard log/run script will be created. path/to/directory name=my-preferred-name,logscript =cut