class Incline::CLI::Prepare

Defines the 'prepare' command for the CLI.

Constants

DEFAULT_LOC
DEPLOY_HOME_PLACEHOLDER
FLY_TRAP_PING
FLY_TRAP_ROUTES
FLY_TRAP_SECRETS
INST_REG_COMMENT_PLACEHOLDER
NGINX_CONFIG
PASSENGER_ROOT_PATH
PASSENGER_ROOT_PLACEHOLDER
UTIL_NGINX_RELOAD

create setuid utilities to test the config and reload the config.

UTIL_NGINX_TEST

Public Class Methods

new(host_name_or_ip, ssh_user, *options) click to toggle source

Creates a new 'prepare' command for the CLI.

# File lib/incline/cli/prepare.rb, line 31
def initialize(host_name_or_ip, ssh_user, *options)
  @options = {
      port: 22,
      deploy_user: 'deploy',
      deploy_password: SecureRandom.urlsafe_base64(24),
      admin_password: '',
      ruby_version: '2.3.4',
      rails_version: '4.2.9'
  }
  @options[:host] = host_name_or_ip.to_s.strip

  raise UsageError.new("The 'host_name_or_ip' parameter is required.", 'prepare') if @options[:host] == ''

  if @options[:host] =~ /\A(?:\[[0-9a-f:]+\]|[a-z0-9]+(?:\.[a-z0-9]+)*):(?:\d+)\z/i
    h,_,p = @options[:host].rpartition(':')
    @options[:host] = h
    @options[:port] = p.to_i
  end

  @options[:admin_user] = ssh_user.to_s.strip

  raise UsageError.new("The 'ssh_user' parameter is required.", 'prepare') if @options[:admin_user] == ''

  while options.any?
    flag = options.delete_at(0)
    case flag
      when '--ssh-password'
        @options[:admin_password] = options.delete_at(0).to_s.strip
      when '--port'
        @options[:port] = options.delete_at(0).to_s.to_i
      when '--deploy-user'
        @options[:deploy_user] = options.delete_at(0).to_s.strip
        raise UsageError.new("The '--deploy-user' parameter requires a valid username.", 'prepare') unless @options[:deploy_user] =~ /\A[a-z][a-z0-9_]*\z/i
        raise UsageError.new("The '--deploy-user' parameter cannot match the 'ssh_user' parameter.", 'prepare') if @options[:deploy_user] == @options[:admin_user]
      when '--ruby-version'
        @options[:ruby_version] = options.delete_at(0).to_s.strip
        raise UsageError.new("The '--ruby-version' parameter must be at least 2.3.", 'prepare') if @options[:ruby_version].to_f < 2.3
      when '--rails-version'
        @options[:rails_version] = options.delete_at(0).to_s.strip
        raise UsageError.new("The '--rails-version' parameter must be at least 4.2.", 'prepare') if @options[:rails_version].to_f < 4.2

      # These options can be used to customize the self-signed certificate created initially.
      when '--ssl-country'
        @options[:ssl_country] = options.delete_at(0).to_s.strip
      when '--ssl-state', '--ssl-province'
        @options[:ssl_state] = options.delete_at(0).to_s.strip
      when '--ssl-location', '--ssl-city'
        @options[:ssl_location] = options.delete_at(0).to_s.strip
      when '--ssl-org'
        @options[:ssl_org] = options.delete_at(0).to_s.strip

      else
        raise UsageError.new("The '#{flag}' parameter is not recognized.", 'prepare')
    end
  end

  @options[:port] = 22 unless (1..65535).include?(@options[:port])
  if @options[:admin_password].to_s.strip == ''
    print 'Please enter the sudo password: '
    @options[:admin_password] = STDIN.noecho(&:gets).to_s.strip
    puts ''
    if @options[:admin_password].to_s.strip == ''
      puts 'WARNING: Sudo password is blank and script may fail because of this.'
    end
  end

  @options[:ssl_country] = 'US' if @options[:ssl_country].to_s == ''
  @options[:ssl_state] = 'Pennsylvania' if @options[:ssl_state].to_s == ''
  @options[:ssl_location] = 'Pittsburgh' if @options[:ssl_location].to_s == ''
  @options[:ssl_org] = 'WEB' if @options[:ssl_org].to_s == ''

