package Net::FullAuto::ISets::Local::FullAutoAPI_is; ### 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; use warnings; my $service_and_cert_password='Full@ut0O1'; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw($select_fullautoapi_setup); use Net::FullAuto::Cloud::fa_amazon; use Net::FullAuto::FA_Core qw[$localhost cleanup fetch clean_filehandle]; use Time::Local; use File::HomeDir; 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 (-1cmd($sudo. "wget --random-wait --progress=dot ". "https://github.com/transcode-open/apt-cyg/archive/master.zip", '__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('~'); # http://blogostuffivelearnt.blogspot.com/2012/07/ # 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 (-1print(); } elsif (-1print('yes'); } elsif (-1print('no'); } elsif (-1print('yes'); } elsif (-1print('yes'); } elsif (-1print('no'); } elsif (-1print('yes'); } elsif (-1print(); } elsif (-1print('default'); } elsif (-1print('yes'); } elsif (-1print('no'); } elsif (-1print($service_and_cert_password); } elsif (-1print($service_and_cert_password); } elsif (-1print('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"; # http://www.iis.net/learn/install/installing-iis-85/ # installing-iis-85-on-windows-server-2012-r2 # https://technet.microsoft.com/en-us/library/hh831475.aspx # http://twiki.org/cgi-bin/view/TWiki/TWikiOnWindowsIISCygwin # https://www.iis.net/configreference/system.webserver/fastcgi #($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 -1300; #} #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=<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 ". # "https://github.com/erlang/otp/archive/maint.zip", # '__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- ". # "https://www.rabbitmq.com/download.html"); #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 ". # "https://github.com/rabbitmq/rabbitmq-tutorials/archive/master.zip", # '__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- '. # 'http://169.254.169.254/latest/dynamic/instance-identity/'); #$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 -1cmd($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 ". "http://download.fedoraproject.org". "/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 ". "http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz", '__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 ". "https://github.com/jedisct1/libsodium/archive/master.zip", '__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. 'wget -qO- https://www.python.org/downloads/release'); $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 ". "https://bootstrap.pypa.io/ez_setup.py",'__display__'); 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. 'git clone https://github.com/zeromq/zeromq4-x.git', '__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 # https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx # -dont-trust-the-tutorials-check-your-configuration/ # https://www.digitalocean.com/community/tutorials/ # understanding-and-implementing-fastcgi-proxying-in-nginx # http://dev.soup.io/post/1622791/I-managed-to-get-nginx-running-on # http://search.cpan.org/dist/Catalyst-Manual-5.9002/lib/Catalyst/ # Manual/Deployment/nginx/FastCGI.pod # https://serverfault.com/questions/171047/why-is-php-request-array-empty # https://codex.wordpress.org/Nginx # https://www.sitepoint.com/setting-up-php-behind-nginx-with-fastcgi/ # http://codingsteps.com/install-php-fpm-nginx-mysql-on-ec2-with-amazon-linux-ami/ # http://code.tutsplus.com/tutorials/revisiting-open-source-social-networking-installing-gnu-social--cms-22456 # https://wiki.loadaverage.org/clipbucket/installation_guides/install_like_loadaverage # https://karp.id.au/social/index.html # http://jeffreifman.com/how-to-install-your-own-private-e-mail-server-in-the-amazon-cloud-aws/ # https://www.wpwhitesecurity.com/creating-mysql-wordpress-database/ #($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 (-1print($service_and_cert_password); $output=''; next; } elsif (-1print($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. "wget -qO- https://nginx.org/en/download.html"); $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. "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/^.*?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 ". "https://www.openssl.org/source/$ossl.tar.gz", '__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'); # https://www.liberiangeek.net/2015/10/ # how-to-install-self-signed-certificates-on-nginx-webserver/ # https://www.hrupin.com/2017/07/how-to-automatically-restart-nginx ($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__'); # https://www.digitalocean.com/community/tutorials/ # 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__'); # https://www.liberiangeek.net/2015/10/ # 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=<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 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=<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 ((-1print(\\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=<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 (-1print('1'); $output=''; } elsif (-1print('2'); $output=''; } elsif (-1print('brian.kelly@fullauto.com'); $output=''; } elsif (-1print('A'); $output=''; } elsif (-1print('Y'); $output=''; } elsif ((-1print('C'); $output=''; } } ($stdout,$stderr)=clean_filehandle($handle); ($stdout,$stderr)=$handle->cmd($sudo. 'grep Certbot /etc/nginx/nginx.conf'); last if $stdout; } # https://ssldecoder.org ($stdout,$stderr)=$handle->cmd($sudo."service nginx restart", '__display__'); } } $do=0; if ($do==1) { # NGINX print "DOING NGINX\n"; # https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx # -dont-trust-the-tutorials-check-your-configuration/ # https://www.digitalocean.com/community/tutorials/ # understanding-and-implementing-fastcgi-proxying-in-nginx # http://dev.soup.io/post/1622791/I-managed-to-get-nginx-running-on # http://search.cpan.org/dist/Catalyst-Manual-5.9002/lib/Catalyst/ # 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 ". "ftp://ftp.csx.cam.ac.uk/pub/software/". "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 ". "https://www.openssl.org/source/$ossl.tar.gz", '__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__'); # https://www.liberiangeek.net/2015/10/ # 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 (-1print($service_and_cert_password); $output=''; next; } elsif (-1print($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 (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print('.'); $output=''; $test=''; next; } elsif (-1print('.'); $output=''; $test=''; next; } elsif ( -1print(); $output=''; $test=''; next; } elsif (-1print(); $output=''; $test=''; next; } elsif (-1print(); $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 (-1print($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=<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=<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 ((-1print(\\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=<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 (-1print($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- '. 'https://github.com/membrane/service-proxy/releases/latest'); $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 '. # 'https://github.com/membrane/service-proxy.git','__display__'); 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 (-1print('yes'); } elsif (-1print('sudo'); } elsif (-1print('no'); } elsif (-1print('no'); } elsif (-1print('http://www.cpan.org'); } elsif (-1print(); } elsif ($output=~/cpan[[]\d+[]][>]/) { $handle->print('bye'); } } } ($stdout,$stderr)=$handle->cmd("export PERL_MM_USE_DEFAULT=1"); if ($^O eq 'cygwin') { my $show=<cmd_raw($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","Starman")\'', '__display__'); $show=<cmd_raw($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","HTTP::Server::Simple")\'', '__display__'); } my $show=<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=<cmd_raw($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","Perl::Critic")\'', '__display__'); $show=<cmd_raw($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","IO::CaptureOutput")\'', '__display__'); $show=<cmd_raw($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","Devel::CheckLib")\'', '__display__'); $show=<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 # https://metacpan.org/pod/DBIx::Class::Manual::Cookbook#Predefined-searches # # http://ajct.info/2015/08/16/oauth-and-catalyst.html # # http://stackoverflow.com/questions/23652166/how-to-generate-oauth-2-client-id-and-secret # # https://bshaffer.github.io/oauth2-server-php-docs/grant-types/refresh-token/ # http://cygwin.1069669.n5.nabble.com/where-is-my-quot-usr-dict- # words-quot-or-quot-usr-share-dict-words-on-cygwin-1-7-td59328.html ($stdout,$stderr)=$handle->cwd('deps'); my $mirror='https://dl.fedoraproject.org/pub/fedora/linux/releases/'; # "http://mirrors.maine.edu/Fedora/releases/"; ($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=<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 $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=<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 (-1print('y'); } if (-1print('y'); } } $show=<cmd_raw($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","DBIx::Class")\'', '__display__'); $show=<cmd_raw($sudo. 'cpan DBIx::Class::Schema::Loader', '__display__'); # $show=<print($sudo.'cpan Net::RabbitFoot'); # $prompt=$handle->prompt(); # while (1) { # my $output.=fetch($handle); # last if $output=~/$prompt/; # print $output; # if (-1print('y'); # $output=''; # next; # } # } # $show=<cmd_raw($sudo.'cpan YAML::Syck','__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Controller::REST','__display__'); # $show=<cmd_raw("${sudo}cpan Catalyst::Model::Adaptor",'__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::View::JSON', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::View::TT::Alloy', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Plugin::Unicode', '__display__'); $show=<cmd_raw($sudo. 'cpan DBIx::Class::PassphraseColumn', '__display__'); $show=<cmd_raw($sudo. 'cpan Authen::Passphrase::BlowfishCrypt', '__display__'); $show=<cmd_raw($sudo. 'cpan Method::Signatures::Simple', '__display__'); # $show=<cmd_raw("${sudo}cpan HTML::FormHandler", # '__display__'); # $show=<cmd_raw("${sudo}cpan HTML::FormHandler::Model::DBIC", # '__display__'); $show=<cmd_raw($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","CatalystX::SimpleLogin")\'', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Plugin::Session', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Plugin::Session::Store::Memcached', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Plugin::Session::State::Cookie', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Plugin::Authentication', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Authentication::Store::DBIx::Class', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Plugin::Authorization::Roles', '__display__'); $show=<print($sudo. 'perl -MCPAN -e \'CPAN::Shell->notest('. '"install","Time::Warp")\''); $show=<cmd_raw($sudo. 'cpan DBIx::Class::TimeStamp', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Controller::ActionRole', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::ActionRole::ACL', '__display__'); $show=<cmd_raw($sudo.'cpan FCGI', '__display__'); $show=<cmd_raw($sudo. 'cpan FCGI::ProcManager', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::Helper::Model::DBIC::Schema', '__display__'); $show=<cmd_raw($sudo. 'cpan Catalyst::View::Email', '__display__'); $show=<print($sudo.'cpan Finance::Quote'); $prompt=$handle->prompt(); while (1) { my $output.=fetch($handle); last if $output=~/$prompt/; print $output; if (-1print('Y'); $output=''; next; } if (-1print('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://www.catalystframework.org/calendar/2011/15 # 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' %]
[% FOR field IN login_form.error_fields %] [% FOR error IN field.errors %]

