Merge lp:~sergiusens/snappy/seccompError into lp:~snappy-dev/snappy/snappy-moved-to-github
- seccompError
- Merge into snappy-moved-to-github
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~sergiusens/snappy/seccompError | ||||
Merge into: | lp:~snappy-dev/snappy/snappy-moved-to-github | ||||
Diff against target: |
1765 lines (+1354/-8) (has conflicts) 20 files modified
cmd/snappy/cmd_internal_unpack.go (+4/-0) cmd/snappy/cmd_internal_unpack_test.go (+20/-0) cmd/snappy/cmd_rollback.go (+9/-0) cmd/snappy/cmd_set.go (+14/-0) cmd/snappy/main.go (+4/-0) etc/grub.d/09_snappy.OTHER (+441/-0) helpers/helpers.go (+170/-8) helpers/helpers_test.go (+104/-0) oauth/oauth_test.go (+72/-0) partition/bootloader_uboot.go (+104/-0) partition/bootloader_uboot_test.go (+37/-0) partition/partition.go (+20/-0) snappy/click.go (+258/-0) snappy/errors.go (+23/-0) snappy/security.go (+7/-0) snappy/snapp.go (+21/-0) snappy/snapp_test.go (+19/-0) snappy/systemimage.go (+7/-0) systemd/systemd.go (+14/-0) systemd/systemd_test.go (+6/-0) Text conflict in cmd/snappy/cmd_internal_unpack.go Text conflict in cmd/snappy/cmd_internal_unpack_test.go Text conflict in cmd/snappy/cmd_set.go Text conflict in cmd/snappy/main.go Conflict adding files to etc. Created directory. Conflict because etc is not versioned, but has versioned children. Versioned directory. Conflict adding files to etc/grub.d. Created directory. Conflict because etc/grub.d is not versioned, but has versioned children. Versioned directory. Contents conflict in etc/grub.d/09_snappy Text conflict in helpers/helpers.go Text conflict in helpers/helpers_test.go Text conflict in oauth/oauth_test.go Text conflict in partition/bootloader_uboot.go Text conflict in partition/partition.go Text conflict in snappy/click.go Text conflict in snappy/errors.go Text conflict in snappy/security.go Text conflict in snappy/snapp.go Text conflict in snappy/snapp_test.go Text conflict in snappy/systemimage.go Text conflict in systemd/systemd.go Text conflict in systemd/systemd_test.go |
||||
To merge this branch: | bzr merge lp:~sergiusens/snappy/seccompError | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Snappy Developers | Pending | ||
Review via email: mp+263963@code.launchpad.net |
Commit message
Backport, Provide a more specific error than '%f is a directory' when missing a seccomp entry
Description of the change
Unmerged revisions
- 457. By Sergio Schvezov
-
Provide a more specific error than '%f is a directory' when missing a seccomp entry
- 456. By Michael Terry
-
Restart systemd services on failure by default
This is a backport of r492 from trunk. by mterry approved by rsalveti
- 455. By Michael Terry
-
Add an are-we-
root-check/ mutex-lock to the set command and make the message nicer. This is a backport of r528 from trunk. by mterry approved by rsalveti
- 454. By John Lenton
-
Cherry picked r493 to fix oauth quoting. Fixes LP:1461262. by chipaca approved by rsalveti
- 453. By Ricardo Salveti
-
Fixing lint errors by rsalveti approved by mterry
- 452. By Sergio Schvezov
-
Backport 09_snappy to support azure kernel cmdline requirements by sergiusens approved by chipaca
- 451. By Michael Terry
-
When rolling back. output version info, especially any messages about rebooting to pick up the new version.
This is a backport of r485 from trunk. by mterry approved by sergiusens
- 450. By Sergio Schvezov
-
Don't allow installation of packages with unsupported architectures (backported from trunk with bzr merge -c 484 from trunk) by sergiusens approved by chipaca
- 449. By Michael Terry
-
Allow ".." in file paths as long as it isn't an entire element. (i.e. allow "hello..you" or "...")
We call filepath.Clean right before our ".." check. So the only instances of ".." will be in the first element. That lets us simplify the check a lot.
This is a backport of r457 from trunk. by mterry approved by chipaca
- 448. By Michael Terry
-
Fix intermittent "permission denied" errors when installing snaps by making sure that we always unpack in the same OS thread that dropped its privileges.
This is a backport of r481 from trunk. by mterry approved by chipaca
Preview Diff
1 | === modified file 'clickdeb/deb.go' |
2 | === modified file 'clickdeb/deb_test.go' |
3 | === modified file 'cmd/snappy/cmd_internal_unpack.go' |
4 | --- cmd/snappy/cmd_internal_unpack.go 2015-07-02 16:01:11 +0000 |
5 | +++ cmd/snappy/cmd_internal_unpack.go 2015-07-06 19:58:38 +0000 |
6 | @@ -129,6 +129,7 @@ |
7 | |
8 | // first find out what user to use |
9 | passFile := passwdFile(rootDir, "passwd") |
10 | +<<<<<<< TREE |
11 | for _, dropPrivsUser = range dropPrivsUsers { |
12 | _, err := readUID(dropPrivsUser, passFile) |
13 | if err == nil { |
14 | @@ -138,6 +139,9 @@ |
15 | |
16 | // then get uid/gid |
17 | uid, err := readUID(dropPrivsUser, passFile) |
18 | +======= |
19 | + uid, err := readUID(dropPrivsUser, passFile) |
20 | +>>>>>>> MERGE-SOURCE |
21 | if err != nil { |
22 | return err |
23 | } |
24 | |
25 | === modified file 'cmd/snappy/cmd_internal_unpack_test.go' |
26 | --- cmd/snappy/cmd_internal_unpack_test.go 2015-07-02 16:01:11 +0000 |
27 | +++ cmd/snappy/cmd_internal_unpack_test.go 2015-07-06 19:58:38 +0000 |
28 | @@ -42,7 +42,11 @@ |
29 | snappypkg:x:101:104::/nonexistent:/bin/false |
30 | `) |
31 | |
32 | +<<<<<<< TREE |
33 | uid, err := readUID("snappypkg", f.Name()) |
34 | +======= |
35 | + uid, err := readUID("clickpkg", f.Name()) |
36 | +>>>>>>> MERGE-SOURCE |
37 | c.Assert(err, IsNil) |
38 | c.Assert(uid, Equals, 101) |
39 | } |
40 | @@ -53,7 +57,11 @@ |
41 | snappypkg:x:104: |
42 | `) |
43 | |
44 | +<<<<<<< TREE |
45 | gid, err := readUID("snappypkg", f.Name()) |
46 | +======= |
47 | + gid, err := readUID("clickpkg", f.Name()) |
48 | +>>>>>>> MERGE-SOURCE |
49 | c.Assert(err, IsNil) |
50 | c.Assert(gid, Equals, 104) |
51 | } |
52 | @@ -66,7 +74,11 @@ |
53 | `) |
54 | defer os.Remove(f.Name()) |
55 | |
56 | +<<<<<<< TREE |
57 | uid, err := readUID("snappypkg", f.Name()) |
58 | +======= |
59 | + uid, err := readUID("clickpkg", f.Name()) |
60 | +>>>>>>> MERGE-SOURCE |
61 | c.Assert(err, IsNil) |
62 | c.Assert(uid, Equals, 102) |
63 | } |
64 | @@ -77,7 +89,11 @@ |
65 | snappypkg:x: |
66 | `) |
67 | |
68 | +<<<<<<< TREE |
69 | _, err := readUID("snappypkg", f.Name()) |
70 | +======= |
71 | + _, err := readUID("clickpkg", f.Name()) |
72 | +>>>>>>> MERGE-SOURCE |
73 | c.Assert(err, NotNil) |
74 | } |
75 | |
76 | @@ -86,6 +102,10 @@ |
77 | daemon: |
78 | `) |
79 | |
80 | +<<<<<<< TREE |
81 | _, err := readUID("snappypkg", f.Name()) |
82 | +======= |
83 | + _, err := readUID("clickpkg", f.Name()) |
84 | +>>>>>>> MERGE-SOURCE |
85 | c.Assert(err, NotNil) |
86 | } |
87 | |
88 | === modified file 'cmd/snappy/cmd_rollback.go' |
89 | --- cmd/snappy/cmd_rollback.go 2015-07-02 17:16:11 +0000 |
90 | +++ cmd/snappy/cmd_rollback.go 2015-07-06 19:58:38 +0000 |
91 | @@ -77,5 +77,14 @@ |
92 | parts := snappy.FindSnapsByNameAndVersion(pkg, nowVersion, installed) |
93 | showVerboseList(parts, os.Stdout) |
94 | |
95 | + m := snappy.NewMetaRepository() |
96 | + installed, err := m.Installed() |
97 | + if err != nil { |
98 | + return err |
99 | + } |
100 | + |
101 | + parts := snappy.FindSnapsByNameAndVersion(pkg, nowVersion, installed) |
102 | + showVerboseList(parts, os.Stdout) |
103 | + |
104 | return nil |
105 | } |
106 | |
107 | === modified file 'cmd/snappy/cmd_set.go' |
108 | --- cmd/snappy/cmd_set.go 2015-06-30 12:52:52 +0000 |
109 | +++ cmd/snappy/cmd_set.go 2015-07-06 19:58:38 +0000 |
110 | @@ -23,8 +23,12 @@ |
111 | "fmt" |
112 | "strings" |
113 | |
114 | +<<<<<<< TREE |
115 | "launchpad.net/snappy/i18n" |
116 | "launchpad.net/snappy/logger" |
117 | +======= |
118 | + "launchpad.net/snappy/priv" |
119 | +>>>>>>> MERGE-SOURCE |
120 | "launchpad.net/snappy/progress" |
121 | "launchpad.net/snappy/snappy" |
122 | ) |
123 | @@ -53,8 +57,18 @@ |
124 | } |
125 | |
126 | func (x *cmdSet) Execute(args []string) (err error) { |
127 | +<<<<<<< TREE |
128 | x.args = args |
129 | return withMutex(x.doSet) |
130 | +======= |
131 | + privMutex := priv.New() |
132 | + if err := privMutex.TryLock(); err != nil { |
133 | + return err |
134 | + } |
135 | + defer privMutex.Unlock() |
136 | + |
137 | + return set(args) |
138 | +>>>>>>> MERGE-SOURCE |
139 | } |
140 | |
141 | func (x *cmdSet) doSet() (err error) { |
142 | |
143 | === modified file 'cmd/snappy/main.go' |
144 | --- cmd/snappy/main.go 2015-06-11 20:30:46 +0000 |
145 | +++ cmd/snappy/main.go 2015-07-06 19:58:38 +0000 |
146 | @@ -52,10 +52,14 @@ |
147 | // the CLI user. |
148 | err = snappy.ErrNeedRoot |
149 | } |
150 | +<<<<<<< TREE |
151 | fmt.Fprintln(os.Stderr, err) |
152 | if _, ok := err.(*flags.Error); !ok { |
153 | logger.Debugf("%v failed: %v", os.Args, err) |
154 | } |
155 | +======= |
156 | + fmt.Fprintln(os.Stderr, err) |
157 | +>>>>>>> MERGE-SOURCE |
158 | os.Exit(1) |
159 | } |
160 | } |
161 | |
162 | === added directory 'etc' |
163 | === added directory 'etc/grub.d' |
164 | === added file 'etc/grub.d/09_snappy.OTHER' |
165 | --- etc/grub.d/09_snappy.OTHER 1970-01-01 00:00:00 +0000 |
166 | +++ etc/grub.d/09_snappy.OTHER 2015-07-06 19:58:38 +0000 |
167 | @@ -0,0 +1,441 @@ |
168 | +#!/bin/sh |
169 | +#--------------------------------------------------------------------- |
170 | +# Summary: Grub bootloader logic for Ubuntu Snappy systems. |
171 | +# Description: This is a heavily modified "10_linux" grub snippet that |
172 | +# deals with Snappy dual-rootfs systems. |
173 | +# |
174 | +# XXX: Note that this script is called from within a chroot environment |
175 | +# on snappy systems! |
176 | +# |
177 | +#--------------------------------------------------------------------- |
178 | + |
179 | +set -e |
180 | + |
181 | +prefix="/usr" |
182 | +exec_prefix="/usr" |
183 | +datarootdir="/usr/share" |
184 | + |
185 | +# Utility functions |
186 | +. "${datarootdir}/grub/grub-mkconfig_lib" |
187 | + |
188 | +# Globals |
189 | +machine=`uname -m` |
190 | + |
191 | +SNAPPY_OS="Ubuntu Core Snappy" |
192 | +SNAPPY_TYPE=simple |
193 | + |
194 | +#--------------------------------------------------------------------- |
195 | + |
196 | +# Display message and exit |
197 | +die() |
198 | +{ |
199 | + msg="$*" |
200 | + echo "ERROR: $msg" >&2 |
201 | + exit 1 |
202 | +} |
203 | + |
204 | +# Create a grub menu entry by writing a menuentry to stdout. |
205 | +linux_entry_ext() |
206 | +{ |
207 | + local name="$1" |
208 | + local os="$2" |
209 | + local version="$3" |
210 | + local type="$4" |
211 | + local args="$5" |
212 | + local device="$6" |
213 | + local kernel="$7" |
214 | + local initrd="$8" |
215 | + |
216 | + local boot_device_id= |
217 | + local prepare_root_cache= |
218 | + local prepare_boot_cache= |
219 | + |
220 | + if [ -z "$boot_device_id" ]; then |
221 | + boot_device_id="$(grub_get_device_id "${device}")" |
222 | + fi |
223 | + |
224 | + echo "menuentry '$name' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" |
225 | + |
226 | + if [ x$type != xrecovery ] ; then |
227 | + save_default_entry | grub_add_tab |
228 | + fi |
229 | + |
230 | + # Use ELILO's generic "efifb" when it's known to be available. |
231 | + # FIXME: We need an interface to select vesafb in case efifb can't be used. |
232 | + if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then |
233 | + echo " load_video" | sed "s/^/$submenu_indentation/" |
234 | + else |
235 | + if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then |
236 | + echo " load_video" | sed "s/^/$submenu_indentation/" |
237 | + fi |
238 | + fi |
239 | + if ([ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]) && \ |
240 | + ([ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 1 ]); then |
241 | + echo " gfxmode \$linux_gfx_mode" | sed "s/^/$submenu_indentation/" |
242 | + fi |
243 | + |
244 | + echo " insmod gzio" | sed "s/^/$submenu_indentation/" |
245 | + echo " if [ x\$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi" | sed "s/^/$submenu_indentation/" |
246 | + |
247 | + # device may be a label (LABEL=name), so convert back to full path |
248 | + label_name=$(echo "$device"|sed 's/^LABEL=//g') |
249 | + if [ "$device" = "$label_name" ] |
250 | + then |
251 | + device_path="$device" |
252 | + else |
253 | + # found a label |
254 | + device_path=$(get_partition_from_label "$label_name") |
255 | + fi |
256 | + |
257 | + if [ x$dirname = x/ ]; then |
258 | + if [ -z "${prepare_root_cache}" ]; then |
259 | + |
260 | + prepare_root_cache="$(prepare_grub_to_access_device ${device_path} | grub_add_tab)" |
261 | + fi |
262 | + printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/" |
263 | + else |
264 | + if [ -z "${prepare_boot_cache}" ]; then |
265 | + prepare_boot_cache="$(prepare_grub_to_access_device ${device_path} | grub_add_tab)" |
266 | + fi |
267 | + printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" |
268 | + fi |
269 | + |
270 | + if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then |
271 | + message="$(gettext_printf "Loading Linux %s ..." ${version})" |
272 | + sed "s/^/$submenu_indentation/" << EOF |
273 | + echo '$(echo "$message" | grub_quote)' |
274 | +EOF |
275 | + fi |
276 | + |
277 | + sed "s/^/$submenu_indentation/" << EOF |
278 | + linux ${kernel} root=${device} ro ${args} |
279 | +EOF |
280 | + |
281 | + if test -n "${initrd}"; then |
282 | + # TRANSLATORS: ramdisk isn't identifier. Should be translated. |
283 | + if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then |
284 | + message="$(gettext_printf "Loading initial ramdisk ...")" |
285 | + sed "s/^/$submenu_indentation/" << EOF |
286 | + echo '$(echo "$message" | grub_quote)' |
287 | +EOF |
288 | + fi |
289 | + sed "s/^/$submenu_indentation/" << EOF |
290 | + initrd ${initrd} |
291 | +EOF |
292 | + fi |
293 | + |
294 | + sed "s/^/$submenu_indentation/" << EOF |
295 | +} |
296 | +EOF |
297 | +} |
298 | + |
299 | +# Returns a list of the currently available kernels. |
300 | +# $1: If set, look for kernel below "$1/boot/". |
301 | +get_kernels() |
302 | +{ |
303 | + local prefix_dir="$1" |
304 | + local list |
305 | + |
306 | + case "x$machine" in |
307 | + xi?86 | xx86_64) |
308 | + list=`for i in $prefix_dir/boot/vmlinuz-* \ |
309 | + $prefix_dir/vmlinuz-* \ |
310 | + $prefix_dir/boot/kernel-* ; do |
311 | + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi |
312 | + done` ;; |
313 | + *) |
314 | + list=`for i in $prefix_dir/boot/vmlinuz-* \ |
315 | + $prefix_dir/boot/vmlinux-* \ |
316 | + $prefix_dir/vmlinuz-* \ |
317 | + $prefix_dir/vmlinux-* \ |
318 | + $prefix_dir/boot/kernel-* ; do |
319 | + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi |
320 | + done` ;; |
321 | + esac |
322 | + echo "$list" |
323 | +} |
324 | + |
325 | +# Composes and returns a kernel cmd line |
326 | +get_cmdline() { |
327 | + channel_ini="/etc/system-image/channel.ini" |
328 | + grep -q 'device: azure_amd64' "$channel_ini" && azure_cmdline="rootdelay=300" |
329 | + |
330 | + echo "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} $azure_cmdline" |
331 | +} |
332 | + |
333 | +# Returns the path to the initrd for the kernel specified by $1. |
334 | +# $1: kernel version. |
335 | +# $2: directory to look in. |
336 | +get_initrd() |
337 | +{ |
338 | + local version="$1" |
339 | + local dir="$2" |
340 | + |
341 | + local alt_version=`echo $version | sed -e "s,\.old$,,g"` |
342 | + local initrd= |
343 | + local i= |
344 | + |
345 | + for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \ |
346 | + "initrd-${version}" "initramfs-${version}.img" \ |
347 | + "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ |
348 | + "initrd-${alt_version}" "initramfs-${alt_version}.img" \ |
349 | + "initramfs-genkernel-${version}" \ |
350 | + "initramfs-genkernel-${alt_version}" \ |
351 | + "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \ |
352 | + "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do |
353 | + if test -e "${dir}/${i}" ; then |
354 | + initrd="${dir}/${i}" |
355 | + break |
356 | + fi |
357 | + done |
358 | + echo "$initrd" |
359 | +} |
360 | + |
361 | +# Determine full path to disk partition given a filesystem label. |
362 | +get_partition_from_label() |
363 | +{ |
364 | + local label="$1" |
365 | + local part= |
366 | + local path= |
367 | + |
368 | + [ -n "$label" ] || grub_warn "need FS label" |
369 | + |
370 | + part=$(find /dev -name "$label"|tail -1) |
371 | + [ -z "$part" ] && return |
372 | + path=$(readlink -f "$part") |
373 | + [ -n "$path" ] && echo "$path" |
374 | +} |
375 | + |
376 | +# Return the partition label for the given partition device. |
377 | +# $1: full path to partition device. |
378 | +get_label_from_device() |
379 | +{ |
380 | + local root="$1" |
381 | + |
382 | + local label= |
383 | + local std_label= |
384 | + local label_rootfs= |
385 | + |
386 | + for std_label in system-a system-b; do |
387 | + label_rootfs=$(findfs "PARTLABEL=$std_label" 2>/dev/null || :) |
388 | + if [ "$label_rootfs" = "$root" ]; then |
389 | + label="$std_label" |
390 | + break |
391 | + fi |
392 | + done |
393 | + |
394 | + echo "$label" |
395 | +} |
396 | + |
397 | +# Return the full path to the device corresponding to the given |
398 | +# partition label. |
399 | +# |
400 | +# $1: partition label. |
401 | +get_device_from_label() |
402 | +{ |
403 | + local label="$1" |
404 | + local device= |
405 | + |
406 | + device=$(findfs "PARTLABEL=$label" 2>/dev/null || :) |
407 | + echo "$device" |
408 | +} |
409 | + |
410 | +# Given a rootfs label, return the rootfs label corresponding to the |
411 | +# "other" rootfs partition. |
412 | +get_other_rootfs_label() |
413 | +{ |
414 | + local label="$1" |
415 | + |
416 | + if [ "$label" = "system-a" ]; then |
417 | + echo "system-b" |
418 | + else |
419 | + echo "system-a" |
420 | + fi |
421 | +} |
422 | + |
423 | +# Given a mountpoint, return the corresponding device path |
424 | +# $1: mountpoint. |
425 | +get_device_from_mountpoint() |
426 | +{ |
427 | + local mountpoint="$1" |
428 | + local device= |
429 | + |
430 | + # XXX: Parse mount output rather than looking in /proc/mounts to |
431 | + # avoid seeing the mounts outside the chroot. |
432 | + device=$(/bin/mount | grep "^/dev/.* on ${mountpoint}[[:space:]]" 2>/dev/null |\ |
433 | + awk '{print $1}' || :) |
434 | + |
435 | + echo "$device" |
436 | +} |
437 | + |
438 | +# Convert a partition label name to a menuentry name |
439 | +make_name() |
440 | +{ |
441 | + local label="$1" |
442 | + |
443 | + echo "$SNAPPY_OS $label rootfs" | grub_quote |
444 | +} |
445 | + |
446 | +# Arrange for a grub menuentry to be created for the given partition. |
447 | +# |
448 | +# $1: full path to rootfs partition device |
449 | +# $2: partition label associated with $1 |
450 | +# $3: mountpoint of $1. |
451 | +handle_menu_entry() |
452 | +{ |
453 | + local rootfs_device="$1" |
454 | + local label="$2" |
455 | + local mountpoint="$3" |
456 | + |
457 | + local name= |
458 | + local device= |
459 | + local mount_prefix= |
460 | + local list= |
461 | + local linux= |
462 | + local basename= |
463 | + local dirname= |
464 | + local rel_dirname= |
465 | + local version= |
466 | + local initrd= |
467 | + local cmdline= |
468 | + |
469 | + # boot by label |
470 | + device="LABEL=$label" |
471 | + |
472 | + name=$(make_name "$label") |
473 | + |
474 | + # avoid double-leading slashes and the subsequent need to call |
475 | + # 'readlink -f'. |
476 | + if [ "$mountpoint" = "/" ]; then |
477 | + mount_prefix="" |
478 | + else |
479 | + mount_prefix="$mountpoint" |
480 | + fi |
481 | + list=$(get_kernels "$mount_prefix") |
482 | + |
483 | + linux=$(version_find_latest $list) |
484 | + basename=$(basename "$linux") |
485 | + dirname=$(dirname "$linux") |
486 | + rel_dirname=$(make_system_path_relative_to_its_root "$dirname") |
487 | + version=$(echo "$basename" | sed -e "s,^[^0-9]*-,,g") |
488 | + |
489 | + initrd=$(get_initrd "$version" "$dirname") |
490 | + |
491 | + cmdline=$(get_cmdline) |
492 | + |
493 | + # convert the path to the mounted "other" rootfs back to a |
494 | + # a standard one by removing the mountpoint prefix. |
495 | + if [ "$mountpoint" != "/" ]; then |
496 | + linux=$(echo "$linux" | sed "s!^${mountpoint}!!g") |
497 | + initrd=$(echo "$initrd" | sed "s!^${mountpoint}!!g") |
498 | + fi |
499 | + |
500 | + # Create menu entries for the 2 snappy rootfs's. |
501 | + linux_entry_ext "$name" "$SNAPPY_OS" "$version" \ |
502 | + "$SNAPPY_TYPE" "$cmdline" "$device" \ |
503 | + "$linux" "$initrd" |
504 | +} |
505 | + |
506 | +#--------------------------------------------------------------------- |
507 | +# main |
508 | + |
509 | +case "$machine" in |
510 | + i?86) GENKERNEL_ARCH="x86" ;; |
511 | + mips|mips64) GENKERNEL_ARCH="mips" ;; |
512 | + mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;; |
513 | + arm*) GENKERNEL_ARCH="arm" ;; |
514 | + *) GENKERNEL_ARCH="$machine" ;; |
515 | +esac |
516 | + |
517 | +# Determine which partition label is being used for the current root |
518 | +# directory. This is slightly convoluted but required since this code |
519 | +# runs within a chroot environment (where lsblk does not work). |
520 | +# |
521 | +# XXX: Note that since this code is run from within a chroot (where the |
522 | +# "other" rootfs is mounted), it might appear that the logic is |
523 | +# inverted. However, the code below simply |
524 | +this_mountpoint="/" |
525 | +this_root=$(get_device_from_mountpoint "$this_mountpoint") |
526 | +[ -z "$this_root" ] && { |
527 | + die "cannot determine rootfs for $this_mountpoint" |
528 | +} |
529 | + |
530 | +this_label=$(get_label_from_device "$this_root") |
531 | +[ -z "$this_label" ] && { |
532 | + die "cannot determine partition label for rootfs $this_root" |
533 | +} |
534 | + |
535 | +handle_menu_entry "$this_root" "$this_label" "$this_mountpoint" |
536 | + |
537 | +other_mountpoint="/writable/cache/system" |
538 | + |
539 | +# When this script is run on a real snappy system, even if there is only |
540 | +# a single rootfs provisioned, the other rootfs partition is expected to |
541 | +# be formatted and mounted. |
542 | +# |
543 | +# However this script is also run at provisioning time where |
544 | +# $other_mountpoint will not be a mountpoint. Therefore in the provisioning |
545 | +# scenario, only a single menuentry will be generated if only a single |
546 | +# rootfs is provisioned. |
547 | +if $(mountpoint -q "$other_mountpoint"); then |
548 | + other_label=$(get_other_rootfs_label "$this_label") |
549 | + |
550 | + other_root=$(get_device_from_label "$other_label") |
551 | + [ -z "$other_root" ] && { |
552 | + die "cannot determine rootfs" |
553 | + } |
554 | + |
555 | + handle_menu_entry "$other_root" "$other_label" "$other_mountpoint" |
556 | +fi |
557 | + |
558 | +# Toggle rootfs if previous boot failed. |
559 | +# |
560 | +# Since grub sets snappy_trial_boot, if it is _already_ set when grub starts |
561 | +# and we're in try mode, the previous boot must have failed to unset it, |
562 | +# so toggle the rootfs. |
563 | +sed "s/^/$submenu_indentation/" << EOF |
564 | + # set defaults |
565 | + if [ -z "\$snappy_mode" ]; then |
566 | + set snappy_mode=regular |
567 | + save_env snappy_mode |
568 | + fi |
569 | + if [ -z "\$snappy_ab" ]; then |
570 | + set snappy_ab=a |
571 | + save_env snappy_ab |
572 | + fi |
573 | + |
574 | + if [ "\$snappy_mode" = "try" ]; then |
575 | + if [ "\$snappy_trial_boot" = "1" ]; then |
576 | + # Previous boot failed to unset snappy_trial_boot, so toggle |
577 | + # rootfs. |
578 | + if [ "\$snappy_ab" = "a" ]; then |
579 | + set default="$(make_name system-b)" |
580 | + set snappy_ab=b |
581 | + else |
582 | + set snappy_ab=a |
583 | + set default="$(make_name system-a)" |
584 | + fi |
585 | + save_env snappy_ab |
586 | + else |
587 | + # Trial mode so set the snappy_trial_boot (which snappy is |
588 | + # expected to unset). |
589 | + # |
590 | + # Note: don't use the standard recordfail variable since that forces |
591 | + # the menu to be displayed and sets an infinite timeout if set. |
592 | + set snappy_trial_boot=1 |
593 | + save_env snappy_trial_boot |
594 | + |
595 | + if [ "\$snappy_ab" = "a" ]; then |
596 | + set default="$(make_name system-a)" |
597 | + else |
598 | + set default="$(make_name system-b)" |
599 | + fi |
600 | + fi |
601 | + else |
602 | + if [ "\$snappy_ab" = "a" ]; then |
603 | + set default="$(make_name system-a)" |
604 | + else |
605 | + set default="$(make_name system-b)" |
606 | + fi |
607 | + fi |
608 | +EOF |
609 | |
610 | === modified file 'helpers/helpers.go' |
611 | --- helpers/helpers.go 2015-07-01 21:09:59 +0000 |
612 | +++ helpers/helpers.go 2015-07-06 19:58:38 +0000 |
613 | @@ -26,6 +26,7 @@ |
614 | "encoding/hex" |
615 | "fmt" |
616 | "io" |
617 | + "io/ioutil" |
618 | "math/rand" |
619 | "os" |
620 | "os/exec" |
621 | @@ -198,14 +199,37 @@ |
622 | } |
623 | } |
624 | |
625 | -// IsSupportedArchitecture returns true if the system architecture is in the |
626 | -// list of architectures. |
627 | -func IsSupportedArchitecture(architectures []string) bool { |
628 | - systemArch := UbuntuArchitecture() |
629 | - |
630 | - for _, arch := range architectures { |
631 | - if arch == "all" || arch == systemArch { |
632 | - return true |
633 | +<<<<<<< TREE |
634 | +// IsSupportedArchitecture returns true if the system architecture is in the |
635 | +// list of architectures. |
636 | +func IsSupportedArchitecture(architectures []string) bool { |
637 | + systemArch := UbuntuArchitecture() |
638 | + |
639 | + for _, arch := range architectures { |
640 | + if arch == "all" || arch == systemArch { |
641 | + return true |
642 | +======= |
643 | +// IsSupportedArchitecture returns true if the system architecture is in the |
644 | +// list of architectures. |
645 | +func IsSupportedArchitecture(architectures []string) bool { |
646 | + systemArch := UbuntuArchitecture() |
647 | + |
648 | + for _, arch := range architectures { |
649 | + if arch == "all" || arch == systemArch { |
650 | + return true |
651 | + } |
652 | + } |
653 | + |
654 | + return false |
655 | +} |
656 | + |
657 | +// EnsureDir ensures that the given directory exists and if |
658 | +// not creates it with the given permissions. |
659 | +func EnsureDir(dir string, perm os.FileMode) (err error) { |
660 | + if _, err := os.Stat(dir); os.IsNotExist(err) { |
661 | + if err := os.MkdirAll(dir, perm); err != nil { |
662 | + return err |
663 | +>>>>>>> MERGE-SOURCE |
664 | } |
665 | } |
666 | |
667 | @@ -346,6 +370,7 @@ |
668 | return syscall.Getuid() == 0 || syscall.Getgid() == 0 |
669 | |
670 | } |
671 | +<<<<<<< TREE |
672 | |
673 | // MajorMinor returns the major/minor number of the given os.FileInfo |
674 | func MajorMinor(info os.FileInfo) (uint32, uint32, error) { |
675 | @@ -509,3 +534,140 @@ |
676 | |
677 | return nil |
678 | } |
679 | +======= |
680 | + |
681 | +func makeDirMap(dirName string) (map[string]struct{}, error) { |
682 | + dir, err := ioutil.ReadDir(dirName) |
683 | + if err != nil { |
684 | + return nil, err |
685 | + } |
686 | + |
687 | + dirMap := make(map[string]struct{}) |
688 | + for _, dent := range dir { |
689 | + if dent.IsDir() { |
690 | + return nil, fmt.Errorf("subdirs are not supported") |
691 | + } |
692 | + dirMap[dent.Name()] = struct{}{} |
693 | + } |
694 | + |
695 | + return dirMap, nil |
696 | +} |
697 | + |
698 | +// RSyncWithDelete syncs srcDir to destDir |
699 | +func RSyncWithDelete(srcDirName, destDirName string) error { |
700 | + |
701 | + // first remove everything thats not in srcdir |
702 | + err := filepath.Walk(destDirName, func(path string, info os.FileInfo, err error) error { |
703 | + if err != nil { |
704 | + return err |
705 | + } |
706 | + |
707 | + // relative to the root "destDirName" |
708 | + relPath := path[len(destDirName):] |
709 | + if !FileExists(filepath.Join(srcDirName, relPath)) { |
710 | + if err := os.RemoveAll(path); err != nil { |
711 | + return err |
712 | + } |
713 | + if info.IsDir() { |
714 | + return filepath.SkipDir |
715 | + } |
716 | + } |
717 | + return nil |
718 | + }) |
719 | + if err != nil { |
720 | + return err |
721 | + } |
722 | + |
723 | + // then copy or update the data from srcdir to destdir |
724 | + err = filepath.Walk(srcDirName, func(path string, info os.FileInfo, err error) error { |
725 | + if err != nil { |
726 | + return err |
727 | + } |
728 | + |
729 | + // relative to the root "srcDirName" |
730 | + relPath := path[len(srcDirName):] |
731 | + if info.IsDir() { |
732 | + return os.MkdirAll(filepath.Join(destDirName, relPath), info.Mode()) |
733 | + } |
734 | + src := path |
735 | + dst := filepath.Join(destDirName, relPath) |
736 | + if !FilesAreEqual(src, dst) { |
737 | + // XXX: on snappy-trunk we can use CopyFile here |
738 | + output, err := exec.Command("cp", "-va", src, dst).CombinedOutput() |
739 | + if err != nil { |
740 | + fmt.Errorf("Failed to copy %s to %s (%s)", src, dst, output) |
741 | + } |
742 | + } |
743 | + return nil |
744 | + }) |
745 | + |
746 | + return err |
747 | +} |
748 | + |
749 | +func fillSnapEnvVars(desc interface{}, vars []string) []string { |
750 | + for i, v := range vars { |
751 | + var templateOut bytes.Buffer |
752 | + t := template.Must(template.New("wrapper").Parse(v)) |
753 | + if err := t.Execute(&templateOut, desc); err != nil { |
754 | + // this can never happen, except we forget a variable |
755 | + logger.LogAndPanic(err) |
756 | + } |
757 | + vars[i] = templateOut.String() |
758 | + } |
759 | + return vars |
760 | +} |
761 | + |
762 | +// GetBasicSnapEnvVars returns the app-level environment variables for a snap. |
763 | +// Despite this being a bit snap-specific, this is in helpers.go because it's |
764 | +// used by so many other modules, we run into circular dependencies if it's |
765 | +// somewhere more reasonable like the snappy module. |
766 | +func GetBasicSnapEnvVars(desc interface{}) []string { |
767 | + return fillSnapEnvVars(desc, []string{ |
768 | + "TMPDIR=/tmp/snaps/{{.UdevAppName}}/{{.Version}}/tmp", |
769 | + "TEMPDIR=/tmp/snaps/{{.UdevAppName}}/{{.Version}}/tmp", |
770 | + "SNAP_APP_PATH={{.AppPath}}", |
771 | + "SNAP_APP_DATA_PATH=/var/lib{{.AppPath}}", |
772 | + "SNAP_APP_TMPDIR=/tmp/snaps/{{.UdevAppName}}/{{.Version}}/tmp", |
773 | + "SNAP_NAME={{.AppName}}", |
774 | + "SNAP_VERSION={{.Version}}", |
775 | + "SNAP_ORIGIN={{.Namespace}}", |
776 | + "SNAP_FULLNAME={{.UdevAppName}}", |
777 | + "SNAP_ARCH={{.AppArch}}", |
778 | + }) |
779 | +} |
780 | + |
781 | +// GetUserSnapEnvVars returns the user-level environment variables for a snap. |
782 | +// Despite this being a bit snap-specific, this is in helpers.go because it's |
783 | +// used by so many other modules, we run into circular dependencies if it's |
784 | +// somewhere more reasonable like the snappy module. |
785 | +func GetUserSnapEnvVars(desc interface{}) []string { |
786 | + return fillSnapEnvVars(desc, []string{ |
787 | + "SNAP_APP_USER_DATA_PATH={{.Home}}{{.AppPath}}", |
788 | + }) |
789 | +} |
790 | + |
791 | +// GetDeprecatedBasicSnapEnvVars returns the app-level deprecated environment |
792 | +// variables for a snap. |
793 | +// Despite this being a bit snap-specific, this is in helpers.go because it's |
794 | +// used by so many other modules, we run into circular dependencies if it's |
795 | +// somewhere more reasonable like the snappy module. |
796 | +func GetDeprecatedBasicSnapEnvVars(desc interface{}) []string { |
797 | + return fillSnapEnvVars(desc, []string{ |
798 | + "SNAPP_APP_PATH={{.AppPath}}", |
799 | + "SNAPP_APP_DATA_PATH=/var/lib{{.AppPath}}", |
800 | + "SNAPP_APP_TMPDIR=/tmp/snaps/{{.UdevAppName}}/{{.Version}}/tmp", |
801 | + "SNAPPY_APP_ARCH={{.AppArch}}", |
802 | + }) |
803 | +} |
804 | + |
805 | +// GetDeprecatedUserSnapEnvVars returns the user-level deprecated environment |
806 | +// variables for a snap. |
807 | +// Despite this being a bit snap-specific, this is in helpers.go because it's |
808 | +// used by so many other modules, we run into circular dependencies if it's |
809 | +// somewhere more reasonable like the snappy module. |
810 | +func GetDeprecatedUserSnapEnvVars(desc interface{}) []string { |
811 | + return fillSnapEnvVars(desc, []string{ |
812 | + "SNAPP_APP_USER_DATA_PATH={{.Home}}{{.AppPath}}", |
813 | + }) |
814 | +} |
815 | +>>>>>>> MERGE-SOURCE |
816 | |
817 | === modified file 'helpers/helpers_test.go' |
818 | --- helpers/helpers_test.go 2015-07-01 18:27:44 +0000 |
819 | +++ helpers/helpers_test.go 2015-07-06 19:58:38 +0000 |
820 | @@ -271,6 +271,7 @@ |
821 | c.Assert(err, IsNil) |
822 | c.Assert(home, Equals, oldHome) |
823 | } |
824 | +<<<<<<< TREE |
825 | |
826 | func skipOnMissingDevKmsg(c *C) { |
827 | _, err := os.Stat("/dev/kmsg") |
828 | @@ -483,3 +484,106 @@ |
829 | err := CopyIfDifferent(src, dst) |
830 | c.Assert(err, NotNil) |
831 | } |
832 | +======= |
833 | + |
834 | +func makeTestFiles(c *C, srcDir, destDir string) { |
835 | + // a new file |
836 | + err := ioutil.WriteFile(filepath.Join(srcDir, "new"), []byte(nil), 0644) |
837 | + c.Assert(err, IsNil) |
838 | + |
839 | + // a existing file that needs update |
840 | + err = ioutil.WriteFile(filepath.Join(destDir, "existing-update"), []byte("old-content"), 0644) |
841 | + c.Assert(err, IsNil) |
842 | + err = ioutil.WriteFile(filepath.Join(srcDir, "existing-update"), []byte("some-new-content"), 0644) |
843 | + c.Assert(err, IsNil) |
844 | + |
845 | + // existing file that needs no update |
846 | + err = ioutil.WriteFile(filepath.Join(srcDir, "existing-unchanged"), []byte(nil), 0644) |
847 | + c.Assert(err, IsNil) |
848 | + err = exec.Command("cp", "-a", filepath.Join(srcDir, "existing-unchanged"), filepath.Join(destDir, "existing-unchanged")).Run() |
849 | + c.Assert(err, IsNil) |
850 | + |
851 | + // a file that needs removal |
852 | + err = ioutil.WriteFile(filepath.Join(destDir, "to-be-deleted"), []byte(nil), 0644) |
853 | + c.Assert(err, IsNil) |
854 | +} |
855 | + |
856 | +func compareDirs(c *C, srcDir, destDir string) { |
857 | + d1, err := exec.Command("ls", "-al", srcDir).CombinedOutput() |
858 | + c.Assert(err, IsNil) |
859 | + d2, err := exec.Command("ls", "-al", destDir).CombinedOutput() |
860 | + c.Assert(err, IsNil) |
861 | + c.Assert(string(d1), Equals, string(d2)) |
862 | + // ensure content got updated |
863 | + c1, err := exec.Command("sh", "-c", fmt.Sprintf("find %s -type f |xargs cat", srcDir)).CombinedOutput() |
864 | + c.Assert(err, IsNil) |
865 | + c2, err := exec.Command("sh", "-c", fmt.Sprintf("find %s -type f |xargs cat", destDir)).CombinedOutput() |
866 | + c.Assert(err, IsNil) |
867 | + c.Assert(string(c1), Equals, string(c2)) |
868 | +} |
869 | + |
870 | +func (ts *HTestSuite) TestSyncDirs(c *C) { |
871 | + |
872 | + for _, l := range [][2]string{ |
873 | + [2]string{"src-short", "dst-loooooooooooong"}, |
874 | + [2]string{"src-loooooooooooong", "dst-short"}, |
875 | + [2]string{"src-eq", "dst-eq"}, |
876 | + } { |
877 | + |
878 | + // ensure we have src, dest dirs with different length |
879 | + srcDir := filepath.Join(c.MkDir(), l[0]) |
880 | + err := os.MkdirAll(srcDir, 0755) |
881 | + c.Assert(err, IsNil) |
882 | + destDir := filepath.Join(c.MkDir(), l[1]) |
883 | + err = os.MkdirAll(destDir, 0755) |
884 | + c.Assert(err, IsNil) |
885 | + |
886 | + // add a src subdir |
887 | + subdir := filepath.Join(srcDir, "subdir") |
888 | + err = os.Mkdir(subdir, 0755) |
889 | + c.Assert(err, IsNil) |
890 | + makeTestFiles(c, subdir, destDir) |
891 | + |
892 | + // add a dst subdir that needs to get deleted |
893 | + subdir2 := filepath.Join(destDir, "to-be-deleted-subdir") |
894 | + err = os.Mkdir(subdir2, 0755) |
895 | + subdir3 := filepath.Join(subdir2, "to-be-deleted-sub-subdir") |
896 | + err = os.Mkdir(subdir3, 0755) |
897 | + |
898 | + // and a toplevel |
899 | + makeTestFiles(c, srcDir, destDir) |
900 | + |
901 | + // do it |
902 | + err = RSyncWithDelete(srcDir, destDir) |
903 | + c.Assert(err, IsNil) |
904 | + |
905 | + // ensure meta-data is identical |
906 | + compareDirs(c, srcDir, destDir) |
907 | + compareDirs(c, filepath.Join(srcDir, "subdir"), filepath.Join(destDir, "subdir")) |
908 | + } |
909 | +} |
910 | + |
911 | +func (ts *HTestSuite) TestSyncDirFails(c *C) { |
912 | + srcDir := c.MkDir() |
913 | + err := os.MkdirAll(srcDir, 0755) |
914 | + c.Assert(err, IsNil) |
915 | + |
916 | + destDir := c.MkDir() |
917 | + err = os.MkdirAll(destDir, 0755) |
918 | + c.Assert(err, IsNil) |
919 | + |
920 | + err = ioutil.WriteFile(filepath.Join(destDir, "meep"), []byte(nil), 0644) |
921 | + c.Assert(err, IsNil) |
922 | + |
923 | + // ensure remove fails |
924 | + err = os.Chmod(destDir, 0100) |
925 | + c.Assert(err, IsNil) |
926 | + // make tempdir cleanup work again |
927 | + defer os.Chmod(destDir, 0755) |
928 | + |
929 | + // do it |
930 | + err = RSyncWithDelete(srcDir, destDir) |
931 | + c.Check(err, NotNil) |
932 | + c.Check(err, ErrorMatches, ".*permission denied.*") |
933 | +} |
934 | +>>>>>>> MERGE-SOURCE |
935 | |
936 | === modified file 'helpers/touch.go' |
937 | === modified file 'oauth/oauth_test.go' |
938 | --- oauth/oauth_test.go 2015-06-09 13:02:35 +0000 |
939 | +++ oauth/oauth_test.go 2015-07-06 19:58:38 +0000 |
940 | @@ -1,3 +1,4 @@ |
941 | +<<<<<<< TREE |
942 | // -*- Mode: Go; indent-tabs-mode: t -*- |
943 | |
944 | /* |
945 | @@ -67,3 +68,74 @@ |
946 | c.Check(needsEscape(no), Equals, false) |
947 | } |
948 | } |
949 | +======= |
950 | +// -*- Mode: Go; indent-tabs-mode: t -*- |
951 | + |
952 | +/* |
953 | + * Copyright (C) 2014-2015 Canonical Ltd |
954 | + * |
955 | + * This program is free software: you can redistribute it and/or modify |
956 | + * it under the terms of the GNU General Public License version 3 as |
957 | + * published by the Free Software Foundation. |
958 | + * |
959 | + * This program is distributed in the hope that it will be useful, |
960 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
961 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
962 | + * GNU General Public License for more details. |
963 | + * |
964 | + * You should have received a copy of the GNU General Public License |
965 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
966 | + * |
967 | + */ |
968 | + |
969 | +package oauth |
970 | + |
971 | +import ( |
972 | + "testing" |
973 | + |
974 | + . "launchpad.net/gocheck" |
975 | +) |
976 | + |
977 | +func Test(t *testing.T) { TestingT(t) } |
978 | + |
979 | +type OAuthTestSuite struct{} |
980 | + |
981 | +var _ = Suite(&OAuthTestSuite{}) |
982 | + |
983 | +func (s *OAuthTestSuite) TestMakePlaintextSignature(c *C) { |
984 | + mockToken := Token{ |
985 | + ConsumerKey: "consumer-key+", |
986 | + ConsumerSecret: "consumer-secret+", |
987 | + TokenKey: "token-key+", |
988 | + TokenSecret: "token-secret+", |
989 | + } |
990 | + sig := MakePlaintextSignature(&mockToken) |
991 | + c.Assert(sig, Matches, `OAuth oauth_nonce="[a-zA-Z]+", oauth_timestamp="[0-9]+", oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="consumer-key%2B", oauth_token="token-key%2B", oauth_signature="consumer-secret%2B&token-secret%2B"`) |
992 | +} |
993 | + |
994 | +func (s *OAuthTestSuite) TestQuote(c *C) { |
995 | + // see http://wiki.oauth.net/w/page/12238556/TestCases |
996 | + c.Check(quote("abcABC123"), Equals, "abcABC123") |
997 | + c.Check(quote("-._~"), Equals, "-._~") |
998 | + c.Check(quote("%"), Equals, "%25") |
999 | + c.Check(quote("+"), Equals, "%2B") |
1000 | + c.Check(quote("&=*"), Equals, "%26%3D%2A") |
1001 | + c.Check(quote("\u000A"), Equals, "%0A") |
1002 | + c.Check(quote("\u0020"), Equals, "%20") |
1003 | + c.Check(quote("\u007F"), Equals, "%7F") |
1004 | + c.Check(quote("\u0080"), Equals, "%C2%80") |
1005 | + c.Check(quote("\u3001"), Equals, "%E3%80%81") |
1006 | +} |
1007 | + |
1008 | +func (s *OAuthTestSuite) TestNeedsEscape(c *C) { |
1009 | + for _, needed := range []byte{'?', '/', ':'} { |
1010 | + c.Check(needsEscape(needed), Equals, true) |
1011 | + } |
1012 | +} |
1013 | + |
1014 | +func (s *OAuthTestSuite) TestNeedsNoEscape(c *C) { |
1015 | + for _, no := range []byte{'a', 'z', 'A', 'Z', '-', '.', '_', '~'} { |
1016 | + c.Check(needsEscape(no), Equals, false) |
1017 | + } |
1018 | +} |
1019 | +>>>>>>> MERGE-SOURCE |
1020 | |
1021 | === modified file 'partition/bootloader_uboot.go' |
1022 | --- partition/bootloader_uboot.go 2015-07-01 06:27:50 +0000 |
1023 | +++ partition/bootloader_uboot.go 2015-07-06 19:58:38 +0000 |
1024 | @@ -203,6 +203,110 @@ |
1025 | return os.RemoveAll(bootloaderUbootStampFile) |
1026 | } |
1027 | |
1028 | +<<<<<<< TREE |
1029 | +======= |
1030 | +func (u *uboot) SyncBootFiles() (err error) { |
1031 | + srcDir := u.currentBootPath |
1032 | + destDir := u.otherBootPath |
1033 | + |
1034 | + return helpers.RSyncWithDelete(srcDir, destDir) |
1035 | +} |
1036 | + |
1037 | +func (u *uboot) HandleAssets() (err error) { |
1038 | + // check if we have anything, if there is no hardware yaml, there is nothing |
1039 | + // to process. |
1040 | + hardware, err := u.partition.hardwareSpec() |
1041 | + if err == ErrNoHardwareYaml { |
1042 | + return nil |
1043 | + } else if err != nil { |
1044 | + return err |
1045 | + } |
1046 | + // ensure to remove the file once we are done |
1047 | + defer os.Remove(u.partition.hardwareSpecFile) |
1048 | + |
1049 | + // validate bootloader |
1050 | + if hardware.Bootloader != u.Name() { |
1051 | + return fmt.Errorf( |
1052 | + "bootloader is of type %s but hardware spec requires %s", |
1053 | + u.Name(), |
1054 | + hardware.Bootloader) |
1055 | + } |
1056 | + |
1057 | + // validate partition layout |
1058 | + if u.partition.dualRootPartitions() && hardware.PartitionLayout != bootloaderSystemAB { |
1059 | + return fmt.Errorf("hardware spec requires dual root partitions") |
1060 | + } |
1061 | + |
1062 | + // ensure we have the destdir |
1063 | + destDir := u.otherBootPath |
1064 | + if err := os.MkdirAll(destDir, dirMode); err != nil { |
1065 | + return err |
1066 | + } |
1067 | + |
1068 | + // install kernel+initrd |
1069 | + for _, file := range []string{hardware.Kernel, hardware.Initrd} { |
1070 | + |
1071 | + if file == "" { |
1072 | + continue |
1073 | + } |
1074 | + |
1075 | + // expand path |
1076 | + path := path.Join(u.partition.cacheDir(), file) |
1077 | + |
1078 | + if !helpers.FileExists(path) { |
1079 | + return fmt.Errorf("can not find file %s", path) |
1080 | + } |
1081 | + |
1082 | + // ensure we remove the dir later |
1083 | + defer os.RemoveAll(filepath.Dir(path)) |
1084 | + |
1085 | + if err := runCommand("/bin/cp", path, destDir); err != nil { |
1086 | + return err |
1087 | + } |
1088 | + } |
1089 | + |
1090 | + // TODO: look at the OEM package for dtb changes too once that is |
1091 | + // fully speced |
1092 | + |
1093 | + // install .dtb files |
1094 | + dtbSrcDir := filepath.Join(u.partition.cacheDir(), hardware.DtbDir) |
1095 | + if helpers.FileExists(dtbSrcDir) { |
1096 | + // ensure we cleanup the source dir |
1097 | + defer os.RemoveAll(dtbSrcDir) |
1098 | + |
1099 | + dtbDestDir := path.Join(destDir, "dtbs") |
1100 | + if err := os.MkdirAll(dtbDestDir, dirMode); err != nil { |
1101 | + return err |
1102 | + } |
1103 | + |
1104 | + files, err := filepath.Glob(path.Join(dtbSrcDir, "*")) |
1105 | + if err != nil { |
1106 | + return err |
1107 | + } |
1108 | + |
1109 | + for _, file := range files { |
1110 | + if err := runCommand("/bin/cp", file, dtbDestDir); err != nil { |
1111 | + return err |
1112 | + } |
1113 | + } |
1114 | + } |
1115 | + |
1116 | + flashAssetsDir := u.partition.flashAssetsDir() |
1117 | + |
1118 | + if helpers.FileExists(flashAssetsDir) { |
1119 | + // FIXME: we don't currently do anything with the |
1120 | + // MLO + uImage files since they are not specified in |
1121 | + // the hardware spec. So for now, just remove them. |
1122 | + |
1123 | + if err := os.RemoveAll(flashAssetsDir); err != nil { |
1124 | + return err |
1125 | + } |
1126 | + } |
1127 | + |
1128 | + return err |
1129 | +} |
1130 | + |
1131 | +>>>>>>> MERGE-SOURCE |
1132 | // Write lines to file atomically. File does not have to preexist. |
1133 | // FIXME: put into utils package |
1134 | func atomicFileUpdateImpl(file string, lines []string) (err error) { |
1135 | |
1136 | === modified file 'partition/bootloader_uboot_test.go' |
1137 | --- partition/bootloader_uboot_test.go 2015-06-29 23:15:00 +0000 |
1138 | +++ partition/bootloader_uboot_test.go 2015-07-06 19:58:38 +0000 |
1139 | @@ -318,3 +318,40 @@ |
1140 | c.Check(strings.Contains(string(bytes), "snappy_mode=regular"), Equals, true) |
1141 | c.Check(strings.Contains(string(bytes), "snappy_ab=a"), Equals, true) |
1142 | } |
1143 | + |
1144 | +func (s *PartitionTestSuite) TestNoWriteNotNeeded(c *C) { |
1145 | + s.makeFakeUbootEnv(c) |
1146 | + |
1147 | + atomiCall := false |
1148 | + atomicFileUpdate = func(a string, b []string) error { atomiCall = true; return atomicFileUpdateImpl(a, b) } |
1149 | + |
1150 | + partition := New() |
1151 | + u := newUboot(partition) |
1152 | + c.Assert(u, NotNil) |
1153 | + |
1154 | + c.Check(u.MarkCurrentBootSuccessful(), IsNil) |
1155 | + c.Assert(atomiCall, Equals, false) |
1156 | +} |
1157 | + |
1158 | +func (s *PartitionTestSuite) TestWriteDueToMissingValues(c *C) { |
1159 | + s.makeFakeUbootEnv(c) |
1160 | + |
1161 | + // this file needs specific data |
1162 | + c.Assert(ioutil.WriteFile(bootloaderUbootEnvFile, []byte(""), 0644), IsNil) |
1163 | + |
1164 | + atomiCall := false |
1165 | + atomicFileUpdate = func(a string, b []string) error { atomiCall = true; return atomicFileUpdateImpl(a, b) } |
1166 | + |
1167 | + partition := New() |
1168 | + u := newUboot(partition) |
1169 | + c.Assert(u, NotNil) |
1170 | + |
1171 | + c.Check(u.MarkCurrentBootSuccessful(), IsNil) |
1172 | + c.Assert(atomiCall, Equals, true) |
1173 | + |
1174 | + bytes, err := ioutil.ReadFile(bootloaderUbootEnvFile) |
1175 | + c.Assert(err, IsNil) |
1176 | + c.Check(strings.Contains(string(bytes), "snappy_mode=try"), Equals, false) |
1177 | + c.Check(strings.Contains(string(bytes), "snappy_mode=regular"), Equals, true) |
1178 | + c.Check(strings.Contains(string(bytes), "snappy_ab=a"), Equals, true) |
1179 | +} |
1180 | |
1181 | === modified file 'partition/partition.go' |
1182 | --- partition/partition.go 2015-07-01 14:48:33 +0000 |
1183 | +++ partition/partition.go 2015-07-06 19:58:38 +0000 |
1184 | @@ -583,6 +583,7 @@ |
1185 | return errors.New("System is not dual root") |
1186 | } |
1187 | |
1188 | +<<<<<<< TREE |
1189 | bootloader, err := bootloader(p) |
1190 | if err != nil { |
1191 | return err |
1192 | @@ -606,4 +607,23 @@ |
1193 | } |
1194 | |
1195 | return bootloader.BootDir() |
1196 | +======= |
1197 | + bootloader, err := getBootloader(p) |
1198 | + if err != nil { |
1199 | + return err |
1200 | + } |
1201 | + |
1202 | + // XXX: first toggle roofs and then handle assets? that seems |
1203 | + // wrong given that handleAssets may fails and we will |
1204 | + // knowingly boot into a broken system |
1205 | + err = p.RunWithOther(RW, func(otherRoot string) (err error) { |
1206 | + return bootloader.ToggleRootFS() |
1207 | + }) |
1208 | + |
1209 | + if err != nil { |
1210 | + return err |
1211 | + } |
1212 | + |
1213 | + return bootloader.HandleAssets() |
1214 | +>>>>>>> MERGE-SOURCE |
1215 | } |
1216 | |
1217 | === modified file 'progress/progress.go' |
1218 | === modified file 'progress/progress_test.go' |
1219 | === modified file 'snappy/auth.go' |
1220 | === modified file 'snappy/auth_test.go' |
1221 | === modified file 'snappy/click.go' |
1222 | --- snappy/click.go 2015-06-17 12:02:24 +0000 |
1223 | +++ snappy/click.go 2015-07-06 19:58:38 +0000 |
1224 | @@ -332,9 +332,15 @@ |
1225 | AppArch string |
1226 | AppPath string |
1227 | Version string |
1228 | +<<<<<<< TREE |
1229 | UdevAppName string |
1230 | Origin string |
1231 | Home string |
1232 | +======= |
1233 | + UdevAppName string |
1234 | + Namespace string |
1235 | + Home string |
1236 | +>>>>>>> MERGE-SOURCE |
1237 | Target string |
1238 | AaProfile string |
1239 | OldAppVars string |
1240 | @@ -344,9 +350,15 @@ |
1241 | AppArch: helpers.UbuntuArchitecture(), |
1242 | AppPath: pkgPath, |
1243 | Version: m.Version, |
1244 | +<<<<<<< TREE |
1245 | UdevAppName: udevPartName, |
1246 | Origin: origin, |
1247 | Home: "$HOME", |
1248 | +======= |
1249 | + UdevAppName: udevPartName, |
1250 | + Namespace: namespace, |
1251 | + Home: "$HOME", |
1252 | +>>>>>>> MERGE-SOURCE |
1253 | Target: actualBinPath, |
1254 | AaProfile: aaProfile, |
1255 | } |
1256 | @@ -736,6 +748,7 @@ |
1257 | |
1258 | func installClick(snapFile string, flags InstallFlags, inter progress.Meter, origin string) (name string, err error) { |
1259 | allowUnauthenticated := (flags & AllowUnauthenticated) != 0 |
1260 | +<<<<<<< TREE |
1261 | part, err := NewSnapPartFromSnapFile(snapFile, origin, allowUnauthenticated) |
1262 | if err != nil { |
1263 | return "", err |
1264 | @@ -743,6 +756,251 @@ |
1265 | defer part.deb.Close() |
1266 | |
1267 | return part.Install(inter, flags) |
1268 | +======= |
1269 | + if err := auditClick(snapFile, allowUnauthenticated); err != nil { |
1270 | + return "", err |
1271 | + // ? |
1272 | + //return SnapAuditError |
1273 | + } |
1274 | + |
1275 | + d, err := clickdeb.Open(snapFile) |
1276 | + if err != nil { |
1277 | + return "", err |
1278 | + } |
1279 | + defer d.Close() |
1280 | + |
1281 | + manifestData, err := d.ControlMember("manifest") |
1282 | + if err != nil { |
1283 | + log.Printf("Snap inspect failed: %s", snapFile) |
1284 | + return "", err |
1285 | + } |
1286 | + |
1287 | + manifest, err := readClickManifest([]byte(manifestData)) |
1288 | + if err != nil { |
1289 | + return "", err |
1290 | + } |
1291 | + |
1292 | + yamlData, err := d.MetaMember("package.yaml") |
1293 | + if err != nil { |
1294 | + return "", err |
1295 | + } |
1296 | + |
1297 | + m, err := parsePackageYamlData(yamlData) |
1298 | + if err != nil { |
1299 | + return "", err |
1300 | + } |
1301 | + |
1302 | + if err := m.checkForPackageInstalled(namespace); err != nil { |
1303 | + return "", err |
1304 | + } |
1305 | + |
1306 | + // verify we have a valid architecture |
1307 | + if !helpers.IsSupportedArchitecture(m.Architectures) { |
1308 | + return "", &ErrArchitectureNotSupported{m.Architectures} |
1309 | + } |
1310 | + |
1311 | + if err := m.checkForNameClashes(); err != nil { |
1312 | + return "", err |
1313 | + } |
1314 | + |
1315 | + if err := m.checkForFrameworks(); err != nil { |
1316 | + return "", err |
1317 | + } |
1318 | + |
1319 | + targetDir := snapAppsDir |
1320 | + // the "oem" parts are special |
1321 | + if manifest.Type == SnapTypeOem { |
1322 | + targetDir = snapOemDir |
1323 | + |
1324 | + // TODO do the following at a higher level once the store publishes snap types |
1325 | + // this is horrible |
1326 | + if allowOEM := (flags & AllowOEM) != 0; !allowOEM { |
1327 | + if currentOEM, err := getOem(); err == nil { |
1328 | + if currentOEM.Name != manifest.Name { |
1329 | + fmt.Println(currentOEM.Name, manifest.Name) |
1330 | + return "", ErrOEMPackageInstall |
1331 | + } |
1332 | + } else { |
1333 | + // there should always be an oem package now |
1334 | + return "", ErrOEMPackageInstall |
1335 | + } |
1336 | + } |
1337 | + |
1338 | + if err := installOemHardwareUdevRules(m); err != nil { |
1339 | + return "", err |
1340 | + } |
1341 | + } |
1342 | + |
1343 | + fullName := manifest.Name |
1344 | + // namespacing only applies to apps. |
1345 | + if manifest.Type != SnapTypeFramework && manifest.Type != SnapTypeOem { |
1346 | + fullName += "." + namespace |
1347 | + } |
1348 | + instDir := filepath.Join(targetDir, fullName, manifest.Version) |
1349 | + currentActiveDir, _ := filepath.EvalSymlinks(filepath.Join(instDir, "..", "current")) |
1350 | + |
1351 | + if err := m.checkLicenseAgreement(inter, d, currentActiveDir); err != nil { |
1352 | + return "", err |
1353 | + } |
1354 | + |
1355 | + dataDir := filepath.Join(snapDataDir, fullName, manifest.Version) |
1356 | + |
1357 | + if err := helpers.EnsureDir(instDir, 0755); err != nil { |
1358 | + log.Printf("WARNING: Can not create %s", instDir) |
1359 | + } |
1360 | + |
1361 | + // if anything goes wrong here we cleanup |
1362 | + defer func() { |
1363 | + if err != nil { |
1364 | + if e := os.RemoveAll(instDir); e != nil && !os.IsNotExist(e) { |
1365 | + log.Printf("Warning: failed to remove %s: %s", instDir, e) |
1366 | + } |
1367 | + } |
1368 | + }() |
1369 | + |
1370 | + // we need to call the external helper so that we can reliable drop |
1371 | + // privs |
1372 | + if err := unpackWithDropPrivs(d, instDir); err != nil { |
1373 | + return "", err |
1374 | + } |
1375 | + |
1376 | + // legacy, the hooks (e.g. apparmor) need this. Once we converted |
1377 | + // all hooks this can go away |
1378 | + clickMetaDir := path.Join(instDir, ".click", "info") |
1379 | + if err := os.MkdirAll(clickMetaDir, 0755); err != nil { |
1380 | + return "", err |
1381 | + } |
1382 | + if err := writeCompatManifestJSON(clickMetaDir, manifestData, namespace); err != nil { |
1383 | + return "", err |
1384 | + } |
1385 | + |
1386 | + // write the hashes now |
1387 | + if err := writeHashesFile(d, instDir); err != nil { |
1388 | + return "", err |
1389 | + } |
1390 | + |
1391 | + inhibitHooks := (flags & InhibitHooks) != 0 |
1392 | + |
1393 | + // deal with the data: |
1394 | + // |
1395 | + // if there was a previous version, stop it |
1396 | + // from being active so that it stops running and can no longer be |
1397 | + // started then copy the data |
1398 | + // |
1399 | + // otherwise just create a empty data dir |
1400 | + if currentActiveDir != "" { |
1401 | + oldManifest, err := readClickManifestFromClickDir(currentActiveDir) |
1402 | + if err != nil { |
1403 | + return "", err |
1404 | + } |
1405 | + |
1406 | + // we need to stop making it active |
1407 | + err = unsetActiveClick(currentActiveDir, inhibitHooks, inter) |
1408 | + defer func() { |
1409 | + if err != nil { |
1410 | + if cerr := setActiveClick(currentActiveDir, inhibitHooks, inter); cerr != nil { |
1411 | + log.Printf("setting old version back to active failed: %v", cerr) |
1412 | + } |
1413 | + } |
1414 | + }() |
1415 | + if err != nil { |
1416 | + return "", err |
1417 | + } |
1418 | + |
1419 | + err = copySnapData(fullName, oldManifest.Version, manifest.Version) |
1420 | + } else { |
1421 | + err = helpers.EnsureDir(dataDir, 0755) |
1422 | + } |
1423 | + |
1424 | + defer func() { |
1425 | + if err != nil { |
1426 | + if cerr := removeSnapData(fullName, manifest.Version); cerr != nil { |
1427 | + log.Printf("when clenaning up data for %s %s: %v", manifest.Name, manifest.Version, cerr) |
1428 | + } |
1429 | + } |
1430 | + }() |
1431 | + |
1432 | + if err != nil { |
1433 | + return "", err |
1434 | + } |
1435 | + |
1436 | + // and finally make active |
1437 | + err = setActiveClick(instDir, inhibitHooks, inter) |
1438 | + defer func() { |
1439 | + if err != nil && currentActiveDir != "" { |
1440 | + if cerr := setActiveClick(currentActiveDir, inhibitHooks, inter); cerr != nil { |
1441 | + log.Printf("when setting old %s version back to active: %v", manifest.Name, cerr) |
1442 | + } |
1443 | + } |
1444 | + }() |
1445 | + if err != nil { |
1446 | + return "", err |
1447 | + } |
1448 | + |
1449 | + // oh, one more thing: refresh the security bits |
1450 | + if !inhibitHooks { |
1451 | + part, err := NewSnapPartFromYaml(filepath.Join(instDir, "meta", "package.yaml"), namespace, m) |
1452 | + if err != nil { |
1453 | + return "", err |
1454 | + } |
1455 | + |
1456 | + deps, err := part.Dependents() |
1457 | + if err != nil { |
1458 | + return "", err |
1459 | + } |
1460 | + |
1461 | + sysd := systemd.New(globalRootDir, inter) |
1462 | + stopped := make(map[string]time.Duration) |
1463 | + defer func() { |
1464 | + if err != nil { |
1465 | + for serviceName := range stopped { |
1466 | + if e := sysd.Start(serviceName); e != nil { |
1467 | + inter.Notify(fmt.Sprintf("unable to restart %s with the old %s: %s", serviceName, part.Name(), e)) |
1468 | + } |
1469 | + } |
1470 | + } |
1471 | + }() |
1472 | + |
1473 | + for _, dep := range deps { |
1474 | + if !dep.IsActive() { |
1475 | + continue |
1476 | + } |
1477 | + for _, svc := range dep.Services() { |
1478 | + serviceName := filepath.Base(generateServiceFileName(dep.m, svc)) |
1479 | + timeout := time.Duration(svc.StopTimeout) |
1480 | + if err = sysd.Stop(serviceName, timeout); err != nil { |
1481 | + inter.Notify(fmt.Sprintf("unable to stop %s; aborting install: %s", serviceName, err)) |
1482 | + return "", err |
1483 | + } |
1484 | + stopped[serviceName] = timeout |
1485 | + } |
1486 | + } |
1487 | + |
1488 | + if err := part.RefreshDependentsSecurity(currentActiveDir, inter); err != nil { |
1489 | + return "", err |
1490 | + } |
1491 | + |
1492 | + started := make(map[string]time.Duration) |
1493 | + defer func() { |
1494 | + if err != nil { |
1495 | + for serviceName, timeout := range started { |
1496 | + if e := sysd.Stop(serviceName, timeout); e != nil { |
1497 | + inter.Notify(fmt.Sprintf("unable to stop %s with the old %s: %s", serviceName, part.Name(), e)) |
1498 | + } |
1499 | + } |
1500 | + } |
1501 | + }() |
1502 | + for serviceName, timeout := range stopped { |
1503 | + if err = sysd.Start(serviceName); err != nil { |
1504 | + inter.Notify(fmt.Sprintf("unable to restart %s; aborting install: %s", serviceName, err)) |
1505 | + return "", err |
1506 | + } |
1507 | + started[serviceName] = timeout |
1508 | + } |
1509 | + } |
1510 | + |
1511 | + return manifest.Name, nil |
1512 | +>>>>>>> MERGE-SOURCE |
1513 | } |
1514 | |
1515 | // removeSnapData removes the data for the given version of the given snap |
1516 | |
1517 | === modified file 'snappy/click_test.go' |
1518 | === modified file 'snappy/errors.go' |
1519 | --- snappy/errors.go 2015-06-30 12:30:02 +0000 |
1520 | +++ snappy/errors.go 2015-07-06 19:58:38 +0000 |
1521 | @@ -138,13 +138,20 @@ |
1522 | |
1523 | // ErrInvalidPart is returned when something on the filesystem does not make sense |
1524 | ErrInvalidPart = errors.New("invalid package on system") |
1525 | +<<<<<<< TREE |
1526 | |
1527 | // ErrInvalidSeccompPolicy is returned when policy-version and policy-vender are not set together |
1528 | ErrInvalidSeccompPolicy = errors.New("policy-version and policy-vendor must be specified together") |
1529 | // ErrNoSeccompPolicy is returned when an expected seccomp policy is not provided. |
1530 | ErrNoSeccompPolicy = errors.New("no seccomp policy provided") |
1531 | +======= |
1532 | + |
1533 | + // ErrNoSeccompPolicy is returned when an expected seccomp policy is not provided. |
1534 | + ErrNoSeccompPolicy = errors.New("no seccomp policy provided") |
1535 | +>>>>>>> MERGE-SOURCE |
1536 | ) |
1537 | |
1538 | +<<<<<<< TREE |
1539 | // ErrDownload represents a download error |
1540 | type ErrDownload struct { |
1541 | code int |
1542 | @@ -165,6 +172,18 @@ |
1543 | return fmt.Sprintf("package's supported architectures (%s) is incompatible with this system (%s)", strings.Join(e.architectures, ", "), helpers.UbuntuArchitecture()) |
1544 | } |
1545 | |
1546 | +======= |
1547 | +// ErrArchitectureNotSupported is returned when trying to install a snappy package that |
1548 | +// is not supported on the system |
1549 | +type ErrArchitectureNotSupported struct { |
1550 | + architectures []string |
1551 | +} |
1552 | + |
1553 | +func (e *ErrArchitectureNotSupported) Error() string { |
1554 | + return fmt.Sprintf("package's supported architectures (%s) is incompatible with this system (%s)", strings.Join(e.architectures, ", "), helpers.UbuntuArchitecture()) |
1555 | +} |
1556 | + |
1557 | +>>>>>>> MERGE-SOURCE |
1558 | // ErrInstallFailed is an error type for installation errors for snaps |
1559 | type ErrInstallFailed struct { |
1560 | snap string |
1561 | @@ -184,7 +203,11 @@ |
1562 | } |
1563 | |
1564 | func (e *ErrHookFailed) Error() string { |
1565 | +<<<<<<< TREE |
1566 | return fmt.Sprintf("hook command %v failed with exit status %d (output: %q)", e.cmd, e.exitCode, e.output) |
1567 | +======= |
1568 | + return fmt.Sprintf("hook command %v failed with exit status %d (output: '%s')", e.cmd, e.exitCode, e.output) |
1569 | +>>>>>>> MERGE-SOURCE |
1570 | } |
1571 | |
1572 | // ErrDataCopyFailed is returned if copying the snap data fialed |
1573 | |
1574 | === modified file 'snappy/security.go' |
1575 | --- snappy/security.go 2015-06-24 17:05:21 +0000 |
1576 | +++ snappy/security.go 2015-07-06 19:58:38 +0000 |
1577 | @@ -151,11 +151,18 @@ |
1578 | syscalls := []string{} |
1579 | |
1580 | if sd.SecurityOverride != nil { |
1581 | +<<<<<<< TREE |
1582 | if sd.SecurityOverride.Seccomp == "" { |
1583 | logger.Noticef("No seccomp policy found") |
1584 | return nil, ErrNoSeccompPolicy |
1585 | } |
1586 | |
1587 | +======= |
1588 | + if sd.SecurityOverride.Seccomp == "" { |
1589 | + return nil, ErrNoSeccompPolicy |
1590 | + } |
1591 | + |
1592 | +>>>>>>> MERGE-SOURCE |
1593 | fn := filepath.Join(baseDir, sd.SecurityOverride.Seccomp) |
1594 | var s securitySeccompOverride |
1595 | err := readSeccompOverride(fn, &s) |
1596 | |
1597 | === modified file 'snappy/security_test.go' |
1598 | === modified file 'snappy/snapp.go' |
1599 | --- snappy/snapp.go 2015-07-06 17:12:53 +0000 |
1600 | +++ snappy/snapp.go 2015-07-06 19:58:38 +0000 |
1601 | @@ -40,9 +40,13 @@ |
1602 | |
1603 | "launchpad.net/snappy/clickdeb" |
1604 | "launchpad.net/snappy/helpers" |
1605 | +<<<<<<< TREE |
1606 | "launchpad.net/snappy/logger" |
1607 | "launchpad.net/snappy/oauth" |
1608 | "launchpad.net/snappy/pkg" |
1609 | +======= |
1610 | + "launchpad.net/snappy/oauth" |
1611 | +>>>>>>> MERGE-SOURCE |
1612 | "launchpad.net/snappy/policy" |
1613 | "launchpad.net/snappy/progress" |
1614 | "launchpad.net/snappy/release" |
1615 | @@ -1866,6 +1870,7 @@ |
1616 | // are required when calling a meta/hook/ script and that will override |
1617 | // any already existing SNAP_* variables in os.Environment() |
1618 | func makeSnapHookEnv(part *SnapPart) (env []string) { |
1619 | +<<<<<<< TREE |
1620 | desc := struct { |
1621 | AppName string |
1622 | AppArch string |
1623 | @@ -1880,6 +1885,22 @@ |
1624 | part.Version(), |
1625 | QualifiedName(part), |
1626 | part.Origin(), |
1627 | +======= |
1628 | + desc := struct { |
1629 | + AppName string |
1630 | + AppArch string |
1631 | + AppPath string |
1632 | + Version string |
1633 | + UdevAppName string |
1634 | + Namespace string |
1635 | + }{ |
1636 | + part.Name(), |
1637 | + helpers.UbuntuArchitecture(), |
1638 | + part.basedir, |
1639 | + part.Version(), |
1640 | + Dirname(part), |
1641 | + part.Namespace(), |
1642 | +>>>>>>> MERGE-SOURCE |
1643 | } |
1644 | snapEnv := helpers.MakeMapFromEnvList(helpers.GetBasicSnapEnvVars(desc)) |
1645 | |
1646 | |
1647 | === modified file 'snappy/snapp_test.go' |
1648 | --- snappy/snapp_test.go 2015-06-30 02:32:37 +0000 |
1649 | +++ snappy/snapp_test.go 2015-07-06 19:58:38 +0000 |
1650 | @@ -747,6 +747,7 @@ |
1651 | c.Check(p.notified[0], Matches, "Waiting for .* stop.") |
1652 | } |
1653 | |
1654 | +<<<<<<< TREE |
1655 | func (s *SnapTestSuite) TestErrorOnUnsupportedArchitecture(c *C) { |
1656 | const packageHello = `name: hello-app |
1657 | version: 1.10 |
1658 | @@ -766,6 +767,24 @@ |
1659 | c.Assert(err.Error(), Equals, errorMsg) |
1660 | } |
1661 | |
1662 | +======= |
1663 | +func (s *SnapTestSuite) TestErrorOnUnsupportedArchitecture(c *C) { |
1664 | + const packageHello = `name: hello-app |
1665 | +version: 1.10 |
1666 | +vendor: Somebody |
1667 | +icon: meta/hello.svg |
1668 | +architectures: |
1669 | + - yadayada |
1670 | + - blahblah |
1671 | +` |
1672 | + |
1673 | + snapPkg := makeTestSnapPackage(c, packageHello) |
1674 | + _, err := installClick(snapPkg, 0, nil, testNamespace) |
1675 | + errorMsg := fmt.Sprintf("package's supported architectures (yadayada, blahblah) is incompatible with this system (%s)", helpers.UbuntuArchitecture()) |
1676 | + c.Assert(err.Error(), Equals, errorMsg) |
1677 | +} |
1678 | + |
1679 | +>>>>>>> MERGE-SOURCE |
1680 | func (s *SnapTestSuite) TestRemoteSnapErrors(c *C) { |
1681 | snap := RemoteSnapPart{} |
1682 | |
1683 | |
1684 | === modified file 'snappy/systemimage.go' |
1685 | --- snappy/systemimage.go 2015-07-01 14:48:33 +0000 |
1686 | +++ snappy/systemimage.go 2015-07-06 19:58:38 +0000 |
1687 | @@ -191,10 +191,17 @@ |
1688 | |
1689 | // Ensure there is always a kernel + initrd to boot with, even |
1690 | // if the update does not provide new versions. |
1691 | +<<<<<<< TREE |
1692 | if pb != nil { |
1693 | pb.Notify("Syncing boot files") |
1694 | } |
1695 | err = s.partition.SyncBootloaderFiles(bootAssetFilePaths()) |
1696 | +======= |
1697 | + if pb != nil { |
1698 | + pb.Notify("Syncing boot files") |
1699 | + } |
1700 | + err = s.partition.SyncBootloaderFiles() |
1701 | +>>>>>>> MERGE-SOURCE |
1702 | if err != nil { |
1703 | return "", err |
1704 | } |
1705 | |
1706 | === modified file 'snappy/systemimage_native.go' |
1707 | === modified file 'systemd/systemd.go' |
1708 | --- systemd/systemd.go 2015-06-05 18:29:52 +0000 |
1709 | +++ systemd/systemd.go 2015-07-06 19:58:38 +0000 |
1710 | @@ -208,10 +208,17 @@ |
1711 | FullPathPostStop string |
1712 | AppTriple string |
1713 | ServiceSystemdTarget string |
1714 | +<<<<<<< TREE |
1715 | Origin string |
1716 | AppArch string |
1717 | Home string |
1718 | EnvVars string |
1719 | +======= |
1720 | + Namespace string |
1721 | + AppArch string |
1722 | + Home string |
1723 | + EnvVars string |
1724 | +>>>>>>> MERGE-SOURCE |
1725 | }{ |
1726 | *desc, |
1727 | filepath.Join(desc.AppPath, desc.Start), |
1728 | @@ -219,10 +226,17 @@ |
1729 | filepath.Join(desc.AppPath, desc.PostStop), |
1730 | fmt.Sprintf("%s_%s_%s", desc.AppName, desc.ServiceName, desc.Version), |
1731 | servicesSystemdTarget, |
1732 | +<<<<<<< TREE |
1733 | origin, |
1734 | helpers.UbuntuArchitecture(), |
1735 | "%h", |
1736 | "", |
1737 | +======= |
1738 | + namespace, |
1739 | + helpers.UbuntuArchitecture(), |
1740 | + "%h", |
1741 | + "", |
1742 | +>>>>>>> MERGE-SOURCE |
1743 | } |
1744 | allVars := helpers.GetBasicSnapEnvVars(wrapperData) |
1745 | allVars = append(allVars, helpers.GetUserSnapEnvVars(wrapperData)...) |
1746 | |
1747 | === modified file 'systemd/systemd_test.go' |
1748 | --- systemd/systemd_test.go 2015-06-05 18:29:52 +0000 |
1749 | +++ systemd/systemd_test.go 2015-07-06 19:58:38 +0000 |
1750 | @@ -26,9 +26,15 @@ |
1751 | "testing" |
1752 | "time" |
1753 | |
1754 | +<<<<<<< TREE |
1755 | . "gopkg.in/check.v1" |
1756 | |
1757 | "launchpad.net/snappy/helpers" |
1758 | +======= |
1759 | + . "launchpad.net/gocheck" |
1760 | + |
1761 | + "launchpad.net/snappy/helpers" |
1762 | +>>>>>>> MERGE-SOURCE |
1763 | ) |
1764 | |
1765 | type testreporter struct { |