Automating installation of gems on remote machine with Capistrano

Greetings,

I'm wondering if anyone has used Capistrano to automate the installation of gems on remote machines.

The problem I'm having is that when you install a gem from the command line, at various stages it will prompt you for a 'Y' or 'N' answer.

Let's say I have the following task and I want it to run on a remote machine:

desc "Install rails"
task :install_rails do
  run "gem install rails"
end

The task starts up and begins the installation, but then hangs after I get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

Regards,
Steven

You can use the "--include-dependencies" option. You will have trouble with
platform specific gems, though, as it will ask you to pick a version. You
can probably specify the specific version in those cases, though.

Justin

···

On 11/27/06, Steven Hansen <runner@berkeley.edu> wrote:

The task starts up and begins the installation, but then hangs after I
get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

Quoting Steven Hansen <runner@berkeley.edu>:

Greetings,

I'm wondering if anyone has used Capistrano to automate the installation
of gems on remote machines.

The problem I'm having is that when you install a gem from the command
line, at various stages it will prompt you for a 'Y' or 'N' answer.

Let's say I have the following task and I want it to run on a remote
machine:

desc "Install rails"
task :install_rails do
  run "gem install rails"
end

The task starts up and begins the installation, but then hangs after I
get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

Could you use the Unix 'yes' command?

man yes

Instead of:

run "gem install rails"

use:

run "gem install rails -y"

Steven Hansen wrote:

···

Greetings,

I'm wondering if anyone has used Capistrano to automate the installation
of gems on remote machines.

The problem I'm having is that when you install a gem from the command
line, at various stages it will prompt you for a 'Y' or 'N' answer.

Let's say I have the following task and I want it to run on a remote
machine:

desc "Install rails"
task :install_rails do
  run "gem install rails"
end

The task starts up and begins the installation, but then hangs after I
get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

Regards,
Steven

Instead of:

run "gem install rails"

use:

run "gem install rails -y"

Steven Hansen wrote:

···

Greetings,

I'm wondering if anyone has used Capistrano to automate the installation
of gems on remote machines.

The problem I'm having is that when you install a gem from the command
line, at various stages it will prompt you for a 'Y' or 'N' answer.

Let's say I have the following task and I want it to run on a remote
machine:

desc "Install rails"
task :install_rails do
  run "gem install rails"
end

The task starts up and begins the installation, but then hangs after I
get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

Regards,
Steven

Hey Steven-

  Here is a capistrano plugin for installing gems remotely. This supports slecting gem versions or letting it pick from the list itself when it gets presented with a list of choices it will choose the correct latest version based on architecture.

  This is code adapted and extracted from the vmgen gem for generating Xen instances.

require 'capistrano'
# Installs within Capistrano as the plugin _gem_.
# Prefix all calls to the library with <tt>gem.</tt>
# Manages installing gems and versioned gems.
module Gem

   # Default install command

···

On Nov 27, 2006, at 1:56 PM, Steven Hansen wrote:

Greetings,

I'm wondering if anyone has used Capistrano to automate the installation of gems on remote machines.

The problem I'm having is that when you install a gem from the command line, at various stages it will prompt you for a 'Y' or 'N' answer.

Let's say I have the following task and I want it to run on a remote machine:

desc "Install rails"
task :install_rails do
run "gem install rails"
end

The task starts up and begins the installation, but then hangs after I get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

Regards,
Steven

   #
   # * doesn't install documentation
   # * installs all required dependencies automatically.
   #
   GEM_INSTALL="gem install -y --no-rdoc"

   # Upgrade the *gem* system to the latest version. Runs via *sudo*
   def update_system
     sudo "gem update --system"
   end

   # Updates all the installed gems to the latest version. Runs via *sudo*.
   # Don't use this command if any of the gems require a version selection.
   def upgrade
     sudo "gem update --no-rdoc"
   end

   # Removes old versions of gems from installation area.
   def cleanup
     sudo "gem cleanup"
   end

   # Installs the gems detailed in +packages+, selecting version +version+ if
   # specified.
   #
   # +packages+ can be a single string or an array of strings.
   #
   def install(packages, version=nil)
     sudo "#{GEM_INSTALL} #{if version then '-v '+version.to_s end} #{packages.to_a.join(' ')}"
   end

   # Auto selects a gem from a list and installs it.
   #
   # *gem* has no mechanism on the command line of disambiguating builds for
   # different platforms, and instead asks the user. This method has the necessary
   # conversation to select the +version+ relevant to +platform+ (or the one nearest
   # the top of the list if you don't specify +version+).
   def select(package, version=nil, platform='ruby')
     selections={}
     cmd="#{GEM_INSTALL} #{if version then '-v '+version.to_s end} #{package}"
     sudo cmd do |channel, stream, data|
       data.each_line do | line |
  case line
  when /\s(\d+).*\(#{platform}\)/
    if selections[channel[:host]].nil?
      selections[channel[:host]]=$1.dup+"\n"
      logger.info "Selecting #$&", "#{stream} :: #{channel[:host]}"
    end
  when /\s\d+\./
    # Discard other selections from data stream
  when /^>/
    channel.send_data selections[channel[:host]]
    logger.debug line, "#{stream} :: #{channel[:host]}"
  else
    logger.info line, "#{stream} :: #{channel[:host]}"
  end
       end
     end
   end

end

Capistrano.plugin :gem, Gem

Cheers-
-- Ezra Zygmuntowicz-- Lead Rails Evangelist
-- ez@engineyard.com
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)

