Merge lp:~smoser/curtin/trunk.use-smtar into lp:~curtin-dev/curtin/trunk

Proposed by Scott Moser
Status: Merged
Approved by: Ryan Harper
Approved revision: 295
Merged at revision: 311
Proposed branch: lp:~smoser/curtin/trunk.use-smtar
Merge into: lp:~curtin-dev/curtin/trunk
Diff against target: 164 lines (+123/-2)
4 files modified
curtin/commands/extract.py (+5/-2)
curtin/deps/__init__.py (+1/-0)
debian/control (+1/-0)
helpers/smtar (+116/-0)
To merge this branch: bzr merge lp:~smoser/curtin/trunk.use-smtar
Reviewer Review Type Date Requested Status
Ryan Harper (community) Needs Fixing
Review via email: mp+276007@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Ryan Harper (raharper) wrote :

This is missing a unit/functional test of smtar.

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

After merging https://code.launchpad.net/~smoser/curtin/install-from-url/+merge/277482
we're now installing from a url. That url is gzip compressed, so smtar would be used.

One thing i'd like to do is to be able to run the tests with a install from .tar also.

the reason would be that on a local system, installing http://host.ip/foo.tar does uncompressed transfer through virtio with no decompression cost. while the .tar.gz does compressed transfer at cost of decompress to cpu.

lp:~smoser/curtin/trunk.use-smtar updated
292. By Scott Moser

merge from trunk

293. By Scott Moser

merge from trunk

294. By Scott Moser

precise's 'file' says application/x-gzip not application/gzip.

295. By Scott Moser

update dependencies

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

ok. so we're now pushing code through 'smtar' in vmtest. We can definitely add unit tests, but the code path is executed now.

