$:.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','unix-like')) require 'optparse' require 'rho_connect_install_constants' require 'fileutils' options = {} optparse = OptionParser.new do |opts| options[:dist] = nil opts.on( '-d', '--dist DISTRO', 'Specify DISTRO as the current distribution.' ) do |dist| options[:dist] = dist end #do options[:prefix] = '/opt/rhoconnect' opts.on( '-p', '--prefix RHODIR', 'Specify RHODIR as the prefix directory.' ) do |dir| options[:prefix] = dir end #do options[:redis] = true opts.on( '--no-redis', '', 'Skip installing the redis server.' ) do options[:redis] = false end #do options[:rubyVersion] = 'rubyee' opts.on( '-r', '--rubyVer VERSION', 'Specify VERSION as the verion of ruby that is installed.' ) do |rubyVer| options[:rubyVersion] = rubyVer end #do options[:web_server] = "nginx" opts.on('-w', '--web-server Server', ' Specify that you are using web server SERVER') do |server| options[:web_server] = server end #do end #do optparse.parse! @prefix = options[:prefix] @dist = options[:dist] @redis = options[:redis] @ruby_version = options[:rubyVersion] @profile = (@dist == 'debian') ? '~/.profile' : '~/.bash_profile' @server = options[:web_server] def passenger_version (`#{@prefix}/bin/passenger --version`.match /\d+\.\d+\.\d+/)[0] end # create_redis_init # Creates the redis initialization file and places it into the correct directory def create_redis_init redis_init_script = <<'_REDIS_INIT_SCRIPT_' #!/usr/bin/env bash ### BEGIN INIT INFO # Provides: redis-server # Required-Start: $syslog # Required-Stop: $syslog # Should-Start: $local_fs # Should-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: redis-server - Persistent key-value db # Description: redis-server - Persistent key-value db ### END INIT INFO # # Author: Wayne E. Seguin # License: The same licence as Redis, New BSD # http://www.opensource.org/licenses/bsd-license.php # # Source the system config file, if it exists. if [[ -s /etc/conf.d/redis ]] ; then source /etc/conf.d/redis fi # Default config variables that have not been set. port="${port:-6379}" prefix="${prefix:-/opt/rhoconnect}" redis="${prefix}/bin/redis-server" redis_cli="${prefix}/bin/redis-cli" pidfile="${pidfile:-/var/run/redis.pid}" config="${config:-/opt/rhoconnect/etc/redis.conf}" user="${user:-root}" #prefix="${prefix:-/usr/local}" #config="${config:-/usr/local/etc/redis.conf}" #pidfile="${pidfile:-/var/run/redis/redis.pid}" #config="${config:-/etc/redis/redis.conf}" #user="${user:-redis}" # If the redis-cli file is not found, terminate the script. test -x $redis_cli || exit 0 # # Set the running $pid value based on $pidfile. # if [[ -s "$pidfile" ]] ; then pid=$(cat $pidfile) else rm -f $pidfile fi # In case there was pidfile corruption... if [[ "Linux" = "$(uname)" ]] ; then # /proc does not exist on say, Darwin if [[ ! -z "${pid}" ]] && [[ ! -x "/proc/${pid}" ]] ;then pid="$(ps auxww | grep [r]edis | grep "$config" | grep -v 'grep' | awk '{print $2}')" elif [[ -z "${pid}" ]] ; then pid="$(ps auxww | grep [r]edis | grep "$config" | grep -v 'grep' | awk '{print $2}')" fi else if [[ -z "${pid}" ]] ; then pid="$(ps auxww | grep [r]edis | grep "$config" | grep -v 'grep' | awk '{print $2}')" fi fi # # Start redis using redis-server as user 'redis'. # redis_start() { if [[ -f $pidfile ]] ; then echo "$pidfile exists, redis-server is either already running or crashed." exit 1 elif [[ ! -z "$pid" ]] ; then echo -e "\nRedis is already running with configuration '$config'." echo "$pid" > $pidfile # Ensure pidfile exists with the pid. else echo "Starting Redis server..." su $user -c "$redis $config" exit 0 fi } # # Stop redis using redis-cli SHUTDOWN. # redis_stop() { echo -n "Stopping redis server on port ${port} ... " "$redis_cli" -p ${port} SHUTDOWN # Keep user informed while server shuts down. echo "Waiting for the redis server to shutdown " if [[ "Linux" = "$(uname)" ]] ; then if [[ "${pid}" = "" ]] ; then echo "redis server is not running." # Clear out the old pidfile if available rm -f $pidfile exit 1 fi while [[ -x /proc/${pid} ]] ; do echo -n '.' ; sleep 1 done else # Darwin, etc... while [[ ! -z "$(ps auxww | grep [r]edis | grep "$config" | awk '{print $2}')" ]] ; do echo -n '.' ; sleep 1 done fi # Clear out the old pidfile. rm -f $pidfile # Notify user of successful completion. echo -e "redis server stopped." exit 0 } redis_usage() { echo -e "Usage: $0 {start,stop,restart,status}" exit 1 } redis_status() { "$redis_cli" -p ${port} INFO > /dev/null 2>&1 info=$? if (( $info )) ; then echo "Redis server not running"; else echo "Redis server running"; fi exit $info } # # CLI logic. # case "$1" in start) redis_start ;; stop) redis_stop ;; restart) $0 stop $0 start ;; status) redis_status ;; *) redis_usage ;; esac _REDIS_INIT_SCRIPT_ redisInit="/etc/init.d/redis" File.open(redisInit, 'w') { |f| f << redis_init_script } # Make the init script executable `chmod +x #{redisInit}` # Set run levels if @dist == 'debian' `update-rc.d -f redis defaults` else `/sbin/chkconfig redis on` # `/sbin/chkconfig --list redis` end redis_init_script end #create_redis_init def create_redis_logrotate redis_logrotate_conf = <<'_REDIS_LOGRORATE_CONF_' /var/log/redis.log { rotate 3 missingok notifempty size 250k create 0644 root root compress } _REDIS_LOGRORATE_CONF_ File.open('/etc/logrotate.d/redis', 'w') { |f| f << redis_logrotate_conf } end # # Nginx stuff ... def create_nginx_init nginx_init_script = <<'_NGINX_INIT_SCRIPT_' #!/bin/sh # Author: Ryan Norbauer http://norbauerinc.com # Modified: Geoffrey Grosenbach http://topfunky.com # Modified: Clement NEDELCU # Modified: Alexander Babichev # Reproduced with express authorization from its contributors PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DESC="nginx daemon" NAME=nginx DAEMON=/opt/nginx/sbin/$NAME SCRIPTNAME=/etc/init.d/$NAME # If the daemon file is not found, terminate the script. test -x $DAEMON || exit 0 d_start() { $DAEMON || echo -n " already running" } d_stop() { $DAEMON -s quit || echo -n " not running" } d_reload() { $DAEMON -s reload || echo -n " could not reload" } case "$1" in start) echo -n "Starting $DESC: $NAME" d_start echo "." ;; stop) echo -n "Stopping $DESC: $NAME" d_stop echo "." ;; reload) echo -n "Reloading $DESC configuration ... " d_reload echo "reloaded." ;; restart) echo -n "Restarting $DESC: $NAME" d_stop # Sleep for two seconds before starting again, this should give the # Nginx daemon some time to perform a graceful stop. sleep 2 d_start echo "." ;; *) echo "Usage: $SCRIPTNAME {start|stop|restart|reload}" >&2 exit 3 ;; esac exit 0 _NGINX_INIT_SCRIPT_ nginx_script = '/etc/init.d/nginx' File.open(nginx_script, 'w') { |f| f << nginx_init_script } # Make the init script executable `chmod +x #{nginx_script}` # Set run levels # if @dist == 'debian' # #`update-rc.d -f nginx defaults` # else # #`/sbin/chkconfig nginx on` # end end def create_nginx_logrotate nginx_logrorate_conf = <<'_NGINX_LOGRORATE_CONF_' /opt/nginx/logs/*log { missingok notifempty rotate 4 size 100k delaycompress sharedscripts postrotate test ! -f /opt/nginx/logs/nginx.pid || kill -USR1 `cat /opt/nginx/logs/nginx.pid` endscript } _NGINX_LOGRORATE_CONF_ File.open('/etc/logrotate.d/nginx', 'w') { |f| f << nginx_logrorate_conf } end def create_nginx_conf_files(app_name) nginx_server_conf = <<'_NGINX_CONF_' user nginx; worker_processes 4; error_log logs/error.log; pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #gzip on; include /opt/nginx/conf/conf.d/*.conf; } _NGINX_CONF_ # create 'nginx' user if it does not exist user_nginx = `cat /etc/passwd | cut -d: -f1 | grep nginx` if user_nginx.empty? puts "Creating 'nginx' user ..." if @dist == 'debian' `adduser --system --home /opt/nginx/html --no-create-home --disabled-login --disabled-password --group nginx` else `/usr/sbin/useradd -M -r -s /sbin/nologin -d /opt/nginx/html nginx` end end FileUtils.mv("/opt/nginx/conf/nginx.conf", "/opt/nginx/conf/nginx.conf.bak") unless File.exist? "/opt/nginx/conf/nginx.conf.bak" File.open('/opt/nginx/conf/nginx.conf', 'w' ) { |f| f << nginx_server_conf } Dir.mkdir "/opt/nginx/conf/conf.d" unless File.exist? "/opt/nginx/conf/conf.d" rho_vhost_conf = <<_VHOST_CONF_ server { listen 80; root /opt/nginx/html/#{app_name}/public; # <-- be sure to point to 'public' folder of your application! passenger_enabled on; # access_log off; # <-- disable access logging # error_log /dev/null crit; # <-- disable error logging, but critical errors only } _VHOST_CONF_ File.open('/opt/nginx/conf/conf.d/rhoconnect.conf', 'w' ) { |f| f << rho_vhost_conf } passenger_conf = <<_PASSENGER_CONF_ passenger_root /opt/rhoconnect/lib/ruby/gems/1.8/gems/passenger-#{passenger_version}; passenger_ruby /opt/rhoconnect/bin/ruby; passenger_max_pool_size 20; passenger_min_instances 6; _PASSENGER_CONF_ File.open('/opt/nginx/conf/conf.d/passenger.conf', 'w' ) { |f| f << passenger_conf } end # End of nginx stuff ... # generate_common_info # Generates the readme info that is common across all distributions def generate_common_info readme = <<_README_ Thank you for choosing Rhomobile for your cross-platform app needs! To finish this setup, please complete the following... 1) Add necessary bins to the path(s) of the users who will be using this software. You may also wish to add these items to your #{@profile} to automatically add them upon login. export PATH=#{@prefix}/bin:$PATH If you had other versions of ruby installed previously to running this installation, you may instead wish to simply create an alias for the newly installed ruby: alias #{@ruby_version}=#{@prefix}/bin/ruby _README_ if @dist == "yum" rpm_lib = <<_RPM_LIB_ Add #{@prefix}/lib to your library path like so: export LD_LIBRARY_PATH=#{@prefix}/lib:$LD_LIBRARY_PATH Note: You may also want to add this line to #{@profile} _RPM_LIB_ # concatenate _RPM_LIB_ onto _README_ readme = readme + rpm_lib end #if readme_2 = <<_README2_ 2) Rhoconnect installer configured redis server with the following settings: A) redis.conf file is located in #{@prefix}/etc/ directory with properties: daemonize yes pidfile /var/run/redis.pid logfile /var/log/redis.log B) Redis logrotate settings for /var/log/redis.log files defined in '/etc/logrotate.d/redis': /var/log/redis.log { rotate 3 missingok notifempty size 250k create 0644 root root compress } C) Redis start-up script '/etc/init.d/redis'. You can start/stop redis server by running the following commands: /etc/init.d/redis {start|stop} 3) Setup rhoconnect application directory Put your application code in a directory called /var/www/rhoconnect (make sure this is the root of your application directory, i.e. /var/www/rhoconnect/config.ru should exist). _README2_ readme = readme + readme_2 readme end #generate_common_info def create_passenger_load if @dist == 'debian' passenger_load_file = '/etc/apache2/mods-available/passenger.load' else passenger_load_file = '/etc/httpd/conf.d/passenger.conf' end # if passenger_load = <<_PASSENGER_LOAD_ LoadModule passenger_module /opt/rhoconnect/lib/ruby/gems/1.8/gems/passenger-#{passenger_version}/ext/apache2/mod_passenger.so PassengerRoot /opt/rhoconnect/lib/ruby/gems/1.8/gems/passenger-#{passenger_version} PassengerRuby /opt/rhoconnect/bin/ruby _PASSENGER_LOAD_ File.open( passenger_load_file, 'w' ) { |f| f << passenger_load } end #create_passenger_load def create_apache_vhost if @dist == 'debian' vhost_file = '/etc/apache2/sites-available/rhoconnect' else vhost_file = '/etc/httpd/conf.d/rhoconnect.conf' end vhost = <<_VHOST_ ServerName www.yourhost.com DocumentRoot /var/www/rhoapp/public PassengerMaxPoolSize 20 PassengerMinInstances 6 #... AllowOverride all Options -MultiViews _VHOST_ File.open( vhost_file, 'w' ) { |f| f << vhost } end #create_apache_vhost # The debian Apache2 specific part of the readme and places it in options[:prefix] def debian_apache_readme readme = <<_README_ 4) Installer created the following Apache2 configuration files: - rhoconnect application template (/etc/apache2/sites-available/rhoconnect) - passenger module (/etc/apache2/mods-available/passenger.load) To complete setup of web server A) Configure virtual host for rhoconnect application: Edit the file /etc/apache2/sites-available/rhoconnect so that it reflects your specifications. B) Enable the virtual host: sudo a2ensite rhoconnect C) Load the passenger.load module sudo a2enmod passenger D) Start server to pick up the changes: sudo /etc/init.d/apache2 start _README_ readme end # The non-debian Apache2 specific part of the readme file and places it in options[:prefix] def yum_apache_readme readme = <<_README_ 4) Installer created the following Apache2 configuration files: - rhoconnect application template (/etc/httpd/conf.d/rhoconnect.conf) - passenger module (/etc/httpd/conf.d/passenger.conf) To complete setup of web server A) Configure virtual host for rhoconnect application: Edit the file /etc/httpd/conf.d/rhoconnect.conf so that it reflects your specifications. B) As root user start server to pick up the changes: /sbin/service httpd start _README_ readme end def nginx_readme readme = <<_NGINX_README_ 4) Installer compiled Nginx web server (/opt/nginx) with the following configuration files: - Nginx start-up script (/etc/init.d/nginx) - Nginx logrotate settings (/etc/logrotate.d/nginx) - Nginx configuration file (/opt/nginx/conf/nginx.conf) - passenger configuration file and virtual host template for rhoconnect application (/opt/nginx/conf/conf.d/passenger.conf and /opt/nginx/conf/conf.d/rhoconnect.conf) To complete setup of web server A) Configure virtual host for rhoconnect application: Edit the file /opt/nginx/conf/conf.d/rhoconnect.conf so that it reflects your specifications. B) As root user start server to pick up the changes: /etc/init.d/nginx start _NGINX_README_ readme end def generate_rhoapp(rho_path) puts "Generating rhoconnect application: /opt/nginx/html/rhoapp ..." Dir.chdir "/opt/nginx/html" unless File.directory? "/opt/nginx/html/rhoapp" `#{rho_path}/bin/rhoconnect app rhoapp` Dir.chdir "rhoapp" log = `#{rho_path}/bin/bundle install --without=test development` raise "Generatiion of rhoconnect application failured:\n#{log}" if $? != 0 Dir.chdir "../" `chown -R nginx:nginx rhoapp/` end end def copy_benchapp(rho_path) puts "Copy bench rhoconnect application to /opt/nginx/html directory ..." Dir.chdir "#{rho_path}/installer" `tar xzf bench.tar.gz -C #{rho_path}` `rm -rf bench.tar.gz` `#{rho_path}/bin/gem install ffaker --no-ri --no-rdoc` `#{rho_path}/bin/gem install thor --no-ri --no-rdoc` Dir.chdir "#{rho_path}/bench" `cp -r benchapp /opt/nginx/html` Dir.chdir "/opt/nginx/html/benchapp" `rm -rf Gemfile.lock` `#{rho_path}/bin/bundle install --without=test development` Dir.chdir "../" `chown -R nginx:nginx benchapp/` end def create_texts if @redis create_redis_init create_redis_logrotate end if @server == 'nginx' create_nginx_init create_nginx_logrotate @use_bench_app = File.exist? "#{@prefix}/installer/bench.tar.gz" if @use_bench_app create_nginx_conf_files "benchapp" copy_benchapp @prefix else create_nginx_conf_files "rhoapp" generate_rhoapp @prefix end distro_info = nginx_readme else create_passenger_load create_apache_vhost distro_info = (@dist == 'debian') ? debian_apache_readme : yum_apache_readme end common_info = generate_common_info readme = common_info + distro_info File.open("#{@prefix}/README", 'w') { |f| f << readme } afterwords = <<_IT_SHOULD_BE_DONE_ Thank you for choosing Rhomobile for your cross-platform app needs! To finish this setup, please complete the following... 1) Add necessary bins to the path(s) of the users who will be using this software. You may also wish to add these items to your #{@profile} to automatically add them upon login. export PATH=#{@prefix}/bin:$PATH _IT_SHOULD_BE_DONE_ about_app = if @use_bench_app server_todo_list = <<_NGINX_TO_DO_ 2) Rhoconnect 'benchapp' application is created in /opt/nginx/html directory. To run it A) As root user start redis and nginx servers: /etc/init.d/redis start /etc/init.d/nginx start B) To verify that application up and running open web console in your browser: http://localhost/console/ _NGINX_TO_DO_ else if @server == 'nginx' server_todo_list = <<_NGINX_TO_DO_ 2) Try rhoconnect 'rhoapp' application, created in /opt/nginx/html directory A) As root user start redis and nginx servers: /etc/init.d/redis start /etc/init.d/nginx start B) Open RhoConnect application web console in your browser: http://localhost/console/ _NGINX_TO_DO_ else server_todo_list = <<_APACHE2_TO_DO_ 2) Complete setup of Apache2 web server A) Configure virtual host for your rhoconnect application: Edit the file /etc/httpd/conf.d/rhoconnect.conf so that it reflects your specifications. B) As root user start server to pick up the changes: /sbin/service httpd start _APACHE2_TO_DO_ end end puts afterwords + about_app + "For more details see #{@prefix}/README file." end #create_texts create_texts