August 7, 2013

vagrant-lxc 0.5.0 and beyond

Last week I was able to release vagrant-lxc 0.5.0 and on this post you’ll get to know about some cool new stuff and the upcoming work I have in mind to reach what I believe would be a nice 1.0.0 milestone.

0.5.0 goodies

This release it mostly related to the “user experience” of using the plugin. Apart from some highlights you’ll get to know below, there are a few small things that makes people’s lives a bit easier:

  • Forwarded ports collision detection - the plugin no longer keeps silent about forwarding ports that are already in use by the host.
  • The plugin now errors if required dependencies are not installed - no more silent errors or stacktraces if the lxc and / or redir packages are not installed.
  • Support for redir logging to syslog - some people got bitten by redir issues this so I thought it would be nice to have this in places

Support for a sudo wrapper script, aka no more sudo passwords!

If you are using the plugin from within a VM on a Windows / Mac host you probably haven’t suffered from the pain of typing in your password quite a few times during the day while using the plugin. While there are certainly smarter ways to work around that, I ended up adding support for a wrapper / proxy script that allow us to add a single passwordless sudo entry on our /etc/sudoers for the plugin to use when sudo is required.

As stated on the the README, right now the script I’m using is really dumb AND INSECURE but it does the trick. It’s basically a ruby script that acts as a proxy for executing the commands:

#!/usr/bin/env ruby
exec ARGV.join(' ')

With that in place we can then add a single entry to our /usr/bin/lxc-vagrant-wrapper like the one below:

USERNAME ALL=NOPASSWD:/usr/bin/lxc-vagrant-wrapper

And tell vagrant-lxc to use it on our Vagrantfiles:

# Protip: Drop this into your ~/.vagrant.d/Vagrantfile to apply the configuration to all vagrant-lxc VMs
Vagrant.configure("2") do |config|
  config.vm.provider :lxc do |lxc|
    lxc.sudo_wrapper = '/usr/bin/lxc-vagrant-wrapper'
  end
end

That’s it, no more typing in your password when using vagrant-lxc boxes :)

Since user namespaces will be supported at some point, I’m not willing to give much attention on improving this for now and this is the reason I’m not bundling this with the plugin. Feel free to submit a Pull Request in case you have a better idea of doing this, I’ll be more than happy to review it ;)

“Promiscuous” port forwarding

On my very first vagrant-lxc post I showed an example of a Vagrantfile that could be used for setting up a VirtualBox VM between Mac / Windows hosts and vagrant-lxc containers but because vagrant-lxc < 0.5.0 used to bind forwarded ports with redir only to 127.0.0.1 there was no easy way of hitting the guest container directy from the host machine. Starting with 0.5.0 that set up now works out of the box because the port forwarding will work for any of the configured VBox IP.

Vagrant.configure("2") do |config|
  config.vm.box = "quantal64"

  config.vm.define :vbox do |vb_config|
    # Exposes access to the container
    vb_config.vm.network :forwarded_port, guest: 8000, host: 8080
    vb_config.vm.network :forwarded_port, guest: 2221, host: 2000
  end

  config.vm.define :lxc do |lxc_config|
    # Exposes a web server and SSH access
    lxc_config.vm.network :forwarded_port, guest: 80, host: 8000
    lxc_config.vm.network :forwarded_port, guest: 22, host: 2221
  end
end

So using a Vagrantfile similiar to the one above you should be able to SSH into the vbox VM, bring up the lxc container and hit a web server running on the container on port 80 through http://localhost:8080 from your host or SSH directly into the guest container from your host with ssh vagrant@localhost -p 2000.

Improved customizations

Prior to 0.5.0 the provided customizations and shared folders bind mounts where passed in as -s parameters to lxc-start. While that was working fine, it was a PITA to debug which of the configurations were giving us a bad time because it made us look into Vagrant debug logs to find out exactly which arguments were being passed in.

Starting with 0.5.0 those customizations are writen out to the container configuration file (usualy kept under /var/lib/lxc/<container>/config) prior to bringing it up with lxc-start.

A side effect of that is that in case the container is not able to boot, you can start the container on the foreground with something like lxc-start -n $(cat .vagrant/machines/<machine-name>/lxc/id) and replicate vagrant-lxc’s behavior. With that you’ll be able to find out more information on why things are not working and you’ll be able to tweak the Vagrantfile / lxc config file in order to track the issue down.

You can also benefit from this if you want to enable LXC Upstart Jobs for your vagrant-lxc containers on a real server. Although the VM won’t be provisioned automatically and ports won’t be forwarded like it normally would when using vagrant up, shared folders should work just fine and you can easily set up some shared socket for communication between the host and the guest container to avoid the need of using forwarded ports.

Demo

To better understand the new port forwarding, upstart and debugging capabilities check out the Asciicasts below. To save you some wait time, I’ll use the setup described on this gist with the VBox VM already running and the inner vagrant-lxc container created. The VBox VM has Nginx installed and is configured to use proxy /unicorn requests to a Ruby Rack “Hello world” application running behind an Unicorn Server listening on an UNIX socket shared between the VBox VM and vagrant-lxc container.

I’ve had some trouble recording the Asciicast in one go, so I had to split it into 2 recordings:

How does vagrant-lxc 1.0 look like?

I’ve been asking myself that question for a while now and I think I have a good list of things to accomplish to reach 1.0. I believe the plugin is pretty stable at this point (at least for myself) and most of the pain points from the initial releases have been sorted out (like sudoing and forwarded ports collision detection) so I might slow down a bit and focus on other projects for a while.

Of course the list is subject to change but here’s what I have in mind:

If you can think of something else or have any suggestion feel free to reach out ;)

UPDATE: Please check out this other post to find out more about my latest plans regarding 1.0

© Fabio Rehm 2013-2022

Powered by Hugo & Kiss.