The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

### OPEN SOURCE LICENSE - GNU AFFERO PUBLIC LICENSE Version 3.0 #######
#
# Net::FullAuto - Powerful Network Process Automation Software
# Copyright © 2000-2034 Brian M. Kelly
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but **WITHOUT ANY WARRANTY**; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program. If not, see:
#
#######################################################################
our $VERSION='0.01';
our $DISPLAY='FullAuto RESTful API Server';
our $CONNECT='secure';
our $defaultInstanceType='t2.small';
use 5.005;
use strict;
my $service_and_cert_password='Full@ut0O1';
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw($select_fullautoapi_setup);
use Net::FullAuto::FA_Core qw[$localhost cleanup fetch clean_filehandle];
my $home_dir=File::HomeDir->my_home;
$home_dir||=$ENV{'HOME'}||'';
$home_dir.='/';
my $username=getlogin || getpwuid($<);
my $do;my $ad;my $prompt;my $public_ip='';
my $builddir='';my @ls_tmp=();
my $avail_port='';
my $configure_fullautoapi=sub {
my $selection=$_[0]||'';
my $service_and_cert_password=$_[1]||'';
my $domain_url=$_[2]||'';
my ($stdout,$stderr)=('','');
my $handle=connect_shell();my $connect_error='';
$handle->cwd('~');
my $userhome=$handle->cmd('pwd');
my $sudo=($^O eq 'cygwin')?'':'sudo ';
my $security_group='FullAutoAPISecurityGroup';
($stdout,$stderr)=setup_aws_security(
$security_group,'FullAutoAPI Security Group');
my $c='aws ec2 describe-security-groups '.
"--group-names $security_group";
my ($hash,$output,$error)=('','','');
($hash,$output,$error)=run_aws_cmd($c);
my $cidr=$hash->{SecurityGroups}->[0]->{IpPermissions}
->[0]->{IpRanges}->[0]->{CidrIp};
$c='aws ec2 authorize-security-group-ingress '.
"--group-name $security_group --protocol ".
'tcp --port 80 --cidr '.$cidr." 2>&1";
($hash,$output,$error)=run_aws_cmd($c);
$c='aws ec2 authorize-security-group-ingress '.
"--group-name $security_group --protocol ".
'tcp --port 443 --cidr '.$cidr." 2>&1";
$c='aws ec2 authorize-security-group-ingress '.
"--group-name $security_group --protocol ".
'tcp --port 11211 --cidr '.$cidr." 2>&1";
($hash,$output,$error)=run_aws_cmd($c);
$c='aws ec2 authorize-security-group-ingress '.
"--group-name $security_group --protocol ".
'tcp --port 3000 --cidr '.$cidr." 2>&1";
($hash,$output,$error)=run_aws_cmd($c);
($stdout,$stderr)=$handle->cmd($sudo."perl -e \'use CPAN;".
"CPAN::HandleConfig-\>load;print \$CPAN::Config-\>{build_dir}\'");
$builddir=$stdout;
my $fa_ver=$Net::FullAuto::VERSION;
($stdout,$stderr)=$handle->cmd($sudo.
"ls -1t $builddir | grep Net-FullAuto-$fa_ver");
my @lstmp=split /\n/,$stdout;
foreach my $line (@lstmp) {
unshift @ls_tmp, $line if $line!~/\.yml$/;
}
$do=1;
if ($do==1) {
unless ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd($sudo.
"chmod -v 755 ~",'__display__');
($stdout,$stderr)=$handle->cmd("sudo yum clean all");
($stdout,$stderr)=$handle->cmd("sudo yum grouplist hidden");
($stdout,$stderr)=$handle->cmd("sudo yum groups mark convert");
($stdout,$stderr)=$handle->cmd(
"sudo yum -y groupinstall 'Development tools'",'__display__');
($stdout,$stderr)=$handle->cmd(
'sudo yum -y install openssl-devel icu cyrus-sasl'.
' libicu cyrus-sasl-devel libtool-ltdl-devel libxml2-devel'.
' freetype-devel libpng-devel java-1.7.0-openjdk-devel'.
' unixODBC unixODBC-devel libtool-ltdl libtool-ltdl-devel'.
' ncurses-devel xmlto git-all autoconf','__display__');
} else {
my $cygcheck=`/bin/cygcheck -c` || die $!;
my $uname=`/bin/uname` || die $!;
my $uname_all=`/bin/uname -a` || die $!;
$uname_all.=$uname;
my %need_packages=();
my $srvout='';
($srvout,$stderr)=$handle->cmd("cygrunsrv -L",'__display__');
if ($srvout=~/exim/) {
($stdout,$stderr)=$handle->cmd("cygrunsrv --stop exim",'__display__');
($stdout,$stderr)=$handle->cmd("cygrunsrv -R exim");
}
if ($srvout=~/nginx_first_time/) {
($stdout,$stderr)=$handle->cmd(
"cygrunsrv --stop nginx_first_time",'__display__');
($stdout,$stderr)=$handle->cmd("cygrunsrv -R nginx_first_time");
($stdout,$stderr)=$handle->cmd(
"rm -rvf ${home_dir}FullAutoAPI/deps/nginx*",
'__display__');
}
if ($srvout=~/fullautoapi/) {
($stdout,$stderr)=$handle->cmd("cygrunsrv --stop fullautoapi",
'__display__');
($stdout,$stderr)=$handle->cmd("cygrunsrv -R fullautoapi");
($stdout,$stderr)=$handle->cmd("rm -rvf ${home_dir}FullAutoAPI/lib",
'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf ${home_dir}FullAutoAPI/script",
'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf ${home_dir}FullAutoAPI/root",
'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf ${home_dir}FullAutoAPI/db*",
'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf ${home_dir}FullAutoAPI/inc",
'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf ${home_dir}FullAutoAPI/full*",
'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf ${home_dir}FullAutoAPI/blib",
'__display__');
}
if ($srvout=~/memcached/) {
($stdout,$stderr)=$handle->cmd("cygrunsrv --stop memcached",
'__display__');
($stdout,$stderr)=$handle->cmd("cygrunsrv -R memcached");
($stdout,$stderr)=$handle->cmd(
"rm -rvf ${home_dir}FullAutoAPI/deps/memcached*",
'__display__');
}
if ($uname_all=~/x86_64/) {
foreach my $package ('libxml2','libxml2-devel','libtool',
'autoconf','autobuild','automake','pkg-config',
'libuuid-devel','wget','git','httpd',
'httpd-mod_ssl','httpd-tools','exim','zip') {
unless (-1<index $cygcheck, "$package ") {
$need_packages{$package}='';
}
}
} else {
foreach my $package ('libxml2','libxml2-devel','libtool',
'autoconf','autobuild','automake','pkg-config',
'libuuid-devel','wget','git','httpd','httpd-mod_ssl',
'httpd-tools','exim','zip') {
unless (-1<index $cygcheck, "$package ") {
$need_packages{$package}='';
}
}
}
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'chown -v $username:$username master.zip','__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd("unzip -o master.zip",'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf master.zip",'__display__');
($stdout,$stderr)=$handle->cmd("mv apt-cyg-master/apt-cyg /usr/bin");
($stdout,$stderr)=$handle->cmd($sudo."chmod -v 755 /usr/bin/apt-cyg",
'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf apt-cyg-master",'__display__');
my $packs='';$|=1;
foreach my $pack (sort keys %need_packages) {
($stdout,$stderr)=$handle->cmd("apt-cyg install $pack",
'__display__');
}
if ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cwd('~');
# smtp-mail-server-with-windows.html
($stdout,$stderr)=$handle->cmd(
"chmod -v 755 /usr/bin/exim*",'__display__');
$handle->print('/bin/exim-config');
$prompt=$handle->prompt();
while (1) {
my $output=fetch($handle);
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'local postmaster') {
$handle->print();
} elsif (-1<index $output,'Is it') {
$handle->print('yes');
} elsif (-1<index $output,'change that setting') {
$handle->print('no');
} elsif (-1<index $output,'standard values') {
$handle->print('yes');
} elsif (-1<index $output,'be links to') {
$handle->print('yes');
} elsif (-1<index $output,'some CPAN') {
$handle->print('no');
} elsif (-1<index $output,'install the exim') {
$handle->print('yes');
} elsif (-1<index $output,'in minutes') {
$handle->print();
} elsif (-1<index $output,'CYGWIN for the daemon') {
$handle->print('default');
} elsif (-1<index $output,'the cygsla package') {
$handle->print('yes');
} elsif (-1<index $output,'another privileged account') {
$handle->print('no');
} elsif (-1<index $output,'enter the password') {
$handle->print($service_and_cert_password);
} elsif (-1<index $output,'Reenter') {
$handle->print($service_and_cert_password);
} elsif (-1<index $output,'start the exim') {
$handle->print('yes');
}
next;
}
}
#if ($packs) {
# print "\n\n Fatal Error!: The following Cygwin",
# "\n packages are missing from",
# "\n your installation:",
# "\n\n $packs",
# "\n\n Please report any bugs and send any",
# "\n questions, thoughts or feedback to:",
# "\n\n Brian.Kelly\@FullAuto.com.",
# "\n\n";
# &Net::FullAuto::FA_Core::cleanup;
#}
#print "\nInstalling Microsoft IIS Web Server . . .\n\n";
# installing-iis-85-on-windows-server-2012-r2
#($stdout,$stderr)=$handle->cmd("DISM.EXE /enable-feature /all ".
# "/online /featureName:IIS-WebServerRole /featureName:IIS-WebServer ".
# "/featureName:IIS-CommonHttpFeatures /featureName:IIS-StaticContent ".
# "/featureName:IIS-DefaultDocument /featureName:IIS-DirectoryBrowsing ".
# "/featureName:IIS-HttpErrors /featureName:IIS-HttpRedirect ".
# "/featureName:IIS-ApplicationDevelopment /featureName:IIS-ASPNET ".
# "/featureName:IIS-NetFxExtensibility /featureName:IIS-ASPNET45 ".
# "/featureName:IIS-NetFxExtensibility45 /featureName:IIS-ASP ".
# "/featureName:IIS-CGI /featureName:IIS-ISAPIExtensions ".
# "/featureName:IIS-ISAPIFilter /featureName:IIS-ServerSideIncludes ".
# "/featureName:IIS-HealthAndDiagnostics /featureName:IIS-HttpLogging ".
# "/featureName:IIS-LoggingLibraries /featureName:IIS-RequestMonitor ".
# "/featureName:IIS-HttpTracing /featureName:IIS-CustomLogging ".
# "/featureName:IIS-ODBCLogging /featureName:IIS-Security ".
# "/featureName:IIS-BasicAuthentication ".
# "/featureName:IIS-WindowsAuthentication ".
# "/featureName:IIS-DigestAuthentication ".
# "/featureName:IIS-ClientCertificateMappingAuthentication ".
# "/featureName:IIS-IISCertificateMappingAuthentication ".
# "/featureName:IIS-URLAuthorization /featureName:IIS-RequestFiltering ".
# "/featureName:IIS-IPSecurity /featureName:IIS-Performance ".
# "/featureName:IIS-HttpCompressionStatic ".
# "/featureName:IIS-HttpCompressionDynamic /featureName:IIS-WebDAV ".
# "/featureName:IIS-WebServerManagementTools ".
# "/featureName:IIS-ManagementScriptingTools ".
# "/featureName:IIS-ManagementService ".
# "/featureName:IIS-IIS6ManagementCompatibility ".
# "/featureName:IIS-Metabase /featureName:IIS-WMICompatibility ".
# "/featureName:IIS-LegacyScripts /featureName:NetFx4Extended-ASPNET45 ".
# "/featureName:IIS-ApplicationInit /featureName:IIS-WebSockets ".
# "/featureName:IIS-CertProvider /featureName:IIS-ManagementConsole ".
# "/featureName:IIS-LegacySnapIn",'__display__');
#($stdout,$stderr)=$handle->cmd("DISM.EXE /online /enable-feature ".
# "/featureName:IIS-WebServerRole /featureName:IIS-WebServer ".
# "/featureName:IIS-CommonHttpFeatures /featureName:IIS-StaticContent ".
# "/featureName:IIS-DefaultDocument /featureName:IIS-DirectoryBrowsing ".
# "/featureName:IIS-HttpErrors /featureName:IIS-HealthAndDiagnostics ".
# "/featureName:IIS-HttpLogging /featureName:IIS-Performance ".
# "/featureName:IIS-HttpCompressionStatic /featureName:IIS-Security ".
# "/featureName:IIS-RequestFiltering /featureName:IIS-CGI ".
# "/featureName:IIS-WebServerManagementTools ".
# "/featureName:IIS-ManagementConsole",'__display__');
#my $appcmd="$ENV{WINDIR}/SYSTEM32/inetsrv";
#($appcmd,$stderr)=$handle->cmd("cygpath -u $appcmd");
#my $cyglocb=$handle->cmd("cygpath -w /");
#my $cyglocw=$handle->cmd("cygpath -w ~");
#my $cyglocwf="$cyglocw\\FullAutoAPI";
#$cyglocw=~s/\\/\\\\/g;
#$cyglocwf=~s/\\/\\\\/g;
#($stdout,$stderr)=$handle->cwd($appcmd);
#($stdout,$stderr)=$handle->cmd("pwd",'__display__');
#my $sleep=0;
#while (1==1) {
# my $ls_output=$handle->cmd("ls -1");
# last if -1<index $ls_output,'appcmd.exe';
# sleep 2;
# last if $sleep++>300;
#}
#sleep 5;
#($stdout,$stderr)=$handle->cmd("./appcmd add site /name:FullAutoAPI ".
# "/id:2 /physicalPath:$cyglocwf\\root /bindings:http/*:4000",
# '__display__');
#sleep 2;
#($stdout,$stderr)=$handle->cmd("./appcmd set config -section:".
# "system.webServer/fastCgi /+[\"fullpath=\'$cyglocb\\script\\".
# "CGI_script.bat\',arguments=\'$cyglocwf\\script\\".
# "fullautoapi_fastcgi.pl -e\',maxInstances=\'4\',".
# "idleTimeout=\'300\',activityTimeout=\'30\',requestTimeout='\90\',".
# "instanceMaxRequests=\'1000\',protocol=\'NamedPipe\',".
# "flushNamedPipe=\'False\']\" /commit:apphost",'__display__');
#sleep 2;
#($stdout,$stderr)=$handle->cmd("./appcmd set config -section:".
# "system.webServer/handlers /+\"[name=\'FullAutoAPI\',".
# "path=\'*\',verb=\'GET,HEAD,POST\',modules=".
# "\'FastCgiModule\',scriptProcessor=\'$cyglocb\\script\\".
# "CGI_Script.bat|$cyglocwf\\script\\fullautoapi_fastcgi.pl -e\',".
# "resourceType=\'Unspecified\',requireAccess=\'Script\']\" ".
# "/commit:apphost",'__display__');
#($stdout,$stderr)=$handle->cwd("FullAutoAPI/script");
#($stdout,$stderr)=$handle->cmd("touch CGI_Script.bat");
#
# echo-ing/streaming files over ssh can be tricky. Use echo -e
# and replace these characters with thier HEX
# equivalents (use an external editor for quick
# search and replace - and paste back results.
# use copy/paste or cat file and copy/paste results.):
#
# ! - \\x21 ` - \\x60
# " - \\x22 \ - \\x5C
# $ - \\x24 % - \\x25
#
#$cyglocb=~s/\\/\\x5C/g;
#my $content=<<END;
#$cyglocb\\x5Cbin\\x5Cbash -lc \\x22/bin/perl \\x251 \\x252\\x22
#END
#($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > CGI_Script.bat");
#($stdout,$stderr)=$handle->cwd("~");
#($stdout,$stderr)=$handle->cmd("iisreset /start",'__display__');
}
###############
## RABBITMQ
###############
#($stdout,$stderr)=$handle->cmd(
# "wget --random-wait --progress=dot ".
# '__display__');
#($stdout,$stderr)=$handle->cmd("unzip -o maint.zip",'__display__');
#($stdout,$stderr)=$handle->cmd("rm -rvf maint.zip",'__display__');
#($stdout,$stderr)=$handle->cwd("otp-maint");
#($stdout,$stderr)=$handle->cmd("export ERL_TOP=`pwd`",'__display__');
#($stdout,$stderr)=$handle->cmd("./otp_build autoconf");
#($stdout,$stderr)=$handle->cmd("./configure",'__display__');
#($stdout,$stderr)=$handle->cmd("sudo make install",'__display__');
#($stdout,$stderr)=$handle->cwd("..");
#($stdout,$stderr)=$handle->cmd("sudo sed -i ".
# "'s#secure_path = #secure_path = /usr/local/bin:/usr/local/sbin:#'".
# " /etc/sudoers");
#($stdout,$stderr)=$handle->cmd("wget -qO- ".
#my $source_flag=0;
#my $rmq='';my $rmqtar='';my $rmqdir='';
#foreach my $line (split "\n", $stdout) {
# if ($line=~/Source/) {
# $source_flag=1;
# } elsif ($source_flag) {
# $rmq=$line;
# $rmq=~s/^.*href=["](.*?)["].*$/$1/;
# $rmq='https://www.rabbitmq.com'.$rmq;
# ($rmqtar=$rmq)=~s/^.*\/(.*)$/$1/;
# ($rmqdir=$rmqtar)=~s/^(.*).tar.gz/$1/;
# last;
# }
#}
#($stdout,$stderr)=$handle->cmd(
# "wget --random-wait --progress=dot ".$rmq,'__display__');
#($stdout,$stderr)=$handle->cmd("tar zxvf $rmqtar",'__display__');
#($stdout,$stderr)=$handle->cmd("rm -rvf $rmqtar",'__display__');
#($stdout,$stderr)=$handle->cwd($rmqdir);
#$handle->print('sudo su');
#$prompt=$handle->prompt();
#while (1) {
# my $output.=Net::FullAuto::FA_Core::fetch($handle);
# last if $output=~/$prompt/;
# print $output;
#}
#$handle->print('export TARGET_DIR=/usr/local');
#while (1) {
# my $output.=Net::FullAuto::FA_Core::fetch($handle);
# last if $output=~/$prompt/;
# print $output;
#}
#$handle->print('export SBIN_DIR=/usr/local');
#while (1) {
# my $output.=Net::FullAuto::FA_Core::fetch($handle);
# last if $output=~/$prompt/;
# print $output;
#}
#$handle->print('export MAN_DIR=/usr/local');
#while (1) {
# my $output.=Net::FullAuto::FA_Core::fetch($handle);
# last if $output=~/$prompt/;
# print $output;
#}
#$handle->print('make install');
#while (1) {
# my $output.=Net::FullAuto::FA_Core::fetch($handle);
# last if $output=~/$prompt/;
# print $output;
#}
#$handle->print('exit');
#while (1) {
# my $output.=Net::FullAuto::FA_Core::fetch($handle);
# last if $output=~/$prompt/;
# print $output;
#}
#($stdout,$stderr)=$handle->cwd("..");
#($stdout,$stderr)=$handle->cmd(
# "wget --random-wait --progress=dot ".
# '__display__');
#($stdout,$stderr)=$handle->cmd("unzip -o master.zip",'__display__');
#($stdout,$stderr)=$handle->cmd("rm -rvf master.zip",'__display__');
#($stdout,$stderr)=$handle->cmd("sudo rabbitmq-server -detached",
# '__display__');
# TEST FOR AMAZON EC2 INSTANCE
#($stdout,$stderr)=$handle->cmd('wget --timeout=5 --tries=1 -qO- '.
#$public_ip=$stdout if $stdout=~/^\d+\.\d+\.\d+\.\d+\s*/s;
#my $z=1;
#while ($z==1) {
# ($stdout,$stderr)=$handle->cmd("ps -ef",'__display__');
# if ($stdout=~/nginx/) {
# my @psinfo=();
# foreach my $line (split /\n/, $stdout) {
# next unless -1<index $line, 'nginx';
# @psinfo=split /\s+/, $line;
# ($stdout,$stderr)=$handle->cmd($sudo."kill -9 $psinfo[2]");
# } last
# } else { last }
#}
($stdout,$stderr)=$handle->cmd($sudo."pkill nginx");
($stdout,$stderr)=$handle->cmd($sudo."rm -rvf /usr/local/nginx",'__display__');
($stdout,$stderr)=$handle->cmd("wget -qO- https://icanhazip.com");
$public_ip=$stdout if $stdout=~/^\d+\.\d+\.\d+\.\d+\s*/s;
unless ($public_ip) {
require Sys::Hostname;
import Sys::Hostname;
require Socket;
import Socket;
my($addr)=inet_ntoa((gethostbyname(Sys::Hostname::hostname))[4]);
$public_ip=$addr if $addr=~/^\d+\.\d+\.\d+\.\d+\s*/s;
}
chomp($public_ip);
$public_ip='127.0.0.1' unless $public_ip;
unless ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
"/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username epel-release-6-8.noarch.rpm",
'__display__') if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd(
"sudo rpm -ivh epel-release-6-8.noarch.rpm",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'rm -rvf epel-release-6-8.noarch.rpm',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.'yum -y install uuid-devel '.
'pkgconfig libtool gcc-c++','__display__');
}
($stdout,$stderr)=$handle->cmd('mkdir -vp FullAutoAPI/deps',
'__display__');
($stdout,$stderr)=$handle->cmd(
'mkdir -vp FullAutoAPI/root/static/images',
'__display__');
#($stdout,$stderr)=$handle->cmd("${sudo}perl -e \'use CPAN;".
# "CPAN::HandleConfig-\>load;print \$CPAN::Config-\>{build_dir}\'");
#$builddir=$stdout;
#my $fa_ver=$Net::FullAuto::VERSION;
#($stdout,$stderr)=$handle->cmd(
# "${sudo}ls -1t $builddir | grep Net-FullAuto-$fa_ver");
#my @lstmp=split /\n/,$stdout;
#foreach my $line (@lstmp) {
# unshift @ls_tmp, $line if $line!~/\.yml$/;
#}
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/Docker_is.py ".
"FullAutoAPI",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/automates_everything.jpg ".
"FullAutoAPI/root/static/images",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/automationapi.jpg ".
"FullAutoAPI/root/static/images",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/fullauto_com.jpg ".
"FullAutoAPI/root/static/images",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/".
"South-Shore-Food-Market-Ghost-sign_with_FA_1_faded_1024.jpg ".
"FullAutoAPI/root/static/images",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/zeromq.jpg ".
"FullAutoAPI/root/static/images",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/nginx.png ".
"FullAutoAPI/root/static/images",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/wrapper.tt2 ".
"FullAutoAPI/root",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/installer/FA.ico ".
"FullAutoAPI/root/favicon.ico",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chmod -v 755 FullAutoAPI/root/static/images/*",
'__display__');
($stdout,$stderr)=$handle->cwd("FullAutoAPI/deps");
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username autoconf-latest.tar.gz",'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd("tar zxvf autoconf-latest.tar.gz",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.'rm -rvf autoconf-latest.tar.gz',
'__display__');
($stdout,$stderr)=$handle->cwd("autoconf-*");
($stdout,$stderr)=$handle->cmd("./configure",'__display__');
($stdout,$stderr)=$handle->cmd("make",'__display__');
($stdout,$stderr)=$handle->cmd($sudo."make install",'__display__');
($stdout,$stderr)=$handle->cwd("..");
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username master.zip",'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd("unzip -o master.zip",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.'rm -rvf master.zip','__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -Rv $username:$username libsodium-master",'3600')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cwd('libsodium-master');
($stdout,$stderr)=$handle->cmd('./autogen.sh','__display__');
($stdout,$stderr)=$handle->cmd('./configure','__display__');
($stdout,$stderr)=$handle->cmd('make','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'make install','__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
$do=1;
if ($do==1) { # INSTALL LATEST VERSION OF PYTHON
($stdout,$stderr)=$handle->cmd($sudo.
$stdout=~s/^.*list-row-container menu.*?Python (.*?)[<].*$/$1/s;
my $version=$stdout;
($stdout,$stderr)=$handle->cmd($sudo.
"if test -f /usr/local/bin/python$version; then echo Exists; fi");
unless ($stdout=~/Exists/) {
($stdout,$stderr)=$handle->cmd($sudo.
'wget --random-wait --progress=dot '.
"http://python.org/ftp/python/$version/Python-$version.tar.xz",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"tar xvf Python-$version.tar.xz",
'__display__');
($stdout,$stderr)=$handle->cwd("Python-$version");
($stdout,$stderr)=$handle->cmd($sudo.
'./configure --prefix=/usr/local --exec-prefix=/usr/local '.
'--enable-shared --enable-optimizations '.
'LDFLAGS="-Wl,-rpath /usr/local/lib"',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'make','3600','__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'make altinstall','__display__');
$version=~s/^(\d+\.\d+).*$/$1/;
($stdout,$stderr)=$handle->cmd($sudo.
"ln -s /usr/local/bin/python$version /usr/local/bin/python");
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
($stdout,$stderr)=$handle->cmd($sudo.
"/usr/local/bin/python$version -m ensurepip --default-pip",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"/usr/local/bin/python$version -m pip install ".
"--upgrade pip setuptools wheel",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"/usr/local/bin/python$version -m pip install pyasn1",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"/usr/local/bin/python$version -m pip install pyasn1-modules",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"/usr/local/bin/python$version -m pip install --upgrade oauth2client",
'__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
($stdout,$stderr)=$handle->cmd($sudo.
"/usr/local/bin/python$version -m pip install oauth2",
'__display__');
unless ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd('echo /usr/local/lib > '.
'~/local.conf','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'chmod -v 644 ~/local.conf',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'mv -v ~/local.conf /etc/ld.so.conf.d','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'ldconfig');
} else {
($stdout,$stderr)=$handle->cmd(
"python$version -m pip install awscli",
'__display__');
}
$sudo='sudo env "PATH=$PATH" ';
($stdout,$stderr)=$handle->cmd($sudo.
'python --version','__display__');
}
}
$do=0;
if ($do==1) {
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
if ($^O eq 'cygwin') {
# ez_setup.py uses curl by default which is broken with --location
# in Cygwin. So using wget instead by forcing return False.
($stdout,$stderr)=$handle->cmd(
"sed -i '/has_curl()/areturn False' ez_setup.py");
$handle->cmd_raw(
"sed -i 's/\\(^return False$\\\)/ \\1/' ez_setup.py");
} else {
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username ez_setup.py",'__display__');
}
($stdout,$stderr)=$handle->cmd('python ez_setup.py','__display__');
($stdout,$stderr)=$handle->cmd('easy_install pip','__display__');
# ($stdout,$stderr)=$handle->cmd(
# 'git clone https://github.com/pypa/setuptools.git','__display__');
# ($stdout,$stderr)=$handle->cmd(
# 'chown -Rv $username:$username setuptools','__display__')
# if $^O ne 'cygwin';
# ($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps/setuptools');
#print "OK1\n";
# ($stdout,$stderr)=$handle->cmd($sudo.'python setup.py install',
# '__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
($stdout,$stderr)=$handle->cmd(
'git clone https://github.com/google/oauth2client.git','__display__');
($stdout,$stderr)=$handle->cwd('oauth2client');
($stdout,$stderr)=$handle->cmd($sudo.'python setup.py install',
'__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
unless ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd($sudo.'pip install httplib2','__display__');
($stdout,$stderr)=$handle->cmd($sudo."ls -1 ".
"/usr/local/lib/python2.7/site-packages",'__display__');
$stdout=~s/^.*(httplib2.*?egg).*$/$1/s;
($stdout,$stderr)=$handle->cmd($sudo."chmod o+r -v -R ".
"/usr/local/lib/python2.7/site-packages/$stdout",
'__display__');
}
($stdout,$stderr)=$handle->cmd($sudo.'pip install oauth2','__display__');
unless ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd('echo /usr/local/lib > '.
'local.conf','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'chmod -v 644 local.conf',
'__display__');
($stdout,$stderr)=$handle->cmd(
$sudo.'mv -v local.conf /etc/ld.so.conf.d','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'ldconfig');
} else {
($stdout,$stderr)=$handle->cmd('pip install awscli','__display__');
}
}
}
$do=1;
if ($do==1) {
($stdout,$stderr)=$handle->cmd($sudo.
'__display__');
($stdout,$stderr)=$handle->cwd('zeromq4-x');
my $zmq_branch='v4.0.1';
($stdout,$stderr)=$handle->cmd($sudo.
"git checkout $zmq_branch",'__display__');
if ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd("./autogen.sh",'__display__');
$handle->cmd_raw('export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig');
($stdout,$stderr)=$handle->cmd('./configure','__display__');
my $ad=" -no-undefined \\%NL%".
" -avoid-version \\";
($stdout,$stderr)=$handle->cmd(
"sed -i \'/^libzmq_la_LDFLAGS = \\/a$ad\' ./Makefile");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
"./Makefile");
} else {
# Following cmd shows default pkg-config locations
# pkg-config --variable pc_path pkg-config
$handle->cmd_raw('export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig');
my $e='PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ';
($stdout,$stderr)=$handle->cmd($sudo.$e."./autogen.sh",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.$e.'./configure','__display__');
my $ad="Defaults env_keep += \"PKG_CONFIG_PATH\"";
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'/_XKB_CHARSET/a$ad\' /etc/sudoers")
}
($stdout,$stderr)=$handle->cmd($sudo.'make','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'make install','__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
}
$do=1;
if ($do==1) { # INSTALL LATEST VERSION OF NGINX
# -dont-trust-the-tutorials-check-your-configuration/
# understanding-and-implementing-fastcgi-proxying-in-nginx
# Manual/Deployment/nginx/FastCGI.pod
#($stdout,$stderr)=$handle->cmd($sudo.'groupadd www-data');
#($stdout,$stderr)=$handle->cmd($sudo.'adduser -r -m -g www-data www-data');
#$handle->print($sudo.'passwd www-data');
my $prompt=$handle->prompt();
while (0) {
my $output.=fetch($handle);
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'New password:') {
$handle->print($service_and_cert_password);
$output='';
next;
} elsif (-1<index $output,'Retype new password:') {
$handle->print($service_and_cert_password);
$output='';
next;
}
}
my $nginx_path='/etc';
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
($stdout,$stderr)=$handle->cmd($sudo.
'rm -rvf /etc/nginx','__display__');
($stdout,$stderr)=$handle->cmd($sudo.
$stdout=~s/^.*Mainline.*?\/download\/(.*?)\.tar\.gz.*$/$1/s;
my $nginx=$stdout;
($stdout,$stderr)=$handle->cmd($sudo."wget --random-wait --progress=dot ".
"http://nginx.org/download/$nginx.tar.gz",300,'__display__');
($stdout,$stderr)=$handle->cmd($sudo."tar xvf $nginx.tar.gz",'__display__');
($stdout,$stderr)=$handle->cwd($nginx);
($stdout,$stderr)=$handle->cmd($sudo."mkdir -vp objs/lib",'__display__');
($stdout,$stderr)=$handle->cwd("objs/lib");
($stdout,$stderr)=$handle->cmd("wget -qO- https://ftp.pcre.org/pub/pcre/");
my %pcre=();
my %conv=(
Jan => 0, Feb => 1, Mar => 2, Apr => 3, May => 4, Jun => 5, Jul => 6,
Aug => 7, Sep => 8, Oct => 9, Nov => 10, Dec => 11
);
foreach my $line (split /\n/, $stdout) {
last unless $line;
$line=~/^.*?["](.*?)["].*(\d\d-\w\w\w-\d\d\d\d \d\d:\d\d).*(\d+\w).*$/;
my $file=$1;my $date=$2;my $size=$3;
next if $file=~/^pcre2|\.sig$|\.tar\.gz$|\.tar\.bz2$/;
next if $file!~/\.zip$/;
next unless $date;
$date=~/^(\d\d)-(\w\w\w)-(\d\d\d\d) (\d\d):(\d\d)$/;
my $day=$1;my $month=$2;my $year=$3;my $hour=$4,my $minute=$5;
my $timestamp=timelocal(0,$minute,$hour,$day,$conv{$month},--$year);
$pcre{$timestamp}=[$file,$size];
}
my $latest=(reverse sort keys %pcre)[0];
my $pcre=$pcre{$latest}->[0];
$pcre=~s/\.[^\.]+$//;
my $checksum='';
foreach my $cnt (1..3) {
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
"https://ftp.pcre.org/pub/pcre/$pcre.tar.gz",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"tar xvf $pcre.tar.gz",'__display__');
last unless $stderr;
($stdout,$stderr)=$handle->cmd($sudo.
"rm -rfv $pcre.tar.gz",'__display__');
}
($stdout,$stderr)=$handle->cmd($sudo.
my $zlib_ver=$stdout;
my $sha__256=$stdout;
$zlib_ver=~s/^.*? source code, version (\d+\.\d+\.\d+).*$/$1/s;
$sha__256=~s/^.*?SHA-256 hash [<]tt[>](.*?)[<][\/]tt[>].*$/$1/s;
foreach my $count (1..3) {
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
"http://zlib.net/zlib-$zlib_ver.tar.gz",'__display__');
$checksum=$sha__256;
($stdout,$stderr)=$handle->cmd($sudo.
"sha256sum -c - <<<\"$checksum zlib-$zlib_ver.tar.gz\"",
'__display__');
unless ($stderr) {
print(qq{ + CHECKSUM Test for zlib-$zlib_ver *PASSED* \n});
last
} elsif ($count>=3) {
print "FATAL ERROR! : CHECKSUM Test for ".
"zlib-$zlib_ver.tar.gz *FAILED* ",
"after $count attempts\n";
cleanup;
}
($stdout,$stderr)=$handle->cmd($sudo.
"rm -rvf zlib-$zlib_ver.tar.gz",'__display__');
}
($stdout,$stderr)=$handle->cmd($sudo."tar xvf zlib-$zlib_ver.tar.gz",
'__display__');
my $ossl='openssl-1.1.1c';
foreach my $count (1..3) {
$checksum='71b830a077276cbeccc994369538617a21bee808';
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"sha1sum -c - <<<\"$checksum $ossl.tar.gz\"",'__display__');
unless ($stderr) {
print(qq{ + CHECKSUM Test for $ossl *PASSED* \n});
last
} elsif ($count>=3) {
print "FATAL ERROR! : CHECKSUM Test for $ossl.tar.gz *FAILED* ",
"after $count attempts\n";
cleanup;
}
($stdout,$stderr)=$handle->cmd($sudo.
"rm -rvf $ossl.tar.gz",'__display__');
}
($stdout,$stderr)=$handle->cmd($sudo."tar xvf $ossl.tar.gz",'__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
# how-to-install-self-signed-certificates-on-nginx-webserver/
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI/deps/$nginx");
#
# echo-ing/streaming files over ssh can be tricky. Use echo -e
# and replace these characters with thier HEX
# equivalents (use an external editor for quick
# search and replace - and paste back results.
# use copy/paste or cat file and copy/paste results.):
#
# ! - \\x21 ` - \\x60 * - \\x2A
# " - \\x22 \ - \\x5C
# $ - \\x24 % - \\x25
#
# https://www.lisenet.com/2014/ - bash approach to conversion
my $inet_d_script=<<'END';
#\\x21/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# pidfile: /var/run/nginx.pid
# user: nginx
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ \\x22\\x24NETWORKING\\x22 = \\x22no\\x22 ] && exit 0
nginx=\\x22/usr/sbin/nginx\\x22
prog=\\x24(basename \\x24nginx)
NGINX_CONF_FILE=\\x22/etc/nginx/nginx.conf\\x22
lockfile=/var/run/nginx.lock
start() {
[ -x \\x24nginx ] || exit 5
[ -f \\x24NGINX_CONF_FILE ] || exit 6
echo -n \\x24\\x22Starting \\x24prog: \\x22
daemon \\x24nginx -c \\x24NGINX_CONF_FILE
retval=\\x24?
echo
[ \\x24retval -eq 0 ] && touch \\x24lockfile
return \\x24retval
}
stop() {
echo -n \\x24\\x22Stopping \\x24prog: \\x22
killproc \\x24prog -QUIT
retval=\\x24?
echo
[ \\x24retval -eq 0 ] && rm -f \\x24lockfile
return \\x24retval
}
restart() {
configtest || return \\x24?
stop
start
}
reload() {
configtest || return \\x24?
echo -n \\x24\\x22Reloading \\x24prog: \\x22
killproc \\x24nginx -HUP
RETVAL=\\x24?
echo
}
force_reload() {
restart
}
configtest() {
\\x24nginx -t -c \\x24NGINX_CONF_FILE
}
rh_status() {
status \\x24prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case \\x22\\x241\\x22 in
start)
rh_status_q && exit 0
\\x241
;;
stop)
rh_status_q || exit 0
\\x241
;;
restart|configtest)
\\x241
;;
reload)
rh_status_q || exit 7
\\x241
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo \\x24\\x22Usage: \\x240 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}\\x22
exit 2
esac
END
($stdout,$stderr)=$handle->cmd("echo -e \"$inet_d_script\" > ".
"~/nginx");
($stdout,$stderr)=$handle->cmd($sudo.'mv -fv ~/nginx /etc/init.d',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.'chmod -v +x /etc/init.d/nginx',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo."chkconfig --add nginx");
($stdout,$stderr)=$handle->cmd($sudo."chkconfig --level 345 nginx on");
($stdout,$stderr)=$handle->cmd($sudo.
'yum -y install certbot-nginx','__display__');
# how-to-secure-nginx-with-let-s-encrypt-on-centos-7
my $make_nginx="./configure --user=$username ".
"--group=$username ".
"--prefix=$nginx_path/nginx ".
'--sbin-path=/usr/sbin/nginx '.
"--conf-path=$nginx_path/nginx/nginx.conf ".
'--pid-path=/var/run/nginx.pid '.
'--lock-path=/var/run/nginx.lock '.
'--error-log-path=/var/log/nginx/error.log '.
'--http-log-path=/var/log/nginx/access.log '.
"--with-http_ssl_module --with-pcre=objs/lib/$pcre ".
"--with-zlib=objs/lib/zlib-$zlib_ver ".
'--with-http_gzip_static_module '.
'--with-http_ssl_module '.
'--with-file-aio '.
'--with-http_realip_module '.
'--without-http_scgi_module '.
'--without-http_uwsgi_module '.
'--with-http_v2_module';
($stdout,$stderr)=$handle->cmd($sudo.$make_nginx,'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i 's/-Werror //' ./objs/Makefile");
($stdout,$stderr)=$handle->cmd($sudo.'make install','__display__');
# how-to-install-self-signed-certificates-on-nginx-webserver/
my $ngx="$nginx_path/nginx/nginx.conf";
($stdout,$stderr)=$handle->cmd($sudo."sed -i 's/1024/64/' ".$ngx);
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i 's/worker_processes 1;/worker_processes 2;/' ".$ngx);
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i '0,/root html/{//d;}' ".$ngx);
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i '0,/index index.html/{//d;}' ".$ngx);
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'/koi8-r/a%NL% root ${home_dir}FullAutoAPI/root;\' ".
$ngx);
$handle->cmd_raw($sudo.
"sed -i 's/\\(^root.*;$\\\)/ \\1/' $ngx");
$ad=' include fastcgi_params;%NL%'.
" fastcgi_param SCRIPT_NAME %SQ%%SQ%;%NL%".
' fastcgi_param PATH_INFO $fastcgi_script_name;%NL%'.
' fastcgi_pass unix:/tmp/fullautoapi.socket;';
$ad=<<END;
sed -i '1,/location/ {/location/a\\\
$ad
}' $ngx
END
$handle->cmd_raw($sudo.$ad);
$ad='%NL% location /static {'.
"%NL% root ${home_dir}FullAutoAPI/root;".
'%NL% }%NL%';
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'/404/a$ad\' ".$ngx);
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".$ngx);
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \"s/%SQ%/\'/g\" ".$ngx);
foreach my $port (443,444,445,443) {
$avail_port=
`true &>/dev/null </dev/tcp/127.0.0.1/$port && echo open || echo closed`;
my $status=$avail_port;
$avail_port=$port;
chomp($status);
last if $status eq 'closed';
}
$ad='client_max_body_size 10M;';
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'/octet-stream/i$ad\' ".$ngx);
$handle->cmd_raw($sudo.
"sed -i 's/\\(^client_max_body_size 10M;$\\\)/ \\1/' $ngx");
#($stdout,$stderr)=$handle->cmd($sudo.
# "sed -i \'s/^ listen 80/ listen ".
# "\*:$avail_port ssl http2 default_server/\' ".
# $nginx_path."/nginx/nginx.conf");
#($stdout,$stderr)=$handle->cmd($sudo.
# "sed -i 's/SCRIPT_NAME/PATH_INFO/' ".
# $nginx_path."/local/nginx/fastcgi_params");
#$ad='# Catalyst requires setting PATH_INFO (instead of SCRIPT_NAME)'.
# ' to \$fastcgi_script_name';
#($stdout,$stderr)=$handle->cmd($sudo.
# "sed -i \'/PATH_INFO/i$ad\' $nginx_path/nginx/fastcgi_params");
#$ad='fastcgi_param SCRIPT_NAME /;';
#($stdout,$stderr)=$handle->cmd($sudo.
# "sed -i \'/PATH_INFO/a$ad\' $nginx_path/nginx/fastcgi_params");
#($stdout,$stderr)=$handle->cmd($sudo.
# "sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
# "$nginx_path/nginx/fastcgi_params");
#
# echo-ing/streaming files over ssh can be tricky. Use echo -e
# and replace these characters with thier HEX
# equivalents (use an external editor for quick
# search and replace - and paste back results.
# use copy/paste or cat file and copy/paste results.):
#
# ! - \\x21 ` - \\x60 * - \\x2A
# " - \\x22 \ - \\x5C
# $ - \\x24 % - \\x25
#
# https://www.lisenet.com/2014/ - bash approach to conversion
my $script=<<END;
use Net::FullAuto;
\\x24Net::FullAuto::FA_Core::debug=1;
my \\x24handle=connect_shell();
\\x24handle->print('$nginx_path/nginx/nginx -g \\x22daemon on;\\x22');
\\x24prompt=\\x24handle->prompt();
my \\x24output='';my \\x24password_not_submitted=1;
while (1) {
eval {
local \\x24SIG{ALRM} = sub { die \\x22alarm\\x5Cn\\x22 };# \\x5Cn required
alarm 10;
my \\x24output=fetch(\\x24handle);
last if \\x24output=~/\\x24prompt/;
print \\x24output;
if ((-1<index \\x24output,'Enter PEM pass phrase:') &&
\\x24password_not_submitted) {
\\x24handle->print(\\x24ARGV[0]);
\\x24password_not_submitted=0;
}
};
if (\\x24\@) {
\\x24handle->print();
next;
}
}
exit 0;
END
if ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cwd("~/WordPress");
my $vimrc=<<END;
set paste
set mouse-=a
END
($stdout,$stderr)=$handle->cmd("echo -e \"$vimrc\" > ~/.vimrc");
($stdout,$stderr)=$handle->cmd("mkdir -vp script",'__display__');
($stdout,$stderr)=$handle->cmd("touch script/start_nginx.pl");
($stdout,$stderr)=$handle->cmd("chmod -v 755 script/start_nginx.pl",
'__display__');
($stdout,$stderr)=$handle->cmd("chmod o+r $nginx_path/nginx/*",
'__display__');
($stdout,$stderr)=$handle->cmd("chmod -v 755 $nginx_path/nginx/nginx.exe",
'__display__');
($stdout,$stderr)=$handle->cmd("echo -e \"$script\" > ".
"script/start_nginx.pl");
($stdout,$stderr)=$handle->cmd("cygrunsrv -I nginx_first_time ".
"-p /bin/perl -a ".
"\'${home_dir}WordPress/script/start_nginx.pl ".
"\"$service_and_cert_password\"'");
($stdout,$stderr)=$handle->cmd("cygrunsrv --start nginx_first_time",
'__display__');
($stdout,$stderr)=$handle->cmd("touch script/first_time_start.flag");
} else {
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i 's/server_name localhost/".
"server_name $domain_url www.$domain_url/' ".
"$nginx_path/nginx/nginx.conf");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s/#user nobody;/user $username;/\' ".
"$nginx_path/nginx/nginx.conf");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i 's/#error_page 404 /404.html;/".
"error_page 404 /404.html;/' ".
"$nginx_path/nginx/nginx.conf");
($stdout,$stderr)=$handle->cmd($sudo.'service nginx start',
'__display__');
($stdout,$stderr)=$handle->cwd("$nginx_path/nginx");
foreach my $num (1..3) {
sleep 3;
($stdout,$stderr)=clean_filehandle($handle);
$handle->print($sudo.
"certbot --nginx -d $domain_url -d www.$domain_url");
$prompt=$handle->prompt();
my $output='';
while (1) {
$output.=fetch($handle);
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'Attempt to reinstall') {
$handle->print('1');
$output='';
} elsif (-1<index $output,'No redirect') {
$handle->print('2');
$output='';
} elsif (-1<index $output,'Enter email address') {
$handle->print('brian.kelly@fullauto.com');
$output='';
} elsif (-1<index $output,'Terms of Service') {
$handle->print('A');
$output='';
} elsif (-1<index $output,'Would you be willing') {
$handle->print('Y');
$output='';
} elsif ((-1<index $output,'existing certificate')
&& (-1==index $output,'--duplicate')) {
$handle->print('C');
$output='';
}
}
($stdout,$stderr)=clean_filehandle($handle);
($stdout,$stderr)=$handle->cmd($sudo.
'grep Certbot /etc/nginx/nginx.conf');
last if $stdout;
}
($stdout,$stderr)=$handle->cmd($sudo."service nginx restart",
'__display__');
}
}
$do=0;
if ($do==1) { # NGINX
print "DOING NGINX\n";
# -dont-trust-the-tutorials-check-your-configuration/
# understanding-and-implementing-fastcgi-proxying-in-nginx
# Manual/Deployment/nginx/FastCGI.pod
my $nginx='nginx-1.10.0';
$nginx='nginx-1.9.13' if $^O eq 'cygwin';
($stdout,$stderr)=$handle->cmd($sudo."wget --random-wait --progress=dot ".
"http://nginx.org/download/$nginx.tar.gz",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $nginx.tar.gz",'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd("tar xvf $nginx.tar.gz",'__display__');
($stdout,$stderr)=$handle->cwd($nginx);
($stdout,$stderr)=$handle->cmd("mkdir -vp objs/lib",'__display__');
($stdout,$stderr)=$handle->cwd("objs/lib");
my $pcre='pcre-8.40';
my $checksum='';
($stdout,$stderr)=$handle->cmd($sudo."wget --random-wait --progress=dot ".
"programming/pcre/$pcre.tar.gz",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $pcre.tar.gz",'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd($sudo."tar xvf $pcre.tar.gz",'__display__');
($stdout,$stderr)=$handle->cmd($sudo."wget -qO- http://zlib.net/index.html");
my $zlib_ver=$stdout;
my $sha__256=$stdout;
$zlib_ver=~s/^.*? source code, version (\d+\.\d+\.\d+).*$/$1/s;
$sha__256=~s/^.*?tar.gz.*?SHA-256 hash [<]tt[>](.*?)[<][\/]tt[>].*$/$1/s;
foreach my $count (1..3) {
($stdout,$stderr)=$handle->cmd($sudo."wget --random-wait --progress=dot ".
"http://zlib.net/zlib-$zlib_ver.tar.gz",'__display__');
$checksum=$sha__256;
($stdout,$stderr)=$handle->cmd($sudo.
"sha256sum -c - <<<\"$checksum *zlib-$zlib_ver.tar.gz\"",
'__display__');
unless ($stderr) {
print(qq{ + CHECKSUM Test for zlib-$zlib_ver *PASSED* \n});
last
} elsif ($count>=3) {
print "FATAL ERROR! : CHECKSUM Test for ".
"zlib-$zlib_ver.tar.gz *FAILED* ",
"after $count attempts\n";
&Net::FullAuto::FA_Core::cleanup;
}
($stdout,$stderr)=$handle->cmd($sudo."rm -rvf zlib-$zlib_ver.tar.gz",
'__display__');
}
($stdout,$stderr)=$handle->cmd($sudo."tar xvf zlib-$zlib_ver.tar.gz",
'__display__');
my $ossl='openssl-1.0.2h';
$checksum='577585f5f5d299c44dd3c993d3c0ac7a219e4949';
($stdout,$stderr)=$handle->cmd($sudo."wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $ossl.tar.gz",'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd("sha1sum -c - <<<\"$checksum *$ossl.tar.gz\"",
'__display__');
unless ($stderr) {
print(qq{ + CHECKSUM Test for $ossl *PASSED* \n});
} else {
($stdout,$stderr)=$handle->cmd("rm -rvf $ossl.tar.gz",'__display__');
my $dc=1;
print "FATAL ERROR! : CHECKSUM Test for $ossl.tar.gz *FAILED* ",
"after $dc attempts\n";
&Net::FullAuto::FA_Core::cleanup;
}
($stdout,$stderr)=$handle->cmd("tar xvf $ossl.tar.gz",'__display__');
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI/deps/$nginx");
my $make_nginx='./configure --sbin-path=/usr/local/nginx/nginx '.
'--conf-path=/usr/local/nginx/nginx.conf '.
'--pid-path=/usr/local/nginx/nginx.pid '.
"--with-http_ssl_module --with-pcre=objs/lib/$pcre ".
"--with-zlib=objs/lib/zlib-$zlib_ver";
($stdout,$stderr)=$handle->cmd($make_nginx,'__display__');
($stdout,$stderr)=$handle->cmd(
$sudo."sed -i 's/-Werror //' ./objs/Makefile");
($stdout,$stderr)=$handle->cmd($sudo.'make install','__display__');
# how-to-install-self-signed-certificates-on-nginx-webserver/
($stdout,$stderr)=$handle->cmd(
$sudo.'mkdir -vp /etc/nginx/ssl.key');
($stdout,$stderr)=$handle->cmd(
$sudo.'mkdir -vp /etc/nginx/ssl.crt');
($stdout,$stderr)=$handle->cmd(
$sudo.'mkdir -vp /etc/nginx/ssl.csr');
$handle->print(
$sudo.'openssl genrsa -des3 -out '.
"/etc/nginx/ssl.key/$public_ip.key 2048");
$prompt=$handle->prompt();
$prompt=~s/\$$//;
while (1) {
my $output.=fetch($handle);
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'pass phrase for') {
$handle->print($service_and_cert_password);
$output='';
next;
} elsif (-1<index $output,'Verifying - Enter') {
$handle->print($service_and_cert_password);
$output='';
next;
}
}
while (1) {
my $trys=0;
my $ereturn=eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
alarm 7;
$handle->print($sudo.
"openssl req -new -key /etc/nginx/ssl.key/$public_ip.key ".
"-out /etc/nginx/ssl.csr/$public_ip.csr");
my $test='';my $output='';
while (1) {
$output.=Net::FullAuto::FA_Core::fetch($handle);
$test.=$output;
$test=~tr/\0-\11\14-\37\177-\377//d;
return 'DONE' if $output=~/$prompt/;
print $output;
$test=~s/\n//gs;
if ($test=~/Enter pass phrase.*key:/s) {
$handle->print($service_and_cert_password);
$output='';
$test='';
next;
} elsif (-1<index $test,'[AU]:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'[Some-State]:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'city) []:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'Pty Ltd]:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'section) []:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'YOUR name) []:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'Address []:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'challenge password []:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'company name []:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,'Country Name (2 letter code) [XX]') {
$handle->print('.');
$output='';
$test='';
next;
} elsif (-1<index $test,'State or Province Name (full name) []') {
$handle->print('.');
$output='';
$test='';
next;
} elsif (
-1<index $test,'Locality Name (eg, city) [Default City]:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,
'Organization Name (eg, company) [Default Company Ltd]:') {
$handle->print();
$output='';
$test='';
next;
} elsif (-1<index $test,
'Common Name (eg, your name or your server\'s hostname) []') {
$handle->print();
$output='';
$test='';
next;
}
}
return 'DONE';
};
alarm(0);
last if $ereturn eq 'DONE' || $trys++>3;
}
$handle->print($sudo.
'openssl x509 -req -days 365 -in '.
"/etc/nginx/ssl.csr/$public_ip.csr -signkey ".
"/etc/nginx/ssl.key/$public_ip.key -out ".
"/etc/nginx/ssl.crt/$public_ip.crt");
while (1) {
my $output=fetch($handle);
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'Enter pass phrase') {
$handle->print($service_and_cert_password);
}
}
($stdout,$stderr)=$handle->cmd($sudo."sed -i 's/1024/64/' ".
"/usr/local/nginx/nginx.conf");
$ad=" include fastcgi_params;%NL%".
" fastcgi_pass localhost:3003;";
$ad=<<END;
sed -i '1,/location/ {/location/a\\\
$ad
}' /usr/local/nginx/nginx.conf
END
$handle->cmd_raw($sudo.$ad);
$ad='%NL% location /static {'.
"%NL% root ${home_dir}FullAutoAPI/root;".
'%NL% }%NL%'.
'%NL% ssl on;'.
"%NL% ssl_certificate /etc/nginx/ssl.crt/$public_ip.crt;".
"%NL% ssl_certificate_key /etc/nginx/ssl.key/$public_ip.key;".
'%NL% ssl_protocols TLSv1 TLSv1.1 TLSv1.2;'.
'%NL% ssl_ciphers '.
'"HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";';
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'/404/a$ad\' /usr/local/nginx/nginx.conf");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
"/usr/local/nginx/nginx.conf");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s/^ listen 80/ listen ".
"\*:443 ssl default_server/\' /usr/local/nginx/nginx.conf");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i 's/SCRIPT_NAME/PATH_INFO/' ".
"/usr/local/nginx/fastcgi_params");
$ad='# Catalyst requires setting PATH_INFO (instead of SCRIPT_NAME)'.
' to \$fastcgi_script_name';
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'/PATH_INFO/i$ad\' /usr/local/nginx/fastcgi_params");
$ad='fastcgi_param SCRIPT_NAME /;';
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'/PATH_INFO/a$ad\' /usr/local/nginx/fastcgi_params");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
"/usr/local/nginx/fastcgi_params");
#
# echo-ing/streaming files over ssh can be tricky. Use echo -e
# and replace these characters with thier HEX
# equivalents (use an external editor for quick
# search and replace - and paste back results.
# use copy/paste or cat file and copy/paste results.):
#
# ! - \\x21 ` - \\x60
# " - \\x22 \ - \\x5C
# $ - \\x24 % - \\x25
#
my $script=<<END;
use Net::FullAuto;
\\x24Net::FullAuto::FA_Core::debug=1;
my \\x24handle=connect_shell();
\\x24handle->print('/usr/local/nginx/nginx -g \\x22daemon on;\\x22');
\\x24prompt=\\x24handle->prompt();
my \\x24output='';my \\x24password_not_submitted=1;
while (1) {
eval {
local \\x24SIG{ALRM} = sub { die \\x22alarm\\x5Cn\\x22 };# \\x5Cn required
alarm 10;
my \\x24output=Net::FullAuto::FA_Core::fetch(\\x24handle);
last if \\x24output=~/\\x24prompt/;
print \\x24output;
if ((-1<index \\x24output,'Enter PEM pass phrase:') &&
\\x24password_not_submitted) {
\\x24handle->print(\\x24ARGV[0]);
\\x24password_not_submitted=0;
}
};
if (\\x24\@) {
\\x24handle->print();
next;
}
}
exit 0;
END
if ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI");
my $vimrc=<<END;
set paste
set mouse-=a
END
($stdout,$stderr)=$handle->cmd("echo -e \"$vimrc\" > ~/.vimrc");
($stdout,$stderr)=$handle->cmd("mkdir -vp script",'__display__');
($stdout,$stderr)=$handle->cmd("touch script/start_nginx.pl");
($stdout,$stderr)=$handle->cmd("chmod -v 755 script/start_nginx.pl",
'__display__');
($stdout,$stderr)=$handle->cmd("chmod -v o+r /usr/local/nginx/*",
'__display__');
($stdout,$stderr)=$handle->cmd("chmod -v 755 /usr/local/nginx/nginx.exe",
'__display__');
($stdout,$stderr)=$handle->cmd("echo -e \"$script\" > ".
"script/start_nginx.pl");
($stdout,$stderr)=$handle->cmd("cygrunsrv -I nginx_first_time ".
"-p /bin/perl -a ".
"\'${home_dir}FullAutoAPI/script/start_nginx.pl ".
"\"$service_and_cert_password\"'");
($stdout,$stderr)=$handle->cmd("cygrunsrv --start nginx_first_time",
'__display__');
($stdout,$stderr)=$handle->cmd("touch script/first_time_start.flag");
} else {
$handle->print($sudo."/usr/local/nginx/nginx");
$prompt=$handle->prompt();
while (1) {
my $output=fetch($handle);
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'PEM pass phrase') {
$handle->print($service_and_cert_password);
}
}
}
}
$do=0;
if ($do==1) {
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI/deps");
my $go=$1;my $gosha1=$2;
($stdout,$stderr)=$handle->cmd($sudo."wget -qO- https://golang.org/dl");
if ($^O eq 'cygwin') {
$stdout=~
/^.*?href=["]([^"]+windows-amd64.zip)["].*?[<]tt[>](.*?)[<].*$/s;
$go=$1;$gosha1=$2;
} else {
$stdout=~
/^.*?href=["]([^"]+linux-amd64.tar.gz)["].*?[<]tt[>](.*?)[<].*$/s;
$go=$1;$gosha1=$2;
}
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".$go,
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $go",'__display__')
if $^O ne 'cygwin';
$go=~s/^.*\/(.*)$/$1/;
($stdout,$stderr)=$handle->cmd("sha1sum -c - <<<\"$gosha1 *$go\"",
'__display__');
unless ($stderr) {
print(qq{ + CHECKSUM Test for $go *PASSED* \n});
} else {
($stdout,$stderr)=$handle->cmd($sudo."rm -rvf $go",'__display__');
print "FATAL ERROR! : CHECKSUM Test for $go *FAILED* ";
&Net::FullAuto::FA_Core::cleanup;
}
if ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd("unzip -o $go",'__display__');
} else {
($stdout,$stderr)=$handle->cmd("tar zxvf $go",'__display__');
}
($stdout,$stderr)=$handle->cmd("rm -rvf $go",'__display__');
}
$do=0;
if ($do==1) {
($stdout,$stderr)=$handle->cmd($sudo.'wget -qO- '.
$stdout=~s/^.*?href=["]([^"]+zip)["].*$/$1/s;
my $membrane_zip=$stdout;
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot https://github.com".$membrane_zip,
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $membrane_zip",'__display__')
if $^O ne 'cygwin';
$membrane_zip=~s/^.*\/(.*)$/$1/;
($stdout,$stderr)=$handle->cmd("unzip -o $membrane_zip",'__display__');
($stdout,$stderr)=$handle->cmd("rm -rvf $membrane_zip",'__display__');
#($stdout,$stderr)=$handle->cmd('git clone --depth=1 '.
exit;
}
unless (-e '/usr/bin/cpan') {
if ($^O eq 'cygwin') {
$handle->print('cpan');
} else {
($stdout,$stderr)=$handle->cmd($sudo.'yum -y install cpan',
'__display__');
$handle->print($sudo.'cpan');
}
$prompt=$handle->prompt();
while (1) {
my $output=fetch($handle);
last if $output=~/$prompt/;
print 'm'.$output;
if (-1<index $output,'possible automatically') {
$handle->print('yes');
} elsif (-1<index $output,'by bootstrapping') {
$handle->print('sudo');
} elsif (-1<index $output,'some CPAN') {
$handle->print('no');
} elsif (-1<index $output,'pick from') {
$handle->print('no');
} elsif (-1<index $output,'CPAN site') {
$handle->print('http://www.cpan.org');
} elsif (-1<index $output,'ENTER to quit') {
$handle->print();
} elsif ($output=~/cpan[[]\d+[]][>]/) {
$handle->print('bye');
}
}
}
($stdout,$stderr)=$handle->cmd("export PERL_MM_USE_DEFAULT=1");
if ($^O eq 'cygwin') {
my $show=<<END;
########################################
INSTALLING Starman
########################################
END
print $show;
$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","Starman")\'',
'__display__');
$show=<<END;
########################################
INSTALLING HTTP::Server::Simple
########################################
END
print $show;
$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","HTTP::Server::Simple")\'',
'__display__');
}
my $show=<<END;
########################################
INSTALLING autodie
########################################
END
print $show;
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI/deps");
$stdout=$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->get('.
'"install","autodie")\'',
'__display__');
$stdout=~s/^.*Checksum for (.*autodie.*gz) ok.*$/$1/s;
my $gzfile=$stdout;
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $gzfile ~/FullAutoAPI/deps",'__display__');
$stdout=~/^(.*)\/(.*gz)$/;
my $modpath=$1;my $modfile=$2;
($stdout,$stderr)=$handle->cmd(
"tar zxvf $modfile",'__display__');
($stdout,$stderr)=$handle->cwd("autodie*");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i 's/\"Test::Perl/#\"Test::Perl/' Makefile.PL");
($stdout,$stderr)=$handle->cmd($sudo.
'perl Makefile.PL','__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'make install','__display__');
($stdout,$stderr)=$handle->cwd('..');
($stdout,$stderr)=$handle->cmd($sudo.
'rm -rvf autodie*','__display__');
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI/deps");
$show=<<END;
########################################
INSTALLING Perl::Critic
########################################
END
print $show;
$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","Perl::Critic")\'',
'__display__');
$show=<<END;
########################################
INSTALLING IO::CaptureOutput
########################################
END
print $show;
$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","IO::CaptureOutput")\'',
'__display__');
$show=<<END;
########################################
INSTALLING Devel::CheckLib
########################################
END
print $show;
$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","Devel::CheckLib")\'',
'__display__');
$show=<<END;
########################################
INSTALLING ExtUtils::Embed
########################################
END
#print $show;
#$handle->cmd_raw(
# 'sudo perl -MCPAN -e \'CPAN::Shell->force('.
# '"install","ExtUtils::Embed")\'',
# '__display__');
my @cpan_modules = qw(
Test::More
Text::Glob
File::Find::Rule
Crypt::UnixCrypt_XS
Digest::CRC
Data::Integer
Data::Float
HTTP::Lite
Authen::Passphrase
DBICx::TestDatabase
Class::Mix
Crypt::MySQL
Module::Build
AnyEvent
Test::Requires
Proc::Guard
ZMQ::LibZMQ4
CPAN::Meta
ExtUtils::ParseXS
Package::Generator
Test::Output
Compress::Raw::Bzip2
IO::Compress::Bzip2
Package::Anon
Text::Diff
Archive::Tar
Archive::Zip
inc::latest
PAR::Dist
Regexp::Common
Pod::Checker
Pod::Parser
Pod::Man
File::Slurp
Test::Taint
Test::Warnings
Test::Without::Module
Devel::LexAlias
BSD::Resource
IPC::System::Simple
Sub::Identify
Fatal
Sub::Name
Role::Tiny
Test::LeakTrace
Test::CleanNamespaces
Test::Pod
Test::Pod::Coverage
Class::Load
Class::Load::XS
Algorithm::C3
SUPER
Module::Refresh
Declare::Constraints::Simple
Devel::Cycle
CGI
Test::Memory::Cycle
IO::String
Mouse::Tiny
DateTime::Format::MySQL
Moose
Moo
MooseX::Role::WithOverloading
Pod::Coverage::Moose
MooseX::AttributeHelpers
MooseX::ConfigFromFile
MooseX::MarkAsMethods
MooseX::SimpleConfig
MooseX::StrictConstructor
MooseX::NonMoose
Net::FullAuto
Time::HiRes
Business::ISBN
App::FatPacker
JSON
JSON::XS
Test::DistManifest
Term::Size::Any
Type::Tiny
File::ReadBackwards
Imager
Astro::MoonPhase
Date::Manip
XML::LibXML
SQL::Translator
Template::Alloy
URI::Amazon::APA
Catalyst::Runtime
Proc::ProcessTable
Parallel::Forker
UUID::Tiny
Regexp::Assemble
Bytes::Random::Secure
Math::Random::ISAAC::XS
HTML::FormHandler
Crypt::PassGen
Catalyst::Controller::HTML::FormFu
HTML::FormHandler::Model::DBIC
HTML::FormHandler::Model::DBIC
CatalystX::OAuth2
Task::Catalyst::Tutorial
YAML::Syck
Catalyst::Model::Adaptor
);
#EXODIST/Test-Simple-1.001014.tar.gz
#Test::Aggregate
#Test::Aggregate::Nested
# words-quot-or-quot-usr-share-dict-words-on-cygwin-1-7-td59328.html
($stdout,$stderr)=$handle->cwd('deps');
($stdout,$stderr)=$handle->cmd($sudo."wget -qO- $mirror");
my @num=();
foreach my $line (split /\n/, $stdout) {
next unless $line=~/DIR/;
$line=~/^.*DIR.*href=["](\d+)\/["].*$/;
my $num=$1;
next unless $num;
push @num, $num;
}
my $num=(reverse sort {$a<=>$b} @num)[0];
($stdout,$stderr)=$handle->cmd($sudo.
"wget -qO- $mirror$num/Server/x86_64/os/Packages/w/");
$stdout=~s/^.*(words.*?rpm).*$/$1/s;
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
"$mirror$num/Server/x86_64/os/Packages/w/$stdout",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username words*.rpm",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd(
"rpm2cpio words*.rpm | \(cd /; cpio -idmv\)");
($stdout,$stderr)=$handle->cmd($sudo.'chmod -v 755 /usr/share/dict/',
'__display__');
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI");
my $install_fullautoapi=<<'END';
o o o .oPYo. ooooo .oo o o o o o .oPYo.
8 8b 8 8 8 .P 8 8 8 8 8b 8 8 8
8 8`b 8 `Yooo. 8 .P 8 8 8 8 8`b 8 8
8 8 `b 8 `8 8 oPooo8 8 8 8 8 `b 8 8 oo
8 8 `b8 8 8 .P 8 8 8 8 8 `b8 8 8
8 8 `8 `YooP' 8 .P 8 8oooo 8oooo 8 8 `8 `YooP8
........................................................
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
_
((_)
/
/ _ _ _
\__/_ ___ __ _| |_ __ _| |_ _ ___| |_
/ \ / __/ _` | __/ _` | | | | / __| __| Perl MVC
_- | | | (_| (_| | || (_| | | |_| \__ \ | framework
_ _-' \____/ \___\__,_|\__\__,_|_|\__, |___/\__|c
((_) ---\ |___/
\
\\_ Web Framework
(_)
(Catalyst Foundation is **NOT** a sponsor of the FullAuto© Project.)
END
foreach my $module (@cpan_modules) {
next if $module=~/^\s*[#]/;
my $show=<<END;
########################################
INSTALLING $module
########################################
END
sleep 1;
print $show;
if ($module eq 'Catalyst::Runtime') {
print $install_fullautoapi;
sleep 10;
}
if ($module eq 'Regexp::Assemble' ||
$module eq 'ZMQ::LibZMQ4' ||
$module eq 'CatalystX::OAuth2') {
$handle->print($sudo.
'perl -MCPAN -e \'CPAN::Shell->force('.
"\"install\",\"$module\")\'"
)
} else {
$handle->print($sudo."cpan $module 2>&1");
}
my $prompt=$handle->prompt();
my $error=0;my $force=0;my $tries=0;my $allout='';my $save='';
while (1) {
my $done=eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
alarm 120;
select(undef,undef,undef,0.02);
# sleep for 1/50th second;
my $output='';
($output,$save)=fetch($handle,$save,'__display__');
$allout.=$output;
if ($output=~/$prompt/) {
if ($error) {
$error=0;$force=1;
$handle->print($sudo.
'perl -MCPAN -e \'CPAN::Shell->force('.
"\"install\",\"$module\")\'"
)
} elsif ($output=~/y\s*y\s*y/s) {
print "\n\nCLEARING MEMORY ...\n\n";
sleep 3;
clean_filehandle($handle);
$handle->close();
$handle=connect_shell();
return 'done';
} else {
return 'done';
}
} elsif ($output=~/y\s*y\s*y/s) {
print "\n\nCLEARING MEMORY ...\n\n";
sleep 3;
clean_filehandle($handle);
$handle->close();
$handle=connect_shell();
return 'done';
} elsif ($output=~/build the XS Stash module/) {
$handle->print('y');
} elsif ($output=~/use the XS Stash by default/) {
$handle->print('y');
} elsif ($output=~/it permanently/) {
$handle->print('yes');
} elsif ($output=~/from CPAN/) {
$handle->print('yes');
}
if (!$force &&
((-1<index $allout,'[test_dynamic] Error 255') ||
(-1<index $allout,'Connection reset by peer'))) {
$error=1;
#$output=~s/$prompt//gs;
}
#print $output;
return 'continue';
};
next if $done eq 'continue';
if ($done=~/^\d$/ && $done==1) {
my $output=fetch($handle);
my $attempt='attempts';
$attempt='attempt' if $tries==0;
print "\n\n FATAL ERROR!: Could not install CPAN Module",
": $module\n\n",
" --> $output\n",
" after ",++$tries," $attempt\n\n";
cleanup;
} elsif ($@ && ++$tries<4) {
alarm(0);$allout='';
$handle->print("\003");
my $done=eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
while (my $ln=fetch($handle)) {
return 'done' if $ln=~/$prompt/s;
}
};
if ($@) {
my $attempt='attempts';
$attempt='attempt' if $tries==0;
print "\n\n FATAL ERROR!: Could not install CPAN Module",
": $module\n\n",
" --> could not recover handle after \n",
" ",++$tries," $attempt\n\n";
cleanup;
} elsif ($done) {
next
} else {
print "\n\n FATAL ERROR!: Could not install CPAN Module",
" $module\n",
" - Unknown Error after ",
--$tries," attempts\n\n";
cleanup;
}
} elsif ($tries>3) {
my $attempt='attempts';
print "\n\n FATAL ERROR!: Could not install CPAN Module",
": $module\n\n",
" after ",++$tries," $attempt\n\n";
cleanup;
}
last if $done;
}
}
$show=<<END;
########################################
INSTALLING Catalyst::Devel
########################################
END
print $show;
if ($^O eq 'cygwin') {
$handle->print($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","Catalyst::Devel")\'');
} else {
$handle->print($sudo.'cpan Catalyst::Devel');
}
$prompt=$handle->prompt();my $save='';
while (1) {
my $output='';
($output,$save)=fetch($handle,$save,'__display__');
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'XS Stash module?') {
$handle->print('y');
}
if (-1<index $output,'XS Stash by default?') {
$handle->print('y');
}
}
$show=<<END;
########################################
INSTALLING DBIx::Class
########################################
END
$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","DBIx::Class")\'',
'__display__');
$show=<<END;
########################################
INSTALLING DBIx::Class::Schema::Loader
########################################
END
$handle->cmd_raw($sudo.
'cpan DBIx::Class::Schema::Loader',
'__display__');
# $show=<<END;
#
########################################
#
# INSTALLING Net::RabbitFoot
#
########################################
#END
# print $show;
# $handle->print($sudo.'cpan Net::RabbitFoot');
# $prompt=$handle->prompt();
# while (1) {
# my $output.=fetch($handle);
# last if $output=~/$prompt/;
# print $output;
# if (-1<index $output,'Skip further questions and use') {
# $handle->print('y');
# $output='';
# next;
# }
# }
# $show=<<END;
#
########################################
#
# INSTALLING YAML::Syck
#
########################################
#END
# print $show;
# sleep 1;
# $handle->cmd_raw($sudo.'cpan YAML::Syck','__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Controller::REST
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Controller::REST','__display__');
# $show=<<END;
#
########################################
#
# INSTALLING Catalyst::Model::Adaptor
#
########################################
#END
# print $show;
# sleep 1;
# $handle->cmd_raw("${sudo}cpan Catalyst::Model::Adaptor",'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::View::JSON
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::View::JSON',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::View::TT::Alloy
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::View::TT::Alloy',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Plugin::Unicode
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Plugin::Unicode',
'__display__');
$show=<<END;
########################################
INSTALLING DBIx::Class::PassphraseColumn
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan DBIx::Class::PassphraseColumn',
'__display__');
$show=<<END;
########################################
INSTALLING Authen::Passphrase::BlowfishCrypt
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Authen::Passphrase::BlowfishCrypt',
'__display__');
$show=<<END;
########################################
INSTALLING Method::Signatures::Simple
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Method::Signatures::Simple',
'__display__');
# $show=<<END;
#
########################################
#
# INSTALLING HTML::FormHandler
#
########################################
#END
# print $show;
# sleep 1;
# $handle->cmd_raw("${sudo}cpan HTML::FormHandler",
# '__display__');
# $show=<<END;
#
########################################
#
# INSTALLING HTML::FormHandler::Model::DBIC
#
########################################
#END
# print $show;
# sleep 1;
# $handle->cmd_raw("${sudo}cpan HTML::FormHandler::Model::DBIC",
# '__display__');
$show=<<END;
########################################
INSTALLING CatalystX::SimpleLogin
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","CatalystX::SimpleLogin")\'',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Plugin::Session
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Plugin::Session',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Plugin::Session::Store::Memcached
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Plugin::Session::Store::Memcached',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Plugin::Session::State::Cookie
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Plugin::Session::State::Cookie',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Plugin::Authentication
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Plugin::Authentication',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Authentication::Store::DBIx::Class
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Authentication::Store::DBIx::Class',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Plugin::Authorization::Roles
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Plugin::Authorization::Roles',
'__display__');
$show=<<END;
########################################
INSTALLING Time::Warp
########################################
END
print $show;
sleep 1;
$handle->print($sudo.
'perl -MCPAN -e \'CPAN::Shell->notest('.
'"install","Time::Warp")\'');
$show=<<END;
########################################
INSTALLING DBIx::Class::TimeStamp
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan DBIx::Class::TimeStamp',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Controller::ActionRole
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Controller::ActionRole',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::ActionRole::ACL
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::ActionRole::ACL',
'__display__');
$show=<<END;
########################################
INSTALLING FCGI
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.'cpan FCGI',
'__display__');
$show=<<END;
########################################
INSTALLING FCGI::ProcManager
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan FCGI::ProcManager',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::Helper::Model::DBIC::Schema
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::Helper::Model::DBIC::Schema',
'__display__');
$show=<<END;
########################################
INSTALLING Catalyst::View::Email
########################################
END
print $show;
sleep 1;
$handle->cmd_raw($sudo.
'cpan Catalyst::View::Email',
'__display__');
$show=<<END;
########################################
INSTALLING Finance::Quote
########################################
END
print $show;
$handle->print($sudo.'cpan Finance::Quote');
$prompt=$handle->prompt();
while (1) {
my $output.=fetch($handle);
last if $output=~/$prompt/;
print $output;
if (-1<index $output,'traffic to external sites') {
$handle->print('Y');
$output='';
next;
}
if (-1<index $output,'have network connectivity. [n]') {
$handle->print('y');
$output='';
next;
}
}
($stdout,$stderr)=$handle->cwd('~');
($stdout,$stderr)=$handle->cmd('catalyst.pl FullAutoAPI','__display__');
($stdout,$stderr)=$handle->cwd('FullAutoAPI');
($stdout,$stderr)=$handle->cmd('perl Makefile.PL','__display__');
# http://search.cpan.org/~bobtfish/Catalyst-Plugin-Authentication-0.10023/
my $pm_path="./lib/FullAutoAPI.pm";
$ad=" Session%NL%".
" Session::Store::Memcached%NL%".
" Session::State::Cookie%NL%".
" Authentication%NL%".
" Authorization::Roles%NL%".
" +CatalystX::SimpleLogin";
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i '/ Static::Simple/a$ad' $pm_path");
$ad=" use_request_uri_for_path => 1,%NL%".
" authentication => {%NL%".
" default_realm => %SQ%users%SQ%,%NL%".
" realms => {%NL%".
" users => {%NL%".
" credential => {%NL%".
" class => %SQ%Password%SQ%,%NL%".
" password_field => %SQ%password%SQ%,%NL%".
" password_type => %SQ%self_check%SQ%%NL%".
" },%NL%".
" store => {%NL%".
" class => %SQ%DBIx::Class%SQ%,%NL%".
" user_model => %SQ%DB::Users%SQ%,%NL%".
" role_relation => %SQ%roles%SQ%,%NL%".
" role_field => %SQ%name%SQ%,%NL%".
" }%NL%".
" }%NL%".
" },%NL%".
" },%NL%".
" %SQ%Controller::Login%SQ% => {%NL%".
" traits => [%SQ%-RenderAsTTTemplate%SQ%],%NL%".
" login_form_args => {%NL%".
" authenticate_args => { active => %SQ%Y%SQ% },%NL%".
" },%NL%".
" },";
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i '/Send X-Catalyst header/a$ad' $pm_path");
$handle->cmd_raw($sudo.
"sed -i 's/\\(^use_request_uri$\\\)/ \\1/' $pm_path");
$handle->cmd_raw($sudo.
"sed -i 's/\\(^Session$\\\)/ \\1/' $pm_path");
$handle->cmd_raw($sudo.
"sed -i 's/\\(^authentication =.*\\\)/ \\1/' $pm_path");
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" $pm_path");
($stdout,$stderr)=$handle->cmd($sudo."sed -i \"s/%SQ%/\'/g\" $pm_path");
($stdout,$stderr)=$handle->cmd("mkdir -vp root/login",'__display__');
($stdout,$stderr)=$handle->cmd("touch root/login/login.tt2",
'__display__');
my $content=<<'ENDD';
[% META title = 'Welcome to the FullAuto API Management Dashboard: Please Log In' %]
<div>
[% FOR field IN login_form.error_fields %]
[% FOR error IN field.errors %]
<p><span style=\\x22color: red;\\x22>[% field.label _ ': ' _ error %]</span></p>
[% END %]
[% END %]
</div>
<div>
<form id=\\x22login_form\\x22 method=\\x22post\\x22 action=\\x22[% c.req.uri %]\\x22>
<fieldset style=\\x22border: 0;\\x22>
<table>
<tr>
<td><label class=\\x22label\\x22 for=\\x22username\\x22>Username:</label></td>
<td><input type=\\x22text\\x22 name=\\x22username\\x22 value=\\x22\\x22 /></td>
</tr>
<tr>
<td><label class=\\x22label\\x22 for=\\x22password\\x22>Password:</label></td>
<td><input type=\\x22password\\x22 name=\\x22password\\x22 value=\\x22\\x22 /></td>
</tr>
<tr><td><input type=\\x22submit\\x22 name=\\x22submit\\x22 value=\\x22Login\\x22 /></td></tr>
</table>
</fieldset>
</form>
</div>
ENDD
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/login/login.tt2");
($stdout,$stderr)=$handle->cmd("mkdir -vp root/email",'__display__');
($stdout,$stderr)=$handle->cmd("touch root/email/welcome.tt2",
'__display__');
$content=<<'END';
<\\x21DOCTYPE html PUBLIC \\x22-//W3C//DTD XHTML 1.0 Transitional//EN\\x22
xml:lang=\\x22en\\x22
lang=\\x22en\\x22>
<head>
</head>
<body>
<h2 align=\\x22center\\x22>Welcome to the FullAuto API Management Dashboard.</h2>
<p>Your username is: <span style=\\x22color: green;\\x22>[% username %]</span></p>
<p>Your initial password is: <span style=\\x22color: red;\\x22>[% password %]</span></p>
<p>Your client id is: <span style=\\x22color: purple;\\x22>[% client_id %]</span></p>
<p>Your client secret is: <span style=\\x22color: purple;\\x22>[% client_secret %]</span></p>
<p>You will be asked to change your password on first login.</p>
</body>
</html>
END
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/email/welcome.tt2");
($stdout,$stderr)=$handle->cmd("touch root/email/reset_password.tt2",
'__display__');
$content=<<'END';
<\\x21DOCTYPE html PUBLIC \\x22-//W3C//DTD XHTML 1.0 Transitional//EN\\x22
xml:lang=\\x22en\\x22
lang=\\x22en\\x22>
<head>
</head>
<body>
<h2 align=\\x22center\\x22>Your FullAuto API Management Dashboard Password has been Reset</h2>
<p>Your username is: <span style=\\x22color: green;\\x22>[% username %]</span></p>
<p>Your password is: <span style=\\x22color: red;\\x22>[% password %]</span></p>
<p>You will be asked to change your password on first login.</p>
</body>
</html>
END
($stdout,$stderr)=$handle->cmd("mkdir -vp root/user",'__display__');
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/user/list.tt2");
($stdout,$stderr)=$handle->cmd("touch root/user/list.tt2",
'__display__');
$content=<<'END';
[% META title = 'FullAuto API: User Admin' %]
<br />
<a class=\\x22button\\x22 href=\\x22[% c.uri_for('/user/add') %]\\x22 onclick='this.blur();'><span>Add User</span></a>
<br />
Displaying users [% pager.first %]-[% pager.last %] of [% pager.total_entries %]
<table>
<tr>
<th>Username</th>
<th>Name</th>
<th>Email Address</th>
<th>Client ID</th>
<th>Client Secret</th>
</tr>
[% WHILE (u = users.next) %]
<tr>
<td><a href=\\x22[% c.uri_for('/user', u.id, 'edit') %]\\x22>[% u.username %]</a></td>
<td>[% u.name %]</td>
<td>[% u.email_address %]</td>
<td>[% u.client_id %]</td>
<td>[% u.client_secret %]</td>
<td><a href=\\x22[% c.uri_for('/user', u.id, 'reset_password') %]\\x22>Reset Password</a></td>
<td><a href=\\x22[% c.uri_for('/user', u.id, 'inactivate') %]\\x22>Inactivate</a></td>
</tr>
[% END %]
</table>
&lt;&lt;
<a href=\\x22[% c.req.uri_with({ page => pager.first_page }) %]\\x22>First</a>
<a href=\\x22[% c.req.uri_with({ page => pager.previous_page })%]\\x22>Previous</a>
|
<a href=\\x22[% c.req.uri_with({ page => pager.next_page })%]\\x22>Next</a>
<a href=\\x22[% c.req.uri_with({ page => pager.last_page }) %]\\x22>Last</a>
&gt;&gt;
END
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/user/list.tt2");
($stdout,$stderr)=$handle->cmd("touch root/user/add.tt2",
'__display__');
$content=<<'ENDD';
[% META title = 'FullAuto API: Add User' %]
<div>
<form name=\\x22[% form.name %]\\x22 action=\\x22[% c.req.uri %]\\x22 method=\\x22post\\x22>
[% FOR field IN form.error_fields %]
[% FOR error IN field.errors %]
<p><span style=\\x22color: red;\\x22>[% field.label _ ': ' _ error %]</span></p>
[% END %]
[% END %]
<fieldset style=\\x22border: 0;\\x22>
<table>
<tr>
[% f = form.field('username') %]
<td><label for=\\x22[% f.name %]\\x22>[% f.label %]:</label></td>
<td><input type=\\x22text\\x22 size=30 name=\\x22[% f.name %]\\x22 id=\\x22[% f.name %]\\x22 value=\\x22[% f.fif %]\\x22></td>
</tr>
[% PROCESS user/edit_details.tt2 %]
<tr>
<td><input type=\\x22submit\\x22 name=\\x22submit\\x22 id=\\x22submit\\x22 value=\\x22Add\\x22 /></td>
<td><a href=\\x22/user/list\\x22>Users List</a></td>
</tr>
</fieldset>
</table>
</form>
</div>
ENDD
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/user/add.tt2");
($stdout,$stderr)=$handle->cmd("touch root/user/change_password.tt2",
'__display__');
$content=<<'ENDD';
[% META title = 'FullAuto API: Change Password' %]
<div>
<form name=\\x22[% form.name %]\\x22 action=\\x22[% c.req.uri %]\\x22 method=\\x22post\\x22>
[% FOR field IN form.error_fields %]
[% FOR error IN field.errors %]
<p><span style=\\x22color: red;\\x22>[% field.label _ ': ' _ error %]</span></p>
[% END %]
[% END %]
<fieldset style=\\x22border: 0;\\x22>
<table>
[% FOREACH field_name = ['current_password', 'new_password', 'new_password_conf'] %]
<tr>
[% f = form.field(field_name) %]
<td><label for=\\x22[% f.name %]\\x22>[% f.label %]:</label></td>
<td><input type=\\x22password\\x22 name=\\x22[% f.name %]\\x22 id=\\x22[% f.name %]\\x22 value=\\x22[% f.fif %]\\x22></td>
</tr>
[% END %]
<tr><td><input type=\\x22submit\\x22 name=\\x22submit\\x22 value=\\x22Change\\x22 /></td></tr>
</fieldset>
</table>
</form>
</div>
ENDD
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/user/change_password.tt2");
($stdout,$stderr)=$handle->cmd("touch root/user/edit.tt2",
'__display__');
$content=<<'ENDD';
[% META title = 'FullAuto API: Edit User' %]
<div>
<form name=\\x22[% form.name %]\\x22 action=\\x22[% c.req.uri %]\\x22 method=\\x22post\\x22>
[% FOR field IN form.error_fields %]
[% FOR error IN field.errors %]
<p><span style=\\x22color: red;\\x22>[% field.label _ ': ' _ error %]</span></p>
[% END %]
[% END %]
<fieldset style=\\x22border: 0;\\x22>
<table>
[% PROCESS user/edit_details.tt2 %]
<tr>
<td><input type=\\x22submit\\x22 name=\\x22submit\\x22 id=\\x22submit\\x22 value=\\x22Update\\x22 /></td>
<td><a href=\\x22/user/list\\x22>Users List</a></td>
</tr>
</fieldset>
</table>
</form>
</div>
ENDD
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/user/edit.tt2");
($stdout,$stderr)=$handle->cmd("touch root/user/edit_details.tt2",
'__display__');
$content=<<'ENDD';
[% FOREACH field_name = ['name', 'email_address',
'phone_number', 'mail_address'] %]
<tr>
[% f = form.field(field_name) %]
<td><label class=\\x22text.label\\x22 for=\\x22[% f.name %]\\x22>[% f.label %]:</label></td>
<td><input class=\\x22text\\x22 type=\\x22text\\x22 size=30 name=\\x22[% f.name %]\\x22 id=\\x22[% f.name %]\\x22 value=\\x22[% f.fif %]\\x22></td>
</tr>
[% END %]
<tr>
[% f = form.field('roles') %]
<td><label for=\\x22[% f.name %]\\x22>Roles:</label></td>
<td>[% f.render %]</td>
</tr>
ENDD
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/user/edit_details.tt2");
($stdout,$stderr)=$handle->cmd("touch root/user/profile.tt2",
'__display__');
$content=<<'ENDD';
[% META title = 'MyApp: User Profile' %]
<div>
<form name=\\x22[% form.name %]\\x22 action=\\x22[% c.req.uri %]\\x22 method=\\x22post\\x22>
[% FOR field IN form.error_fields %]
[% FOR error IN field.errors %]
<p><span style=\\x22color: red;\\x22>[% field.label _ ': ' _ error %]</span></p>
[% END %]
[% END %]
<fieldset style=\\x22border: 0;\\x22>
<table>
[% FOREACH field_name = ['name', 'email_address',
'phone_number', 'mail_address'] %]
<tr>
[% f = form.field(field_name) %]
<td><label for=\\x22[% f.name %]\\x22>[% f.label %]:</label></td>
<td><input type=\\x22text\\x22 size=30 name=\\x22[% f.name %]\\x22 id=\\x22[% f.name %]\\x22 value=\\x22[% f.fif %]\\x22></td>
</tr>
[% END %]
<tr><td><input type=\\x22submit\\x22 name=\\x22submit\\x22 id=\\x22submit\\x22 value=\\x22Update\\x22 /></td></tr>
</fieldset>
</table>
</form>
</div>
ENDD
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > root/user/profile.tt2");
($stdout,$stderr)=$handle->cmd('mkdir -vp db lib/FullAutoAPI/Schema',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.'chmod -v 777 db');
($stdout,$stderr)=$handle->cwd('db');
my $have_fadb=1;
unless (-e 'fullautoapi.db') {
$have_fadb=0;
#($stdout,$stderr)=$handle->cmd($sudo.
# "wget --random-wait --progress=dot ".
# "examples/RestYUI/db/adventrest.db",
# '__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/RestYUI/db/adventrest.db .",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username adventrest.db",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd($sudo.'mv adventrest.db fullautoapi.db');
}
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI');
my $db_sql="db.sql";
$content=<<'END';
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS roles;
DROP TABLE IF EXISTS user_roles;
DROP TABLE IF EXISTS client;
DROP TABLE IF EXISTS owner;
DROP TABLE IF EXISTS access_token_to_refresh_token;
DROP TABLE IF EXISTS refresh_token;
DROP TABLE IF EXISTS refresh_token_to_access_token;
DROP TABLE IF EXISTS code;
DROP TABLE IF EXISTS token;
CREATE TABLE token (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code_id INTEGER NOT NULL,
timestamp TEXT,
FOREIGN KEY (code_id) REFERENCES code(id)
);
CREATE TABLE code (
client_id INTEGER NOT NULL,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
is_active INTEGER NOT NULL DEFAULT 1,
owner_id INTEGER,
FOREIGN KEY (client_id) REFERENCES client(id),
FOREIGN KEY (owner_id) REFERENCES owner(id)
);
CREATE TABLE refresh_token_to_access_token (
access_token_id INTEGER NOT NULL UNIQUE,
code_id INTEGER NOT NULL,
refresh_token_id INTEGER NOT NULL UNIQUE,
PRIMARY KEY (access_token_id, code_id, refresh_token_id),
FOREIGN KEY (access_token_id) REFERENCES token(id),
FOREIGN KEY (code_id) REFERENCES code(id),
FOREIGN KEY (refresh_token_id) REFERENCES refresh_token(id)
);
CREATE TABLE refresh_token (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
code_id INTEGER NOT NULL,
timestamp TEXT,
FOREIGN KEY (code_id) REFERENCES code(id)
);
CREATE TABLE access_token_to_refresh_token (
access_token_id INTEGER NOT NULL UNIQUE,
code_id INTEGER NOT NULL,
refresh_token_id INTEGER NOT NULL UNIQUE,
PRIMARY KEY (access_token_id, code_id, refresh_token_id),
FOREIGN KEY (access_token_id) REFERENCES token(id),
FOREIGN KEY (code_id) REFERENCES code(id),
FOREIGN KEY (refresh_token_id) REFERENCES refresh_token(id)
);
CREATE TABLE owner (
id INTEGER PRIMARY KEY AUTOINCREMENT
);
CREATE TABLE client (
id INTEGER PRIMARY KEY,
endpoint TEXT NOT NULL,
client_secret TEXT
);
CREATE TABLE users (
id INTEGER PRIMARY KEY,
active CHAR(1) NOT NULL,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
password_expires TIMESTAMP,
name TEXT NOT NULL,
email_address TEXT NOT NULL,
phone_number TEXT,
mail_address TEXT,
client_id INTEGER,
client_secret TEXT,
FOREIGN KEY (client_id) REFERENCES client(id)
);
CREATE TABLE roles (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
CREATE TABLE user_roles (
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE,
role_id INTEGER NOT NULL REFERENCES roles(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE,
PRIMARY KEY (user_id, role_id)
);
INSERT INTO users (username, active, name, email_address, password) VALUES (
'admin', 'Y', 'Administrator', 'admin@fullauto.com', 'password'
);
INSERT INTO roles (name) VALUES ('admin');
INSERT INTO roles (name) VALUES ('can_edit');
INSERT INTO user_roles (user_id, role_id) VALUES (
(SELECT id FROM users WHERE username = 'admin'),
(SELECT id FROM roles WHERE name = 'admin')
);
END
#CREATE TABLE user (
# user_id TYPE text NOT NULL PRIMARY KEY,
# fullname TYPE text NOT NULL,
# description TYPE text NOT NULL
#);
#END
($stdout,$stderr)=$handle->cmd("touch $db_sql");
($stdout,$stderr)=$handle->cmd("chmod -v 777 $db_sql",'__display__');
($stdout,$stderr)=$handle->cmd("echo \"$content\" > $db_sql");
($stdout,$stderr)=$handle->cmd("chmod -v 644 $db_sql",'__display__');
($stdout,$stderr)=$handle->cmd('sqlite3 db/fullautoapi.db < db.sql')
unless $have_fadb;
($stdout,$stderr)=$handle->cmd('chmod -v 777 db/fullautoapi.db',
'__display__');
my $client_path="./lib/FullAutoAPI/Schema/Result/Client.pm";
($stdout,$stderr)=$handle->cmd("./script/fullautoapi_create.pl ".
"model DB DBIC::Schema FullAutoAPI::Schema create=static ".
"components=TimeStamp,PassphraseColumn ".
"moniker_map='{ users => \"Users\" }' ".
"on_connect_do='PRAGMA foreign_keys=ON' quote_char='\"' ".
"dbi:SQLite:db/fullautoapi.db",
'__display__') unless $have_fadb;
$ad="%NL%sub find_refresh {%NL%".
" shift->codes->search( { is_active => 1 } )%NL%".
" ->related_resultset(%SQ%refresh_tokens%SQ%)->find(\@_);%NL%".
"}";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/DO NOT MODIFY THIS/a$ad' $client_path");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".$client_path);
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" ".
$client_path);
my $refreshtoken_path="./lib/FullAutoAPI/Schema/Result/RefreshToken.pm";
$ad="%NL%".# this is a has many but will only ever return a single record%NL%".
"# because of the constraint on the relationship table%NL%".
"__PACKAGE__->has_many(%NL%".
" from_access_token_map =>%NL%".
" %SQ%FullAutoAPI::Schema::Result::AccessTokenToRefreshToken%SQ% => {%NL%".
" %SQ%foreign.refresh_token_id%SQ% => %SQ%self.id%SQ%,%NL%".
" %SQ%foreign.code_id%SQ% => %SQ%self.code_id%SQ%%NL%".
" }%NL%".
");%NL%".
"__PACKAGE__->many_to_many(%NL%".
" from_access_token_map_m2m => from_access_token_map => %SQ%access_token%SQ% );%NL%".
"%NL%".
"# this is a has many but will only ever return a single record%NL%".
"# because of the constraint on the relationship table%NL%".
"__PACKAGE__->has_many(%NL%".
" to_access_token_map =>%NL%".
" %SQ%FullAutoAPI::Schema::Result::RefreshTokenToAccessToken%SQ% => {%NL%".
" %SQ%foreign.refresh_token_id%SQ% => %SQ%self.id%SQ%,%NL%".
" %SQ%foreign.code_id%SQ% => %SQ%self.code_id%SQ%%NL%".
" }%NL%".
");%NL%".
"__PACKAGE__->many_to_many(%NL%".
" to_access_token_map_m2m => to_access_token_map => %SQ%access_token%SQ% );%NL%".
"%NL%".
"sub from_access_token { shift->from_access_token_map_m2m->first }%NL%".
"sub to_access_token { shift->to_access_token_map_m2m->first }%NL%".
"%NL%".
"sub create_access_token {%NL%".
" my (\$self) = \@_;%NL%".
" my \$code = \$self->code;%NL%".
" my \$token;%NL%".
" \$self->result_source->storage->txn_do(%NL%".
" sub {%NL%".
" # create a new token from this refresh token%NL%".
" \$token = \$code->tokens->create(%NL%".
" { from_refresh_token_map => [ { refresh_token => \$self } ] } );%NL%".
"%NL%".
" # create a new refresh token and add it to the new token%NL%".
" my \$refresh = \$code->refresh_tokens->create( {} );%NL%".
" \$token->to_refresh_token_map->create(%NL%".
" { code => \$code, refresh_token => \$refresh } );%NL%".
" }%NL%".
" );%NL%".
" return \$token;%NL%".
"}%NL%".
"%NL%".
"# if we have already created a token from this refresh, de-activate it".
"%NL%%NL%".
"sub is_active { !shift->to_access_token_map->count }%NL%".
"%NL%".
"sub as_string { shift->id }";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/DO NOT MODIFY THIS/a$ad' $refreshtoken_path");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".$refreshtoken_path);
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" ".
$refreshtoken_path);
$refreshtoken_path=
"./lib/FullAutoAPI/Schema/Result/RefreshTokenToAccessToken.pm";
($stdout,$stderr)=$handle->cmd("${sudo}sed -i ".
"\'s/\> \"refresh_token_id\" \}/\> \"refresh_token_id\"/\' ".
$refreshtoken_path);
($stdout,$stderr)=$handle->cmd("${sudo}sed -i ".
"\'s/\> \"access_token_id\" \}/\> \"access_token_id\"/\' ".
$refreshtoken_path);
$ad=" code_id => \"code_id\" },";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/\> \"refresh_token_id\",/a$ad' $refreshtoken_path");
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/\> \"access_token_id\",/a$ad' $refreshtoken_path");
$handle->cmd_raw(
"${sudo}sed -i 's/\\(^code_id.*\\\)/ \\1/' $refreshtoken_path");
$refreshtoken_path=
"./lib/FullAutoAPI/Schema/Result/AccessTokenToRefreshToken.pm";
($stdout,$stderr)=$handle->cmd("${sudo}sed -i ".
"\'s/\> \"refresh_token_id\" \}/\> \"refresh_token_id\"/\' ".
$refreshtoken_path);
($stdout,$stderr)=$handle->cmd("${sudo}sed -i ".
"\'s/\> \"access_token_id\" \}/\> \"access_token_id\"/\' ".
$refreshtoken_path);
$ad=" code_id => \"code_id\" },";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/\> \"refresh_token_id\",/a$ad' $refreshtoken_path");
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/\> \"access_token_id\",/a$ad' $refreshtoken_path");
$handle->cmd_raw(
"${sudo}sed -i 's/\\(^code_id.*\\\)/ \\1/' $refreshtoken_path");
my $code_path="./lib/FullAutoAPI/Schema/Result/Code.pm";
$ad="%NL%sub as_string { shift->id }%NL%".
"%NL%".
"sub activate {%NL%".
" my(\$self, \$owner_id) = \@_;%NL%".
" \$self->update( { is_active => 1, owner_id => \$owner_id } )%NL%".
"}";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/DO NOT MODIFY THIS/a$ad' $code_path");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".$code_path);
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" ".
$code_path);
my $token_path="./lib/FullAutoAPI/Schema/Result/Token.pm";
$ad="# this is a has many but will only ever return a single record%NL%".
"# because of the constraint on the relationship table%NL%".
"__PACKAGE__->has_many(%NL%".
" from_refresh_token_map =>%NL%".
" %SQ%FullAutoAPI::Schema::Result::RefreshTokenToAccessToken%SQ% => {%NL%".
" %SQ%foreign.access_token_id%SQ% => %SQ%self.id%SQ%,%NL%".
" %SQ%foreign.code_id%SQ% => %SQ%self.code_id%SQ%%NL%".
" }%NL%".
");%NL%".
"__PACKAGE__->many_to_many(%NL%".
" from_refresh_token_map_m2m => from_refresh_token_map => %SQ%refresh_token%SQ% );%NL%".
"%NL%".
"# this is a has many but will only ever return a single record%NL%".
"# because of the constraint on the relationship table%NL%".
"__PACKAGE__->has_many(%NL%".
" to_refresh_token_map =>%NL%".
" %SQ%FullAutoAPI::Schema::Result::AccessTokenToRefreshToken%SQ% => {%NL%".
" %SQ%foreign.access_token_id%SQ% => %SQ%self.id%SQ%,%NL%".
" %SQ%foreign.code_id%SQ% => %SQ%self.code_id%SQ%%NL%".
" }%NL%".
");%NL%".
"__PACKAGE__->many_to_many(%NL%".
" to_refresh_token_map_m2m => to_refresh_token_map => %SQ%refresh_token%SQ% );%NL%".
"%NL%".
"sub from_refresh_token { shift->from_refresh_token_map_m2m->first }%NL%".
"sub to_refresh_token { shift->to_refresh_token_map_m2m->first }%NL%".
"%NL%".
"sub as_string { shift->id }%NL%".
"sub type {%SQ%bearer%SQ%}%NL%".
"sub expires_in {3600}%NL%".
"sub owner { shift->code->owner }";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/DO NOT MODIFY THIS/a$ad' $token_path");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".$token_path);
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" ".
$token_path);
$content=<<ENDD;
package FullAutoAPI::Schema::ResultSet::Client;
use parent 'DBIx::Class::ResultSet';
sub find_refresh {
shift->related_resultset('codes')->search( { is_active => 1 } )
->related_resultset('refresh_tokens')->find(\@_);
}
1;
__END__
=pod
=head1 NAME
FUllAutoAPI::Schema::ResultSet::Client
=head1 VERSION
version 0.001004
=head1 AUTHOR
Eden Cardim <edencardim\@gmail.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2015 by Suretec Systems Ltd.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
ENDD
my $resultset_path="./lib/FullAutoAPI/Schema/ResultSet/Client.pm";
($stdout,$stderr)=$handle->cmd(
"mkdir -vp ./lib/FullAutoAPI/Schema/ResultSet",'__display__');
($stdout,$stderr)=$handle->cmd("touch $resultset_path");
($stdout,$stderr)=$handle->cmd(
$sudo."chmod -v 777 $resultset_path",'__display__');
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > $resultset_path");
my $user_path="./lib/FullAutoAPI/Schema/Result/Users.pm";
$ad="%NL%__PACKAGE__->add_columns(%NL%".
" %SQ%+password%SQ% => {%NL%".
" passphrase => %SQ%rfc2307%SQ%,%NL%".
" passphrase_class => %SQ%BlowfishCrypt%SQ%,%NL%".
" passphrase_args => {%NL%".
" cost => 14,%NL%".
" salt_random => 20,%NL%".
" },%NL%".
" passphrase_check_method => %SQ%check_password%SQ%,%NL%".
" }%NL%".
");";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/DO NOT MODIFY THIS/a$ad' $user_path");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" $user_path");
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" $user_path");
($stdout,$stderr)=$handle->cmd("./script/fullautoapi_create.pl ".
"controller OAuth2::Provider",'__display__');
($stdout,$stderr)=$handle->cwd('deps');
($stdout,$stderr)=$handle->cmd($sudo."wget -qO- http://libevent.org/");
$stdout=~/^.*Stable releases.*?href=["](.*?)["].*?href=["](.*?)["].*$/s;
my $le_rel=$1;my $le_asc=$2;
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".$le_rel,'__display__');
$le_rel=~s/^.*\/(.*)$/$1/;
$le_asc=~s/^.*\/(.*)$/$1/;
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $le_rel",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".$le_asc,'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $le_asc",
'__display__')
if $^O ne 'cygwin';
$le_rel=~s/^.*\/(.*.tar.gz)$/$1/;
($stdout,$stderr)=$handle->cmd("tar xvf $le_rel",'__display__');
$stdout=~s/^.*\n(.*)\/.*$/$1/s;
($stdout,$stderr)=$handle->cwd($stdout);
($stdout,$stderr)=$handle->cmd('./autogen.sh','__display__');
($stdout,$stderr)=$handle->cmd('./configure',300,'__display__');
($stdout,$stderr)=$handle->cmd('make','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'make install','__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/deps');
($stdout,$stderr)=$handle->cmd($sudo."wget -qO- http://memcached.org/");
print $stderr if $stderr;
$stdout=~/^.*?Tar.Gz Download.*?href=["](.*?)["].*$/s;
my $mc_rel=$1;
unless ($mc_rel) {
($stdout,$stderr)=$handle->cmd($sudo.
"wget -qO- http://memcached.org/ -S --content-on-error",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot --no-check-certificate ".
'__display__');
($stdout,$stderr)=$handle->cmd('unzip -o master.zip','__display__');
$mc_rel='memcached-master';
($stdout,$stderr)=$handle->cwd($mc_rel);
($stdout,$stderr)=$handle->cmd('./autogen.sh','__display__');
#&exit_on_error("$stdout\n\n Output from http://memcached.org/");
} else {
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".$mc_rel,'__display__');
$mc_rel=~s/^.*\/(.*.tar.gz)$/$1/;
($stdout,$stderr)=$handle->cmd("tar xvf $mc_rel",'__display__');
$stdout=~s/^.*\n(.*)\/.*$/$1/s;
($stdout,$stderr)=$handle->cwd($stdout);
}
($stdout,$stderr)=$handle->cmd('./configure','__display__');
if ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd("sed -i 's/ -Werror//' Makefile");
($stdout,$stderr)=$handle->cmd("sed -i ".
"'s#struct sigaction a#// struct sigaction a#' testapp.c");
($stdout,$stderr)=$handle->cmd("sed -i ".
"'s#sigemptyset#// sigemptyset#' testapp.c");
($stdout,$stderr)=$handle->cmd("sed -i ".
"'s#sigaction(#// sigaction(#' testapp.c");
($stdout,$stderr)=$handle->cmd("sed -i ".
"'s#{ \"cache_redzone#// { \"cache_redzone#' testapp.c");
}
($stdout,$stderr)=$handle->cmd('make','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'make install','__display__');
unless ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cwd('scripts');
($stdout,$stderr)=$handle->cmd($sudo.
'cp -v memcached.service /etc/systemd/system',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s#bin#local/bin#\' ".
'/etc/systemd/system/memcached.service');
($stdout,$stderr)=$handle->cmd($sudo.
'systemctl daemon-reload');
($stdout,$stderr)=$handle->cmd($sudo.
'cp -v memcached.sysconfig /etc/sysconfig/memcached',
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i \'s/nobody/$username/\' /etc/sysconfig/memcached");
($stdout,$stderr)=$handle->cmd($sudo.
'chmod -v 777 /var/run','__display__');
}
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI');
#
# echo-ing/streaming files over ssh can be tricky. Use echo -e
# and replace these characters with thier HEX
# equivalents (use an external editor for quick
# search and replace - and paste back results.
# use copy/paste or cat file and copy/paste results.):
#
# ! - \\x21 ` - \\x60
# " - \\x22 \ - \\x5C
# $ - \\x24 % - \\x25
#
$content=<<'END';
#\\x21/usr/bin/env perl
use strict;
use warnings;
use lib 'lib';
BEGIN { \\x24ENV{CATALYST_DEBUG} = 0 }
use FullAutoAPI;
use DateTime;
my \\x24admin = FullAutoAPI->model('DB::Users')->search({ username => 'admin' })
->single;
\\x24admin->update({ password => 'admin', password_expires => DateTime->now });
END
($stdout,$stderr)=$handle->cmd($sudo.'touch script/set_admin_password.pl');
($stdout,$stderr)=$handle->cmd($sudo.
'chmod -v 777 script/set_admin_password.pl',
'__display__');
($stdout,$stderr)=$handle->cmd(
"echo -e \"$content\" > script/set_admin_password.pl");
my $pro_path="./lib/FullAutoAPI/Controller/OAuth2/Provider.pm";
($stdout,$stderr)=$handle->cmd($sudo."sed -i ".
"\"s/Catalyst::Controller/Catalyst::Controller::ActionRole/\" ".
$pro_path);
$ad="%NL%".
"with %SQ%CatalystX::OAuth2::Controller::Role::Provider%SQ%;%NL%".
"%NL%".
"__PACKAGE__->config(%NL%".
" store => {%NL%".
" class => %SQ%DBIC%SQ%,%NL%".
" client_model => %SQ%DB::Client%SQ%%NL%".
" }%NL%".
");%NL%".
"%NL%".
"sub request : Chained(%SQ%/%SQ%) Args(0) ".
"Does(%SQ%OAuth2::RequestAuth%SQ%) {%NL%".
" my ( \$self, \$c ) = \@_;%NL%".
"%NL%".
" my \$oauth2 = \$c->req->oauth2;%NL%".
"%NL%".
" \$oauth2->{enable_client_secret}=0;%NL%".
"}%NL%".
"%NL%".
"sub grant : Chained(%SQ%/%SQ%) Args(0) ".
"Does(%SQ%OAuth2::GrantAuth%SQ%) {%NL%".
" my ( \$self, \$c ) = \@_;%NL%".
"%NL%".
" my \$oauth2 = \$c->req->oauth2;%NL%".
"%NL%".
" \$c->user_exists and \$oauth2->user_is_valid(1)%NL%".
" or \$c->detach(%SQ%/passthrulogin%SQ%);%NL%".
"}%NL%".
"%NL%".
"sub token : Chained(%SQ%/%SQ%) Args(0) ".
"Does(%SQ%OAuth2::AuthToken::ViaAuthGrant%SQ%) {%NL%".
" my ( \$self, \$c ) = \@_;%NL%".
"%NL%".
" my \$oauth2 = \$c->req->oauth2;%NL%".
"%NL%".
" \$oauth2->{refresh_token}=1;%NL%".
"}%NL%".
"%NL%".
"sub refresh : Chained(%SQ%/%SQ%) Args(0) ".
"Does(%SQ%OAuth2::AuthToken::ViaRefreshToken%SQ%) {}%NL%";
($stdout,$stderr)=$handle->cmd($sudo.
"sed -i '/ActionRole/a$ad' $pro_path");
($stdout,$stderr)=$handle->cmd( # bash shell specific
$sudo."sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" $pro_path");
($stdout,$stderr)=$handle->cmd($sudo."sed -i \"s/%SQ%/\'/g\" $pro_path");
$content=<<'END';
name: FullAutoAPI
Model::DB:
schema_class: FullAutoAPI::Schema
connect_info:
- DBI:SQLite:dbname=__path_to(db/fullautoapi.db)__
- \\x22\\x22
- \\x22\\x22
END
($stdout,$stderr)=$handle->cmd($sudo."touch fullautoapi.yml");
($stdout,$stderr)=$handle->cmd($sudo."chmod -v 777 fullautoapi.yml",
'__display__');
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > fullautoapi.yml");
($stdout,$stderr)=$handle->cmd($sudo."chmod -v 644 fullautoapi.yml",
'__display__');
$content=<<'END';
<View::Email::Template>
    <sender>
        mailer Sendmail
    </sender>
    template_prefix email
    <default>
        content_type text/html
        charset utf-8
        view TT
    </default>
</View::Email::Template>
 
default_view TT
END
($stdout,$stderr)=$handle->cmd($sudo.'chmod -v 777 fullautoapi.conf',
'__display__');
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" >> fullautoapi.conf");
($stdout,$stderr)=$handle->cmd($sudo.'chmod -v 644 fullautoapi.conf',
'__display__');
($stdout,$stderr)=$handle->cmd(
"./script/fullautoapi_create.pl controller User",'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'rm -rvf lib/FullAutoAPI/Controller/User.pm',
'__display__');
my $view_path='./lib/FullAutoAPI/View/TT.pm';
($stdout,$stderr)=$handle->cmd(
"./script/fullautoapi_create.pl view TT TT",'__display__');
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i \'s/\.tt/\.tt2/\' $view_path");
$ad='WRAPPER => %SQ%wrapper.tt2%SQ%,';
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i \'/render_die/a$ad\' $view_path");
$handle->cmd_raw(
"${sudo}sed -i 's/\\(^WRAPPER =.*\\\)/ \\1/' $view_path");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" $view_path");
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" $view_path");
($stdout,$stderr)=$handle->cmd($sudo.
'mkdir -vp root/static/jquery','__display__');
($stdout,$stderr)=$handle->cwd('root/static/jquery');
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username jquery-ui.js",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username jquery-1.11.3.js",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/root');
($stdout,$stderr)=$handle->cmd($sudo.
"wget --random-wait --progress=dot ".
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username master.zip",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd('unzip -o master.zip','__display__');
($stdout,$stderr)=$handle->cmd($sudo.'rm -rvf master.zip','__display__');
($stdout,$stderr)=$handle->cwd('DataTables-master');
($stdout,$stderr)=$handle->cmd('cp -Rv media ..','__display__');
($stdout,$stderr)=$handle->cwd('examples');
($stdout,$stderr)=$handle->cmd('cp -Rv resources ../..','__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI');
($stdout,$stderr)=$handle->cmd("./script/fullautoapi_create.pl ".
"view Email::Template Email::Template",'__display__');
#
# echo-ing/streaming files over ssh can be tricky. Use echo -e
# and replace these characters with thier HEX
# equivalents (use an external editor for quick
# search and replace - and paste back results.
# use copy/paste or cat file and copy/paste results.):
#
# ! - \\x21 ` - \\x60
# " - \\x22 \ - \\x5C
# $ - \\x24 % - \\x25
#
$content=<<END;
package FullAutoAPI::Controller::User;
use strict;
use warnings;
use Moose;
use DBI;
use namespace::autoclean;
use ZMQ::LibZMQ4;
use ZMQ::Constants qw(:all);
use JSON::XS;
use YAML;
use Carp::Assert;
use Crypt::PassGen 'passgen';
use FullAutoAPI::Form::AddUser ();
use FullAutoAPI::Form::EditUser ();
use FullAutoAPI::Form::ChangePassword ();
use FullAutoAPI::Form::UserProfile ();
use Math::Random::ISAAC::XS;
use Bytes::Random::Secure;
use constant NBR_WORKERS => 2;
use constant READY => \\x22\\x5C001\\x22;
use constant FRONTEND_URL =>
\\x22ipc://${home_dir}FullAutoAPI/frontend.ipc\\x22;
BEGIN { extends 'Catalyst::Controller::ActionRole' }
with 'CatalystX::OAuth2::Controller::Role::WithStore';
BEGIN { extends 'Catalyst::Controller::REST' }
BEGIN {
if (\\x24^O eq 'cygwin') {
if (-e 'script/first_time_start.flag') {
unlink 'script/first_time_start.flag';
} else {
my \\x24out=\\x60/bin/cygrunsrv -L\\x60;
if (-1<index \\x24out,'nginx_first_time') {
\\x60/bin/cygrunsrv -R nginx_first_time\\x60;
}
}
}
}
__PACKAGE__->config(
store => {
class => 'DBIC',
client_model => 'DB::Client'
}
);
__PACKAGE__->config(
'default' => 'application/json',
'map' => {
'text/html' => [ 'View', 'TT' ],
'text/xml' => [ 'View', 'TT' ],
'text/x-yaml' => 'YAML',
'application/json' => 'JSON',
'text/x-json' => 'JSON',
'text/x-data-dumper' => [ 'Data::Serializer', 'Data::Dumper' ],
'text/x-data-denter' => [ 'Data::Serializer', 'Data::Denter' ],
'text/x-data-taxi' => [ 'Data::Serializer', 'Data::Taxi' ],
'application/x-storable' => [ 'Data::Serializer', 'Storable' ],
'application/x-freezethaw' => [ 'Data::Serializer', 'FreezeThaw' ],
'text/x-config-general' => [ 'Data::Serializer', 'Config::General' ],
'application/x-www-form-urlencoded' => 'JSON',
},
);
sub cmd : Path('/cmd') : Args(0) : ActionClass('REST') { }
sub cmd_POST : Chained('/') Args(0) Does('OAuth2::ProtectedResource') {
my ( \\x24self, \\x24c ) = \@_;
my \\x24auth = \\x24c->req->header('Authorization')||'';
my ( \\x24type, \\x24token ) = split ' ', \\x24auth;
my \\x24token_obj = \\x24self->store->verify_client_token(\\x24token);
print \\x22EXPIRES_IN=\\x22,\\x24token_obj->expires_in,\\x22\\\\\\\\n\\x22;
print \\x22TOKEN=\\x22,\\x24token,\\x22\\\\\\\\n\\x22;
my \\x24cmd_data = '';
my \\x24cmd = '';
my \\x24file = '';
if ( \\x24c->req->data ) {
print \\x22REQUEST DATA=\\x22,Data::Dump::Streamer::Dump(\\x24c->req->data)->Out(),\\x22\\\\\\\\n\\x22;
\\x24cmd_data = \\x24c->req->data;
unless (ref \\x24cmd_data->{'cmd'} eq 'ARRAY') {
\\x24cmd_data->{'cmd'}=[ \\x24cmd_data->{'cmd'} ];
}
\\x24cmd=encode_json \\x24cmd_data->{'cmd'};
} elsif ( \\x24c->req->uploads ) {
print \\x22REQUEST UPLOADS=\\x22,Data::Dump::Streamer::Dump(\\x24c->req->uploads)->Out(),\\x22\\\\\\\\n\\x22;
for my \\x24field ( \\x24c->req->upload ) {
my \\x24upload = \\x24c->req->upload(\\x24field);
\\x24cmd = encode_json [[ 'upload', \\x24upload->filename,
\\x24upload->slurp() ]];
last;
}
} else {
return \\x24self->status_bad_request(\\x24c,
message => 'You must provide a cmd to execute\\x21' );
}
my \\x24id = 'Client-'.\\x24\\x24;
my \\x24ctx = zmq_init();
my \\x24socket = zmq_socket(\\x24ctx,ZMQ_REQ);
my \\x24rv = zmq_setsockopt(\\x24socket,ZMQ_IDENTITY,\\x24id);
assert(\\x24rv == 0, 'setting socket options');
\\x24rv = zmq_connect(\\x24socket,FRONTEND_URL());
assert(\\x24rv == 0,'connecting client ...');
print \\x22\\x24id sending cmd\\\\\\\\n\\x22;
\\x24rv = zmq_msg_send(\\x24cmd,\\x24socket);
my \\x24reply = zmq_recvmsg(\\x24socket);
print \\x22\\x24id got a result -> \\x22,zmq_msg_data(\\x24reply),\\x22\\\\\\\\n\\x22;
my \\x24return_entity = {
result => zmq_msg_data(\\x24reply),
};
\\x24self->status_ok( \\x24c, entity => \\x24return_entity, );
}
sub base : Chained('/base') PathPrefix CaptureArgs(0) {}
sub admin : Chained('base') PathPart('') CaptureArgs(0) Does('ACL') RequiresRole('admin') ACLDetachTo('denied') {}
sub change_password : Chained('base') PathPart('change_password') Args(0) {
my (\\x24self, \\x24c) = \@_;
my \\x24form = FullAutoAPI::Form::ChangePassword->new;
\\x24c->stash(form => \\x24form);
return unless \\x24form->process(
user => \\x24c->user,
params => \\x24c->req->body_parameters,
);
\\x24c->user->update({
password => \\x24form->field('new_password')->value,
password_expires => undef,
});
\\x24c->res->redirect(\\x24c->uri_for('/rest/demo', {
status_msg => 'Password changed successfully'
}));
}
sub profile : Chained('base') PathPart('profile') Args(0) {
my (\\x24self, \\x24c) = \@_;
my \\x24form = FullAutoAPI::Form::UserProfile->new;
\\x24c->stash(form => \\x24form);
return unless \\x24form->process(
schema => \\x24c->model('DB')->schema,
item_id => \\x24c->user->id,
params => \\x24c->req->body_parameters,
);
\\x24c->res->redirect(\\x24c->uri_for('/user', {
status_msg => 'Profile Updated'
}));
}
sub user_list : Path('/user') :Args(0) : ActionClass('REST') { }
sub user_list_GET {
my ( \\x24self, \\x24c ) = \@_;
my \\x24draw = \\x24c->req->params->{draw} || 0;
my \\x24start = \\x24c->req->params->{start} || 0;
my \\x24per_page = \\x24c->req->params->{length} || 10;
my \\x24page = 1;
if (\\x24start<\\x24per_page) {
\\x24page=1;
} else {
\\x24page=int(\\x24start/\\x24per_page)+1;
}
my \\x24id = 'Client-'.\\x24\\x24;
my \\x24ctx = zmq_init();
my \\x24socket = zmq_socket(\\x24ctx,ZMQ_REQ);
my \\x24rv = zmq_setsockopt(\\x24socket,ZMQ_IDENTITY,\\x24id);
assert(\\x24rv == 0, 'setting socket options');
\\x24rv = zmq_connect(\\x24socket,FRONTEND_URL());
assert(\\x24rv == 0,'connecting client ...');
print \\x22\\x24id sending Hello\\\\\\\\n\\x22;
\\x24rv = zmq_msg_send(encode_json(['Hello']),\\x24socket);
my \\x24reply = zmq_recvmsg(\\x24socket);
assert(\\x24reply);
print \\x22\\x24id got a reply -> \\x22,zmq_msg_data(\\x24reply),\\x22\\\\\\\\n\\x22;
# We'll use an array now:
my \@user_list;
my \\x24rs = \\x24c->model('DB::User')
->search(undef, { rows => \\x24per_page })->page( \\x24page );
while ( my \\x24user_row = \\x24rs->next ) {
push \@user_list, {
\\x24user_row->get_columns,
uri => \\x24c->uri_for( '/user/' . \\x24user_row->user_id )->as_string
};
}
\\x24self->status_ok( \\x24c, entity => {
draw => \\x24draw,
recordsTotal => \\x24rs->pager->total_entries,
recordsFiltered => \\x24rs->pager->total_entries,
data => [ \@user_list ]
});
};
sub single_user : Path('/user') : Args(1) : ActionClass('REST') {
my ( \\x24self, \\x24c, \\x24user_id ) = \@_;
\\x24c->stash->{'user'} = \\x24c->model('DB::User')->find(\\x24user_id);
}
sub single_user_POST {
my ( \\x24self, \\x24c, \\x24user_id ) = \@_;
my \\x24new_user_data = \\x24c->req->data;
if ( \\x21defined(\\x24new_user_data) ) {
return \\x24self->status_bad_request(\\x24c,
message => 'You must provide a user to create or modify\\x21' );
}
if ( \\x24new_user_data->{'user_id'} ne \\x24user_id ) {
return \\x24self->status_bad_request(
\\x24c,
message =>
'Cannot create or modify user '
. \\x24new_user_data->{'user_id'} . ' at '
. \\x24c->req->uri->as_string
. '; the user_id does not match\\x21' );
}
foreach my \\x24required (qw(user_id fullname description)) {
return \\x24self->status_bad_request( \\x24c,
message => 'Missing required field: ' . \\x24required )
if \\x21exists( \\x24new_user_data->{\\x24required} );
}
my \\x24user = \\x24c->model('DB::User')->update_or_create(
user_id => \\x24new_user_data->{'user_id'},
fullname => \\x24new_user_data->{'fullname'},
description => \\x24new_user_data->{'description'},
);
my \\x24return_entity = {
user_id => \\x24user->user_id,
fullname => \\x24user->fullname,
description => \\x24user->description,
};
if ( \\x24c->stash->{'user'} ) {
\\x24self->status_ok( \\x24c, entity => \\x24return_entity, );
} else {
\\x24self->status_created(
\\x24c,
location => \\x24c->req->uri->as_string,
entity => \\x24return_entity,
);
}
}
*single_user_PUT = *single_user_POST;
sub single_user_GET {
my ( \\x24self, \\x24c, \\x24user_id ) = \@_;
my \\x24user = \\x24c->stash->{'user'};
if ( defined(\\x24user) ) {
\\x24self->status_ok(
\\x24c,
entity => {
user_id => \\x24user->user_id,
fullname => \\x24user->fullname,
description => \\x24user->description,
}
);
}
else {
\\x24self->status_not_found( \\x24c,
message => 'Could not find User '.\\x24user_id.'\\x21' );
}
}
sub single_user_DELETE {
my ( \\x24self, \\x24c, \\x24user_id ) = \@_;
my \\x24user = \\x24c->stash->{'user'};
if ( defined(\\x24user) ) {
\\x24user->delete;
\\x24self->status_ok(
\\x24c,
entity => {
user_id => \\x24user->user_id,
fullname => \\x24user->fullname,
description => \\x24user->description,
}
);
} else {
\\x24self->status_not_found( \\x24c,
message => 'Cannot delete non-existent user '.\\x24user_id.'\\x21' );
}
}
sub list : Chained('admin') PathPart('list') Args(0) {
my (\\x24self, \\x24c) = \@_;
my \\x24users = \\x24c->model('DB::Users')->search(
{ active => 'Y'},
{
order_by => ['username'],
page => (\\x24c->req->param('page') || 1),
rows => 20,
}
);
\\x24c->stash(
users => \\x24users,
pager => \\x24users->pager,
);
}
sub add : Chained('admin') PathPart('add') Args(0) {
my (\\x24self, \\x24c) = \@_;
my \\x24form = FullAutoAPI::Form::AddUser->new;
\\x24c->stash(form => \\x24form);
my \\x24user = \\x24c->model('DB::Users')->new_result({});
my \\x24client = \\x24c->model('DB::Client')->new_result({});
my (\\x24temp_password) = passgen(NWORDS => 1, NLETT => 8);
\\x24user->password(\\x24temp_password);
\\x24user->password_expires(DateTime->now);
\\x24user->active('Y');
return unless \\x24form->process(
schema => \\x24c->model('DB')->schema,
item => \\x24user,
params => \\x24c->req->body_parameters,
);
my \\x24client_id=\\x24user->id.time();
\\x24user->client_id(\\x24client_id);
\\x24client->id(\\x24client_id);
\\x24client->endpoint('/cmd');
my \\x24secret=Bytes::Random::Secure::random_bytes_base64(30);
\\x24user->client_secret(\\x24secret);
\\x24user->update;
\\x24client->client_secret(\\x24secret);
\\x24client->insert;
\\x24c->stash->{email} = {
to => \\x24user->email_address,
from => 'admin\@MyOrg.com',
subject => 'Welcome to the FullAuto API',
content_type => 'text/html',
template => 'email/welcome.tt2',
};
\\x24c->stash(
username => \\x24user->username,
password => \\x24temp_password,
client_id => \\x24client->id,
client_secret => \\x24client->client_secret,
);
\\x24c->forward(\\x24c->view('Email::Template'));
\\x24c->res->redirect(\\x24c->uri_for(\\x24self->action_for('list'), {
status_msg => 'User '
. \\x24user->username
. ' created successfully'
. ', initial password emailed ' . 'to '
. \\x24user->email_address
}));
}
sub user : Chained('admin') PathPart('') CaptureArgs(1) {
my (\\x24self, \\x24c, \\x24user_id) = \@_;
\\x24c->stash(user => \\x24c->model('DB::Users')->find(\\x24user_id));
}
sub inactivate : Chained('user') PathPart('inactivate') Args(0) {
my (\\x24self, \\x24c) = \@_;
my \\x24user = \\x24c->stash->{user};
\\x24user->update({ active => 'N' });
my \\x24username = \\x24user->username;
\\x24c->res->redirect(\\x24c->uri_for(\\x24self->action_for('list'), {
status_msg => \\x22User \\x24username inactivated\\x22
}));
}
sub reset_password : Chained('user') PathPart('reset_password') Args(0) {
my (\\x24self, \\x24c) = \@_;
my \\x24user = \\x24c->stash->{user};
my (\\x24temp_password) = passgen(NWORDS => 1, NLETT => 8);
\\x24user->password(\\x24temp_password);
\\x24user->password_expires(DateTime->now);
\\x24user->update;
\\x24c->stash->{email} = {
to => \\x24user->email_address,
from => 'admin\@MyOrg.com',
subject => 'Your FullAuto API Management Dashboard Password has been Reset',
content_type => 'text/html',
template => 'reset_password.tt2',
};
\\x24c->stash(
username => \\x24user->username,
password => \\x24temp_password,
);
\\x24c->forward(\\x24c->view('Email::Template'));
\\x24c->res->redirect(\\x24c->uri_for(\\x24self->action_for('list'), {
status_msg => 'Password reset email for '
. \\x24user->username
. ' sent to '
. \\x24user->email_address
}));
}
sub edit : Chained('user') PathPart('edit') Args(0) {
my (\\x24self, \\x24c) = \@_;
my \\x24form = FullAutoAPI::Form::EditUser->new;
\\x24c->stash(form => \\x24form);
return unless \\x24form->process(
schema => \\x24c->model('DB')->schema,
item_id => \\x24c->stash->{user}->id,
params => \\x24c->req->body_parameters,
);
\\x24c->res->redirect(\\x24c->uri_for(\\x24self->action_for('list'), {
status_msg => 'User '
. \\x24c->stash->{user}->username
. ' updated successfully'
}));
}
sub denied : Private {
my (\\x24self, \\x24c) = \@_;
\\x24c->res->redirect(\\x24c->uri_for('/rest/demo', {
status_msg => \\x22Access Denied\\x22
}));
}
1;
END
($stdout,$stderr)=$handle->cwd('lib/FullAutoAPI/Controller');
($stdout,$stderr)=$handle->cmd("touch User.pm");
($stdout,$stderr)=$handle->cmd($sudo."chmod -v 777 User.pm",'__display__');
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > User.pm");
$content=<<END;
package FullAutoAPI::Controller::Rest;
use Moose;
use namespace::autoclean;
BEGIN {extends 'Catalyst::Controller::ActionRole'; }
sub base : Chained('/base') PathPrefix CaptureArgs(0) {}
sub rest : Chained('base') PathPart('demo') Args(0) {
my (\\x24self, \\x24c) = \@_;
\\x24c->stash(template => 'rest/demo.tt2');
}
sub denied : Private {
my (\\x24self, \\x24c) = \@_;
\\x24c->res->redirect(\\x24c->uri_for(\\x24self->action_for('rest'),
{status_msg => \\x22Access Denied\\x22}));
}
__PACKAGE__->meta->make_immutable;
1;
END
($stdout,$stderr)=$handle->cmd($sudo.'touch Rest.pm');
($stdout,$stderr)=$handle->cmd($sudo."chmod -v 777 Rest.pm",'__display__');
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > Rest.pm");
$ad='sub home : Chained(%SQ%/base%SQ%) PathPart(%SQ%%SQ%) Args(0) {'.
'%NL% my ($self, $c) = @_;%NL%%NL%'.
' $c->res->redirect($c->uri_for(%SQ%/rest/demo%SQ%));%NL%'.
'}%NL%%NL%';
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i \'/sub index :Path/i$ad\' ./Root.pm");
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i '/index :Path :/,+6d' ./Root.pm");
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i 's/index/home/' ./Root.pm");
$ad='%NL%sub base : Chained(%SQ%/login/required%SQ%) PathPrefix '.
'CaptureArgs(0) {%NL%'.
' my ($self, $c) = @_;%NL%'.
'%NL%'.
' if ($c->action ne $c->controller(%SQ%User%SQ%)->action_for('.
'%SQ%change_password%SQ%)%NL%'.
' && $c->user_exists%NL%'.
' && $c->user->password_expires%NL%'.
' && $c->user->password_expires <= DateTime->now)%NL%'.
' {%NL% '.
'$c->res->redirect($c->uri_for(%SQ%/user/change_password%SQ%, {%NL%'.
' status_msg => %SQ%Password Expired%SQ%%NL%'.
' }));%NL%'.
' $c->detach;%NL%'.
' }%NL%'.
'}%NL%';
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i \'/home : Chained/i$ad\' ./Root.pm");
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i 's#default :Path#default : Chained(%SQ%/base%SQ%) ".
"PathPart(%SQ%%SQ%) Args#' ./Root.pm");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ./Root.pm");
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" ./Root.pm");
($stdout,$stderr)=$handle->cwd("~/FullAutoAPI/lib/FullAutoAPI");
($stdout,$stderr)=$handle->cmd("mkdir -vp Form");
($stdout,$stderr)=$handle->cwd("Form");
$content=<<END;
package FullAutoAPI::Form::AddUser;
use HTML::FormHandler::Moose;
extends 'FullAutoAPI::Form::EditUser';
use namespace::autoclean;
has_field 'username' => (
type => 'Text',
label => 'User name',
required => 1,
);
__PACKAGE__->meta->make_immutable;
1;
END
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > AddUser.pm");
$content=<<END;
package FullAutoAPI::Form::ChangePassword;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
use namespace::autoclean;
use Method::Signatures::Simple;
has user => (is => 'rw');
has_field 'current_password' => (
type => 'Password',
label => 'Current Password',
required => 1,
);
method validate_current_password(\\x24field) {
\\x24field->add_error('Incorrect password')
if not \\x24self->user->check_password(\\x24field->value);
}
has_field 'new_password' => (
type => 'Password',
label => 'New Password',
required => 1,
minlength => 5,
);
after validate => method {
if (\\x24self->field('new_password')->value eq
\\x24self->field('current_password')->value )
{
\\x24self->field('new_password')
->add_error('Must be different from current password');
}
};
has_field 'new_password_conf' => (
type => 'PasswordConf',
label => 'New Password (again)',
password_field => 'new_password',
required => 1,
minlength => 5,
);
has_field submit => (type => 'Submit', value => 'Change');
__PACKAGE__->meta->make_immutable;
1;
END
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > ChangePassword.pm");
$content=<<END;
package FullAutoAPI::Form::EditUser;
use HTML::FormHandler::Moose;
extends 'FullAutoAPI::Form::UserProfile';
use namespace::autoclean;
has_field 'roles' => (
type => 'Multiple',
widget => 'checkbox_group',
label_column => 'name',
label => '',
);
__PACKAGE__->meta->make_immutable;
1;
END
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > EditUser.pm");
$content=<<END;
package FullAutoAPI::Form::UserProfile;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler::Model::DBIC';
use namespace::autoclean;
has '+item_class' => (default => 'Users');
has_field 'name' => ( type => 'Text', required => 1 );
has_field 'email_address' => ( type => 'Email', required => 1 );
has_field 'phone_number' => ( type => 'Text' );
has_field 'mail_address' => ( type => 'Text' );
has_field submit => (
type => 'Submit',
value => 'Update'
);
__PACKAGE__->meta->make_immutable;
1;
END
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > UserProfile.pm");
($stdout,$stderr)=$handle->cmd($sudo."chmod -v 644 UserProfile.pm",
'__display__');
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/root/static');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/RestYUI/root/static/json2.js .",
'__display__');
#($stdout,$stderr)=$handle->cmd($sudo.
# "wget --random-wait --progress=dot ".
# "examples/RestYUI/root/static/json2.js",
# '__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username json2.js",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd('mkdir -vp yui','__display__');
($stdout,$stderr)=$handle->cwd('yui');
my @yuifiles=('utilities.js','dom.js','connection.js','event.js',
'yahoo.js');
foreach my $file (@yuifiles) {
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/RestYUI/root/static/yui/$file .",
'__display__');
#($stdout,$stderr)=$handle->cmd($sudo.
# "wget --random-wait --progress=dot ".
# "examples/RestYUI/root/static/yui/$file",
# '__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username $file",
'__display__')
if $^O ne 'cygwin';
}
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/root');
($stdout,$stderr)=$handle->cmd('mkdir -vp user','__display__');
($stdout,$stderr)=$handle->cwd('user');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/RestYUI/root/user/single_user.tt .",
'__display__');
#($stdout,$stderr)=$handle->cmd($sudo.
# "wget --random-wait --progress=dot ".
# "examples/RestYUI/root/user/single_user.tt",
# '__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"chown -v $username:$username single_user.tt",
'__display__')
if $^O ne 'cygwin';
($stdout,$stderr)=$handle->cmd(
"sed -i 's/POSTT/POST/' single_user.tt");
($stdout,$stderr)=$handle->cmd(
"mv single_user.tt single_user.tt2");
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI/root');
($stdout,$stderr)=$handle->cmd($sudo.'rm -rvf rest');
($stdout,$stderr)=$handle->cmd('mkdir -vp rest','__display__');
($stdout,$stderr)=$handle->cwd('rest');
#
# echo-ing/streaming files over ssh can be tricky. Use echo -e
# and replace these characters with thier HEX
# equivalents (use an external editor for quick
# search and replace - and paste back results.
# use copy/paste or cat file and copy/paste results.):
#
# ! - \\x21 ` - \\x60
# " - \\x22 \ - \\x5C
# $ - \\x24 % - \\x25
#
$content=<<END;
<\\x21DOCTYPE html>
<html>
<head>
<meta charset=\\x22utf-8\\x22>
<meta name=\\x22viewport\\x22 content=\\x22initial-scale=1.0, maximum-scale=2.0\\x22>
<title>Catalyst REST Example</title>
<link rel=\\x22stylesheet\\x22 type=\\x22text/css\\x22 href=\\x22https://cdn.datatables.net/1.10.8/css/jquery.dataTables.min.css\\x22>
<link rel=\\x22stylesheet\\x22 type=\\x22text/css\\x22 href=\\x22resources/demo.css\\x22></script>
<script type=\\x22text/javascript\\x22 language=\\x22javascript\\x22 src=\\x22//code.jquery.com/jquery-1.11.3.min.js\\x22></script>
<script type=\\x22text/javascript\\x22 language=\\x22javascript\\x22 src=\\x22https://cdn.datatables.net/1.10.8/js/jquery.dataTables.min.js\\x22></script>
<script type=\\x22text/javascript\\x22 language=\\x22javascript\\x22 class=\\x22init\\x22>
\\x24(document).ready(function() {
\\x24(\\x22#example\\x22).dataTable({
\\x22processing\\x22: true,
\\x22serverSide\\x22: true,
\\x22ajax\\x22: \\x22[%c.uri_for( c.controller('User').action_for('user_list') ) %]?page=1&content-type=application/json\\x22,
\\x22aoColumns\\x22: [{
\\x22mData\\x22:\\x22user_id\\x22,
},{
\\x22mData\\x22: \\x22fullname\\x22,
},{
\\x22mData\\x22: \\x22description\\x22,
}]
});
} );
</script>
</head>
<body class=\\x22dt-example\\x22>
<div class=\\x22container\\x22>
<section>
<h1>Catalyst REST Example <span>Using JQuery DataTable</span></h1>
<div class=\\x22info\\x22>
<p>FullAuto was used to stand up this fully functional Catalyst REST installation.
The following table is full of demo user data. To add or update a user, manually
modify the browser URL like so:
<br><br><code>[%c.uri_for( c.controller('User').action_for('user_list') ) %]/user_id</code></p>
<p>Data can be accessed on the command line:
<br><br><code>curl -X GET -k -H 'Content-Type: application/json'
[%c.uri_for( c.controller('User').action_for('user_list') ) %]</code>
<br><br><code>
curl -X GET -k
\\x22[% c.req.base %]request?client_id=&lt;client_id&gt;&response_type=code&redirect_uri=/cmd\\x22
</code><br><br><code>
curl -X GET -k
\\x22[% c.req.base %]/token?grant_type=authorization_code&client_id=&lt;client_id&gt;&redirect_uri=/cmd&code=&lt;code&gt;\\x22
</code><br><br><code>
curl -X POST -k -H 'Authorization: Bearer &lt;token&gt;'
-H 'Content-Type: application/json'
-d '{\\x22cmd\\x22:\\x22hostname\\x22}'
[% c.req.base %]cmd
</code></p>
</div>
<table id=\\x22example\\x22 class=\\x22display\\x22 cellspacing=\\x220\\x22 width=\\x22100%\\x22>
<thead>
<tr>
<th>ID</th>
<th>Full Name</th>
<th>Description</tn>
</tr>
</thead>
<tfoot>
<tr>
<th>ID</th>
<th>Full Name</th>
<th>Description</th>
</tr>
</tfoot>
</table>
</div>
</section>
</div>
</body>
</html>
END
($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > demo.tt2");
($stdout,$stderr)=$handle->cwd('~/FullAutoAPI');
$ad="use Net::FullAuto;%NL%".
"use Net::FullAuto::Cloud::fa_amazon;%NL%".
"use ZMQ::LibZMQ4;%NL%".
"use ZMQ::Constants qw(:all);%NL%".
"use JSON::XS;%NL%".
"use YAML;%NL%".
"use Carp::Assert;%NL%".
"use Crypt::PassGen %SQ%passgen%SQ%;%NL%".
"use Math::Random::ISAAC::XS;%NL%".
"use Bytes::Random::Secure;%NL%%NL%".
"use constant NBR_WORKERS => 2;%NL%".
"use constant READY => \"\\\\001\";%NL%".
"%NL%".
"use constant BACKEND_URL =>%NL%".
" %SQ%ipc://${home_dir}FullAutoAPI/backend.ipc%SQ%;%NL%".
"use constant FRONTEND_URL =>%NL%".
" %SQ%ipc://${home_dir}FullAutoAPI/frontend.ipc%SQ%;%NL%".
"%NL%".
"use Parallel::Forker;%NL%".
"%NL%".
"my \$fa_sub=sub {%NL%".
"%NL%".
" # A bit of custom config riding/hacking to use the application".
"%SQ%s%NL%".
" # config for the DB.%NL%".
" my \$config_file = %SQ%${home_dir}FullAutoAPI/fullautoapi.yml".
"%SQ%;%NL%".
" my \$config_data = YAML::LoadFile( \$config_file );%NL%".
" #my \$args = \$config_data->{\"Model::ZeroMQ\"}->{args};%NL%".
"%NL%".
" my \$id = %SQ%Worker-%SQ%.\$\$;%NL%%NL%".
" my \$ctx = zmq_init();%NL%".
" my \$socket = zmq_socket(\$ctx,ZMQ_REQ);%NL%%NL%".
" my \$rv = zmq_setsockopt(\$socket,ZMQ_IDENTITY,\$id);%NL%".
" assert(\$rv == 0);%NL%%NL%".
" \$rv = zmq_connect(\$socket,BACKEND_URL());%NL%".
" assert(\$rv == 0,%SQ%connecting to backend%SQ%);%NL%%NL%".
" print \"\$id sending READY\\n\";%NL%".
"%NL%".
" \$rv = zmq_msg_send(READY(),\$socket);%NL%".
" assert(\$rv);%NL%".
"%NL%".
" my \$buf = zmq_msg_init();%NL%".
"%NL%".
" my (\$fullauto,\$stdout,\$stderr,\$exitcode,".
"\$connect_error)=(%SQ%%SQ%,%SQ%%SQ%,%SQ%%SQ%,%SQ%%SQ%,%SQ%%SQ%);%NL%".
" (\$fullauto,\$connect_error)=connect_shell();%NL%".
"%NL%".
" use Time::HiRes;%NL%".
" my \$msg = zmq_msg_init();%NL%".
" my \$handles={};%NL%".
" while (1) {%NL%".
"%NL%".
" my \@msg=();%NL%".
" if (zmq_msg_recv(\$buf,\$socket,ZMQ_DONTWAIT)) {%NL%".
" push \@msg, zmq_msg_data(\$buf);%NL%".
" while (zmq_getsockopt(\$socket,ZMQ_RCVMORE)) {%NL%".
" zmq_msg_recv(\$buf,\$socket);%NL%".
" push \@msg, zmq_msg_data(\$buf);%NL%".
" }%NL%".
" }%NL%".
" if (getppid==1) {%NL%".
" `pgrep -P \$\$ | xargs kill -TERM`;%NL%".
" exit;%NL%".
" }%NL%".
" if (\$#msg) {%NL%".
" print \"\$id got: \$msg[2] from \$msg[0]\\n\";%NL%".
" print \"\$id sending OK to \$msg[0]\\n\";%NL%".
" zmq_msg_send(\$msg[0],\$socket,ZMQ_SNDMORE);%NL%".
" zmq_msg_send(%SQ%%SQ%,\$socket,ZMQ_SNDMORE);%NL%".
" my \$cmds=decode_json \$msg[2];%NL%".
" if (\$cmds->[0] eq %SQ%Hello%SQ%) {%NL%".
" zmq_msg_send(encode_json([%SQ%Hello Back%SQ%]),%NL%".
" \$socket);%NL%".
" next;%NL%".
" }%NL%".
" \$cmds=[\$cmds] unless ref \$cmds eq %SQ%ARRAY%SQ%;%NL%".
" my \$out=[];%NL%".
" foreach my \$cmd (\@{\$cmds}) {%NL%".
" if (ref \$cmd eq %SQ%ARRAY%SQ%) {%NL%".
" if (\$cmd->[0] eq %SQ%cmd%SQ%) {%NL%".
" (\$stdout,\$stderr)=\$fullauto->cmd(%NL%".
" \$cmd->[1],%SQ%__display__%SQ%);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" } elsif (\$cmd->[0] eq %SQ%cmd_raw%SQ%) {%NL%".
" (\$stdout,\$stderr)=\$fullauto->cmd_raw(%NL%".
" \$cmd->[1]);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" } elsif (\$cmd->[0] eq %SQ%cwd%SQ%) {%NL%".
" (\$stdout,\$stderr)=\$fullauto->cwd(%NL%".
" \$cmd->[1]);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" } elsif (\$cmd->[0] eq %SQ%aws_configure%SQ%) {%NL%".
" my \$key=\$cmd->[1];%NL%".
" my \$secret=\$cmd->[2];%NL%".
" \$aws_configure->(\$key,\$secret);%NL%".
" } elsif (\$cmd->[0] eq %SQ%upload%SQ%) {%NL%".
" open(FH,\">/tmp/\$cmd->[1]\") || warn \$!;%NL%".
" print FH \$cmd->[2];%NL%".
" close FH;%NL%".
" } elsif (\$cmd->[0] eq %SQ%label%SQ%) {%NL%".
" print \"LABEL=\".\$cmd->[1]->[0];%NL%".
" if (exists \$handles->{\$cmd->[1]->[0]}) {%NL%".
" if (\$cmd->[1]->[1] eq %SQ%cmd%SQ%) {%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->cmd(%NL%".
" \$cmd->[1]->[2]);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" } elsif (\$cmd->[1]->[0] eq %SQ%close%SQ%) {%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->close();%NL%".
" delete \$handles->{\$cmd->[1]->[0]};%NL%".
" \$stdout=\"\$cmd->[1]->[0] CLOSED\";%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" } elsif (\$cmd->[1]->[1] eq 'docker_run') {%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->docker_run(%NL%".
" \$cmd->[1]->[2]);%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->cmd(%NL%".
" %SQ%hostname%SQ%);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" } elsif (\$cmd->[1]->[1] eq %NL%".
" %SQ%docker_attach%SQ%) {%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->docker_attach(%NL%".
" \$cmd->[1]->[2]);%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->cmd(%NL%".
" %SQ%hostname%SQ%);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" } elsif (\$cmd->[1]->[1] eq%NL%".
" %SQ%docker_exit%SQ%) {%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->docker_exit();%NL%".
" (\$stdout,\$stderr)=\$handles->{%NL%".
" \$cmd->[1]->[0]}->cmd(%NL%".
" %SQ%hostname%SQ%);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" }%NL%".
" }%NL%".
" } elsif (\$cmd->[0] eq %SQ%connect_secure%SQ%) {%NL%".
" my \$identityfile=\$cmd->[1]->{%NL%".
" %SQ%identityfile%SQ%};%NL%".
" my \$pwd=`pwd`;%NL%".
" chomp(\$pwd);%NL%".
" \$identityfile=\$pwd.%SQ%/%SQ%.\$identityfile if%NL%".
" -1==index(\$identityfile,%SQ%/%SQ%);%NL%".
" my (\$connect_label) = passgen(NWORDS => 1,%NL%".
" NLETT => 8);%NL%".
" my \$server={%NL%".
" Label => \$connect_label,%NL%".
" IP => \$cmd->[1]->{%SQ%ip%SQ%},%NL%".
" Login => \$cmd->[1]->{%SQ%login%SQ%},%NL%".
" IdentityFile => \$identityfile,%NL%".
" NoRetry => \$cmd->[1]->{%SQ%noretry%SQ%}||".
"%SQ%%SQ%,%NL%".
" debug => \$cmd->[1]->{%SQ%debug%SQ%}||0%NL%".
" };%NL%".
" my \$error=%SQ%%SQ%;my \$stdout=%SQ%%SQ%;%NL%".
" my \$stderr=%SQ%%SQ%;%NL%".
" (\$handles->{\$connect_label},\$error)=%NL%".
" connect_ssh(\$server);%NL%".
" if (\$error) {%NL%".
" \$stdout=%SQ%%SQ%;%NL%".
" \$stderr=\$error;%NL%".
" } else {%NL%".
" \$stdout=\$connect_label%NL%".
" }%NL%".
" push \@{\$out},[\$stdout,\$stderr];%NL%".
" }%NL%".
" } else {%NL%".
" (\$stdout,\$stderr)=\$fullauto->cmd(\$cmd);%NL%".
" push \@{\$out},[\$stdout,\$stderr]%NL%".
" }%NL%".
" }%NL%".
" \$stdout=encode_json \$out;%NL%".
" zmq_msg_send(\$stdout,\$socket);%NL%".
" }%NL%".
" Time::HiRes::sleep (.0001);%NL%".
"%NL%".
" }%NL%".
"};%NL%".
"%NL%".
"my \$zeromq_broker=sub {%NL%".
"%NL%".
" print \"LOADING BROKER\\n\";%NL%".
"%NL%".
" my \$ctx = zmq_init();%NL%".
" my \$frontend = zmq_socket(\$ctx, ZMQ_ROUTER);%NL%".
" my \$backend = zmq_socket(\$ctx, ZMQ_ROUTER);%NL%".
"%NL%".
" my \$rv = zmq_bind(\$frontend,FRONTEND_URL());%NL%".
" assert(\$rv == 0);%NL%".
"%NL%".
" \$rv = zmq_bind(\$backend,BACKEND_URL());%NL%".
" assert(\$rv == 0);%NL%".
"%NL%".
" my \@workers;%NL%".
"%NL%".
" my (\$w_addr,\$delim,\$c_addr,\$data);%NL%".
" my \$items = [%NL%".
"%NL%".
" {%NL%".
" events => ZMQ_POLLIN,%NL%".
" socket => \$frontend,%NL%".
" callback => sub {%NL%".
"%NL%".
" if (-1<\$#workers) {%NL%".
"%NL%".
" print \"frontend…\\n\";%NL%".
"%NL%".
" my \$buf = zmq_msg_init();%NL%".
" my \@msg=();%NL%".
" if (zmq_msg_recv(\$buf,\$frontend)) {%NL%".
" push \@msg, zmq_msg_data(\$buf);%NL%".
" while (zmq_getsockopt(\$frontend,ZMQ_RCVMORE)) {%NL%".
" zmq_msg_recv(\$buf,\$frontend);%NL%".
" push \@msg, zmq_msg_data(\$buf);%NL%".
" }%NL%".
" }%NL%".
"%NL%".
" assert(\$#msg);%NL%".
"%NL%".
" assert(\$#workers < NBR_WORKERS());%NL%".
"%NL%".
" zmq_msg_send(pop(\@workers),\$backend,ZMQ_SNDMORE);%NL%".
" zmq_msg_send(%SQ%%SQ%,\$backend,ZMQ_SNDMORE);%NL%".
" zmq_msg_send(\$msg[0],\$backend,ZMQ_SNDMORE);%NL%".
" zmq_msg_send(%SQ%%SQ%,\$backend,ZMQ_SNDMORE);%NL%".
" zmq_msg_send(\$msg[2],\$backend,);%NL%".
"%NL%".
" }%NL%".
" },%NL%".
" },%NL%".
" {%NL%".
" events => ZMQ_POLLIN,%NL%".
" socket => \$backend,%NL%".
" callback => sub {%NL%".
"%NL%".
" print \"backend…\\n\";%NL%".
"%NL%".
" my \$buf = zmq_msg_init();%NL%".
" my \@msg=();%NL%".
" if (zmq_msg_recv(\$buf,\$backend)) {%NL%".
" push \@msg, zmq_msg_data(\$buf);%NL%".
" while (zmq_getsockopt(\$backend,ZMQ_RCVMORE)) {%NL%".
" zmq_msg_recv(\$buf,\$backend);%NL%".
" push \@msg, zmq_msg_data(\$buf);%NL%".
" }%NL%".
" }%NL%".
"%NL%".
" assert(\$#msg);%NL%".
"%NL%".
" \$w_addr = \$msg[0];%NL%".
" push(\@workers,\$w_addr);%NL%".
"%NL%".
" \$delim = \$msg[1];%NL%".
" assert(\$delim eq %SQ%%SQ%);%NL%".
"%NL%".
" \$c_addr = \$msg[2];%NL%".
"%NL%".
" if(\$c_addr ne READY()){%NL%".
" \$delim = \$msg[3];%NL%".
" assert (\$delim eq %SQ%%SQ%);%NL%".
"%NL%".
" \$data = \$msg[4];%NL%".
"%NL%".
" print %SQ%sending %SQ%.\$data.%SQ% to %SQ%.\$c_addr.\"\\n\";%NL%".
"%NL%".
" zmq_msg_send(\$c_addr,\$frontend,ZMQ_SNDMORE);%NL%".
" zmq_msg_send(%SQ%%SQ%,\$frontend,ZMQ_SNDMORE);%NL%".
" zmq_msg_send(\$data,\$frontend);%NL%".
"%NL%".
" } else {%NL%".
" print %SQ%worker checking in: %SQ%.\$w_addr.\"\\n\";%NL%".
" }%NL%".
" },%NL%".
" },%NL%".
" ];%NL%".
" while(1){%NL%".
" zmq_poll(\$items);%NL%".
" select undef,undef,undef,0.025;%NL%".
" if (getppid==1) {%NL%".
" `pgrep -P \$\$ | xargs kill -TERM`;%NL%".
" exit;%NL%".
" }%NL%".
" }%NL%".
"%NL%".
"};%NL%".
"%NL%".
"my \$Fork = new Parallel::Forker();%NL%".
"\$Fork->schedule(run_on_start => \$zeromq_broker)->run()%NL%".
" if \$Fork->in_parent;%NL%".
"setpgrp(0,0) unless \$Fork->in_parent;%NL%".
"%NL%".
"for (1..NBR_WORKERS()) {%NL%".
"%NL%".
" my \$Fork = new Parallel::Forker();%NL%".
" #\$SIG{TERM} = sub { \$Fork->kill_tree_all(%SQ%TERM%SQ%) ".
"if \$Fork && \$Fork->in_parent; die \"Quitting...\\n\"; };%NL%".
" \$Fork->schedule(run_on_start => \$fa_sub)->run()%NL%".
" if \$Fork->in_parent;%NL%".
" setpgrp(0,0) unless \$Fork->in_parent;%NL%".
"%NL%".
"}%NL%";
($stdout,$stderr)=$handle->cmd(
"${sudo}sed -i \'/use Catalyst::ScriptRunner/i$ad\' ".
"./script/fullautoapi_fastcgi.pl");
($stdout,$stderr)=$handle->cmd( # bash shell specific
"${sudo}sed -i \'s/%NL%/\'\"`echo \\\\\\n`/g\" ".
"./script/fullautoapi_fastcgi.pl");
($stdout,$stderr)=$handle->cmd("${sudo}sed -i \"s/%SQ%/\'/g\" ".
"./script/fullautoapi_fastcgi.pl");
($stdout,$stderr)=$handle->cmd("${sudo}ldconfig");
($stdout,$stderr)=$handle->cmd('./script/set_admin_password.pl');
if ($^O eq 'cygwin') {
($stdout,$stderr)=$handle->cmd("cygrunsrv -I memcached ".
"-p /usr/local/bin/memcached");
($stdout,$stderr)=$handle->cmd("cygrunsrv -I fullautoapi ".
"-y memcached -p /cygdrive/c/cygwin64/bin/bash -a ".
"'-lc \"/bin/perl /home/$username/FullAutoAPI/script/".
"fullautoapi_fastcgi.pl -l localhost:3003\"'");
($stdout,$stderr)=$handle->cmd("cygrunsrv --start fullautoapi");
sleep 15;
print "\n ACCESS FULLAUTO API MANAGEMENT DASHBOARD AT:\n\n",
" https://$domain_url -OR- https://localhost\n";
} else {
($stdout,$stderr)=$handle->cmd($sudo.
"chown -Rv $username:$username .",'3600');
#($stdout,$stderr)=$handle->cmd($sudo.
# "cp -v $builddir/$ls_tmp[0]/api/memcached /etc/init.d",
# '__display__');
#($stdout,$stderr)=$handle->cmd($sudo.
# 'chmod -v 755 /etc/init.d/memcached','__display__');
($stdout,$stderr)=$handle->cmd($sudo.
"cp -v $builddir/$ls_tmp[0]/api/fullautoapi /etc/init.d",
'__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'chmod -v 755 /etc/init.d/fullautoapi','__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'chmod -v 777 /var/log','__display__');
($stdout,$stderr)=$handle->cmd($sudo.
'chmod -v 777 /var/lock/subsys','__display__');
print "\n STARTING FULLAUTO API MANAGEMENT DASHBOARD . . .\n\n",
($stdout,$stderr)=$handle->cmd($sudo.
'service fullautoapi start','__display__');
sleep 15;
print "\n ACCESS FULLAUTO API MANAGEMENT DASHBOARD AT:\n\n",
" https://$domain_url\n";
}
my $thanks=<<'END';
______ _ ,
/ / / ' ) / /
--/ /_ __. ____ /_ / / __ . . /
(_/ / /_(_/|_/ / <_/ <_ (__/_(_)(_/_' For Trying
//
_ _ _ _____ _ _ _ _
| \ | | ___| |_ | ___| _| | | / \ _ _| |_ |
| \| |/ _ \ __| o o | |_ | | | | | | / _ \| | | | __/ | \
| |\ | __/ |_ o o | _|| |_| | | |/ ___ \ |_| | || |
|_| \_|\___|\__| |_| \__,_|_|_/_/ \_\__,_|\__\___/ (C)
Copyright (C) 2000-2034 Brian M. Kelly Brian.Kelly@FullAuto.com
END
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
alarm 15;
print $thanks;
print " \n Press Any Key to EXIT ... ";
<STDIN>;
};alarm(0);
print "\n\n";
#print "\n\n\n Please wait at least a minute for the Default Browser\n",
# " to start with your new Catalyst installation!\n\n\n";
&Net::FullAuto::FA_Core::cleanup;
};
my $standup_fullautoapi=sub {
my $catalyst="]T[{select_fullautoapi_setup}";
my $password="]I[{'enter_password',1}";
my $domain_url="]I[{'domain_url',1}";
my $cnt=0;
$configure_fullautoapi->($catalyst,$password,$domain_url);
return '{choose_demo_setup}<';
};
my $fullautoapi_setup_summary=sub {
use JSON::XS;
my $region="]T[{awsregions}";
$region=~s/^"//;
$region=~s/"$//;
my $type="]T[{select_type}";
$type=~s/^"//;
$type=~s/"$//;
my $money=$type;
$money=~s/^.*-> \$(.*?) +(?:[(].+[)] )*\s*per hour$/$1/;
$type=substr($type,0,(index $type,' ->')-3);
my $catalyst="]T[{select_fullautoapi_setup}";
$catalyst=~s/^"//;
$catalyst=~s/"$//;
print "REGION=$region and TYPE=$type\n";
print "CATALYST=$catalyst\n";
my $num_of_servers=0;
my $ol=$catalyst;
$ol=~s/^.*(\d+)\sServer.*$/$1/;
if ($ol==1) {
$main::aws->{'CatalystFramework.org'}->[0]=[];
} elsif ($ol=~/^\d+$/ && $ol) {
foreach my $n (0..$ol) {
$main::aws->{'CatalystFramework.org'}=[] unless exists
$main::aws->{'CatalystFramework.org'};
$main::aws->{'CatalystFramework.org'}->[$n]=[];
}
}
$num_of_servers=$ol;
my $cost=int($num_of_servers)*$money;
my $cents='';
if ($cost=~/^0\./) {
$cents=$cost;
$cents=~s/^0\.//;
if (length $cents>2) {
$cents=~s/^(..)(.*)$/$1.$2/;
$cents=~s/^0//;
$cents=' ('.$cents.' cents)';
} else {
$cents=' ('.$cents.' cents)';
}
}
my $show_cost_banner=<<'END';
_ _ ___ _ ___
/_\ __ __ ___ _ __| |_ / __|___ __| ||__ \
/ _ \/ _/ _/ -_) '_ \ _| | (__/ _ (_-< _|/_/
/_/ \_\__\__\___| .__/\__| \___\___/__/\__(_)
|_|
END
$show_cost_banner.=<<END;
Note: There is a \$$cost per hour cost$cents to launch $num_of_servers
AWS EC2 $type servers for the FullAuto Demo:
$catalyst
END
my %show_cost=(
Name => 'show_cost',
Item_1 => {
Text => "I accept the \$$cost$cents per hour cost",
Result => $standup_fullautoapi,
},
Item_2 => {
Text => "Return to Choose Demo Menu",
Result => sub { return '{choose_demo_setup}<' },
},
Item_3 => {
Text => "Exit FullAuto",
Result => sub { Net::FullAuto::FA_Core::cleanup() },
},
Scroll => 1,
Banner => $show_cost_banner,
);
return \%show_cost;
};
our $choose_strong_password=sub {
my $password_banner=<<'END';
___ _ ___ _
/ __| |_ _ _ ___ _ _ __ _ | _ \__ _ _______ __ _____ _ _ __| |
\__ \ _| '_/ _ \ ' \/ _` | | _/ _` (_-<_-< V V / _ \ '_/ _` |
|___/\__|_| \___/_||_\__, | |_| \__,_/__/__/\_/\_/\___/_| \__,_|
|___/
END
my $word='';
foreach my $count (1..10) {
print "\n Generating Password ...\n";
$word=eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
alarm 7;
my $word=word(10,15,3,5,6);
print "\n Trying Password - $word ...\n";
die if -1<index $word,'*';
die if -1<index $word,'$';
die if -1<index $word,'+';
return $word;
};
alarm 0;
last if $word;
}
$password_banner.=<<END;
The Web Server (NGINX) and the SSL Certificate each need a strong password.
Use the one supplied here, or create your own. To create your own, use the
[DEL] key to clear the highlighted input box first.
*** BE SURE TO WRITE IT DOWN AND KEEP IT SOMEWHERE SAFE! ***
Input box with === border is highlighted (active) input box.
Use [TAB] key to switch focus between input boxes.
Password
]I[{1,\'$word\',50}
Confirm
]I[{2,\'$word\',50}
END
my $enter_password={
Name => 'enter_password',
Input => 1,
Result => $standup_fullautoapi,
#Result =>
#$Net::FullAuto::ISets::Local::FullAutoAPI_is::select_fullautoapi_setup,
Banner => $password_banner,
};
return $enter_password;
};
our $domain_url=sub {
package domain_url;
my $handle=connect_shell();
my ($stdout,$stderr)=$handle->cmd("wget -qO- http://icanhazip.com");
my $public_ip=$stdout if $stdout=~/^\d+\.\d+\.\d+\.\d+\s*/s;
unless ($public_ip) {
require Sys::Hostname;
import Sys::Hostname;
require Socket;
import Socket;
my($addr)=inet_ntoa((gethostbyname(Sys::Hostname::hostname))[4]);
$public_ip=$addr if $addr=~/^\d+\.\d+\.\d+\.\d+\s*/s;
}
chomp($public_ip);
$public_ip='127.0.0.1' unless $public_ip;
my $domain_url_banner=<<'END';
___ _ _ _ ___ _
| \ ___ _ __ __ _(_)_ _ | | | | _ \ |
| |) / _ \ ' \/ _` | | ' \ | |_| | / |__
|___/\___/_|_|_\__,_|_|_||_| \___/|_|_\____|
END
$domain_url_banner.=<<END;
Type or paste the domain url for the site:
*** A properly registered domain url is necessary! ***
Make sure the DNS A/AAAA record(s) for this domain
contain(s) this IP address --> $public_ip
Domain URL
]I[{1,'fullautosoftware.net',46}
END
my $domain_url={
Name => 'domain_url',
Input => 1,
Result => $choose_strong_password,
#Result =>
#$Net::FullAuto::ISets::Local::WordPress_is::select_wordpress_setup,
Banner => $domain_url_banner,
};
return $domain_url;
};
our $select_fullautoapi_setup=sub {
my @options=('FullAuto Automation API on This Host');
my $fullautoapi_setup_banner=<<'END';
_ ___ _ _ _ _
((_) | __| _| | | /_\ _ _| |_ |
/ | _| || | | |/ _ \ || | _/ | \ Automates _
/ |_| \_,_|_|_/_/ \_\_,_|\__\___/c Everything _| |_
\__/_ ___ __ _| |_ __ _| |_ _ ___| |_ |_ _|
/ \ / __/ _` | __/ _` | | | | / __| __| Perl MVC |_|
_- | | | (_| (_| | || (_| | | |_| \__ \ | framework
_ _-' \____/ \___\__,_|\__\__,_|_|\__, |___/\__|c
((_) ---\ |___/
\
\\_ Web Framework & Automation API via RESTful
(_)
Choose the FullAutoAPI setup you wish to install on this localhost:
END
my %select_fullautoapi_setup=(
Name => 'select_fullautoapi_setup',
Item_1 => {
Text => ']C[',
Convey => \@options,
#Result => $standup_fullautoapi,
Result => $domain_url,
},
Scroll => 1,
Banner => $fullautoapi_setup_banner,
);
return \%select_fullautoapi_setup
};
sub exit_on_error {
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
alarm 1800;
print "\n FATAL ERROR!:\n\n ";
print $_[0];
print " \n\n Press Any Key to EXIT ... ";
<STDIN>;
};alarm(0);
print "\n\n";
&Net::FullAuto::FA_Core::cleanup;
}
1