source: projects/casparbuster/devel/bin/cbusterize @ 1485

Last change on this file since 1485 was 1485, checked in by bruno, 7 years ago
  • Adds a Plugin module to support plugin management
  • cbusterize now works with both -s and -p options
  • One plugin example added (dhcpd)

-cb script started. Not working now

  • Property svn:executable set to *
File size: 9.1 KB
Line 
1#!/usr/bin/perl -w
2#
3=head1 NAME
4
5cbusterize - Creates the correct CasparBuster structure in your CMS environment
6
7=head1 SYNOPSIS
8
9cbusterize [options] --source /path/to/file/to/CasparBusterize
10
11 Options:
12   --debug  |-d         debug mode
13   --help   |-h         brief help message
14   --man            full documentation
15   --force   |-f            force copy of files, even if they exist
16   --source |-s <file/dir>  directory or files to copy in the CasparBuster tree (',' separated if many)
17   --plugin |-p <plugin name>   plugin defining what to copy in the CasparBuster tree (',' separated if many)
18   --machine|-m <machine>   machine to consider in the subtree
19
20=head1 OPTIONS
21
22=over 4
23
24=item B<--debug>
25
26Enter debug mode. This will print what would be done. No commands are executed,
27so this is safe to use when testing.
28
29=item B<--help>
30
31Print a brief help message and exits.
32
33=item B<--man>
34
35Prints the manual page and exits.
36
37=item B<--machine> I<machine name>
38
39Specify the machine to consider when dealing with the CasparBuster structure.
40The file will be taken from this machine, and a subdirectory named after the machine
41will be used under the basedir to host the directory structure to manage
42
43=item B<--source> I<path>
44
45Specify the path to the source file or directory to manage with CasparBuster. Multiple paths can be specified separated by ','.
46
47=item B<--plugin> I<name>
48
49Specify the name of the plugin to manage with CasparBuster. Multiple plugins can be specified separated by ','.
50A plugin defines a set of files (with their mode and owner), a set of directories (with their mode and owner) and a set of scripts to launch once the files are copied remotely.
51
52=back
53
54=head1 DESCRIPTION
55
56Creates a directory under the machine dir passed as parameter in working
57directory or directory passed as parameter named like the last path
58element of the parameter, and creates the standard CasparBuster setup
59that refers to the parameter path in the new directory, and configuration
60files when possible. It also copies the original config file into the new dir.
61Is reasonably picky about path names, tries to avoid common errors.
62
63Schema looks like:
64
65Base dir
66   |
67   |- machine1 (optional)
68   |     |
69   |     |-- conf dir1
70   |     |       |
71   |     |       |- conf file 1
72   |   [...]    [...]
73   |
74   |- machine2 (optional)
75   |     |
76   |     |-- conf dir2
77   |     |       |
78   |     |       |- conf file 2
79   |   [...]    [...]
80
81Use of machines require use of option -m (if using cbusemachines in cb.conf)
82If not, the conf dirs are directly attached to the base dir
83
84=head1 EXAMPLES
85
86    # this will create the appropriate CasparBuster environment
87    # under the base ~/prj/musique-ancienne.org directory (Cf cbbasedir in cb.conf)
88    # containing the directory victoria2 for this machine
89    # under which it will copy the required structure if needed (/etc/ssh)
90    # to finaly put a copy of the file sshd_conf in it from the victoria2 machine
91
92    cbusterize -m victoria2 -s /etc/ssh/sshd_config
93
94=head1 AUTHOR
95
96=over 4
97
98Bruno Cornec, http://brunocornec.wordpress.com
99
100=back
101
102=head1 LICENSE
103
104Copyright (C) 2012  Bruno Cornec <bruno@project-builder.org>
105Released under the GPLv2 or the Artistic license at your will.
106
107=cut
108use strict;
109use CasparBuster::Version;
110use CasparBuster::Env;
111use CasparBuster::Plugin;
112#use Cwd 'realpath';
113use File::Find;
114use File::Copy;
115use File::Basename;
116use File::Path;
117use File::Glob ':glob';
118use Getopt::Long;
119use Pod::Usage;
120use Data::Dumper;
121use List::Util qw(first);
122use ProjectBuilder::Base;
123use ProjectBuilder::Conf;
124use ProjectBuilder::VCS;
125
126# settings
127my $debug = 0;
128my $help = undef;
129my $man = undef;
130my $source = undef;
131my $machine = undef;
132my $plugin = undef;
133my $quiet = undef;
134my $force = undef;
135my $log = undef;
136my $LOG = undef;
137
138my ($cbver,$cbrev) = cb_version_init();
139my $appname = "cb";
140$ENV{'PBPROJ'} = $appname;
141pb_temp_init();
142
143# Initialize the syntax string
144pb_syntax_init("$appname (aka CasparBuster) Version $cbver-$cbrev\n");
145
146# parse command-line options
147GetOptions(
148    'machine|m=s' => \$machine,
149    'debug|d+'    => \$debug,
150    'help|h'      => \$help,
151    'quiet|q'     => \$quiet,
152    'force|f'     => \$force,
153    'man'         => \$man,
154    'logfile|l=s' => \$log,
155    'source|s=s'  => \$source,
156    'plugin|p=s'  => \$plugin,
157) || pb_syntax(-1,0);
158
159if (defined $help) {
160    pb_syntax(0,1);
161}
162if (defined $man) {
163    pb_syntax(0,2);
164}
165if (defined $quiet) {
166    $debug=-1;
167}
168if (defined $log) {
169    open(LOG,"> $log") || die "Unable to log to $log: $!";
170    $LOG = \*LOG;
171    $debug = 0  if ($debug == -1);
172}
173
174$pbdebug = $debug;
175pb_log_init($debug, $LOG);
176pb_log(0,"Starting cbusterize\n");
177
178# Get conf file in context
179pb_conf_init($appname);
180# The personal one if there is such
181pb_conf_add("$ENV{'HOME'}/.cbrc") if (-f "$ENV{'HOME'}/.cbrc");
182# The system one
183pb_conf_add(cb_env_conffile());
184
185# Get configuration parameters
186my %cb;
187my $cb = \%cb;
188($cb->{'basedir'},$cb->{'usemachines'},$cb->{'cms'}) = pb_conf_get("cbbasedir","cbusemachines","cbcms");
189pb_log(2,"%cb: ",Dumper($cb));
190
191# Check for mandatory params
192pod2usage("Error: --source or --plugin is a mandatory argument\n") if ((not defined $source) && (not defined $plugin));
193pod2usage("Error: --machine is a mandatory argument when configure with cbusemachines = true\n") if (($cb->{'usemachines'}->{$appname} =~ /true/) && (not defined $machine));
194
195if (defined $plugin) {
196    # Load plugins
197    cb_plugin_load();
198}
199
200my $basedir = $cb->{'basedir'}->{$appname};
201eval { $basedir =~ s/(\$ENV.+\})/$1/eeg };
202
203pb_log(1, "DEBUG MODE, not doing anything, just printing\nDEBUG: basedir = $basedir\n");
204pb_log(1, "DEBUG: source = $source\n") if (defined $source);
205pb_log(1, "DEBUG: machine = $machine\n") if (defined $machine);
206
207# Use potentially a remote account if defined
208my $account = undef;
209my $remote = $machine;
210($account) = pb_conf_get_if("cbaccount") if (defined $machine);
211$remote = $account->{$machine}."@".$machine if ((defined $account) && (defined $account->{$machine}));
212pb_log(1, "DEBUG: remote = $remote\n") if (defined $remote);
213
214# Create basedir if it doesn't exist
215if (not -d $basedir) {
216    if ($debug) {
217        pb_log(1, "DEBUG: Creating recursively directory $basedir\n");
218    } else {
219        pb_mkdir_p($basedir) || die "Unable to recursively create $basedir: $!";
220    }
221}
222
223if (defined $source) {
224    foreach my $f (split(/,/,$source)) {   
225        cb_busterize($f);
226    }
227}
228
229# Now handle plugins if any
230my $cbp = ();
231
232if (defined $plugin) {
233    foreach my $p (split(/,/,$plugin)) {   
234        pb_log(1,"Getting context for plugin $p\n");
235        $cbp = cb_plugin_get($p,$cbp);
236        pb_log(2,"cbp: ".Dumper($cbp)."\n");
237        foreach my $k ((keys %{$cbp->{$plugin}->{'files'}}),(keys %{$cbp->{$plugin}->{'dirs'}})) {
238            cb_busterize($k);
239        }
240    }
241}
242
243sub cb_busterize {
244
245my $source = shift;
246
247pb_log(2,"Entering cb_busterize source: $source\n");
248# Is the source a file or a dir ? Split the source parameter in 2
249my $srcdir = undef;
250my $srcfile = undef;
251my $cmd = undef;
252
253if (not defined $machine) {
254    if (-d $source) {
255        $srcdir = $source;
256    } else {
257        $srcdir = dirname($source);
258        $srcfile = basename($source);
259    }
260} else {
261    $cmd = "ssh -q $remote \'echo \"if [ -d $source ]; then exit 0; else exit -1; fi\" | sudo bash\'";
262    my $res = pb_system($cmd,"","quiet");
263    pb_log(2,"DEBUG: Found res = $res\n");
264    if ($res == 0) {
265        $srcdir = $source;
266        pb_log(1,"DEBUG: Found remote dir = $source\n");
267    } else {
268        $srcdir = dirname($source);
269        $srcfile = basename($source);
270        pb_log(1,"DEBUG: Found remote file = $source\n");
271    }
272}
273
274pb_log(1,"DEBUG: Found srcdir = $srcdir\n");
275if (defined $srcfile) {
276    pb_log(1,"DEBUG: Found srcfile = $srcfile\n");
277} else {
278    pb_log(1,"DEBUG: Found no srcfile\n");
279}
280
281# Deduce the target directory from the local structure and the source
282my $target = $basedir;
283$target .= "/$machine" if defined ($machine);
284$target .= "$srcdir";
285
286my $scheme = $cb->{'cms'}->{$appname};
287
288# If both source and target are dirs, then copy into the parent of the target
289$target = basename($target) if ((not defined $srcfile) && (-d $target));
290
291# Create target if it doesn't exist when we have to copy a file
292if ((not -d $target) && (defined $srcfile)) {
293    if ($debug) {
294        pb_log(1,"DEBUG: Creating recursively directory $target\n");
295    } else {
296        pb_mkdir_p($target) || die "Unable to recursively create $target: $!";
297        pb_vcs_add($scheme,$target);
298        pb_log(0,"INFO: Created $target and added it to your $scheme system\n");
299    }
300}
301
302# We need to know where to get the content from
303my $cmdopt = "";
304
305# Recursive if we copy dirs
306$cmdopt = "-r" if (not defined $srcfile);
307
308if (defined $machine) {
309    $cmd = "scp -p -q $cmdopt $remote:$source $target";
310} else {
311    $cmd = "cp -p $cmdopt $source $target";
312}
313
314# Now add content if not already there
315if (defined $srcfile) {
316    # File case
317    if ((! -f "$target/$srcfile") || (defined $force)){
318        if ($debug) {
319            pb_log(1,"DEBUG: launching $cmd\n");
320        } else {
321            pb_system($cmd);
322            pb_vcs_add($scheme,"$target/$srcfile");
323            pb_log(0,"INFO: Created $target/$srcfile and added it to your $scheme system\n");
324        }
325    } else {
326        pb_log(0,"INFO: File $target/$srcfile already there\n");
327    }
328} else {
329    # Directory case
330    if ($debug) {
331        pb_log(1,"DEBUG: launching $cmd\n");
332    } else {
333        pb_system($cmd);
334        pb_vcs_add($scheme,"$target");
335        pb_log(0,"INFO: Created $target and added it to your $scheme system\n");
336    }
337}
338pb_log(2,"Exiting cb_busterize\n");
339}
Note: See TracBrowser for help on using the repository browser.