Merge lp:~developer-ubuntu-com-dev/developer-ubuntu-com/hero-tour-changes into lp:developer-ubuntu-com

Proposed by Daniel Holbach on 2016-03-08
Status: Merged
Approved by: David Callé on 2016-03-22
Approved revision: 227
Merged at revision: 197
Proposed branch: lp:~developer-ubuntu-com-dev/developer-ubuntu-com/hero-tour-changes
Merge into: lp:developer-ubuntu-com
Prerequisite: lp:~dholbach/developer-ubuntu-com/importer-post-deployment-fixes
Diff against target: 1977 lines (+1602/-25)
29 files modified
developer_portal/settings.py (+1/-0)
md_importer/importer/__init__.py (+6/-0)
md_importer/importer/article.py (+7/-3)
md_importer/importer/process.py (+3/-1)
md_importer/importer/publish.py (+14/-7)
md_importer/importer/repo.py (+22/-10)
md_importer/migrations/0002_hero_tour_changes.py (+24/-0)
md_importer/models.py (+21/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-macos.md (+77/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-ubuntu.md (+49/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-windows.md (+53/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-macos.md (+74/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-ubuntu.md (+46/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-windows.md (+50/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-macos.md (+73/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-ubuntu.md (+73/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-windows.md (+73/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-macos.md (+74/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-ubuntu.md (+46/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-windows.md (+50/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step3-get-familiar.md (+212/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step4-first-snap.md (+8/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step5-further-readings.md (+3/-0)
md_importer/tests/data/website-test/out/get-started/as-dev/index.html (+63/-0)
md_importer/tests/test_branch_import.py (+66/-0)
md_importer/tests/test_link_rewrite.py (+4/-2)
md_importer/tests/test_website_import.py (+72/-0)
md_importer/tests/utils.py (+4/-2)
templates/snappy_hero_tour.html (+334/-0)
To merge this branch: bzr merge lp:~developer-ubuntu-com-dev/developer-ubuntu-com/hero-tour-changes
Reviewer Review Type Date Requested Status
David Callé 2016-03-08 Needs Fixing on 2016-03-22
Review via email: mp+288401@code.launchpad.net

This proposal supersedes a proposal from 2016-03-08.

Description of the Change

### Template ###

Template details for testing purposes:

The template currently assumes the following snappy page tree, where all the pages starting from "ubuntu-core-developers-tour" are using the "Snappy Hero Tour" template.

snappy
    get-started
        ubuntu-core-developers-tour
            16-04 (redirect to ubuntu-core-developers-tour)
                step2-<host>-<target> (eg. step2-ubuntu-raspi2)
                step3-*
                step4-*
                step5-*
            15-10 (redirect to ubuntu-core-developers-tour)
                step2-*
                step3-*
                step4-*
                step5-*

The template provides a shell for content, this content is CMS editable and/or imported via the md importer.

Examples:
- http://i.imgur.com/WlMcMeH.png
- http://i.imgur.com/awWXsrp.png

The ubuntu-core-developers-tour page needs to contain specific data for tour navigation to work as intended:
- The snappy version selector needs name="version"
- Each radio input needs name="host" (for host choices) or name="target" (for board choices)

V0 of the tour landing page: http://paste.ubuntu.com/15328791/

To post a comment you must log in.
219. By David Callé on 2016-03-08

Add first iteration of the snappy hero tour

220. By Daniel Holbach on 2016-03-09

fix unicode craziness

221. By Daniel Holbach on 2016-03-09

extend db_add_empty_page do you can define your own slug

222. By Daniel Holbach on 2016-03-10

add tests for hero tour IA

223. By Daniel Holbach on 2016-03-21

merge trunk

224. By Daniel Holbach on 2016-03-22

merge trunk

David Callé (davidc3) wrote :

Everything looks and tests are very nice!

Except this failing one:

======================================================================
FAIL: runTest (md_importer.tests.test_link_rewrite.TestLinkRewrite)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/david/dev/duc/mtotrunk_mar16/developer-ubuntu-com/md_importer/tests/test_link_rewrite.py", line 37, in runTest
    self.assertEqual(link.attrs['href'], '/file2')
AssertionError: u'/en/file2/' != '/file2'

review: Needs Fixing
David Callé (davidc3) wrote :

looks good*

Daniel Holbach (dholbach) wrote :

Ran 32 tests in 153.276s

OK

225. By Daniel Holbach on 2016-03-22

adapt url expectation to a crash David was seeing

226. By Daniel Holbach on 2016-03-22

make pep8/pyflakes happy

227. By Daniel Holbach on 2016-03-22

apply fix from David - thanks

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'developer_portal/settings.py'
2--- developer_portal/settings.py 2016-02-19 10:14:32 +0000
3+++ developer_portal/settings.py 2016-03-22 10:52:56 +0000
4@@ -185,6 +185,7 @@
5 ('landing_page.html', 'Landing Page'),
6 ('no_subnav.html', 'Without Subnav'),
7 ('with_hero.html', 'With Hero'),
8+ ('snappy_hero_tour.html', 'Snappy Hero Tour'),
9 )
10
11 LOCALE_PATHS = (
12
13=== modified file 'md_importer/importer/__init__.py'
14--- md_importer/importer/__init__.py 2016-02-29 14:20:41 +0000
15+++ md_importer/importer/__init__.py 2016-03-22 10:52:56 +0000
16@@ -1,5 +1,7 @@
17 from developer_portal.settings import LANGUAGE_CODE
18
19+from md_importer.models import ExternalDocsBranchImportDirective
20+
21 DEFAULT_LANG = LANGUAGE_CODE
22 HOME_PAGE_URL = '/{}/'.format(DEFAULT_LANG)
23 SUPPORTED_ARTICLE_TYPES = ['.md', '.html']
24@@ -15,3 +17,7 @@
25 'pymdownx.tasklist',
26 'pymdownx.superfences',
27 ]
28+
29+model_info = ExternalDocsBranchImportDirective._meta
30+TEMPLATE_CHOICES = model_info.get_field('template').choices
31+DEFAULT_TEMPLATE = model_info.get_field('template').default
32
33=== modified file 'md_importer/importer/article.py'
34--- md_importer/importer/article.py 2016-03-02 11:13:43 +0000
35+++ md_importer/importer/article.py 2016-03-22 10:52:56 +0000
36@@ -20,7 +20,7 @@
37
38
39 class Article:
40- def __init__(self, fn, write_to):
41+ def __init__(self, fn, write_to, advertise, template):
42 self.html = None
43 self.page = None
44 self.title = ""
45@@ -30,6 +30,8 @@
46 self.slug = os.path.basename(self.full_url)
47 self.links_rewritten = False
48 self.local_images = []
49+ self.advertise = advertise
50+ self.template = template
51
52 def _find_local_images(self):
53 '''Local images are currently not supported.'''
54@@ -116,7 +118,8 @@
55 '''Publishes pages in their branch alias namespace.'''
56 self.page = get_or_create_page(
57 title=self.title, full_url=self.full_url, menu_title=self.title,
58- html=self.html)
59+ html=self.html, in_navigation=self.advertise,
60+ template=self.template)
61 if not self.page:
62 return False
63 self.full_url = re.sub(
64@@ -127,7 +130,8 @@
65 def publish(self):
66 if self.links_rewritten:
67 update_page(self.page, title=self.title, full_url=self.full_url,
68- menu_title=self.title, html=self.html)
69+ menu_title=self.title, html=self.html,
70+ in_navigation=self.advertise, template=self.template)
71 if self.page.is_dirty(DEFAULT_LANG):
72 self.page.publish(DEFAULT_LANG)
73 if self.page.get_public_object():
74
75=== modified file 'md_importer/importer/process.py'
76--- md_importer/importer/process.py 2016-01-16 00:36:39 +0000
77+++ md_importer/importer/process.py 2016-03-22 10:52:56 +0000
78@@ -22,7 +22,9 @@
79 for directive in ExternalDocsBranchImportDirective.objects.filter(
80 external_docs_branch=branch):
81 repo.add_directive(directive.import_from,
82- directive.write_to)
83+ directive.write_to,
84+ directive.advertise,
85+ directive.template)
86 if not repo.execute_import_directives():
87 return False
88 if not repo.publish():
89
90=== modified file 'md_importer/importer/publish.py'
91--- md_importer/importer/publish.py 2016-02-29 14:25:52 +0000
92+++ md_importer/importer/publish.py 2016-03-22 10:52:56 +0000
93@@ -1,4 +1,8 @@
94-from md_importer.importer import DEFAULT_LANG, HOME_PAGE_URL
95+from md_importer.importer import (
96+ DEFAULT_LANG,
97+ DEFAULT_TEMPLATE,
98+ HOME_PAGE_URL,
99+)
100
101 from cms.api import create_page, add_plugin
102 from cms.models import Title
103@@ -51,7 +55,7 @@
104
105
106 def update_page(page, title, full_url, menu_title=None,
107- in_navigation=True, redirect=None, html=None):
108+ in_navigation=True, redirect=None, html=None, template=None):
109 if page.get_title() != title:
110 page.title = title
111 if page.get_menu_title() != menu_title:
112@@ -60,6 +64,8 @@
113 page.in_navigation = in_navigation
114 if page.get_redirect() != redirect:
115 page.redirect = redirect
116+ if page.template != template:
117+ page.template = template
118 if html:
119 update = True
120 (placeholder, plugin) = find_text_plugin(page)
121@@ -85,23 +91,24 @@
122
123
124 def get_or_create_page(title, full_url, menu_title=None,
125- in_navigation=True, redirect=None, html=None):
126+ in_navigation=True, redirect=None, html=None,
127+ template=DEFAULT_TEMPLATE):
128 # First check if pages already exist.
129 pages = Title.objects.select_related('page').filter(
130 path__regex=full_url).filter(publisher_is_draft=True)
131 if pages:
132 page = pages[0].page
133 update_page(page, title, full_url, menu_title, in_navigation,
134- redirect, html)
135+ redirect, html, template)
136 else:
137 parent = _find_parent(full_url)
138 if not parent:
139 return None
140 slug = os.path.basename(full_url)
141 page = create_page(
142- title, 'default.html', DEFAULT_LANG, slug=slug, parent=parent,
143- menu_title=menu_title, in_navigation=in_navigation,
144+ title=title, template=template, language=DEFAULT_LANG, slug=slug,
145+ parent=parent, menu_title=menu_title, in_navigation=in_navigation,
146 position='last-child', redirect=redirect)
147- placeholder = page.placeholders.get()
148+ placeholder = page.placeholders.all()[0]
149 add_plugin(placeholder, 'RawHtmlPlugin', DEFAULT_LANG, body=html)
150 return page
151
152=== modified file 'md_importer/importer/repo.py'
153--- md_importer/importer/repo.py 2016-01-28 17:23:38 +0000
154+++ md_importer/importer/repo.py 2016-03-22 10:52:56 +0000
155@@ -6,6 +6,8 @@
156 from .publish import get_or_create_page, slugify
157 from .source import SourceCode
158
159+from md_importer.models import ExternalDocsBranchImportDirective
160+
161 import glob
162 import logging
163 import os
164@@ -56,12 +58,18 @@
165 return 1
166 return 0
167
168- def add_directive(self, import_from, write_to):
169+ def add_directive(self, import_from, write_to, advertise=True,
170+ template=None):
171+ if template is None:
172+ model_info = ExternalDocsBranchImportDirective._meta
173+ template = model_info.get_field('template').default
174 self.directives += [
175 {
176 'import_from': os.path.join(self.checkout_location,
177 import_from),
178- 'write_to': write_to
179+ 'write_to': write_to,
180+ 'advertise': advertise,
181+ 'template': template,
182 }
183 ]
184
185@@ -71,7 +79,8 @@
186 for directive in [d for d in self.directives
187 if os.path.isfile(d['import_from'])]:
188 import_list += [
189- (directive['import_from'], directive['write_to'])
190+ (directive['import_from'], directive['write_to'],
191+ directive['advertise'], directive['template'])
192 ]
193 # Import directories next
194 for directive in [d for d in self.directives
195@@ -79,7 +88,8 @@
196 for fn in glob.glob('{}/*'.format(directive['import_from'])):
197 if fn not in [a[0] for a in import_list]:
198 import_list += [
199- (fn, os.path.join(directive['write_to'], slugify(fn)))
200+ (fn, os.path.join(directive['write_to'], slugify(fn)),
201+ directive['advertise'], directive['template'])
202 ]
203 # If we import into a namespace and don't have an index doc,
204 # we need to write one.
205@@ -91,7 +101,8 @@
206 return False
207 # The actual import
208 for entry in import_list:
209- article = self._read_article(entry[0], entry[1])
210+ article = self._read_article(
211+ entry[0], entry[1], entry[2], entry[3])
212 if article:
213 self.imported_articles += [article]
214 self.titles[article.fn] = article.title
215@@ -106,8 +117,8 @@
216 self._write_fake_index_doc()
217 return True
218
219- def _read_article(self, fn, write_to):
220- article = self.article_class(fn, write_to)
221+ def _read_article(self, fn, write_to, advertise, template):
222+ article = self.article_class(fn, write_to, advertise, template)
223 if article.read():
224 return article
225 return None
226@@ -142,12 +153,13 @@
227 return True
228
229 def _write_fake_index_doc(self):
230- list_pages = ''
231+ list_pages = u''
232 for article in [a for a
233 in self.imported_articles
234 if a.full_url.startswith(self.index_doc_url)]:
235- list_pages += '<li><a href=\"{}\">{}</a></li>'.format(
236- os.path.basename(article.full_url), article.title)
237+ list_pages += u'<li><a href=\"{}\">{}</a></li>'.format(
238+ unicode(os.path.basename(article.full_url)),
239+ article.title)
240 self.index_page.html = (
241 u'<div class=\"row\"><div class=\"eight-col\">\n'
242 '<p>This section contains documentation for the '
243
244=== added file 'md_importer/migrations/0002_hero_tour_changes.py'
245--- md_importer/migrations/0002_hero_tour_changes.py 1970-01-01 00:00:00 +0000
246+++ md_importer/migrations/0002_hero_tour_changes.py 2016-03-22 10:52:56 +0000
247@@ -0,0 +1,24 @@
248+# -*- coding: utf-8 -*-
249+from __future__ import unicode_literals
250+
251+from django.db import migrations, models
252+
253+
254+class Migration(migrations.Migration):
255+
256+ dependencies = [
257+ ('md_importer', '0001_initial'),
258+ ]
259+
260+ operations = [
261+ migrations.AddField(
262+ model_name='externaldocsbranchimportdirective',
263+ name='advertise',
264+ field=models.BooleanField(default=True, help_text='Should the imported articles be listed in the navigation? Default: yes.'),
265+ ),
266+ migrations.AddField(
267+ model_name='externaldocsbranchimportdirective',
268+ name='template',
269+ field=models.CharField(default=b'default.html', help_text='Django CMS template to use for the imported articles. Default: default.html', max_length=50, choices=[(b'default.html', b'Default'), (b'landing_page.html', b'Landing Page'), (b'no_subnav.html', b'Without Subnav'), (b'with_hero.html', b'With Hero')]),
270+ ),
271+ ]
272
273=== modified file 'md_importer/models.py'
274--- md_importer/models.py 2016-01-11 08:10:08 +0000
275+++ md_importer/models.py 2016-03-22 10:52:56 +0000
276@@ -1,9 +1,18 @@
277+from django.conf import settings
278 from django.db import models
279 from django.utils.translation import ugettext_lazy as _
280
281 from cms.models import Page
282
283
284+if settings.CMS_TEMPLATES:
285+ cms_templates = settings.CMS_TEMPLATES
286+else:
287+ cms_templates = (
288+ ('default.html', 'Default'),
289+ )
290+
291+
292 class ExternalDocsBranch(models.Model):
293 origin = models.CharField(
294 max_length=200,
295@@ -43,6 +52,18 @@
296 help_text=_('Article URL (for a specific file) or article namespace '
297 'for a directory or a set of files.'),
298 blank=True)
299+ advertise = models.BooleanField(
300+ default=True,
301+ help_text=_('Should the imported articles be listed in the '
302+ 'navigation? Default: yes.'),
303+ )
304+ template = models.CharField(
305+ max_length=50,
306+ default=cms_templates[0][0],
307+ choices=cms_templates,
308+ help_text=_('Django CMS template to use for the imported articles. '
309+ 'Default: {}'.format(cms_templates[0][0])),
310+ )
311
312 def __str__(self):
313 return "{} -- {}".format(self.external_docs_branch,
314
315=== added directory 'md_importer/tests/data/website-test'
316=== added directory 'md_importer/tests/data/website-test/out'
317=== added directory 'md_importer/tests/data/website-test/out/get-started'
318=== added directory 'md_importer/tests/data/website-test/out/get-started/as-dev'
319=== added directory 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04'
320=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-macos.md'
321--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-macos.md 1970-01-01 00:00:00 +0000
322+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-macos.md 2016-03-22 10:52:56 +0000
323@@ -0,0 +1,77 @@
324+# Setting up your Beaglebone Black
325+
326+![Beaglebone Black image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/beaglebone.png "Beaglebone Black image")
327+
328+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your Beaglebone Black and copy it to an SD card. You can then get started with your project!
329+
330+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
331+
332+## Downloading and installing
333+
334+1. Start by **downloading the Ubuntu Core image** for Beaglebone Black in your current folder.
335+```sh
336+curl -O http://people.canonical.com/~mvo/all-snaps/bbb-all-snap.img.xz
337+```
338+
339+1. **Extract** the downloaded zip file into your Downloads folder by double clicking on it. You should now have an uncompressed file named bbb-all-snap.img.
340+> You might have to install archive extractor software, like [The Unarchiver](https://itunes.apple.com/gb/app/the-unarchiver/id425424353?mt=12) or similar as the standard tools do not support xz
341+
342+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before running the commands below.
343+
344+1. **Determine which disk to write to and inmount it**.
345+ * Run
346+```sh
347+diskutil list
348+```
349+ In the results identify your SD card, it will probably an entry like the one below:
350+```sh
351+/dev/disk0
352+ #: TYPE NAME SIZE IDENTIFIER
353+ 0: GUID_partition_scheme *500.3 GB disk0
354+/dev/disk2
355+ #: TYPE NAME SIZE IDENTIFIER
356+ 0: Apple_HFS Macintosh HD *428.8 GB disk1
357+ Logical Volume on disk0s2
358+ E2E7C215-99E4-486D-B3CC-DAB8DF9E9C67
359+ Unlocked Encrypted
360+/dev/disk3
361+ #: TYPE NAME SIZE IDENTIFIER
362+ 0: FDisk_partition_scheme *7.9 GB disk3
363+ 1: DOS_FAT_32 NO NAME 7.9 GB disk3s1
364+```
365+ > Note that your SD Card must be DOS_FAT_32 formatted. The SIZE will be the size of your SD card, in this example an 8GB SD Card.
366+
367+ Write down the number after /dev/disk that is associated with your SD card, in this case 3.
368+
369+ * Unmount your SD card by entering the command:
370+ `diskutil unmountDisk /dev/diskX` where X is the number you just wrote down. When successful you should see a message similar to this one: *Unmount of all volumes on diskX was successful*.
371+
372+1. **Copy your downloaded image to the SD card**. Note that you need to specify the path to the disk device with the number you just wrote down in previous step.
373+```sh
374+sudo dd if=~/Downloads/bbb-all-snap.img of=/dev/diskX bs=32MB
375+sync
376+```
377+You will be prompted to enter your Apple password after this command.
378+
379+ > Note that this operation length can vary depending on your SD card speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
380+
381+1. **Eject** the SD card physically from your Mac and **insert it** in your Beaglebone Black.
382+
383+## First boot to Ubuntu Core 16.04
384+
385+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
386+
387+Power on your Beaglebone Black and wait a couple of minutes for the OS to complete its first boot.
388+
389+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
390+http://webdm.local:4200.
391+
392+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
393+
394+Since we require our own boot loader in order to be fully compatible with Snappy, it's recommended to remove the bootloader available in the eMMC partition:
395+* On first boot (or each boot if you don't want to erase the bootloader available at the eMMC), you can also force it to boot to the sd card by pressing the user/boot switch button before powering up the device.
396+* Then, to remove the bootloader in the eMMC partition, you can run the following command on you Ubuntu Core system: `sudo dd if=/dev/zero of=/dev/mmcblk1 bs=1024 count=1024`
397+
398+
399+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
400+install some snaps to it!
401
402=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-ubuntu.md'
403--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-ubuntu.md 1970-01-01 00:00:00 +0000
404+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-ubuntu.md 2016-03-22 10:52:56 +0000
405@@ -0,0 +1,49 @@
406+# Setting up your Beaglebone Black
407+
408+![Beaglebone Black image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/beaglebone.png "Beaglebone Black image")
409+
410+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your Beaglebone Black and copy it to an SD card. You can then get started with your project!
411+
412+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
413+
414+## Downloading and installing
415+
416+1. Start by **downloading the Ubuntu Core image** for Beaglebone Black in your current folder.
417+```sh
418+wget http://people.canonical.com/~mvo/all-snaps/bbb-all-snap.img.xz
419+```
420+Once the download is finished, you’ll have a zip file named bbb-all-snap.img.xz.
421+
422+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before performing next steps below.
423+
424+1. **Unmount it**: if your SD card is mounted when you insert it into your computer (you will know it if the file manager automatically opens a window showing the card's contents), you must manually unmount it before writing the snappy image to it. Either eject your SD card from the file manager, or from the command line: `sudo umount /media/$USER/`
425+
426+1. **Copy your downloaded image to the SD card**. You must specify the path to the disk device representing your SD card in the dd command below. Common device paths for the SD card disk device are either of the form **/dev/sdX** (such as **/dev/sdb**, not /dev/sdb1!) or **/dev/mmcblk0** (not /dev/mmcblk0p1!)
427+```sh
428+xzcat bbb-all-snap.img.xz | sudo dd of=/dev/sdX bs=32M
429+sync
430+```
431+ You will be prompted to enter your password after this command.
432+
433+ > Note that this operation length can vary depending on your SD card speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
434+
435+1. **Eject** the SD card physically from your PC and **insert it** in your Beaglebone Black.
436+
437+## First boot to Ubuntu Core 16.04
438+
439+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
440+
441+Power on your Beaglebone Black and wait a couple of minutes for the OS to complete its first boot.
442+
443+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
444+http://webdm.local:4200.
445+
446+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
447+
448+Since we require our own boot loader in order to be fully compatible with Snappy, it's recommended to remove the bootloader available in the eMMC partition:
449+* On first boot (or each boot if you don't want to erase the bootloader available at the eMMC), you can also force it to boot to the sd card by pressing the user/boot switch button before powering up the device.
450+* Then, to remove the bootloader in the eMMC partition, you can run the following command on you Ubuntu Core system: `sudo dd if=/dev/zero of=/dev/mmcblk1 bs=1024 count=1024`
451+
452+
453+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
454+install some snaps to it!
455
456=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-windows.md'
457--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-windows.md 1970-01-01 00:00:00 +0000
458+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-beaglebone-windows.md 2016-03-22 10:52:56 +0000
459@@ -0,0 +1,53 @@
460+# Setting up your Beaglebone Black
461+
462+![Beaglebone Black image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/beaglebone.png "Beaglebone Black image")
463+
464+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your Beaglebone Black and copy it to an SD card. You can then get started with your project!
465+
466+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
467+
468+## Downloading and installing
469+
470+1. Start by **downloading the Ubuntu Core image** for Beaglebone Black in your **Downloads** folder from [this link](http://people.canonical.com/~mvo/all-snaps/bbb-all-snap.img.xz).
471+Once the download is finished, you’ll have a zip file named bbb-all-snap.img.xz.
472+
473+1. **Extract** the downloaded zip file into your Downloads folder. You should now have an uncompressed file named bbb-all-snap.img.
474+> You might have to install archive extractor software, like [7-zip](http://www.7-zip.org/) or similar as the standard tools do not support xz
475+
476+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before performing next steps below.
477+
478+1. **Copy your downloaded image to the SD card**. Install and launch [Win32DiskImager](http://sourceforge.net/projects/win32diskimager/files/latest/download).
479+ > Find out where what drive your SD card is mounted to. Open a File Explorer window to check which drive your SD card is listed under. Here is an example of a card listed under **E:** and the setup in Diskimager.
480+
481+ ![Windows drives](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/windows-drives.png)
482+
483+ Win32DiskImager will need 2 elements:
484+ * *An Image File* which is the file you want to copy on your SD Card. Navigate to your *Downloads* folder and select the bbb-all-snap.img image you have just extracted.
485+ * *A Device* which is the location of your SD card. Select the Drive in which your SD card is mounted.
486+
487+ ![Win32DiskImager image selection](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/windows-diskimager-setup.png)
488+
489+ > To be safe, unplug every External USB Drive you may have connected to your PC.
490+
491+ When ready click on Write and wait for the process to complete.
492+
493+1. Exit from Win32DiskImager. **Eject** the SD card from the File Explorer window and **insert it** in your Beaglebone Black.
494+
495+## First boot to Ubuntu Core 16.04
496+
497+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
498+
499+Power on your Beaglebone Black and wait a couple of minutes for the OS to complete its first boot.
500+
501+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
502+http://webdm.local:4200.
503+
504+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
505+
506+Since we require our own boot loader in order to be fully compatible with Snappy, it's recommended to remove the bootloader available in the eMMC partition:
507+* On first boot (or each boot if you don't want to erase the bootloader available at the eMMC), you can also force it to boot to the sd card by pressing the user/boot switch button before powering up the device.
508+* Then, to remove the bootloader in the eMMC partition, you can run the following command on you Ubuntu Core system: `sudo dd if=/dev/zero of=/dev/mmcblk1 bs=1024 count=1024`
509+
510+
511+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
512+install some snaps to it!
513
514=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-macos.md'
515--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-macos.md 1970-01-01 00:00:00 +0000
516+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-macos.md 2016-03-22 10:52:56 +0000
517@@ -0,0 +1,74 @@
518+# Setting up your DragonBoard
519+
520+![DragonBoard image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/dragonboard.png "DragonBoard image")
521+
522+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your DragonBoard and copy it to an SD card. You can then get started with your project!
523+
524+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
525+
526+## Downloading and installing
527+
528+1. Start by **downloading the Ubuntu Core image** for DragonBoard in your current folder.
529+```sh
530+curl -O http://people.canonical.com/~ogra/snappy/all-snaps/dragonboard/dragon-all-snap.img.xz
531+```
532+
533+1. **Extract** the downloaded zip file into your Downloads folder by double clicking on it. You should now have an uncompressed file named dragon-all-snap.img.
534+> You might have to install archive extractor software, like [The Unarchiver](https://itunes.apple.com/gb/app/the-unarchiver/id425424353?mt=12) or similar as the standard tools do not support xz
535+
536+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before running the commands below.
537+
538+1. **Determine which disk to write to and inmount it**.
539+ * Run
540+```sh
541+diskutil list
542+```
543+ In the results identify your SD card, it will probably an entry like the one below:
544+```sh
545+/dev/disk0
546+ #: TYPE NAME SIZE IDENTIFIER
547+ 0: GUID_partition_scheme *500.3 GB disk0
548+/dev/disk2
549+ #: TYPE NAME SIZE IDENTIFIER
550+ 0: Apple_HFS Macintosh HD *428.8 GB disk1
551+ Logical Volume on disk0s2
552+ E2E7C215-99E4-486D-B3CC-DAB8DF9E9C67
553+ Unlocked Encrypted
554+/dev/disk3
555+ #: TYPE NAME SIZE IDENTIFIER
556+ 0: FDisk_partition_scheme *7.9 GB disk3
557+ 1: DOS_FAT_32 NO NAME 7.9 GB disk3s1
558+```
559+ > Note that your SD Card must be DOS_FAT_32 formatted. The SIZE will be the size of your SD card, in this example an 8GB SD Card.
560+
561+ Write down the number after /dev/disk that is associated with your SD card, in this case 3.
562+
563+ * Unmount your SD card by entering the command:
564+ `diskutil unmountDisk /dev/diskX` where X is the number you just wrote down. When successful you should see a message similar to this one: *Unmount of all volumes on diskX was successful*.
565+
566+1. **Copy your downloaded image to the SD card**. Note that you need to specify the path to the disk device with the number you just wrote down in previous step.
567+```sh
568+sudo dd if=~/Downloads/dragon-all-snap.img of=/dev/diskX bs=32MB
569+sync
570+```
571+You will be prompted to enter your Apple password after this command.
572+
573+ > Note that this operation length can vary depending on your SD card speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
574+
575+1. **Eject** the SD card physically from your Mac and **insert it** in your DragonBoard.
576+
577+## First boot to Ubuntu Core 16.04
578+
579+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
580+
581+Power on your DragonBoard and wait a couple of minutes for the OS to complete its first boot.
582+
583+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
584+http://webdm.local:4200.
585+
586+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
587+
588+<<ADDITIONAL_FIRST_BOOT_NOTES>>
589+
590+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
591+install some snaps to it!
592
593=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-ubuntu.md'
594--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-ubuntu.md 1970-01-01 00:00:00 +0000
595+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-ubuntu.md 2016-03-22 10:52:56 +0000
596@@ -0,0 +1,46 @@
597+# Setting up your DragonBoard
598+
599+![DragonBoard image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/dragonboard.png "DragonBoard image")
600+
601+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your DragonBoard and copy it to an SD card. You can then get started with your project!
602+
603+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
604+
605+## Downloading and installing
606+
607+1. Start by **downloading the Ubuntu Core image** for DragonBoard in your current folder.
608+```sh
609+wget http://people.canonical.com/~ogra/snappy/all-snaps/dragonboard/dragon-all-snap.img.xz
610+```
611+Once the download is finished, you’ll have a zip file named dragon-all-snap.img.xz.
612+
613+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before performing next steps below.
614+
615+1. **Unmount it**: if your SD card is mounted when you insert it into your computer (you will know it if the file manager automatically opens a window showing the card's contents), you must manually unmount it before writing the snappy image to it. Either eject your SD card from the file manager, or from the command line: `sudo umount /media/$USER/`
616+
617+1. **Copy your downloaded image to the SD card**. You must specify the path to the disk device representing your SD card in the dd command below. Common device paths for the SD card disk device are either of the form **/dev/sdX** (such as **/dev/sdb**, not /dev/sdb1!) or **/dev/mmcblk0** (not /dev/mmcblk0p1!)
618+```sh
619+xzcat dragon-all-snap.img.xz | sudo dd of=/dev/sdX bs=32M
620+sync
621+```
622+ You will be prompted to enter your password after this command.
623+
624+ > Note that this operation length can vary depending on your SD card speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
625+
626+1. **Eject** the SD card physically from your PC and **insert it** in your DragonBoard.
627+
628+## First boot to Ubuntu Core 16.04
629+
630+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
631+
632+Power on your DragonBoard and wait a couple of minutes for the OS to complete its first boot.
633+
634+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
635+http://webdm.local:4200.
636+
637+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
638+
639+<<ADDITIONAL_FIRST_BOOT_NOTES>>
640+
641+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
642+install some snaps to it!
643
644=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-windows.md'
645--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-windows.md 1970-01-01 00:00:00 +0000
646+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-dragonboard-windows.md 2016-03-22 10:52:56 +0000
647@@ -0,0 +1,50 @@
648+# Setting up your DragonBoard
649+
650+![DragonBoard image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/dragonboard.png "DragonBoard image")
651+
652+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your DragonBoard and copy it to an SD card. You can then get started with your project!
653+
654+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
655+
656+## Downloading and installing
657+
658+1. Start by **downloading the Ubuntu Core image** for DragonBoard in your **Downloads** folder from [this link](http://people.canonical.com/~ogra/snappy/all-snaps/dragonboard/dragon-all-snap.img.xz).
659+Once the download is finished, you’ll have a zip file named dragon-all-snap.img.xz.
660+
661+1. **Extract** the downloaded zip file into your Downloads folder. You should now have an uncompressed file named dragon-all-snap.img.
662+> You might have to install archive extractor software, like [7-zip](http://www.7-zip.org/) or similar as the standard tools do not support xz
663+
664+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before performing next steps below.
665+
666+1. **Copy your downloaded image to the SD card**. Install and launch [Win32DiskImager](http://sourceforge.net/projects/win32diskimager/files/latest/download).
667+ > Find out where what drive your SD card is mounted to. Open a File Explorer window to check which drive your SD card is listed under. Here is an example of a card listed under **E:** and the setup in Diskimager.
668+
669+ ![Windows drives](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/windows-drives.png)
670+
671+ Win32DiskImager will need 2 elements:
672+ * *An Image File* which is the file you want to copy on your SD Card. Navigate to your *Downloads* folder and select the dragon-all-snap.img image you have just extracted.
673+ * *A Device* which is the location of your SD card. Select the Drive in which your SD card is mounted.
674+
675+ ![Win32DiskImager image selection](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/windows-diskimager-setup.png)
676+
677+ > To be safe, unplug every External USB Drive you may have connected to your PC.
678+
679+ When ready click on Write and wait for the process to complete.
680+
681+1. Exit from Win32DiskImager. **Eject** the SD card from the File Explorer window and **insert it** in your DragonBoard.
682+
683+## First boot to Ubuntu Core 16.04
684+
685+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
686+
687+Power on your DragonBoard and wait a couple of minutes for the OS to complete its first boot.
688+
689+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
690+http://webdm.local:4200.
691+
692+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
693+
694+<<ADDITIONAL_FIRST_BOOT_NOTES>>
695+
696+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
697+install some snaps to it!
698
699=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-macos.md'
700--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-macos.md 1970-01-01 00:00:00 +0000
701+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-macos.md 2016-03-22 10:52:56 +0000
702@@ -0,0 +1,73 @@
703+# Setting up your Intel® NUC
704+
705+![Intel® NUC image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/Thin_Canyon_NUC_Front_Angle_Board.png "Intel® NUC image")
706+
707+Installing Snappy Ubuntu Core on your Intel® NUC, only takes 3 steps and a 2G USB key:
708+1. Install a live version of Ubuntu Classic on a USB key.
709+1. Boot on your Intel® NUC from the live USB key.
710+1. Install Ubuntu Core onto Intel® NUC disk from the live session.
711+And you can get started with your project!
712+
713+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
714+
715+## Create an Ubuntu live disk from Mac
716+
717+Visit [this link](http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-mac-osx) for all the instructions on how to create an Ubuntu live disk.
718+
719+## Installing from Live disk
720+
721+Now that you have your Live Disk USB key, we will install the Ubuntu Core image after booting that Live Disk.
722+
723+### Preparing the NUC (if using internal ROM as disk)
724+> Note that this step is only necessary in case you want to install Ubuntu Core on the 4GB eMMC Built-In Storage.
725+If you wired an ssd disk to your NUC, this section can be skipped.
726+1. Start your NUC by pressing the On button while pressing F2 during the boot up, this will open the BIOS settings.
727+1. On the initial screen, access the "advanced" tab and press to access the "Devices and Peripherals" Tab.
728+1. On the "Devices and Peripherals" menu, under the "On board devices" submenu, make sure that the emmc checkbox ("4GB emmc Built-in Storage") is checked.
729+ > If you didn't find this option, this means that you need to update your NUC BIOS to latest version. For this, you can follow online instructions on the [Intel website](http://www.intel.com/content/www/us/en/support/boards-and-kits/000005850.html).
730+1. In the "Boot" menu, "Secure boot" submenu, make sure that the "secure boot" is not checked.
731+
732+
733+### Booting from the Live CD
734+
735+1. Insert the USB key with the Ubuntu live distribution
736+1. Start you Intel® NUC and push **F10** to enter the boot menu.
737+1. Select the USB key as boot option.
738+1. Choose **"Try Ubuntu without installing”**.
739+
740+### Installing Ubuntu Core onto your Intel® NUC
741+
742+Once the Live distro is running, open a terminal with the key combination Ctrl+Alt+t.
743+
744+1. Start by **downloading the Ubuntu Core image** for Intel® NUC in your current folder.
745+```sh
746+wget http://people.canonical.com/~platform/snappy/ubuntu-core-15.04-intel-nuc.img.xz
747+```
748+Once the download is finished, you’ll have a zip file named ubuntu-core-15.04-intel-nuc.img.xz.
749+
750+1. **Copy your downloaded image to the disk**. You must specify the path to the disk device representing your disk in the dd command below. Common device paths for the ssd disks are of the form **/dev/sdX** (such as **/dev/sda**, not /dev/sda1!). Please note that if you want to use the eMMC instead of an internal ssd drive, replace **/dev/sdX** by **/dev/mmcblk0** which refers to the eMMC option.
751+
752+```sh
753+xzcat ubuntu-core-15.04-intel-nuc.img.xz | sudo dd of=/dev/sdX bs=32M
754+sync
755+```
756+
757+ > Note that this operation length can vary depending on your disk speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
758+
759+1. ​You can now **reboot** your Intel® NUC
760+
761+## First boot to Ubuntu Core 16.04
762+
763+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
764+
765+Power on your Intel® NUC and wait a couple of minutes for the OS to complete its first boot.
766+
767+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
768+http://webdm.local:4200.
769+
770+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
771+
772+<<ADDITIONAL_FIRST_BOOT_NOTES>>
773+
774+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
775+install some snaps to it!
776
777=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-ubuntu.md'
778--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-ubuntu.md 1970-01-01 00:00:00 +0000
779+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-ubuntu.md 2016-03-22 10:52:56 +0000
780@@ -0,0 +1,73 @@
781+# Setting up your Intel® NUC
782+
783+![Intel® NUC image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/Thin_Canyon_NUC_Front_Angle_Board.png "Intel® NUC image")
784+
785+Installing Snappy Ubuntu Core on your Intel® NUC, only takes 3 steps and a 2G USB key:
786+1. Install a live version of Ubuntu Classic on a USB key.
787+1. Boot on your Intel® NUC from the live USB key.
788+1. Install Ubuntu Core onto Intel® NUC disk from the live session.
789+And you can get started with your project!
790+
791+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
792+
793+## Create an Ubuntu live disk from Ubuntu
794+
795+Visit [this link](http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-ubuntu) for all the instructions on how to create an Ubuntu live disk.
796+
797+## Installing from Live disk
798+
799+Now that you have your Live Disk USB key, we will install the Ubuntu Core image after booting that Live Disk.
800+
801+### Preparing the NUC (if using internal ROM as disk)
802+> Note that this step is only necessary in case you want to install Ubuntu Core on the 4GB eMMC Built-In Storage.
803+If you wired an ssd disk to your NUC, this section can be skipped.
804+1. Start your NUC by pressing the On button while pressing F2 during the boot up, this will open the BIOS settings.
805+1. On the initial screen, access the "advanced" tab and press to access the "Devices and Peripherals" Tab.
806+1. On the "Devices and Peripherals" menu, under the "On board devices" submenu, make sure that the emmc checkbox ("4GB emmc Built-in Storage") is checked.
807+ > If you didn't find this option, this means that you need to update your NUC BIOS to latest version. For this, you can follow online instructions on the [Intel website](http://www.intel.com/content/www/us/en/support/boards-and-kits/000005850.html).
808+1. In the "Boot" menu, "Secure boot" submenu, make sure that the "secure boot" is not checked.
809+
810+
811+### Booting from the Live CD
812+
813+1. Insert the USB key with the Ubuntu live distribution
814+1. Start you Intel® NUC and push **F10** to enter the boot menu.
815+1. Select the USB key as boot option.
816+1. Choose **"Try Ubuntu without installing”**.
817+
818+### Installing Ubuntu Core onto your Intel® NUC
819+
820+Once the Live distro is running, open a terminal with the key combination Ctrl+Alt+t.
821+
822+1. Start by **downloading the Ubuntu Core image** for Intel® NUC in your current folder.
823+```sh
824+wget http://people.canonical.com/~platform/snappy/ubuntu-core-15.04-intel-nuc.img.xz
825+```
826+Once the download is finished, you’ll have a zip file named ubuntu-core-15.04-intel-nuc.img.xz.
827+
828+1. **Copy your downloaded image to the disk**. You must specify the path to the disk device representing your disk in the dd command below. Common device paths for the ssd disks are of the form **/dev/sdX** (such as **/dev/sda**, not /dev/sda1!). Please note that if you want to use the eMMC instead of an internal ssd drive, replace **/dev/sdX** by **/dev/mmcblk0** which refers to the eMMC option.
829+
830+```sh
831+xzcat ubuntu-core-15.04-intel-nuc.img.xz | sudo dd of=/dev/sdX bs=32M
832+sync
833+```
834+
835+ > Note that this operation length can vary depending on your disk speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
836+
837+1. ​You can now **reboot** your Intel® NUC
838+
839+## First boot to Ubuntu Core 16.04
840+
841+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
842+
843+Power on your Intel® NUC and wait a couple of minutes for the OS to complete its first boot.
844+
845+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
846+http://webdm.local:4200.
847+
848+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
849+
850+<<ADDITIONAL_FIRST_BOOT_NOTES>>
851+
852+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
853+install some snaps to it!
854
855=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-windows.md'
856--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-windows.md 1970-01-01 00:00:00 +0000
857+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-intel-nuc-windows.md 2016-03-22 10:52:56 +0000
858@@ -0,0 +1,73 @@
859+# Setting up your Intel® NUC
860+
861+![Intel® NUC image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/Thin_Canyon_NUC_Front_Angle_Board.png "Intel® NUC image")
862+
863+Installing Snappy Ubuntu Core on your Intel® NUC, only takes 3 steps and a 2G USB key:
864+1. Install a live version of Ubuntu Classic on a USB key.
865+1. Boot on your Intel® NUC from the live USB key.
866+1. Install Ubuntu Core onto Intel® NUC disk from the live session.
867+And you can get started with your project!
868+
869+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
870+
871+## Create an Ubuntu live disk from Windows
872+
873+Visit [this link](http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-windows) for all the instructions on how to create an Ubuntu live disk.
874+
875+## Installing from Live disk
876+
877+Now that you have your Live Disk USB key, we will install the Ubuntu Core image after booting that Live Disk.
878+
879+### Preparing the NUC (if using internal ROM as disk)
880+> Note that this step is only necessary in case you want to install Ubuntu Core on the 4GB eMMC Built-In Storage.
881+If you wired an ssd disk to your NUC, this section can be skipped.
882+1. Start your NUC by pressing the On button while pressing F2 during the boot up, this will open the BIOS settings.
883+1. On the initial screen, access the "advanced" tab and press to access the "Devices and Peripherals" Tab.
884+1. On the "Devices and Peripherals" menu, under the "On board devices" submenu, make sure that the emmc checkbox ("4GB emmc Built-in Storage") is checked.
885+ > If you didn't find this option, this means that you need to update your NUC BIOS to latest version. For this, you can follow online instructions on the [Intel website](http://www.intel.com/content/www/us/en/support/boards-and-kits/000005850.html).
886+1. In the "Boot" menu, "Secure boot" submenu, make sure that the "secure boot" is not checked.
887+
888+
889+### Booting from the Live CD
890+
891+1. Insert the USB key with the Ubuntu live distribution
892+1. Start you Intel® NUC and push **F10** to enter the boot menu.
893+1. Select the USB key as boot option.
894+1. Choose **"Try Ubuntu without installing”**.
895+
896+### Installing Ubuntu Core onto your Intel® NUC
897+
898+Once the Live distro is running, open a terminal with the key combination Ctrl+Alt+t.
899+
900+1. Start by **downloading the Ubuntu Core image** for Intel® NUC in your current folder.
901+```sh
902+wget http://people.canonical.com/~platform/snappy/ubuntu-core-15.04-intel-nuc.img.xz
903+```
904+Once the download is finished, you’ll have a zip file named ubuntu-core-15.04-intel-nuc.img.xz.
905+
906+1. **Copy your downloaded image to the disk**. You must specify the path to the disk device representing your disk in the dd command below. Common device paths for the ssd disks are of the form **/dev/sdX** (such as **/dev/sda**, not /dev/sda1!). Please note that if you want to use the eMMC instead of an internal ssd drive, replace **/dev/sdX** by **/dev/mmcblk0** which refers to the eMMC option.
907+
908+```sh
909+xzcat ubuntu-core-15.04-intel-nuc.img.xz | sudo dd of=/dev/sdX bs=32M
910+sync
911+```
912+
913+ > Note that this operation length can vary depending on your disk speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
914+
915+1. ​You can now **reboot** your Intel® NUC
916+
917+## First boot to Ubuntu Core 16.04
918+
919+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
920+
921+Power on your Intel® NUC and wait a couple of minutes for the OS to complete its first boot.
922+
923+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
924+http://webdm.local:4200.
925+
926+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
927+
928+<<ADDITIONAL_FIRST_BOOT_NOTES>>
929+
930+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
931+install some snaps to it!
932
933=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-macos.md'
934--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-macos.md 1970-01-01 00:00:00 +0000
935+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-macos.md 2016-03-22 10:52:56 +0000
936@@ -0,0 +1,74 @@
937+# Setting up your Raspberry Pi 2
938+
939+![Raspberry Pi 2 image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/raspberry-pi.png "Raspberry Pi 2 image")
940+
941+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your Raspberry Pi 2 and copy it to an SD card. You can then get started with your project!
942+
943+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
944+
945+## Downloading and installing
946+
947+1. Start by **downloading the Ubuntu Core image** for Raspberry Pi 2 in your current folder.
948+```sh
949+curl -O http://people.canonical.com/~mvo/all-snaps/rpi2-all-snap.img.xz
950+```
951+
952+1. **Extract** the downloaded zip file into your Downloads folder by double clicking on it. You should now have an uncompressed file named rpi2-all-snap.img.
953+> You might have to install archive extractor software, like [The Unarchiver](https://itunes.apple.com/gb/app/the-unarchiver/id425424353?mt=12) or similar as the standard tools do not support xz
954+
955+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before running the commands below.
956+
957+1. **Determine which disk to write to and inmount it**.
958+ * Run
959+```sh
960+diskutil list
961+```
962+ In the results identify your SD card, it will probably an entry like the one below:
963+```sh
964+/dev/disk0
965+ #: TYPE NAME SIZE IDENTIFIER
966+ 0: GUID_partition_scheme *500.3 GB disk0
967+/dev/disk2
968+ #: TYPE NAME SIZE IDENTIFIER
969+ 0: Apple_HFS Macintosh HD *428.8 GB disk1
970+ Logical Volume on disk0s2
971+ E2E7C215-99E4-486D-B3CC-DAB8DF9E9C67
972+ Unlocked Encrypted
973+/dev/disk3
974+ #: TYPE NAME SIZE IDENTIFIER
975+ 0: FDisk_partition_scheme *7.9 GB disk3
976+ 1: DOS_FAT_32 NO NAME 7.9 GB disk3s1
977+```
978+ > Note that your SD Card must be DOS_FAT_32 formatted. The SIZE will be the size of your SD card, in this example an 8GB SD Card.
979+
980+ Write down the number after /dev/disk that is associated with your SD card, in this case 3.
981+
982+ * Unmount your SD card by entering the command:
983+ `diskutil unmountDisk /dev/diskX` where X is the number you just wrote down. When successful you should see a message similar to this one: *Unmount of all volumes on diskX was successful*.
984+
985+1. **Copy your downloaded image to the SD card**. Note that you need to specify the path to the disk device with the number you just wrote down in previous step.
986+```sh
987+sudo dd if=~/Downloads/rpi2-all-snap.img of=/dev/diskX bs=32MB
988+sync
989+```
990+You will be prompted to enter your Apple password after this command.
991+
992+ > Note that this operation length can vary depending on your SD card speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
993+
994+1. **Eject** the SD card physically from your Mac and **insert it** in your Raspberry Pi 2.
995+
996+## First boot to Ubuntu Core 16.04
997+
998+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
999+
1000+Power on your Raspberry Pi 2 and wait a couple of minutes for the OS to complete its first boot.
1001+
1002+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
1003+http://webdm.local:4200.
1004+
1005+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
1006+
1007+<<ADDITIONAL_FIRST_BOOT_NOTES>>
1008+
1009+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
1010+install some snaps to it!
1011
1012=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-ubuntu.md'
1013--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-ubuntu.md 1970-01-01 00:00:00 +0000
1014+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-ubuntu.md 2016-03-22 10:52:56 +0000
1015@@ -0,0 +1,46 @@
1016+# Setting up your Raspberry Pi 2
1017+
1018+![Raspberry Pi 2 image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/raspberry-pi.png "Raspberry Pi 2 image")
1019+
1020+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your Raspberry Pi 2 and copy it to an SD card. You can then get started with your project!
1021+
1022+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
1023+
1024+## Downloading and installing
1025+
1026+1. Start by **downloading the Ubuntu Core image** for Raspberry Pi 2 in your current folder.
1027+```sh
1028+wget http://people.canonical.com/~mvo/all-snaps/rpi2-all-snap.img.xz
1029+```
1030+Once the download is finished, you’ll have a zip file named rpi2-all-snap.img.xz.
1031+
1032+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before performing next steps below.
1033+
1034+1. **Unmount it**: if your SD card is mounted when you insert it into your computer (you will know it if the file manager automatically opens a window showing the card's contents), you must manually unmount it before writing the snappy image to it. Either eject your SD card from the file manager, or from the command line: `sudo umount /media/$USER/`
1035+
1036+1. **Copy your downloaded image to the SD card**. You must specify the path to the disk device representing your SD card in the dd command below. Common device paths for the SD card disk device are either of the form **/dev/sdX** (such as **/dev/sdb**, not /dev/sdb1!) or **/dev/mmcblk0** (not /dev/mmcblk0p1!)
1037+```sh
1038+xzcat rpi2-all-snap.img.xz | sudo dd of=/dev/sdX bs=32M
1039+sync
1040+```
1041+ You will be prompted to enter your password after this command.
1042+
1043+ > Note that this operation length can vary depending on your SD card speed. There is no progress displayed unless you send SIGINFO signal pressing Ctrl+T.
1044+
1045+1. **Eject** the SD card physically from your PC and **insert it** in your Raspberry Pi 2.
1046+
1047+## First boot to Ubuntu Core 16.04
1048+
1049+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
1050+
1051+Power on your Raspberry Pi 2 and wait a couple of minutes for the OS to complete its first boot.
1052+
1053+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
1054+http://webdm.local:4200.
1055+
1056+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
1057+
1058+<<ADDITIONAL_FIRST_BOOT_NOTES>>
1059+
1060+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
1061+install some snaps to it!
1062
1063=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-windows.md'
1064--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-windows.md 1970-01-01 00:00:00 +0000
1065+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step2-setup-rpi2-windows.md 2016-03-22 10:52:56 +0000
1066@@ -0,0 +1,50 @@
1067+# Setting up your Raspberry Pi 2
1068+
1069+![Raspberry Pi 2 image](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/devices/raspberry-pi.png "Raspberry Pi 2 image")
1070+
1071+From your desktop computer, you can download and install a pre-built Snappy Ubuntu Core 16.04 image for your Raspberry Pi 2 and copy it to an SD card. You can then get started with your project!
1072+
1073+> Make sure your board is connected to the same network as your computer to manage Ubuntu Core remotely via SSH, or has a screen and keyboard attached if you prefer managing Ubuntu Core directly on the board.
1074+
1075+## Downloading and installing
1076+
1077+1. Start by **downloading the Ubuntu Core image** for Raspberry Pi 2 in your **Downloads** folder from [this link](http://people.canonical.com/~mvo/all-snaps/rpi2-all-snap.img.xz).
1078+Once the download is finished, you’ll have a zip file named rpi2-all-snap.img.xz.
1079+
1080+1. **Extract** the downloaded zip file into your Downloads folder. You should now have an uncompressed file named rpi2-all-snap.img.
1081+> You might have to install archive extractor software, like [7-zip](http://www.7-zip.org/) or similar as the standard tools do not support xz
1082+
1083+1. **Insert your SD card**. Ensure there is no data you care about on the SD card before performing next steps below.
1084+
1085+1. **Copy your downloaded image to the SD card**. Install and launch [Win32DiskImager](http://sourceforge.net/projects/win32diskimager/files/latest/download).
1086+ > Find out where what drive your SD card is mounted to. Open a File Explorer window to check which drive your SD card is listed under. Here is an example of a card listed under **E:** and the setup in Diskimager.
1087+
1088+ ![Windows drives](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/windows-drives.png)
1089+
1090+ Win32DiskImager will need 2 elements:
1091+ * *An Image File* which is the file you want to copy on your SD Card. Navigate to your *Downloads* folder and select the rpi2-all-snap.img image you have just extracted.
1092+ * *A Device* which is the location of your SD card. Select the Drive in which your SD card is mounted.
1093+
1094+ ![Win32DiskImager image selection](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/windows-diskimager-setup.png)
1095+
1096+ > To be safe, unplug every External USB Drive you may have connected to your PC.
1097+
1098+ When ready click on Write and wait for the process to complete.
1099+
1100+1. Exit from Win32DiskImager. **Eject** the SD card from the File Explorer window and **insert it** in your Raspberry Pi 2.
1101+
1102+## First boot to Ubuntu Core 16.04
1103+
1104+> Note that the first boot can be longer than usual as your primary disk is repartioned to take all available free space.
1105+
1106+Power on your Raspberry Pi 2 and wait a couple of minutes for the OS to complete its first boot.
1107+
1108+You can then access your snappy Ubuntu Core system by loading the webdm interface from your browser. Just point it to
1109+http://webdm.local:4200.
1110+
1111+![Webdm vanilla interface](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm.png)
1112+
1113+<<ADDITIONAL_FIRST_BOOT_NOTES>>
1114+
1115+Congrats, you just installed your new Snappy Ubuntu Core 16.04 system. It's now time to explore it and
1116+install some snaps to it!
1117
1118=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step3-get-familiar.md'
1119--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step3-get-familiar.md 1970-01-01 00:00:00 +0000
1120+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step3-get-familiar.md 2016-03-22 10:52:56 +0000
1121@@ -0,0 +1,212 @@
1122+# Install your first snap package!
1123+
1124+It is now time to transform your Snappy Ubuntu Core system in an awesome arcade game machine!
1125+You can easily install any snap through the webdm store UI.
1126+
1127+> If you retrieved the ip in the previous step, replace **webdm.local** by the **ip address** you noted before.
1128+
1129+## The webdm store
1130+
1131+Ensure you have a tab opened on the **Snappy store** tab
1132+or visit directly http://webdm.local:4200/store.
1133+
1134+![Webdm store](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/setup/webdm-store.png)
1135+
1136+You will see there all available snaps for your release version. Note that the store can be branded differently and
1137+have access to all or partial snaps list depending on the device you are playing with. This configuration is available
1138+to board makers when then enable a new device with Snappy Ubuntu Core.
1139+
1140+## Install snake!
1141+
1142+Let's try to install your first package by simply clicking on **Install** next to *snake*. Once this is done, open a new
1143+browser tab and head over http://webdm.local:9999/.
1144+
1145+![Snake snap](https://raw.githubusercontent.com/ubuntu-core/snappy-dev-website/master/src/img/first-snap-snake.png)
1146+
1147+It's high time for you to perform new ground breaking records!
1148+
1149+Installing (and removing) new snaps is that easy! Extend your system in a breath and get your router to perform your home
1150+backups, monitoring and even regulating your average home temperature!
1151+
1152+Of course, we have options for having this preinstalled when building a factory image and there is also a command line tool
1153+available to perform similar operations.
1154+
1155+# Getting a shell access to your board
1156+
1157+You can then access your snappy Ubuntu Core system either directly with a keyboard and display connected, or through SSH:
1158+```sh
1159+ssh ubuntu@webdm.local
1160+```
1161+
1162+The default *password* is **ubuntu**.
1163+
1164+As soon as you get a prompt similar to `ubuntu@webdm.local:~$`, you are good to go!
1165+
1166+> Note that if you have multiple Ubuntu Core systems on the same network, the webdm.local aliases can conflict.
1167+In that case, you need to retrieve the ip address of the machine by connecting the keyboard/display combo to it.
1168+Once logged in, just use: `ifconfig` and note the ip address. You can then connect to your board via `sh ubuntu@<ip_address>`.
1169+
1170+# Basic instructions for snappy as a developer
1171+
1172+Let's dive into your Ubuntu Core system and see how it feels to get things done the Snappy way!
1173+
1174+You need to be logged in to your Ubuntu Core instance to try these commands, they won't work on a traditional apt-get or
1175+deb-based Ubuntu system!
1176+
1177+## Differences with a traditional Ubuntu distribution
1178+
1179+### Read-only system
1180+
1181+Let's check that most of system files (apart from user and snaps data) are read-only, which is what ensure integrity on your system.
1182+
1183+```sh
1184+$ sudo touch /foo
1185+touch: cannot touch '/foo': Read-only file system
1186+```
1187+
1188+-> we couldn't write in **/** even as root (sudo)!
1189+
1190+### No apt-get or debs installs
1191+
1192+Ubuntu Core is based on the traditional Ubuntu system, deb-based. However, we don't let in the main partition apt and debs
1193+mixed with snaps, as this will break our transaction and updates story.
1194+```sh
1195+$ apt-get update
1196+Ubuntu Core does not use apt-get, see 'snappy --help'!
1197+$ dpkg -l
1198+dpkg: error: unable to execute dpkg-query (dpkg-query): No such file or directory
1199+```
1200+
1201+## Version, channels and default installed snaps
1202+
1203+We interact with Ubuntu Core via the **snappy** command. Let's check which version of Ubuntu Core we are on:
1204+```sh
1205+$ snappy info
1206+release: core/16.04/stable
1207+architecture: amd64
1208+apps: snake
1209+```
1210+
1211+This is a pristine system, freshly installed with only the snake apps installed. The "release" tells you that you are running
1212+the latest Ubuntu Core's stable release, which is the recommended [image channel](https://developer.ubuntu.com/en/snappy/guides/channels/)
1213+for starting with Snappy.
1214+
1215+Let's see which snaps are installed:
1216+```sh
1217+$ snappy list
1218+Name Date Version Developer
1219+canonical-pc 2016-02-02 3.0 canonical
1220+canonical-pc-linux 2016-02-22 4.4.0-6-1 canonical
1221+ubuntu-core 2016-03-08 16.04.0-24 canonical
1222+snake 2016-02-17 1.0 mectors
1223+```
1224+
1225+Each systems have at least 3 snaps installed (the first 3 in our list):
1226+* The base system layer (ubuntu-core)
1227+* The kernel snap (canonical-pc-linux)
1228+* The gadget snap, with some specific configuration to your device (canonical-pc)
1229+
1230+## Updating your system
1231+
1232+The good news is that the system will update in the background and reboot automatically! You can easily see if updates
1233+are available via:
1234+```sh
1235+$ snappy list -u
1236+Name Date Version
1237+canonical-pc 2016-02-02 3.0
1238+ubuntu-core* 2016-03-08 16.04.0-24
1239+snake 2016-02-17 1.0 mectors
1240+```
1241+
1242+Do you note (*) next to ubuntu-core? This means a new update is available and that the kernel is probably already downloading on your system!
1243+
1244+You will simply run it once it's downloaded (the message `Reboot to use ubuntu-core version 16.04.0-25` would appear on
1245+any `snappy list` command) and after performing a reboot (`sudo reboot`). You can check using the verbose list mode that
1246+two base system snaps are present on the system:
1247+```sh
1248+$ snappy list -v
1249+Name Date Version Developer
1250+canonical-pc 2016-02-02 3.0 canonical*
1251+canonical-pc-linux 2016-02-22 4.4.0-6-1 canonical*
1252+ubuntu-core 2016-03-08 16.04.0-24 canonical
1253+ubuntu-core 2016-03-09 16.04.0-25 canonical*
1254+snake 2016-02-17 1.0 mectors*
1255+```
1256+
1257+The active flag (*) tells you that this version of the component is what is currently running. Here ubuntu-core 16.04.0-25. Only one snap of a given name can be active at a time. Older snap versions are garbage collected after a while.
1258+
1259+## Installing a package from the store
1260+
1261+It's time to search and install a second app snaps from the store!
1262+```sh
1263+$ snap find hello
1264+Name Version Summary
1265+hello-dbus-app.canonical 1.0.2 hello-dbus-app
1266+hello-dbus-fwk.canonical 1.0.2 hello-dbus-fwk
1267+hello-world.canonical 16.04-3 hello-world
1268+hello-world.elopio 1.0.20 hello-world
1269+hello-world.mvo 2.0 hello-world
1270+```
1271+
1272+Let's install the canonical one:
1273+```sh
1274+$ sudo snap install hello-world.canonical
1275+```
1276+
1277+The **hello-world** snap is now part of this system!
1278+
1279+## Running snap-provided command on your system
1280+
1281+Contrary to the **snake** snap, which provided a service app activated at boot, the **hello-world** snap provides multiple commands. Those are available under the *<snap_package>.<command_name>* scheme.
1282+
1283+For instance, let's run the *echo* command:
1284+```sh
1285+$ hello-world.echo
1286+Hello World!
1287+```
1288+
1289+It works! Remember that one of the key concepts of Snappy Ubuntu Core is security, and that snaps can't have access to the whole system and perform evil actions:
1290+```sh
1291+$ hello-world.evil
1292+Hello Evil World!
1293+This example demonstrates the app confinement
1294+You should see a permission denied error next
1295+/snaps/hello-world.canonical/5.0/bin/evil: 9: /snaps/hello-world.canonical/5.0/bin/evil: cannot create /var/tmp/myevil.txt: Permission denied
1296+```
1297+
1298+Phew, that was close! Finally, let's check which environments variables are accessible to our snap commands:
1299+```sh
1300+$ hello-world.env | grep SNAP
1301+SNAP_APP_PATH=/snaps/hello-world.canonical/5.0
1302+SNAP_ORIGIN=canonical
1303+SNAP_APP_USER_DATA_PATH=/home/ubuntu/snaps/hello-world.canonical/5.0
1304+SNAP_FULLNAME=hello-world.canonical
1305+SNAP_USER_DATA=/home/ubuntu/snaps/hello-world.canonical/5.0
1306+SNAP_DATA=/var/lib/snaps/hello-world.canonical/5.0
1307+SNAPP_APP_TMPDIR=/tmp
1308+SNAP_NAME=hello-world
1309+SNAP_APP_TMPDIR=/tmp
1310+SNAP_OLD_PWD=/home/ubuntu
1311+SNAP_ARCH=amd64
1312+SNAP_VERSION=5.0
1313+SNAP=/snaps/hello-world.canonical/5.0
1314+SNAP_DATA=/var/lib/snaps/hello-world.canonical/5.0
1315+```
1316+
1317+**SNAP_DATA** and **SNAP_USER_DATA** are the writable directories for your snaps. Your application and services will always start with **SNAP_DATA** as your current directory.
1318+
1319+> Note that those variables are versioned. When you update your snap, the content will be **copied** under a new directory. This is what enables the `snap rollback` functionality, ensuring that you get back to an older version without having to care about data format compatibility!
1320+
1321+## Uninstalling an snap
1322+
1323+Unsurprisingly, removing a snap is just:
1324+```sh
1325+$ sudo snap remove hello-world.canonical
1326+```
1327+
1328+This removes this snap and all older snaps
1329+
1330+> Note that this doesn't remove snap associated data that we previously mentioned. It means you can reinstall your snap and get access to the same data! `sudo snap purge hello-world.canonical` will though.
1331+
1332+You are now an expert developer on Snappy Ubuntu Core! It's now time to get to the most interesting
1333+part for you: building and testing your own first snap package!
1334
1335=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step4-first-snap.md'
1336--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step4-first-snap.md 1970-01-01 00:00:00 +0000
1337+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step4-first-snap.md 2016-03-22 10:52:56 +0000
1338@@ -0,0 +1,8 @@
1339+# This is how to setup your dev environment with snapcraft
1340+
1341+Enable classic mode
1342+installing snapcraft on it and such…
1343+This part will be imported from snapcraft doc
1344+# This is how we build the first snap
1345+
1346+And this will be imported as well from snapcraft doc
1347
1348=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step5-further-readings.md'
1349--- md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step5-further-readings.md 1970-01-01 00:00:00 +0000
1350+++ md_importer/tests/data/website-test/out/get-started/as-dev/16.04/step5-further-readings.md 2016-03-22 10:52:56 +0000
1351@@ -0,0 +1,3 @@
1352+# Awesome page for celebrating things!
1353+
1354+Bla bli blou
1355
1356=== added file 'md_importer/tests/data/website-test/out/get-started/as-dev/index.html'
1357--- md_importer/tests/data/website-test/out/get-started/as-dev/index.html 1970-01-01 00:00:00 +0000
1358+++ md_importer/tests/data/website-test/out/get-started/as-dev/index.html 2016-03-22 10:52:56 +0000
1359@@ -0,0 +1,63 @@
1360+<div class="row no-border no-padding-bottom">
1361+<div class="twelve-col">
1362+<div class="twelve-col equal-height">
1363+<div class="two-col">
1364+<h4>I want to run</h4>
1365+</div>
1366+
1367+<div class="ten-col last-col"><select name="version"><option value="16-04">Latest Ubuntu Core (16.04)</option><option value="15-10">Ubuntu Core 15.10</option> </select></div>
1368+
1369+<div class="two-col">
1370+<h4>I am using:</h4>
1371+</div>
1372+
1373+<div class="two-col"><label><input checked="checked" name="host" type="radio" value="ubuntu" /> Ubuntu</label></div>
1374+
1375+<div class="two-col"><label><input name="host" type="radio" value="macos" /> Mac OS</label></div>
1376+
1377+<div class="two-col"><label><input name="host" type="radio" value="windows" /> Windows</label></div>
1378+</div>
1379+
1380+<div class="twelve-col">
1381+<h4>Ubuntu Core is supported on a wide variety on platform. We advise you to start with one of the following to get immediately the zen of the Ubuntu Core snappy experience!</h4>
1382+</div>
1383+
1384+<div class="twelve-col equal-height">
1385+<div class="three-col box"><label><input checked="checked" name="target" type="radio" value="rpi2" /> Raspberry Pi 2 (armhf)<br />
1386+<img src="http://i.imgur.com/sis6nSF.jpg" /> </label></div>
1387+
1388+<div class="three-col box"><label><input name="target" type="radio" value="intel-nuc" /> Intel NUC&trade; (amd64)<br />
1389+<img src="http://i.imgur.com/dgloAX6.jpg" /> </label></div>
1390+
1391+<div class="three-col box"><label><input name="target" type="radio" value="artik" /> Artik 5/Artik 10 (armhf)<br />
1392+<img src="http://i.imgur.com/YY4NxB2.jpg" /> </label></div>
1393+
1394+<div class="three-col box last-col"><label><input name="target" type="radio" value="dragonboard" /> DragonBoard (arm64)<br />
1395+<img src="http://i.imgur.com/YY4NxB2.jpg" /> </label></div>
1396+</div>
1397+
1398+<div class="twelve-col">
1399+<h4>We are also available on:</h4>
1400+</div>
1401+
1402+<div class="twelve-col equal-height">
1403+<div class="four-col box"><label><input name="target" type="radio" value="kvm" /> KVM (virtual machine)<br />
1404+<img src="http://i.imgur.com/sis6nSF.jpg" /> </label></div>
1405+
1406+<div class="four-col box"><label><input name="target" type="radio" value="bare-metal" /> Bare metal x86 devices<br />
1407+<img src="http://i.imgur.com/dgloAX6.jpg" /> </label></div>
1408+
1409+<div class="four-col box last-col"><label><input name="target" type="radio" value="beaglebone" /> BeagleBone<br />
1410+<img src="http://i.imgur.com/YY4NxB2.jpg" /> </label></div>
1411+
1412+<div class="four-col box"><label><input name="target" type="radio" value="azure" /> Microsoft Azure cloud<br />
1413+<img src="http://i.imgur.com/YY4NxB2.jpg" /> </label></div>
1414+
1415+<div class="four-col box"><label><input name="target" type="radio" value="gce" /> Google Cloud Engine<br />
1416+<img src="http://i.imgur.com/YY4NxB2.jpg" /> </label></div>
1417+
1418+<div class="four-col box last-col"><label><input name="target" type="radio" value="ecs" /> Amazon Elastic Compute Cloud<br />
1419+<img src="http://i.imgur.com/YY4NxB2.jpg" /> </label></div>
1420+</div>
1421+</div>
1422+</div>
1423
1424=== modified file 'md_importer/tests/test_branch_import.py'
1425--- md_importer/tests/test_branch_import.py 2016-03-01 14:01:01 +0000
1426+++ md_importer/tests/test_branch_import.py 2016-03-22 10:52:56 +0000
1427@@ -4,8 +4,13 @@
1428
1429 from cms.models import Page
1430
1431+from md_importer.importer import (
1432+ DEFAULT_TEMPLATE,
1433+ TEMPLATE_CHOICES,
1434+)
1435 from md_importer.importer.article import Article
1436 from md_importer.importer.publish import find_text_plugin
1437+
1438 from .utils import TestLocalBranchImport
1439
1440
1441@@ -100,6 +105,38 @@
1442 self.assertIsNotNone(page.get_slug())
1443
1444
1445+class TestAdvertiseImport(TestLocalBranchImport):
1446+ '''Check if all imported articles are advertised in the navigation when
1447+ using defaults.'''
1448+ def runTest(self):
1449+ self.create_repo('data/snapcraft-test')
1450+ self.repo.add_directive('docs', '')
1451+ self.assertTrue(self.repo.execute_import_directives())
1452+ for article in self.repo.imported_articles:
1453+ self.assertTrue(article.advertise)
1454+ self.assertTrue(self.repo.publish())
1455+ for page in Page.objects.filter(publisher_is_draft=False):
1456+ if page.parent is not None:
1457+ self.assertEqual(page.parent_id, self.root.id)
1458+ self.assertTrue(page.in_navigation)
1459+
1460+
1461+class TestNoAdvertiseImport(TestLocalBranchImport):
1462+ '''Check if all imported articles are advertised in the navigation when
1463+ using defaults.'''
1464+ def runTest(self):
1465+ self.create_repo('data/snapcraft-test')
1466+ self.repo.add_directive('docs', '', advertise=False)
1467+ self.assertTrue(self.repo.execute_import_directives())
1468+ for article in self.repo.imported_articles:
1469+ self.assertFalse(article.advertise)
1470+ self.assertTrue(self.repo.publish())
1471+ for page in Page.objects.filter(publisher_is_draft=False):
1472+ if page.parent is not None:
1473+ self.assertEqual(page.parent_id, self.root.id)
1474+ self.assertFalse(page.in_navigation)
1475+
1476+
1477 class TestTwiceImport(TestLocalBranchImport):
1478 '''Run import on the same contents twice, make sure we don't
1479 add new pages over and over again.'''
1480@@ -150,3 +187,32 @@
1481 if page != self.root:
1482 (dummy, plugin) = find_text_plugin(page)
1483 self.assertGreater(now, plugin.changed_date)
1484+
1485+
1486+class TestImportNoTemplateChange(TestLocalBranchImport):
1487+ '''Check if all imported articles use the default template.'''
1488+ def runTest(self):
1489+ self.create_repo('data/snapcraft-test')
1490+ self.repo.add_directive('docs', '')
1491+ self.assertTrue(self.repo.execute_import_directives())
1492+ for article in self.repo.imported_articles:
1493+ self.assertEqual(article.template, DEFAULT_TEMPLATE)
1494+ self.assertTrue(self.repo.publish())
1495+ for page in Page.objects.filter(publisher_is_draft=False):
1496+ if page.parent is not None:
1497+ self.assertEqual(page.template, DEFAULT_TEMPLATE)
1498+
1499+
1500+class TestImportTemplateChange(TestLocalBranchImport):
1501+ '''Check if all imported articles use the desired template.'''
1502+ def runTest(self):
1503+ self.create_repo('data/snapcraft-test')
1504+ template_to_use = TEMPLATE_CHOICES[1][0]
1505+ self.repo.add_directive('docs', '', template=template_to_use)
1506+ self.assertTrue(self.repo.execute_import_directives())
1507+ for article in self.repo.imported_articles:
1508+ self.assertEqual(article.template, template_to_use)
1509+ self.assertTrue(self.repo.publish())
1510+ for page in Page.objects.filter(publisher_is_draft=False):
1511+ if page.parent is not None:
1512+ self.assertEqual(page.template, template_to_use)
1513
1514=== modified file 'md_importer/tests/test_link_rewrite.py'
1515--- md_importer/tests/test_link_rewrite.py 2016-03-01 14:01:01 +0000
1516+++ md_importer/tests/test_link_rewrite.py 2016-03-22 10:52:56 +0000
1517@@ -2,6 +2,7 @@
1518
1519 from cms.models import Page
1520
1521+from ..importer import DEFAULT_LANG
1522 from ..importer.article import Article
1523 from .utils import (
1524 db_add_empty_page,
1525@@ -34,7 +35,9 @@
1526 for link in soup.find_all('a'):
1527 if not link.has_attr('class') or \
1528 'headeranchor-link' not in link.attrs['class']:
1529- self.assertEqual(link.attrs['href'], '/file2')
1530+ self.assertIn(
1531+ link.attrs['href'],
1532+ ['/file2', '/{}/file2/'.format(DEFAULT_LANG)])
1533
1534
1535 class TestLinkBrokenRewrite(TestLocalBranchImport):
1536@@ -70,7 +73,6 @@
1537 self.repo.add_directive('docs', 'snappy/build-apps/current')
1538 self.assertTrue(self.repo.execute_import_directives())
1539 self.assertTrue(self.repo.publish())
1540- pages = Page.objects.all()
1541 for article in self.repo.imported_articles:
1542 self.assertTrue(isinstance(article, Article))
1543 self.assertGreater(len(article.html), 0)
1544
1545=== added file 'md_importer/tests/test_website_import.py'
1546--- md_importer/tests/test_website_import.py 1970-01-01 00:00:00 +0000
1547+++ md_importer/tests/test_website_import.py 2016-03-22 10:52:56 +0000
1548@@ -0,0 +1,72 @@
1549+from md_importer.importer import DEFAULT_LANG
1550+from md_importer.importer.repo import Repo
1551+from .utils import (
1552+ db_add_empty_page,
1553+ TestLocalBranchImport,
1554+)
1555+
1556+from cms.api import add_plugin, publish_pages
1557+from cms.models import Page
1558+
1559+
1560+class TestSnappyWebsiteRead(TestLocalBranchImport):
1561+ def runTest(self):
1562+ self.create_repo('data/website-test')
1563+ self.assertTrue(isinstance(self.repo, Repo))
1564+ self.repo.add_directive('out/get-started/as-dev/index.html', '')
1565+ self.repo.add_directive('out/get-started/as-dev/16.04', '')
1566+ self.assertEqual(len(self.repo.directives), 2)
1567+ self.assertTrue(self.repo.execute_import_directives())
1568+ self.assertTrue(self.repo.publish())
1569+ self.assertGreater(len(self.repo.pages), 10)
1570+
1571+
1572+class TestSnappyWebsiteIA(TestLocalBranchImport):
1573+ def runTest(self):
1574+ self.create_repo('data/website-test')
1575+ snappy_page = db_add_empty_page('Snappy', self.root)
1576+ start = db_add_empty_page(
1577+ 'Get started', parent=snappy_page, slug='start')
1578+ as_dev = db_add_empty_page(
1579+ 'As developer', parent=start, slug='as-dev')
1580+ placeholder = as_dev.placeholders.all()[0]
1581+ add_plugin(placeholder, 'RawHtmlPlugin', DEFAULT_LANG, body='')
1582+ page_16_04 = db_add_empty_page(
1583+ '16.04', parent=as_dev, slug='16-04')
1584+ publish_pages([snappy_page, start, as_dev, page_16_04])
1585+ self.assertTrue(isinstance(self.repo, Repo))
1586+ self.repo.add_directive('out/get-started/as-dev/index.html',
1587+ 'snappy/start/as-dev')
1588+ self.repo.add_directive('out/get-started/as-dev/16.04/index.html',
1589+ 'snappy/start/as-dev/16-04')
1590+ self.repo.add_directive('out/get-started/as-dev/16.04',
1591+ 'snappy/start/as-dev/16-04')
1592+ self.assertTrue(self.repo.execute_import_directives())
1593+ self.assertTrue(self.repo.publish())
1594+ self.assertGreater(len(self.repo.pages), 10)
1595+ pages = Page.objects.filter(publisher_is_draft=False)
1596+ expected_urls = [
1597+ '/en/',
1598+ '/en/snappy/',
1599+ '/en/snappy/start/',
1600+ '/en/snappy/start/as-dev/',
1601+ '/en/snappy/start/as-dev/16-04/',
1602+ '/en/snappy/start/as-dev/16-04/step2-setup-beaglebone-macos/',
1603+ '/en/snappy/start/as-dev/16-04/step2-setup-beaglebone-ubuntu/',
1604+ '/en/snappy/start/as-dev/16-04/step2-setup-beaglebone-windows/',
1605+ '/en/snappy/start/as-dev/16-04/step2-setup-dragonboard-macos/',
1606+ '/en/snappy/start/as-dev/16-04/step2-setup-dragonboard-ubuntu/',
1607+ '/en/snappy/start/as-dev/16-04/step2-setup-dragonboard-windows/',
1608+ '/en/snappy/start/as-dev/16-04/step2-setup-intel-nuc-macos/',
1609+ '/en/snappy/start/as-dev/16-04/step2-setup-intel-nuc-ubuntu/',
1610+ '/en/snappy/start/as-dev/16-04/step2-setup-intel-nuc-windows/',
1611+ '/en/snappy/start/as-dev/16-04/step2-setup-rpi2-macos/',
1612+ '/en/snappy/start/as-dev/16-04/step2-setup-rpi2-ubuntu/',
1613+ '/en/snappy/start/as-dev/16-04/step2-setup-rpi2-windows/',
1614+ '/en/snappy/start/as-dev/16-04/step3-get-familiar/',
1615+ '/en/snappy/start/as-dev/16-04/step4-first-snap/',
1616+ '/en/snappy/start/as-dev/16-04/step5-further-readings/',
1617+ ]
1618+ self.assertEqual(len(expected_urls), len(pages))
1619+ for url in expected_urls:
1620+ self.assertTrue(url in [p.get_absolute_url() for p in pages])
1621
1622=== modified file 'md_importer/tests/utils.py'
1623--- md_importer/tests/utils.py 2016-02-25 15:43:10 +0000
1624+++ md_importer/tests/utils.py 2016-03-22 10:52:56 +0000
1625@@ -27,9 +27,11 @@
1626 return db_add_empty_page('root')
1627
1628
1629-def db_add_empty_page(title, parent=None):
1630+def db_add_empty_page(title, parent=None, slug=None):
1631+ if not slug:
1632+ slug = slugify(title)
1633 page = create_page(
1634- title, 'default.html', DEFAULT_LANG, slug=slugify(title),
1635+ title, 'default.html', DEFAULT_LANG, slug=slug,
1636 published=True, parent=parent)
1637 page.reload()
1638 page.publish(DEFAULT_LANG)
1639
1640=== added file 'templates/snappy_hero_tour.html'
1641--- templates/snappy_hero_tour.html 1970-01-01 00:00:00 +0000
1642+++ templates/snappy_hero_tour.html 2016-03-22 10:52:56 +0000
1643@@ -0,0 +1,334 @@
1644+{% extends "cms_page_base.html" %}
1645+{% load cms_tags %}
1646+{% block nav_secondary %}
1647+{% endblock %}
1648+{% block content %}
1649+<div class="row last-col row--intro no-border text-center no-padding-bottom">
1650+ <div class="strip-inner-wrapper">
1651+ <div class="ubuntu-intro">
1652+ &nbsp;
1653+ </div>
1654+ <div class="eight-col">
1655+ <h3 class="left">Ubuntu Core's<br />
1656+ <strong>developer</strong> tour</h3>
1657+ </div>
1658+ <div class="four-col right last-col box" style="color: black;">
1659+ Completion time: 20 min
1660+ </div>
1661+ </div>
1662+</div>
1663+
1664+<div class="row equal-height row-grey" style="padding:0px;padding-top:20px;padding-bottom:20px;">
1665+
1666+ <div class="one-col no-margin-bottom">
1667+ &nbsp;
1668+ </div>
1669+
1670+ <div class="two-col center dot no-margin-bottom" style="text-align: center;"><a href="">
1671+ <div class="round-nav-circle">
1672+ 1
1673+ </div>
1674+ <p>Pick up device</p>
1675+ </a>
1676+ <p class="eta">1 min</p>
1677+ </div>
1678+
1679+ <div class="two-col center dot no-margin-bottom" style="text-align: center;"><a href="">
1680+ <div class="round-nav-circle">
1681+ 2
1682+ </div>
1683+ <p>Setup your board</p>
1684+ </a>
1685+ <p class="eta">7 min</p>
1686+ </div>
1687+
1688+ <div class="two-col center dot no-margin-bottom" style="text-align: center;"><a href="">
1689+ <div class="round-nav-circle">
1690+ 3
1691+ </div>
1692+ <p>Get familiar with your new install</p>
1693+ </a>
1694+ <p class="eta">5 min</p>
1695+ </div>
1696+
1697+ <div class="two-col center dot no-margin-bottom" style="text-align: center;"><a href="">
1698+ <div class="round-nav-circle">
1699+ 4
1700+ </div>
1701+ <p>Create your first snap</p>
1702+ </a>
1703+ <p class="eta">7 min</p>
1704+ </div>
1705+
1706+ <div class="two-col center dot last-dot no-margin-bottom" style="text-align: center;"><a href="">
1707+ <div class="round-nav-circle">
1708+ 5
1709+ </div>
1710+ <p>Fireworks!</p>
1711+ </a>
1712+ </div>
1713+
1714+ <div class="one-col last-col no-margin-bottom">
1715+ &nbsp;
1716+ </div>
1717+
1718+ <div class="round-button" id="button-container-left">
1719+ <div class="round-button-circle">
1720+ <a id="prev" href="#" class="round-button">&lsaquo;</a>
1721+ </div>
1722+ </div>
1723+
1724+ <div class="round-button" id="button-container-right">
1725+ <div class="round-button-circle">
1726+ <a id="next" href="#" class="round-button">&rsaquo;</a>
1727+ </div>
1728+ </div>
1729+</div>
1730+
1731+{% placeholder page_content %}
1732+
1733+<script>
1734+ var path = "{{ request.path }}";
1735+ var nextBtn = document.getElementById('next');
1736+
1737+ // Remove next button on last page
1738+ if (path.includes("/step5")) {
1739+ document.getElementById("button-container-right").style.display = "none";
1740+ }
1741+ else {
1742+ document.getElementById("button-container-right").style.display = "block";
1743+ }
1744+
1745+ // Set next button url
1746+ nextBtn.href = getChoicesString();
1747+
1748+ // Setup navigation dots
1749+ setDots()
1750+
1751+ // Dynamically update all nav urls to match user choices
1752+ if (!path.includes("/step")) {
1753+ var atags = document.getElementsByTagName('a');
1754+ for (var i = 0, length = atags.length; i < length; i++) {
1755+ atags[i].addEventListener('mouseover', function () {
1756+ nextBtn.href = getChoicesString();
1757+ setDots();
1758+ });
1759+ atags[i].addEventListener('mousedown', function () {
1760+ nextBtn.href = getChoicesString();
1761+ setDots();
1762+ });
1763+ }
1764+ }
1765+
1766+ function setDots() {
1767+ var dots = document.getElementsByClassName("dot");
1768+ for (var i = 0, length = dots.length; i < length; i++) {
1769+ dots[i].firstChild.href = createURLForDot(dots.length, i + 1)
1770+ var short_path = path.split("/snappy/get-started/")[1];
1771+ var short_url = dots[i].firstChild.href.split("/snappy/get-started/")[1];
1772+ if (short_path == short_url.replace("#", "")) {
1773+ addClass(dots[i].firstChild.children[0], "here");
1774+ addClass(dots[i].firstChild.children[1], "here");
1775+ } else {
1776+ removeClass(dots[i].firstChild.children[0], "here");
1777+ removeClass(dots[i].firstChild.children[1], "here");
1778+ }
1779+ }
1780+ }
1781+
1782+ function createURLForDot(length, position) {
1783+ var host = getCookie("snappy-tour-host");
1784+ var version = getCookie("snappy-tour-version");
1785+ var target = getCookie("snappy-tour-target");
1786+ var url = "";
1787+ if (position == 1) {
1788+ if (path.includes("/step")) {
1789+ url = "..";
1790+ }
1791+ else {
1792+ url += "#";
1793+ }
1794+ }
1795+ else {
1796+ if (path.includes("/step")) {
1797+ url = "../step" + position + "-" + host + "-" + target + "/";
1798+ }
1799+ else {
1800+ url = version + "/step" + position + "-" + host + "-" + target + "/";
1801+ }
1802+ }
1803+ return url;
1804+ }
1805+
1806+ function getChoicesString() {
1807+ if (path.includes("/step")) {
1808+ page = path.split("/").reverse()[1];
1809+ current_step = page.split("-")[0];
1810+ next_step = current_step.replace(/(\d+)/, function () {
1811+ return arguments[1] * 1 + 1;
1812+ });
1813+ return "../" + page.replace(current_step, next_step);
1814+ }
1815+ else {
1816+ var step = "step2";
1817+ var host_item = document.getElementsByName('host');
1818+ var version_item = document.getElementsByName('version')[0].options;
1819+ var target_item = document.getElementsByName('target');
1820+
1821+ var version = version_item[version_item.selectedIndex].value;
1822+
1823+ for (var i = 0, length = host_item.length; i < length; i++) {
1824+ if (host_item[i].checked) {
1825+ var host = host_item[i].value;
1826+ break;
1827+ }
1828+ }
1829+
1830+ for (var i = 0, length = target_item.length; i < length; i++) {
1831+ if (target_item[i].checked) {
1832+ var target = target_item[i].value;
1833+ break;
1834+ }
1835+ }
1836+ setCookie("snappy-tour-version", version);
1837+ setCookie("snappy-tour-host", host);
1838+ setCookie("snappy-tour-target", target);
1839+ return version + "/" + step + "-" + host + "-" + target + "/";
1840+ }
1841+ }
1842+
1843+ // Utils
1844+
1845+ function setCookie(cname, cvalue) {
1846+ document.cookie = cname + "=" + cvalue + ";";
1847+ }
1848+
1849+ function getCookie(cname) {
1850+ var name = cname + "=";
1851+ var ca = document.cookie.split(';');
1852+ for (var i = 0; i < ca.length; i++) {
1853+ var c = ca[i];
1854+ while (c.charAt(0) == ' ') c = c.substring(1);
1855+ if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
1856+ }
1857+ return "";
1858+ }
1859+
1860+ function hasClass(el, className) {
1861+ if (el.classList)
1862+ return el.classList.contains(className);
1863+ else
1864+ return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
1865+ }
1866+
1867+ function addClass(el, className) {
1868+ if (el.classList)
1869+ el.classList.add(className);
1870+ else if (!hasClass(el, className)) el.className += " " + className;
1871+ }
1872+
1873+ function removeClass(el, className) {
1874+ if (el.classList)
1875+ el.classList.remove(className);
1876+ else if (hasClass(el, className)) {
1877+ var reg = new RegExp('(\\s|^)' + className + '(\\s|$)');
1878+ el.className=el.className.replace(reg, ' ');
1879+ }
1880+ }
1881+</script>
1882+<style>
1883+#button-container-left {
1884+ position: absolute;
1885+ display:none;
1886+ top: 105px;
1887+ left:-24px;
1888+}
1889+
1890+#button-container-right {
1891+ position: absolute;
1892+ display:none;
1893+ top: 105px;
1894+ right:-24px;
1895+}
1896+
1897+.round-button {
1898+ width:64px;
1899+
1900+}
1901+.round-button-circle {
1902+ width: 100%;
1903+ height:0;
1904+ padding-bottom: 100%;
1905+ border-radius: 50%;
1906+ border:0px solid;
1907+ overflow:hidden;
1908+
1909+ background: #dd4814;
1910+ box-shadow: 0 0 10px gray;
1911+}
1912+.round-button-circle:hover {
1913+ background: #dd4814;
1914+}
1915+.round-button a {
1916+ display: block;
1917+ float: left;
1918+ width: 100%;
1919+ padding-top: 50%;
1920+ padding-bottom: 50%;
1921+ line-height: 3em;
1922+ margin-top: -1.57em;
1923+ text-align: center;
1924+ color: #e2eaf3;
1925+ font-size: 4em;
1926+ text-decoration: none;
1927+ padding-left: 0.02em;
1928+}
1929+.dot:before {
1930+ content: '';
1931+ position: absolute;
1932+ bottom: 73%;
1933+ width: 85%;
1934+ height: 0;
1935+ line-height: 0;
1936+ border-bottom: 2px dotted grey;
1937+ float: right;
1938+ left: 65%;
1939+}
1940+.last-dot:before {
1941+ width: 0;
1942+}
1943+.dot a {
1944+ color: #333;
1945+ text-decoration: none;
1946+}
1947+p.here {
1948+ font-weight:400;
1949+}
1950+.eta {
1951+ position: absolute;
1952+ top: 0px;
1953+ right: -20%;
1954+}
1955+.round-nav-circle {
1956+ width: 30px;
1957+ height: 30px;
1958+ border-radius: 100%;
1959+ border: 2px solid #333;
1960+ overflow: hidden;
1961+ background: transparent;
1962+ align-content: center;
1963+ line-height: 30px;
1964+ font-weight: 400;
1965+ font-size: 1.2em;
1966+ margin: auto;
1967+ margin-bottom: 8px;
1968+ margin-top:8px;
1969+}
1970+.round-nav-circle.here {
1971+ background: #dd4814;
1972+ color:#fff;
1973+}
1974+</style>
1975+{% endblock %}
1976+{% block footer %}
1977+{% endblock %}

Subscribers

People subscribed via source and target branches