end

Public Instance Methods

flytrap_path() click to toggle source
# File lib/incline/cli/prepare/install_flytrap.rb, line 36
def flytrap_path
  "http://#{@options[:host]}/#{FLY_TRAP_PING}"
end
run() click to toggle source

Prepares an Ubuntu server with NGINX and Passenger to run Rails applications.

Set 'host_name_or_ip' to the DNS name or IP address for the host. Set 'ssh_user' to the user name you want to access the host as. This user must be able to run 'sudo' commands and must not be 'root'.

You can provide a port value either appended to the host name or as a separate argument using the '–port' option. e.g. ssh.example.com:22 or –port 22

If you are configured with key authentication to the host then you don't need to provide an SSH password to connect. However, this password is also used to run sudo commands. You can specify a password on the command line by using the '–ssh-password' option. If you do not, then the script will prompt you for a “sudo” password to use. You can leave this blank, but the script will warn you that it may lead to failure. Obviously, if you are configured with NOPASSWD in the sudoers file, then you can safely leave the password blank.

By default, a deployment user named 'deploy' will be created on the host. If a user by this name already exists, that user will be removed first. This means that any data stored in the user profile will be destroyed by the script prior to creating the new user. You can change the name of the deployment user using the '–deploy-user' option. e.g. –deploy_user bob

The script will install 'rbenv' under the deploy user's account and then install Ruby followed by Rails. The default Ruby version installed is 2.3.4 and the Rails version installed is 4.2.9. To change these versions use the '–ruby-version' and '–rails-version' options. The Ruby version must be at least 2.3 and the rails version must be at least 4.2.

# File lib/incline/cli/prepare.rb, line 137
def run
  # reset the host info.
  @host_info = nil

  admin_shell do |admin|
    # test the connection and sudo capabilities.
    admin.sudo_stat_exec 'Testing connection', 'ls -al /root'

    # retrieve the host info now that we are connected.
    @host_info = admin.host_info
    raise CliError, "Host OS (#{host_id}) is not supported." unless [ :ubuntu ].include?(host_id)

    # update the system and configure SSH.
    update_system admin
    ssh_copy_id(admin) unless @options[:admin_password] == ''
    config_ssh admin
  end
  # end the session and reconnect to take advantage of the SSH reset done at the end of config_ssh
  admin_shell do |admin|
    # install ruby prerequisites and mariadb.
    install_prereqs admin
    install_db admin

    # add the deploy user.
    add_deploy_user admin

    # log in as deploy user
    deploy_shell do |deploy|
      # enable key auth.
      ssh_copy_id deploy

      # install rbenv.
      install_rbenv deploy
    end

    # log out and then back in to load rbenv
    deploy_shell do |deploy|
      # install ruby & rails
      install_ruby deploy
      install_rails deploy

      # one more fun little addition, we'll add the flytrap app to catch path attacks.
      install_flytrap deploy
    end
    # done with the deploy user, so log out of that session.

    # install Phusion Passenger to the host and then configure it.
    install_passenger admin
    config_passenger admin

    # create a few helper utilities to test and reload the configuration.
    create_nginx_utils admin

    # then restart nginx.
    restart_nginx admin

    puts 'Testing nginx server...'
    admin.exec_ignore_code 'curl http://localhost/this-is-a-test'
    admin.exec "curl #{flytrap_path}"
  end

  puts ''
  puts ANSI.ansi(:bold, :white) { 'Host preparation completed.' }
  puts ''
  puts 'Deployment User'
  puts ('-' * 70)
  puts "User:     " + ANSI.ansi(:bold) { @options[:deploy_user] }
  puts "Password: " + ANSI.ansi(:bold) { @options[:deploy_password] }
  puts "Home:     " + ANSI.ansi(:bold) { @options[:deploy_home] }
  puts ''
  puts 'Server Test Path'
  puts ('-' * 70)
  puts ANSI.ansi(:bold) { flytrap_path }

  logfile.flush
  logfile.close
  @logfile = nil

end

Private Instance Methods

add_deploy_user(shell) click to toggle source
# File lib/incline/cli/prepare/add_deploy_user.rb, line 26
def add_deploy_user(shell)
  # clean up first
  unless shell.get_user_id(@options[:deploy_user]) == 0
    shell.with_stat('Removing previous deploy user') do
      unless kill_processes(shell, @options[:deploy_user], 'TERM')
        unless kill_processes(shell, @options[:deploy_user], 'KILL')
          raise CliError, "Failed to kill all processes owned by #{@options[:deploy_user]}."
        end
      end
      # remove crontab for user.
      shell.sudo_exec_ignore_code "crontab -u #{@options[:deploy_user]} -r"
      # remove at jobs for user.
      shell.sudo_exec_ignore_code "find /var/spool/cron/atjobs -name \"[^.]*\" -type f -user #{@options[:deploy_user]} -delete"
      # remove the user.
      shell.sudo_exec "userdel -r #{@options[:deploy_user]}"
      # remove the main user group.
      shell.sudo_exec_ignore_code "groupdel #{@options[:deploy_user]}"
    end
  end

  shell.with_stat('Adding deploy user') do
    # create the user.
    shell.sudo_exec "useradd -mU -s /bin/bash #{@options[:deploy_user]}"
    shell.sudo_exec "printf \"#{@options[:deploy_password]}\\n#{@options[:deploy_password]}\\n\" | passwd #{@options[:deploy_user]}"

    # add the user's group to the admin user.
    shell.sudo_exec "usermod -G #{@options[:deploy_user]} -a #{@options[:admin_user]}"

    # set the permissions on the user's home directory.
    # it should be /home/deploy or some such, but let's not assume so.
    @options[:deploy_home] = shell.exec("eval echo \"~#{@options[:deploy_user]}\"").split("\n").first.strip
    shell.sudo_exec "chown #{@options[:deploy_user]}:#{@options[:deploy_user]} #{@options[:deploy_home]} && chmod 755 #{@options[:deploy_home]}"
  end
end
admin_shell() { |sh| ... } click to toggle source
# File lib/incline/cli/prepare.rb, line 239
def admin_shell
  Shells::SshBashShell.new(
      host: @options[:host],
      port: @options[:port],
      user: @options[:admin_user],
      password: @options[:admin_password],
      retrieve_exit_code: true,
      on_non_zero_exit_code: :raise,
      silence_timeout: 5
  ) do |sh|
    extend_shell sh, '# '
    yield sh
  end
end
config_passenger(shell) click to toggle source
# File lib/incline/cli/prepare/config_passenger.rb, line 114
def config_passenger(shell)
  shell.with_stat('Configuring Passenger') do
    
    # add the ruby-apps user.
    if shell.get_user_id('ruby-apps') == 0
      shell.sudo_exec "useradd -mU ruby-apps"
    end
    
    # add ruby-apps and deploy groups to each other.
    shell.sudo_exec_ignore_code "usermod -G ruby-apps -a #{@options[:deploy_user]}"
    shell.sudo_exec_ignore_code "usermod -G #{@options[:deploy_user]} -a ruby-apps"

    # backup and remove the original configuration.
    shell.sudo_exec 'if [ ! -f /etc/nginx/nginx.conf.original ]; then mv -f /etc/nginx/nginx.conf /etc/nginx/nginx.conf.original; fi'

    # get the passenger_root path.
    pr_path = shell.sudo_exec_ignore_code "ls {#{PASSENGER_ROOT_SEARCH.join(',')}}/#{PASSENGER_ROOT_PATH} 2>/dev/null"
    pr_path = pr_path.to_s.split("\n").first.to_s.strip
    raise CliError, 'Failed to locate passenger_root path' if pr_path == ''
    
    # write the new configuration to a temporary file.
    shell.write_file(
        "#{shell.home_path}/nginx.conf",
        NGINX_CONFIG
            .gsub(PASSENGER_ROOT_PLACEHOLDER, pr_path)
            .gsub(DEPLOY_HOME_PLACEHOLDER, @options[:deploy_home])
            .gsub(INST_REG_COMMENT_PLACEHOLDER, host_id == :centos ? '' : '# ')
    )

    # move it where it belongs.
    shell.sudo_exec "mv -f #{shell.home_path}/nginx.conf /etc/nginx/nginx.conf"
    shell.sudo_exec 'chown root:root /etc/nginx/nginx.conf && chmod 644 /etc/nginx/nginx.conf'

    # create the location folders.
    %w(locations-available locations-enabled).each do |loc|
      loc = "/etc/nginx/#{loc}"
      shell.sudo_exec "if [ ! -d #{loc} ]; then mkdir #{loc}; fi"
      shell.sudo_exec "chown #{@options[:deploy_user]}:root #{loc} && chmod 6755 #{loc}"
    end

    # create the default location.
    shell.write_file(
        "#{shell.home_path}/default.loc",
        DEFAULT_LOC
            .gsub(PASSENGER_ROOT_PLACEHOLDER, pr_path)
            .gsub(DEPLOY_HOME_PLACEHOLDER, @options[:deploy_home])
    )
    shell.sudo_exec "mv -f #{shell.home_path}/default.loc /etc/nginx/locations-available/default"
    shell.sudo_exec "chown #{@options[:deploy_user]}:root /etc/nginx/locations-available/default && chmod 644 /etc/nginx/locations-available/default"
    shell.sudo_exec "ln -s /etc/nginx/locations-available/default /etc/nginx/locations-enabled/default"

    # create the SSL files.
    shell.sudo_exec 'if [ ! -d /var/ssl ]; then mkdir /var/ssl; fi'
    shell.sudo_exec 'chown ruby-apps:root /var/ssl && chmod 700 /var/ssl'
    # strengthen SSL by using unique dhparams
    shell.sudo_exec 'openssl dhparam -out /var/ssl/dhparams.pem 2048'
    # generate a generic self-signed certificate to get started with.
    shell.sudo_exec "openssl req -x509 -nodes -days 365 -newkey rsa:4096 -subj \"/C=#{@options[:ssl_country]}/ST=#{@options[:ssl_state]}/L=#{@options[:ssl_location]}/O=#{@options[:ssl_org]}/CN=$(hostname -f)\" -keyout /var/ssl/ssl.key -out /var/ssl/ssl.crt"
    shell.sudo_exec 'chown ruby-apps:root /var/ssl/* -R && chmod 600 /var/ssl/*'
  end
end
config_ssh(shell) click to toggle source
# File lib/incline/cli/prepare/config_ssh.rb, line 8
def config_ssh(shell)
  pa_rex = /#\s*PubkeyAuthentication\s+[^\n]*\n/
  rl_rex = /#\s*PermitRootLogin\s+[^\n]*\n/

  shell.with_stat('Configuring SSH') do
    shell.sudo_exec "cp -f /etc/ssh/sshd_config #{shell.home_path}/tmp_sshd_conf"
    contents = shell.read_file("#{shell.home_path}/tmp_sshd_conf")
    new_contents = contents.gsub(pa_rex, "PubkeyAuthentication yes\n").gsub(rl_rex, "PermitRootLogin no\n")
    if new_contents != contents
      shell.write_file "#{shell.home_path}/tmp_sshd_conf", new_contents
      shell.sudo_exec "chown root:root #{shell.home_path}/tmp_sshd_conf"
      shell.sudo_exec "chmod 600 #{shell.home_path}/tmp_sshd_conf"
      shell.sudo_exec "mv -f #{shell.home_path}/tmp_sshd_conf /etc/ssh/sshd_config"
      
      begin
        shell.sudo_exec_ignore_code 'systemctl restart sshd.service'
      rescue
        # ignore any errors from the SSH restart since we should be exiting the SSH session immediately after this gets executed anyway.
      end
    end
  end
end
create_nginx_utils(shell) click to toggle source
# File lib/incline/cli/prepare/create_nginx_utils.rb, line 37
def create_nginx_utils(shell)
  shell.with_status('Creating utilities') do
    nginx_path = shell.exec("which nginx").split("\n").first.to_s.strip
  
    { 'nginx-reload' => UTIL_NGINX_RELOAD, 'nginx-test' => UTIL_NGINX_TEST }.each do |util,src|
      shell.write_file "#{shell.home_path}/temp-util.c", src.gsub("??NG", nginx_path)
      shell.exec "gcc -o #{shell.home_path}/#{util} #{shell.home_path}/temp-util.c"
      shell.sudo_exec "chown root:root #{shell.home_path}/#{util} && chmod 4755 #{shell.home_path}/#{util}"
      shell.sudo_exec "mv -f #{shell.home_path}/#{util} /usr/local/bin/#{util}"
      shell.exec "rm #{shell.home_path}/temp-util.c"
    end
  end
