Skip to content

Instantly share code, notes, and snippets.

@whiteinge
Created August 8, 2012 02:07
Show Gist options
  • Save whiteinge/3291404 to your computer and use it in GitHub Desktop.
Save whiteinge/3291404 to your computer and use it in GitHub Desktop.
A fabric file to bootstrap an Ubuntu system for use as a VirtualBox master image for development VMs using port-forwarding and shared folders.
# utf-8
"""A fabfile to boostrap a vanilla VirtualBox master image
Generally you will create a master image with the following commands::
fab -f ./bootstrap_venv_fab.py portfwd:guest=somevm-precise64-fresh
fab -f ./bootstrap_venv_fab.py -H 'localhost:2222' -u somedev -p somedev shared
fab -f ./bootstrap_venv_fab.py -H 'localhost:2222' -u somedev -p somedev nopasswd
fab -f ./bootstrap_venv_fab.py -H 'localhost:2222' -u somedev -p somedev resetmac
fab -f ./bootstrap_venv_fab.py -H 'localhost:2222' -u somedev -p somedev -- sudo shutdown -h now
Last, export an "appliance" as an .ova file.
You may create a Fabric config ini file in your home directory to avoid the
host/user/pass boilerplate.
"""
import textwrap
import fabric
import fabric.state
import fabric.version
import fabric.api as _fab
SSH_HOST = "localhost"
SSH_PORT = "2222"
SSH_USER = "somedev"
SSH_PASS = SSH_USER
# Override the above host settings with the -H flag
if not _fab.env['hosts']:
_fab.env['hosts'] = ['{SSH_USER}@{SSH_HOST}:{SSH_PORT}'.format(**locals())]
_fab.env['password'] = SSH_PASS
# Chances are we don't care about security while boostrapping
_fab.env['disable_known_hosts'] = True
def portfwd(guest, custom=''):
"""Configure VBox port forwarding for ssh and http(s)
This allows you to easily access the services hosted on the VirtualBox
Guest OS from your local Host machine.
.. cmdoption:: guest
The name of the virtual machine to set up forwarding for
.. cmdoption:: custom
Add forwarding for a custom port in the form of "desc/guest/host". For
example, to access Django's builtin runserver from your host::
fab vbox_portfwd:custom="runserver/8000/8000"
.. warning::
The virtual machine must be stopped and started before forwarding
becomes available.
"""
if custom:
fwd_ports = [custom.split('/')]
else:
fwd_ports = (
('ssh', '22', SSH_PORT),
('http', '80', '8080'))
for name, guestport, hostport in fwd_ports:
with _fab.settings(_fab.hide('warnings'), warn_only=True):
_fab.local('VBoxManage modifyvm %(guest)s --natpf1 delete %(name)s' % locals())
_fab.local('VBoxManage modifyvm %(guest)s --natpf1 '
'%(name)s,tcp,,%(hostport)s,,%(guestport)s' % locals())
def shared():
"""Build the vboxsf module for Shared Folders
Try to automatically build the vboxsf module. Before invoking this
function, click on the "Devices" menu then "Install Guest Additions" to
make the VBoxGuestAdditions.iso image available to be mounted.
.. note::
This cannot be completely scripted without a ton of guesswork based on
platform since the VBoxGuestAdditions.iso file can be in a number of
places.
"""
VBOXSF = '/media/cdrom/VBoxLinuxAdditions.run'
with _fab.settings(_fab.hide('warnings'), warn_only=True):
_fab.sudo('mkdir -p /media/cdrom')
_fab.sudo('mount /dev/cdrom /media/cdrom')
if not fabric.contrib.files.exists(VBOXSF):
with _fab.settings(_fab.hide('warnings'), warn_only=True):
_fab.sudo('umount /media/cdrom')
_fab.abort(textwrap.dedent("""\
You must click 'Install Guest Additions' in the 'Devices'
menu before running this."""))
_fab.sudo('aptitude update')
_fab.sudo('aptitude -y install %s' % ' '.join((
'build-essential',
'module-assistant',
)))
with _fab.settings(_fab.hide('warnings'), warn_only=True):
_fab.sudo('sh %(VBOXSF)s' % locals())
_fab.sudo('umount /media/cdrom')
### Add fstab entries for Shared Folders
fabric.contrib.files.append(
'/etc/fstab',
'sharename /path/to/share/on/guest vboxsf '\
'rw,uid={0},gid=www-data 0 0'.format(SSH_USER),
use_sudo=True)
_fab.warn("Now edit fstab with the correct path to the share.")
def nopasswd():
"""Configure sudo to not require a password"""
fabric.contrib.files.sed('/etc/sudoers',
'ALL$', 'NOPASSWD: ALL', limit='%sudo', use_sudo=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment