Merge lp:~facundo/locolander/ns2df into lp:locolander

Proposed by Facundo Batista
Status: Merged
Approved by: Loco Lander
Approved revision: 5
Merged at revision: 8
Proposed branch: lp:~facundo/locolander/ns2df
Merge into: lp:locolander
Diff against target: 308 lines (+297/-0)
2 files modified
ns2df.py (+129/-0)
tests/test_ns2df.py (+168/-0)
To merge this branch: bzr merge lp:~facundo/locolander/ns2df
Reviewer Review Type Date Requested Status
Loco Lander Approve
Review via email: mp+170959@code.launchpad.net

Commit message

The transformer from locolander config to docker stuff

Description of the change

The transformer from locolander config to docker stuff

To post a comment you must log in.
Revision history for this message
Loco Lander (locolander) wrote :

l. 31-33: this should be

run pip install --download=/var/cache/locolander/pip --no-install foobar
run ip link set dev eth0 down
run pip install --find-links=file:///var/cache/locolander/pip --no-index foobar

Revision history for this message
Loco Lander (locolander) wrote :

l. 20: I'd use pip instead of pypi
l. 29: I'd split each dependency into it's own line to make better use of the underlying caching algorithm of docker
l. 29: use apt-get install -q -y to avoid apt-get asking questions interactively
l. 30: no longer needed, part of the base image (assume /var/cache/locolander exists and will be used as the pip cache)

lp:~facundo/locolander/ns2df updated
3. By Facundo Batista

Some changes.

4. By Facundo Batista

More changes.

5. By Facundo Batista

Merged trunk in.

