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

Last change on this file since 1487 was 1487, checked in by bruno, 7 years ago
  • Fix Plugin.pm for caspar structure management (don't use tables but hashes)
  • more code in cb still not ready.
  • Property svn:executable set to *
File size: 9.0 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;
112use File::Basename;
113use File::Path;
114use Getopt::Long;
115use Pod::Usage;
116use Data::Dumper;
117use ProjectBuilder::Base;
118use ProjectBuilder::Conf;
119use ProjectBuilder::VCS;
120
121# settings
122my $debug = 0;
123my $help = undef;
124my $man = undef;
125my $source = undef;
126my $machine = undef;
127my $plugin = undef;
128my $quiet = undef;
129my $force = undef;
130my $log = undef;
131my $LOG = undef;
132
133my ($cbver,$cbrev) = cb_version_init();
134my $appname = "cb";
135$ENV{'PBPROJ'} = $appname;
136pb_temp_init();
137
138# Initialize the syntax string
139pb_syntax_init("$appname (aka CasparBuster) Version $cbver-$cbrev\n");
140
141# parse command-line options
142GetOptions(
143    'machine|m=s' => \$machine,
144    'debug|d+'    => \$debug,
145    'help|h'      => \$help,
146    'quiet|q'     => \$quiet,
147    'force|f'     => \$force,
148    'man'         => \$man,
149    'logfile|l=s' => \$log,
150    'source|s=s'  => \$source,
151    'plugin|p=s'  => \$plugin,
152) || pb_syntax(-1,0);
153
154if (defined $help) {
155    pb_syntax(0,1);
156}
157if (defined $man) {
158    pb_syntax(0,2);
159}
160if (defined $quiet) {
161    $debug=-1;
162}
163if (defined $log) {
164    open(LOG,"> $log") || die "Unable to log to $log: $!";
165    $LOG = \*LOG;
166    $debug = 0  if ($debug == -1);
167}
168
169$pbdebug = $debug;
170pb_log_init($debug, $LOG);
171pb_log(0,"Starting cbusterize\n");
172
173# Get conf file in context
174pb_conf_init($appname);
175# The personal one if there is such
176pb_conf_add("$ENV{'HOME'}/.cbrc") if (-f "$ENV{'HOME'}/.cbrc");
177# The system one
178pb_conf_add(cb_env_conffile());
179
180# Get configuration parameters
181my %cb;
182my $cb = \%cb;
183($cb->{'basedir'},$cb->{'usemachines'},$cb->{'cms'}) = pb_conf_get("cbbasedir","cbusemachines","cbcms");
184pb_log(2,"%cb: ",Dumper($cb));
185
186# Check for mandatory params
187pod2usage("Error: --source or --plugin is a mandatory argument\n") if ((not defined $source) && (not defined $plugin));
188pod2usage("Error: --machine is a mandatory argument when configure with cbusemachines = true\n") if (($cb->{'usemachines'}->{$appname} =~ /true/) && (not defined $machine));
189
190if (defined $plugin) {
191    # Load plugins
192    cb_plugin_load();
193}
194
195my $basedir = $cb->{'basedir'}->{$appname};
196eval { $basedir =~ s/(\$ENV.+\})/$1/eeg };
197
198pb_log(1, "DEBUG MODE, not doing anything, just printing\nDEBUG: basedir = $basedir\n");
199pb_log(1, "DEBUG: source = $source\n") if (defined $source);
200pb_log(1, "DEBUG: machine = $machine\n") if (defined $machine);
201
202# Use potentially a remote account if defined
203my $account = undef;
204my $remote = $machine;
205($account) = pb_conf_get_if("cbaccount") if (defined $machine);
206$remote = $account->{$machine}."@".$machine if ((defined $account) && (defined $account->{$machine}));
207pb_log(1, "DEBUG: remote = $remote\n") if (defined $remote);
208
209# Create basedir if it doesn't exist
210if (not -d $basedir) {
211    if ($debug) {
212        pb_log(1, "DEBUG: Creating recursively directory $basedir\n");
213    } else {
214        pb_mkdir_p($basedir) || die "Unable to recursively create $basedir: $!";
215    }
216}
217
218if (defined $source) {
219    foreach my $f (split(/,/,$source)) {   
220        cb_busterize($f);
221    }
222}
223
224# Now handle plugins if any
225my $cbp = ();
226
227if (defined $plugin) {
228    foreach my $p (split(/,/,$plugin)) {   
229        pb_log(1,"Getting context for plugin $p\n");
230        $cbp = cb_plugin_get($p,$cbp);
231        pb_log(2,"cbp: ".Dumper($cbp)."\n");
232        foreach my $k ((keys %{$cbp->{$plugin}->{'files'}}),(keys %{$cbp->{$plugin}->{'dirs'}})) {
233            cb_busterize($k);
234        }
235    }
236}
237
238sub cb_busterize {
239
240my $source = shift;
241
242pb_log(2,"Entering cb_busterize source: $source\n");
243# Is the source a file or a dir ? Split the source parameter in 2
244my $srcdir = undef;
245my $srcfile = undef;
246my $cmd = undef;
247
248if (not defined $machine) {
249    if (-d $source) {
250        $srcdir = $source;
251    } else {
252        $srcdir = dirname($source);
253        $srcfile = basename($source);
254    }
255} else {
256    $cmd = "ssh -q $remote \'echo \"if [ -d $source ]; then exit 0; else exit -1; fi\" | sudo bash\'";
257    my $res = pb_system($cmd,"","quiet");
258    pb_log(2,"DEBUG: Found res = $res\n");
259    if ($res == 0) {
260        $srcdir = $source;
261        pb_log(1,"DEBUG: Found remote dir = $source\n");
262    } else {
263        $srcdir = dirname($source);
264        $srcfile = basename($source);
265        pb_log(1,"DEBUG: Found remote file = $source\n");
266    }
267}
268
269pb_log(1,"DEBUG: Found srcdir = $srcdir\n");
270if (defined $srcfile) {
271    pb_log(1,"DEBUG: Found srcfile = $srcfile\n");
272} else {
273    pb_log(1,"DEBUG: Found no srcfile\n");
274}
275
276# Deduce the target directory from the local structure and the source
277my $target = $basedir;
278$target .= "/$machine" if defined ($machine);
279$target .= "$srcdir";
280
281my $scheme = $cb->{'cms'}->{$appname};
282
283# If both source and target are dirs, then copy into the parent of the target
284$target = basename($target) if ((not defined $srcfile) && (-d $target));
285
286# Create target if it doesn't exist when we have to copy a file
287if ((not -d $target) && (defined $srcfile)) {
288    if ($debug) {
289        pb_log(1,"DEBUG: Creating recursively directory $target\n");
290    } else {
291        pb_mkdir_p($target) || die "Unable to recursively create $target: $!";
292        pb_vcs_add($scheme,$target);
293        pb_log(0,"INFO: Created $target and added it to your $scheme system\n");
294    }
295}
296
297# We need to know where to get the content from
298my $cmdopt = "";
299
300# Recursive if we copy dirs
301$cmdopt = "-r" if (not defined $srcfile);
302
303if (defined $machine) {
304    $cmd = "scp -p -q $cmdopt $remote:$source $target";
305} else {
306    $cmd = "cp -p $cmdopt $source $target";
307}
308
309# Now add content if not already there
310if (defined $srcfile) {
311    # File case
312    if ((! -f "$target/$srcfile") || (defined $force)){
313        if ($debug) {
314            pb_log(1,"DEBUG: launching $cmd\n");
315        } else {
316            pb_system($cmd);
317            pb_vcs_add($scheme,"$target/$srcfile");
318            pb_log(0,"INFO: Created $target/$srcfile and added it to your $scheme system\n");
319        }
320    } else {
321        pb_log(0,"INFO: File $target/$srcfile already there\n");
322    }
323} else {
324    # Directory case
325    if ($debug) {
326        pb_log(1,"DEBUG: launching $cmd\n");
327    } else {
328        pb_system($cmd);
329        pb_vcs_add($scheme,"$target");
330        pb_log(0,"INFO: Created $target and added it to your $scheme system\n");
331    }
332}
333pb_log(2,"Exiting cb_busterize\n");
334}
Note: See TracBrowser for help on using the repository browser.