end
deploy_shell() { |sh| ... } click to toggle source
# File lib/incline/cli/prepare.rb, line 254
def deploy_shell
  Shells::SshBashShell.new(
      host: @options[:host],
      port: @options[:port],
      user: @options[:deploy_user],
      password: @options[:deploy_password],
      retrieve_exit_code: true,
      on_non_zero_exit_code: :raise,
      silence_timeout: 5
  ) do |sh|
    extend_shell sh, '$ '
    yield sh
  end
end
extend_shell(sh, prefix) click to toggle source

Add full logging to the shell along with a few helper methods. The prefix is used to identify the shell creating the messages and will be prefixed to each line in the log.

# File lib/incline/cli/prepare/extend_shell.rb, line 9
def extend_shell(sh, prefix)
  logfile.write "\n" + prefix
  sh.instance_variable_set :@prep_log, logfile
  sh.instance_variable_set :@prep_prefix, "\n#{prefix}"
  sh.instance_variable_set :@stat_count, -1
  sh.instance_variable_set :@stat_every, 128
  sh.instance_variable_set :@home_path, nil

  def sh.home_path
    @home_path ||= exec_ignore_code("eval echo \"~#{@options[:user]}\"").to_s.split("\n").first.to_s.strip
  end

  def sh.with_stat(status, stat_every = 128)
    if @stat_count > -1
      yield
    else
      @stat_count = 0
      @stat_every = stat_every < 1 ? 128 : stat_every
      print status
      yield
      print "\n"
      @stat_count = -1
      @stat_every = 128
    end
  end

  def sh.exec(cmd, options = {}, &block)
    super(cmd, options) do |data, type|
      @prep_log.write data.gsub("\n", @prep_prefix)
      @prep_log.flush
      if @stat_count > -1
        @stat_count += data.length
        while @stat_count >= @stat_every
          @stat_count -= @stat_every
          print '.'
        end
      end
      if block
        block.call data, type
      else
        nil
      end
    end
  end

  def sh.stat_exec(status, cmd, options = {}, &block)
    with_stat(status) { exec(cmd, options, &block) }
  end

  def sh.sudo_stat_exec(status, cmd, options = {}, &block)
    with_stat(status) { sudo_exec(cmd, options, &block) }
  end

  def sh.apt_get(command)
    sudo_exec "DEBIAN_FRONTEND=noninteractive apt-get -y -q #{command}"
  end

  def sh.get_user_id(user)
    result = exec_ignore_code("id -u #{user} 2>/dev/null").to_s.split("\n")
    result.any? ? result.first.strip.to_i : 0
  end

  def sh.host_info
    @host_info ||=
        begin
          results = exec('cat /etc/*-release').split("\n").map{|s| s.strip}.reject{|s| s == ''}
          info = {}

          results.each do |line|
            if line.include?('=')
              var,_,val = line.partition('=').map{|s| s.strip}
              val = val[1...-1] if val[0] == '"' && val[-1] == '"'
              var.upcase!
              info[var] = val
            end
          end

          info['ID'] = (info['ID'] || 'unknown').downcase.to_sym
          info['NAME'] ||= info['ID'].to_s
          info['VERSION'] ||= '??'
          info['PRETTY_NAME'] ||= "#{info['NAME']} #{info['VERSION']}"

          puts info['PRETTY_NAME']

          info
        end
  end

  sh
end
host_id() click to toggle source
# File lib/incline/cli/prepare.rb, line 224
def host_id
  host_info['ID'] ||= :unknown
end
host_info() click to toggle source
# File lib/incline/cli/prepare.rb, line 220
def host_info
  @host_info ||= {}
end
install_db(shell) click to toggle source
# File lib/incline/cli/prepare/install_db.rb, line 8
def install_db(shell)
  shell.with_stat('Installing MariaDB') do
    shell.sudo_exec 'debconf-set-selections <<< \'mariadb-server mysql-server/root_password password \''
    shell.sudo_exec 'debconf-set-selections <<< \'mariadb-server mysql-server/root_password_again password \''
    shell.apt_get 'install mariadb-server mariadb-client libmysqlclient-dev'
    shell.sudo_exec_ignore_code 'systemctl stop mysql.service'
    shell.sudo_exec 'systemctl start mysql.service'
    shell.sudo_exec 'systemctl enable mysql.service'
  end
