Browse Source

initial commit

egradman 4 years ago
commit
94c4ddb668
4 changed files with 222 additions and 0 deletions
  1. 60
    0
      README.md
  2. 46
    0
      Vagrantfile
  3. 56
    0
      openframeworks-pi.yml
  4. 60
    0
      playbook.yml

+ 60
- 0
README.md View File

@@ -0,0 +1,60 @@
1
+# Introduction
2
+
3
+This package uses Vagrant and Ansible to spin up a virtual machine that runs on Mac, Linux, or Windows.  In less than five minutes, you'll have an environment that:
4
+
5
+- Cross-compiles for the Raspberry Pi armv6l architecture.
6
+- NFS boots one or more Raspberry Pis.  The root partition is loop-mounted from a .img file, so you can later dd it to an SD card for disconnected operation.
7
+- Is ready to cross-compile OpenFrameworks applications and run them on a cluster of Raspberry Pis.
8
+
9
+## Why cross-compile?
10
+
11
+The Raspberry Pi is slow.  This environment will let you compile OpenFrameworks applications on your fast desktop.
12
+
13
+## Why NFS-boot?
14
+
15
+If you're writing code that runs on a single Raspberry Pi, NFS-booting lets you edit code locally on your desktop.  There's no need to SSH into a Pi to edit and compile.
16
+
17
+Because the root partition is loop-mounted from a .img file, you can later create a standalone SD card by merely dd'ing it SD cards.
18
+
19
+The magic comes when you're building a cluster of Raspberry Pis.  There's no need to rsync or to reflash a stack of SD cards.  The latest code is accessible on every Pi at all times.  At Two Bit Circus, a common design pattern is to have a cluster of NFS-booted Raspberry Pis all choreographed by a single Linux server.  This virtual machine serves as the starting point for that design pattern.
20
+
21
+# Instructions
22
+
23
+## Prerequisites
24
+
25
+1. Install [VirtualBox](https://www.virtualbox.org/).
26
+1. Install [vagrant](http://www.vagrantup.com/).
27
+1. Install [Ansible](http://ansible.com).  I used pip.
28
+
29
+## Other Dependencies
30
+1. Clone this repository and cd into it.
31
+1. Download your preferred Raspberry Pi SD card image.  I'm using [2014-06-20-wheezy-raspbian](http://downloads.raspberrypi.org/raspbian_latest).  Unzip it, and symlink it to `image.img`.
32
+    ln -s 2014-06-20-wheezy-raspbian.img image.img
33
+1. Download a zip file of the Raspberry Pi [cross-compiler tools](https://github.com/raspberrypi/tools/archive/master.zip).  Make sure the zip file is named `tools-master.zip`.  Leave it compressed.
34
+1. Download [OpenFrameworks for armv6](http://www.openframeworks.cc/versions/v0.8.1/of_v0.8.1_linuxarmv6l_release.tar.gz).  Leave it compressed.
35
+
36
+## Get the image ready
37
+_You only have to do this if you're not using 2014-06-20-wheezy-raspbian._
38
+
39
+The NFS root with which you're booting the Pi lives in the image.img file.  You need to calculate the offsets to the boot and root partitions on that device.  On OSX you can just type `file image.img`.  The relevant information here is the start sector for the boot (1st) and root (2nd) partitions.  Multiply the start sector by the block size (512) to get the byte offset.  Put these numbers in `offset_boot` and `offset_root` in playbook.yml.
40
+
41
+## Create the virtual machine
42
+
43
+1. Configure a _wired ethernet_ network.  I use a USB Ethernet adapter on my Macbook.  Set the IP/netmask of the wired connection to `10.0.0.2/255.0.0.0`.
44
+1. Type `vagrant up`.  It will probably ask you to select the network interface to bridge to.  Select your wired connection.
45
+1. The machine will start and provision itself.  If there's an error and the provisioning doesn't complete, you can type `vagrant provision` to retry the provisioning process.
46
+1. Get a cup of coffee.  It'll take awhile.
47
+1. Type `vagrant ssh` to connect to and begin using your new environment.
48
+
49
+## Make a bootable card
50
+
51
+The provisioning process in the preceding section has already modified your SD card image to enable NFS booting.  We need to write the boot partition _and not the root partition_ to an SD card.
52
+
53
+1. On OSX and Linux: `dd if=image.img of=/dev/rdiskX bs=1m count=<root_offset>`.  The root offset is the same as before.  On my card it is 62914560.
54
+
55
+
56
+
57
+
58
+
59
+
60
+

+ 46
- 0
Vagrantfile View File

@@ -0,0 +1,46 @@
1
+# -*- mode: ruby -*-
2
+# vi: set ft=ruby :
3
+
4
+# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+VAGRANTFILE_API_VERSION = "2"
6
+
7
+Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8
+  config.vm.box = "ubuntu/precise32"
9
+
10
+  config.vm.network "public_network", bridge: 'en5: Thunderbolt Ethernet', ip: "10.0.0.1"
11
+  #config.vm.network "private_network", type: "dhcp"
12
+  #if Vagrant.has_plugin?("vagrant-cachier")
13
+  #  config.cache.scope = :box
14
+  #  #config.cache.synced_folder_opts = {
15
+  #  #  type: :nfs,
16
+  #  #  mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
17
+  #  #}
18
+  #end
19
+
20
+
21
+  # If true, then any SSH connections made will enable agent forwarding.
22
+  # Default value: false
23
+  # config.ssh.forward_agent = true
24
+
25
+  # Share an additional folder to the guest VM. The first argument is
26
+  # the path on the host to the actual folder. The second argument is
27
+  # the path on the guest to mount the folder. And the optional third
28
+  # argument is a set of non-required options.
29
+  # config.vm.synced_folder "../data", "/vagrant_data"
30
+
31
+  # Provider-specific configuration so you can fine-tune various
32
+  # backing providers for Vagrant. These expose provider-specific options.
33
+  # Example for VirtualBox:
34
+  #
35
+   config.vm.provider "virtualbox" do |vb|
36
+     vb.gui = false
37
+  
38
+     ## Use VBoxManage to customize the VM. For example to change memory:
39
+     #vb.customize ["modifyvm", :id, "--memory", "1024"]
40
+   end
41
+  
42
+  config.vm.provision "ansible" do |ansible|
43
+    ansible.playbook = "playbook.yml"
44
+  end
45
+
46
+end

+ 56
- 0
openframeworks-pi.yml View File

@@ -0,0 +1,56 @@
1
+---
2
+- hosts: all
3
+  remote_user: pi
4
+  sudo: yes
5
+  environment:
6
+    http_proxy: http://10.0.0.1:8888
7
+  tasks:
8
+
9
+  
10
+    # this does the equivalent of "install_dependencies.sh"
11
+    - file: path=/etc/apt/sources.list.d/gstreamer.list state=absent
12
+    - apt_repository: repo='deb http://vontaene.de/raspbian-updates/ . main' state=present update_cache=yes
13
+
14
+    - apt: name=libmpg123-dev
15
+    - apt: name=alsa-base
16
+    - apt: name=alsa-tools
17
+    - apt: name=alsa-utils
18
+    - apt: name=libupnp-dev
19
+    - apt: name=automake
20
+    - apt: name=cvs
21
+    - apt: name=libavcodec-dev
22
+    - apt: name=libavformat-dev
23
+    - apt: name=libavutil-dev
24
+    - apt: name=libswscale-dev
25
+    - apt: name=libasound2-dev
26
+    - apt: name=libxmu-dev
27
+    - apt: name=libxxf86vm-dev
28
+    - apt: name=g++
29
+    - apt: name=libgl1-mesa-dev
30
+    - apt: name=libglu1-mesa-dev
31
+    - apt: name=libraw1394-dev
32
+    - apt: name=libudev-dev
33
+    - apt: name=libdrm-dev
34
+    - apt: name=libglew-dev
35
+    - apt: name=libopenal-dev
36
+    - apt: name=libsndfile-dev
37
+    - apt: name=libfreeimage-dev
38
+    - apt: name=libcairo2-dev
39
+    - apt: name=libgtk2.0-dev
40
+    - apt: name=python-lxml
41
+    - apt: name=python-argparse
42
+    - apt: name=libfreetype6-dev
43
+    - apt: name=libassimp-dev
44
+    - apt: name=portaudio19-dev
45
+    - apt: name=libssl-dev
46
+    - apt: name=libpulse-dev
47
+    - apt: name=libgtk2.0-dev
48
+    - apt: name=libgstreamer1.0-dev
49
+    - apt: name=libgstreamer-plugins-base1.0-dev
50
+    - apt: name=gstreamer1.0-pulseaudio
51
+    - apt: name=gstreamer1.0-x
52
+    - apt: name=gstreamer1.0-plugins-bad
53
+    - apt: name=gstreamer1.0-alsa
54
+    - apt: name=gstreamer1.0-plugins-base
55
+    - apt: name=gstreamer1.0-plugins-good
56
+    - apt: name=1.0-omx

+ 60
- 0
playbook.yml View File

@@ -0,0 +1,60 @@
1
+---
2
+- hosts: all
3
+  remote_user: vagrant
4
+  sudo: yes
5
+  vars:
6
+    offset_boot: 4194304
7
+    offset_root: 62914560
8
+  tasks:
9
+    - apt: upgrade=dist
10
+    - command: mkdir -p /opt/raspberrypi creates=/opt/raspberrypi
11
+
12
+    - apt: name=nfs-kernel-server
13
+    - lineinfile: dest=/etc/exports line="/opt/raspberrypi/root 10.0.0.0/24(rw,sync,no_root_squash,no_subtree_check)"
14
+
15
+    - service: name=nfs-kernel-server state=restarted
16
+
17
+    - apt: name=build-essential
18
+    - apt: name=pkg-config
19
+    - apt: name=git
20
+    - apt: name=python-pip
21
+
22
+
23
+    - apt: name=unzip
24
+    - unarchive: src=tools-master.zip dest=/opt/raspberrypi creates=/opt/raspberrypi/tools-master
25
+
26
+    - file: path=/opt/raspberrypi/boot state=directory
27
+    - file: path=/opt/raspberrypi/root state=directory
28
+
29
+    - mount: src="/vagrant/image.img" name="/opt/raspberrypi/boot" fstype="auto"  opts="loop,offset={{offset_boot}},noauto" state="mounted"
30
+    - mount: src="/vagrant/image.img" name="/opt/raspberrypi/root" fstype="auto"  opts="loop,offset={{offset_root}},noauto" state="mounted"
31
+
32
+    # the pi is unbootable unless it is told not to mount the root filesystem from the card!
33
+    - lineinfile: dest=/opt/raspberrypi/root/etc/fstab regexp="^\/dev\/mmcblk0p2" state="absent"
34
+    - replace: dest=/opt/raspberrypi/boot/cmdline.txt regexp="rootwait$" replace="rootwait ip=10.0.0.101:10.0.0.1:10.0.0.1:255.255.255.0:rpi:eth0:off root=/dev/nfs rootfstype=nfs nfsroot=10.0.0.1:/opt/raspberrypi/root,udp,vers=3 smsc95xx.turbo_mode=N" backup=no
35
+
36
+    # build helpies
37
+    - lineinfile: dest="/home/vagrant/.bashrc" line="export RPI_TOOLS=/opt/raspberrypi/tools-master"
38
+    - lineinfile: dest="/home/vagrant/.bashrc" line="export RPI_ROOT=/opt/raspberrypi/root"
39
+    - lineinfile: dest="/home/vagrant/.bashrc" line="export PKG_CONFIG_PATH=$RPI_ROOT/usr/lib/arm-linux-gnueabihf/pkgconfig:$RPI_ROOT/usr/share/pkgconfig:$RPI_ROOT/usr/lib/pkgconfig"
40
+    - lineinfile: dest="/home/vagrant/.bashrc" line="alias rmake='make RPI_TOOLS=$RPI_TOOLS RPI_ROOT=$RPI_ROOT GST_VERSION=1.0 PLATFORM_OS=Linux PLATFORM_ARCH=armv6l'"
41
+
42
+    - git: repo=https://github.com/ansible/ansible.git dest=/opt/ansible
43
+    - apt: name=sshpass
44
+    - pip: name=paramiko
45
+    - pip: name=PyYAML
46
+    - pip: name=jinja2
47
+    - pip: name=httplib2
48
+
49
+
50
+    - unarchive: src=of_v0.8.1_linuxarmv6l_release.tar.gz dest=/opt/raspberrypi/root/opt creates=/opt/raspberrypi/root/opt/of_v0.8.1_linuxarmv6l_release
51
+    - file: src=of_v0.8.1_linuxarmv6l_release dest=/opt/raspberrypi/root/opt/openframeworks state=link
52
+    - file: src=/opt/raspberrypi/root/opt/openframeworks dest=/opt/openframeworks state=link
53
+    - command: chown -R vagrant /opt/raspberrypi/root/opt/of_v0.8.1_linuxarmv6l_release
54
+
55
+    - apt: name=tinyproxy
56
+    - lineinfile: dest="/etc/tinyproxy.conf" line="Allow 10.0.0.0/8"
57
+    - service: name=tinyproxy state=restarted
58
+
59
+  handlers:
60
+

Loading…
Cancel
Save