I ran a full test suite successfully through here.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'curtin/commands/extract.py'
2--- curtin/commands/extract.py 2015-10-28 20:29:28 +0000
3+++ curtin/commands/extract.py 2015-11-19 01:21:54 +0000
4@@ -52,10 +52,13 @@
5
6
7 def extract_root_tgz_url(source, target):
8+ # extract a -root.tar.gz url in the 'target' directory
9+ #
10+ # Uses smtar to avoid specifying the compression type
11 curtin.util.subp(args=['sh', '-cf',
12 ('wget "$1" --progress=dot:mega -O - |'
13- 'tar -C "$2" ' + ' '.join(tar_xattr_opts()) +
14- ' ' + '-Sxpzf - --numeric-owner'),
15+ 'smtar -C "$2" ' + ' '.join(tar_xattr_opts()) +
16+ ' ' + '-Sxpf - --numeric-owner'),
17 '--', source, target])
18
19
20
21=== modified file 'curtin/deps/__init__.py'
22--- curtin/deps/__init__.py 2015-11-18 16:36:32 +0000
23+++ curtin/deps/__init__.py 2015-11-19 01:21:54 +0000
24@@ -27,6 +27,7 @@
25
26 REQUIRED_EXECUTABLES = [
27 # executable in PATH, package
28+ ('file', 'file'),
29 ('lvcreate', 'lvm2'),
30 ('mdadm', 'mdadm'),
31 ('mkfs.btrfs', 'btrfs-tools'),
32
33=== modified file 'debian/control'
34--- debian/control 2015-11-17 18:28:30 +0000
35+++ debian/control 2015-11-19 01:21:54 +0000
36@@ -27,6 +27,7 @@
37 Priority: extra
38 Depends: btrfs-tools,
39 e2fsprogs,
40+ file,
41 gdisk,
42 lvm2,
43 mdadm,
44
45=== added file 'helpers/smtar'
46--- helpers/smtar 1970-01-01 00:00:00 +0000
47+++ helpers/smtar 2015-11-19 01:21:54 +0000
48@@ -0,0 +1,116 @@
49+#!/bin/sh
50+# smtar (smart tar)
51+# GNU Tar can only determine the compression type if input is a local file.
52+# If input is a pipe, it will not even attempt.
53+#
54+# This works around that limitation by using 'file' to determine
55+# the compression format via a local temp file of BUFLEN (1024) bytes.
56+# After determining format, it passes the correct flag to tar.
57+#
58+# Compression format determination is done with 'file' via use of a temp file
59+#
60+# The following are supported:
61+#
62+# # compression option provided explicitly: just exec tar
63+# $ ./smtar -tvz < my.tar.gz
64+#
65+# # file argument provided, tar can determine: just exec tar
66+# $ ./smtar -tvf my.tar.gz
67+# $ ./smtar -tvf my.tar
68+#
69+# # input from stdin. determine the appropriate compress flag and execute
70+# $ ./smtar -tv < my.tar.bz2
71+# $ ./smtar -tv < my.tar.bz2
72+# $ cat my.tar.xz | ./smtar -tv -f -
73+# $ wget http://some.tar | ./smtar -tv -f -
74+#
75+#
76+TEMPF=""
77+BUFLEN="1024"
78+cleanup() { [ -z "$TEMPF" ] || rm -f "$TEMPF"; }
79+error() { echo "$@" 1>&2; }
80+fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
81+find_tar_filearg() {
82+ # walk through list of args, return the 'file' argument in _RET
83+ local cur="" next=""
84+ while [ $# -ne 0 ]; do
85+ cur="$1"
86+ next="$2"
87+ case "$cur" in
88+ --file=*) _RET=${cur#*=}; return 0;;
89+ --file) _RET=$next; return 0;;
90+ --*=*) :;;
91+ *-f) _RET="$next"; return 0;;
92+ --) _RET=""; return 0;;
93+ esac
94+ shift
95+ done
96+ return 1
97+}
98+
99+tar_has_compress_opt() {
100+ # this isnt perfect, but catch common ways
101+ # without fully parsing the args, we risk interpreting
102+ # tar -xvf -J
103+ # as bzip2 compression, where in reality its a file name '-J'
104+ local cur="" next=""
105+ while [ $# -ne 0 ]; do
106+ cur="$1"
107+ next="$2"
108+ case "$cur" in
109+ -z|--gzip|--gunzip|--ungzip) return 0;;
110+ -j|--bzip2) return 0;;
111+ -J|--xz) return 0;;
112+ -Z|--compress|--uncompress) return 0;;
113+ --) return 1;;
114+ esac
115+ shift
116+ done
117+ return 1
118+}
119+
120+# see if we can get out without reading anything
121+if [ -t 0 ] || tar_has_compress_opt; then
122+ # input is a terminal, or args contain a compress option
123+ exec tar "$@"
124+fi
125+
126+# if there was a compression arg in input, then let it be
127+find_tar_filearg "$@"
128+if ! [ "$_RET" = "/dev/stdin" -o "$_RET" = "-" -o -z "$_RET" ]; then
129+ exec "tar" "$@"
130+fi
131+
132+# now we have work to do
133+zopt=""
134+TEMPF=$(mktemp) || fail "mktemp failed"
135+trap cleanup EXIT
136+head -c "$BUFLEN" > "$TEMPF" || fail "FAILED: head -c '$BUFLEN'"
137+size=$(stat --format="%s" "$TEMPF")
138+file_out=$(LANG=C file --mime-type "$TEMPF")
139+# my.tar: application/x-tar
140+# my.tar.bz2: application/x-bzip2
141+# my.tar.gz: application/gzip
142+# my.tar.xz: application/x-xz
143+# my.tar.Z: application/x-compress
144+if [ $? -eq 0 ]; then
145+ case "$file_out" in
146+ */x-bzip2|*/bzip2) zopt="--bzip2";;
147+ */x-gzip|*/gzip) zopt="--gzip";;
148+ */x-xz|*/xz) zopt="--xz";;
149+ */x-compress|*/compress) zopt="--compress";;
150+ *) zopt="";;
151+ esac
152+else
153+ error "WARN: 'file' failed on input"
154+fi
155+if [ "$size" -lt "$BUFLEN" ]; then
156+ # input was less than BUFLEN chars, so we just exec tar with input from it
157+ exec < "$TEMPF"
158+ rm -f "$TEMPF"
159+ exec tar $zopt "$@"
160+else
161+ ( cat "$TEMPF" && rm "$TEMPF" && exec cat ) | exec tar $zopt "$@"
162+fi
163+
164+# vi: ts=4 expandtab syntax=sh

Subscribers

People subscribed via source and target branches