Mojo-Command-Generate-InitScript
view release on metacpan or search on metacpan
Revision history for Mojo-Command-Generate-InitScript
0.03 05.02
Fixed deploying for Debian, added some :) documentation
0.02 26.01
Added Debian initscript generation
0.01 26.01
First version, released on an unsuspecting world.
Changes
ignore.txt
lib/Mojo/Command/Generate/InitScript.pm
lib/Mojo/Command/Generate/InitScript/Freebsd.pm
lib/Mojo/Command/Generate/InitScript/Debian.pm
Makefile.PL
MANIFEST This list of files
README
t/00-load.t
t/boilerplate.t
t/manifest.t
t/pod-coverage.t
t/pod.t
META.yml Module meta-data (added by MakeMaker)
--- #YAML:1.0
name: Mojo-Command-Generate-InitScript
version: 0.03
abstract: Initscript generator command
author:
- Anatoliy Lapitskiy <nuclon@cpan.org>
license: perl
distribution_type: module
configure_requires:
ExtUtils::MakeMaker: 0
build_requires:
ExtUtils::MakeMaker: 0
requires:
Test::More: 0
no_index:
directory:
- t
- inc
generated_by: ExtUtils::MakeMaker version 6.56
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
Makefile.PL view on Meta::CPAN
use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'Mojo::Command::Generate::InitScript',
AUTHOR => q{Anatoliy Lapitskiy <nuclon@cpan.org>},
VERSION_FROM => 'lib/Mojo/Command/Generate/InitScript.pm',
ABSTRACT_FROM => 'lib/Mojo/Command/Generate/InitScript.pm',
($ExtUtils::MakeMaker::VERSION >= 6.3002
? ('LICENSE'=> 'perl')
: ()),
PL_FILES => {},
PREREQ_PM => {
'Test::More' => 0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Mojo-Command-Generate-InitScript-*' },
);
Mojo-Command-Generate-InitScript
The README is used to introduce the module and provide instructions on
how to install the module, any machine dependencies it may have (for
example C compilers and installed libraries) and any other information
that should be provided before the module is installed.
A README file is required for CPAN modules since CPAN extracts the README
file from a module distribution so that people browsing the archive
can use it to get an idea of the module's uses. It is usually a good idea
to provide version information here so that people can decide whether
fixes for the module are worth downloading.
INSTALLATION
To install this module, run the following commands:
perl Makefile.PL
make
make test
make install
SUPPORT AND DOCUMENTATION
After installing, you can find documentation for this module with the
perldoc command.
perldoc Mojo::Command::Generate::InitScript
You can also look for information at:
RT, CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Mojo-Command-Generate-InitScript
AnnoCPAN, Annotated CPAN documentation
http://annocpan.org/dist/Mojo-Command-Generate-InitScript
CPAN Ratings
http://cpanratings.perl.org/d/Mojo-Command-Generate-InitScript
Search CPAN
http://search.cpan.org/dist/Mojo-Command-Generate-InitScript/
LICENSE AND COPYRIGHT
Copyright (C) 2010 Anatoliy
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
blib*
Makefile
Makefile.old
Build
Build.bat
_build*
pm_to_blib*
*.tar.gz
.lwpcookies
cover_db
pod2htm*.tmp
Mojo-Command-Generate-InitScript-*
.hg*
*.swp
lib/Mojo/Command/Generate/InitScript.pm view on Meta::CPAN
package Mojo::Command::Generate::InitScript;
use warnings;
use strict;
use base 'Mojo::Commands';
use File::Spec;
use Getopt::Long 'GetOptions';
use Mojo::ByteStream 'b';
__PACKAGE__->attr(description => <<'EOF');
Generate application initscript (also known as rc.d script)
EOF
__PACKAGE__->attr(usage => <<"EOF");
usage: $0 generate init_script target_os [OPTIONS]
These options are available:
--output <folder> Set folder to output initscripts
--deploy Deploy initscripts into OS
Either --deploy or --output=dist should be specified
--name <name> Ovewrite name which is used for initscript filename(s)
EOF
__PACKAGE__->attr(namespaces => sub { ['Mojo::Command::Generate::InitScript'] });
=head1 NAME
Mojo::Command::Generate::InitScript - Initscript generator command
=head1 SYNOPSYS
$ ./mojo_app.pl generate help init_script
usage: ./mojo_app.pl generate init_script target_os [OPTIONS]
These options are available:
--output <folder> Set folder to output initscripts
--deploy Deploy initscripts into OS
Either --deploy or --output=dist should be specified
--name <name> Ovewrite name which is used for initscript filename(s)
=cut
our $VERSION = '0.03';
sub run
{
my ( $self, $target ) = @_;
my $opt = {};
Getopt::Long::Configure('pass_through');
GetOptions( $opt,
'output=s', 'name=s', 'deploy',
);
if ( !( $opt->{'deploy'} || $opt->{'output'} ) )
{
die qq{Either --deploy or --output <folder> should be specified\n};
}
if ( $opt->{'deploy'} && $opt->{'output'} )
{
die qq{Either --deploy or --output <folder> should be specified but not both\n};
}
if ( $opt->{'deploy'} && !$self->user_is_root )
{
die qq{You must be root to deploy init script\n};
}
if ( !$opt->{'name'} )
{
my ( $vol, $folder, $filename ) = File::Spec->splitpath( $0 );
($opt->{'name'}) = $filename =~ m/^(.*?)(?:\.pl)?$/;
}
$opt->{'app_script'} = File::Spec->rel2abs( $0 );
$self->SUPER::run( $target, $opt, @_ );
}
sub user_is_root
{
my $self = shift;
return $> == 0 || $< == 0
}
sub help
{
my $self = shift;
my $name = pop @ARGV;
if ( $name eq 'init_script' )
{
print $self->usage;
return;
}
my $module;
for my $namespace (@{$self->namespaces})
{
# Generate module
my $try = $namespace . '::' . b($name)->camelize;
# Load
if (my $e = Mojo::Loader->load($try)) {
# Module missing
next unless ref $e;
# Real error
die $e;
}
# Module is a command?
next unless $try->can('new') && $try->can('run');
# Found
$module = $try;
last;
}
die qq/Command "$name" missing, maybe you need to install it?\n/
unless $module;
my $command = $module->new;
print $self->usage, "\n", $command->usage;
}
=head1 AUTHOR
Anatoliy Lapitskiy, C<< <nuclon at cpan.org> >>
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Mojo::Command::Generate::InitScript
You can also look for information at:
=over 4
=item * bitbucket repository
L<http://bitbucket.org/nuclon/mojo-command-generate-initscript/>
=item * Search CPAN
L<http://search.cpan.org/dist/Mojo-Command-Generate-InitScript/>
=back
=head1 ACKNOWLEDGEMENTS
=head1 LICENSE AND COPYRIGHT
Copyright 2010 Anatoliy Lapitskiy.
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
=cut
1; # End of Mojo::Command::Generate::InitScript
lib/Mojo/Command/Generate/InitScript/Debian.pm view on Meta::CPAN
package Mojo::Command::Generate::InitScript::Debian;
use warnings;
use strict;
use File::Spec;
#use base 'Mojo::Command::Generate::InitScript::Base';
use base 'Mojo::Command';
use Getopt::Long 'GetOptions';
use File::Spec;
use IO::File;
use List::Util qw(first);
__PACKAGE__->attr(usage => <<"EOF");
Debian initscript related options:
--should-start <applist> defines facilities which, if present,
should be available during startup of this service
--should-stop <applist> facilities which should be available
during shutdown of this service.
--runlevels <runlevels> which run levels should by default run the init script
with a start (stop) argument to start (stop)
(Default: 2 3 4 5)
EOF
sub run
{
my ( $self, $opt ) = @_;
$opt->{'should-start'} = [];
$opt->{'should-stop'} = [];
$opt->{'runlevels'} = [2, 3, 4, 5];
$opt->{'stoplevels'} = [];
GetOptions($opt,
'should-start=s{,}', 'should-stop=s{,}', 'runlevels=i{,}',
);
for my $i (0..6)
{
if ( !first { $i == $_ } @{ $opt->{'runlevels'} } )
{
push @{ $opt->{'stoplevels'} }, $i;
}
}
# init script
my $file = $opt->{'deploy'}
? '/etc/init.d/'. $opt->{'name'}
: File::Spec->join($opt->{'output'}, $opt->{'name'});
$self->render_to_file( 'initscript', $file, $opt );
$self->chmod_file( $file, 0755 );
# config file
$file = $opt->{'deploy'}
? '/etc/default/'. $opt->{'name'}
: File::Spec->join($opt->{'output'}, 'etc_default_'.$opt->{'name'});
$self->render_to_file( 'config', $file, $opt );
$self->chmod_file( $file, 0644 );
if ( $opt->{'deploy'} )
{
system('/usr/sbin/update-rc.d', $opt->{'name'},
'start', '20', (@{ $opt->{'runlevels'} }), '.',
'stop', '20', (@{ $opt->{'stoplevels'} }), '.'
);
}
}
1;
__DATA__
@@ initscript
% my $opt = shift;
% my $name = $opt->{'name'};
#! /bin/sh
### BEGIN INIT INFO
# Provides: <%= $name %>
# Required-Start: $remote_fs $local_fs $network $syslog $time
# Required-Stop: $remote_fs $local_fs $network $syslog $time
% if ( @{ $opt->{'should-start'} } )
% {
# Should-Start: <%= join(' ', @{ $opt->{'should-start'} } ) %>
% }
% if ( @{ $opt->{'should-stop'} } )
% {
# Should-Stop: <%= join(' ', @{ $opt->{'should-stop'} } ) %>
% }
# Default-Start: <%= join(' ', @{ $opt->{'runlevels'} } ) %>
# Default-Stop: <%= join(' ', @{ $opt->{'stoplevels'} } ) %>
# Short-Description: starts <%= $name %> application
# Description: starts <%= $name %> application
### END INIT INFO
set -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=<%= $opt->{'app_script'} %>
NAME=<%= $name %>
DESC=<%= $name %>
MODE="daemon_prefork"
PIDFILE="/var/run/<%= $name %>.pid"
EXTRA_ARGS=""
USER="nobody"
# Include nginx defaults if available
if [ -f /etc/default/<%= $name %> ] ; then
. /etc/default/<%= $name %>
fi
DAEMON_ARGS="$MODE --daemonize --pid $PIDFILE --user $USER $EXTRA_ARGS"
. /lib/lsb/init-functions
do_start() {
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS
}
do_stop() {
start-stop-daemon --stop --quiet --pidfile $PIDFILE
}
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
do_start
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
log_end_msg $?
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
do_start
log_end_msg $?
;;
status)
status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $?
;;
*)
echo "Usage: $NAME {start|stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0
@@ config
% my $opt = shift;
% my $name = $opt->{'name'};
MODE="daemon_prefork"
PIDFILE="/var/run/<%= $name %>.pid"
EXTRA_ARGS=""
USER="nobody"
__END__
=head1 NAME
Mojo::Command::Generate::InitScript::Debian - Initscript generator for Linux Debian
=head1 SYNOPSYS
$ ./mojo_app.pl generate help init_script debian
usage: ./mojo_app.pl generate init_script target_os [OPTIONS]
These options are available:
--output <folder> Set folder to output initscripts
--deploy Deploy initscripts into OS
Either --deploy or --output=dist should be specified
--name <name> Ovewrite name which is used for initscript filename(s)
Debian initscript related options:
--should-start <applist> defines facilities which, if present,
should be available during startup of this service
--should-stop <applist> facilities which should be available
during shutdown of this service.
--runlevels <runlevels> which run levels should by default run the init script
with a start (stop) argument to start (stop)
(Default: 2 3 4 5)
=cut
lib/Mojo/Command/Generate/InitScript/Freebsd.pm view on Meta::CPAN
package Mojo::Command::Generate::InitScript::Freebsd;
use warnings;
use strict;
use File::Spec;
#use base 'Mojo::Command::Generate::InitScript::Base';
use base 'Mojo::Command';
use Getopt::Long 'GetOptions';
use File::Spec;
use IO::File;
__PACKAGE__->attr(usage => <<"EOF");
FreeBSD related initscript options:
--before <applist> Defines services which
should start after this initscript
for example: --before nginx
--requre <applist> Defines services which
should be started before this initscript
for example: --requre postgresql
EOF
sub run
{
my ( $self, $opt ) = @_;
$opt->{'before'} = [];
$opt->{'require'} = [];
GetOptions($opt,
'before=s{,}', 'require=s{,}',
);
my $rc_file = $opt->{'deploy'}
? '/usr/local/etc/rc.d/'. $opt->{'name'}
: File::Spec->join($opt->{'output'}, $opt->{'name'});
$self->render_to_file( 'initscript', $rc_file, $opt );
$self->chmod_file( $rc_file, 0755 );
# update /etc/rc.conf
$self->update_rc_conf( $opt->{'name'} ) if $opt->{'deploy'};
}
sub update_rc_conf
{
my ( $self, $name ) = @_;
my $fh = IO::File->new();
$fh->open('/etc/rc.conf', '+<') or die qq{Can't open /etc/rc.conf\n};
my $current_pos = 0;
my @lines = ();
my $read_lines = 0;
my $update_from_pos = undef;
my $already_done = 0;
while ( my $line = $fh->getline )
{
chomp $line;
if ( $read_lines )
{
push @lines, $line;
next;
}
if ( $line =~ m/^\Q$name\E_enable="(.*?)"$/i )
{
if ( $1 =~ /^yes$/i )
{
$already_done = 1;
last;
}
$update_from_pos = $current_pos;
$read_lines = 1;
}
$current_pos = $fh->tell;
}
if ( ! $already_done )
{
if ( defined $update_from_pos )
{
$fh->seek( $update_from_pos, 0 );
}
$fh->print("\n") if $fh->eof;
$fh->print($name, '_enable="YES"', "\n");
if ( @lines )
{
$fh->print( join("\n", @lines) );
}
$fh->truncate( $fh->tell );
}
close $fh;
}
1;
__DATA__
@@ initscript
% my $opt = shift;
% my $name = $opt->{'name'};
#!/bin/sh
# PROVIDE: <%= $name %>
% if ( @{ $opt->{'before'} } )
% {
# BEFORE: <%= join(' ', @{ $opt->{'before'} }) %>
% }
# REQUIRE: NETWORKING<%= @{ $opt->{'require'} } ? ' '.join(' ', @{ $opt->{'require'} }) : '' %>
# KEYWORD: shutdown
. /etc/rc.subr
name="<%= $name %>"
rcvar=`set_rcvar`
load_rc_config $name
: ${<%= $name %>_enable="NO"}
: ${<%= $name %>_pidfile="/var/tmp/<%= $name %>.pid"}
: ${<%= $name %>_mode="daemon_prefork"}
: ${<%= $name %>_args=""}
: ${<%= $name %>_user="nobody"}
command="<%= $opt->{'app_script'} %>"
extra_commands="reload"
pidfile="${<%= $name %>_pidfile}"
sig_reload="USR1"
command_args="${<%= $name %>_mode} --daemonize --pid ${<%= $name %>_pidfile} --user ${<%= $name %>_user} ${<%= $name %>_args}"
procname="perl"
run_rc_command "$1"
__END__
=head1 NAME
Mojo::Command::Generate::InitScript::Freebsd - Initscript generator for FreeBSD
=head1 SYNOPSYS
$ ./mojo_app.pl generate help init_script freebsd
usage: ./mojo_app.pl generate init_script target_os [OPTIONS]
These options are available:
--output <folder> Set folder to output initscripts
--deploy Deploy initscripts into OS
Either --deploy or --output=dist should be specified
--name <name> Ovewrite name which is used for initscript filename(s)
FreeBSD related initscript options:
--before <applist> Defines services which
should start after this initscript
for example: --before nginx
--requre <applist> Defines services which
should be started before this initscript
for example: --requre postgresql
=cut
t/00-load.t view on Meta::CPAN
#!perl
use Test::More tests => 1;
BEGIN {
use_ok( 'Mojo::Command::Generate::InitScript' ) || print "Bail out!
";
}
diag( "Testing Mojo::Command::Generate::InitScript $Mojo::Command::Generate::InitScript::VERSION, Perl $], $^X" );
t/boilerplate.t view on Meta::CPAN
#!perl -T
use strict;
use warnings;
use Test::More tests => 3;
sub not_in_file_ok {
my ($filename, %regex) = @_;
open( my $fh, '<', $filename )
or die "couldn't open $filename for reading: $!";
my %violated;
while (my $line = <$fh>) {
while (my ($desc, $regex) = each %regex) {
if ($line =~ $regex) {
push @{$violated{$desc}||=[]}, $.;
}
}
}
if (%violated) {
fail("$filename contains boilerplate text");
diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
} else {
pass("$filename contains no boilerplate text");
}
}
sub module_boilerplate_ok {
my ($module) = @_;
not_in_file_ok($module =>
'the great new $MODULENAME' => qr/ - The great new /,
'boilerplate description' => qr/Quick summary of what the module/,
'stub function definition' => qr/function[12]/,
);
}
TODO: {
local $TODO = "Need to replace the boilerplate text";
not_in_file_ok(README =>
"The README is used..." => qr/The README is used/,
"'version information here'" => qr/to provide version information/,
);
not_in_file_ok(Changes =>
"placeholder date/time" => qr(Date/time)
);
module_boilerplate_ok('lib/Mojo/Command/Generate/InitScript.pm');
}
t/manifest.t view on Meta::CPAN
#!perl -T
use strict;
use warnings;
use Test::More;
unless ( $ENV{RELEASE_TESTING} ) {
plan( skip_all => "Author tests not required for installation" );
}
eval "use Test::CheckManifest 0.9";
plan skip_all => "Test::CheckManifest 0.9 required" if $@;
ok_manifest();
t/pod-coverage.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
# Ensure a recent version of Test::Pod::Coverage
my $min_tpc = 1.08;
eval "use Test::Pod::Coverage $min_tpc";
plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
if $@;
plan skip_all => 'set TEST_POD to enable this test (developer only!)'
unless $ENV{TEST_POD};
all_pod_coverage_ok();
#!perl -T
use strict;
use warnings;
use Test::More;
# Ensure a recent version of Test::Pod
my $min_tp = 1.22;
eval "use Test::Pod $min_tp";
plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
plan skip_all => 'set TEST_POD to enable this test (developer only!)'
unless $ENV{TEST_POD};
all_pod_files_ok();
( run in 0.390 second using v1.01-cache-2.11-cpan-7add2cbd662 )