Merge lp:~sergiusens/snapcraft/wiki into lp:~snappy-dev/snapcraft/core

Proposed by Sergio Schvezov
Status: Merged
Approved by: Sergio Schvezov
Approved revision: no longer in the source branch.
Merged at revision: 167
Proposed branch: lp:~sergiusens/snapcraft/wiki
Merge into: lp:~snappy-dev/snapcraft/core
Diff against target: 271 lines (+182/-1)
8 files modified
examples/downloader-with-wiki-parts/Makefile (+11/-0)
examples/downloader-with-wiki-parts/snapcraft.yaml (+15/-0)
examples/downloader-with-wiki-parts/test.c (+17/-0)
runtests.sh (+1/-1)
snapcraft/tests/test_wiki.py (+50/-0)
snapcraft/tests/test_yaml.py (+31/-0)
snapcraft/wiki.py (+50/-0)
snapcraft/yaml.py (+7/-0)
To merge this branch: bzr merge lp:~sergiusens/snapcraft/wiki
Reviewer Review Type Date Requested Status
Sergio Schvezov Approve
John Lenton (community) Approve
Daniel Holbach (community) Approve
Review via email: mp+271140@code.launchpad.net

Commit message

Try to use wiki when after in part is not local

To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

A few small things:
 - examples/downloader-with-wiki-parts/icon.png is missing
 - "curl based downloaded" → "curl based downloader"?

I wasn't part of the design decisions regarding the wiki plugin, but I'm not quite sure how we could safe-guard against tampering of wiki pages. Do we want to look up who made the last edit of the page or something like that or introduce some kind of other security measure?

review: Needs Fixing
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

> A few small things:
> - examples/downloader-with-wiki-parts/icon.png is missing

ah, always forget to bzr add :-) (I also added test_wiki.py)

> - "curl based downloaded" → "curl based downloader"?
>
> I wasn't part of the design decisions regarding the wiki plugin, but I'm not
> quite sure how we could safe-guard against tampering of wiki pages. Do we want
> to look up who made the last edit of the page or something like that or
> introduce some kind of other security measure?

The idea was to lock down the wiki endpoint to specific people only.

Revision history for this message
Daniel Holbach (dholbach) wrote :

Good work!

review: Approve
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

Taking advantage of community reviewers due to the high load.

review: Approve
Revision history for this message
Snappy Tarmac (snappydevtarmac) wrote :
Download full text (4.1 KiB)

The attempt to merge lp:~sergiusens/snapcraft/wiki into lp:snapcraft failed. Below is the output from the failed tests.

The project has gotten complex.
Here's the list of units exceeding 10:
- snapcraft/cmds.py:
  246:1: 'cmd' 12

cp --preserve=all -R zzz /tmp/tmpsetsbpul/parts/copy/install/zzz
cp --preserve=all -R src /tmp/tmpq0hhcvas/parts/copy/install/dst
cp --preserve=all -R src /tmp/tmpuu5cjsbn/parts/copy/install/dir/dst

.........E...................Warning: unable to find "test_relexepath" in the path
..........................................EE
======================================================================
ERROR: snapcraft.tests.test_cmds (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/case.py", line 57, in testPartExecutor
    yield
  File "/usr/lib/python3.4/unittest/case.py", line 574, in run
    testMethod()
  File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure
    raise exception
ImportError: Failed to import test module: snapcraft.tests.test_cmds
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name
    __import__(name)
  File "/tmp/tarmac/branch.9LlwxZ/snapcraft/tests/test_cmds.py", line 24, in <module>
    from snapcraft import (
  File "/tmp/tarmac/branch.9LlwxZ/snapcraft/cmds.py", line 27, in <module>
    import snapcraft.yaml
  File "/tmp/tarmac/branch.9LlwxZ/snapcraft/yaml.py", line 25, in <module>
    import snapcraft.wiki
  File "/tmp/tarmac/branch.9LlwxZ/snapcraft/wiki.py", line 18, in <module>
    import requests
ImportError: No module named 'requests'

======================================================================
ERROR: snapcraft.tests.test_wiki (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/case.py", line 57, in testPartExecutor
    yield
  File "/usr/lib/python3.4/unittest/case.py", line 574, in run
    testMethod()
  File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure
    raise exception
ImportError: Failed to import test module: snapcraft.tests.test_wiki
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name
    __import__(name)
  File "/tmp/tarmac/branch.9LlwxZ/snapcraft/tests/test_wiki.py", line 19, in <module>
    import snapcraft.wiki
  File "/tmp/tarmac/branch.9LlwxZ/snapcraft/wiki.py", line 18, in <module>
    import requests
ImportError: No module named 'requests'

======================================================================
ERROR: snapcraft.tests.test_yaml (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/li...

Read more...

Revision history for this message
John Lenton (chipaca) :
Revision history for this message
John Lenton (chipaca) :
review: Approve
Revision history for this message
Sergio Schvezov (sergiusens) wrote :

after review (and tarmac now has python3-requests)

review: Approve
lp:~sergiusens/snapcraft/wiki updated
167. By Sergio Schvezov

Try to use wiki when after in part is not local by sergiusens approved by sergiusens,chipaca,dholbach

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'examples/downloader-with-wiki-parts'
2=== added file 'examples/downloader-with-wiki-parts/Makefile'
3--- examples/downloader-with-wiki-parts/Makefile 1970-01-01 00:00:00 +0000
4+++ examples/downloader-with-wiki-parts/Makefile 2015-09-15 21:52:37 +0000
5@@ -0,0 +1,11 @@
6+# -*- Mode:Makefile; indent-tabs-mode:t; tab-width:4 -*-
7+
8+all:
9+ gcc -Wall -Wextra -Werror -pedantic -o test ./test.c $(CFLAGS) $(LDFLAGS) -lcurl -lssl -lcrypto -lssl -lcrypto -lz
10+
11+install:
12+ install -d -m755 $(DESTDIR)/bin/
13+ install -m755 ./test $(DESTDIR)/bin/test
14+
15+clean:
16+ rm -f test
17
18=== added file 'examples/downloader-with-wiki-parts/icon.png'
19Binary files examples/downloader-with-wiki-parts/icon.png 1970-01-01 00:00:00 +0000 and examples/downloader-with-wiki-parts/icon.png 2015-09-15 21:52:37 +0000 differ
20=== added file 'examples/downloader-with-wiki-parts/snapcraft.yaml'
21--- examples/downloader-with-wiki-parts/snapcraft.yaml 1970-01-01 00:00:00 +0000
22+++ examples/downloader-with-wiki-parts/snapcraft.yaml 2015-09-15 21:52:37 +0000
23@@ -0,0 +1,15 @@
24+name: downloader
25+version: 1.0
26+vendor: "Sergio Schvezov <sergio.schvezov@canonical.com>"
27+summary: curl based downloader
28+description: this is an example package
29+icon: icon.png
30+binaries:
31+ - name: bin/test
32+
33+parts:
34+ main:
35+ type: make-project
36+ source: .
37+ after:
38+ - curl
39
40=== added file 'examples/downloader-with-wiki-parts/test.c'
41--- examples/downloader-with-wiki-parts/test.c 1970-01-01 00:00:00 +0000
42+++ examples/downloader-with-wiki-parts/test.c 2015-09-15 21:52:37 +0000
43@@ -0,0 +1,17 @@
44+#include <stdio.h>
45+#include <curl/curl.h>
46+
47+int main(void)
48+{
49+ CURL *curl;
50+
51+ curl = curl_easy_init();
52+ if(curl) {
53+ curl_easy_setopt(curl, CURLOPT_URL, "ubuntu.com");
54+ curl_easy_perform(curl);
55+
56+ curl_easy_cleanup(curl);
57+ }
58+
59+ return 0;
60+}
61
62=== modified file 'runtests.sh'
63--- runtests.sh 2015-08-26 04:20:25 +0000
64+++ runtests.sh 2015-09-15 21:52:37 +0000
65@@ -31,7 +31,7 @@
66
67 # mccabe in 'warning' mode as we have high complexity
68 mccabe_list=
69-for unit in $(find . -type f -name '*.py')
70+for unit in $(find snapcraft -type f -name '*.py')
71 do
72 output=$(python3 -m mccabe --min 10 "$unit")
73 [ -n "$output" ] && mccabe_list="- $unit:\n $output\n$mccabe_list"
74
75=== added file 'snapcraft/tests/test_wiki.py'
76--- snapcraft/tests/test_wiki.py 1970-01-01 00:00:00 +0000
77+++ snapcraft/tests/test_wiki.py 2015-09-15 21:52:37 +0000
78@@ -0,0 +1,50 @@
79+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
80+#
81+# Copyright (C) 2015 Canonical Ltd
82+#
83+# This program is free software: you can redistribute it and/or modify
84+# it under the terms of the GNU General Public License version 3 as
85+# published by the Free Software Foundation.
86+#
87+# This program is distributed in the hope that it will be useful,
88+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90+# GNU General Public License for more details.
91+#
92+# You should have received a copy of the GNU General Public License
93+# along with this program. If not, see <http://www.gnu.org/licenses/>.
94+
95+import unittest.mock
96+
97+import snapcraft.wiki
98+
99+from snapcraft.tests import TestCase
100+
101+
102+class TestYaml(TestCase):
103+
104+ def setUp(self):
105+ super().setUp()
106+
107+ class Content:
108+
109+ @property
110+ def text(self):
111+ return '''{{{part1:
112+ type: go
113+}}}'''
114+
115+ patcher = unittest.mock.patch('requests.get')
116+ self.mock_requests = patcher.start()
117+ self.mock_requests.return_value = Content()
118+ self.addCleanup(patcher.stop)
119+
120+ def test_get_part(self):
121+ w = snapcraft.wiki.Wiki()
122+
123+ self.mock_requests.assert_called_once_with(
124+ 'https://wiki.ubuntu.com/Snappy/Parts',
125+ params={'action': 'raw'})
126+
127+ self.assertEqual(w.get_part('part1'), {'type': 'go'})
128+ self.assertEqual(w.get_part('part2'), None)
129
130=== modified file 'snapcraft/tests/test_yaml.py'
131--- snapcraft/tests/test_yaml.py 2015-09-14 19:22:59 +0000
132+++ snapcraft/tests/test_yaml.py 2015-09-15 21:52:37 +0000
133@@ -39,6 +39,10 @@
134 mock_wrap_exe.return_value = True
135 self.addCleanup(patcher.stop)
136
137+ patcher = unittest.mock.patch('snapcraft.wiki.Wiki')
138+ self.mock_wiki = patcher.start()
139+ self.addCleanup(patcher.stop)
140+
141 def make_snapcraft_yaml(self, content):
142 tempdirObj = tempfile.TemporaryDirectory()
143 self.addCleanup(tempdirObj.cleanup)
144@@ -66,6 +70,32 @@
145 'stage': [], 'snap': [],
146 })
147
148+ self.assertFalse(self.mock_wiki.get_part.called)
149+
150+ @unittest.mock.patch('snapcraft.yaml.Config.load_plugin')
151+ def test_config_loads_plugins_with_wiki_part(self, mock_loadPlugin):
152+ self.make_snapcraft_yaml("""name: test
153+version: "1"
154+vendor: me <me@me.com>
155+summary: test
156+description: test
157+icon: my-icon.png
158+
159+parts:
160+ part1:
161+ after:
162+ - part2wiki
163+ type: go
164+ stage-packages: [fswebcam]
165+""")
166+ snapcraft.yaml.Config()
167+ mock_loadPlugin.assert_called_with('part1', 'go', {
168+ 'stage-packages': ['fswebcam'],
169+ 'stage': [], 'snap': [],
170+ })
171+
172+ self.assertFalse(self.mock_wiki.get_part.called)
173+
174 def test_config_raises_on_missing_snapcraft_yaml(self):
175 fake_logger = fixtures.FakeLogger(level=logging.ERROR)
176 self.useFixture(fake_logger)
177@@ -99,6 +129,7 @@
178 snapcraft.yaml.Config()
179
180 self.assertEqual(raised.exception.message, 'circular dependency chain found in parts definition')
181+ self.assertFalse(self.mock_wiki.get_part.called)
182
183 @unittest.mock.patch('snapcraft.yaml.Config.load_plugin')
184 def test_invalid_yaml_missing_name(self, mock_loadPlugin):
185
186=== added file 'snapcraft/wiki.py'
187--- snapcraft/wiki.py 1970-01-01 00:00:00 +0000
188+++ snapcraft/wiki.py 2015-09-15 21:52:37 +0000
189@@ -0,0 +1,50 @@
190+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
191+#
192+# Copyright (C) 2015 Canonical Ltd
193+#
194+# This program is free software: you can redistribute it and/or modify
195+# it under the terms of the GNU General Public License version 3 as
196+# published by the Free Software Foundation.
197+#
198+# This program is distributed in the hope that it will be useful,
199+# but WITHOUT ANY WARRANTY; without even the implied warranty of
200+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
201+# GNU General Public License for more details.
202+#
203+# You should have received a copy of the GNU General Public License
204+# along with this program. If not, see <http://www.gnu.org/licenses/>.
205+
206+import logging
207+import requests
208+import yaml
209+
210+PARTS_URI = 'https://wiki.ubuntu.com/Snappy/Parts'
211+PARTS_URI_PARAMS = {'action': 'raw'}
212+
213+_WIKI_OPEN = '{{{'
214+_WIKI_CLOSE = '}}}'
215+
216+logging.getLogger("urllib3").setLevel(logging.CRITICAL)
217+
218+
219+class Wiki:
220+
221+ def __init__(self):
222+ self.wiki_parts = self._fetch()
223+
224+ def _fetch(self):
225+ raw_content = requests.get(PARTS_URI, params=PARTS_URI_PARAMS)
226+ content = raw_content.text.strip()
227+
228+ if content.startswith(_WIKI_OPEN):
229+ content = content[len(_WIKI_OPEN):].strip()
230+ if content.endswith(_WIKI_CLOSE):
231+ content = content[:-len(_WIKI_CLOSE)]
232+
233+ return yaml.load(content)
234+
235+ def get_part(self, name):
236+ try:
237+ return self.wiki_parts[name]
238+ except KeyError:
239+ return None
240
241=== modified file 'snapcraft/yaml.py'
242--- snapcraft/yaml.py 2015-09-08 18:06:03 +0000
243+++ snapcraft/yaml.py 2015-09-15 21:52:37 +0000
244@@ -22,6 +22,7 @@
245 import os.path
246
247 import snapcraft.plugin
248+import snapcraft.wiki
249 from snapcraft import common
250
251
252@@ -114,6 +115,7 @@
253
254 def _compute_part_dependencies(self, after_requests):
255 '''Gather the lists of dependencies and adds to all_parts.'''
256+ w = snapcraft.wiki.Wiki()
257
258 for part in self.all_parts:
259 dep_names = part.config.get('requires', []) + after_requests.get(part.names()[0], [])
260@@ -125,6 +127,11 @@
261 found = True
262 break
263 if not found:
264+ wiki_part = w.get_part(dep)
265+ found = True if wiki_part else False
266+ if found:
267+ part.deps.append(self.load_plugin(dep, wiki_part['type'], wiki_part))
268+ if not found:
269 raise SnapcraftLogicError('part name missing {}'.format(dep))
270
271 def _sort_parts(self):

Subscribers

People subscribed via source and target branches