Justin Bailey wrote:

···

On 11/27/06, Steven Hansen <runner@berkeley.edu> wrote:

The task starts up and begins the installation, but then hangs after I
get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

You can use the "--include-dependencies" option. You will have trouble with
platform specific gems, though, as it will ask you to pick a version. You
can probably specify the specific version in those cases, though.

Justin

Sweet, that's exactly what I was looking for.

-Steven

Ezra Zygmuntowicz wrote:

Greetings,

I'm wondering if anyone has used Capistrano to automate the installation of gems on remote machines.

The problem I'm having is that when you install a gem from the command line, at various stages it will prompt you for a 'Y' or 'N' answer.

Let's say I have the following task and I want it to run on a remote machine:

desc "Install rails"
task :install_rails do
run "gem install rails"
end

The task starts up and begins the installation, but then hangs after I get the 'Y' or 'N' prompt.

Is there a way to just skip the prompt and specify 'Y' for everything?

Regards,
Steven

Hey Steven-

    Here is a capistrano plugin for installing gems remotely. This supports slecting gem versions or letting it pick from the list itself when it gets presented with a list of choices it will choose the correct latest version based on architecture.

    This is code adapted and extracted from the vmgen gem for generating Xen instances.

require 'capistrano'
# Installs within Capistrano as the plugin _gem_.
# Prefix all calls to the library with <tt>gem.</tt>
# Manages installing gems and versioned gems.
module Gem

  # Default install command
  #
  # * doesn't install documentation
  # * installs all required dependencies automatically.
  #
  GEM_INSTALL="gem install -y --no-rdoc"

  # Upgrade the *gem* system to the latest version. Runs via *sudo*
  def update_system
    sudo "gem update --system"
  end

  # Updates all the installed gems to the latest version. Runs via *sudo*.
  # Don't use this command if any of the gems require a version selection.
  def upgrade
    sudo "gem update --no-rdoc"
  end

  # Removes old versions of gems from installation area.
  def cleanup
    sudo "gem cleanup"
  end

  # Installs the gems detailed in +packages+, selecting version +version+ if
  # specified.
  #
  # +packages+ can be a single string or an array of strings.
  #
  def install(packages, version=nil)
    sudo "#{GEM_INSTALL} #{if version then '-v '+version.to_s end} #{packages.to_a.join(' ')}"
  end

  # Auto selects a gem from a list and installs it.
  #
  # *gem* has no mechanism on the command line of disambiguating builds for
  # different platforms, and instead asks the user. This method has the necessary
  # conversation to select the +version+ relevant to +platform+ (or the one nearest
  # the top of the list if you don't specify +version+).
  def select(package, version=nil, platform='ruby')
    selections={}
    cmd="#{GEM_INSTALL} #{if version then '-v '+version.to_s end} #{package}"
    sudo cmd do |channel, stream, data|
      data.each_line do | line |
    case line
    when /\s(\d+).*\(#{platform}\)/
      if selections[channel[:host]].nil?
        selections[channel[:host]]=$1.dup+"\n"
        logger.info "Selecting #$&", "#{stream} :: #{channel[:host]}"
      end
    when /\s\d+\./
      # Discard other selections from data stream
    when /^>/
      channel.send_data selections[channel[:host]]
      logger.debug line, "#{stream} :: #{channel[:host]}"
    else
      logger.info line, "#{stream} :: #{channel[:host]}"
    end
      end
    end
  end

end

Capistrano.plugin :gem, Gem

Cheers-
-- Ezra Zygmuntowicz-- Lead Rails Evangelist
-- ez@engineyard.com
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)

Ezra,

Thank you! :slight_smile:

One question, is there a standard location to put capistrano plugins? The capistrano manual didn't mention anything about this so I suppose I could just stick it in my app's lib dir?

Kind Regards,
Steven

···

On Nov 27, 2006, at 1:56 PM, Steven Hansen wrote:

Hey Steven-

  It really doesn't matter where you put it as long as it is in the load path so you can require it in your recipe file. So lib is a fin place to put it.

Cheers-
-- Ezra Zygmuntowicz-- Lead Rails Evangelist
-- ez@engineyard.com
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)

···

On Nov 28, 2006, at 4:41 PM, Steven Hansen wrote:

Ezra Zygmuntowicz wrote:

<snip>
Ezra,

Thank you! :slight_smile:

One question, is there a standard location to put capistrano plugins? The capistrano manual didn't mention anything about this so I suppose I could just stick it in my app's lib dir?

Kind Regards,
Steven