~smoser/curtin/trunk.bzr-dead

« back to all changes in this revision

Viewing changes to tools/curtainer

  • Committer: Scott Moser
  • Date: 2017-12-20 17:33:03 UTC
  • Revision ID: smoser@ubuntu.com-20171220173303-29gha5qb8wpqrd40
README: Mention move of revision control to git.

curtin development has moved its revision control to git.
It is available at
  https://code.launchpad.net/curtin

Clone with
  git clone https://git.launchpad.net/curtin
or
  git clone git+ssh://git.launchpad.net/curtin

For more information see
  http://curtin.readthedocs.io/en/latest/topics/development.html

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/bin/bash
2
 
 
3
 
set -o pipefail
4
 
 
5
 
VERBOSITY=0
6
 
CONTAINER=""
7
 
 
8
 
error() { echo "$@" 1>&2; }
9
 
fail() { local r=$?;  [ $r -eq 0 ] && r=1; failrc "$r" "$@"; }
10
 
failrc() { local r=$1; shift; [ $# -eq 0 ] || error "$@"; exit $r; }
11
 
 
12
 
Usage() {
13
 
    cat <<EOF
14
 
Usage: ${0##*/} [ options ] <image> name
15
 
 
16
 
   start a container of image (ubuntu-daily:xenial) and install curtin.
17
 
 
18
 
   options:
19
 
      --proposed    enable proposed
20
 
      --daily       enable daily curtin archive
21
 
      --source   D  grab the source deb, unpack inside, and copy unpacked
22
 
                    source out to 'D'
23
 
EOF
24
 
}
25
 
 
26
 
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
27
 
cleanup() {
28
 
    if [ -n "$CONTAINER" ]; then
29
 
        debug 1 "deleting container $CONTAINER"
30
 
        lxc delete --force "$CONTAINER"
31
 
    fi
32
 
}
33
 
 
34
 
inside() {
35
 
    local n="$1" close_in=true
36
 
    shift
37
 
    [ "$1" = "-" ] && { close_in=false; shift; }
38
 
    set -- lxc exec --mode=non-interactive "$n" -- "$@"
39
 
    if ${close_in}; then
40
 
        debug 1 "$* </dev/null"
41
 
        "$@" </dev/null
42
 
    else
43
 
        debug 1 "$*"
44
 
        "$@"
45
 
    fi
46
 
}
47
 
 
48
 
install() {
49
 
    local name="$1"
50
 
    shift
51
 
    inside "$name" $eatmydata \
52
 
        env DEBIAN_FRONTEND=noninteractive \
53
 
        apt-get install --no-install-recommends -qy "$@" || {
54
 
            error "failed apt-get install --no-install-recommends -qy $*"
55
 
            return 1
56
 
        }
57
 
}
58
 
 
59
 
wait_for_ready() {
60
 
    local n="$1" max="${2:-30}" debug=${3}
61
 
    inside "$n" - /bin/sh -s $max $debug <<"EOF"
62
 
max=$1; debug=${2:-0};
63
 
i=0;
64
 
while [ ! -e /run/cloud-init/result.json ] && i=$(($i+1)); do
65
 
    [ $i -ge $max ] && exit 1
66
 
    [ "$debug" = "0" ] || echo -n .
67
 
    sleep 1
68
 
done
69
 
[ "$debug" = "0" ] || echo "[done after $i]"
70
 
exit 0
71
 
}
72
 
EOF
73
 
}
74
 
 
75
 
debug() {
76
 
    local level=${1}; shift;
77
 
    [ "${level}" -gt "${VERBOSITY}" ] && return
78
 
    error "${@}"
79
 
}
80
 
 
81
 
main() {
82
 
    local short_opts="hv"
83
 
    local long_opts="help,daily,proposed,source:,verbose"
84
 
    local getopt_out=""
85
 
    getopt_out=$(getopt --name "${0##*/}" \
86
 
        --options "${short_opts}" --long "${long_opts}" -- "$@") &&
87
 
        eval set -- "${getopt_out}" ||
88
 
        { bad_Usage; return; }
89
 
 
90
 
    local cur="" next=""
91
 
    local proposed=false daily=false src="" name="" maxwait=30
92
 
    local eatmydata="eatmydata" getsource="none"
93
 
 
94
 
    while [ $# -ne 0 ]; do
95
 
        cur="$1"; next="$2";
96
 
        case "$cur" in
97
 
            -h|--help) Usage ; exit 0;;
98
 
               --source) getsource="$next"; shift;;
99
 
               --proposed) proposed=true;;
100
 
               --daily) daily=true;;
