Skip to content

zaius/vagrant-listen-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vagrant-listen-server

Forward filesystem events from a host to a client

Vagrant's shared folders don't pass file modification notifications to the guest. That means editing files locally won't trigger off inotify file events, which means any build / test / servers that need to reload on change have to poll for changes.

If you're using virtualbox, vboxsf performance really really sucks. Hard links are impossible. Statting takes forever.

Since polling implementations will probably rely on statting the file in some way, this creates a pretty awful experience.

I have tried to keep dependencies to a minimum and only rely on ruby stdlib and gems already required by vagrant. The listen gem is used by vagrant (as part of rsync-auto) so it is used for file system notifications.

Clients

Clients should run inside the virtual machine as part of your build process. Instead of listenting for filesystem events, they should listen on a tcp connection.

The message format is a newline separated, json encoded object with keys type and data. The two message types:

listen

{"type": "listen", "data": [modified, added, removed]}

data is an array of 3 arrays containing the full path of the files that are modified, added and removed (in that order).

ping

{"type": "ping", "data": "message to be echoed"}

response will be of type "pong". Data will be echoed back to the client.

In many cases, a simple client that touches all modified files on the guest is sufficient, however you'll have to be aware of loops created if filesystem notifications are passed back from the guest to the host in any way. Listen coalesces events for us, so there is no need to do so in your client.

See the examples section for some implementations. Currently there is solely my node based client, but if you're using this in any other languages, please add your client and submit a pull request!

Keepalives

Ideally, the client and server sockets would both support keepalives. But we can't rely on that working on both guest and host - windows has spotty support, and many languages don't give control over socket flags (it's awkward in ruby). Instead, the client can send a ping message to check the connection is alive.

A simple client can safely ignore keepalive messages.

http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/

Usage

Install the plugin:

vagrant plugin install vagrant-listen-server

Then in your Vagrantfile:

config.vm.synced_folder '/host/code', '/client/code'

# You have to specify a private network for the guest to connect to.
config.vm.network :private_network, ip: '172.16.172.16'

if Vagrant.has_plugin? 'vagrant-listen-server'
  # The host will always be the same IP as the private network with the last
  # octet as .1
  config.listen_server.ip = '172.168.172.1'
  config.listen_server.port = 4000
  config.listen_server.folders = '/host/code'
  config.listen_server.pid_file = '/tmp/servername.listen.pid'
end

Because sleep states of both the host and guest machines can mess with long connections in unexpected ways, you can use the command to control the listen server.

vagrant listen stop
vagrant listen start
vagrant listen status

Other options

Filesystem is shared using rsync-auto protocol instead of vboxsf

Hasn't been updated to work with vagrant's new plugin system.

Development

To develop locally

gem build vagrant-listen-server.gemspec
vagrant plugin install vagrant-listen-server-*.gem

Other good vagrant plugins used for reference:

TODO:

Listen maybe is a bit of a resource hog:

There might be some better, native implementations that make this faster. e.g.

Gemspecs don't allow platform specific requirements, so we have to include all the gems for filesystem events. It looks like the only great solution to this is to switch to a separate gem for each platform...

You can automate the install pretty easily though:

Fork in a way that will work with windows. Childprocess gem is included with vagrant by default - see if it will fit the bill.

There's also a "subprocess" module under vagrant util

About

Vagrant plugin for forwarding file system events

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages