Merge lp:~sergiusens/snapweb/profileUnconfinedNoScrubSnappy into lp:~stephen-stewart/snapweb/npm-shrinkwrap

Proposed by Sergio Schvezov
Status: Superseded
Proposed branch: lp:~sergiusens/snapweb/profileUnconfinedNoScrubSnappy
Merge into: lp:~stephen-stewart/snapweb/npm-shrinkwrap
Diff against target: 614 lines (+274/-43)
25 files modified
package.json (+1/-1)
pkg/meta/package.yaml (+1/-1)
pkg/meta/readme.md (+2/-2)
pkg/meta/snappyd.profile (+1/-1)
www/src/css/button.css (+50/-0)
www/src/css/headline.css (+6/-0)
www/src/css/icon.css (+1/-0)
www/src/css/snap.css (+1/-1)
www/src/css/snaplist.css (+33/-5)
www/src/js/collections/snaplist.js (+4/-1)
www/src/js/controllers/store.js (+3/-3)
www/src/js/templates/home.hbs (+0/-5)
www/src/js/templates/snap-detail.hbs (+9/-0)
www/src/js/templates/snap-layout.hbs (+3/-1)
www/src/js/templates/snaplist-item.hbs (+3/-2)
www/src/js/templates/snaplist.hbs (+23/-0)
www/src/js/templates/store.hbs (+1/-1)
www/src/js/templates/storelist-item.hbs (+11/-0)
www/src/js/views/home.js (+10/-4)
www/src/js/views/snaplist-item.js (+8/-1)
www/src/js/views/snaplist.js (+61/-10)
www/src/js/views/store.js (+12/-3)
www/src/js/views/storelist-item.js (+10/-0)
www/src/js/views/storelist.js (+7/-0)
www/tests/snapItemViewSpec.js (+13/-1)
To merge this branch: bzr merge lp:~sergiusens/snapweb/profileUnconfinedNoScrubSnappy
Reviewer Review Type Date Requested Status
Stephen Stewart Pending
Review via email: mp+260624@code.launchpad.net

This proposal has been superseded by a proposal from 2015-05-29.

Commit message

Allowing snappy unpack to work by no scrubbing the env in the apparmor profile

To post a comment you must log in.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'package.json'
2--- package.json 2015-05-28 19:37:45 +0000
3+++ package.json 2015-05-29 20:57:09 +0000
4@@ -39,7 +39,7 @@
5 "normalize.css": "^3.0.3",
6 "postcss-bem-linter": "^0.3.0",
7 "postcss-custom-media": "^3.0.0",
8- "pretty-bytes": "^1.0.4",
9+ "pretty-bytes": "^2.0.1",
10 "vinyl-buffer": "~1.0.0",
11 "vinyl-source-stream": "~1.1.0",
12 "watchify": "~3.1.2"
13
14=== modified file 'pkg/meta/package.yaml'
15--- pkg/meta/package.yaml 2015-05-08 19:21:46 +0000
16+++ pkg/meta/package.yaml 2015-05-29 20:57:09 +0000
17@@ -3,7 +3,7 @@
18 icon: meta/webdm-icon.png
19 source: lp:webdm
20 type: framework
21-version: 0.6.1
22+version: 0.7
23 architecture: UNKNOWN_ARCH
24 services:
25 - name: snappyd
26
27=== modified file 'pkg/meta/readme.md'
28--- pkg/meta/readme.md 2014-11-27 11:36:50 +0000
29+++ pkg/meta/readme.md 2015-05-29 20:57:09 +0000
30@@ -1,6 +1,6 @@
31-# Snappyd
32+# Ubuntu Core Snappy Device Manager
33
34-This service allows you to manage your core device from a web interface.
35+This service allows you to manage your Ubuntu Core device from a web interface or REST API.
36
37 Features include:
38
39
40=== modified file 'pkg/meta/snappyd.profile'
41--- pkg/meta/snappyd.profile 2015-05-08 20:15:01 +0000
42+++ pkg/meta/snappyd.profile 2015-05-29 20:57:09 +0000
43@@ -64,7 +64,7 @@
44
45
46 # snappy unpack
47- /usr/bin/snappy Uxr,
48+ /usr/bin/snappy uxr,
49
50 # snappy tty change
51 /dev/tty r,
52
53=== added file 'www/src/css/button.css'
54--- www/src/css/button.css 1970-01-01 00:00:00 +0000
55+++ www/src/css/button.css 2015-05-29 20:57:09 +0000
56@@ -0,0 +1,50 @@
57+/** @define b-button; weak */
58+
59+.b-button__group {
60+ display:flex;
61+}
62+
63+.b-button__group + .b-button__group {
64+ margin-left:8px;
65+}
66+
67+.b-button__group > * {
68+ padding:3px 10px;
69+}
70+
71+.b-button__group .b-button {
72+ border:1px solid #ccc;
73+ border-radius:3px;
74+ background-color:#efefef;
75+ color:#666;
76+ user-select: none;
77+ cursor: pointer;
78+}
79+
80+.b-button__group .b-button_active {
81+ background-color:#fff;
82+}
83+
84+.b-button__group .b-button:hover {
85+ background-color:#fff;
86+}
87+
88+.b-button__group .b-button:nth-of-type(1) {
89+ border-right:none;
90+ border-top-right-radius:0;
91+ border-bottom-right-radius:0;
92+}
93+
94+.b-button__group .b-button:nth-last-of-type(1) {
95+ border-top-left-radius:0;
96+ border-bottom-left-radius:0;
97+}
98+
99+.b-button__group .b-button:not(:nth-of-type(1)):not(:nth-last-of-type(1)) {
100+ border-right:none;
101+ border-radius:0;
102+}
103+
104+.b-button__group .b-button:nth-of-type(1):nth-last-of-type(1) {
105+ border-radius:3px;
106+}
107
108=== modified file 'www/src/css/headline.css'
109--- www/src/css/headline.css 2015-05-22 12:46:22 +0000
110+++ www/src/css/headline.css 2015-05-29 20:57:09 +0000
111@@ -3,7 +3,13 @@
112 .b-headline {
113 }
114
115+.b-headline .b-layout__container {
116+ display:flex;
117+ align-items: baseline;
118+}
119+
120 .b-headline__h1 {
121+ flex:1;
122 font-size:18px;
123 font-weight:400;
124 margin:20px 15px 5px 15px;
125
126=== modified file 'www/src/css/icon.css'
127--- www/src/css/icon.css 2015-05-21 16:11:37 +0000
128+++ www/src/css/icon.css 2015-05-29 20:57:09 +0000
129@@ -15,6 +15,7 @@
130 background-repeat:no-repeat;
131 background-position:50% 50%;
132 background-size:100% 100%;
133+ z-index:10;
134 }
135
136 .b-icon img {
137
138=== modified file 'www/src/css/snap.css'
139--- www/src/css/snap.css 2015-05-22 15:21:34 +0000
140+++ www/src/css/snap.css 2015-05-29 20:57:09 +0000
141@@ -63,5 +63,5 @@
142 }
143
144 .b-snap__tab-content {
145- padding:1.3em 3em 1.3em;
146+ padding:1.3em 0;
147 }
148
149=== modified file 'www/src/css/snaplist.css'
150--- www/src/css/snaplist.css 2015-05-22 12:46:22 +0000
151+++ www/src/css/snaplist.css 2015-05-29 20:57:09 +0000
152@@ -5,9 +5,13 @@
153
154 .b-snaplist__item {
155 cursor: pointer;
156- font-size:0;
157 }
158
159+.b-snaplist__actions {
160+ display:flex;
161+ font-size: 11px;
162+ justify-content: flex-end;
163+}
164
165 /** grid style **/
166
167@@ -19,6 +23,13 @@
168 .b-snaplist_grid .b-snaplist__item {
169 flex: 0 1 auto;
170 padding:7px;
171+ font-size:0;
172+}
173+
174+.b-snaplist_grid .b-snaplist__item * {
175+ font-size: 12px;
176+ color:#999;
177+ text-align: center;
178 }
179
180 .b-snaplist_grid .b-snaplist__name {
181@@ -26,8 +37,6 @@
182 white-space: nowrap;
183 overflow: hidden;
184 text-overflow: ellipsis;
185- font-size:12px;
186- color:#999;
187 margin-top:4px;
188 }
189
190@@ -36,7 +45,25 @@
191 width:90px;
192 }
193
194-.b-snaplist_grid .b-snaplist__name ~ * {
195+.b-snaplist_grid :not(.b-snaplist__item-app) .b-icon::after {
196+ content: attr(data-type);
197+ position:absolute;
198+ width:100%;
199+ bottom:0;
200+ left:0;
201+ right:0;
202+ background: rgba(221,72,20,0.8);
203+ color:#fff;
204+ z-index:0;
205+ padding:3px 0 5px;
206+ text-transform:uppercase;
207+ font-size:10px;
208+}
209+
210+.b-snaplist_grid .b-snaplist__version,
211+.b-snaplist_grid .b-snaplist__type,
212+.b-snaplist_grid .b-snaplist__origin,
213+.b-snaplist_grid .b-snaplist__actions {
214 display:none;
215 }
216
217@@ -61,7 +88,7 @@
218 /** row style **/
219
220 .b-snaplist_row {
221- margin:3em;
222+ margin:1em 0;
223 }
224
225 .b-snaplist_row .b-snaplist__item {
226@@ -88,6 +115,7 @@
227 background-image: url(/public/images/icon-mask-on-white.png);
228 }
229
230+
231 .b-snaplist_row .b-icon img {
232 display:block;
233 width: 40px;
234
235=== modified file 'www/src/js/collections/snaplist.js'
236--- www/src/js/collections/snaplist.js 2015-04-24 11:15:41 +0000
237+++ www/src/js/collections/snaplist.js 2015-05-29 20:57:09 +0000
238@@ -7,5 +7,8 @@
239
240 module.exports = Backbone.Collection.extend({
241 url: CONF.PACKAGES,
242- model: Snap
243+ model: Snap,
244+ comparator: function(model) {
245+ return model.get('name');
246+ }
247 });
248
249=== modified file 'www/src/js/controllers/store.js'
250--- www/src/js/controllers/store.js 2015-04-24 11:15:41 +0000
251+++ www/src/js/controllers/store.js 2015-05-29 20:57:09 +0000
252@@ -2,14 +2,14 @@
253 var Marionette = require('backbone.marionette');
254 var Radio = require('backbone.radio');
255 var StoreLayoutView = require('../views/store.js');
256-var Bask = require('../collections/snaplist.js');
257+var Snaplist = require('../collections/snaplist.js');
258
259 module.exports = {
260 index: function() {
261 var chan = Radio.channel('root');
262- var storeBask = new Bask();
263+ var storeSnaplist = new Snaplist();
264
265- storeBask.fetch({
266+ storeSnaplist.fetch({
267 success: function(snaplist) {
268 var view = new StoreLayoutView({
269 collection: snaplist
270
271=== modified file 'www/src/js/templates/home.hbs'
272--- www/src/js/templates/home.hbs 2015-05-22 12:46:22 +0000
273+++ www/src/js/templates/home.hbs 2015-05-29 20:57:09 +0000
274@@ -1,6 +1,1 @@
275-<div class="b-headline">
276- <div class="b-layout__container">
277- <h1 class="b-headline__h1">Installed snaps</h1>
278- </div>
279-</div>
280 <div class="region-installed"></div>
281
282=== modified file 'www/src/js/templates/snap-detail.hbs'
283--- www/src/js/templates/snap-detail.hbs 2015-05-26 11:30:56 +0000
284+++ www/src/js/templates/snap-detail.hbs 2015-05-29 20:57:09 +0000
285@@ -0,0 +1,9 @@
286+{{#if description}}
287+<p>{{ description }}</p>
288+{{/if}}
289+{{#if prettyInstalledSize}}
290+<p>Installed size: {{prettyInstalledSize}}</p>
291+{{/if}}
292+{{#if prettyDownloadSize}}
293+<p>Download size: {{prettyDownloadSize}}</p>
294+{{/if}}
295
296=== modified file 'www/src/js/templates/snap-layout.hbs'
297--- www/src/js/templates/snap-layout.hbs 2015-05-22 15:21:34 +0000
298+++ www/src/js/templates/snap-layout.hbs 2015-05-29 20:57:09 +0000
299@@ -16,4 +16,6 @@
300 </div>
301 </div>
302 <div class="region-menu"></div>
303-<div class="region-tab"></div>
304+<div class="b-layout__container">
305+ <div class="region-tab"></div>
306+</div>
307
308=== modified file 'www/src/js/templates/snaplist-item.hbs'
309--- www/src/js/templates/snaplist-item.hbs 2015-05-21 16:11:37 +0000
310+++ www/src/js/templates/snaplist-item.hbs 2015-05-29 20:57:09 +0000
311@@ -1,11 +1,12 @@
312-<div class="b-icon">
313+<div class="b-icon" data-type="{{type}}">
314 <img src="{{ icon }}" width="90" height="90">
315 </div>
316 <div class="b-snaplist__name">{{ name }}</div>
317 {{!-- only name is shown in grid view, everything after is hidden --}}
318+<div class="b-snaplist__size" title="Installed file size">{{ prettyInstalledSize }}</div>
319 <div class="b-snaplist__version">{{ version }}</div>
320+<div class="b-snaplist__type">{{ type }}</div>
321 <div class="b-snaplist__origin">{{ origin }}</div>
322-<div class="b-snaplist__type">{{ type }}</div>
323 <div class="b-snaplist__actions">
324 {{> installer}}
325 </div>
326
327=== added file 'www/src/js/templates/snaplist.hbs'
328--- www/src/js/templates/snaplist.hbs 1970-01-01 00:00:00 +0000
329+++ www/src/js/templates/snaplist.hbs 2015-05-29 20:57:09 +0000
330@@ -0,0 +1,23 @@
331+{{#if title}}
332+<div class="b-headline">
333+ <div class="b-layout__container">
334+ <h1 class="b-headline__h1">{{ title }}</h1>
335+ <div class="b-snaplist__actions">
336+ {{#if canSort}}
337+ <div class="b-button__group">
338+ <div id="sortAlpha" class="b-button b-button_small{{#if isAlpha}} b-button_active{{/if}}">A-Z</div>
339+ <div id="sortBytes" class="b-button b-button_small{{#unless isAlpha}} b-button_active{{/unless}}">kB</div>
340+ </div>
341+ {{/if}}
342+ {{#if canStyle}}
343+ <div class="b-button__group">
344+ <div id="styleGrid" class="b-button b-button_small{{#if isGrid}} b-button_active{{/if}}">Grid</div>
345+ <div id="styleRow" class="b-button b-button_small{{#unless isGrid}} b-button_active{{/unless}}">Row</div>
346+ </div>
347+ {{/if}}
348+ </div>
349+ </div>
350+</div>
351+{{/if}}
352+<div class="b-snaplist b-snaplist_{{#if isGrid}}grid{{else}}row{{/if}}">
353+</div>
354
355=== modified file 'www/src/js/templates/store.hbs'
356--- www/src/js/templates/store.hbs 2015-05-21 16:11:37 +0000
357+++ www/src/js/templates/store.hbs 2015-05-29 20:57:09 +0000
358@@ -1,1 +1,1 @@
359-<div class="region-product"></div>
360+<div class="region-snaplist"></div>
361
362=== added file 'www/src/js/templates/storelist-item.hbs'
363--- www/src/js/templates/storelist-item.hbs 1970-01-01 00:00:00 +0000
364+++ www/src/js/templates/storelist-item.hbs 2015-05-29 20:57:09 +0000
365@@ -0,0 +1,11 @@
366+<div class="b-icon" data-type="{{type}}">
367+ <img src="{{ icon }}" width="90" height="90">
368+</div>
369+<div class="b-snaplist__name">{{ name }}</div>
370+{{!-- only name is shown in grid view, everything after is hidden --}}
371+<div class="b-snaplist__version">{{ version }}</div>
372+<div class="b-snaplist__type">{{ type }}</div>
373+<div class="b-snaplist__origin">{{ origin }}</div>
374+<div class="b-snaplist__actions">
375+ {{> installer}}
376+</div>
377
378=== modified file 'www/src/js/views/home.js'
379--- www/src/js/views/home.js 2015-05-22 12:46:22 +0000
380+++ www/src/js/views/home.js 2015-05-29 20:57:09 +0000
381@@ -1,7 +1,7 @@
382 // home view
383 var Backbone = require('backbone');
384 var Marionette = require('backbone.marionette');
385-var BaskView = require('./snaplist.js');
386+var SnapListView = require('./snaplist.js');
387 var template = require('../templates/home.hbs');
388
389 module.exports = Backbone.Marionette.LayoutView.extend({
390@@ -14,9 +14,15 @@
391
392 onBeforeShow: function() {
393 // TODO if collection empty use emptyView
394- this.showChildView('installedRegion', new BaskView({
395- collection: this.collection,
396- style: 'grid'
397+ this.showChildView('installedRegion', new SnapListView({
398+ model: new Backbone.Model({
399+ title: 'Installed snaps',
400+ isGrid: true,
401+ isAlpha: true,
402+ canSort: true,
403+ canStyle: true
404+ }),
405+ collection: this.collection
406 }));
407 },
408
409
410=== modified file 'www/src/js/views/snaplist-item.js'
411--- www/src/js/views/snaplist-item.js 2015-05-08 14:53:07 +0000
412+++ www/src/js/views/snaplist-item.js 2015-05-29 20:57:09 +0000
413@@ -13,7 +13,14 @@
414
415 module.exports = Marionette.ItemView.extend({
416
417- className: 'b-snaplist__item',
418+ className: function() {
419+ var type = this.model.get('type');
420+ var className = 'b-snaplist__item';
421+ if (type) {
422+ className += ' b-snaplist__item-' + type;
423+ }
424+ return className;
425+ },
426
427 template: function(model) {
428 return template(model);
429
430=== modified file 'www/src/js/views/snaplist.js'
431--- www/src/js/views/snaplist.js 2015-05-08 20:03:48 +0000
432+++ www/src/js/views/snaplist.js 2015-05-29 20:57:09 +0000
433@@ -1,21 +1,72 @@
434 // snaplist view
435 var _ = require('lodash');
436+var $ = require('jquery');
437 var Backbone = require('backbone');
438+Backbone.$ = $;
439 var Marionette = require('backbone.marionette');
440 var SnaplistItemView = require('../views/snaplist-item.js');
441 var EmptySnaplistView = require('./empty-snaplist.js');
442+var template = require('../templates/snaplist.hbs');
443 var CONF = require('../config.js');
444
445-module.exports = Marionette.CollectionView.extend({
446-
447- className: function() {
448- var style = this.options.style || 'row';
449-
450- if (style === 'row') {
451- return 'b-snaplist b-snaplist_row';
452- } else if (style === 'grid') {
453- return 'b-snaplist b-snaplist_grid';
454- }
455+module.exports = Marionette.CompositeView.extend({
456+
457+ childViewContainer: '.b-snaplist',
458+
459+ template : function(model) {
460+ return template(model);
461+ },
462+
463+ ui: {
464+ 'sortAlpha': '#sortAlpha',
465+ 'sortBytes': '#sortBytes',
466+ 'styleRow': '#styleRow',
467+ 'styleGrid': '#styleGrid'
468+ },
469+
470+ events: {
471+ 'click @ui.sortBytes': 'sortBytes',
472+ 'click @ui.sortAlpha': 'sortAlpha',
473+ 'click @ui.styleRow': 'styleRow',
474+ 'click @ui.styleGrid': 'styleGrid'
475+ },
476+
477+ sortAlpha: function() {
478+ this.model.set('isAlpha', true);
479+ this.viewComparator = function(model) {
480+ return model.get('name');
481+ };
482+ this.render();
483+ },
484+
485+ sortBytes: function() {
486+ this.model.set('isAlpha', false);
487+ this.viewComparator = function(model) {
488+ return -model.get('installed_size');
489+ };
490+ this.render();
491+ },
492+
493+ styleGrid: function() {
494+ this.model.set('isGrid', true);
495+
496+ this.$('.b-snaplist')
497+ .removeClass('b-snaplist_row')
498+ .addClass('b-snaplist_grid');
499+
500+ this.$('#styleRow').removeClass('b-button_active');
501+ this.$('#styleGrid').addClass('b-button_active');
502+ },
503+
504+ styleRow: function() {
505+ this.model.set('isGrid', false);
506+
507+ this.$('.b-snaplist')
508+ .removeClass('b-snaplist_grid')
509+ .addClass('b-snaplist_row');
510+
511+ this.$('#styleGrid').removeClass('b-button_active');
512+ this.$('#styleRow').addClass('b-button_active');
513 },
514
515 childView: SnaplistItemView,
516
517=== modified file 'www/src/js/views/store.js'
518--- www/src/js/views/store.js 2015-04-24 20:47:44 +0000
519+++ www/src/js/views/store.js 2015-05-29 20:57:09 +0000
520@@ -1,22 +1,31 @@
521 // store layout view
522 var Backbone = require('backbone');
523 var Marionette = require('backbone.marionette');
524-var BaskView = require('./snaplist.js');
525+var StorelistView = require('./storelist.js');
526 var template = require('../templates/store.hbs');
527
528 module.exports = Backbone.Marionette.LayoutView.extend({
529
530+ className: 'b-layout__container',
531+
532 template : function() {
533 return template();
534 },
535
536 onBeforeShow: function() {
537- this.showChildView('productRegion', new BaskView({
538+ this.showChildView('store', new StorelistView({
539+ model: new Backbone.Model({
540+ title: 'Store snaps',
541+ isGrid: false,
542+ isAlpha: true,
543+ canSort: false,
544+ canStyle: true
545+ }),
546 collection: this.collection
547 }));
548 },
549
550 regions: {
551- productRegion: '.region-product'
552+ store: '.region-snaplist'
553 }
554 });
555
556=== added file 'www/src/js/views/storelist-item.js'
557--- www/src/js/views/storelist-item.js 1970-01-01 00:00:00 +0000
558+++ www/src/js/views/storelist-item.js 2015-05-29 20:57:09 +0000
559@@ -0,0 +1,10 @@
560+// store list item view
561+
562+var SnapListItemView = require('./snaplist-item.js');
563+var template = require('../templates/storelist-item.hbs');
564+
565+module.exports = SnapListItemView.extend({
566+ template: function(model) {
567+ return template(model);
568+ }
569+});
570
571=== added file 'www/src/js/views/storelist.js'
572--- www/src/js/views/storelist.js 1970-01-01 00:00:00 +0000
573+++ www/src/js/views/storelist.js 2015-05-29 20:57:09 +0000
574@@ -0,0 +1,7 @@
575+// storelist view
576+var Snaplist = require('./snaplist.js');
577+var StorelistItemView = require('./storelist-item.js');
578+
579+module.exports = Snaplist.extend({
580+ childView: StorelistItemView
581+});
582
583=== modified file 'www/tests/snapItemViewSpec.js'
584--- www/tests/snapItemViewSpec.js 2015-05-05 14:40:14 +0000
585+++ www/tests/snapItemViewSpec.js 2015-05-29 20:57:09 +0000
586@@ -1,10 +1,15 @@
587 var Backbone = require('backbone');
588+var Snap = require('../src/js/models/snap.js');
589 var SnapItemView = require('../src/js/views/snaplist-item.js');
590
591 describe('SnapItemView', function() {
592
593 beforeEach(function() {
594- this.view = new SnapItemView();
595+ this.view = new SnapItemView({
596+ model: new Snap({
597+ id: 'foo'
598+ })
599+ });
600 });
601
602 afterEach(function() {
603@@ -16,4 +21,11 @@
604 expect(this.view).toEqual(jasmine.any(Backbone.View));
605 });
606
607+ it('should have a b-snaplist className with type modifier when present in model', function() {
608+ this.view.model.unset('type');
609+ expect(this.view.className()).toBe('b-snaplist__item');
610+ this.view.model.set('type', 'foo');
611+ expect(this.view.className()).toBe('b-snaplist__item b-snaplist__item-foo');
612+ });
613+
614 });

Subscribers

People subscribed via source and target branches