Merge lp:~jtv/maas/import-ephemerals-tftp into lp:maas/trunk

Proposed by Jeroen T. Vermeulen on 2012-06-27
Status: Merged
Approved by: Jeroen T. Vermeulen on 2012-06-28
Approved revision: 692
Merged at revision: 692
Proposed branch: lp:~jtv/maas/import-ephemerals-tftp
Merge into: lp:maas/trunk
Diff against target: 304 lines (+107/-9)
2 files modified
etc/celeryconfig.py (+1/-1)
scripts/maas-import-ephemerals (+106/-8)
To merge this branch: bzr merge lp:~jtv/maas/import-ephemerals-tftp
Reviewer Review Type Date Requested Status
Gavin Panella (community) 2012-06-27 Approve on 2012-06-27
Francesco Banconi (community) code* 2012-06-27 Approve on 2012-06-27
Review via email: mp+112353@code.launchpad.net

Commit Message

Make the maas-import-ephemerals script expose netboot kernels/initrds on the MAAS TFTP setup.

Description of the Change

This is horrific. We have no tests for maas-import-ephemerals, and as yet no clear way to add any, and nothing is documented. And it requires Cobbler.

I'm trying to work around some of these problems along the way. The diff consists of 3 kinds of changes:

1. Publish newly downloaded ephemeral images through the MAAS TFTP setup.

This makes use of a custom maas command that was created for the purpose, and which is already used in maas-import-pxe-files. That script is to replace maas-import-isos. Thanks to the custom command, the addition to maas-import-ephemerals is reasonably small and simple.

2. Optionally skip Cobbler-related portions of the script.

Some parts of the script are now wrapped in a $NO_COBBLER condition. That is, you can set a variable NO_COBBLER and the script will no longer attempt to do anything related to Cobbler. It may still need tweaking, and there's probably more that can be shaved off, but this will mean that when the time comes to drop the Cobbler parts, part of the work will already be done. Actually this mostly just helps me try out as much as possible on my cobblerless system. Which, besides revealing a silly mistake in my script code, also allowed me to find a nasty little bug in the defaults as you'll see in the diff!

3. Document what I can.

This is depressingly little, as it happens. But I've had to do some figuring out and at least now I see a bit of how the images are exported over iSCSI, and I managed to figure out what some of the required parameters are. It'd be a shame not to share those nuggets of hard-won knowledge.

Jeroen

To post a comment you must log in.
Francesco Banconi (frankban) wrote :

Thanks for this branch Jeroen, and thanks for adding comments to the shell script.
I believe that you didn't indented the code inside the [if cobblers is null] blocks on purpose, because this is a work in progress to get rid of cobbler, and the NO_COBBLER var will go away in the future.

Just an observation:

221 + maas install_pxe_image \
222 + --arch=$arch --subarch=$2 --release=$release \
223 + --purpose="commissioning" --image="$tmpdir"

Shouldn't "$subarch" be passed to --subarch, rather than "$2"?

review: Approve (code*)
Jeroen T. Vermeulen (jtv) wrote :

Thanks! Yes, you're right on both scores. I fixed the --subarch argument.

lp:~jtv/maas/import-ephemerals-tftp updated on 2012-06-27
692. By Jeroen T. Vermeulen on 2012-06-27

Review changes.

Gavin Panella (allenap) wrote :

Only one thing to add to Francesco's review:

[1]

+# Cobbler is being removed from MAAS. Set NO_COBBLER to skip anything
+# in this script that is related to Cobbler.
+NO_COBBLER=${NO_COBBLER:-}

Consider making this non-negative, HAS_COBBLER for example.

review: Approve
Jeroen T. Vermeulen (jtv) wrote :

I considered phrasing NO_COBBLER in a non-negative way, but in this case the negative expresses exactly what we want: no Cobbler. HAS_COBBLER suggests that having Cobbler installed is desirable.

At any rate, it's transitional so not worth much bother.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'etc/celeryconfig.py'
2--- etc/celeryconfig.py 2012-06-26 04:22:16 +0000
3+++ etc/celeryconfig.py 2012-06-27 14:55:24 +0000
4@@ -30,7 +30,7 @@
5 "templates")
6
7 # TFTP server's root directory.
8-TFTPROOT = "/var/lib/tftp"
9+TFTPROOT = "/var/lib/tftpboot"
10
11
12 try:
13
14=== modified file 'scripts/maas-import-ephemerals'
15--- scripts/maas-import-ephemerals 2012-04-18 21:38:17 +0000
16+++ scripts/maas-import-ephemerals 2012-06-27 14:55:24 +0000
17@@ -19,24 +19,44 @@
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21+# Cobbler is being removed from MAAS. Set NO_COBBLER to skip anything
22+# in this script that is related to Cobbler.
23+NO_COBBLER=${NO_COBBLER:-}
24+
25 VERBOSITY=0
26 REMOTE_IMAGES_MIRROR="https://maas.ubuntu.com/images"
27+
28+if [ -z "$NO_COBBLER" ]
29+then
30 CONSOLE="ttyS0,9600n8"
31 EPH_KOPTS_CONSOLE="console=$CONSOLE"
32 EPH_KOPTS_ISCSI="ip=dhcp iscsi_target_name=@@iscsi_target@@ iscsi_target_ip=@@iscsi_target_ip@@ iscsi_target_port=3260"
33 EPH_KOPTS_ROOT="root=LABEL=cloudimg-rootfs ro"
34 EPH_KOPTS_LOGGING="log_host=@@server_ip@@ log_port=514"
35+KSDIR="/var/lib/cobbler/kickstarts"
36+KICKSTART="$KSDIR/maas-commissioning.preseed"
37+SYS_TGT_CONF="/etc/tgt/targets.conf"
38+fi
39+
40+# TODO: What's this for? If set, it gets run on a downloaded disk.img,
41+# kernel, and initrd.
42 EPH_UPDATE_CMD=""
43+
44+# Prefix for iSCSI target name.
45 TARGET_NAME_PREFIX="iqn.2004-05.com.ubuntu:maas:"
46+
47+# TODO: DATA_DIR seems to be the root of a directory tree that's exposed over
48+# iSCSI for download by nodes. Can we confirm this?
49 DATA_DIR="/var/lib/maas/ephemeral"
50+
51+# Optional configuration script that may set variables for use by this
52+# script. It gets sourced later on.
53 CONFIG="/etc/maas/import_ephemerals"
54+
55 RELEASES="precise"
56 ARCHES="amd64 i386"
57 BUILD_NAME="ephemeral"
58 STREAM="released"
59-KSDIR="/var/lib/cobbler/kickstarts"
60-KICKSTART="$KSDIR/maas-commissioning.preseed"
61-SYS_TGT_CONF="/etc/tgt/targets.conf"
62
63 # DATA_DIR layout is like:
64 # tgt.conf
65@@ -57,6 +77,7 @@
66 fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
67 failp() { [ $# -eq 0 ] || errorp "$@"; exit 1; }
68
69+
70 Usage() {
71 cat <<EOF
72 Usage: ${0##*/} [ options ] <<ARGUMENTS>>
73@@ -73,32 +94,45 @@
74 EOF
75 }
76
77+
78 bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
79+
80+
81 cleanup() {
82 [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
83 }
84
85+
86 debug() {
87 local level=${1}; shift;
88 [ "${level}" -gt "${VERBOSITY}" ] && return
89 error "${@}"
90 }
91+
92+
93 arch2u() {
94- # arch2ubuntu
95+ # Normalize architecture name to an Ubuntu architecture name.
96 _RET=$1
97 case "$1" in
98 i?86) _RET=i386;;
99 x86_64) _RET=amd64;;
100 esac
101 }
102+
103+
104+if [ -z "$NO_COBBLER" ]
105+then
106 arch2cob() {
107- # arch 2 cobbler arch
108+ # Normalize an architecture name for use in Cobbler.
109 _RET=$1
110 case "$1" in
111 i?86) _RET=i386;;
112 amd64) _RET=x86_64;;
113 esac
114 }
115+fi
116+
117+
118 query_remote() {
119 # query /query data at REMOTE_IMAGES_MIRROR
120 # returns 7 values prefixed with 'r_'
121@@ -131,6 +165,7 @@
122 return
123 }
124
125+
126 query_local() {
127 local iarch=$1 irelease=$2 istream=$3 out=""
128 local label="" name="" serial="" url=""
129@@ -159,6 +194,8 @@
130 l_dir="${found%/*}";
131 fi
132 }
133+
134+
135 serial_gt() {
136 # is $1 a larger serial than $2 ?
137 local a=${1:-0} b=${2:-0}
138@@ -171,6 +208,7 @@
139 [ $a -gt $b ]
140 }
141
142+
143 prep_dir() {
144 local wd="$1" exdir="" tarball=""
145 shift
146@@ -238,7 +276,7 @@
147 { error "failed to move extracted kernel to $wd/kernel"; return 1; }
148
149 [ -z "$initrd" ] || mv "$initrd" "$wd/initrd" ||
150- { error "failed to move extracted kernel to $wd/initrd"; return 1; }
151+ { error "failed to move extracted initrd to $wd/initrd"; return 1; }
152
153 rm -Rf "$exdir" || { error "failed to cleanup extract dir"; return 1; }
154 { [ -z "$rmtar" ] || rm "$rmtar"; } ||
155@@ -259,6 +297,7 @@
156 return 0
157 }
158
159+
160 write_tgt_conf() {
161 local file="$1" target_name="$2" image="$3"
162 shift 2;
163@@ -271,13 +310,20 @@
164 EOF
165 }
166
167+
168+if [ -z "$NO_COBBLER" ]
169+then
170 cobbler_has() {
171 local noun="$1" name="$2" out=""
172
173 out=$(cobbler "$noun" find "--name=$name" 2>/dev/null) &&
174 [ "$out" = "$name" ]
175 }
176-
177+fi
178+
179+
180+if [ -z "$NO_COBBLER" ]
181+then
182 cobbler_add_update() {
183 # cobbler_add_update(distro_name, profile_name,
184 # release, arch, kopts, kickstart,
185@@ -301,7 +347,11 @@
186
187 return 0
188 }
189-
190+fi
191+
192+
193+if [ -z "$NO_COBBLER" ]
194+then
195 replace() {
196 # replace(input, key1, value1, key2, value2, ...)
197 local input="$1" key="" val=""
198@@ -312,6 +362,30 @@
199 done
200 _RET=${input}
201 }
202+fi
203+
204+
205+install_tftp_image() {
206+ # Make image in directory $1, for architecture $2 and subarchitecture $3,
207+ # and OS release $4, available over TFTP for netbooting nodes. Only the
208+ # kernel and initrd are needed.
209+
210+ local src="$1" arch="$2" subarch="$3" release="$4" tmpdir=""
211+
212+ # Create image in a temporary directory; the installation process
213+ # deletes it.
214+ tmpdir="$(mktemp -d)"
215+
216+ for filename in kernel initrd
217+ do
218+ cp -- "$src/$filename" "$tmpdir/"
219+ done
220+
221+ maas install_pxe_image \
222+ --arch=$arch --subarch=$subarch --release=$release \
223+ --purpose="commissioning" --image="$tmpdir"
224+}
225+
226
227 short_opts="hciuv"
228 long_opts="help,import,update,update-check,verbose"
229@@ -346,6 +420,9 @@
230 [ ! -f "$CONFIG" ] || . "$CONFIG"
231 [ ! -f ".${CONFIG}" ] || . ".${CONFIG}"
232
233+
234+if [ -z "$NO_COBBLER" ]
235+then
236 # get default server ip
237 [ -n "$SERVER_IP" ] ||
238 _ip=$(awk '$1 == "server:" { print $2 }' /etc/cobbler/settings) ||
239@@ -354,12 +431,19 @@
240 SERVER_IP=${SERVER_IP:-${_ip}}
241 [ -n "${SERVER_IP}" ] &&
242 KOPTS="$KOPTS log_host=$SERVER_IP log_port=514"
243+fi
244+
245
246 ISCSI_TARGET_IP=${ISCSI_TARGET_IP:-${SERVER_IP}}
247 [ -n "$ISCSI_TARGET_IP" ] || fail "ISCSI_TARGET_IP must have a value"
248
249+
250+if [ -z "$NO_COBBLER" ]
251+then
252 [ -f "$KICKSTART" ] ||
253 fail "kickstart $KICKSTART is not a file"
254+fi
255+
256
257 mkdir -p "$DATA_DIR" "$DATA_DIR/.working" ||
258 fail "failed to make $DATA_DIR"
259@@ -410,6 +494,8 @@
260 "$r_serial" "$r_arch" "$r_url" "$r_name" ||
261 fail "failed to prepare image for $release/$arch"
262
263+ install_tftp_image "$wd" "$r_arch" "generic" "$r_release"
264+
265 target_name="${TARGET_NAME_PREFIX}${r_name}"
266
267 final_d="${r_release}/${r_stream}/${r_arch}/${r_serial}"
268@@ -448,6 +534,9 @@
269 fail "failed tgt-admin add for $name"
270 }
271
272+
273+if [ -z "$NO_COBBLER" ]
274+then
275 # cobbler_update
276 kopts_in="$EPH_CONSOLE_KOPTS $EPH_KOPTS_ISCSI $EPH_KOPTS_ROOT $EPH_KOPTS_LOGGING"
277 replace "${kopts_in}" \
278@@ -470,9 +559,13 @@
279 rm "${tgt_conf_d}/${name}.conf";
280 fail "failed to update cobbler for $profile/$distro"
281 }
282+fi
283+
284+
285 done
286 done
287
288+
289 if [ $check -eq 1 ]; then
290 # if --update-check, but no updates needed, exit 3
291 [ $updates_needed -eq 0 ] && exit 3
292@@ -480,7 +573,12 @@
293 exit 0
294 fi
295
296+
297+if [ -z "$NO_COBBLER" ]
298+then
299 cobbler sync
300+fi
301+
302
303 ## cleanup
304 # here, go through anything non-current,