[% field.label _ ': ' _ error %]

[% END %] [% END %]
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 \\x22http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\\x22>

Welcome to the FullAuto API Management Dashboard.

Your username is: [% username %]

Your initial password is: [% password %]

Your client id is: [% client_id %]

Your client secret is: [% client_secret %]

You will be asked to change your password on first login.

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 \\x22http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\\x22>

Your FullAuto API Management Dashboard Password has been Reset

Your username is: [% username %]

Your password is: [% password %]

You will be asked to change your password on first login.

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' %]
Add User
Displaying users [% pager.first %]-[% pager.last %] of [% pager.total_entries %] [% WHILE (u = users.next) %] [% END %]
Username Name Email Address Client ID Client Secret
[% u.username %] [% u.name %] [% u.email_address %] [% u.client_id %] [% u.client_secret %] Reset Password Inactivate
<< pager.first_page }) %]\\x22>First pager.previous_page })%]\\x22>Previous | pager.next_page })%]\\x22>Next pager.last_page }) %]\\x22>Last >> 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' %]
[% FOR field IN form.error_fields %] [% FOR error IN field.errors %]

[% field.label _ ': ' _ error %]

[% END %] [% END %]
[% f = form.field('username') %] [% PROCESS user/edit_details.tt2 %]
Users List
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' %]
[% FOR field IN form.error_fields %] [% FOR error IN field.errors %]

[% field.label _ ': ' _ error %]

[% END %] [% END %]
[% FOREACH field_name = ['current_password', 'new_password', 'new_password_conf'] %] [% f = form.field(field_name) %] [% END %]
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' %]
[% FOR field IN form.error_fields %] [% FOR error IN field.errors %]

[% field.label _ ': ' _ error %]

[% END %] [% END %]
[% PROCESS user/edit_details.tt2 %]
Users List
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'] %] [% f = form.field(field_name) %] [% END %] [% f = form.field('roles') %] [% f.render %] 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' %]
[% FOR field IN form.error_fields %] [% FOR error IN field.errors %]

[% field.label _ ': ' _ error %]

[% END %] [% END %]
[% FOREACH field_name = ['name', 'email_address', 'phone_number', 'mail_address'] %] [% f = form.field(field_name) %] [% END %]
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 ". # "http://dev.catalyst.perl.org/repos/Catalyst/trunk/". # "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=<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 =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 ". "https://github.com/memcached/memcached/archive/master.zip", '__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';              mailer Sendmail          template_prefix email              content_type text/html         charset utf-8         view TT        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 ". "https://code.jquery.com/ui/1.11.3/jquery-ui.js", '__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 ". "https://code.jquery.com/jquery-1.11.3.js", '__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'); # http://www.sitepoint.com/working-jquery-datatables/ ($stdout,$stderr)=$handle->cmd($sudo. "wget --random-wait --progress=dot ". "https://github.com/DataTables/DataTables/archive/master.zip", '__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=< 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 (-1config( 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=<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=< ( type => 'Text', label => 'User name', required => 1, ); __PACKAGE__->meta->make_immutable; 1; END ($stdout,$stderr)=$handle->cmd("echo -e \"$content\" > AddUser.pm"); $content=< (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=< ( 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=< (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 ". # "http://dev.catalyst.perl.org/repos/Catalyst/trunk/". # "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 ". # "http://dev.catalyst.perl.org/repos/Catalyst/trunk/". # "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 ". # "http://dev.catalyst.perl.org/repos/Catalyst/trunk/". # "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=< Catalyst REST Example

Catalyst REST Example Using JQuery DataTable

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:

[%c.uri_for( c.controller('User').action_for('user_list') ) %]/user_id

Data can be accessed on the command line:

curl -X GET -k -H 'Content-Type: application/json' [%c.uri_for( c.controller('User').action_for('user_list') ) %]

curl -X GET -k \\x22[% c.req.base %]request?client_id=<client_id>&response_type=code&redirect_uri=/cmd\\x22

curl -X GET -k \\x22[% c.req.base %]/token?grant_type=authorization_code&client_id=<client_id>&redirect_uri=/cmd&code=<code>\\x22

curl -X POST -k -H 'Authorization: Bearer <token>' -H 'Content-Type: application/json' -d '{\\x22cmd\\x22:\\x22hostname\\x22}' [% c.req.base %]cmd

ID Full Name Description
ID Full Name Description
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%". " # http://www.unitconversion.org/unit_converter/time-ex.html%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 ... "; ; };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 { package fullautoapi_setup_summary; 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.=< '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 { package choose_strong_password; my $password_banner=<<'END'; ___ _ ___ _ / __| |_ _ _ ___ _ _ __ _ | _ \__ _ _______ __ _____ _ _ __| | \__ \ _| '_/ _ \ ' \/ _` | | _/ _` (_-<_-< V V / _ \ '_/ _` | |___/\__|_| \___/_||_\__, | |_| \__,_/__/__/\_/\_/\___/_| \__,_| |___/ END use Crypt::GeneratePassword qw(word); 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 '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; use Net::FullAuto; 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.=< $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 ... "; ; };alarm(0); print "\n\n"; &Net::FullAuto::FA_Core::cleanup; } 1