Merge lp:click/devel into lp:click

Proposed by Michael Vogt
Status: Merged
Approved by: Michael Vogt
Approved revision: 562
Merged at revision: 454
Proposed branch: lp:click/devel
Merge into: lp:click
Diff against target: 798 lines (+285/-160)
14 files modified
click/build.py (+48/-71)
click/commands/build.py (+5/-0)
click/commands/buildsource.py (+6/-0)
click/framework.py (+19/-13)
click/tests/helpers.py (+21/-0)
click/tests/test_build.py (+37/-35)
click/tests/test_database.py (+12/-0)
click/tests/test_user.py (+22/-8)
debian/changelog (+17/-0)
debian/rules (+1/-1)
doc/manpage.rst (+12/-2)
lib/click/database.vala (+29/-3)
lib/click/user.vala (+48/-27)
pk-plugin/pk-plugin-click.c (+8/-0)
To merge this branch: bzr merge lp:click/devel
Reviewer Review Type Date Requested Status
click hackers Pending
Review via email: mp+250584@code.launchpad.net

Commit message

Click 0.4.38: stop apps when uninstalling them, fix crash on empty db, add --ignore option to click build, fix framework validation for snappy frameworks

Description of the change

click (0.4.38) UNRELEASED; urgency=low

  * lp:~mvo/click/lp1232130-kill-on-remove-2:
    - When uninstalling a app, stop it if its running (LP: #1232130)
  * lp:~mvo/click/dont-crash-for-empty-db:
    - Do not crash when no database configuration is used and
      Click.DB.{get,props.overlay,gc,ensure_ownership} are called.
  * lp:~mvo/click/lp1219912-build-exclude:
    - add a new --ignore option to click {build,buildsource}
      (LP: #1219912)
  * lp:~mvo/click/fix-multiple-framework-validation:
    - fix framework validation for snappy

 -- Michael Vogt <email address hidden> Mon, 23 Feb 2015 08:20:04 +0100

To post a comment you must log in.
lp:click/devel updated
563. By Michael Vogt

merged lp:~mvo/click/fix-options-ignore

564. By Michael Vogt

bump version number

565. By Michael Vogt

bump version number

566. By Michael Vogt

run debian/packagekit-check with "sh" as something in jenkins
made it mode 0644

567. By Michael Vogt

merged lp:~mvo/click/fix-autopkgtest

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'click/build.py'
2--- click/build.py 2015-01-19 10:26:26 +0000
3+++ click/build.py 2015-02-26 17:06:20 +0000
4@@ -83,6 +83,42 @@
5 class ClickBuilderBase:
6 def __init__(self):
7 self.file_map = {}
8+ # From @Dpkg::Source::Package::tar_ignore_default_pattern.
9+ # (more in ClickSourceBuilder)
10+ self._ignore_patterns = [
11+ "*.click",
12+ ".*.sw?",
13+ "*~",
14+ ",,*",
15+ ".[#~]*",
16+ ".arch-ids",
17+ ".arch-inventory",
18+ ".bzr",
19+ ".bzr-builddeb",
20+ ".bzr.backup",
21+ ".bzr.tags",
22+ ".bzrignore",
23+ ".cvsignore",
24+ ".git",
25+ ".gitattributes",
26+ ".gitignore",
27+ ".gitmodules",
28+ ".hg",
29+ ".hgignore",
30+ ".hgsigs",
31+ ".hgtags",
32+ ".shelf",
33+ ".svn",
34+ "CVS",
35+ "DEADJOE",
36+ "RCS",
37+ "_MTN",
38+ "_darcs",
39+ "{arch}",
40+ ]
41+
42+ def add_ignore_pattern(self, pattern):
43+ self._ignore_patterns.append(pattern)
44
45 def add_file(self, source_path, dest_path):
46 self.file_map[source_path] = dest_path
47@@ -132,39 +168,6 @@
48
49
50 class ClickBuilder(ClickBuilderBase):
51- # TODO: This should be configurable, or at least extensible.
52- _ignore_patterns = [
53- "*.click",
54- ".*.sw?",
55- "*~",
56- ",,*",
57- ".[#~]*",
58- ".arch-ids",
59- ".arch-inventory",
60- ".be",
61- ".bzr",
62- ".bzr-builddeb",
63- ".bzr.backup",
64- ".bzr.tags",
65- ".bzrignore",
66- ".cvsignore",
67- ".git",
68- ".gitattributes",
69- ".gitignore",
70- ".gitmodules",
71- ".hg",
72- ".hgignore",
73- ".hgsigs",
74- ".hgtags",
75- ".shelf",
76- ".svn",
77- "CVS",
78- "DEADJOE",
79- "RCS",
80- "_MTN",
81- "_darcs",
82- "{arch}",
83- ]
84
85 def list_files(self, root_path):
86 for dirpath, _, filenames in os.walk(root_path):
87@@ -298,44 +301,18 @@
88
89
90 class ClickSourceBuilder(ClickBuilderBase):
91- # From @Dpkg::Source::Package::tar_ignore_default_pattern.
92- # TODO: This should be configurable, or at least extensible.
93- _ignore_patterns = [
94- "*.a",
95- "*.click",
96- "*.la",
97- "*.o",
98- "*.so",
99- ".*.sw?",
100- "*~",
101- ",,*",
102- ".[#~]*",
103- ".arch-ids",
104- ".arch-inventory",
105- ".be",
106- ".bzr",
107- ".bzr-builddeb",
108- ".bzr.backup",
109- ".bzr.tags",
110- ".bzrignore",
111- ".cvsignore",
112- ".deps",
113- ".git",
114- ".gitattributes",
115- ".gitignore",
116- ".gitmodules",
117- ".hg",
118- ".hgignore",
119- ".hgsigs",
120- ".hgtags",
121- ".shelf",
122- ".svn",
123- "CVS",
124- "DEADJOE",
125- "RCS",
126- "_MTN",
127- "_darcs",
128- "{arch}",
129+
130+ def __init__(self):
131+ super(ClickSourceBuilder, self).__init__()
132+ # From @Dpkg::Source::Package::tar_ignore_default_pattern.
133+ # (more in ClickBuilderBase)
134+ self._ignore_patterns += [
135+ "*.a",
136+ ".be",
137+ ".deps",
138+ "*.la",
139+ "*.o",
140+ "*.so",
141 ]
142
143 def build(self, dest_dir, manifest_path=None):
144
145=== modified file 'click/commands/build.py'
146--- click/commands/build.py 2014-09-05 14:03:19 +0000
147+++ click/commands/build.py 2015-02-26 17:06:20 +0000
148@@ -34,6 +34,9 @@
149 parser.add_option(
150 "--no-validate", action="store_false", default=True, dest="validate",
151 help="Don't run click-reviewers-tools check on resulting .click")
152+ parser.add_option(
153+ "-I", "--ignore", metavar="file-pattern", action='append', default=[],
154+ help="Ignore the given pattern when building the package")
155 options, args = parser.parse_args(argv)
156 if len(args) < 1:
157 parser.error("need directory")
158@@ -48,6 +51,8 @@
159 (directory, options.manifest))
160 builder = ClickBuilder()
161 builder.add_file(directory, "./")
162+ for ignore in options.ignore:
163+ builder.add_ignore_pattern(ignore)
164 try:
165 path = builder.build(".", manifest_path=options.manifest)
166 except ClickBuildError as e:
167
168=== modified file 'click/commands/buildsource.py'
169--- click/commands/buildsource.py 2014-06-17 08:25:27 +0000
170+++ click/commands/buildsource.py 2015-02-26 17:06:20 +0000
171@@ -29,6 +29,10 @@
172 parser.add_option(
173 "-m", "--manifest", metavar="PATH",
174 help="read package manifest from PATH")
175+ parser.add_option(
176+ "-I", "--ignore", metavar="file-pattern", action='append',
177+ default=[],
178+ help="Ignore the given pattern when building the package")
179 options, args = parser.parse_args(argv)
180 if len(args) < 1:
181 parser.error("need directory")
182@@ -45,6 +49,8 @@
183 (directory, options.manifest))
184 builder = ClickSourceBuilder()
185 builder.add_file(directory, "./")
186+ for ignore in options.ignore:
187+ builder.add_ignore_pattern(ignore)
188 try:
189 path = builder.build(".", manifest_path=options.manifest)
190 except ClickBuildError as e:
191
192=== modified file 'click/framework.py'
193--- click/framework.py 2014-06-23 21:14:06 +0000
194+++ click/framework.py 2015-02-26 17:06:20 +0000
195@@ -31,12 +31,6 @@
196 pass
197
198
199-# FIXME: use native lib if available
200-#from gi.repository import Click
201-#click_framework_get_base_version = Click.framework_get_base_version
202-#click_framework_has_framework = Click.has_framework
203-
204-
205 # python version of the vala parse_deb822_file()
206 def parse_deb822_file(filename):
207 data = {}
208@@ -76,6 +70,12 @@
209 return deb822.get("base-version", None)
210
211
212+# python version of the vala click_framework_get_base_version()
213+def click_framework_get_base_name(framework_name):
214+ deb822 = parse_deb822_file(get_framework_path(framework_name))
215+ return deb822.get("base-name", None)
216+
217+
218 # python version of the vala click_framework_has_framework
219 def click_framework_has_framework(framework_name):
220 return os.path.exists(get_framework_path(framework_name))
221@@ -94,7 +94,7 @@
222 raise ClickFrameworkInvalid(
223 'Could not parse framework "%s"' % framework_string)
224
225- framework_base_versions = set()
226+ base_name_versions = {}
227 missing_frameworks = []
228 for or_dep in parsed_framework:
229 if len(or_dep) > 1:
230@@ -110,9 +110,20 @@
231 if not click_framework_has_framework(framework_name):
232 missing_frameworks.append(framework_name)
233 continue
234+ # ensure we do not use different base versions for the same base-name
235+ framework_base_name = click_framework_get_base_name(
236+ framework_name)
237 framework_base_version = click_framework_get_base_version(
238 framework_name)
239- framework_base_versions.add(framework_base_version)
240+ prev = base_name_versions.get(framework_base_name, None)
241+ if prev and prev != framework_base_version:
242+ raise ClickFrameworkInvalid(
243+ 'Multiple frameworks with different base versions are not '
244+ 'allowed. Found: {} ({} != {})'.format(
245+ framework_base_name,
246+ framework_base_version,
247+ base_name_versions[framework_base_name]))
248+ base_name_versions[framework_base_name] = framework_base_version
249
250 if not ignore_missing_frameworks:
251 if len(missing_frameworks) > 1:
252@@ -132,8 +143,3 @@
253 elif missing_frameworks:
254 logging.warning('Ignoring missing framework "%s"' % (
255 missing_frameworks[0]))
256-
257- if len(framework_base_versions) > 1:
258- raise ClickFrameworkInvalid(
259- 'Multiple frameworks with different base versions are not '
260- 'allowed. Found: {0}'.format(framework_base_versions))
261
262=== modified file 'click/tests/helpers.py'
263--- click/tests/helpers.py 2014-09-29 13:23:52 +0000
264+++ click/tests/helpers.py 2015-02-26 17:06:20 +0000
265@@ -30,6 +30,7 @@
266
267 import contextlib
268 from functools import wraps
269+import json
270 import os
271 import re
272 import shutil
273@@ -59,6 +60,26 @@
274 return wrapper
275
276
277+def make_installed_click(db, db_dir, package="test-1", version="1.0",
278+ json_data={}, make_current=True, user="@all"):
279+ """Create a fake installed click package for the given db/db_dir"""
280+ json_data["name"] = package
281+ json_data["version"] = version
282+ with mkfile_utf8(os.path.join(
283+ db_dir, package, version, ".click", "info",
284+ "%s.manifest" % package)) as f:
285+ json.dump(json_data, f, ensure_ascii=False)
286+ if make_current:
287+ os.symlink(
288+ version, os.path.join(db_dir, package, "current"))
289+ if user == "@all":
290+ registry = Click.User.for_all_users(db)
291+ else:
292+ registry = Click.User.for_user(db, user)
293+ registry.set_version(package, version)
294+ return os.path.join(db_dir, package, version)
295+
296+
297 class TestCase(gimock.GIMockTestCase):
298 def setUp(self):
299 super(TestCase, self).setUp()
300
301=== modified file 'click/tests/test_build.py'
302--- click/tests/test_build.py 2015-01-19 10:26:26 +0000
303+++ click/tests/test_build.py 2015-02-26 17:06:20 +0000
304@@ -207,21 +207,37 @@
305 self.assertEqual(
306 "foo", os.readlink(os.path.join(extract_path, "bin", "bar")))
307
308+ def _make_scratch_dir(self, manifest_override={}):
309+ self.use_temp_dir()
310+ scratch = os.path.join(self.temp_dir, "scratch")
311+ manifest = {
312+ "name": "com.example.test",
313+ "version": "1.0",
314+ "maintainer": "Foo Bar <foo@example.org>",
315+ "title": "test title",
316+ "architecture": "all",
317+ "framework": "ubuntu-sdk-13.10",
318+ }
319+ manifest.update(manifest_override)
320+ with mkfile(os.path.join(scratch, "manifest.json")) as f:
321+ json.dump(manifest, f)
322+ self.builder.add_file(scratch, "/")
323+ return scratch
324+
325 @disable_logging
326 def test_build_excludes_dot_click(self):
327- self.use_temp_dir()
328- scratch = os.path.join(self.temp_dir, "scratch")
329+ scratch = self._make_scratch_dir()
330 touch(os.path.join(scratch, ".click", "evil-file"))
331- with mkfile(os.path.join(scratch, "manifest.json")) as f:
332- json.dump({
333- "name": "com.example.test",
334- "version": "1.0",
335- "maintainer": "Foo Bar <foo@example.org>",
336- "title": "test title",
337- "architecture": "all",
338- "framework": "ubuntu-sdk-13.10",
339- }, f)
340+ path = self.builder.build(self.temp_dir)
341+ extract_path = os.path.join(self.temp_dir, "extract")
342+ subprocess.check_call(["dpkg-deb", "-x", path, extract_path])
343+ self.assertEqual([], os.listdir(extract_path))
344+
345+ def test_build_ignore_pattern(self):
346+ scratch = self._make_scratch_dir()
347+ touch(os.path.join(scratch, "build", "foo.o"))
348 self.builder.add_file(scratch, "/")
349+ self.builder.add_ignore_pattern("build")
350 path = self.builder.build(self.temp_dir)
351 extract_path = os.path.join(self.temp_dir, "extract")
352 subprocess.check_call(["dpkg-deb", "-x", path, extract_path])
353@@ -229,18 +245,9 @@
354
355 @disable_logging
356 def test_build_multiple_architectures(self):
357- self.use_temp_dir()
358- scratch = os.path.join(self.temp_dir, "scratch")
359- with mkfile(os.path.join(scratch, "manifest.json")) as f:
360- json.dump({
361- "name": "com.example.test",
362- "version": "1.0",
363- "maintainer": "Foo Bar <foo@example.org>",
364- "title": "test title",
365+ scratch = self._make_scratch_dir(manifest_override={
366 "architecture": ["armhf", "i386"],
367- "framework": "ubuntu-sdk-13.10",
368- }, f)
369- self.builder.add_file(scratch, "/")
370+ })
371 path = os.path.join(self.temp_dir, "com.example.test_1.0_multi.click")
372 self.assertEqual(path, self.builder.build(self.temp_dir))
373 self.assertTrue(os.path.exists(path))
374@@ -255,22 +262,12 @@
375 del target_json["installed-size"]
376 self.assertEqual(source_json, target_json)
377
378- # FIXME: DRY violation with test_build_multiple_architectures etc
379 @disable_logging
380 def test_build_multiple_frameworks(self):
381- self.use_temp_dir()
382- scratch = os.path.join(self.temp_dir, "scratch")
383- with mkfile(os.path.join(scratch, "manifest.json")) as f:
384- json.dump({
385- "name": "com.example.test",
386- "version": "1.0",
387- "maintainer": "Foo Bar <foo@example.org>",
388- "title": "test title",
389- "architecture": "all",
390+ scratch = self._make_scratch_dir(manifest_override={
391 "framework":
392 "ubuntu-sdk-14.04-basic, ubuntu-sdk-14.04-webapps",
393- }, f)
394- self.builder.add_file(scratch, "/")
395+ })
396 path = self.builder.build(self.temp_dir)
397 control_path = os.path.join(self.temp_dir, "control")
398 subprocess.check_call(["dpkg-deb", "-e", path, control_path])
399@@ -289,13 +286,15 @@
400 self.builder = ClickBuilder()
401 for framework_name in ("ubuntu-sdk-13.10",
402 "ubuntu-sdk-14.04-papi",
403- "ubuntu-sdk-14.04-html"):
404+ "ubuntu-sdk-14.04-html",
405+ "docker-sdk-1.3"):
406 self._create_mock_framework_file(framework_name)
407
408 def test_validate_framework_good(self):
409 valid_framework_values = (
410 "ubuntu-sdk-13.10",
411 "ubuntu-sdk-14.04-papi, ubuntu-sdk-14.04-html",
412+ "ubuntu-sdk-13.10, docker-sdk-1.3",
413 )
414 for framework in valid_framework_values:
415 self.builder._validate_framework(framework)
416@@ -322,6 +321,8 @@
417 scratch = os.path.join(self.temp_dir, "scratch")
418 touch(os.path.join(scratch, "bin", "foo"))
419 touch(os.path.join(scratch, ".git", "config"))
420+ touch(os.path.join(scratch, "foo.so"))
421+ touch(os.path.join(scratch, "build", "meep.goah"))
422 with mkfile(os.path.join(scratch, "manifest.json")) as f:
423 json.dump({
424 "name": "com.example.test",
425@@ -334,6 +335,7 @@
426 # build() overrides this back to 0o644
427 os.fchmod(f.fileno(), 0o600)
428 self.builder.add_file(scratch, "./")
429+ self.builder.add_ignore_pattern("build")
430 path = os.path.join(self.temp_dir, "com.example.test_1.0.tar.gz")
431 self.assertEqual(path, self.builder.build(self.temp_dir))
432 self.assertTrue(os.path.exists(path))
433
434=== modified file 'click/tests/test_database.py'
435--- click/tests/test_database.py 2014-09-10 11:54:14 +0000
436+++ click/tests/test_database.py 2015-02-26 17:06:20 +0000
437@@ -562,6 +562,18 @@
438 db = Click.DB()
439 self.assertEqual(0, db.props.size)
440
441+ def test_no_db_conf_errors(self):
442+ db = Click.DB()
443+ self.assertRaisesDatabaseError(
444+ Click.DatabaseError.INVALID, db.get, 0)
445+ self.assertEqual(db.props.overlay, "")
446+ self.assertRaisesDatabaseError(
447+ Click.DatabaseError.INVALID, db.maybe_remove, "something", "1.0")
448+ self.assertRaisesDatabaseError(
449+ Click.DatabaseError.INVALID, db.gc)
450+ self.assertRaisesDatabaseError(
451+ Click.DatabaseError.INVALID, db.ensure_ownership)
452+
453 def test_read_nonexistent(self):
454 db = Click.DB()
455 db.read(db_dir=os.path.join(self.temp_dir, "nonexistent"))
456
457=== modified file 'click/tests/test_user.py'
458--- click/tests/test_user.py 2014-09-29 11:12:52 +0000
459+++ click/tests/test_user.py 2015-02-26 17:06:20 +0000
460@@ -34,6 +34,7 @@
461 from click.tests.gimock_types import Passwd
462 from click.tests.helpers import (
463 TestCase,
464+ make_installed_click,
465 mkfile,
466 make_file_with_content,
467 touch,
468@@ -557,21 +558,34 @@
469 self.assertEqual(b_overlay, registry.get_path("b"))
470 self.assertTrue(registry.is_removable("b"))
471
472- def test_app_stops_on_remove(self):
473+
474+class StopAppTestCase(TestCase):
475+
476+ def setUp(self):
477+ super(StopAppTestCase, self).setUp()
478+ self.use_temp_dir()
479+ self.db = Click.DB()
480+ self.db.add(self.temp_dir)
481+
482+ # setup fake app_stop
483 fake_app_stop = os.path.join(self.temp_dir, "bin", "ubuntu-app-stop")
484- fake_app_stop_output = os.path.join(self.temp_dir, "fake-app-stop.out")
485+ self.fake_app_stop_output = os.path.join(
486+ self.temp_dir, "fake-app-stop.out")
487 fake_app_stop_content = dedent("""\
488 #!/bin/sh
489 echo "$@" >> %s
490- """ % fake_app_stop_output)
491+ """ % self.fake_app_stop_output)
492 make_file_with_content(fake_app_stop, fake_app_stop_content, 0o755)
493 # its ok to modify env here, click.helpers.TestCase will take care
494 # of it
495 os.environ["PATH"] = "%s:%s" % (
496 os.path.dirname(fake_app_stop), os.environ["PATH"])
497- # get a app with manifest etc all
498- _, registry = self._setUpMultiDB()
499- registry.remove("a")
500+
501+ def test_app_stops_on_remove(self):
502+ make_installed_click(self.db, self.temp_dir, "meep", "2.0",
503+ {"hooks": {"a-app": {}}})
504+ registry = Click.User.for_user(self.db, "user")
505+ registry.remove("meep")
506 # ensure that stop was called with the right app
507- with open(fake_app_stop_output) as f:
508- self.assertEqual("a_a-app_1.1", f.read().strip())
509+ with open(self.fake_app_stop_output) as f:
510+ self.assertEqual("meep_a-app_2.0", f.read().strip())
511
512=== modified file 'debian/changelog'
513--- debian/changelog 2015-02-13 14:46:35 +0000
514+++ debian/changelog 2015-02-26 17:06:20 +0000
515@@ -1,3 +1,20 @@
516+click (0.4.38.4) UNRELEASED; urgency=low
517+
518+ * lp:~mvo/click/lp1232130-kill-on-remove-2:
519+ - When uninstalling a app, stop it if its running (LP: #1232130)
520+ * lp:~mvo/click/dont-crash-for-empty-db:
521+ - Do not crash when no database configuration is used and
522+ Click.DB.{get,props.overlay,gc,ensure_ownership} are called.
523+ * lp:~mvo/click/lp1219912-build-exclude:
524+ - add a new --ignore option to click {build,buildsource}
525+ (LP: #1219912)
526+ * lp:~mvo/click/fix-multiple-framework-validation:
527+ - fix framework validation for snappy
528+ * run debian/packagekit-check with "sh" as something in jenkins
529+ made it mode 0644
530+
531+ -- Michael Vogt <michael.vogt@ubuntu.com> Mon, 23 Feb 2015 08:20:04 +0100
532+
533 click (0.4.37) vivid; urgency=low
534
535 [ Michael Vogt ]
536
537=== modified file 'debian/rules'
538--- debian/rules 2014-10-10 07:10:23 +0000
539+++ debian/rules 2015-02-26 17:06:20 +0000
540@@ -1,6 +1,6 @@
541 #! /usr/bin/make -f
542
543-PACKAGEKIT := $(shell debian/packagekit-check)
544+PACKAGEKIT := $(shell sh debian/packagekit-check)
545 ifeq ($(PACKAGEKIT),yes)
546 EXTRA_DH_OPTIONS :=
547 else
548
549=== modified file 'doc/manpage.rst'
550--- doc/manpage.rst 2014-10-13 12:48:35 +0000
551+++ doc/manpage.rst 2015-02-26 17:06:20 +0000
552@@ -73,6 +73,11 @@
553
554 -m PATH, --manifest=PATH Read package manifest from PATH
555 (default: ``manifest.json``).
556+-I file-pattern, --ignore=file-pattern Ignore the given shell-pattern
557+ when building the package.
558+ The option may be repeated multiple
559+ times to list multiple patterns to
560+ exclude.
561 --no-validate Don't run checks from click-reviewers-tools on
562 the resulting .click file.
563
564@@ -90,8 +95,13 @@
565
566 Options:
567
568--m PATH, --manifest=PATH Read package manifest from PATH
569- (default: ``manifest.json``).
570+-m PATH, --manifest=PATH Read package manifest from PATH
571+ (default: ``manifest.json``).
572+-I file-pattern, --ignore=file-pattern Ignore the given shell-pattern
573+ when building the package.
574+ The option may be repeated multiple
575+ times to list multiple patterns to
576+ exclude.
577
578 click chroot
579 ------------
580
581=== modified file 'lib/click/database.vala'
582--- lib/click/database.vala 2014-09-12 11:46:05 +0000
583+++ lib/click/database.vala 2015-02-26 17:06:20 +0000
584@@ -34,7 +34,11 @@
585 /**
586 * Package manifest cannot be parsed.
587 */
588- BAD_MANIFEST
589+ BAD_MANIFEST,
590+ /**
591+ * No database available for the given request
592+ */
593+ INVALID
594 }
595
596 private string? app_pid_command = null;
597@@ -602,8 +606,11 @@
598 public int size { get { return db.size; } }
599
600 public new SingleDB
601- @get (int index)
602+ @get (int index) throws DatabaseError
603 {
604+ if (index >= db.size)
605+ throw new DatabaseError.INVALID
606+ ("invalid index %i for db of size %i", index, db.size);
607 return db.get (index);
608 }
609
610@@ -618,7 +625,15 @@
611 *
612 * The directory where changes should be written.
613 */
614- public string overlay { get { return db.last ().root; } }
615+ public string overlay
616+ {
617+ get {
618+ if (db.size == 0)
619+ return "";
620+ else
621+ return db.last ().root;
622+ }
623+ }
624
625 /**
626 * get_path:
627@@ -812,21 +827,32 @@
628 return generator.to_data (null);
629 }
630
631+ private void
632+ ensure_db () throws Error
633+ {
634+ if (db.size == 0)
635+ throw new DatabaseError.INVALID
636+ ("no database loaded");
637+ }
638+
639 public void
640 maybe_remove (string package, string version) throws Error
641 {
642+ ensure_db();
643 db.last ().maybe_remove (package, version);
644 }
645
646 public void
647 gc () throws Error
648 {
649+ ensure_db();
650 db.last ().gc ();
651 }
652
653 public void
654 ensure_ownership () throws Error
655 {
656+ ensure_db();
657 db.last ().ensure_ownership ();
658 }
659 }
660
661=== modified file 'lib/click/user.vala'
662--- lib/click/user.vala 2014-12-05 15:09:48 +0000
663+++ lib/click/user.vala 2015-02-26 17:06:20 +0000
664@@ -658,8 +658,49 @@
665 old_version, username);
666 }
667
668- private bool
669- stop_running_app (string package, string version)
670+ private string
671+ get_dbus_session_bus_env_for_current_user()
672+ {
673+ string euid = "%i".printf((int)(Posix.geteuid ()));
674+ var dbus_session_file = Path.build_filename(
675+ "/run", "user", euid, "dbus-session");
676+ string session_env;
677+ try {
678+ FileUtils.get_contents(dbus_session_file, out session_env);
679+ session_env = session_env.strip();
680+ } catch (Error e) {
681+ warning("Can not get the dbus session to stop app (%s)", e.message);
682+ }
683+ return session_env;
684+ }
685+
686+ private bool
687+ stop_single_app (string app_id)
688+ {
689+ // get the users dbus session when we run as root first as this
690+ // is where ubuntu-app-stop listens
691+ string[] envp = Environ.get();
692+ envp += get_dbus_session_bus_env_for_current_user();
693+
694+ string[] command = {
695+ "ubuntu-app-stop", app_id
696+ };
697+ bool res = false;
698+ try {
699+ int exit_status;
700+ Process.spawn_sync
701+ (null, command, envp,
702+ SpawnFlags.SEARCH_PATH,
703+ null, null, null, out exit_status);
704+ res = Process.check_exit_status (exit_status);
705+ } catch (Error e) {
706+ res = false;
707+ }
708+ return res;
709+ }
710+
711+ private bool
712+ stop_running_apps_for_package (string package, string version)
713 {
714 var res = true;
715 if (! find_on_path ("ubuntu-app-stop"))
716@@ -679,24 +720,7 @@
717 }
718 var hooks = manifest.get_object_member ("hooks");
719 foreach (unowned string app_name in hooks.get_members ())
720- {
721- // FIXME: move this into a "stop_single_app" helper
722- string[] command = {
723- "ubuntu-app-stop",
724- @"$(package)_$(app_name)_$(version)"
725- };
726- try {
727- int exit_status;
728- Process.spawn_sync
729- (null, command, null,
730- SpawnFlags.SEARCH_PATH |
731- SpawnFlags.STDOUT_TO_DEV_NULL,
732- null, null, null, out exit_status);
733- res &= Process.check_exit_status (exit_status);
734- } catch (Error e) {
735- res &= false;
736- }
737- }
738+ res &= stop_single_app (@"$(package)_$(app_name)_$(version)");
739 return res;
740 }
741
742@@ -718,6 +742,8 @@
743 old_version = Path.get_basename (target);
744 drop_privileges ();
745 try {
746+ // stop before removing the path to the manifest
747+ stop_running_apps_for_package (package, old_version);
748 unlink_force (path);
749 } finally {
750 regain_privileges ();
751@@ -733,19 +759,14 @@
752 ensure_db ();
753 drop_privileges ();
754 try {
755+ // stop before removing the path to the manifest
756+ stop_running_apps_for_package (package, old_version);
757 symlink_force (HIDDEN_VERSION, path);
758 } finally {
759 regain_privileges ();
760 }
761 }
762
763- drop_privileges ();
764- try {
765- stop_running_app (package, old_version);
766- } finally {
767- regain_privileges ();
768- }
769-
770 if (! is_pseudo_user)
771 package_remove_hooks (db, package, old_version, name);
772
773
774=== modified file 'pk-plugin/pk-plugin-click.c'
775--- pk-plugin/pk-plugin-click.c 2014-09-02 08:44:39 +0000
776+++ pk-plugin/pk-plugin-click.c 2015-02-26 17:06:20 +0000
777@@ -637,6 +637,11 @@
778 GError *error = NULL;
779 gchar *summary = NULL;
780
781+ // PK does not set a PATH, but we need one for removal
782+ const gchar *old_path = g_getenv("PATH");
783+ if(old_path == NULL)
784+ g_setenv("PATH", DEFAULT_PATH, 0);
785+
786 username = click_get_username_for_uid
787 (pk_transaction_get_uid (transaction));
788 if (!username) {
789@@ -701,6 +706,9 @@
790 ret = TRUE;
791
792 out:
793+ if(old_path == NULL)
794+ g_unsetenv("PATH");
795+
796 g_free (summary);
797 if (error)
798 g_error_free (error);

Subscribers

People subscribed via source and target branches

to all changes: