Merge lp:~smoser/maas/lp-1313550 into lp:~maas-committers/maas/trunk

Proposed by Scott Moser
Status: Merged
Merged at revision: 4028
Proposed branch: lp:~smoser/maas/lp-1313550
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 60 lines (+31/-15)
1 file modified
src/provisioningserver/import_images/uec2roottar.py (+31/-15)
To merge this branch: bzr merge lp:~smoser/maas/lp-1313550
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Needs Fixing
Review via email: mp+261981@code.launchpad.net

Description of the change

use xattr flags when available

Currently when maas collects the tarball from a image, it does not collect
xattrs. This means its a lossy conversion, which can cause problems
in runtime such as those seen in bug 1313550.

The change here adds the flags
  --xattrs '--xattrs-include=*'
if and only if the system 'tar' supports those. Note, tar on 12.04
does *not* support xattrs.

To post a comment you must log in.
Revision history for this message
Scott Moser (smoser) wrote :

Note, I know tests are broken by this. Probably need to mock tar_xattr_opts and then test both possible returns.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

We won't be able to land it until the tests pass. Let me pull your branch and take a look.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Here's what will need to be fixed before we can land this:

$ make lint
src/provisioningserver/import_images/uec2roottar.py:155:19: F821 undefined name 'curtin'
make: *** [lint-py] Error 123

Test failures:
http://paste.ubuntu.com/11720348/

Obviously the lint problem will need to be fixed, but see the note in the diff below regarding the test failures.

review: Needs Fixing
Revision history for this message
Mike Pontillo (mpontillo) wrote :

You may be able to quickly fix the tests if you just figure out how you want to remove the 'str' parameter from the isinstance() call.

Revision history for this message
Scott Moser (smoser) wrote :

  You can drop the 'isinstance' entirely, but then the caller just has to pass in a list.
  All that did was say "if the caller gave me a string make it a list" as the list is what is necessary for check_output.

I dont see how that would affect tests.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

The isinstance() itself isn't wrong; it's just that in MAAS we set "str = None" at the top, so you can't use "str" in the isinstance(). That's why the tests failed. Had you changed it to test for "not a list" or "unicode" instead, it probably would have been fine.

Revision history for this message
Gavin Panella (allenap) wrote :

Or use `bytes` in Python 2.

Revision history for this message
Scott Moser (smoser) wrote :

oh. ok. well, its dropped as unnecesary now.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Different error this time:

http://paste.ubuntu.com/11727540/

review: Needs Fixing
Revision history for this message
Raphaël Badin (rvb) wrote :

Thanks Scott. I've added the tests to your code in https://code.launchpad.net/~rvb/maas/lp-1313550/+merge/262314.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/import_images/uec2roottar.py'
2--- src/provisioningserver/import_images/uec2roottar.py 2015-05-07 18:14:38 +0000
3+++ src/provisioningserver/import_images/uec2roottar.py 2015-06-16 13:47:22 +0000
4@@ -144,25 +144,41 @@
5 unmount(mountpoint)
6
7
8+def tar_xattr_opts(cmd=None):
9+ # if tar cmd supports xattrs, return the required flags to extract them.
10+ if cmd is None:
11+ cmd = ['tar']
12+
13+ out = check_output(cmd + ['--help'], capture=True)
14+
15+ if "xattr" in out:
16+ return ['--xattrs', '--xattrs-include=*']
17+ return []
18+
19+
20 def extract_image(image, output):
21 """Loop-mount `image`, and tar its contents into `output`."""
22+
23+ tar = ['tar']
24+ xattr_opts = tar_xattr_opts(tar)
25 with tempdir() as mountpoint:
26+ cmd = tar + xattr_opts + [
27+ # Work from mountpoint as the current directory.
28+ '-C', mountpoint,
29+ # Options:
30+ # -c: Create tarfile.
31+ # -p: Preserve permissions.
32+ # -S: Handle sparse files efficiently (images have those).
33+ # -z: Compress using gzip.
34+ # -f: Work on given tar file.
35+ '-cpSzf', output,
36+ '--numeric-owner',
37+ # Tar up the "current directory": the mountpoint.
38+ '.',
39+ ]
40+
41 with loop_mount(image, mountpoint):
42- check_call([
43- 'tar',
44- # Work from mountpoint as the current directory.
45- '-C', mountpoint,
46- # Options:
47- # -c: Create tarfile.
48- # -p: Preserve permissions.
49- # -S: Handle sparse files efficiently (images have those).
50- # -z: Compress using gzip.
51- # -f: Work on given tar file.
52- '-cpSzf', output,
53- '--numeric-owner',
54- # Tar up the "current directory": the mountpoint.
55- '.',
56- ])
57+ check_call(cmd)
58
59
60 def set_ownership(path, user=None):