Revision history for this message
Loco Lander (locolander) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'ns2df.py'
2--- ns2df.py 1970-01-01 00:00:00 +0000
3+++ ns2df.py 2013-06-22 23:34:26 +0000
4@@ -0,0 +1,129 @@
5+"""Nessita Syntax to Docker File.
6+
7+Example:
8+
9+ precise:
10+ apt:
11+ apache2: 3.3-4
12+ bzr:
13+ pip:
14+ foobar:
15+ metadata:
16+ test_script: ./test
17+
18+
19+will be converted to
20+
21+ from ubuntu:precise
22+ run apt-get -q -y install apache2=3.3-4
23+ run apt-get -q -y install bzr
24+ run pip install --download=/tmp/pipcache --no-install foobar
25+ run ip link set dev eth0 down
26+ run pip install --find-links=file:///tmp/pipcache --no-index foobar
27+
28+and also the system will use "./test" as script
29+"""
30+
31+import yaml
32+
33+# the conversion between our nice base names and those that are
34+# needed by docker
35+BASE_TRANSLATIONS = {
36+ 'precise': 'ubuntu:precise',
37+}
38+
39+def _get_base(config, **params):
40+ """Process the system base stuff."""
41+ # support only one base for now
42+ if len(config) > 1:
43+ raise NotImplementedError("Too many base machines.")
44+ base = config.keys()[0]
45+ return ["from " + BASE_TRANSLATIONS[base]]
46+
47+
48+def _get_depends_prev(config, **params):
49+ """All the dependencies before securing machine."""
50+ # support only one base for now
51+ config = config.values()[0]
52+ dependencies = []
53+
54+ # apt
55+ items = config.get('apt', [])
56+ if items:
57+ for name, ver in sorted(items.items()):
58+ if ver is None:
59+ p = name
60+ else:
61+ p = "%s=%s" % (name, ver)
62+ dep = "run apt-get -q -y install " + p
63+ dependencies.append(dep)
64+
65+ # pip
66+ items = config.get('pip', [])
67+ pip_cache_dir = params["pip_cache_dir"]
68+ if items:
69+ for name, ver in sorted(items.items()):
70+ if ver is None:
71+ p = name
72+ else:
73+ p = "%s==%s" % (name, ver)
74+ dep = "run pip install --download=%s --no-install %s" % (
75+ pip_cache_dir, p)
76+ dependencies.append(dep)
77+
78+ return dependencies
79+
80+def _get_secure(config, **params):
81+ """All that needs to be done to secure the machine."""
82+ return ["run ip link set dev eth0 down"]
83+
84+def _get_depends_post(config, **params):
85+ """All the dependencies stuff after the machine was secured."""
86+ # support only one base for now
87+ config = config.values()[0]
88+ dependencies = []
89+
90+ # pip
91+ items = config.get('pip', [])
92+ pip_cache_dir = params["pip_cache_dir"]
93+ if items:
94+ for name, ver in sorted(items.items()):
95+ if ver is None:
96+ p = name
97+ else:
98+ p = "%s==%s" % (name, ver)
99+ dep = "run pip install --find-links=file://%s --no-index %s" % (
100+ pip_cache_dir, p)
101+ dependencies.append(dep)
102+
103+ return dependencies
104+
105+
106+def _get_rest(config, **params):
107+ """The final stuff."""
108+ return []
109+
110+
111+def parse(config_text, pip_cache_dir):
112+ """Convert Nessita Syntax and return the text for Docker."""
113+ config = yaml.load(config_text)
114+ metadata = config.pop("metadata")
115+
116+ # the order for calling these functions is VERY important
117+ functions = [
118+ _get_base,
119+ _get_depends_prev,
120+ _get_secure,
121+ _get_depends_post,
122+ _get_rest,
123+ ]
124+ data = []
125+ for func in functions:
126+ items = func(config, pip_cache_dir=pip_cache_dir)
127+ data.extend(items)
128+ docker = "\n".join(data)
129+
130+ # get stuff from the metadata
131+ script = metadata["test_script"]
132+
133+ return script, docker
134
135=== added directory 'tests'
136=== added file 'tests/__init__.py'
137=== added file 'tests/test_ns2df.py'
138--- tests/test_ns2df.py 1970-01-01 00:00:00 +0000
139+++ tests/test_ns2df.py 2013-06-22 23:34:26 +0000
140@@ -0,0 +1,168 @@
141+"""Tests for the ns2df convertor."""
142+
143+import unittest
144+
145+import ns2df
146+
147+class DependenciesTestCase(unittest.TestCase):
148+ """Tests for the dependencies transformer."""
149+
150+ def test_no_dependencies(self):
151+ config = dict(somebase={})
152+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
153+ self.assertEqual(res, [])
154+ res = ns2df._get_depends_post(config, pip_cache_dir="/tmp/pipcache")
155+ self.assertEqual(res, [])
156+
157+ def test_apt_one(self):
158+ config = dict(somebase={
159+ 'apt': {'bzr': None}
160+ })
161+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
162+ self.assertEqual(res, ["run apt-get -q -y install bzr"])
163+
164+ def test_apt_several(self):
165+ config = dict(somebase={
166+ 'apt': {'bzr': None, 'apache2': None}
167+ })
168+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
169+ self.assertEqual(res, [
170+ "run apt-get -q -y install apache2",
171+ "run apt-get -q -y install bzr",
172+ ])
173+
174+ def test_apt_versions(self):
175+ config = dict(somebase={
176+ 'apt': {'bzr': None, 'apache2': '3.3-4'}
177+ })
178+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
179+ self.assertEqual(res, [
180+ "run apt-get -q -y install apache2=3.3-4",
181+ "run apt-get -q -y install bzr",
182+ ])
183+
184+ def test_pip_prev_one(self):
185+ config = dict(somebase={
186+ 'pip': {'foo': None}
187+ })
188+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
189+ self.assertEqual(res, [
190+ "run pip install --download=/tmp/pipcache --no-install foo",
191+ ])
192+
193+ def test_pip_prev_several(self):
194+ config = dict(somebase={
195+ 'pip': {'foo': None, 'bar': None}
196+ })
197+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
198+ self.assertEqual(res, [
199+ "run pip install --download=/tmp/pipcache --no-install bar",
200+ "run pip install --download=/tmp/pipcache --no-install foo",
201+ ])
202+
203+ def test_pip_prev_versions(self):
204+ config = dict(somebase={
205+ 'pip': {'foo': None, 'bar': '2.1'}
206+ })
207+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
208+ self.assertEqual(res, [
209+ "run pip install --download=/tmp/pipcache --no-install bar==2.1",
210+ "run pip install --download=/tmp/pipcache --no-install foo",
211+ ])
212+
213+ def test_pip_post_one(self):
214+ config = dict(somebase={
215+ 'pip': {'foo': None}
216+ })
217+ res = ns2df._get_depends_post(config, pip_cache_dir="/tmp/pipcache")
218+ self.assertEqual(res, [
219+ "run pip install --find-links=file:///tmp/pipcache --no-index foo"
220+ ])
221+
222+ def test_pip_post_several(self):
223+ config = dict(somebase={
224+ 'pip': {'foo': None, 'bar': None}
225+ })
226+ res = ns2df._get_depends_post(config, pip_cache_dir="/tmp/pipcache")
227+ self.assertEqual(res, [
228+ "run pip install --find-links=file:///tmp/pipcache --no-index bar",
229+ "run pip install --find-links=file:///tmp/pipcache --no-index foo",
230+ ])
231+
232+ def test_pip_post_versions(self):
233+ config = dict(somebase={
234+ 'pip': {'foo': None, 'bar': '2.1'}
235+ })
236+ res = ns2df._get_depends_post(config, pip_cache_dir="/tmcache")
237+ self.assertEqual(res, [
238+ "run pip install --find-links=file:///tmcache --no-index bar==2.1",
239+ "run pip install --find-links=file:///tmcache --no-index foo",
240+ ])
241+
242+ def test_mixed_prev(self):
243+ config = dict(somebase={
244+ 'apt': {'bzr': None, 'apache2': '3.3-4'},
245+ 'pip': {'foo': None, 'bar': None},
246+ })
247+ res = ns2df._get_depends_prev(config, pip_cache_dir="/tmp/pipcache")
248+ self.assertEqual(res, [
249+ "run apt-get -q -y install apache2=3.3-4",
250+ "run apt-get -q -y install bzr",
251+ "run pip install --download=/tmp/pipcache --no-install bar",
252+ "run pip install --download=/tmp/pipcache --no-install foo",
253+ ])
254+
255+ def test_mixed_post(self):
256+ config = dict(somebase={
257+ 'apt': {'bzr': None, 'apache2': '3.3-4'},
258+ 'pip': {'foo': None, 'bar': None},
259+ })
260+ res = ns2df._get_depends_post(config, pip_cache_dir="/tmp/pipcache")
261+ self.assertEqual(res, [
262+ "run pip install --find-links=file:///tmp/pipcache --no-index bar",
263+ "run pip install --find-links=file:///tmp/pipcache --no-index foo",
264+ ])
265+
266+
267+class BoilerplateTestCase(unittest.TestCase):
268+ """Tests for the setup and the rest of commands."""
269+
270+ def test_one_base(self):
271+ config = dict(precise={})
272+ res = ns2df._get_base(config)
273+ self.assertEqual(res, ["from ubuntu:precise"])
274+
275+ def test_several_bases(self):
276+ config = dict(base1={}, base2={})
277+ self.assertRaises(NotImplementedError, ns2df._get_base, config)
278+
279+ def test_secure_actions(self):
280+ res = ns2df._get_secure({})
281+ self.assertEqual(res, ["run ip link set dev eth0 down"])
282+
283+ def test_rest(self):
284+ res = ns2df._get_rest({})
285+ self.assertEqual(res, [])
286+
287+ def test_all_mixed(self):
288+ config_text = """
289+ precise:
290+ apt:
291+ apache2: 3.3-4
292+ bzr:
293+ pip:
294+ foobar:
295+ metadata:
296+ test_script: foo
297+ """
298+ script, docker = ns2df.parse(config_text, "/tmp/pipcache")
299+ self.assertEqual(script, "foo")
300+ self.assertEqual(docker,
301+ "from ubuntu:precise\n"
302+ "run apt-get -q -y install apache2=3.3-4\n"
303+ "run apt-get -q -y install bzr\n"
304+ "run pip install --download=/tmp/pipcache --no-install foobar\n"
305+ "run ip link set dev eth0 down\n"
306+ "run pip install --find-links=file:///tmp/pipcache "
307+ "--no-index foobar"
308+ )

Subscribers

People subscribed via source and target branches

to all changes: