diff options
author | Dmitry Bogatov <KAction@gnu.org> | 2016-08-14 08:19:08 +0300 |
---|---|---|
committer | Dmitry Bogatov <KAction@gnu.org> | 2016-08-14 08:19:18 +0300 |
commit | d912ba4f2edbcd72c4750222e9870fb10b95b874 (patch) | |
tree | 03e567b5f5d9e3a981e0673b791d117790754285 /dh_runit | |
parent | 166847db96a66828c9cc6e2b501a50d204b4597b (diff) |
* Breaking change package.runit file format to improve interoperability
with other tools (supply dh_runit arguments on command line) and make
format extensible. See dh_runit(1).
* Introduce support for automatic generation of log scripts.
Diffstat (limited to 'dh_runit')
-rwxr-xr-x | dh_runit | 184 |
1 files changed, 135 insertions, 49 deletions
@@ -1,53 +1,28 @@ | |||
1 | #!/usr/bin/perl -w | 1 | #!/usr/bin/perl -w |
2 | 2 | ||
3 | =head1 NAME | ||
4 | |||
5 | dh_runit - install/enable runit runscripts | ||
6 | |||
7 | =cut | ||
8 | 3 | ||
4 | use v5.10.1; | ||
9 | use strict; | 5 | use strict; |
10 | use Debian::Debhelper::Dh_Lib; | 6 | use Debian::Debhelper::Dh_Lib; |
11 | use File::Find; | 7 | use File::Find; |
12 | use File::stat; | 8 | use File::stat; |
13 | use feature 'signatures'; | 9 | use feature 'signatures'; |
14 | no warnings 'experimental::signatures'; | 10 | no warnings 'experimental'; |
15 | 11 | ||
16 | =head1 SYNOPSIS | 12 | sub parse_options($opts) { |
17 | 13 | my $conf = { enable => 1 }; | |
18 | B<dh_runit> [S<I<debhelper options>>] | 14 | for my $opt (split(/,/, $opts)) { |
19 | 15 | given($opt) { | |
20 | =head1 DESCRIPTION | 16 | when (/^disable$/) { $conf->{enable} = 0; }; |
21 | 17 | when (/^name=(.*)$/) { $conf->{name} = $1; }; | |
22 | B<dh_runit> is a debhelper program that is responsible for | 18 | when (/^logscript$/) { $conf->{logscript} = 1}; |
23 | installing and enabling I<runit> runscripts. If file named | 19 | when (/^logdir=(.*)$/) { $conf->{logdir} = $1 }; |
24 | F<debian/I<package>.runit> exists, then different actions | 20 | when (/^defaults$/) { "do nothing"; }; |
25 | are performed, depending on its format. | 21 | default { error("unknown option `$opt'"); } |
26 | 22 | } | |
27 | For runit, every unit of supervision, simply speaking program, is | 23 | } |
28 | represented by directory under F</etc/sv>, containing at least F<run> | 24 | return $conf; |
29 | executable file. Every enabled program is represented by symbolic link | 25 | } |
30 | under F</etc/services> pointing to some directory under F</etc/sv>. | ||
31 | |||
32 | F<debian/I<package>.runit> is a list of lines, where | ||
33 | every line is either starts with hash symbol and considered comment, | ||
34 | or contains two or three space-separated words. | ||
35 | |||
36 | # In this case file is installed as 'run' script. Directory name under | ||
37 | # /etc/sv is derived from file basename | ||
38 | enable path/to/file/to/be/installed/as/run/script | ||
39 | |||
40 | # Same, but install directory as whole. It is your responsibility | ||
41 | # to ensure is contains everything required. | ||
42 | enable path/to/directory | ||
43 | |||
44 | # Same as above, but do not create symlink under /etc/service | ||
45 | disable path/to/directory | ||
46 | |||
47 | # Also, you can explicitly specify name of directory under /etc/sv | ||
48 | enable path/to/directory my-preferred-name | ||
49 | |||
50 | =cut | ||
51 | 26 | ||
52 | sub ensure_executable($directory) { | 27 | sub ensure_executable($directory) { |
53 | for my $f ('run', 'finish', 'log/run', 'log/finish') { | 28 | for my $f ('run', 'finish', 'log/run', 'log/finish') { |
@@ -65,20 +40,28 @@ init(); | |||
65 | PKG: foreach my $pkg (@{$dh{DOPACKAGES}}) { | 40 | PKG: foreach my $pkg (@{$dh{DOPACKAGES}}) { |
66 | next if is_udeb($pkg); | 41 | next if is_udeb($pkg); |
67 | 42 | ||
43 | my @entries = (); | ||
44 | if (my $pkgfile = pkgfile($pkg, 'runit')) { | ||
45 | @entries = filedoublearray($pkgfile); | ||
46 | } | ||
47 | while (@ARGV) { | ||
48 | (my $path, my $opts) = splice(@ARGV, 0, 2); | ||
49 | push @entries, [$path, $opts]; | ||
50 | } | ||
51 | |||
68 | my $tmp = tmpdir($pkg); | 52 | my $tmp = tmpdir($pkg); |
69 | my $sv_dir = "$tmp/etc/sv"; | 53 | my $sv_dir = "$tmp/etc/sv"; |
70 | my $runit = pkgfile($pkg, 'runit'); | ||
71 | next unless $runit; | ||
72 | 54 | ||
73 | runit_autoscript($pkg, 'preinst', ''); | 55 | runit_autoscript($pkg, 'preinst', ''); |
74 | install_dir($sv_dir); | 56 | install_dir($sv_dir); |
75 | 57 | ||
76 | for my $words (filedoublearray($runit)) { | 58 | for (@entries) { |
77 | (my $enable, my $path, my $name) = @{$words}; | 59 | (my $path, my $opts) = @$_; |
78 | $name = $name || basename($path); | ||
79 | |||
80 | error("can't read `$path'") unless -r $path; | 60 | error("can't read `$path'") unless -r $path; |
81 | 61 | ||
62 | my $conf = parse_options($opts); | ||
63 | my $name = $conf->{name} || basename($path); | ||
64 | |||
82 | if ( -f $path) { | 65 | if ( -f $path) { |
83 | install_dir("$sv_dir/$name"); | 66 | install_dir("$sv_dir/$name"); |
84 | install_prog($path, "$sv_dir/$name/run"); | 67 | install_prog($path, "$sv_dir/$name/run"); |
@@ -91,13 +74,116 @@ PKG: foreach my $pkg (@{$dh{DOPACKAGES}}) { | |||
91 | "/var/lib/runit/supervise/$name", $tmp); | 74 | "/var/lib/runit/supervise/$name", $tmp); |
92 | install_dir("$tmp/var/lib/runit/supervise/$name"); | 75 | install_dir("$tmp/var/lib/runit/supervise/$name"); |
93 | 76 | ||
94 | if ($enable eq 'enable' && !$dh{NO_ENABLE}) { | 77 | if ($conf->{enable}) { |
95 | runit_autoscript($pkg, 'postinst', "s/#NAME#/$name/"); | 78 | runit_autoscript($pkg, 'postinst', "s/#NAME#/$name/"); |
96 | } | 79 | } |
97 | runit_autoscript($pkg, 'prerm', "s/#NAME#/$name/"); | 80 | runit_autoscript($pkg, 'prerm', "s/#NAME#/$name/"); |
98 | runit_autoscript($pkg, 'postrm', "s/#NAME#/$name/"); | 81 | runit_autoscript($pkg, 'postrm', "s/#NAME#/$name/"); |
82 | if ($conf->{logscript}) { | ||
83 | my $logdir = $conf->{logdir} || "/var/log/runit/$name"; | ||
84 | $logdir = "$tmp/$logdir"; | ||
85 | |||
86 | install_dir("$sv_dir/$name/log"); | ||
87 | install_dir($logdir); | ||
88 | |||
89 | my $run_log = "$sv_dir/$name/log/run"; | ||
90 | my $log_user = $name . "log_"; | ||
91 | open(RUN_LOG, ">$run_log") || die $!; | ||
92 | print RUN_LOG "#!/bin/sh\n"; | ||
93 | print RUN_LOG "mkdir -p '$logdir'\n"; | ||
94 | print RUN_LOG "chown -R '$log_user' '$logdir'\n"; | ||
95 | print RUN_LOG "exec chpst -u '$log_user' svlogd -tt '$logdir'\n"; | ||
96 | close(RUN_LOG); | ||
97 | chmod(0755, $run_log); | ||
98 | doit('dh_sysuser', $log_user, 'defaults'); | ||
99 | } | ||
99 | } | 100 | } |
100 | addsubstvar($pkg, 'misc:Depends', 'runit', '>= 2.1.2-4'); | 101 | addsubstvar($pkg, 'misc:Depends', 'runit', '>= 2.1.2-4'); |
101 | } | 102 | } |
102 | 103 | ||
103 | # PROMISE: DH NOOP WITHOUT runit | 104 | # PROMISE: DH NOOP WITHOUT runit |
105 | |||
106 | =head1 NAME | ||
107 | |||
108 | dh_runit - install/enable runit runscripts | ||
109 | |||
110 | =head1 SYNOPSIS | ||
111 | |||
112 | B<dh_runit> [S<I<debhelper options>>] [I<path> I<options>] ... | ||
113 | |||
114 | =head1 DESCRIPTION | ||
115 | |||
116 | B<dh_runit> is a debhelper program that is responsible for | ||
117 | installing and enabling I<runit> runscripts. If file named | ||
118 | F<debian/I<package>.runit> exists, then different actions | ||
119 | are performed, depending on its format. | ||
120 | |||
121 | For runit, every unit of supervision, simply speaking program, is | ||
122 | represented by directory under F</etc/sv>, containing at least F<run> | ||
123 | executable file. Every enabled program is represented by symbolic link | ||
124 | under F</etc/services> (which itself is symbolic link to | ||
125 | F</etc/runit/runsvdir/default>) pointing to some directory under | ||
126 | F</etc/sv>. | ||
127 | |||
128 | B<dh_runit> reads it's arguments from command line and | ||
129 | F<debian/I<package>.runit> by two, with first one being an | ||
130 | file/directory and second one is options. If first argument is file, | ||
131 | it is considered 'run' script, and it is installed under | ||
132 | F</etc/sv/*/run>, executable bit is added. If first argument is | ||
133 | directory, it is copied as whole under F</etc/sv>. | ||
134 | |||
135 | Options are comma-separated, like to mount. Unsupported option | ||
136 | is error, following are supported: | ||
137 | |||
138 | =over | ||
139 | |||
140 | =item I<disable> | ||
141 | |||
142 | With this option, runscript is installed, but not enabled by | ||
143 | default. It means that corresponding service will not be started. | ||
144 | System administrator can always do it manually or via | ||
145 | update-service(8). | ||
146 | |||
147 | =item I<name>=preferred-name | ||
148 | |||
149 | By default, name of directory under F</etc/sv> for given runscript | ||
150 | is basename of first argument of pair. This option allows you to | ||
151 | be explicit about it. | ||
152 | |||
153 | =item I<logscript> | ||
154 | |||
155 | Install standard F<log/run> script, which invokes svlogd(8) with | ||
156 | rights of dedicated user. It is error, if first argument in pair | ||
157 | is directory, which already contains F</log/run> script. | ||
158 | |||
159 | =item I<logdir>=/path/to/log/directory | ||
160 | |||
161 | This option is meaningful only with I<logscript>. It allows | ||
162 | overriding default log directory F</var/log/runit/I<name>>. | ||
163 | |||
164 | =item I<defaults> | ||
165 | |||
166 | If you need no other options, put this one. | ||
167 | |||
168 | =back | ||
169 | |||
170 | =head1 EXAMPLES | ||
171 | |||
172 | This section contains several example snippets from F<I<package>.runit> | ||
173 | |||
174 | # In this case file is installed as 'run' script. Directory name under | ||
175 | # /etc/sv is derived from file basename | ||
176 | path/to/file/to/be/installed/as/run/script defaults | ||
177 | |||
178 | # Same, but install directory as whole. It is your responsibility | ||
179 | # to ensure is contains everything required. | ||
180 | path/to/directory defaults | ||
181 | |||
182 | # Same as above, but do not create symlink under /etc/service | ||
183 | path/to/directory disable | ||
184 | |||
185 | # You can explicitly specify name of directory under /etc/sv. | ||
186 | # Standard log/run script will be created. | ||
187 | path/to/directory name=my-preferred-name,logscript | ||
188 | |||
189 | =cut | ||