diff options
23 files changed, 201 insertions, 104 deletions
diff --git a/clusters/moonshot-pxe-armv8l64.morph b/clusters/moonshot-pxe-armv8l64.morph new file mode 100644 index 00000000..3286c72e --- /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 00000000..11d01751 --- /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 Binary files differnew file mode 100644 index 00000000..d6fd83ee --- /dev/null +++ b/moonshot/boot/m400-1003.dtb diff --git a/moonshot/manifest b/moonshot/manifest new file mode 100644 index 00000000..dd80fe49 --- /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 e33da527..399914f5 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 58a86957..3aefe75e 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 702858de..63c4ff5b 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 120239b9..4eb92de4 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/strata/cross-bootstrap.morph b/strata/cross-bootstrap.morph index be4f4db8..3aa61caf 100644 --- a/strata/cross-bootstrap.morph +++ b/strata/cross-bootstrap.morph @@ -18,64 +18,11 @@ chunks: unpetrify-ref: baserock/morph build-depends: - groff -- name: python-ttystatus - morph: strata/cross-bootstrap/python-ttystatus.morph - repo: upstream:python-ttystatus - ref: 47d871216cea6ce3b9d6efd70e9a0f38ab8604f0 - unpetrify-ref: baserock/morph - build-depends: [] -- name: python-coveragepy - morph: strata/cross-bootstrap/python-coveragepy.morph - repo: upstream:python-coveragepy - ref: 77d2e3bfd8fb325092aaed37ba1378054d182d19 - unpetrify-ref: baserock/morph - build-depends: [] -- name: python-coverage-test-runner - repo: upstream:python-coverage-test-runner - ref: 8ea9421ac3384b2e88e0c36f2cfa52586c4798b7 - unpetrify-ref: baserock/morph - build-depends: - - python-coveragepy -- name: cliapp - repo: upstream:cliapp - ref: cec20cedd062a3aef1b04f997e77b45090c07806 - unpetrify-ref: baserock/morph - build-depends: - - python-coverage-test-runner -- name: python-markdown - repo: upstream:python-markdown - ref: a9ca97325e9039de90eae29fb3d8879bc9f367f6 - unpetrify-ref: baserock/morph - build-depends: [] -- name: cmdtest - morph: strata/cross-bootstrap/cmdtest.morph - repo: upstream:cmdtest - ref: ac91791842c6e7e6eda3213916af413255999c7b - unpetrify-ref: baserock/morph - build-depends: - - cliapp - - python-ttystatus - - python-markdown - name: linux-user-chroot repo: upstream:linux-user-chroot ref: d25cc110f69e6e71a95b4ac532dcfc5423d4a16b unpetrify-ref: baserock/morph build-depends: [] -- name: pyfilesystem - morph: strata/cross-bootstrap/pyfilesystem.morph - repo: upstream:pyfilesystem - ref: 821f7db1ce3a3e1ac53fa514ddacbc2871eac0f6 - unpetrify-ref: baserock/morph - build-depends: [] -- name: morph - repo: baserock:baserock/morph - ref: 954baf68b9bb7f8bc4fae2447ef16f37928ff01c - unpetrify-ref: master - build-depends: - - cliapp - - cmdtest - - python-coverage-test-runner - - pyfilesystem - name: rsync morph: strata/cross-bootstrap/rsync.morph repo: upstream:rsync diff --git a/strata/cross-bootstrap/cmdtest.morph b/strata/cross-bootstrap/cmdtest.morph deleted file mode 100644 index 3e1c71c6..00000000 --- a/strata/cross-bootstrap/cmdtest.morph +++ /dev/null @@ -1,6 +0,0 @@ -name: cmdtest -kind: chunk -build-commands: -- python setup.py build -install-commands: -- python setup.py install --prefix=/usr --root "$DESTDIR" diff --git a/strata/cross-bootstrap/pyfilesystem.morph b/strata/cross-bootstrap/pyfilesystem.morph deleted file mode 100644 index a4931dfa..00000000 --- a/strata/cross-bootstrap/pyfilesystem.morph +++ /dev/null @@ -1,6 +0,0 @@ -name: pyfilesystem -kind: chunk -build-commands: -- python setup.py build -install-commands: -- python setup.py install --prefix="$PREFIX" --root "$DESTDIR" diff --git a/strata/cross-bootstrap/python-coveragepy.morph b/strata/cross-bootstrap/python-coveragepy.morph deleted file mode 100644 index ed5e3d87..00000000 --- a/strata/cross-bootstrap/python-coveragepy.morph +++ /dev/null @@ -1,6 +0,0 @@ -name: python-coveragepy -kind: chunk -build-commands: -- python setup.py build -install-commands: -- python setup.py install --prefix=/usr --root "$DESTDIR" diff --git a/strata/cross-bootstrap/python-ttystatus.morph b/strata/cross-bootstrap/python-ttystatus.morph deleted file mode 100644 index e45ef7a8..00000000 --- a/strata/cross-bootstrap/python-ttystatus.morph +++ /dev/null @@ -1,6 +0,0 @@ -name: python-ttystatus -kind: chunk -build-commands: -- python setup.py build -install-commands: -- python setup.py install --prefix=/usr --root "$DESTDIR" diff --git a/strata/databases/memcached.morph b/strata/databases/memcached.morph index 28e01362..5d55b727 100644 --- a/strata/databases/memcached.morph +++ b/strata/databases/memcached.morph @@ -6,3 +6,16 @@ configure-commands: - touch README - autoreconf -fvi - ./configure --prefix="$PREFIX" +install-commands: +- make install +- install -D -m 755 scripts/memcached.service "$DESTDIR"/etc/systemd/system/memcached.service +post-install-commands: +- mkdir -p "$DESTDIR"/etc/sysconfig +- | + cat <<EOF > "$DESTDIR"/etc/sysconfig/memcached + PORT="11211" + USER="nobody" + MAXCONN="1024" + CACHESIZE="64" + OPTIONS="" + EOF diff --git a/strata/python-common.morph b/strata/python-common.morph index 5536e13c..e2f4b32a 100644 --- a/strata/python-common.morph +++ b/strata/python-common.morph @@ -5,7 +5,7 @@ build-depends: - morph: strata/python-core.morph chunks: - name: pycrypto - morph: strata/openstack-services/pycrypto.morph + morph: strata/python-common/pycrypto.morph repo: upstream:python-packages/pycrypto ref: af058ee6f5da391a05275470ab4a4a96aa22b350 unpetrify-ref: v2.7a1 diff --git a/strata/python-common/pycrypto.morph b/strata/python-common/pycrypto.morph new file mode 100644 index 00000000..51cc00f0 --- /dev/null +++ b/strata/python-common/pycrypto.morph @@ -0,0 +1,3 @@ +name: pycrypto +kind: chunk +build-system: python-distutils diff --git a/strata/tools/rsync.morph b/strata/tools/rsync.morph index 9a92878d..7b99bdd9 100644 --- a/strata/tools/rsync.morph +++ b/strata/tools/rsync.morph @@ -4,3 +4,6 @@ build-system: autotools build-commands: - make proto - make +install-commands: +- make install +- install -D -m 755 packaging/systemd/rsync.service "$DESTDIR"/etc/systemd/system/rsync.service diff --git a/systems/build-system-armv8l64.morph b/systems/build-system-armv8l64.morph index 7715ecb7..2fcb1e8c 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/cross-bootstrap-system-armv7lhf-generic.morph b/systems/cross-bootstrap-system-armv7lhf-generic.morph index 4eecf7fe..23817c0c 100644 --- a/systems/cross-bootstrap-system-armv7lhf-generic.morph +++ b/systems/cross-bootstrap-system-armv7lhf-generic.morph @@ -7,5 +7,7 @@ strata: morph: strata/build-essential.morph - name: core morph: strata/core.morph +- name: morph-utils + morph: strata/morph-utils.morph - name: cross-bootstrap morph: strata/cross-bootstrap.morph diff --git a/systems/cross-bootstrap-system-armv8l64-generic.morph b/systems/cross-bootstrap-system-armv8l64-generic.morph index 30094e74..c35cff5f 100644 --- a/systems/cross-bootstrap-system-armv8l64-generic.morph +++ b/systems/cross-bootstrap-system-armv8l64-generic.morph @@ -7,5 +7,7 @@ strata: morph: strata/build-essential.morph - name: core morph: strata/core.morph +- name: morph-utils + morph: strata/morph-utils.morph - name: cross-bootstrap morph: strata/cross-bootstrap.morph diff --git a/systems/cross-bootstrap-system-ppc64-generic.morph b/systems/cross-bootstrap-system-ppc64-generic.morph index 8b274e80..40c80c00 100644 --- a/systems/cross-bootstrap-system-ppc64-generic.morph +++ b/systems/cross-bootstrap-system-ppc64-generic.morph @@ -7,5 +7,7 @@ strata: morph: strata/build-essential.morph - name: core morph: strata/core.morph +- name: morph-utils + morph: strata/morph-utils.morph - name: cross-bootstrap morph: strata/cross-bootstrap.morph diff --git a/systems/cross-bootstrap-system-x86_64-generic.morph b/systems/cross-bootstrap-system-x86_64-generic.morph index bdd42cf3..646a04d3 100644 --- a/systems/cross-bootstrap-system-x86_64-generic.morph +++ b/systems/cross-bootstrap-system-x86_64-generic.morph @@ -7,5 +7,7 @@ strata: morph: strata/build-essential.morph - name: core morph: strata/core.morph +- name: morph-utils + morph: strata/morph-utils.morph - name: cross-bootstrap morph: strata/cross-bootstrap.morph diff --git a/systems/devel-system-armv8l64.morph b/systems/devel-system-armv8l64.morph index 27080535..88495e48 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 |