#!/usr/bin/env perl
our
$VERSION
=
'1.16.0'
;
BEGIN {
if
( -d
'/usr/lib/rex/lib'
) {
use
lib
'/usr/lib/rex/lib'
;
}
}
$|++;
$Rex::Logger::silent
= 1;
my
(
$major_minor
) = (
$Rex::VERSION
=~ m/^(\d*\.\d*)/ );
my
$opts
= {};
my
$PERL_DEPEND_SERVER
=
my
$AUTH_USER
;
my
$AUTH_PASSWORD
;
my
$AUTH_REALM
;
Rex::Config->register_config_handler(
"module_server"
,
sub
{
my
(
$param
) =
@_
;
if
(
exists
$param
->{search} ) {
$SEARCH_SERVER
=
$param
->{search};
}
if
(
exists
$param
->{recipes} ) {
$RECIPE_SERVER
=
$param
->{recipes};
}
if
(
exists
$param
->{dependencies} ) {
$DEPEND_SERVER
=
$param
->{dependencies};
}
if
(
exists
$param
->{perl_dependencies} ) {
$PERL_DEPEND_SERVER
=
$param
->{perl_dependencies};
}
if
(
exists
$param
->{username} ) {
$AUTH_USER
=
$param
->{username};
}
if
(
exists
$param
->{password} ) {
$AUTH_PASSWORD
=
$param
->{password};
}
if
(
exists
$param
->{realm} ) {
$AUTH_REALM
=
$param
->{realm};
}
}
);
for
(
my
$i
= 0 ;
$i
<
@ARGV
;
$i
++ ) {
if
(
$ARGV
[
$i
] =~ m/^\-\-([a-z0-9\-_]+)=/ ) {
my
$key
= $1;
my
(
$c_key
,
$val
) =
split
( /=/,
$ARGV
[
$i
], 2 );
if
(
exists
$opts
->{
$key
} ) {
$opts
->{
$key
} = [
$opts
->{
$key
} ]
if
( !
ref
$opts
->{
$key
} );
push
( @{
$opts
->{
$key
} },
$val
);
}
else
{
$opts
->{
$key
} =
$val
|| 0;
}
}
elsif
(
$ARGV
[
$i
] =~ m/^\-\-([a-z0-9\-_]+)/ ) {
my
$key
= $1;
if
( !
$ARGV
[
$i
+ 1 ] ||
$ARGV
[
$i
+ 1 ] =~ m/^\-\-/ ) {
$opts
->{
$key
} = 1;
}
else
{
if
(
exists
$opts
->{
$key
} ) {
$opts
->{
$key
} = [
$opts
->{
$key
} ]
if
( !
ref
$opts
->{
$key
} );
push
( @{
$opts
->{
$key
} },
$ARGV
[ ++
$i
] );
}
else
{
$opts
->{
$key
} =
$ARGV
[ ++
$i
];
}
}
}
}
if
( !
$ARGV
[0]
||
join
(
","
,
@ARGV
) =~ m/\-h,|\-\-help,/
||
$ARGV
[0] eq
"--help"
)
{
print
STDERR
"Usage: rexify [<project-name> [<directory>]] [<options>]\n"
;
print
STDERR
"\n"
;
print
STDERR
"Options:"
;
print
STDERR
"\n"
;
print
STDERR
"\t--search=value\t\t\tWill search community recipes\n"
;
print
STDERR
"\t--use=recipe\t\t\tWill download community recipe\n"
;
print
STDERR
"\t--init=git-url\t\t\tWill download and initialize the given repo\n"
;
print
STDERR
"\t--update-from-git\t\tUpdate the cloned repository.\n"
;
print
STDERR
"\t--template=template\t\tUse a custom template to create the Rexfile skeleton\n"
;
print
STDERR
"\t--create-module\t\t\tCreate a module skeleton.\n"
;
print
STDERR
"\t--create-module=Mod::Name\tCreate a module skeleton inside a Rex project.\n"
;
print
STDERR
"\t--sudo\t\t\t\tTo use sudo for Perl Module installation.\n"
;
print
STDERR
"\t--resolve-deps\t\t\tRead meta.yml and try to resolve project dependencies\n"
;
print
STDERR
"\t--no-install-perl-deps\t\tUse this if you don't want that rexify tries to install Perl Modules.\n"
;
print
STDERR
"\n"
;
print
STDERR
"Custom Templates:\n"
;
print
STDERR
" box - Template to use for Rex::Commands::Box projects.\n"
;
print
STDERR
"\n"
;
print
STDERR
"Application Bundle Commands:\n"
;
print
STDERR
"\n"
;
print
STDERR
"\t--bundle\tCreate an all-containing redistributable binary application.\n"
;
print
STDERR
"\t--task=taskname\tWhich task should be executed. default: setup\n"
;
print
STDERR
"\n"
;
print
STDERR
"Rex-JobControl Commands:\n"
;
print
STDERR
"\n"
;
print
STDERR
"\t--upload\tUpload Rexfile to JobControl server.\n"
;
print
STDERR
"\t\t--project=<project>\t\tProject where the Rexfile should be registered.\n"
;
print
STDERR
"\t\t--name=<name>\t\t\tThe name for the Rexfile.\n"
;
print
STDERR
"\t\t--description='<description>'\tA small description for the Rexfile.\n"
;
print
STDERR
"\n"
;
print
STDERR
"\t--execute\tExecute Job on JobControl server.\n"
;
print
STDERR
"\t\t--project=<project>\t\tProject where the Rexfile should be registered.\n"
;
print
STDERR
"\t\t--job=<job>\t\t\tThe name of the job to execute.\n"
;
print
STDERR
"\t\t--hosts='<server list>'\tA comma seperated list of servers.\n"
;
print
STDERR
"\n"
;
print
STDERR
"General options:"
;
print
STDERR
"\n"
;
print
STDERR
"\t--server=<server>\t\tThe URL to JobControl server.\n"
;
print
STDERR
"\t--username=<username>\t\tThe username to use for login to JobControl server.\n"
;
print
STDERR
"\t--password=<password>\t\tThe password for the user.\n"
;
print
STDERR
"\n"
;
exit
1;
}
sub
print_found {
my
(
$name
,
$data
) =
@_
;
$name
=~ s/\//::/g;
$name
=~ s/\.pm$//;
print
"* $name\n"
;
print
" Author : "
.
$data
->{Author} .
"\n"
;
print
" Requires : "
.
join
(
", "
, @{
$data
->{Requires} } ) .
"\n"
if
(
$data
->{Requires} );
print
" License : "
.
$data
->{License} .
"\n"
if
(
$data
->{License} );
print
" Description: "
.
$data
->{Description} .
"\n"
;
}
sub
update_from_git {
system
"git pull origin"
;
resolve_deps(
"meta.yml"
);
}
sub
download_recipe_git {
my
(
$url
) =
@_
;
$Rex::Logger::silent
= 0;
my
$u
= URI->new(
$url
);
my
$branch
=
$u
->query_param(
"branch"
);
my
@splitted_path
=
split
/\//,
$u
->path;
$splitted_path
[-1] =~ s/\.git$//;
$branch
||=
"master"
;
my
$path
= File::Spec->catdir( File::Spec->rel2abs( File::Spec->curdir() ),
$splitted_path
[-1] );
my
$parent_path
= dirname
$path
;
mkdir
$parent_path
;
my
$clone_url
=
$u
->scheme .
'://'
.
$u
->host .
$u
->path;
Rex::Logger::info(
"Cloning $clone_url to $path. Using branch: $branch."
);
system
"git"
,
"clone"
,
$url
,
"-b"
,
$branch
,
$path
;
chdir
$path
;
resolve_deps(
"meta.yml"
);
}
sub
download_recipe_local_tar_gz {
my
(
$url
) =
@_
;
$Rex::Logger::silent
= 0;
system
"tar"
,
"xzf"
,
$url
;
my
$path
= basename(
$url
);
$path
=~ s/\.tar\.gz$//;
chdir
$path
;
resolve_deps(
"meta.yml"
);
}
sub
upload_rexfile {
my
(
%option
) =
@_
;
my
$tmp_dir
= File::Spec->tmpdir;
my
$tmp_file
= File::Spec->catfile(
$tmp_dir
, basename(getcwd) .
".tar.gz"
);
my
$login_url
=
$option
{server} .
"/login"
;
my
$upload_url
=
$option
{server}
.
"/project/"
. Rex::Helper::URI::encode(
$option
{project} )
.
"/rexfile/new"
;
Rex::Logger::info(
"Creating tar.gz file out of this directory."
);
my
$dir
= basename( getcwd() );
system
"cd .. ; tar czf $tmp_file $dir"
;
my
$ua
= LWP::UserAgent->new(
cookie_jar
=> {} );
my
$res
=
$ua
->post(
$login_url
,
{
username
=>
$option
{username},
password
=>
$option
{password} } );
if
(
$res
->code != 302 ) {
print
"Server not found or authentication wrong.\n"
;
exit
1;
}
my
$up_request
= POST(
$upload_url
,
Content_Type
=>
'form-data'
,
Content
=> [
rexfile_archive
=> [
$tmp_file
],
rexfile_name
=>
$option
{name},
rexfile_description
=>
$option
{description}
]
);
my
$up_res
=
$ua
->request(
$up_request
);
if
(
$up_res
->code != 302 ) {
print
"Upload of Rexfile failed.\n"
;
exit
1;
}
unlink
$tmp_file
;
}
sub
dispatch_execute_job {
my
(
%option
) =
@_
;
my
$login_url
=
$option
{server} .
"/login"
;
my
$execute_url
=
$option
{server}
.
"/project/"
. Rex::Helper::URI::encode(
$option
{project} ) .
"/job/"
. Rex::Helper::URI::encode(
$option
{job} )
.
"/execute"
;
my
$ua
= LWP::UserAgent->new(
cookie_jar
=> {} );
my
$res
=
$ua
->post(
$login_url
,
{
username
=>
$option
{username},
password
=>
$option
{password} } );
if
(
$res
->code != 302 ) {
print
"Server not found or authentication wrong.\n"
;
exit
1;
}
my
$ex_request
= POST(
$execute_url
,
Content
=> [
sel_server
=> [
split
( /[ ,]/,
$option
{hosts} ) ],
]
);
my
$ex_res
=
$ua
->request(
$ex_request
);
if
(
$ex_res
->code != 302 ) {
print
"Execute of job failed.\n"
;
exit
1;
}
}
sub
download_recipe {
my
(
$name
) =
@_
;
if
(
$name
=~ m/^(ssh|https|git):\/\// ) {
download_recipe_git(
$name
);
return
;
}
if
( !-f
"Rexfile"
) {
print
STDERR
"This is not a Rex project directory. There is no Rexfile.\n"
;
exit
1;
}
if
( !-d
"lib"
) {
mkdir
"lib"
; }
print
"Getting dependencies for $name...\n"
;
my
$deps
= decode_json( get(
sprintf
(
$DEPEND_SERVER
,
$name
) ) );
if
(
scalar
( @{
$deps
} ) > 0 ) {
print
" Found: \n - "
.
join
(
"\n - "
, @{
$deps
} ) .
"\n"
;
for
my
$dep
( @{
$deps
} ) {
download_recipe(
$dep
);
}
}
else
{
print
" None found.\n"
;
}
if
( !
exists
$opts
->{
"no-install-perl-deps"
} ) {
print
"Getting perl dependencies for $name...\n"
;
my
$perl_deps
= decode_json( get(
sprintf
(
$PERL_DEPEND_SERVER
,
$name
) ) );
if
(
scalar
( @{
$perl_deps
} ) > 0 ) {
print
" Found: \n - "
.
join
(
"\n - "
, @{
$perl_deps
} ) .
"\n"
;
for
my
$dep
( @{
$perl_deps
} ) {
install_perl_module(
$dep
);
}
}
else
{
print
" None found.\n"
;
}
}
print
"Downloading $name... "
;
$name
=~ s/::/\//g;
my
$content
= get(
sprintf
(
$RECIPE_SERVER
,
$name
) );
open
(
my
$fh
,
">"
,
"tmp-mod.tar.gz"
) or
die
($!);
binmode
$fh
;
print
$fh
$content
;
close
(
$fh
);
chdir
(
"lib"
);
system
"tar"
,
"xzf"
,
"../tmp-mod.tar.gz"
;
chdir
(
".."
);
unlink
(
"tmp-mod.tar.gz"
);
print
"done.\n"
;
}
sub
resolve_deps {
my
(
$file
) =
@_
;
$Rex::Logger::silent
= 0;
$file
||=
"meta.yml"
;
if
( !-f
$file
) {
return
;
}
my
$ref
= YAML::LoadFile(
$file
);
my
(
%deps
,
%perl_deps
);
if
(
exists
$ref
->{Require} ) {
if
(
ref
$ref
->{Require} eq
"ARRAY"
) {
do
{
ref
$_
eq
"HASH"
?
$deps
{
$_
->{name} } =
$_
:
$deps
{
$_
} =
$_
}
for
@{
$ref
->{Require} };
}
else
{
%deps
= %{
$ref
->{Require} };
}
}
if
(
exists
$ref
->{PerlRequire} ) {
if
(
ref
$ref
->{PerlRequire} eq
"ARRAY"
) {
do
{
ref
$_
eq
"HASH"
?
$perl_deps
{
$_
->{name} } =
$_
:
$perl_deps
{
$_
} =
$_
;
}
for
@{
$ref
->{PerlRequire} };
}
else
{
%perl_deps
= %{
$ref
->{PerlRequire} };
}
}
Rex::Logger::debug(
"Found dependencies: "
);
Rex::Logger::debug( Dumper( \
%deps
) );
for
my
$req
(
keys
%deps
) {
if
(
ref
$deps
{
$req
} ) {
if
(
exists
$deps
{
$req
}->{git} ) {
my
$branch
=
"master"
;
if
(
exists
$deps
{
$req
}->{branch} ) {
$branch
=
$deps
{
$req
}->{branch};
}
my
@path_parts
=
split
/::/,
$req
;
my
$path
=
File::Spec->catdir( File::Spec->rel2abs( File::Spec->curdir() ),
"lib"
,
@path_parts
);
my
$parent_path
= dirname
$path
;
if
( !-d
$parent_path
) {
mkdir
$parent_path
;
}
if
( -d
$path
&& !-d
"$path/.git"
) {
Rex::Logger::info(
"$req not under git control. Skipping."
,
"warn"
);
next
;
}
if
( -d
"$path/.git"
) {
rmdir
$path
;
}
Rex::Logger::info(
"Cloning $deps{$req}->{git}#$branch to $path"
);
system
"git"
,
"clone"
,
$deps
{
$req
}->{git},
"-b"
,
$branch
,
$path
;
resolve_deps(
"$path/meta.yml"
);
}
}
else
{
download_recipe(
$req
);
}
}
Rex::Logger::debug(
"Found perl dependencies: "
);
Rex::Logger::debug( Dumper( \
%perl_deps
) );
for
my
$req
(
keys
%perl_deps
) {
if
(
ref
$perl_deps
{
$req
} ) {
if
(
exists
$perl_deps
{
$req
}->{git} ) {
my
$branch
=
"master"
;
if
(
exists
$perl_deps
{
$req
}->{branch} ) {
$branch
=
$perl_deps
{
$req
}->{branch};
}
my
$curdir
= getcwd;
my
$path
= File::Spec->catdir( File::Spec->tmpdir,
"tmp-build-$$"
);
my
$lib_path
=
File::Spec->catdir( File::Spec->rel2abs( File::Spec->curdir() ),
"lib"
,
"perl"
);
my
$parent_path
= dirname
$lib_path
;
if
( !-d
$parent_path
) {
mkdir
$parent_path
;
}
Rex::Logger::info(
"Cloning $perl_deps{$req}->{git}#$branch to $path"
);
system
"git"
,
"clone"
,
$perl_deps
{
$req
}->{git},
"-b"
,
$branch
,
$path
;
chdir
$path
;
system
"cpanm"
,
"-l"
,
$lib_path
,
"."
;
chdir
$curdir
;
rmdir
$path
;
}
}
else
{
my
$lib_path
= File::Spec->catdir( File::Spec->curdir(),
"lib"
,
"perl"
);
eval
"use $req"
;
if
($@) {
system
"cpanm"
,
"-l"
,
$lib_path
,
$req
;
}
}
}
}
sub
install_perl_module {
my
(
$mod
) =
@_
;
print
"Checking $mod: "
;
eval
"use $mod"
;
if
($@) {
print
"[failed]\n"
;
}
else
{
print
"[ok]\n"
;
return
;
}
print
"Trying to install $mod... "
;
my
$cmd
=
"cpanm"
;
my
$out
=
qx($cmd --help 2>&1)
;
if
( $? != 0 ) {
$cmd
=
"cpan"
;
$out
=
qx($cmd -h 2>&1)
;
if
( $? != 0 ) {
print
"[failed]\n"
;
print
"Can't find cpanm or cpan. Please install $mod manually.\n"
;
return
;
}
}
my
$cpanm_opts
=
""
;
if
(
exists
$opts
->{sudo} ) {
$cmd
=
"sudo $cmd"
;
}
$out
=
qx($cmd $cpanm_opts $mod 2>&1)
;
open
(
my
$log
,
">>"
,
"rexify-install.log"
) or
die
($!);
print
$log
$out
;
close
(
$log
);
if
( $? != 0 ) {
print
"[failed]\n"
;
print
"!! Please install $mod manually. See rexify-install.log for more details.\n"
;
}
else
{
print
"[ok]\n"
;
}
}
if
(
exists
$opts
->{bundle} ) {
CORE::
mkdir
(
"rex.payload"
);
system
"cp -vR * rex.payload/ 2>/dev/null"
;
system
"rm -rf rex.payload/rex.payload"
;
my
$rex
= File::Spec->catfile( dirname($0),
"rex"
);
my
$tmp_args_file
=
File::Spec->catfile( File::Spec->tmpdir(),
"pp.args.$$.tmp"
);
open
(
my
$fh
,
">"
,
$tmp_args_file
) or
die
($!);
print
$fh
template(
'@pp.args.tpl'
);
close
(
$fh
);
if
( -d
'/usr/lib/rex/lib'
) {
system
"pp -I /usr/lib/rex/lib \@$tmp_args_file -o rex.payload/rex.bin $rex"
;
}
else
{
system
"pp -I /usr/lib/rex/lib \@$tmp_args_file -o rex.payload/rex.bin $rex"
;
}
my
$arch
=
qx{uname -m}
;
chomp
$arch
;
my
$elf
=
"ELF32"
;
if
(
$arch
eq
"x86_64"
) {
$elf
=
"ELF64"
;
}
CORE::
mkdir
( File::Spec->catdir(
"rex.payload"
,
"lib.bin"
) );
my
@libexpat
=
qx{find /usr/lib /usr/lib32 /usr/lib64 /lib -name 'libexpat.so*' -type f 2>/dev/null}
;
my
@libssh2
=
qx{find /usr/lib /usr/lib32 /usr/lib64 /lib -name 'libssh2.so*' -type f 2>/dev/null}
;
chomp
@libexpat
;
chomp
@libssh2
;
for
my
$f
(
@libexpat
,
@libssh2
) {
my
$elf_class
=
qx{readelf -h $f | grep Class:}
;
if
(
$elf_class
=~ m/
$elf
/ ) {
system
"cp -va $f "
. File::Spec->catdir(
"rex.payload"
,
"lib.bin"
);
}
}
system
"cd rex.payload/lib.bin ; ln -s "
. basename(
$libssh2
[0] )
.
" libssh2.so.1"
;
system
"cd rex.payload/lib.bin ; ln -s "
. basename(
$libexpat
[0] )
.
" libexpat.so.1"
;
open
(
my
$fh2
,
">"
,
"rex.sh"
) or
die
($!);
print
$fh2
template(
'@bundle.sh.tpl'
,
task
=>
'setup'
);
close
(
$fh2
);
system
"cd rex.payload ; tar czf ../rex.payload.tar.gz *"
;
system
"cat rex.sh rex.payload.tar.gz >rex.selfextract.sbx ; chmod 755 rex.selfextract.sbx"
;
CORE::
unlink
(
$tmp_args_file
);
CORE::
unlink
(
"rex.sh"
);
system
"rm -rf rex.payload"
;
CORE::
unlink
(
"rex.payload.tar.gz"
);
exit
0;
}
if
(
exists
$opts
->{upload}
&&
exists
$opts
->{server}
&&
exists
$opts
->{username}
&&
exists
$opts
->{password}
&&
exists
$opts
->{project}
&&
exists
$opts
->{name} )
{
$opts
->{description} ||=
""
;
upload_rexfile( %{
$opts
} );
exit
0;
}
if
(
exists
$opts
->{execute}
&&
exists
$opts
->{server}
&&
exists
$opts
->{username}
&&
exists
$opts
->{password}
&&
exists
$opts
->{project}
&&
exists
$opts
->{hosts}
&&
exists
$opts
->{job} )
{
dispatch_execute_job( %{
$opts
} );
exit
0;
}
if
(
exists
$opts
->{search} ) {
my
$search_string
=
$opts
->{search};
print
"Downloading recipes.yml ... "
;
my
$recipes
= get(
$SEARCH_SERVER
);
print
" done.\n"
;
print
"Searching...\n\n"
;
my
$data
= Load(
$recipes
);
for
my
$mod
(
keys
%{
$data
} ) {
if
(
$mod
=~
qr{$search_string}
i ) {
print_found(
$mod
,
$data
->{
$mod
} );
next
;
}
if
(
$data
->{
$mod
}->{Description} =~
qr{$search_string}
i ) {
print_found(
$mod
,
$data
->{
$mod
} );
}
}
exit
0;
}
if
(
exists
$opts
->{
"update-from-git"
} ) {
update_from_git();
exit
0;
}
if
(
exists
$opts
->{init} ) {
if
( -f
$opts
->{init} ) {
download_recipe_local_tar_gz(
$opts
->{init} );
}
else
{
download_recipe_git(
$opts
->{init} );
}
exit
0;
}
if
(
exists
$opts
->{
use
} &&
$ARGV
[0] =~ /^\-\-
use
/ ) {
if
(
$opts
->{
use
} ) {
if
( !
ref
$opts
->{
use
} ) {
$opts
->{
use
} = [
$opts
->{
use
} ];
}
for
my
$use_mod
( @{
$opts
->{
use
} } ) {
download_recipe(
$use_mod
);
}
}
exit
0;
}
if
(
exists
$opts
->{
"resolve-deps"
} &&
$opts
->{
"resolve-deps"
} ) {
resolve_deps(
"meta.yml"
);
exit
0;
}
if
(
exists
$opts
->{
"create-module"
} ) {
my
$dir
=
$ARGV
[0];
my
$module_name
=
$dir
;
if
(
$dir
!~ m/^[a-zA-Z][a-zA-Z_:0-9]+$/ ) {
print
"USAGE: $0 Module::Name --create-module\n"
;
print
" Allowed characters: a-z, A-Z, _, 0-9, '::'.\n"
;
exit
1;
}
if
( -f
"Rexfile"
&&
$opts
->{
"create-module"
} ) {
$dir
=
"lib/$dir"
;
}
if
(
$dir
=~ m/\-\-create\-module/ ) {
print
"USAGE: $0 Module::Name --create-module\n"
;
print
" Allowed characters: a-z, A-Z, _, 0-9, '::'.\n"
;
exit
1;
}
$dir
=~ s/::/\//g;
print
"Creating module $module_name...\n"
;
print
" mkdir $dir\n"
;
mkdir
$dir
,
recursive
=> 1;
chdir
$dir
;
print
" Creating template file: __module__.pm\n"
;
file
"__module__.pm"
,
content
=>
template(
'@module.pm.tpl'
,
dir
=>
$dir
,
module_name
=>
$module_name
);
print
" Creating template file: meta.yml\n"
;
file
"meta.yml"
,
content
=>
template(
'@meta.yml.tpl'
,
dir
=>
$dir
,
module_name
=>
$module_name
);
print
"\n"
;
print
"Your module has been created in $dir.\n"
;
exit
0;
}
my
$dir
=
$ARGV
[0];
if
(
defined
$ARGV
[1] &&
$ARGV
[1] !~ m/^\-\-/ ) {
$dir
=
$ARGV
[1];
}
if
(
$dir
!~ m/^[a-zA-Z][a-zA-Z_:0-9]+$/ ) {
print
"USAGE: $0 Project::Name\n"
;
print
" Allowed characters: a-z, A-Z, 0-9, _, '::'.\n"
;
exit
1;
}
if
(
exists
$opts
->{template}
&& -f
$opts
->{template}
&&
$opts
->{template} !~ m/^\// )
{
my
$cwd
= getcwd;
$opts
->{template} =
"$cwd/"
.
$opts
->{template};
}
elsif
(
exists
$opts
->{template} &&
$opts
->{template} !~ m/^\// ) {
$opts
->{template} =
'@'
.
$opts
->{template};
}
unless
( -d
$dir
) {
print
"Created $dir\n"
;
mkdir
(
$dir
);
}
print
"chdir to $dir\n"
;
chdir
(
$dir
);
unless
( -d
'lib'
) {
mkdir
(
'lib'
);
}
unless
( -f
'lib'
.
$ARGV
[0] .
'.pm'
) {
open
(
my
$fh
,
">"
,
"lib/$ARGV[0].pm"
) or
die
($!);
print
$fh
template(
'@libfile'
,
lib
=>
$ARGV
[0] );
close
(
$fh
);
print
STDERR
"Created lib/Rex/$ARGV[0].pm\n"
;
if
(
$opts
->{template} ) {
open
(
$fh
,
">"
,
"Rexfile"
) or
die
($!);
print
$fh
template(
$opts
->{template},
lib
=>
$ARGV
[0] );
close
(
$fh
);
}
else
{
open
(
$fh
,
">"
,
"Rexfile"
) or
die
($!);
print
$fh
template(
'@rexfile'
,
lib
=>
$ARGV
[0] );
close
(
$fh
);
}
if
(
$opts
->{
use
} ) {
if
( !
ref
$opts
->{
use
} ) {
$opts
->{
use
} = [
$opts
->{
use
} ];
}
for
my
$use_mod
( @{
$opts
->{
use
} } ) {
download_recipe(
$use_mod
);
}
}
print
STDERR
"Created Rexfile.\n"
;
print
STDERR
"Done.\n\nNow edit Rexfile to suit your needs.\n"
;
print
STDERR
"You can edit $dir/lib/$ARGV[0].pm to define tasks.\n"
;
print
STDERR
"\nIf you need assistance, get in touch via one of our support channels!\n"
;
}
else
{
if
(
$opts
->{
use
} ) {
if
( !
ref
$opts
->{
use
} ) {
$opts
->{
use
} = [
$opts
->{
use
} ];
}
for
my
$use_mod
( @{
$opts
->{
use
} } ) {
download_recipe(
$use_mod
);
}
}
exit
;
}
sub
get {
my
(
$url
) =
@_
;
my
$ua
= LWP::UserAgent->new;
$ua
->env_proxy;
if
(
$AUTH_USER
&&
$AUTH_PASSWORD
) {
my
(
$netloc
) = (
$RECIPE_SERVER
=~ m/^https?:\/\/([^\/]+)\// );
unless
(
$netloc
=~ m/\:\d+$/ ) {
if
(
$netloc
=~ m/^https/ ) {
$netloc
.=
":443"
;
}
else
{
$netloc
.=
":80"
;
}
}
$ua
->credentials(
$netloc
,
$AUTH_REALM
,
$AUTH_USER
,
$AUTH_PASSWORD
);
}
my
$resp
=
$ua
->get(
$url
);
if
(
$resp
->is_success ) {
return
$resp
->decoded_content;
}
}