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

Subscribers

People subscribed via source and target branches