02 May 2008

Capistrano 2.3.0

Posted by Jamis on Friday, May 2

On February 16 I set myself to travel a path that I hoped would eventually help me deal with the project overload I was feeling. Today I get to release Capistrano 2.3, which is very near to the end of that path!

gem install capistrano

Capistrano 2.3 is primarily significant in that it switches to the new Net::SSH v2 library, which is faster and slimmer than the older Net::SSH v1 library. It also pulls in Net::SFTP v2, and the new Net::SSH::Gateway and Net::SCP libraries.

In addition to that, cap 2.3 adds several exciting (if I do say so myself) new features, and a few bug fixes that had lingered for far too long.

FEATURE: The :copy strategy has been significantly improved. Instead of doing a blind checkout/export, archiving the result, and copying it over, you can specify that a local cached copy of your repository should be used. If the cached copy does not exist, it is created (via a checkout), otherwise it is simply updated (a much faster operation than a checkout, typically). This functions much like the :remote_cache strategy, but locally. To use this, simply set the :copy_cache variable to true:

1
2
set :deploy_via, :copy
set :copy_cache, true

By default, the cached copy will be in your machine’s temporary directory (/tmp, for example), but you can specify your own location by setting :copy_cache to the desired path:

1
2
set :deploy_via, :copy
set :copy_cache, "/u/caches/#{application}"

But wait! There’s more! Suppose you have certain files that you don’t want to deploy, like photoshop files or your .git directory. You can set the :copy_exclude variable to a file glob (or an array of globs):

1
2
3
set :deploy_via, :copy
set :copy_cache, true
set :copy_exclude, [".git", "materials"]

This should make your deploys faster than ever, especially using a tip I hope to share in the next day or two that uses this in conjunction with some vendor/rails symlinking.

FEATURE: Even though I strenuously believe it is a mistake to deploy anything that is not under source control, I’ve finally caved and added a dumb :none SCM module. It can be used to deploy a specific directory if used with the :copy strategy:

1
2
3
set :repository, "."
set :scm, :none
set :deploy_via, :copy

Again, there are very, very few cases when I think use of this technique is justified, but because I ran into one myself a month ago, I decided it was worth adding.

FEATURE: Support was added for “depend :remote, file” to test for the existence of a specific file:


depend :remote, "/etc/syslog.conf"

This is used in conjunction with the deploy:check task.

FEATURE: You can specify ssh_options per-server, now, simply by giving an :ssh_options key and corresponding hash with the server definition:


role "some.host", :ssh_options => { :keys => "/path/to/key" }

FEATURE: There are two new file transfer helpers, upload and download, which are much more powerful and resource-friendly than the old ‘put’ and ‘get’ helpers. You can use upload and download to transfer single files, or entire directory trees:

1
2
upload "/local/file", "/remote/file"
download "/remote/file", "/local/file"

This will transfer to or from all active servers, which is particular tricky when using the download helper, since it will download the file simultaneously from all active hosts. To make this work, you need to make sure each is downloaded to a different location:

1
2
Dir.mkdir("destination")
download "/remote/file", "destination/file-$CAPISTRANO:HOST$"

The above will download the file from each host to a file on the local host, where the local file includes the name of the source host. Tricky!

Also, you can now specify that you want to upload or download via SCP instead of SFTP:

1
2
upload "local", "remote", :via => :scp
download "remote", "local", :via => :scp

The default is :sftp.

The less exciting (but still mildly titillating) things are the bug fixes and pleasure-enhancing behavioral changes:

  • The default run options are now mixed into the command options when executing a command from the capistrano shell.
  • The git SCM now uses git-ls-remote instead of git-rev-parse to resolve the revision of the checkout.
  • A trivial export method has been added to the git SCM.
  • The git SCM will include tags when it fetches.`
  • The sudo() helper now works nicely with complex and chained commands.
  • The deploy:setup task will now use sudo if :use_sudo is true (the default)

So, have at it! Remember to report bugs to http://capistrano.lighthouseapp.com. And patches are always welcome via git—just fork the capistrano repository at git://github.com/jamis/capistrano.git (thanks GitHub!).

Cheers!

Posted in Announcements | 27 comments

Net::SSH 2.0 (and friends)

Posted by Jamis on Friday, May 2

At last! Net::SSH 2.0 is available! Also available are Net::SFTP 2.0, Net::SCP 1.0, Net::SSH::Gateway 1.0, and Net::SSH::Multi 1.0.

1
2
3
4
5
$ gem install net-ssh \
  net-sftp \
  net-scp \
  net-ssh-gateway \
  net-ssh-multi

All of these Ruby libraries are for communicating with remote servers via the SSH protocol in different ways.

Net::SSH and Net::SFTP are both significant upgrades from their previous incarnations; if you have used either library in the past, you’ll want to read the documentation (Net::SSH, Net::SFTP). The Net::SSH API is still fairly similar to the way it was before, but the Net::SFTP API is entirely different.

All have pretty complete RDoc documentation, so you should be able to employ “ri” to good effect to find your way around the libraries. (Try “ri Net::SSH”, for example, to get started.)

Per-library synopses follow.

Net::SSH 2.0

This is a significant upgrade from Net::SSH 1.x. Changes from 1.x include (but are not limited to):

  • Net::SSH 2.0 no longer requires the Needle dependency-injection library. This has made the library faster, lighter, and easier to understand.
  • The “sync” and “sync-shell” services have been removed and will not return. (If you need the functionality of those services, I strongly encourage you to port them to Net::SSH 2 and release them as separate extensions.)
  • Options in ~/.ssh/config files are (partially) supported, and are loaded by default now.
  • The Net::SSH::start method now requires both a host and a username as the first two parameters, rather than inferring the username.
  • There is now a Session#exec method that makes it easier than ever to just execute and interact with a command.
  • Channel now sports an #on_process method that you can send a block to, which will be executed on every pass of the event loop.
  • Channel#on_request now accepts a string to indicate which request you want to respond to.
  • Channel open failures may be captured via Channel#on_open_failure.
  • Lots, lots, LOTS, more—refer to the rdocs for all the gory details.
1
2
3
4
5
6
require 'net/ssh'

Net::SSH.start('localhost', 'jamis') do |ssh|
  ssh.exec('hostname') # prints the results to $stdout
  ssh.loop
end

Net::SFTP 2.0

This is a complete rewrite of the original Net::SFTP 1.x code, and shares very, very little in common with it. The new version has a much cleaner implementation and API, and provides some really handy methods for transferring files and directories.

1
2
3
4
5
6
7
8
9
10
require 'net/sftp'

Net::SFTP.start('localhost', 'jamis') do |sftp|
  sftp.upload! "/local/file", "/remote/file"
  sftp.download! "/remote/file", "/local/file"

  sftp.file.open("/remote/file", "w") do |file|
    file.puts "here is some data"
  end
end

Net::SCP 1.0

This provides a way to transfer files and directories via the SCP protocol, over Net::SSH.

1
2
3
4
5
6
require 'net/scp'

Net::SCP.start('localhost', 'jamis') do |scp|
  scp.upload! "/local/file", "/remote/file"
  scp.download! "/remote/file", "/local/file"
end

Net::SSH::Gateway 1.0

This library makes it easy to tunnel connections though firewalls. You simply connect to the gateway machine, and then specify which ports you want forwarded.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require 'net/ssh/gateway'

gateway = Net::SSH::Gateway.new('host', 'user')

gateway.ssh("host.private", "user") do |ssh|
  puts ssh.exec!("hostname")
end

gateway.open("host.private", 80) do |port|
  require 'net/http'
  Net::HTTP.get_print("127.0.0.1", "/path", port)
end

gateway.shutdown!

Net::SSH::Multi 1.0

This library makes it simple to open multiple Net::SSH connections and tie them all together, running commands in parallel (much like Capistrano does).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
require 'net/ssh/multi'

Net::SSH::Multi.start do |session|
  # access servers via a gateway
  session.via 'gateway', 'gateway-user'

  # define the servers we want to use
  session.use 'user1@host1'
  session.use 'user2@host2'

  # define servers in groups for more granular access
  session.group :app do
    session.use 'user@app1'
    session.use 'user@app2'
  end

  # execute commands on all servers
  session.exec "uptime"

  # execute commands on a subset of servers
  session.with(:app).exec "hostname"

  # run the aggregated event loop
  session.loop
end

Enjoy!

Posted in Announcements | 8 comments

30 Apr 2008

Maintenance Releases: Capistrano, Net::SSH

Posted by Jamis on Wednesday, April 30

With the impending releases of the improved Net::SSH family of libraries, and the next Capistrano release that will depend on them, it was time to go back and make sure that the oldies-but-goodies will still work along side these new-comers.

To that end, I present:

Net::SSH 1.1.3

This maintenance release will hopefully fix the hangs that people have been reporting when dealing with long-running requests in Net::SSH, Net::SFTP, and Capistrano.

gem install net-ssh

It is strongly recommended that all Net::SSH users upgrade to this version.

Capistrano 1.4.2

This release merely adds an explicit dependency on Net::SSH and Net::SFTP versions less than 1.99.0, allowing you to use both cap1 and cap2 side-by-side after Net::SSH v2 (and friends) are released.

gem install --version 1.4.2 capistrano

If you are needing to run cap1 and cap2 side-by-side (for instance, if you haven’t yet upgraded some recipes, but want to enjoy the cap2 goodies on newer projects), you should upgrade your cap1 installation to 1.4.2. If you are completely upgraded to cap2, you can safely ignore this release.

Posted in Announcements | 4 comments

19 Apr 2008

Preview Releases: Net::SSH, Net::SSH::Multi

Posted by Jamis on Saturday, April 19

I’m almost ready to do a preview release of the next Capistrano version, which is built on top of the new Net::SSH library. To do that, though, I need to prime the pump by pushing out a few small fixes to Net::SSH. So, behold!

Net::SSH 2.0 Preview Release #4 (1.99.3):

gem install --source http://gems.jamisbuck.org net-ssh

This release has two minor new features and two fixed bugs:

  • Make sure HOME is set to something sane, even on OS’s that don’t set it by default. This makes things work a little better on Windows than before. (Ahem…any windows users out there that want to start playing with Net::SSH…I’d love to hear from you how it does.)
  • Add a :passphrase option to specify the passphrase to use with private keys. This lets you use encrypted keys without interaction (though since it requires you to hard-code the passphrase in your script…it kind of makes it pointless to use an encrypted key. Still, I’ve had lots of requests for this, and Francis Sullivan finally provided a patch).
  • BUG FIX: a new auth-agent connection will now be opened for every auth-agent channel request, rather than reusing a single auth-agent connection. This fixes some rather bizarre errors on some hosts.
  • BUG FIX: explicitly provided keys (those given via the :keys option) are now loaded correctly, thanks to some timely File.expand_path’ing provided in a patch from Thomas Hudson.

Net::SSH::Multi 1.0 Preview Release #2 (0.99.1)

Unrelated to Capistrano (since the next release of cap won’t be using it), I’m also pushing out a second preview release of Net::SSH::Multi, a library for managing multiple Net::SSH connections in parallel.

gem install --source http://gems.jamisbuck.org net-ssh-multi

This release has a single bug fix:

  • BUG FIX: don’t try to do IO.select on closed streams. This fixes a problem related to auth-agent channels getting closed and causing the parallel session processing to blow up.

Capistrano 2.3.0 preview release?

I’ll hopefully have a preview release for the next Capistrano version next week sometime. It’s close! I’m using it myself, locally, but I want to try it on a few more deploys to make sure it really works as advertised. I haven’t actually run any timings on it, but Capistrano with Net::SSH v2 feels significantly faster than it was on Net::SSH 1.x. Stay tuned!

Posted in Announcements | 2 comments

11 Apr 2008

Net::SSH::Multi + Rake == Tasty Potential

Posted by Jamis on Friday, April 11

Last night I released the first preview of Net::SSH::Multi (gem install --source http://gems.jamisbuck.org net-ssh-multi). Today, let me show you a tasty hint of what you can do with it.

Consider the following Rakefile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def remote
  @remote ||= begin
    require 'net/ssh/multi'

    session = Net::SSH::Multi.start

    session.via 'gateway.host', session.default_user

    session.group :web => session.use('web1', 'web2')
    session.group :app => session.use(*(1..8).map { |n| "app%02d" % n })
    session.group :db  => session.use('db1', :properties => { :primary => true })

    session
  end
end

namespace :remote do
  task :hostnames do
    remote.exec("hostname").wait
  end

  task :app_hostnames do
    remote.with(:app).exec("hostname").wait
  end

  task :web_hostnames do
    remote.with(:web).exec("hostname").wait
  end
end

You can now do things like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ rake remote:hostnames
(in /home/jamis)
[web1] web1.host
[app02] app02.host
[app05] app05.host
[app03] app03.host
[app06] app06.host
[app08] app08.host
[db1] db1.host
[app01] app01.host
[web2] web2.host
[app04] app04.host
[app07] app07.host

The Net::SSH::Multi library is still experimental, but it is stable and full-featured enough that I seriously considered implementing the next release of Capistrano on top of it. (I’ll probably put that off until cap3, though, due to the magnitude of the change.) If you do something cool with it, let me know!

Posted in Tips & Tricks | 5 comments

10 Apr 2008

More preview releases from the Net::SSH family

Posted by Jamis on Thursday, April 10

I’ve got lots of code to share with you all today:

Net::SSH 2.0 Preview Release #3

Not very many external changes, but channels now have an on_open_failure callback that you can employee to be told when a channel could not be opened.

1
2
3
4
5
6
7
channel = ssh.open_channel do |ch|
  # ...
end

channel.on_open_failure do |ch, code, reason|
  puts "could not open channel because #{reason.inspect} #{code}"
end

This change was necessary to make port forwarding a bit more reliable for Net::SSH::Gateway (see below).

Also, individual Net::SSH sessions may contain their own custom properties, much as Net::SSH channel objects do, which can be quite handy when you need to keep some state associated with the session.

ssh[:key] = "value"

This change (and several other internal refactorings) was necessary for the correct working of the Net::SSH::Multi library (see below).

To get the preview release #3 (version 1.99.2):

gem install --source http://gems.jamisbuck.org net-ssh

You can follow development via GitHub:

http://github.com/jamis/net-ssh/tree/master

Net::SFTP 2.0 Preview Release #2

All that was added in this preview release was custom properties on Upload instances:

1
2
3
uploader = sftp.upload("local.file", "remote.file")
uploader[:failed] = false
# ...

This was necessary to get Capistrano file transfers to work with Net::SFTP 2.0.

To get the preview release #2 (version 1.99.1):

gem install --source http://gems.jamisbuck.org net-sftp

You can follow development via GitHub:

http://github.com/jamis/net-sftp/tree/master

Net::SSH::Gateway 1.0 Preview Release #1

Net::SSH::Gateway is (in essence) the extraction of the gateway code from Capistrano into its own library. It lets you tunnel SSH connections through some “gateway” server to servers that would be otherwise inaccessible.

1
2
3
4
5
6
require 'net/ssh/gateway'

gateway = Net::SSH::Gateway.new('gateway.host', 'username')
gateway.ssh('remote.host', 'user') do |ssh|
  # ...
end

You can also use it as a general facilitator for forwarding connections over a local port, when you don’t care what port is to be used—you just want to connect to a remote server.

1
2
3
gateway.open('remote.host', 80) do |port|
  Net::HTTP.get_print '127.0.0.1', '/path', port
end

The current thinking is that the next release of Capistrano will ditch its own gateway implementation in favor of Net::SSH::Gateway. To get this first preview release (version 0.99.0):

gem install --source http://gems.jamisbuck.org net-ssh-gateway

You can follow development via GitHub:

http://github.com/jamis/net-ssh-gateway/tree/master

Net::SSH::Multi 1.0 Preview Release #1

Net::SSH::Multi is the guts of Capistrano, extracted into a library of their own. It allows you to define and categorize servers, and then execute commands in parallel on them, or on subsets of them, using an interface similar, if not identical, to that of Net::SSH::Connection::Session and Channel.

Eventually, Capistrano will be refactored to take advantage of Net::SSH::Multi, but doing so will require some significant changes to Capistrano’s innards, and would almost certainly break many third-party libraries. Thus, you won’t see Capistrano on Net::SSH::Multi until Capistrano 3.0 or so (which will not be the next release of Capistrano). However, you can use Net::SSH::Multi to implement most of Capistrano’s functionality in whatever form you like. Want Capistrano-in-a-rakefile? Have at it!

1
2
3
4
5
6
7
8
9
require 'net/ssh/multi'

Net::SSH::Multi.start do |session|
  session.use 'jamis@somewhere.com'
  session.use 'jamis@elsewhere.com'

  session.exec 'hostname'
  session.loop
end

Grab the first preview release (version 0.99.0):

gem install --source http://gems.jamisbuck.org net-ssh-multi

You can follow development via GitHub:

http://github.com/jamis/net-ssh-multi/tree/master

For all of these libraries I’ve tried to make the rdoc and ri documentation as informative as possible, so please refer to those to get started. If those aren’t helpful enough, let me know what could make them more useful!

Posted in Announcements Projects | 0 comments

22 Mar 2008

Preview Releases: Net::SSH and friends

Posted by Jamis on Saturday, March 22

After far, far too long, I’m extremely pleased to announce the next preview release of Net::SSH v2 (preview release #2, actual version 1.99.1), as well as the first ever preview releases of Net::SFTP v2 (preview release #1, actual version 1.99.0) and Net::SCP v1 (preview release #1, actual version 0.99.0). You can grab them from my gem server:

1
2
3
$ sudo gem install --source http://gems.jamisbuck.org net-ssh
$ sudo gem install --source http://gems.jamisbuck.org net-sftp
$ sudo gem install --source http://gems.jamisbuck.org net-scp

I’ve taken Eric Hodel’s advice this time around and ditched the pretty documentation I had started for Net::SSH; I’m going to see how far I can get with ri and rdoc alone, this time. Give it a try after installing the above: “ri Net::SSH”, for instance.

There are several caveats about this release:

1. The new Net::SSH and Net::SFTP are not backwards compatible with the previous 1.x releases, so make sure any existing scripts are explicitly depending on versions less than 1.99.0 of these libraries. (The latest Capistrano already has that explicit dependency in it, so you should be safe installing these preview releases even if you are using Capistrano).

2. The “shell”, “open3” and “sync-shell” services are gone from Net::SSH. (There may be others, too, which aren’t coming to mind at the moment.) I do not intend to bring them back. If you used those services, I strongly encourage you to reimplement them for the new Net::SSH, and release them as third-party extensions.

3. These libraries are reentrant (or ought to be), but are not thread-safe. That is to say, if you are accessing the same Net::SSH connection from multiple threads, you’re definitely going to want to do something to protect that resource (mutexes, etc.).

That said, let me know what you think, what issues you have, what suggestions you have, and so forth. I’m so happy to have this release done, though. I can see the light at the end of the tunnel finally!

Oh, and lastly, if you happen to be drinking the git kool-aid, you can follow along via github:

Posted in Announcements | 9 comments

17 Mar 2008

Net::SSH and Thread-safety

Posted by Jamis on Monday, March 17

Net::SSH 1.x is thread-safe. Net::SSH v2, as currently implemented in its pre-release state, is not.

I’ve debated this long and hard with myself. Wrapping code in mutexes and doing all the other stuff that thread-safety requires adds a surprising amount of overhead, and it feels painful to me to have to add all that when the most common use-case of the library will be in single-threaded environments. However, without the mutexes and all that overhead, using Net::SSH in a multi-threaded environment (where multiple threads are hitting the same Net::SSH connection) will result in some rather ugly errors, and would require those programs to add their own mutexes and such to protect the integrity of the connection.

I’m leaning towards leaving the library optimized for the single-thread experience, and requiring the people wanting multiple threads of execution to fend for themselves. However, in the interest of getting feedback from people who might actually use the library, I ask you: which would you prefer? A faster library in single-threaded programs? Or a simple program in multi-threaded ones? Is there a general best-practice in this case?

Posted in Projects | 26 comments

13 Mar 2008

Net::SFTP v2: done?!

Posted by Jamis on Thursday, March 13

I think...I think I’m actually, done, more or less, with Net::SFTP v2!

I just committed a last bit of documentation tweaking, and although I’m sure there’s more of that to come, and bugs to fix and features to add, I’m calling this bit “good enough”, and I’m moving on now to Net::SCP.

I’m not actually releasing Net::SFTP v2 at this point—it’s pretty much useless without a corresponding Net::SSH v2 release. So why am I saying anything about it right now? Because it’s the first significant milestone that I’ve completed in my track to complete the new Net::SSH suite of libraries! And I’m excited! And I’ve learned something significant by finishing Net::SFTP v2 before completely finishing Net::SSH v2: by completing a dependency of the primary library first, I saw first-hand where the deficiencies in the primary library were. This has resulted in a much tigher, much more useful API than the Net::SSH v1 and Net::SFTP v1 libraries.

Now, there is no real release of Net::SSH v2 and friends, but that’s not to say that if you’re brave, and don’t mind exploring a bit, you couldn’t get the new Net::SSH and Net::SFTP to work. The new Net::SSH is actually mostly done—I just need to revisit the documentation and update a few things here and there. The code is all on github. If you don’t have git, you can download a tarball directly from github, even.

So, have at it, if you’re so inclined. (And if you’d like on the github bandwagon, I’ve still got two invites burning a hole in my pocket…email me at (my first name) at jamisbuck.org, and I’ll be happy to send you one.)

Update: my github invites are all gone. Sorry!

Posted in Projects | 1 comment

07 Mar 2008

Magic 8ttp Ball

Posted by Jamis on Friday, March 7

My son, Britton, woke up this morning a little before 4am. As I was getting back into bed after feeding him, I saw that the clock read “4:04”, and (being the geek I am) I immediately thought “heh, 404 Sleep Not Found”.

He woke up a few minutes later, needing a bit of comforting (he’s definitely not usually this needy!), and when I got back into bed, the clock read “4:22”, obviously telling me that sleep was an “Unprocessable Entity”.

And thus the Magic 8ttp Ball was born.

Go on! Ask it anything! It’ll give you a suitably ambiguous HTTP response code in return. I’ve even been told it works great on the iPhone for when you have those burning questions on-the-go.

Posted in Announcements | 15 comments

06 Mar 2008

When duplication is not duplication

Posted by Jamis on Thursday, March 6

I was looking through some C code today, and stumbled across this lovely little gem:

1
2
3
4
5
tmp = "\"#";
while (*tmp) {
  FD_SET(*tmp, url_encode_map);
  tmp++;
}

Now, be honest. I don’t care how good you are at C, it takes you a few brain cycles to process that and figure out that it is just setting two bits in a bit field. It really should have been written like this:

1
2
FD_SET('"', url_encode_map);
FD_SET('#', url_encode_map);

This raises the question: why wasn’t it? I’ll tell you why:

Programmers have this burning desire to avoid code duplication. We’re taught, almost since the cradle, to abhor duplicated code and to avoid it all cost. Duplicating code is evil, it leads to unmaintainable code, and propogates bugs. Never, ever, do it!!!

Allow me to let you in on a little secret.

Calling the same function twice is NOT duplicating code. Not if the arguments change between calls.

Even calling the same function three times in a row is kosher. Four times, even. At some point, you might want to consider a loop, if the arguments can be determined functionally, but only do so when the list of similar function calls is harder to read and understand than the loop is. This is often when the loop takes fewer lines of code than the function calls do:

1
2
3
4
for (i = 127; i < 256; i++) {
  FD_SET(i, hdr_encode_map);
  FD_SET(i, url_encode_map);
}

There. Had to get that off my chest. Now, back to work.

Posted in Essays and Rants | 17 comments

27 Feb 2008

Capistrano 2.2.0

Posted by Jamis on Wednesday, February 27

Capistrano 2.2.0 is now available (well, it’s released, anyway, you might need to wait for the file to propagate to the gem mirrors).

gem install capistrano

Version 2.2.0 sports the following changes:

FEATURE: Dynamic role definition. The role() method now accepts a block, which should return either a host name, a Capistrano::ServerDefinition object, an array of host names, or an array of Capistrano::ServerDefinition objects. This can be used to describe the servers in a role at runtime.

1
2
3
4
role :app do
  hosts = some_method_that_looks_up_the_current_hosts
  hosts[0,3]
end

FEATURE: Alternative server-centric role definitions, using the server() method:

1
2
3
4
5
role :app, "server"
role :web, "server"

# the above is the same as this:
server "server", :app, :web

FEATURE: Support for a :max_hosts option in tasks, that restricts the task so that it is only executed in hosts at a time, in chunks. This helps people who use Capistrano with very large numbers of servers, and prevents them running into connection caps and from running out of memory.

1
2
3
4
5
6
7
8
9
10
11
12
13
task :ping, :max_hosts => 100 do
  # anything here will only run against 100 hosts at a time
end

# alternatively, you can pass :max_hosts to the run command itself for
# finer granularity
task :pong do
  # this will run on ALL hosts at once
  run "something"

  # this will run on no more than 100 hosts at a time
  run "something-else", :max_hosts => 100
end

ENHANCEMENT: Improved Git support! Not being a git user myself (yet), I can’t really speak intelligently about what the changes are, but if you use git chances are you aren’t afraid to dig into the code and read it. For those of you that use git, I’d encourage you to blog about the changes, to assuage some of my embarrassment about releasing code that I can’t describe intelligently!

ENHANCEMENT: Password prompt support in the Mercurial SCM.

ENHANCEMENT: Implement Bzr#next_revision so that pending changes can be reported correctly, and use checkout—lightweight instead of branch.

ENHANCEMENT: Bring back the :p4sync_flags and :p4client_root variables for perforce SCM.

Additionally, there are several minor bugs and typos that have been fixed. You can see the CHANGELOG for all the gory details.

As ever, please report bugs via the Rails trac, at http://dev.rubyonrails.org. And if you aren’t yet subscribed to the Capistrano mailing list, it’s where all the cool cappists hang out.

Posted in Announcements | 3 comments

25 Feb 2008

Net::SFTP 1.1.1

Posted by Jamis on Monday, February 25

Net::SFTP is a Ruby library for transferring files using the SFTP (Secure FTP) protocol over SSH. This is a maintenance release consisting of only two changes. First, you no longer need to explicitly call the #connect method. It is called automatically as needed. Second, this release has an explicit (RubyGems) dependency on Net::SSH versions less than 1.99.0. This should pave the way for making smoother the eventual release of Net::SSH v2 (which is not backwards compatible and would otherwise break existing installations of Net::SFTP 1.x).

All users of Net::SFTP are encouraged to upgrade. Using Rubygems, installation is simple:

gem install net-sftp

Alternate source packages (bz2 and zip) may be downloaded from the Net::SSH project page:

http://rubyforge.org/frs/?group_id=274&release_id=19594

Posted in Announcements | 4 comments

22 Feb 2008

Capistrano 2.2.0 Preview

Posted by Jamis on Friday, February 22

Alright, I’m almost ready to unleash this monster on the world, but I’d like a few brave souls to kick the tires. Especially, if you use git or bzr with Capistrano, you might want to give this new version a spin, since it includes a few changes to those SCM modules.

Grab the latest beta gem thus:

gem install --source http://gems.rubyonrails.org capistrano

The significant changes in this release:

FEATURE: Thanks to James Duncan Davidson, Cap 2.2.0 will sport an additional way to define roles. If you have servers that overlap roles, this can DRY things up:


server "host.name", :web, :app

FEATURE: Rob Holland submitted a patch that makes cap play more nicely with very large numbers of servers. If you had too many, cap would bog down, and you may even get errors from having too many simultaneous connections. You can now specify a :max_hosts option, and if a task needs to operate on more than that number of servers at once, the server list will be chopped up and fed through the task in pieces.

FEATURE: David Masover gave us a way to define roles dynamically, by passing a block to the role macro:

1
2
3
role :app do
  ["host1", "host2"]
end

This means that if you have a recipe that knows the roles, but won’t know the hosts until runtime (think EC2 and such), you can more easily code for it.

GIT: The git SCM module has the following changes:

  • Distributed git support for better operability with remote_cache strategy
  • Use checkout instead of merge for git SCM [nuttycom]
  • Add support for :git_enable_submodules variable, to enable submodules with the git SCM

And, of course, there are quite a few other smaller changes, too. Check out the CHANGELOG for the full list.

So, kick the tires and report back. If all looks good by the middle of next week or so, we’ll see an official release.

Posted in Announcements | 6 comments

16 Feb 2008

Dealing with project overload

Posted by Jamis on Saturday, February 16

I’ve got my plate full of projects that need attention, and the stress has been getting to me. Everybody has different ways of dealing with stress, but I think mine is the least effective: ignoring things doesn’t make them go away.

So, I’m taking a more active approach. Starting immediately, I’m going to be spending one hour, every day, six days a week, clearing away the backlog of projects. I’ll post a comment each day to keep myself honest—if I don’t leave a comment, you may assume I did not do any work that day!

Here is a list of what I’ll be working on, more or less in order of priority:

  1. Capistrano 2.2.0. This will primarily be a maintenance release, and mostly requires that the patches that are pending be tested and applied. It will also update the Net::SSH and Net::SFTP gem dependencies so that they explicitly exclude any 2.0 versions of those gems.
  2. Net::SFTP 1.1.1. This is a super minor release with no new features. All it will do is update the gem dependency on Net::SFTP such that it won’t try to load Net::SSH v2.
  3. Net::SSH v2, Net::SFTP v2, Net::SCP v1. These will be released simultaneously. They are an 80% rewrite of the original code (and yeah, rewrites are evil, but sometimes they are necessary). The API has changed, and scripts written against the existing API will almost certainly be broken by the upgrade, so make sure you are depending on version 1.x.
  4. Capistrano 2.3.0. This is another maintenance release, which simply modifies Capistrano to work with the new Net::SSH and Net::SFTP versions. (Possibly Net::SCP, too, not sure about that yet).
  5. SQLite3/Ruby 1.2.2. A maintenance release. Haven’t seen a release on this for a long, long time. No new features planned, but lots of bug fixes are pending.

I’m not even going to try and give an ETA on these. Just know that I’m working through them, an hour a day, and that progress is finally being made. I’ll post what I worked on in the comments to this thread, for those who want to follow along.

Posted in Projects | 22 comments