summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Gomes <tiago.gomes@codethink.co.uk>2015-02-27 17:29:00 (GMT)
committerTiago Gomes <tiago.gomes@codethink.co.uk>2015-02-27 17:29:00 (GMT)
commitee7fcd2983476765ce39bcba4b053db990e723b3 (patch)
treea07dd9b3e1116eb066fb1a297436a906c48dcb87
parent38cf9f0c79096574b3c8b7c31c8dd5397e714634 (diff)
parent709c416d5891adac91c3d41af6812409abc9b2b1 (diff)
downloaddefinitions-ee7fcd2983476765ce39bcba4b053db990e723b3.tar.gz
Merge branch 'baserock/tiagogomes/moonshot-deployment'
Reviewed by: * Richard Maw <richard.maw@codethink.co.uk> * Sam Thursfield <sam.thursfield@codethink.co.uk>
-rw-r--r--clusters/moonshot-pxe-armv8l64.morph22
-rw-r--r--moonshot-kernel.configure33
-rw-r--r--moonshot/boot/m400-1003.dtbbin0 -> 18063 bytes
-rw-r--r--moonshot/manifest2
-rwxr-xr-xpxeboot.write102
-rw-r--r--pxeboot.write.help31
-rw-r--r--strata/bsp-armv8l64-generic.morph2
-rw-r--r--strata/bsp-armv8l64-generic/linux-armv8l64-generic.morph (renamed from strata/bsp-armv8l64-generic/bsp-armv8l64-generic.morph)1
-rw-r--r--systems/build-system-armv8l64.morph3
-rw-r--r--systems/devel-system-armv8l64.morph3
10 files changed, 173 insertions, 26 deletions
diff --git a/clusters/moonshot-pxe-armv8l64.morph b/clusters/moonshot-pxe-armv8l64.morph
new file mode 100644
index 0000000..3286c72
--- /dev/null
+++ b/clusters/moonshot-pxe-armv8l64.morph
@@ -0,0 +1,22 @@
+name: moonshot-m400-armv8l64-netboot
+kind: cluster
+description: |
+ Deploy an armv8l64 devel system into a HP Moonshot node
+
+ The system will be configured to boot through PXE from existing DHCP,
+ TFTP and NFS servers.
+systems:
+- morph: systems/devel-system-armv8l64.morph
+ deploy:
+ netboot:
+ type: pxeboot
+ location: 14:58:d0:57:7f:42
+ PXEBOOT_MODE: existing-server
+ PXEBOOT_CONFIG_TFTP_ADDRESS: sftp://192.168.0.1/srv/nfsboot/tftp/
+ PXEBOOT_ROOTFS_RSYNC_ADDRESS: rsync://192.168.0.1/srv/nfsboot/
+ KERNEL_ARGS: console=ttyS0,9600n8r rw
+ DTB_PATH: boot/m400-1003.dtb
+ HOSTNAME: baserock-m400-node31
+ MOONSHOT_KERNEL: yes
+ INSTALL_FILES: moonshot/manifest
+ PXE_INSTALLER: no
diff --git a/moonshot-kernel.configure b/moonshot-kernel.configure
new file mode 100644
index 0000000..11d0175
--- /dev/null
+++ b/moonshot-kernel.configure
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Copyright (C) 2014 Codethink Limited
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# This is a "morph deploy" configuration extension to convert a plain
+# kernel Image to uImage, for an HP Moonshot m400 cartridge
+
+set -eu
+
+case "$MOONSHOT_KERNEL" in
+ True|yes)
+ echo "Converting kernel image for Moonshot"
+ mkimage -A arm -O linux -C none -T kernel -a 0x00080000 \
+ -e 0x00080000 -n Linux -d "$1/boot/vmlinux" "$1/boot/uImage"
+ ;;
+ *)
+ echo Unrecognised option "$MOONSHOT_KERNEL" to MOONSHOT_KERNEL
+ exit 1
+ ;;
+esac
diff --git a/moonshot/boot/m400-1003.dtb b/moonshot/boot/m400-1003.dtb
new file mode 100644
index 0000000..d6fd83e
--- /dev/null
+++ b/moonshot/boot/m400-1003.dtb
Binary files differ
diff --git a/moonshot/manifest b/moonshot/manifest
new file mode 100644
index 0000000..dd80fe4
--- /dev/null
+++ b/moonshot/manifest
@@ -0,0 +1,2 @@
+0040755 0 0 /boot
+0100744 0 0 /boot/m400-1003.dtb
diff --git a/pxeboot.write b/pxeboot.write
index e33da52..399914f 100755
--- a/pxeboot.write
+++ b/pxeboot.write
@@ -223,11 +223,13 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
@contextlib.contextmanager
def _remote_tempdir(self, hostname, template):
+ persist = os.environ.get('PXE_INSTALLER') in ('no', 'False')
td = cliapp.ssh_runcmd(hostname, ['mktemp', '-d', template]).strip()
try:
yield td
finally:
- cliapp.ssh_runcmd(hostname, ['find', td, '-delete'])
+ if not persist:
+ cliapp.ssh_runcmd(hostname, ['find', td, '-delete'])
def _serve_tftpd(self, sock, host, port, interface, tftproot):
self.settings.progname = 'tftp server'
@@ -321,6 +323,7 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
@contextlib.contextmanager
def _remote_copy(self, hostname, src, dst):
+ persist = os.environ.get('PXE_INSTALLER') in ('no', 'False')
with open(src, 'r') as f:
cliapp.ssh_runcmd(hostname,
['install', '-D', '-m644', '/proc/self/fd/0',
@@ -328,7 +331,20 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
try:
yield
finally:
- cliapp.ssh_runcmd(hostname, ['rm', dst])
+ if not persist:
+ cliapp.ssh_runcmd(hostname, ['rm', dst])
+
+ @contextlib.contextmanager
+ def _remote_symlink(self, hostname, src, dst):
+ persist = os.environ.get('PXE_INSTALLER') in ('no', 'False')
+ cliapp.ssh_runcmd(hostname,
+ ['ln', '-s', '-f', src, dst],
+ stdin=None, stdout=None, stderr=None)
+ try:
+ yield
+ finally:
+ if not persist:
+ cliapp.ssh_runcmd(hostname, ['rm', '-f', dst])
@contextlib.contextmanager
def remote_kernel(self, rootfs, tftp_url, macaddr):
@@ -346,6 +362,21 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
yield basename
@contextlib.contextmanager
+ def remote_fdt(self, rootfs, tftp_url, macaddr):
+ fdt_rel_path = os.environ.get('DTB_PATH', '')
+ if fdt_rel_path == '':
+ yield
+ fdt_abs_path = os.path.join(rootfs, fdt_rel_path)
+ if not fdt_abs_path:
+ raise cliapp.AppException('Failed to locate Flattened Device Tree')
+ url = urlparse.urlsplit(tftp_url)
+ basename = '{}-fdt'.format(_normalise_macaddr(macaddr))
+ target_path = os.path.join(url.path, basename)
+ with self._remote_copy(hostname=url.hostname, src=fdt_abs_path,
+ dst=target_path):
+ yield basename
+
+ @contextlib.contextmanager
def local_nfsroot(self, rootfs, target_ip):
nfsroot = target_ip + ':' + rootfs
self.status(msg='Exporting %(nfsroot)s as local nfsroot',
@@ -362,17 +393,21 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
@contextlib.contextmanager
def remote_nfsroot(self, rootfs, rsync_url, macaddr):
url = urlparse.urlsplit(rsync_url)
- template = os.path.join(url.path, 'nfsroot.XXXXXXXXXX')
+ template = os.path.join(url.path,
+ _normalise_macaddr(macaddr) + '.XXXXXXXXXX')
with self._remote_tempdir(hostname=url.hostname, template=template) \
as tempdir:
- nfsroot = urlparse.urlunsplit(url.scheme, url.netloc, tempdir,
- url.query, url.fragment)
- cliapp.runcmd(['rsync', '-asXSPH', '--delete', rootfs, nfsroot],
- stdin=None, stdout=None, stderr=None)
- yield basename
+ nfsroot = urlparse.urlunsplit((url.scheme, url.netloc, tempdir,
+ url.query, url.fragment))
+ cliapp.runcmd(['rsync', '-asSPH', '--delete', rootfs, nfsroot],
+ stdin=None, stdout=open(os.devnull, 'w'),
+ stderr=None)
+ yield os.path.join(os.path.basename(tempdir),
+ os.path.basename(rootfs))
@staticmethod
- def _write_pxe_config(fh, kernel_tftp_url, rootfs_nfs_url, extra_args=''):
+ def _write_pxe_config(fh, kernel_tftp_url, rootfs_nfs_url,
+ fdt_subpath=None, extra_args=''):
fh.write(textwrap.dedent('''\
DEFAULT default
LABEL default
@@ -380,6 +415,8 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
APPEND root=/dev/nfs ip=dhcp nfsroot={rootfs_nfs_url} {extra_args}
''').format(kernel_url=kernel_tftp_url,
rootfs_nfs_url=rootfs_nfs_url, extra_args=extra_args))
+ if fdt_subpath is not None:
+ fh.write("FDT {}\n".format(fdt_subpath))
fh.flush()
@contextlib.contextmanager
@@ -401,19 +438,29 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
@contextlib.contextmanager
def remote_pxeboot_config(self, tftproot, kernel_tftproot, kernel_subpath,
- rootfs_nfsroot, rootfs_subpath, macaddr):
- rootfs_nfs_url = '{}:{}/{}'.format(ip, rootfs_nfsroot, rootfs_subpath)
- kernel_tftp_url = '{}/{}'.format(kernel_tftproot, kernel_subpath)
+ fdt_subpath, rootfs_nfsroot, rootfs_subpath,
+ macaddr):
+ rootfs_nfs_url = '{}/{}'.format(rootfs_nfsroot, rootfs_subpath)
+ url = urlparse.urlsplit(kernel_tftproot)
+ kernel_tftp_url = '{}:{}'.format(url.netloc, kernel_subpath)
pxe_cfg_filename = _normalise_macaddr(macaddr)
url = urlparse.urlsplit(tftproot)
- inst_cfg_path = os.path.join(url.path, 'pxelinux.cfg',
- pxe_cfg_filename)
+ inst_cfg_path = os.path.join(url.path, 'pxelinux.cfg')
with tempfile.NamedTemporaryFile() as f:
- self._write_pxe_config(fh=f, kernel_tftp_url=kernel_tftp_url,
- rootfs_nfs_url=rootfs_nfs_url,
- extra_args=os.environ.get('KERNEL_ARGS',''))
- with self._remote_copy(hostname=url.hostname, src=f.name,
- dst=inst_cfg_path):
+ self._write_pxe_config(
+ fh=f, kernel_tftp_url=kernel_tftp_url,
+ fdt_subpath=fdt_subpath,
+ rootfs_nfs_url=rootfs_nfs_url,
+ extra_args=os.environ.get('KERNEL_ARGS',''))
+ with self._remote_copy(
+ hostname=url.hostname, src=f.name,
+ dst=os.path.join(inst_cfg_path,
+ pxe_cfg_filename)), \
+ self._remote_symlink(
+ hostname=url.hostname,
+ src=pxe_cfg_filename,
+ dst=os.path.join(inst_cfg_path,
+ '01-' + pxe_cfg_filename)):
yield
@contextlib.contextmanager
@@ -660,19 +707,24 @@ class PXEBoot(morphlib.writeexts.WriteExtension):
url = urlparse.urlsplit(rootfs_rsync)
nfsroot = os.environ.get('PXEBOOT_ROOTFS_NFSROOT',
'%s:%s' % (url.hostname, url.path))
- with self.remote_kernel(rootfs=temp_root, url=kernel_tftpaddr,
+ with self.remote_kernel(rootfs=temp_root, tftp_url=kernel_tftpaddr,
macaddr=macaddr) as kernel_subpath, \
- self.remote_nfsroot(rootfs=temp_root, rsync_url=rootfs_rsync)\
- as rootfs_subpath, \
+ self.remote_fdt(rootfs=temp_root, tftp_url=kernel_tftpaddr,
+ macaddr=macaddr) as fdt_subpath, \
+ self.remote_nfsroot(rootfs=temp_root, rsync_url=rootfs_rsync, \
+ macaddr=macaddr) as rootfs_subpath, \
self.remote_pxeboot_config(tftproot=config_tftpaddr,
kernel_tftproot=kernel_tftproot,
kernel_subpath=kernel_subpath,
+ fdt_subpath=fdt_subpath,
rootfs_nfsroot=nfsroot,
rootfs_subpath=rootfs_subpath,
macaddr=macaddr):
- self.ipmi_pxe_reboot_target()
- self.wait_for_target_to_install()
- self.ipmi_reboot_target()
+ persist = os.environ.get('PXE_INSTALLER') in ('no', 'False')
+ if not persist:
+ self.ipmi_pxe_reboot_target()
+ self.wait_for_target_to_install()
+ self.ipmi_reboot_target()
else:
cliapp.AppException('Invalid PXEBOOT_MODE: %s' % mode)
diff --git a/pxeboot.write.help b/pxeboot.write.help
index 58a8695..3aefe75 100644
--- a/pxeboot.write.help
+++ b/pxeboot.write.help
@@ -121,3 +121,34 @@ help: >
If it is possible for the target to notify you that it has finished
installing, you can put a command in here to wait for the event.
+
+
+ # Misc
+
+
+ ## KERNEL_ARGS
+
+
+ Additional kernel command line options. Note that the following
+ options
+
+ root=/dev/nfs ip=dhcp nfsroot=$NFSROOT`
+
+ are implicitly added by the extension.
+
+
+ ## DTB_PATH
+
+
+ Location in the deployed root filesystem of the Flattened Device
+ Tree blob (FDT) to use.
+
+
+ ## PXE_INSTALLER
+
+
+ If set to `no`, `False` or any other YAML value for false, the
+ remotely installed rootfs, kernel, bootloader config file and
+ device tree blob if specified, will not be removed after the
+ deployment finishes. This variable is only meanful on the
+ `existing-server` mode.
diff --git a/strata/bsp-armv8l64-generic.morph b/strata/bsp-armv8l64-generic.morph
index 702858d..63c4ff5 100644
--- a/strata/bsp-armv8l64-generic.morph
+++ b/strata/bsp-armv8l64-generic.morph
@@ -9,7 +9,7 @@ build-depends:
- morph: strata/core.morph
chunks:
- name: linux-armv8l64-generic
- morph: strata/bsp-armv8l64-generic/bsp-armv8l64-generic.morph
+ morph: strata/bsp-armv8l64-generic/linux-armv8l64-generic.morph
repo: upstream:linux
ref: 5f06398ae6a04f414932243de38b5cf3d264ff84
unpetrify-ref: baserock/apm-xgene-m400-moonshot-cartridge
diff --git a/strata/bsp-armv8l64-generic/bsp-armv8l64-generic.morph b/strata/bsp-armv8l64-generic/linux-armv8l64-generic.morph
index 120239b..4eb92de 100644
--- a/strata/bsp-armv8l64-generic/bsp-armv8l64-generic.morph
+++ b/strata/bsp-armv8l64-generic/linux-armv8l64-generic.morph
@@ -102,3 +102,4 @@ build-commands:
install-commands:
- mkdir -p "$DESTDIR"/boot
- make install dtbs_install INSTALL_PATH="$DESTDIR/boot"
+- cp arch/arm64/boot/Image "$DESTDIR/boot/vmlinux"
diff --git a/systems/build-system-armv8l64.morph b/systems/build-system-armv8l64.morph
index 7715ecb..2fcb1e8 100644
--- a/systems/build-system-armv8l64.morph
+++ b/systems/build-system-armv8l64.morph
@@ -12,6 +12,8 @@ strata:
morph: strata/core.morph
- name: foundation
morph: strata/foundation.morph
+- name: python-core
+ morph: strata/python-core.morph
- name: bsp-armv8l64-generic
morph: strata/bsp-armv8l64-generic.morph
- name: tools
@@ -39,3 +41,4 @@ configuration-extensions:
- fstab
- mason
- cloud-init
+- moonshot-kernel
diff --git a/systems/devel-system-armv8l64.morph b/systems/devel-system-armv8l64.morph
index 2708053..88495e4 100644
--- a/systems/devel-system-armv8l64.morph
+++ b/systems/devel-system-armv8l64.morph
@@ -30,6 +30,8 @@ strata:
morph: strata/baserock-import.morph
- name: nfs
morph: strata/nfs.morph
+- name: python-core
+ morph: strata/python-core.morph
- name: python-tools
morph: strata/python-tools.morph
- name: devtools
@@ -41,3 +43,4 @@ configuration-extensions:
- nfsboot
- install-files
- cloud-init
+- moonshot-kernel