← Back to team overview

launchpad-reviewers team mailing list archive

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

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/import-ephemerals-tftp into lp:maas.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jtv/maas/import-ephemerals-tftp/+merge/112353

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
-- 
https://code.launchpad.net/~jtv/maas/import-ephemerals-tftp/+merge/112353
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/import-ephemerals-tftp into lp:maas.
=== modified file 'etc/celeryconfig.py'
--- etc/celeryconfig.py	2012-06-26 04:22:16 +0000
+++ etc/celeryconfig.py	2012-06-27 13:15:35 +0000
@@ -30,7 +30,7 @@
     "templates")
 
 # TFTP server's root directory.
-TFTPROOT = "/var/lib/tftp"
+TFTPROOT = "/var/lib/tftpboot"
 
 
 try:

=== modified file 'scripts/maas-import-ephemerals'
--- scripts/maas-import-ephemerals	2012-04-18 21:38:17 +0000
+++ scripts/maas-import-ephemerals	2012-06-27 13:15:35 +0000
@@ -19,24 +19,44 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+# Cobbler is being removed from MAAS.  Set NO_COBBLER to skip anything
+# in this script that is related to Cobbler.
+NO_COBBLER=${NO_COBBLER:-}
+
 VERBOSITY=0
 REMOTE_IMAGES_MIRROR="https://maas.ubuntu.com/images";
+
+if [ -z "$NO_COBBLER" ]
+then
 CONSOLE="ttyS0,9600n8"
 EPH_KOPTS_CONSOLE="console=$CONSOLE"
 EPH_KOPTS_ISCSI="ip=dhcp iscsi_target_name=@@iscsi_target@@ iscsi_target_ip=@@iscsi_target_ip@@ iscsi_target_port=3260"
 EPH_KOPTS_ROOT="root=LABEL=cloudimg-rootfs ro"
 EPH_KOPTS_LOGGING="log_host=@@server_ip@@ log_port=514"
+KSDIR="/var/lib/cobbler/kickstarts"
+KICKSTART="$KSDIR/maas-commissioning.preseed"
+SYS_TGT_CONF="/etc/tgt/targets.conf"
+fi
+
+# TODO: What's this for?  If set, it gets run on a downloaded disk.img,
+# kernel, and initrd.
 EPH_UPDATE_CMD=""
+
+# Prefix for iSCSI target name.
 TARGET_NAME_PREFIX="iqn.2004-05.com.ubuntu:maas:"
+
+# TODO: DATA_DIR seems to be the root of a directory tree that's exposed over
+# iSCSI for download by nodes.  Can we confirm this?
 DATA_DIR="/var/lib/maas/ephemeral"
+
+# Optional configuration script that may set variables for use by this
+# script.  It gets sourced later on.
 CONFIG="/etc/maas/import_ephemerals"
+
 RELEASES="precise"
 ARCHES="amd64 i386"
 BUILD_NAME="ephemeral"
 STREAM="released"
-KSDIR="/var/lib/cobbler/kickstarts"
-KICKSTART="$KSDIR/maas-commissioning.preseed"
-SYS_TGT_CONF="/etc/tgt/targets.conf"
 
 # DATA_DIR layout is like:
 #   tgt.conf
@@ -57,6 +77,7 @@
 fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
 failp() { [ $# -eq 0 ] || errorp "$@"; exit 1; }
 
+
 Usage() {
 	cat <<EOF
 Usage: ${0##*/} [ options ] <<ARGUMENTS>>
@@ -73,32 +94,45 @@
 EOF
 }
 
+
 bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
+
+
 cleanup() {
 	[ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
 }
 
+
 debug() {
 	local level=${1}; shift;
 	[ "${level}" -gt "${VERBOSITY}" ] && return
 	error "${@}"
 }
+
+
 arch2u() {
-	# arch2ubuntu
+	# Normalize architecture name to an Ubuntu architecture name.
 	_RET=$1
 	case "$1" in
 		i?86) _RET=i386;;
 		x86_64) _RET=amd64;;
 	esac
 }
+
+
+if [ -z "$NO_COBBLER" ]
+then
 arch2cob() {
-	# arch 2 cobbler arch
+	# Normalize an architecture name for use in Cobbler.
 	_RET=$1
 	case "$1" in
 		i?86) _RET=i386;;
 		amd64) _RET=x86_64;;
 	esac
 }
+fi
+
+
 query_remote() {
 	# query /query data at REMOTE_IMAGES_MIRROR
 	# returns 7 values prefixed with 'r_'
@@ -131,6 +165,7 @@
 	return
 }
 
+
 query_local() {
 	local iarch=$1 irelease=$2 istream=$3 out=""
 	local label="" name="" serial="" url=""
@@ -159,6 +194,8 @@
 		l_dir="${found%/*}";
 	fi
 }
+
+
 serial_gt() {
 	# is $1 a larger serial than $2 ?
 	local a=${1:-0} b=${2:-0}
@@ -171,6 +208,7 @@
 	[ $a -gt $b ]
 }
 
+
 prep_dir() {
 	local wd="$1" exdir="" tarball=""
 	shift
@@ -238,7 +276,7 @@
 		{ error "failed to move extracted kernel to $wd/kernel"; return 1; }
 
 	[ -z "$initrd" ] || mv "$initrd" "$wd/initrd" ||
-		{ error "failed to move extracted kernel to $wd/initrd"; return 1; }
+		{ error "failed to move extracted initrd to $wd/initrd"; return 1; }
 
 	rm -Rf "$exdir" || { error "failed to cleanup extract dir"; return 1; }
 	{ [ -z "$rmtar" ] || rm "$rmtar"; } ||
@@ -259,6 +297,7 @@
 	return 0
 }
 
+
 write_tgt_conf() {
 	local file="$1" target_name="$2" image="$3"
 	shift 2;
@@ -271,13 +310,20 @@
 EOF
 }
 
+
+if [ -z "$NO_COBBLER" ]
+then
 cobbler_has() {
 	local noun="$1" name="$2" out=""
 
 	out=$(cobbler "$noun" find "--name=$name" 2>/dev/null) &&
 		[ "$out" = "$name" ]
 }
-
+fi
+
+
+if [ -z "$NO_COBBLER" ]
+then
 cobbler_add_update() {
 	# cobbler_add_update(distro_name, profile_name, 
 	#					 release, arch, kopts, kickstart,
@@ -301,7 +347,11 @@
 
 	return 0
 }
-
+fi
+
+
+if [ -z "$NO_COBBLER" ]
+then
 replace() {
 	# replace(input, key1, value1, key2, value2, ...)
 	local input="$1" key="" val=""
@@ -312,6 +362,30 @@
 	done
 	_RET=${input}
 }
+fi
+
+
+install_tftp_image() {
+    # Make image in directory $1, for architecture $2 and subarchitecture $3,
+    # and OS release $4, available over TFTP for netbooting nodes.  Only the
+    # kernel and initrd are needed.
+
+    local src="$1" arch="$2" subarch="$3" release="$4" tmpdir=""
+
+    # Create image in a temporary directory; the installation process
+    # deletes it.
+    tmpdir="$(mktemp -d)"
+
+    for filename in kernel initrd
+    do
+        cp -- "$src/$filename" "$tmpdir/"
+    done
+
+    maas install_pxe_image \
+        --arch=$arch --subarch=$2 --release=$release \
+        --purpose="commissioning" --image="$tmpdir"
+}
+
 
 short_opts="hciuv"
 long_opts="help,import,update,update-check,verbose"
@@ -346,6 +420,9 @@
 [ ! -f "$CONFIG" ] || . "$CONFIG"
 [ ! -f ".${CONFIG}" ] || . ".${CONFIG}"
 
+
+if [ -z "$NO_COBBLER" ]
+then
 # get default server ip
 [ -n "$SERVER_IP" ] ||
 	_ip=$(awk '$1 == "server:" { print $2 }' /etc/cobbler/settings) ||
@@ -354,12 +431,19 @@
 SERVER_IP=${SERVER_IP:-${_ip}}
 [ -n "${SERVER_IP}" ] &&
 	KOPTS="$KOPTS log_host=$SERVER_IP log_port=514"
+fi
+
 
 ISCSI_TARGET_IP=${ISCSI_TARGET_IP:-${SERVER_IP}}
 [ -n "$ISCSI_TARGET_IP" ] || fail "ISCSI_TARGET_IP must have a value"
 
+
+if [ -z "$NO_COBBLER" ]
+then
 [ -f "$KICKSTART" ] ||
 	fail "kickstart $KICKSTART is not a file"
+fi
+
 
 mkdir -p "$DATA_DIR" "$DATA_DIR/.working" ||
 	fail "failed to make $DATA_DIR"
@@ -410,6 +494,8 @@
 				"$r_serial" "$r_arch" "$r_url" "$r_name" ||
 				fail "failed to prepare image for $release/$arch"
 
+            install_tftp_image "$wd" "$r_arch" "generic" "$r_release"
+
 			target_name="${TARGET_NAME_PREFIX}${r_name}"
 
 			final_d="${r_release}/${r_stream}/${r_arch}/${r_serial}"
@@ -448,6 +534,9 @@
 			fail "failed tgt-admin add for $name"
 		}
 
+
+if [ -z "$NO_COBBLER" ]
+then
 		# cobbler_update
 		kopts_in="$EPH_CONSOLE_KOPTS $EPH_KOPTS_ISCSI $EPH_KOPTS_ROOT $EPH_KOPTS_LOGGING"
 		replace "${kopts_in}" \
@@ -470,9 +559,13 @@
 				rm "${tgt_conf_d}/${name}.conf";
 				fail "failed to update cobbler for $profile/$distro"
 			}
+fi
+
+
 	done
 done
 
+
 if [ $check -eq 1 ]; then
 	# if --update-check, but no updates needed, exit 3
 	[ $updates_needed -eq 0 ] && exit 3
@@ -480,7 +573,12 @@
 	exit 0
 fi
 
+
+if [ -z "$NO_COBBLER" ]
+then
 cobbler sync
+fi
+
 
 ## cleanup
 # here, go through anything non-current,