end
install_flytrap(shell) click to toggle source
# File lib/incline/cli/prepare/install_flytrap.rb, line 42
def install_flytrap(shell)
  shell.with_stat('Installing flytrap') do
    shell.exec "if [ ! -d #{shell.home_path}/apps ]; then mkdir #{shell.home_path}/apps; fi"
    shell.exec "chmod 775 #{shell.home_path}/apps"
    # install the fly_trap app and write the new routes.rb file.
    shell.exec "git clone https://github.com/barkerest/fly_trap.git #{shell.home_path}/apps/fly_trap"
    shell.write_file "#{shell.home_path}/apps/fly_trap/config/routes.rb", FLY_TRAP_ROUTES
    shell.write_file "#{shell.home_path}/apps/fly_trap/config/secrets.yml", FLY_TRAP_SECRETS
    # prep the app.
    shell.exec "cd #{shell.home_path}/apps/fly_trap"
    shell.exec "bundle install --deployment"
    shell.exec "bundle exec rake db:migrate:reset RAILS_ENV=production"
    shell.exec "bundle exec rake assets:precompile RAILS_ENV=production RAILS_GROUPS=assets RAILS_RELATIVE_URL_ROOT=\"/\""
    shell.exec "cd #{shell.home_path}"
    # generate the cron job
    shell.exec "(crontab -l; echo \"*/5 * * * * curl http://localhost/#{FLY_TRAP_PING} >/dev/null 2>&1\";) | crontab -"
  end
end
install_passenger(shell) click to toggle source
# File lib/incline/cli/prepare/install_passenger.rb, line 8
def install_passenger(shell)
  distros = {
      '12.04' => 'precise',
      '12.10' => 'quantal',
      '13.04' => 'raring',
      '13.10' => 'saucy',
      '14.04' => 'trusty',
      '14.10' => 'utopic',
      '15.04' => 'vivid',
      '15.10' => 'wily',
      '16.04' => 'xenial',
      '16.10' => 'yakkety',
      '17.04' => 'zesty'
  }

  distro = distros[host_info['VERSION_ID']]
  shell.with_stat('Installing Phusion Passenger') do
    shell.sudo_exec 'apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7'
    shell.apt_get 'install apt-transport-https ca-certificates'
    shell.sudo_exec "echo deb https://oss-binaries.phusionpassenger.com/apt/passenger #{distro} main > /etc/apt/sources.list.d/passenger.list"
    shell.apt_get 'update'
    shell.apt_get 'install nginx-extras passenger'
    shell.sudo_exec_ignore_code 'systemctl stop nginx'
    shell.sudo_exec 'systemctl start nginx'
    shell.sudo_exec 'systemctl enable nginx'
  end
end
install_prereqs(shell) click to toggle source
# File lib/incline/cli/prepare/install_prereqs.rb, line 7
def install_prereqs(shell)
  shell.with_stat('Installing prerequisites') do
    shell.apt_get 'install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev'
  end
end
install_rails(shell) click to toggle source
# File lib/incline/cli/prepare/install_rails.rb, line 7
def install_rails(shell)
  shell.with_stat("Installing Rails #{@options[:rails_version]}") do
    shell.exec "gem install rails -v #{@options[:rails_version]}"
    shell.exec 'rbenv rehash'
  end
end
install_rbenv(shell) click to toggle source
# File lib/incline/cli/prepare/install_rbenv.rb, line 8
      def install_rbenv(shell)
        
        shell.with_stat('Installing rbenv') do
          shell.exec "git clone https://github.com/rbenv/rbenv.git #{shell.home_path}/.rbenv"
          shell.exec "git clone https://github.com/rbenv/ruby-build.git #{shell.home_path}/.rbenv/plugins/ruby-build"

          bashrc = shell.read_file(shell.home_path + '/.bashrc') || ''
          lines = bashrc.split("\n")
          first_line = nil
          lines.each_with_index do |line,index|
            if line.strip[0] != '#'
              first_line = index
              break
            end
          end
          first_line ||= lines.count
          lines.insert first_line, <<-EORC