101
 
            -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
102
 
            --) shift; break;;
103
 
        esac
104
 
        shift;
105
 
    done
106
 
 
107
 
    [ $# -eq 2 ] || { bad_Usage "expected 2 args, got $#: $*"; return; }
108
 
 
109
 
    trap cleanup EXIT
110
 
    src="$1"
111
 
    name="$2"
112
 
 
113
 
    if [ "$getsource" != "none" ]; then
114
 
        [ ! -e "$getsource" ] || fail "source output '$getsource' exists."
115
 
    fi
116
 
 
117
 
    lxc launch "$src" "$name" || fail "failed lxc launch $src $name"
118
 
    CONTAINER=$name
119
 
 
120
 
    wait_for_ready "$name" $maxwait $VERBOSITY ||
121
 
        fail "$name did not become ready after $maxwait"
122
 
 
123
 
    inside "$name" which eatmydata >/dev/null || eatmydata=""
124
 
 
125
 
    if $proposed; then
126
 
        mirror=$(inside $name awk '$1 == "deb" { print $2; exit(0); }' \
127
 
            /etc/apt/sources.list) &&
128
 
            rel=$(inside $name lsb_release -sc) ||
129
 
            fail "failed to get mirror in $name"
130
 
        line="$mirror $rel-proposed main universe"
131
 
        local fname="/etc/apt/sources.list.d/proposed.list"
132
 
        debug 1 "enabling proposed in $fname: deb $line"
133
 
        inside "$name" sh -c "echo deb $line > $fname" ||
134
 
            fail "failed adding proposed to $fname"
135
 
        if [ "$getsource" != "none" ]; then
136
 
            inside "$name" sh -c "echo deb-src $line >> $fname" ||
137
 
                fail "failed adding proposed deb-src to $fname"
138
 
        fi
139
 
    fi
140
 
    if $daily; then
141
 
        local daily_ppa="ppa:curtin-dev/daily"
142
 
        debug 1 "enabling daily: $daily_ppa"
143
 
        inside "$name" add-apt-repository --enable-source --yes \
144
 
            "${daily_ppa}" ||
145
 
            fail "failed add-apt-repository for daily."
146
 
    fi
147
 
 
148
 
    line="Acquire::Languages \"none\";"
149
 
    fname="/etc/apt/apt.conf.d/99notranslations"
150
 
    inside "$name" sh -c '
151
 
        rm -f /var/lib/apt/lists/*Translation*;
152
 
        echo "$1" > "$2"' -- "$line" "$fname" ||
153
 
        error "failed to disable translations"
154
 
 
155
 
    pkgs="curtin"
156
 
    if [ "${getsource}" = "none" ]; then
157
 
        inside "$name" sed -i '/^deb-src/s/^/#/' /etc/apt/sources.list ||
158
 
            error "failed to disable deb-src entries"
159
 
    else
160
 
        pkgs="${pkgs} dpkg-dev"
161
 
    fi
162
 
 
163
 
    inside "$name" $eatmydata apt-get -q update ||
164
 
        fail "failed apt-get update"
165
 
    install "$name" $pkgs || fail "failed install of $pkgs"
166
 
 
167
 
    if [ "${getsource}" != "none" ]; then
168
 
        local isrcd="/tmp/curtin-source"
169
 
        debug 1 "getting source for curtin to $getsource"
170
 
        inside "$name" $eatmydata sh -ec '
171
 
            target="$1"
172
 
            d=$(mktemp -d)
173
 
            cd "$d"
174
 
            apt-get source curtin
175
 
            for x in *; do [ -d "$x" ] && break; done
176
 
            [ -d "$x" ] || { echo no source dir found.; exit 1; }
177
 
            cp -a $x "$target"
178
 
            rm -Rf "$d"
179
 
            ' -- "$isrcd"
180
 
        mkdir "$getsource" || fail "failed to create dir '$getsource'"
181
 
        inside "$name" tar -C "$isrcd" -cf - . |
182
 
            tar -C "$getsource" -xf - ||
183
 
            fail "failed to copy source out to $getsource"
184
 
        version=$(inside "$name" dpkg-parsechangelog \
185
 
            "--file=$isrcd/debian/changelog" "--show-field=version")
186
 
        inside "$name" rm -Rf "$isrcd" ||
187
 
            fail "failed removal of extract dir"
188
 
        debug 1 "put source for curtin at $version in $getsource"
189
 
    fi
190
 
 
191
 
    CONTAINER=""
192
 
}
193
 
 
194
 
main "$@"
195
 
# vi: ts=4 expandtab