-
Notifications
You must be signed in to change notification settings - Fork 0
/
vo-support.pl.in
437 lines (318 loc) · 10.9 KB
/
vo-support.pl.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
#!/usr/bin/perl -w
# Copyright 2012 Stichting FOM
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This program implements a set of utility functions that may be
# used by packagers in the maintainer scripts (i.e. postinst),
# or by system administrator.
=head1 NAME
vo-support - manage virtual organisation configuration
=head1 SYNOPSIS
vo-support [--debug] [--confdir F<path>] [--sharedir F<path>]
{list-vos | list-modules | run-module I<module> {configure|deconfigure} I<VOs> |
configure-vo I<VOs> | deconfigure-vo I<VOs> |
add-module I<module> | remove-module I<module> }
vo-support --help
=cut
use strict;
use Getopt::Long;
use Pod::Usage;
use File::Copy;
use Site::Configuration::VO;
sub notimpl;
sub listvos;
=head1 DESCRIPTION
This utility interacts with the installed and configured Virtual Organisations (VOs)
on the system, and the special actions (triggers) that help to manage those
parts of the system that relate to them. Normally these triggers are called at
the right time by the system itself, for instance at the moment a VO package is
installed and configured, but the system administrator may choose to run them
at arbitrary times. In addition, this tool can report on the status of various
parts of the VO support system.
The VO support structure is maintained in two places:
=over
=item @datadir@/vo-support/vos/
This directory collects static information about the VOs which is not considered
site-specific or configurable. Data for any specific VO is recorded in a subdirectory
named after the VO.
Adding support for an additional VO is usually just a matter of installing an additional
package.
=item /etc/vo-support/vos/*.conf
Each configured VO has a single file named after it. For details on
the structure of these files see L<vo-config>. These files contain
site-local settings per VO, and may differ radically between sites
depending on local policies and structure.
=back
Typically each VO should be present in both locations, but configuration of a VO is
not easily automated through package management.
=cut
=head1 OPTIONS
The program accepts the following options:
=over
=item B<-d>, B<--debug>
Enter debugging mode. This generates diagnostic output to help
trace the source of difficulties.
=item B<-h>, B<--help>
This option shows the extended help text (which you are reading right
now, if you didn't find this helpful then your only hope is to read
the source code).
=item B<-c>, B<--confdir> F<directory>
Use an alternate configuration directory to look for VO configuration data.
The default is F</etc/vo-config/>. Each configured VO should have one file
in the F<vos> subdirectory named I<VO>.conf.
=item B<-s>, B<--sharedir> F<directory>
Override the static VO data directory (default is F<@datadir@/vo-support>).
For each VO there should be a subdirectory that contains VO-specific data.
=back
=cut
my $debug = 0;
my $help = 0;
my $vo = "";
my $fqan = "";
my $confdir = "";
my $sharedir = "";
GetOptions("debug" => \$debug,
"help" => \$help,
"confdir=s" => \$confdir,
"sharedir=s" => \$sharedir) or do {
pod2usage("Error parsing command line options.\n");
};
if ($help) {
pod2usage(-verbose => 2, -exitval => 0);
}
if (!$confdir) {
$confdir = "/etc/vo-support";
}
if (!$sharedir) {
$sharedir = "@datadir@/vo-support";
}
my $voconf = Site::Configuration::VO->new();
$voconf->confdir($confdir);
if ($debug) {
print STDERR "Entering debugging mode.\n";
}
my $command = $ARGV[0] or do {
pod2usage("$0 requires a command.\n");
};
shift;
=head1 COMMANDS
The program interprets the first non-option argument as the command to execute.
=cut
# The list of commands that this program understands. The keys of the
# hash are the commands as entered by the caller, the values are the names
# of the subroutines to call.
my %commands = ("list-vos" => \&listvos,
"list-modules" => \&listmodules,
"run-module" => \&runmodule,
"configure-vo" => \&configurevo,
"deconfigure-vo" => \&deconfigurevo,
"add-module" => \&addmodule,
"remove-module" => \&removemodule
);
if (! defined $commands{$command}) {
print STDERR "Command '$command' is unknown.\n";
exit 1;
}
if ( &{$commands{$command}}(@ARGV) ) {
exit 0;
} else {
exit 1;
}
=head2 list-vos
List installed and configured virtual organisations. This briefly lists the directories
in
@datadir@/vo-support/vos/
and the .conf files in
/etc/vo-support/vos
=cut
# List all the VO
sub listvos {
# list all the VOs in /usr/share/vo-support/vos
my @installedvos = <$sharedir/vos/*>;
print "Installed VOs in $sharedir/vos/\n\n";
for my $vodir (@installedvos) {
if (-d $vodir) {
$vodir =~ m{.*/([^/]*)};
print $1 . "\n";
}
}
# list all the VOs as configured in /etc/vo-support
my @configuredvos = <$confdir/vos/*.conf>;
print "\nConfigured VOs in $confdir/vos/\n\n";
for my $vo (@configuredvos) {
$vo =~ m{.*/([^/]*).conf$};
printf "%s\n", $1;
}
my @disabledvos = <$confdir/vos/*.conf-disabled>;
print "\nDisabled VOs in $confdir/vos/\n\n";
for my $vo (@disabledvos) {
$vo =~ m{.*/([^/]*).conf-disabled$};
printf "%s\n", $1;
}
}
sub enablevo {
my $vo = shift;
my $conffile = "$confdir/vos/$vo.conf";
my $conftemplate = "$sharedir/vos/$vo/$vo.conf";
return 1 unless ! -e $conffile;
if (-e $conffile . "-disabled") {
move $conffile . "-disabled", $conffile or die "Move failed: $!";
return 1;
}
if (-f $conftemplate) {
copy $conftemplate, $conffile or die "Copy failed: $!";
return 1;
} else {
printf STDERR "Cannot enable VO, missing configuration template %s\n",
$conftemplate;
return 0;
}
}
sub disablevo {
my $vo = shift;
print STDERR "disabling vo $vo\n" if $debug;
my $conffile = "$confdir/vos/$vo.conf";
return 1 unless -e $conffile;
move $conffile, $conffile . "-disabled" or die "Move failed: $!";
return 1;
}
=head2 list-modules
Lists the installed modules in
@datadir@/vo-support/modules/{available,install,remove}
=cut
sub listmodules {
print "Installed modules:\n\n";
for my $module (<$sharedir/modules/*>) {
print $module =~ m{.*/modules/(.*)};
print "\n";
}
}
=head2 run-module I<module> {configure | deconfigure} I<VOs>
Run the specified module for given VOs.
=cut
=head2 configure-vo I<list of VOs>
=head2 deconfigure-vo I<list of VOs>
This function is used from package maintainer scripts (postinst, prerm) to
activate the support for a newly installed VO or list of VOs. Its counterpart
deconfigurevo removes the support for VOs that are about to be deinstalled.
These functions will enable/disable the VOs as well.
=over
=item enabling a VO
If the VO configuration file exists, this is a no-op. If the
configuration file exists but is named I<VO>.conf-disabled, it is renamed
to I<VO>.conf. If no file exists, the default is copied from
@datadir@/vos/I<VO>/
=item disabling a VO
If the VO is configured, disable it by renaming the configuration file
with a '-disabled' suffix. Otherwise, this is a no-op. This will not
remove the actual configuration files of the VOs, as this could
possibly destroy manual modifications to the configuration.
=back
=cut
# Run the module on a list of VOs
# first argument is the name of the module
# second argument is the action "configure"/"deconfigure"
sub runmodule {
my $module = shift or pod2usage("run-module: no module name was given.");
my $action = shift or pod2usage("run-module: no action was specified.");
die "Illegal action: $action" if $action !~ /^(de)?configure$/;
my $modpath = "$sharedir/modules/$module";
return 0 unless -e $modpath;
system $modpath, $action, @_;
return ($? >> 8 == 0); # see perldoc system; exit code needs shift 8
}
sub configurevo {
# for each vo, enable the vo
# for each module, run the module on all the VOs
my @vos = @_;
foreach my $vo (@vos) {
enablevo $vo or return 0;
}
foreach my $module (<$sharedir/modules/*>) {
$module =~ s,.*/,,;
runmodule $module, "configure", @vos or return 0;
}
return 1;
}
sub deconfigurevo {
# be lenient; non-configured VOs are silently
# ignored by removing them from the list
# run each module to deconfigure the given VOs
my @vos = (); # build this list from the arguments
foreach my $vo (@_) {
push @vos, $vo if -e "$confdir/vos/$vo.conf";
}
my @modules = <$sharedir/modules/*>;
foreach my $module (@modules) {
$module =~ s,.*/,,;
runmodule $module, "deconfigure", @vos or return 0;
}
foreach my $vo (@vos) {
disablevo $vo or return 0;
}
return 1;
}
=head2 add-module I<module>
When a new vo-config module is introduced on the system, add-module
should be called to run the module for all the configured VOs on
the system. This is typically done by the post-install script of
the module's package.
=head2 remove-module I<module>
This function is the counterpart of add-module, and makes sure the
module is run for all configured VOs to deconfigure the module before
it is removed, e.g. as the prerm phase of the package maintainer
scripts. This is to make sure no configuration is left behind on
removal.
=cut
sub configuremodule {
my $module = shift;
my $action = shift; # configure or deconfigure
# find all the configured VOs
my @voconfs = <$confdir/vos/*.conf>;
my @vos = ();
# extract the name of the VO from the filename
foreach my $vo (@voconfs) {
(my $voname) = $vo =~ m{([^/]*)\.conf$};
push @vos, $voname;
}
if (@vos) {
runmodule $module, $action, @vos;
}
}
# this is run when a new module is added to the system
# and it should be run on all the configured VOs.
sub addmodule {
configuremodule shift, "configure";
}
# The counterpart of addmodule; this is nearly the same as addmodule
sub removemodule {
configuremodule shift, "deconfigure";
}
=pod
=head1 BUGS
This program probably has bugs.
=head1 AUTHOR
Dennis van Dok <dennisvd at nikhef.nl>
=head1 SEE ALSO
L<Site::Configuration::VO>
=head1 COPYRIGHT
Copyright 2012, 2013 Stichting FOM <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
L<http://www.apache.org/licenses/LICENSE-2.0>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.