# Initialize rbenv and ruby.
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
eval "$(rbenv init -)"

          EORC

          bashrc = lines.join("\n")
          shell.write_file(shell.home_path + '/.bashrc', bashrc)
        end
        
      end
install_ruby(shell) click to toggle source
# File lib/incline/cli/prepare/install_ruby.rb, line 8
def install_ruby(shell)
  shell.with_stat("Install Ruby #{@options[:ruby_version]}") do
    result = shell.exec('which rbenv').to_s.strip
    raise 'failed to install rbenv' if result == ''

    shell.exec "rbenv install -v #{@options[:ruby_version]}"
    shell.exec "rbenv global #{@options[:ruby_version]}"

    result = shell.exec('which ruby').to_s.partition("\n")[0].strip
    raise 'ruby not where expected' unless result == shell.home_path + '/.rbenv/shims/ruby' || result == '~/.rbenv/shims/ruby'

    shell.exec "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
    shell.exec 'gem install bundler'
    shell.exec 'rbenv rehash'
  end
end
kill_processes(shell, user, signal) click to toggle source
# File lib/incline/cli/prepare/add_deploy_user.rb, line 12
def kill_processes(shell, user, signal)
  if user_process_list(shell, user).any?
    shell.sudo_exec_ignore_code "pkill -#{signal} -u #{user}"
    et = Time.now + 5
    while Time.now < et
      return true if user_process_list(shell, user).empty?
      sleep 1
    end
    user_process_list(shell,user).any?
  else
    true
  end
end
logfile() click to toggle source
# File lib/incline/cli/prepare.rb, line 229
def logfile
  @logfile ||=
      begin
        dir = File.expand_path('~/incline-logs')
        Dir.mkdir(dir) unless Dir.exist?(dir)
        File.open(File.expand_path("#{dir}/prepare-#{@options[:host]}.log"), 'wt')
      end

end
restart_nginx(shell) click to toggle source
# File lib/incline/cli/prepare/restart_nginx.rb, line 8
def restart_nginx(shell)
  shell.with_stat('Restarting nginx') do
    # test the configuration.
    shell.sudo_exec('nginx -t')

    # stop the service.
    shell.sudo_exec_ignore_code 'systemctl stop nginx.service'
    
    # start the service.
    shell.sudo_exec 'systemctl start nginx.service'
  end
end
ssh_copy_id(shell) click to toggle source
# File lib/incline/cli/prepare/ssh_copy_id.rb, line 7
def ssh_copy_id(shell)
  my_id_file = File.expand_path('~/.ssh/rsa_id.pub')
  if File.exist?(my_id_file)
    my_id = File.read(my_id_file)
    shell.with_stat('Enabling public key authentication') do
      
      shell.exec 'if [ ! -d ~/.ssh ]; then mkdir ~/.ssh; fi'
      shell.exec 'chmod 700 ~/.ssh'
      
      contents = shell.read_file("#{shell.home_path}/.ssh/authorized_keys")
      if contents
        unless contents.split("\n").find{|k| k.to_s.strip == my_id.strip}
          contents += "\n" unless contents[-1] == "\n"
          contents += my_id.strip + "\n"
          shell.write_file("#{shell.home_path}/.ssh/authorized_keys", contents)
        end
      else
        shell.write_file("#{shell.home_path}/.ssh/authorized_keys", my_id + "\n")
      end
      
    end
  end
end
update_system(shell) click to toggle source
# File lib/incline/cli/prepare/update_system.rb, line 8
def update_system(shell)
  shell.with_stat('Retrieving updates') { shell.apt_get 'update' }
  shell.with_stat('Updating system') { shell.apt_get 'upgrade' }
  shell.with_stat('Updating kernel') { shell.apt_get 'install linux-generic linux-headers-generic linux-image-generic' }
end
user_process_list(shell, user) click to toggle source
# File lib/incline/cli/prepare/add_deploy_user.rb, line 8
def user_process_list(shell, user)
  shell.sudo_exec_ignore_code("pgrep -u #{@options[:deploy_user]}").to_s.split("\n").map(&:strip).reject{|s| s == ''}
end