ab7ef87e44cb82147e4373f3b26a107c01ae0a8c
[leap_doc.git] / docs / platform / details / development.md
1 @title = "Development Environment"
2 @summary = "Setting up an environment for modifying the leap_platform."
3 @toc = true
4
5 If you are wanting to make local changes to your provider, or want to contribute some fixes back to LEAP, we recommend that you follow this guide to build up a development environment to test your changes first. Using this method, you can quickly test your changes without deploying them to your production environment, while benefitting from the convenience of reverting to known good states in order to retry things from scratch.
6
7 This page will walk you through setting up nodes using [Vagrant](http://www.vagrantup.com/) for convenient deployment testing, snapshotting known good states, and reverting to previous snapshots.
8
9 Requirements
10 ============
11
12 * A real machine with virtualization support in the CPU (VT-x or AMD-V). In other words, not a virtual machine.
13 * Have at least 4gb of RAM.
14 * Have a fast internet connection (because you will be downloading a lot of big files, like virtual machine images).
15 * You should do everything described below as an unprivileged user, and only run those commands as root that are noted with *sudo* in front of them. Other than those commands, there is no need for privileged access to your machine, and in fact things may not work correctly.
16
17 Install prerequisites
18 --------------------------------
19
20 For development purposes, you will need everything that you need for deploying the LEAP platform:
21
22 * LEAP cli
23 * A provider instance
24
25 You will also need to setup a virtualized Vagrant environment, to do so please make sure you have the following
26 pre-requisites installed:
27
28 *Debian & Ubuntu*
29
30 Install core prerequisites:
31
32     sudo apt-get install git ruby ruby-dev rsync openssh-client openssl rake make
33
34 Install Vagrant in order to be able to test with local virtual machines (typically optional, but required for this tutorial). You probably want a more recent version directly from [vagrant.](https://www.vagrantup.com/downloads.htm)
35
36     sudo apt-get install vagrant virtualbox
37
38
39 *Mac OS X 10.9 (Mavericks)*
40
41 Install Homebrew package manager from http://brew.sh/ and enable the [System Duplicates Repository](https://github.com/Homebrew/homebrew/wiki/Interesting-Taps-&-Branches) (needed to update old software versions delivered by Apple) with
42
43     brew tap homebrew/dupes
44
45 Update OpenSSH to support ECDSA keys. Follow [this guide](http://www.dctrwatson.com/2013/07/how-to-update-openssh-on-mac-os-x/) to let your system use the Homebrew binary.
46
47     brew install openssh --with-brewed-openssl --with-keychain-support
48
49 The certtool provided by Apple it's really old, install the one provided by GnuTLS and shadow the system's default.
50
51     sudo brew install gnutls
52     ln -sf /usr/local/bin/gnutls-certtool /usr/local/bin/certool
53
54 Install the Vagrant and VirtualBox packages for OS X from their respective Download pages.
55
56 * http://www.vagrantup.com/downloads.html
57 * https://www.virtualbox.org/wiki/Downloads
58
59 Verify vagrantbox download
60 --------------------------
61
62 Import LEAP archive signing key:
63
64     gpg --search-keys 0x1E34A1828E207901
65
66 now, either you already have a trustpath to it through one of the people 
67 who signed it, or you can verify this by checking this fingerprint:
68
69     gpg --fingerprint  --list-keys 1E34A1828E207901
70
71       pub   4096R/1E34A1828E207901 2013-02-06 [expires: 2015-02-07]
72             Key fingerprint = 1E45 3B2C E87B EE2F 7DFE  9966 1E34 A182 8E20 7901
73       uid                          LEAP archive signing key <sysdev@leap.se>
74
75 if the fingerprint matches, you could locally sign it so you remember the you already
76 verified it:
77
78     gpg --lsign-key 1E34A1828E207901
79
80 Then download the SHA512SUMS file and it's signature file 
81
82     wget https://downloads.leap.se/platform/SHA512SUMS.sign 
83     wget https://downloads.leap.se/platform/SHA512SUMS
84
85 and verify the signature against your local imported LEAP archive signing pubkey
86
87     gpg --verify SHA512SUMS.sign
88
89       gpg: Signature made Sat 01 Nov 2014 12:25:05 AM CET
90       gpg:                using RSA key 1E34A1828E207901
91       gpg: Good signature from "LEAP archive signing key <sysdev@leap.se>"
92
93 Make sure that the last line says "Good signature from...", which tells you that your 
94 downloaded SHA512SUMS file has the right contents!
95
96 Now you can compare the sha512sum of your downloaded vagrantbox with the one in the SHA512SUMS file:
97
98     wget https://downloads.leap.se/platform/vagrant/virtualbox/leap-wheezy.box
99     sha512sum leap-wheezy.box
100     cat SHA512SUMS
101
102
103
104 Adding development nodes to your provider
105 =========================================
106
107 Now you will add local-only Vagrant development nodes to your provider.
108
109 You do not need to setup a different provider instance for development, in fact it is more convenient if you do not, but you can if you wish.  If you do not have a provider already, you will need to create one and configure it before continuing (it is recommended you go through the [Quick Start](quick-start) before continuing down this path).
110
111
112 Create local development nodes
113 ------------------------------
114
115 We will add "local" nodes, which are special nodes that are used only for testing. These nodes exist only as virtual machines on your computer, and cannot be accessed from the outside. Each "node" is a server that can have one or more services attached to it. We recommend that you create different nodes for different services to better isolate issues.
116
117 While in your provider directory, create a local node, with the service "webapp":
118
119     $ leap node add --local web1 services:webapp
120      = created nodes/web1.json
121      = created files/nodes/web1/
122      = created files/nodes/web1/web1.key
123      = created files/nodes/web1/web1.crt
124
125 This command creates a node configuration file in `nodes/web1.json` with the webapp service.
126
127 Starting local development nodes
128 --------------------------------
129
130 In order to test the node "web1" we need to start it. Starting a node for the first time will spin up a virtual machine. The first time you do this will take some time because it will need to download a VM image (about 700mb). After you've downloaded the base image, you will not need to download it again, and instead you will re-use the downloaded image (until you need to update the image).
131
132 NOTE: Many people have difficulties getting Vagrant working. If the following commands do not work, please see the Vagrant section below to troubleshoot your Vagrant install before proceeding.
133
134     $ leap local start web1
135      = created test/
136      = created test/Vagrantfile
137      = installing vagrant plugin 'sahara'
138     Bringing machine 'web1' up with 'virtualbox' provider...
139     [web1] Box 'leap-wheezy' was not found. Fetching box from specified URL for
140     the provider 'virtualbox'. Note that if the URL does not have
141     a box for this provider, you should interrupt Vagrant now and add
142     the box yourself. Otherwise Vagrant will attempt to download the
143     full box prior to discovering this error.
144     Downloading or copying the box...
145     Progress: 3% (Rate: 560k/s, Estimated time remaining: 0:13:36)
146     ...
147     Bringing machine 'web1' up with 'virtualbox' provider...
148     [web1] Importing base box 'leap-wheezy'...
149     0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
150
151 Now the virtual machine 'web1' is running. You can add another local node using the same process. For example, the webapp node needs a databasse to run, so let's add a "couchdb" node:
152
153     $ leap node add --local db1 services:couchdb
154     $ leap local start
155      = updated test/Vagrantfile
156     Bringing machine 'db1' up with 'virtualbox' provider...
157     [db1] Importing base box 'leap-wheezy'...
158     [db1] Matching MAC address for NAT networking...
159     [db1] Setting the name of the VM...
160     [db1] Clearing any previously set forwarded ports...
161     [db1] Fixed port collision for 22 => 2222. Now on port 2202.
162     [db1] Creating shared folders metadata...
163     [db1] Clearing any previously set network interfaces...
164     [db1] Preparing network interfaces based on configuration...
165     [db1] Forwarding ports...
166     [db1] -- 22 => 2202 (adapter 1)
167     [db1] Running any VM customizations...
168     [db1] Booting VM...
169     [db1] Waiting for VM to boot. This can take a few minutes.
170     [db1] VM booted and ready for use!
171     [db1] Configuring and enabling network interfaces...
172     [db1] Mounting shared folders...
173     [db1] -- /vagrant
174
175 You now can follow the normal LEAP process and initialize it and then deploy your recipes to it:
176
177     $ leap node init web1
178     $ leap deploy web1
179     $ leap node init db1
180     $ leap deploy db1
181
182
183 Useful local development commands
184 =================================
185
186 There are many useful things you can do with a virtualized development environment.
187
188 Listing what machines are running
189 ---------------------------------
190
191 Now you have the two virtual machines "web1" and "db1" running, you can see the running machines as follows:
192
193     $ leap local status
194     Current machine states:
195
196     db1                      running (virtualbox)
197     web1                     running (virtualbox)
198
199     This environment represents multiple VMs. The VMs are all listed
200     above with their current state. For more information about a specific
201     VM, run `vagrant status NAME`.
202
203 Stopping machines
204 -----------------
205
206 It is not recommended that you leave your virtual machines running when you are not using them. They consume memory and other resources! To stop your machines, simply do the following:
207
208     $ leap local stop web1 db1
209
210 Connecting to machines
211 ----------------------
212
213 You can connect to your local nodes just like you do with normal LEAP nodes, by running 'leap ssh node'.
214
215 However, if you cannot connect to your local node, because the networking is not setup properly, or you have deployed a firewall that locks you out, you may need to access the graphical console.
216
217 In order to do that, you will need to configure Vagrant to launch a graphical console and then you can login as root there to diagnose the networking problem. To do this, add the following to your $HOME/.leaprc:
218
219     @custom_vagrant_vm_line = 'config.vm.provider "virtualbox" do |v|
220       v.gui = true
221     end'
222
223 and then start, or restart, your local Vagrant node. You should get a VirtualBox graphical interface presented to you showing you the bootup and eventually the login.
224
225 Snapshotting machines
226 ---------------------
227
228 A very useful feature of local Vagrant development nodes is the ability to snapshot the current state and then revert to that when you need.
229
230 For example, perhaps the base image is a little bit out of date and you want to get the packages updated to the latest before continuing. You can do that simply by starting the node, connecting to it and updating the packages and then snapshotting the node:
231
232     $ leap local start web1
233     $ leap ssh web1
234     web1# apt-get -u dist-upgrade
235     web1# exit
236     $ leap local save web1
237
238 Now you can deploy to web1 and if you decide you want to revert to the state before deployment, you simply have to reset the node to your previous save:
239
240     $ leap local reset web1
241
242 More information
243 ----------------
244
245 See `leap help local` for a complete list of local-only commands and how they can be used.
246
247
248 Limitations
249 ===========
250
251 Please consult the known issues for vagrant, see the [Known Issues](known-issues), section *Special Environments*
252
253
254 Other useful plugins
255 ====================
256
257 . The vagrant-cachier (plugin http://fgrehm.viewdocs.io/vagrant-cachier/) lets you cache .deb packages on your hosts so they are not downloaded by multiple machines over and over again, after resetting to a previous state.
258
259 Troubleshooting Vagrant
260 =======================
261
262 To troubleshoot vagrant issues, try going through these steps:
263
264 * Try plain vagrant using the [Getting started guide](http://docs.vagrantup.com/v2/getting-started/index.html).
265 * If that fails, make sure that you can run virtual machines (VMs) in plain virtualbox (Virtualbox GUI or VBoxHeadless).
266   We don't suggest a sepecial howto for that, [this one](http://www.thegeekstuff.com/2012/02/virtualbox-install-create-vm/) seems pretty decent, or you follow the [Oracale Virtualbox User Manual](http://www.virtualbox.org/manual/UserManual.html). There's also specific documentation for [Debian](https://wiki.debian.org/VirtualBox) and for [Ubuntu](https://help.ubuntu.com/community/VirtualBox). If you succeeded, try again if you now can start vagrant nodes using plain vagrant (see first step).
267 * If plain vagrant works for you, you're very close to using vagrant with leap ! If you encounter any problems now, please [contact us](https://leap.se/en/about-us/contact) or use our [issue tracker](https://leap.se/code)
268
269 Known working combinations
270 --------------------------
271
272 Please consider that using other combinations might work for you as well, these are just the combinations we tried and worked for us:
273
274
275 Debian Wheezy
276 -------------
277
278 * `virtualbox-4.2 4.2.16-86992~Debian~wheezy` from Oracle and `vagrant 1.2.2` from vagrantup.com
279
280
281 Ubuntu Raring 13.04
282 -------------------
283
284 * `virtualbox 4.2.10-dfsg-0ubuntu2.1` from Ubuntu raring and `vagrant 1.2.2` from vagrantup.com
285
286 Mac OS X 10.9
287 -------------
288
289 * `VirtualBox 4.3.10` from virtualbox.org and `vagrant 1.5.4` from vagrantup.com
290
291
292 Using Vagrant with libvirt/kvm
293 ==============================
294
295 Vagrant can be used with different providers/backends, one of them is [vagrant-libvirt](https://github.com/pradels/vagrant-libvirt). Here are the steps how to use it. Be sure to use a recent vagrant version for the vagrant-libvirt plugin (>= 1.5, which can only be fetched from http://www.vagrantup.com/downloads.html at this moment).
296
297 Install vagrant-libvirt plugin and add box
298 ------------------------------------------
299     sudo apt-get install libvirt-bin libvirt-dev
300     # you need to assign the new 'libvirtd' group to your user in a running x session, or logout and login again:
301     newgrp libvirtd
302     # to build the vagrant-libvirt plugin you need the following packages:
303     sudo apt-get install ruby-dev libxslt-dev libxml2-dev libvirt-dev
304     vagrant plugin install vagrant-libvirt
305     vagrant plugin install sahara
306     vagrant box add leap-wheezy https://downloads.leap.se/platform/vagrant/libvirt/leap-wheezy.box --provider libvirt
307
308 Remove Virtualbox
309 -----------------
310     sudo apt-get remove virtualbox*
311
312 Debugging
313 ---------
314
315 If you get an error in any of the above commands, try to get some debugging information, it will often tell you what is wrong. In order to get debugging logs, you simply need to re-run the command that produced the error but prepend the command with VAGRANT_LOG=info, for example:
316     VAGRANT_LOG=info vagrant box add leap-wheezy https://downloads.leap.se/platform/vagrant/libvirt/leap-wheezy.box
317
318 Start it
319 --------
320
321 Use this example Vagrantfile:
322
323     Vagrant.configure("2") do |config|
324       config.vm.define :testvm do |testvm|
325         testvm.vm.box = "leap-wheezy"
326         testvm.vm.network :private_network, :ip => '10.6.6.201'
327       end
328
329       config.vm.provider :libvirt do |libvirt|
330         libvirt.connect_via_ssh = false
331       end
332     end
333
334 Then:
335
336     vagrant up --provider=libvirt
337
338 If everything works, you should export libvirt as the VAGRANT_DEFAULT_PROVIDER:
339
340     export VAGRANT_DEFAULT_PROVIDER="libvirt"
341
342 Now you should be able to use the `leap local` commands.
343
344 Known Issues
345 ------------
346
347 * 'Call to virConnectOpen failed: internal error: Unable to locate libvirtd daemon in /usr/sbin (to override, set $LIBVIRTD_PATH to the name of the libvirtd binary)' - you don't have the libvirtd daemon running or installed, be sure you installed the 'libvirt-bin' package and it is running
348 * 'Call to virConnectOpen failed: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied' - you need to be in the libvirt group to access the socket, do 'sudo adduser <user> libvirt' and then re-login to your session
349 * if each call to vagrant ends up with a segfault, it may be because you still have virtualbox around. if so, remove virtualbox to keep only libvirt + KVM. according to https://github.com/pradels/vagrant-libvirt/issues/75 having two virtualization engines installed simultaneously can lead to such weird issues.
350 * see the [vagrant-libvirt issue list on github](https://github.com/pradels/vagrant-libvirt/issues)
351 * be sure to use vagrant-libvirt >= 0.0.11 and sahara >= 0.0.16 (which are the latest stable gems you would get with `vagrant plugin install [vagrant-libvirt|sahara]`) for proper libvirt support
352 * for shared folder support, you need nfs-kernel-server installed on the host machine and set up sudo to allow unpriviledged users to modify /etc/exports. See [vagrant-libvirt#synced-folders](https://github.com/pradels/vagrant-libvirt#synced-folders)
353
354
355     sudo apt-get install nfs-kernel-server