From 0be3bf370864a81cad36ec1947c85175456858cc Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 14:58:35 +0000 Subject: [PATCH 01/22] New boot.d early init sequence. There is a new init sequence that is executed prior to all concurrent init.d services. Placing ordered services in /etc/boot.d allows you to interpose upgrade, verification, and special handling prior to execution of the normal SYSV init. This system can be accessed by placing ordered scripts directly in /etc/boot.d from your package. This infra is used to perform early loader and partition upgrade checks, onie upgrades, cpld upgrades, and the like. Normal filesystem mounts are performed at priority 50. Platform initialization is performated at priority 51. TODO: Integrate upgrade sequence. --- .../rootfs/jessie/common/overlay/etc/inittab | 67 +++++++++++++++++++ .../any/rootfs/jessie/standard/standard.yml | 2 - .../rootfs/wheezy/common/overlay/etc/inittab | 67 +++++++++++++++++++ .../any/rootfs/wheezy/standard/standard.yml | 2 - packages/base/all/boot.d/Makefile | 1 + packages/base/all/boot.d/PKG.yml | 16 +++++ .../base/all/boot.d/src/50.initdev | 9 --- packages/base/all/boot.d/src/boot | 19 ++++++ packages/base/all/vendor-config-onl/PKG.yml | 4 +- .../51.onl-platform-baseconf} | 0 .../src/boot.d/onl-platform-baseconf | 17 +++++ 11 files changed, 189 insertions(+), 15 deletions(-) create mode 100644 builds/any/rootfs/jessie/common/overlay/etc/inittab create mode 100644 builds/any/rootfs/wheezy/common/overlay/etc/inittab create mode 100644 packages/base/all/boot.d/Makefile create mode 100644 packages/base/all/boot.d/PKG.yml rename builds/any/rootfs/wheezy/common/overlay/etc/init.d/initdev => packages/base/all/boot.d/src/50.initdev (68%) create mode 100755 packages/base/all/boot.d/src/boot rename packages/base/all/vendor-config-onl/src/{init.d/onl-platform-baseconf => boot.d/51.onl-platform-baseconf} (100%) create mode 100755 packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf diff --git a/builds/any/rootfs/jessie/common/overlay/etc/inittab b/builds/any/rootfs/jessie/common/overlay/etc/inittab new file mode 100644 index 00000000..e242bf0a --- /dev/null +++ b/builds/any/rootfs/jessie/common/overlay/etc/inittab @@ -0,0 +1,67 @@ +# The default runlevel. +id:2:initdefault: + +# Boot-time system configuration/initialization script. +# This is run first except when booting in emergency (-b) mode. +si0::sysinit:/etc/boot.d/boot +si1::sysinit:/etc/init.d/rcS + +# What to do in single-user mode. +~~:S:wait:/sbin/sulogin + +# /etc/init.d executes the S and K scripts upon change +# of runlevel. +# +# Runlevel 0 is halt. +# Runlevel 1 is single-user. +# Runlevels 2-5 are multi-user. +# Runlevel 6 is reboot. + +l0:0:wait:/etc/init.d/rc 0 +l1:1:wait:/etc/init.d/rc 1 +l2:2:wait:/etc/init.d/rc 2 +l3:3:wait:/etc/init.d/rc 3 +l4:4:wait:/etc/init.d/rc 4 +l5:5:wait:/etc/init.d/rc 5 +l6:6:wait:/etc/init.d/rc 6 +# Normally not reached, but fallthrough in case of emergency. +z6:6:respawn:/sbin/sulogin + +# What to do when CTRL-ALT-DEL is pressed. +ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now + +# Action on special keypress (ALT-UpArrow). +#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work." + +# What to do when the power fails/returns. +pf::powerwait:/etc/init.d/powerfail start +pn::powerfailnow:/etc/init.d/powerfail now +po::powerokwait:/etc/init.d/powerfail stop + +# /sbin/getty invocations for the runlevels. +# +# The "id" field MUST be the same as the last +# characters of the device (after "tty"). +# +# Format: +# ::: +# +# Note that on most Debian systems tty7 is used by the X Window System, +# so if you want to add more getty's go ahead but skip tty7 if you run X. +# +1:2345:respawn:/sbin/getty 38400 tty1 +2:23:respawn:/sbin/getty 38400 tty2 +3:23:respawn:/sbin/getty 38400 tty3 +4:23:respawn:/sbin/getty 38400 tty4 +5:23:respawn:/sbin/getty 38400 tty5 +6:23:respawn:/sbin/getty 38400 tty6 + +# Example how to put a getty on a serial line (for a terminal) +# +#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100 +#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100 + +# Example how to put a getty on a modem line. +# +#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3 + diff --git a/builds/any/rootfs/jessie/standard/standard.yml b/builds/any/rootfs/jessie/standard/standard.yml index 785a2638..49775888 100644 --- a/builds/any/rootfs/jessie/standard/standard.yml +++ b/builds/any/rootfs/jessie/standard/standard.yml @@ -55,8 +55,6 @@ Configure: - ${ONL}/builds/any/rootfs/${ONL_DEBIAN_SUITE}/common/overlay update-rc.d: - - 'initdev defaults' - - 'onl-platform-baseconf defaults' - 'faultd defaults' - 'onlpd defaults' - 'snmpd remove' diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/inittab b/builds/any/rootfs/wheezy/common/overlay/etc/inittab new file mode 100644 index 00000000..e242bf0a --- /dev/null +++ b/builds/any/rootfs/wheezy/common/overlay/etc/inittab @@ -0,0 +1,67 @@ +# The default runlevel. +id:2:initdefault: + +# Boot-time system configuration/initialization script. +# This is run first except when booting in emergency (-b) mode. +si0::sysinit:/etc/boot.d/boot +si1::sysinit:/etc/init.d/rcS + +# What to do in single-user mode. +~~:S:wait:/sbin/sulogin + +# /etc/init.d executes the S and K scripts upon change +# of runlevel. +# +# Runlevel 0 is halt. +# Runlevel 1 is single-user. +# Runlevels 2-5 are multi-user. +# Runlevel 6 is reboot. + +l0:0:wait:/etc/init.d/rc 0 +l1:1:wait:/etc/init.d/rc 1 +l2:2:wait:/etc/init.d/rc 2 +l3:3:wait:/etc/init.d/rc 3 +l4:4:wait:/etc/init.d/rc 4 +l5:5:wait:/etc/init.d/rc 5 +l6:6:wait:/etc/init.d/rc 6 +# Normally not reached, but fallthrough in case of emergency. +z6:6:respawn:/sbin/sulogin + +# What to do when CTRL-ALT-DEL is pressed. +ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now + +# Action on special keypress (ALT-UpArrow). +#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work." + +# What to do when the power fails/returns. +pf::powerwait:/etc/init.d/powerfail start +pn::powerfailnow:/etc/init.d/powerfail now +po::powerokwait:/etc/init.d/powerfail stop + +# /sbin/getty invocations for the runlevels. +# +# The "id" field MUST be the same as the last +# characters of the device (after "tty"). +# +# Format: +# ::: +# +# Note that on most Debian systems tty7 is used by the X Window System, +# so if you want to add more getty's go ahead but skip tty7 if you run X. +# +1:2345:respawn:/sbin/getty 38400 tty1 +2:23:respawn:/sbin/getty 38400 tty2 +3:23:respawn:/sbin/getty 38400 tty3 +4:23:respawn:/sbin/getty 38400 tty4 +5:23:respawn:/sbin/getty 38400 tty5 +6:23:respawn:/sbin/getty 38400 tty6 + +# Example how to put a getty on a serial line (for a terminal) +# +#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100 +#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100 + +# Example how to put a getty on a modem line. +# +#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3 + diff --git a/builds/any/rootfs/wheezy/standard/standard.yml b/builds/any/rootfs/wheezy/standard/standard.yml index 16567372..3010b68d 100644 --- a/builds/any/rootfs/wheezy/standard/standard.yml +++ b/builds/any/rootfs/wheezy/standard/standard.yml @@ -55,8 +55,6 @@ Configure: - ${ONL}/builds/any/rootfs/${ONL_DEBIAN_SUITE}/common/overlay update-rc.d: - - 'initdev defaults' - - 'onl-platform-baseconf defaults' - 'faultd defaults' - 'onlpd defaults' - 'snmpd remove' diff --git a/packages/base/all/boot.d/Makefile b/packages/base/all/boot.d/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/base/all/boot.d/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/base/all/boot.d/PKG.yml b/packages/base/all/boot.d/PKG.yml new file mode 100644 index 00000000..c785401e --- /dev/null +++ b/packages/base/all/boot.d/PKG.yml @@ -0,0 +1,16 @@ +common: + arch: all + version: 1.0.0 + copyright: Copyright 2013, 2014, 2015 Big Switch Networks + maintainer: support@bigswitch.com + +packages: + - name: onl-bootd + version: 1.0.0 + summary: Open Network Linux Boot Stage + + files: + - src : /etc/boot.d + + changelog: Change changes changes., + diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/init.d/initdev b/packages/base/all/boot.d/src/50.initdev similarity index 68% rename from builds/any/rootfs/wheezy/common/overlay/etc/init.d/initdev rename to packages/base/all/boot.d/src/50.initdev index df9dd898..6a0292a2 100755 --- a/builds/any/rootfs/wheezy/common/overlay/etc/init.d/initdev +++ b/packages/base/all/boot.d/src/50.initdev @@ -1,14 +1,5 @@ #!/bin/sh -### BEGIN INIT INFO -# Provides: initdev -# Required-Start: -# Required-Stop: -# Default-Start: S -# Default-Stop: -# Short-Description: Set up block and net devices -### END INIT INFO - . /lib/lsb/init-functions log_action_begin_msg "Setting up block and net devices" diff --git a/packages/base/all/boot.d/src/boot b/packages/base/all/boot.d/src/boot new file mode 100755 index 00000000..ceab23f7 --- /dev/null +++ b/packages/base/all/boot.d/src/boot @@ -0,0 +1,19 @@ +#!/bin/sh +############################################################ +# +# Initial boot setup. Required before running +# any concurrent service initialization in rcS +# +# This is designed to support early setup, platform, +# and upgrade operations. +# +############################################################ +PATH=/sbin:/usr/sbin:/bin:/usr/bin +export PATH + +for script in `ls /etc/boot.d/[0-9]* | sort`; do + echo "boot.d: Running $script..." + $script +done + + diff --git a/packages/base/all/vendor-config-onl/PKG.yml b/packages/base/all/vendor-config-onl/PKG.yml index 3122ba51..82a3d46d 100644 --- a/packages/base/all/vendor-config-onl/PKG.yml +++ b/packages/base/all/vendor-config-onl/PKG.yml @@ -1,6 +1,6 @@ packages: - name: onl-vendor-config-onl - depends: python-yaml + depends: [ python-yaml, onl-bootd ] version: 1.0.0 arch: all copyright: Copyright 2013, 2014, 2015 Big Switch Networks @@ -9,7 +9,7 @@ packages: files: src/python/onl : $PY_INSTALL/onl - src/init.d : /etc/init.d + src/boot.d : /etc/boot.d src/bin : /usr/bin changelog: Changes diff --git a/packages/base/all/vendor-config-onl/src/init.d/onl-platform-baseconf b/packages/base/all/vendor-config-onl/src/boot.d/51.onl-platform-baseconf similarity index 100% rename from packages/base/all/vendor-config-onl/src/init.d/onl-platform-baseconf rename to packages/base/all/vendor-config-onl/src/boot.d/51.onl-platform-baseconf diff --git a/packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf b/packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf new file mode 100755 index 00000000..718fa281 --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf @@ -0,0 +1,17 @@ +#!/usr/bin/python + +### BEGIN INIT INFO +# Provides: onl-platform-baseconf +# Required-Start: +# Required-Stop: +# Default-Start: S +# Default-Stop: +# Short-Description: Set up ONL Platform +### END INIT INFO + +from onl.platform.baseconfig import baseconfig + +baseconfig() + + + From 7f5305327a8b3f11b8e816ea2ac6e084bb74cffb Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 16:04:45 +0000 Subject: [PATCH 02/22] Renamed. --- .../src/boot.d/onl-platform-baseconf | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100755 packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf diff --git a/packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf b/packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf deleted file mode 100755 index 718fa281..00000000 --- a/packages/base/all/vendor-config-onl/src/boot.d/onl-platform-baseconf +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/python - -### BEGIN INIT INFO -# Provides: onl-platform-baseconf -# Required-Start: -# Required-Stop: -# Default-Start: S -# Default-Stop: -# Short-Description: Set up ONL Platform -### END INIT INFO - -from onl.platform.baseconfig import baseconfig - -baseconfig() - - - From d9ea7acf5dc139daef26448af0813d69aa2dafc1 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 16:06:51 +0000 Subject: [PATCH 03/22] Remove log msg. --- packages/base/all/boot.d/src/boot | 1 - sm/infra | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/base/all/boot.d/src/boot b/packages/base/all/boot.d/src/boot index ceab23f7..949b644a 100755 --- a/packages/base/all/boot.d/src/boot +++ b/packages/base/all/boot.d/src/boot @@ -12,7 +12,6 @@ PATH=/sbin:/usr/sbin:/bin:/usr/bin export PATH for script in `ls /etc/boot.d/[0-9]* | sort`; do - echo "boot.d: Running $script..." $script done diff --git a/sm/infra b/sm/infra index 6376b57f..19f74c74 160000 --- a/sm/infra +++ b/sm/infra @@ -1 +1 @@ -Subproject commit 6376b57ff49ee65e7512a52342e59bc1f201db33 +Subproject commit 19f74c743cd8d4c990640d0340fb295da428a0a8 From 425c6a4e511e3b12fc50ae123619db270b1c4e6e Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:22:26 +0000 Subject: [PATCH 04/22] Fix broken code. We need to add a pycompile step for all scripts during the packaging step to catch this at build time. --- .../r0/src/python/x86_64_accton_as7716_32x_r0/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/platform-config/r0/src/python/x86_64_accton_as7716_32x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/platform-config/r0/src/python/x86_64_accton_as7716_32x_r0/__init__.py index 54eed9b3..69069792 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/platform-config/r0/src/python/x86_64_accton_as7716_32x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/platform-config/r0/src/python/x86_64_accton_as7716_32x_r0/__init__.py @@ -19,7 +19,7 @@ class OnlPlatform_x86_64_accton_as7716_32x_r0(OnlPlatformAccton): ('pca9548', 0x77, 0), # initiate leaf multiplexer (PCA9548) - ('pca9548', 0x76 1), + ('pca9548', 0x76, 1), # initiate chassis fan ('as7716_32x_fan', 0x66, 9), @@ -87,4 +87,4 @@ class OnlPlatform_x86_64_accton_as7716_32x_r0(OnlPlatformAccton): ('24c02', 0x56, 0), ]) - return True), + return True From e66f04f816711753d71b8d3b9edcd8a5d8ca97a7 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:23:43 +0000 Subject: [PATCH 05/22] Short console flush prior to executing rcS --- packages/base/all/boot.d/src/boot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/base/all/boot.d/src/boot b/packages/base/all/boot.d/src/boot index 949b644a..1306da91 100755 --- a/packages/base/all/boot.d/src/boot +++ b/packages/base/all/boot.d/src/boot @@ -15,4 +15,9 @@ for script in `ls /etc/boot.d/[0-9]* | sort`; do $script done +# +# Wait for console to flush prior to starting rc.S +# +sleep .1 + From 2c8bf4fa69d0d13bfe4b13ed323dddeefff889f7 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:24:24 +0000 Subject: [PATCH 06/22] Upgrade infrastructure. --- .../src/python/onl/platform/base.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py b/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py index 97acae0b..4426071a 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py @@ -191,6 +191,20 @@ class OnlPlatformBase(object): self.sys_oid_vendor() + self.sys_oid_platform()); + def onie_version(self): + return self.onie_info.ONIE_VERSION + + def upgrade_manifest(self, type_, override_dir=None): + if override_dir: + m = os.path.join(override_dir, "manifest.json") + else: + m = os.path.join(self.basedir_onl(), "upgrade", type_, "manifest.json") + + if os.path.exists(m): + return (os.path.dirname(m), m, json.load(file(m))) + else: + return (None, None, None) + def new_device(self, driver, addr, bus, devdir): if not os.path.exists(os.path.join(bus, devdir)): From e87d52aea955fe47c48c1549764e934d9f49e70a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:25:10 +0000 Subject: [PATCH 07/22] Ignore build products. --- builds/amd64/installer/legacy/builds/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builds/amd64/installer/legacy/builds/.gitignore b/builds/amd64/installer/legacy/builds/.gitignore index fbd18542..80d5c25e 100644 --- a/builds/amd64/installer/legacy/builds/.gitignore +++ b/builds/amd64/installer/legacy/builds/.gitignore @@ -1 +1,6 @@ *INSTALLER +kernel-* +initrd-* +lib/ +usr/ + From dc1cb439b01e34611a4b2996a835ff6e8d590cef Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:26:02 +0000 Subject: [PATCH 08/22] Initial ONIE and Loader upgrade support. --- .../src/boot.d/61.upgrade-onie | 55 +++ .../src/boot.d/62.upgrade-loader | 147 ++++++ .../src/python/onl/upgrade/__init__.py | 9 + .../src/python/onl/upgrade/ubase.py | 427 ++++++++++++++++++ 4 files changed, 638 insertions(+) create mode 100755 packages/base/all/vendor-config-onl/src/boot.d/61.upgrade-onie create mode 100755 packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader create mode 100644 packages/base/all/vendor-config-onl/src/python/onl/upgrade/__init__.py create mode 100644 packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py diff --git a/packages/base/all/vendor-config-onl/src/boot.d/61.upgrade-onie b/packages/base/all/vendor-config-onl/src/boot.d/61.upgrade-onie new file mode 100755 index 00000000..5f0e8883 --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/boot.d/61.upgrade-onie @@ -0,0 +1,55 @@ +#!/usr/bin/python -u +from onl.upgrade import ubase + +class ONIE_Upgrade(ubase.BaseOnieUpgrade): + name="onie" + Name="ONIE" + title="ONIE Upgrade Check" + atype="An ONIE" + + current_version_key="Current ONIE Version" + next_version_key="Next ONIE Version" + + def init_versions(self): + + # Get the current platform ONIE version + self.current_version = self.platform.onie_version() + self.next_version = None + self.updater = None + + (udir, um, data) = self.platform.upgrade_manifest("onie") + self.udir = udir + self.data = data + + if data: + self.next_version = data.get('onie-version', None) + + if data: + self.updater = data.get('onie-updater', None) + + if self.updater is None: + self.finish("No ONIE updater available for the current platform.") + + def summarize(self): + self.logger.info("Current ONIE Version: %s" % self.current_version) + self.logger.info(" Next ONIE Version: %s" % self.next_version) + self.logger.info(" Force-Update: %s" % self.data['force-update']) + self.logger.info(" Updater: %s" % self.updater) + self.logger.info("") + + def upgrade_notes(self): + return """ + * The system will reboot into ONIE to complete the update, and then reboot to return to Switch Light +""" + + def do_upgrade(self, forced=False): + self.install_onie_updater(self.udir, self.updater) + self.initiate_onie_update() + + def do_no_upgrade(self): + self.clean_onie_updater() + + +if __name__ == '__main__': + ONIE_Upgrade().main() + diff --git a/packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader b/packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader new file mode 100755 index 00000000..dad90f70 --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader @@ -0,0 +1,147 @@ +#!/usr/bin/python +############################################################ +# +# ONL Loader Upgrade +# +############################################################ +import os +import fnmatch +from onl.upgrade import ubase + +class Loader_Upgrade(ubase.BaseUpgrade): + name="loader" + Name="Loader" + title="Loader Upgrade Check" + atype="A Loader" + + current_version_key="Current Loader Version" + next_version_key="Next Loader Version" + + def init_versions(self): + # + # Current Loader version file. + # If this file doesn't exist then in-place upgrade is not supported. + # + ETC_LOADER_VERSIONS_JSON = "/etc/onl/loader/versions.json" + + # Upgrade Loader Version file. + NEXT_LOADER_VERSIONS_JSON = "/etc/onl/upgrade/%s/manifest.json" % self.arch + + self.current_version = self.load_json(ETC_LOADER_VERSIONS_JSON, + "RELEASE_ID", + None) + + self.next_version = self.load_json(NEXT_LOADER_VERSIONS_JSON, + "version", {}).get('RELEASE_ID', None) + + # These will be used by the derived class's implementation. + (udir, um, data) = self.platform.upgrade_manifest("loader") + self.manifest = data + + + def summarize(self): + self.logger.info("Current Loader Version: %s" % self.current_version) + self.logger.info(" Next Loader Version: %s" % self.next_version) + self.logger.info("") + + + def upgrade_notes(self): + return """ + * A single reboot will be required to complete this upgrade. +""" + +class Loader_Upgrade_ppc(Loader_Upgrade): + + PPC_FIT_UPGRADE_IMAGE_PLATFORM="/etc/onl/upgrade/ppc/%s.itb" + PPC_FIT_UPGRADE_IMAGE_ALL="/etc/onl/upgrade/ppc/all.itb" + PPC_FIT_LOADER_IMAGE_NAME="switchlight-loader" + + def do_upgrade(self, forced=False): + + # + # The upgrade/ppc directory must have a FIT image called $PPC_FIT_UPGRADE_IMAGE (see constants above) + # This is obviously janky. + # + fit_image = None + + if os.path.exists(self.PPC_FIT_UPGRADE_IMAGE_PLATFORM % self.swlp.platform()): + fit_image = self.PPC_FIT_UPGRADE_IMAGE_PLATFORM % self.swlp.platform() + elif os.path.exists(self.PPC_FIT_UPGRADE_IMAGE_ALL): + fit_image = self.PPC_FIT_UPGRADE_IMAGE_ALL + else: + self.abort("The PPC Upgrade FIT image is missing. Upgrade cannot continue.") + + # + # The manifest says which partition contains the loader, and whether + # the loader is stored as a file in that partition or written raw + # directly to it. + # + partition = self.manifest.get('partition', None) + if not partition: + self.abort("The platform upgrade manifest does not contain a valid partition key.") + + if self.manifest.get('raw', False): + # + # The loader file is written raw to the given partition. + # + print "Writing %s to %s..." % (fit_image, partition) + if os.system("dd of=/dev/%s if=%s" % (partition, fit_image)) != 0: + self.abort("Failure writing loader data to partition." % (partition)) + + else: + # + # Mount the loader partition and rewrite the loader image. + # + mdir="/mnt/upgrade/loader" + self.mount(mdir, partition=partition) + self.copyfile(fit_image, os.path.join(mdir, self.PPC_FIT_LOADER_IMAGE_NAME)) + self.umount(mdir) + + self.reboot() + + + +class Loader_Upgrade_x86_64(Loader_Upgrade): + + X86_64_UPGRADE_DIR="/etc/onl/upgrade/x86_64/" + X86_64_UPGRADE_PATTERNS = [ "kernel-*", "initrd-*" ] + + def do_upgrade(self, forced=False): + # + # Mount the ONL-BOOT partition + # + mdir="/mnt/onl-boot" + self.mount(mdir, label="ONL-BOOT") + + for f in os.listdir(self.X86_64_UPGRADE_DIR): + for pattern in self.X86_64_UPGRADE_PATTERNS: + if fnmatch.fnmatch(f, pattern): + self.copyfile(os.path.join(self.X86_64_UPGRADE_DIR, f), os.path.join(mdir, f)) + + src = "/lib/platform-config/current/onl/boot/grub.cfg" + dst = os.path.join(mdir, "grub/grub.cfg") + if os.path.exists(src): + self.copyfile(src, dst) + + self.umount(mdir) + self.reboot() + + + + + +if __name__ == '__main__': + import platform + + arch = platform.machine() + klass = None + + if arch =='ppc': + klass = Loader_Upgrade_ppc + elif arch == 'x86_64': + klass = Loader_Upgrade_x86_64 + else: + raise Exception("The current architecture (%s) is not supported for upgrade." % arch) + + klass().main() + diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/__init__.py new file mode 100644 index 00000000..c71a523a --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/__init__.py @@ -0,0 +1,9 @@ +############################################################ +# +# +# Copyright 2013, 2014 BigSwitch Networks, Inc. +# +# +# +# +############################################################ diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py new file mode 100644 index 00000000..faebe6cd --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py @@ -0,0 +1,427 @@ +############################################################ +# +# Upgrade Base Classes +# +############################################################ +import logging +import logging.handlers +import platform as pp +import subprocess +import os +import sys +import shutil +import json +import string +import argparse +from time import sleep +from onl.platform.current import OnlPlatform + +class BaseUpgrade(object): + + # Customized by deriving class + name = None + Name = None + atype = None + current_version_key = None + next_version_key = None + def __init__(self): + + if not (self.name and self.Name and self.atype and self.title and + self.current_version_key and self.next_version_key): + raise Exception("Name descriptors must be provided by deriving class.") + + self.init_logger() + self.init_argparser() + self.load_config() + self.arch = pp.machine() + self.platform = OnlPlatform() + + # + # TODO. + # + # DEFAULT_CONFIG = { + # "auto-upgrade" : "advisory", + # } + # + # CONFIG_FILES = [ + # "/etc/boot.d/upgrade/.upgrade-config.json", + # "/mnt/flash/override-upgrade-config.json" + # ] + # + # def load_config(self): + # self.config = self.DEFAULT_CONFIG + # for f in self.CONFIG_FILES: + # if os.path.exists(f): + # self.config.update(json.load(file(f))) + # + # self.logger.debug("Loaded Configuration:\n%s\n" % (json.dumps(self.config, indent=2))) + # + # if self.name in self.config: + # self.config = self.config['name'] + # + # self.logger.debug("Final Configuration:\n%s\n" % (json.dumps(self.config, indent=2))) + # + def load_config(self): + pass + + + def init_logger(self): + fmt = '%(asctime)s.%(msecs)d %(levelname)s %(name)s: %(message)s' + datefmt="%Y-%m-%d %H:%M:%S" + formatter = logging.Formatter(fmt, datefmt) + + logging.basicConfig(format=fmt, datefmt=datefmt) + + self.logger = logging.getLogger(string.rjust("%s-upgrade" % self.name, 16)) + self.logger.setLevel(logging.INFO) + if os.getenv("DEBUG"): + self.logger.setLevel(logging.DEBUG) + + def init_argparser(self): + self.ap = argparse.ArgumentParser("%s-upgrade" % self.name) + self.ap.add_argument("--enable", action='store_true', help="Enable updates.") + self.ap.add_argument("--force", action='store_true', help="Force update.") + self.ap.add_argument("--no-reboot", action='store_true', help="Don't reboot.") + self.ap.add_argument("--check", action='store_true', help="Check only.") + self.ap.add_argument("--auto-upgrade", help="Override auto-upgrade mode.", default='advisory') + self.ap.add_argument("--summarize", action='store_true', help="Summarize only, no upgrades.") + + def banner(self): + self.logger.info("************************************************************") + self.logger.info("* %s" % self.title) + self.logger.info("************************************************************") + self.logger.info("") + + def finish(self, message=None, rc=0): + if message: + self.logger.info("") + if rc == 0: + self.logger.info(message) + else: + self.logger.error(message) + self.logger.info("") + self.logger.info("************************************************************") + self.update_upgrade_status(self.current_version_key, self.current_version) + self.update_upgrade_status(self.next_version_key, self.next_version) + # Flush stdout + sleep(.1) + sys.exit(rc) + + def abort(self, message=None, rc=1): + if message: + message = "Error: %s" % message + self.finish(message, rc) + + def fw_getenv(self, var): + FW_PRINTENV="/usr/bin/fw_printenv" + if os.path.exists(FW_PRINTENV): + try: + if var: + return subprocess.check_output("%s -n %s" % FW_PRINTENV, stderr=subprocess.STDOUT); + else: + variables = {} + for v in subprocess.check_output("/usr/bin/fw_printenv", shell=True).split('\n'): + (name, eq, value) = v.partition('=') + variables[name] = value + return variables + except Exception, e: + return None + else: + return None + + def fw_setenv(self, var, value): + FW_SETENV="/usr/bin/fw_setenv" + if os.system("%s %s %s" % (FW_SETENV, var, value)) != 0: + self.abort("Error setting environment variable %s=%s. Upgrade cannot continue." % (var, value)) + + def copyfile(self, src, dst): + self.logger.info("Installing %s -> %s..." % (src, dst)) + if not os.path.exists(src): + self.abort("Source file '%s' does not exist." % src) + + try: + shutil.copyfile(src, dst) + except Exception, e: + self.abort("Exception while copying: %s" % e) + + def reboot(self): + if self.ops.no_reboot: + self.finish("[ No Reboot ]") + elif self.ops.check: + self.finish("[ Check Abort ]") + else: + self.logger.info("The system will reboot to complete the update.") + sleep(1) + os.system("sync") + sleep(1) + while True: + os.system("reboot -f") + sleep(30) + self.abort("The system did not reboot as expected.") + + + def load_json(self, fname, key=None, default=None): + if os.path.exists(fname): + with open(fname) as f: + data = json.load(f) + if key: + return data.get(key, default) + else: + return data + else: + return default + + + UPGRADE_STATUS_JSON = "/lib/platform-config/current/upgrade.json" + + def update_upgrade_status(self, key, value): + data = {} + if os.path.exists(self.UPGRADE_STATUS_JSON): + with open(self.UPGRADE_STATUS_JSON) as f: + data = json.load(f) + data[key] = value + with open(self.UPGRADE_STATUS_JSON, "w") as f: + json.dump(data, f) + + + # + # Initialize self.current_version, self.next_Version + # and anything required for summarize() + # + def init_versions(self): + raise Exception("init_versions() must be provided by the deriving class.") + + + # + # Perform actual upgrade. Provided by derived class. + # + def do_upgrade(self, forced=False): + raise Exception("do_upgrade() must be provided by the deriving class.") + + # + # Perform any clean up necessary if the system is current (no upgrade required.) + # + def do_no_upgrade(self): + pass + + + def init_upgrade(self): + self.current_version = None + self.next_version = None + self.init_versions() + self.update_upgrade_status(self.current_version_key, self.current_version) + self.update_upgrade_status(self.next_version_key, self.next_version) + + def summarize(self): + pass + + + def __upgrade_prompt(self, instructions, default="yes"): + valid = {"yes": True, "y": True, "ye": True, + "no": False, "n": False} + if default is None: + prompt = " [y/n] " + elif default == "yes": + prompt = " [Y/n] " + elif default == "no": + prompt = " [y/N] " + else: + raise ValueError("invalid default answer: '%s'" % default) + + notes = self.upgrade_notes() + if notes: + instructions = instructions + "\n" + notes + "\n" + + instructions = "\n\n" + instructions + "\n\nStart the upgrade? " + + while True: + sys.stdout.write(instructions + prompt) + choice = raw_input().lower() + if default is not None and choice == '': + return valid[default] + elif choice in valid: + return valid[choice] + else: + sys.stdout.write("Please respond with 'yes' or 'no' " + "(or 'y' or 'n').\n") + + def upgrade_prompt(self, instructions, default='yes'): + try: + return self.__upgrade_prompt(instructions, default) + except Exception, e: + self.logger.error("") + self.logger.error("Exception: %s" % e) + self.abort("No upgrade will be performed.") + return False + except KeyboardInterrupt: + return False + + def upgrade_notes(self): + raise Exception("Must be provided by derived class.") + + def __upgrade_advisory(self): + if not self.ops.enable: + self.finish("%s updates are not enabled." % self.Name) + self.__do_upgrade() + self.finish() + + def __upgrade_force(self): + self.logger.info("This system is configured for automatic %s updates." % self.Name) + self.__do_upgrade() + self.finish() + + def __do_upgrade(self): + if self.ops.check: + self.finish("[ Check abort. ]") + self.do_upgrade() + + + def __upgrade_optional(self): + instructions = """%s upgrade should be performed before continuing for optimal Switch Light +performance on this system. + +While it is recommended that you perform this upgrade it is optional and you +may continue booting Switch Light for testing purposes at this time. + +Please note that you will be asked again each time at boot to perform +this upgrade. Automatic booting will not be possible until the upgrade +is performed.""" % self.atype + + if self.upgrade_prompt(instructions) == True: + self.__do_upgrade() + self.finish() + else: + self.finish("Upgrade cancelled.") + + def __upgrade_required(self): + instructions = """%s upgrade must be performed before Switch Light can run on this system. +If you choose not to perform this upgrade Switch Light cannot continue +booting.""" % self.atype + + if self.upgrade_prompt(instructions) == True: + self.__do_upgrade() + self.finish() + else: + self.logger.info("The system cannot continue without performing %s update. The system will now reboot if you would like to take alternative actions." % self.atype) + self.reboot() + + + def __upgrade(self): + self.logger.info("%s upgrade is required." % self.atype) + + auto_upgrade = self.ops.auto_upgrade + + # + # auto-upgrade modes are: + # advisory : Advisory only. This is the default. + # force : Perform the upgrade automatically. + # optional : Ask the user whether an upgrade should be performed. + # required : Ask the user whether an upgrade should be performed. + # Reboot if the answer is 'no'. + # + if auto_upgrade == 'advisory': + self.__upgrade_advisory() + elif auto_upgrade == 'force': + self.__upgrade_force(); + elif auto_upgrade == 'optional': + self.__upgrade_optional() + elif auto_upgrade == 'required': + self.__upgrade_required() + else: + self.abort("auto-upgrade mode '%s' is not supported." % auto_upgrade) + + + def upgrade_check(self): + + if self.current_version == self.next_version: + # Versions match. Only continue if forced. + if self.ops.force: + self.logger.info("%s version %s is current." % (self.Name, + self.current_version)) + self.logger.info("[ Upgrade Forced. ]") + else: + self.logger.info("%s version %s is current." % (self.Name, + self.current_version)) + self.do_no_upgrade() + self.finish() + + if self.next_version: + self.__upgrade() + + + def mount(self, location, partition=None, label=None): + if not os.path.isdir(location): + os.makedirs(location) + + if partition: + cmd = "mount /dev/%s %s " % (partition,location) + name = partition + + if label: + cmd = "mount LABEL=%s %s" % (label, location) + name = label + + if os.system(cmd) != 0: + self.abort("Could not mount %s @ %s. Upgrade cannot continue." % (name, location)) + + def umount(self, location): + if os.system("umount %s" % location) != 0: + self.abort("Could not unmount %s. Upgrade cannot continue." % location) + + + def main(self): + self.ops = self.ap.parse_args() + self.banner() + self.init_upgrade() + self.summarize() + if not self.ops.summarize: + self.upgrade_check() + + + + +class BaseOnieUpgrade(BaseUpgrade): + + ONIE_UPDATER_PATH = "/mnt/flash2/onie-updater" + + def install_onie_updater(self, src_dir, updater): + if type(updater) is list: + # Copy all files in the list to /mnt/flash2 + for f in updater: + src = os.path.join(src_dir, f) + dst = os.path.join("/mnt/flash2", f) + self.copyfile(src, dst) + else: + # Copy single updater to /mnt/flash2/onie-updater + src = os.path.join(src_dir, updater) + self.copyfile(src, self.ONIE_UPDATER_PATH) + + + def initiate_onie_update(self): + self.logger.info("Initiating %s Update." % self.Name) + if self.arch == 'ppc': + # Initiate update + self.fw_setenv('onie_boot_reason', 'update') + self.reboot() + + elif self.arch == 'x86_64': + OB = "/mnt/onie-boot" + self.mount(OB, label="ONIE-BOOT") + if os.system("/mnt/onie-boot/onie/tools/bin/onie-boot-mode -o update") != 0: + self.abort("Could not set ONIE Boot Mode to Update. Upgrade cannot continue.") + self.umount(OB) + + SL = "/mnt/sl-boot" + self.mount(SL, label="SL-BOOT") + with open("/mnt/sl-boot/grub/grub.cfg", "a") as f: + f.write("set default=ONIE\n") + self.umount(SL) + self.reboot() + + else: + self.abort("Architecture %s unhandled." % self.arch) + + def clean_onie_updater(self): + if os.path.exists(self.ONIE_UPDATER_PATH): + self.logger.info("Removing previous onie-updater.") + os.remove(self.ONIE_UPDATER_PATH) From e3c84da95bc966506a002e846e70896835c05664 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:27:23 +0000 Subject: [PATCH 09/22] Initial upgrade package for amd64 --- packages/base/amd64/upgrade/Makefile | 1 + packages/base/amd64/upgrade/PKG.yml | 26 +++++++++++++++++++ packages/base/amd64/upgrade/builds/.gitignore | 1 + packages/base/amd64/upgrade/builds/Makefile | 18 +++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 packages/base/amd64/upgrade/Makefile create mode 100644 packages/base/amd64/upgrade/PKG.yml create mode 100644 packages/base/amd64/upgrade/builds/.gitignore create mode 100644 packages/base/amd64/upgrade/builds/Makefile diff --git a/packages/base/amd64/upgrade/Makefile b/packages/base/amd64/upgrade/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/base/amd64/upgrade/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/base/amd64/upgrade/PKG.yml b/packages/base/amd64/upgrade/PKG.yml new file mode 100644 index 00000000..20a543fd --- /dev/null +++ b/packages/base/amd64/upgrade/PKG.yml @@ -0,0 +1,26 @@ +prerequisites: + packages: + - onl-kernel-3.9.6-x86-64-all:amd64 + - onl-kernel-3.2-deb7-x86-64-all:amd64 + - onl-kernel-3.18-x86-64-all:amd64 + - onl-loader-initrd:amd64 + +common: + arch: amd64 + version: 1.0.0 + copyright: Copyright 2013, 2014, 2015 Big Switch Networks + maintainer: support@bigswitch.com + +packages: + - name: onl-upgrade + version: 1.0.0 + summary: Open Network Linux Upgrade package for AMD64 platforms. + + files: + builds/files : /etc/onl/upgrade/x86_64 + + changelog: Change changes changes., + + + + diff --git a/packages/base/amd64/upgrade/builds/.gitignore b/packages/base/amd64/upgrade/builds/.gitignore new file mode 100644 index 00000000..027271b9 --- /dev/null +++ b/packages/base/amd64/upgrade/builds/.gitignore @@ -0,0 +1 @@ +files diff --git a/packages/base/amd64/upgrade/builds/Makefile b/packages/base/amd64/upgrade/builds/Makefile new file mode 100644 index 00000000..b95deb4a --- /dev/null +++ b/packages/base/amd64/upgrade/builds/Makefile @@ -0,0 +1,18 @@ +include $(ONL)/make/config.amd64.mk + +# All amd64 kernels +KERNELS := $(shell $(ONLPM) --find-file onl-kernel-3.9.6-x86-64-all:amd64 kernel-3.9.6-x86-64-all) \ + $(shell $(ONLPM) --find-file onl-kernel-3.2-deb7-x86-64-all:amd64 kernel-3.2-deb7-x86_64-all) \ + $(shell $(ONLPM) --find-file onl-kernel-3.18-x86-64-all:amd64 kernel-3.18-x86_64-all) \ + +# Loader initrd +INITRD := $(shell $(ONLPM) --find-file onl-loader-initrd:amd64 onl-loader-initrd-amd64.cpio.gz) +MANIFEST := $(shell $(ONLPM) --find-file onl-loader-initrd:amd64 manifest.json) + +all: + mkdir -p files + cp $(KERNELS) files + cp $(INITRD) files/initrd-amd64 + cp $(MANIFEST) files + + From 64e8c01e57228ff19dcb7308640f4bb121835347 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:27:42 +0000 Subject: [PATCH 10/22] Add upgrade package to AMD64 builds. --- builds/any/rootfs/jessie/common/amd64-packages.yml | 1 + builds/any/rootfs/wheezy/common/amd64-packages.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/builds/any/rootfs/jessie/common/amd64-packages.yml b/builds/any/rootfs/jessie/common/amd64-packages.yml index f06a44d0..c47575d5 100644 --- a/builds/any/rootfs/jessie/common/amd64-packages.yml +++ b/builds/any/rootfs/jessie/common/amd64-packages.yml @@ -7,6 +7,7 @@ - parted - smartmontools - grub2 +- onl-upgrade diff --git a/builds/any/rootfs/wheezy/common/amd64-packages.yml b/builds/any/rootfs/wheezy/common/amd64-packages.yml index f06a44d0..402a4169 100644 --- a/builds/any/rootfs/wheezy/common/amd64-packages.yml +++ b/builds/any/rootfs/wheezy/common/amd64-packages.yml @@ -7,6 +7,8 @@ - parted - smartmontools - grub2 +- onl-upgrade + From d0b968a561fe76b3a5b0d5fccd0078c5340654c9 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:02:32 +0000 Subject: [PATCH 11/22] Increase delay. --- packages/base/all/boot.d/src/boot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/base/all/boot.d/src/boot b/packages/base/all/boot.d/src/boot index 1306da91..9f52fd64 100755 --- a/packages/base/all/boot.d/src/boot +++ b/packages/base/all/boot.d/src/boot @@ -18,6 +18,6 @@ done # # Wait for console to flush prior to starting rc.S # -sleep .1 +sleep 1 From 95a32c5c6ca46ae6ebcbd80858699ce8b2bd90a3 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:02:58 +0000 Subject: [PATCH 12/22] Generic comments. --- .../vendor-config-onl/src/python/onl/upgrade/ubase.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py index faebe6cd..9b9f8176 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py @@ -277,11 +277,11 @@ class BaseUpgrade(object): def __upgrade_optional(self): - instructions = """%s upgrade should be performed before continuing for optimal Switch Light + instructions = """%s upgrade should be performed before continuing for optimal performance on this system. While it is recommended that you perform this upgrade it is optional and you -may continue booting Switch Light for testing purposes at this time. +may continue booting for testing purposes at this time. Please note that you will be asked again each time at boot to perform this upgrade. Automatic booting will not be possible until the upgrade @@ -294,9 +294,8 @@ is performed.""" % self.atype self.finish("Upgrade cancelled.") def __upgrade_required(self): - instructions = """%s upgrade must be performed before Switch Light can run on this system. -If you choose not to perform this upgrade Switch Light cannot continue -booting.""" % self.atype + instructions = """%s upgrade must be performed before the software can run on this system. +If you choose not to perform this upgrade booting cannot continue.""" % self.atype if self.upgrade_prompt(instructions) == True: self.__do_upgrade() From 00a64af3311d40e1c8efd6d9f3abb31315667181 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:03:30 +0000 Subject: [PATCH 13/22] Load the platform-config yaml file at init time. --- .../vendor-config-onl/src/python/onl/platform/base.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py b/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py index 4426071a..8bf9a2a2 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/platform/base.py @@ -105,6 +105,16 @@ class OnlPlatformBase(object): self.add_info_json("platform_info", "%s/platform-info.json" % self.basedir_onl(), required=False) + # Load the platform config yaml file + y = os.path.join(self.basedir_onl(), "%s.yml" % self.platform()) + if os.path.exists(y): + self.platform_config = yaml.load(open(y)) + if self.platform() in self.platform_config: + self.platform_config = self.platform_config[self.platform()] + else: + self.platform_config = {} + + def add_info_dict(self, name, d, klass=None): setattr(self, name, OnlInfoObject(d, klass)) From 8d1f22d6c8175abfd0994d759c66779c30b5ef2d Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:07:06 +0000 Subject: [PATCH 14/22] - Add manifest - Install in upgrade location. --- packages/base/powerpc/fit/loader/PKG.yml | 3 ++- packages/base/powerpc/fit/loader/builds/.gitignore | 1 + packages/base/powerpc/fit/loader/builds/Makefile | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/base/powerpc/fit/loader/PKG.yml b/packages/base/powerpc/fit/loader/PKG.yml index 6c024bce..fa89821f 100644 --- a/packages/base/powerpc/fit/loader/PKG.yml +++ b/packages/base/powerpc/fit/loader/PKG.yml @@ -14,7 +14,8 @@ packages: summary: Open Network Linux FIT Loader Image files: - builds/onl-loader-fit.itb : $$PKG_INSTALL/ + builds/onl-loader-fit.itb : /etc/onl/upgrade/ppc/ + builds/manifest.json : /etc/onl/upgrade/ppc/ changelog: Change changes changes., diff --git a/packages/base/powerpc/fit/loader/builds/.gitignore b/packages/base/powerpc/fit/loader/builds/.gitignore index 126b5b2f..22f6ac21 100644 --- a/packages/base/powerpc/fit/loader/builds/.gitignore +++ b/packages/base/powerpc/fit/loader/builds/.gitignore @@ -2,3 +2,4 @@ kernel-* *.itb *.its loader-initrd-powerpc +manifest.json diff --git a/packages/base/powerpc/fit/loader/builds/Makefile b/packages/base/powerpc/fit/loader/builds/Makefile index 45fdd23b..7c174a7f 100644 --- a/packages/base/powerpc/fit/loader/builds/Makefile +++ b/packages/base/powerpc/fit/loader/builds/Makefile @@ -1,7 +1,10 @@ +include $(ONL)/make/config.powerpc.mk + .PHONY: onl-loader-fit.itb onl-loader-fit.its onl-loader-fit.itb: $(ONL)/tools/flat-image-tree.py --initrd onl-loader-initrd:powerpc,onl-loader-initrd-powerpc.cpio.gz --add-platform initrd --itb $@ + $(ONLPM) --copy-file onl-loader-initrd:powerpc manifest.json . onl-loader-fit.its: $(ONL)/tools/flat-image-tree.py --initrd onl-loader-initrd:powerpc,onl-loader-initrd-powerpc.cpio.gz --add-platform initrd --its $@ From df7b1f3806607bb36f6d73ee2828bb912eee3729 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:07:33 +0000 Subject: [PATCH 15/22] Add upgrade FIT package. --- builds/any/rootfs/jessie/common/powerpc-packages.yml | 1 + builds/any/rootfs/wheezy/common/powerpc-packages.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/builds/any/rootfs/jessie/common/powerpc-packages.yml b/builds/any/rootfs/jessie/common/powerpc-packages.yml index 618f3581..e55a7d8b 100644 --- a/builds/any/rootfs/jessie/common/powerpc-packages.yml +++ b/builds/any/rootfs/jessie/common/powerpc-packages.yml @@ -4,6 +4,7 @@ # ############################################################ - u-boot-tools +- onl-loader-fit diff --git a/builds/any/rootfs/wheezy/common/powerpc-packages.yml b/builds/any/rootfs/wheezy/common/powerpc-packages.yml index 618f3581..0f9eb5bc 100644 --- a/builds/any/rootfs/wheezy/common/powerpc-packages.yml +++ b/builds/any/rootfs/wheezy/common/powerpc-packages.yml @@ -4,7 +4,7 @@ # ############################################################ - u-boot-tools - +- onl-loader-fit From c4a20ba4fb3953785d3cfc7b0dd277d4a4ce1ebc Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:14:32 +0000 Subject: [PATCH 16/22] PPC Upgrade fixes. --- .../src/boot.d/62.upgrade-loader | 54 ++++++++++--------- .../src/python/onl/upgrade/ubase.py | 2 +- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader b/packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader index dad90f70..77011f5b 100755 --- a/packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader +++ b/packages/base/all/vendor-config-onl/src/boot.d/62.upgrade-loader @@ -34,11 +34,6 @@ class Loader_Upgrade(ubase.BaseUpgrade): self.next_version = self.load_json(NEXT_LOADER_VERSIONS_JSON, "version", {}).get('RELEASE_ID', None) - # These will be used by the derived class's implementation. - (udir, um, data) = self.platform.upgrade_manifest("loader") - self.manifest = data - - def summarize(self): self.logger.info("Current Loader Version: %s" % self.current_version) self.logger.info(" Next Loader Version: %s" % self.next_version) @@ -52,41 +47,52 @@ class Loader_Upgrade(ubase.BaseUpgrade): class Loader_Upgrade_ppc(Loader_Upgrade): - PPC_FIT_UPGRADE_IMAGE_PLATFORM="/etc/onl/upgrade/ppc/%s.itb" - PPC_FIT_UPGRADE_IMAGE_ALL="/etc/onl/upgrade/ppc/all.itb" - PPC_FIT_LOADER_IMAGE_NAME="switchlight-loader" - def do_upgrade(self, forced=False): + PPC_FIT_UPGRADE_IMAGE_PLATFORM="/etc/onl/upgrade/ppc/%s.itb" % self.platform.platform() + PPC_FIT_UPGRADE_IMAGE_ALL="/etc/onl/upgrade/ppc/onl-loader-fit.itb" + PPC_FIT_LOADER_IMAGE_NAME="%s.itb" % self.platform.platform() + # # The upgrade/ppc directory must have a FIT image called $PPC_FIT_UPGRADE_IMAGE (see constants above) - # This is obviously janky. + # This is obviously a little janky. # fit_image = None - if os.path.exists(self.PPC_FIT_UPGRADE_IMAGE_PLATFORM % self.swlp.platform()): - fit_image = self.PPC_FIT_UPGRADE_IMAGE_PLATFORM % self.swlp.platform() - elif os.path.exists(self.PPC_FIT_UPGRADE_IMAGE_ALL): - fit_image = self.PPC_FIT_UPGRADE_IMAGE_ALL + if os.path.exists(PPC_FIT_UPGRADE_IMAGE_PLATFORM): + fit_image = PPC_FIT_UPGRADE_IMAGE_PLATFORM + elif os.path.exists(PPC_FIT_UPGRADE_IMAGE_ALL): + fit_image = PPC_FIT_UPGRADE_IMAGE_ALL else: self.abort("The PPC Upgrade FIT image is missing. Upgrade cannot continue.") # - # The manifest says which partition contains the loader, and whether - # the loader is stored as a file in that partition or written raw - # directly to it. + # The platform configuration file will describe which partition + # and which format should be used to store the FIT image. # - partition = self.manifest.get('partition', None) - if not partition: - self.abort("The platform upgrade manifest does not contain a valid partition key.") + partition = None + raw = False + pc = self.platform.platform_config - if self.manifest.get('raw', False): + if pc: + if 'loader' in pc and pc['loader']: + if 'partition' in pc['loader']: + partition = pc['loader']['partition'] + else: + self.abort("No partition listed in the loader section of the platform configuration.") + raw = pc['loader'].get('raw', False) + else: + self.abort("No loader section listed in the platform configuration.") + else: + self.abort("No platform configuration.") + + if raw: # # The loader file is written raw to the given partition. # print "Writing %s to %s..." % (fit_image, partition) - if os.system("dd of=/dev/%s if=%s" % (partition, fit_image)) != 0: - self.abort("Failure writing loader data to partition." % (partition)) + if os.system("dd of=%s if=%s" % (partition, fit_image)) != 0: + self.abort("Failure writing loader data to partition %s." % (partition)) else: # @@ -94,7 +100,7 @@ class Loader_Upgrade_ppc(Loader_Upgrade): # mdir="/mnt/upgrade/loader" self.mount(mdir, partition=partition) - self.copyfile(fit_image, os.path.join(mdir, self.PPC_FIT_LOADER_IMAGE_NAME)) + self.copyfile(fit_image, os.path.join(mdir, PPC_FIT_LOADER_IMAGE_NAME)) self.umount(mdir) self.reboot() diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py index 9b9f8176..0ab417c6 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py @@ -353,7 +353,7 @@ If you choose not to perform this upgrade booting cannot continue.""" % self.aty os.makedirs(location) if partition: - cmd = "mount /dev/%s %s " % (partition,location) + cmd = "mount %s %s " % (partition,location) name = partition if label: From 8974ed29d6c8335b1730cc3e01fa3edc263f17b5 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:14:52 +0000 Subject: [PATCH 17/22] Add loader upgrade information. --- .../r0/src/lib/powerpc-accton-as5610-52x-r0.yml | 3 +++ .../r0/src/lib/powerpc-accton-as5710-54x-r0.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/lib/powerpc-accton-as5610-52x-r0.yml b/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/lib/powerpc-accton-as5610-52x-r0.yml index c03a6eb1..011674d7 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/lib/powerpc-accton-as5610-52x-r0.yml +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/lib/powerpc-accton-as5610-52x-r0.yml @@ -2,3 +2,6 @@ powerpc-accton-as5610-52x-r0: flat_image_tree: kernel: onl-kernel-3.9.6-powerpc-e500v:powerpc, kernel-3.9.6-powerpc-e500v.bin.gz dtb: onl-kernel-3.9.6-powerpc-e500v:powerpc, powerpc-as5610-52x.dtb + + loader: + partition: /dev/sda1 \ No newline at end of file diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/lib/powerpc-accton-as5710-54x-r0.yml b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/lib/powerpc-accton-as5710-54x-r0.yml index 90f6555e..2e3bde00 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/lib/powerpc-accton-as5710-54x-r0.yml +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/lib/powerpc-accton-as5710-54x-r0.yml @@ -3,4 +3,7 @@ powerpc-accton-as5710-54x-r0: kernel: onl-kernel-3.8.13-powerpc-e500mc:powerpc, kernel-3.8.13-powerpc-e500mc.bin.gz dtb: onl-kernel-3.8.13-powerpc-e500mc:powerpc, powerpc-accton-as5710-54x-r0.dtb + loader: + partition: /dev/sda1 + raw: True From 2eaf20505a3726f358e3a98e2d6d438d48c935cc Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:46:42 +0000 Subject: [PATCH 18/22] Add loader upgrade sections. --- .../r0/src/lib/powerpc-accton-as4600-54t-r0.yml | 2 ++ .../r0b/src/lib/powerpc-accton-as5710-54x-r0b.yml | 3 +++ .../r0/src/lib/powerpc-accton-as6700-32x-r0.yml | 2 ++ .../r1/src/lib/powerpc-accton-as6700-32x-r1.yml | 2 ++ .../platform-config/r0/src/lib/powerpc-quanta-lb9-r0.yml | 3 +++ .../platform-config/r0/src/lib/powerpc-quanta-ly2-r0.yml | 2 ++ 6 files changed, 14 insertions(+) diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/lib/powerpc-accton-as4600-54t-r0.yml b/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/lib/powerpc-accton-as4600-54t-r0.yml index aa758dbe..4e178c5e 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/lib/powerpc-accton-as4600-54t-r0.yml +++ b/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/lib/powerpc-accton-as4600-54t-r0.yml @@ -3,3 +3,5 @@ powerpc-accton-as4600-54t-r0: kernel: onl-kernel-3.9.6-powerpc-e500v:powerpc, kernel-3.9.6-powerpc-e500v.bin.gz dtb: onl-kernel-3.9.6-powerpc-e500v:powerpc, powerpc-as4600-54t.dtb + loader: + partition: /dev/sda1 diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/lib/powerpc-accton-as5710-54x-r0b.yml b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/lib/powerpc-accton-as5710-54x-r0b.yml index a56bbfd4..1ceabcfe 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/lib/powerpc-accton-as5710-54x-r0b.yml +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/lib/powerpc-accton-as5710-54x-r0b.yml @@ -3,4 +3,7 @@ powerpc-accton-as5710-54x-r0b: kernel: onl-kernel-3.8.13-powerpc-e500mc:powerpc, kernel-3.8.13-powerpc-e500mc.bin.gz dtb: onl-kernel-3.8.13-powerpc-e500mc:powerpc, powerpc-accton-as5710-54x-r0b.dtb + loader: + partition: /dev/sda1 + raw: True diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/lib/powerpc-accton-as6700-32x-r0.yml b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/lib/powerpc-accton-as6700-32x-r0.yml index 1444e53c..a5287fe1 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/lib/powerpc-accton-as6700-32x-r0.yml +++ b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/lib/powerpc-accton-as6700-32x-r0.yml @@ -3,4 +3,6 @@ powerpc-accton-as6700-32x-r0: kernel: onl-kernel-3.8.13-powerpc-e500mc:powerpc, kernel-3.8.13-powerpc-e500mc.bin.gz dtb: onl-kernel-3.8.13-powerpc-e500mc:powerpc, powerpc-accton-as6700-32x-r0.dtb + loader: + partition: /dev/sda1 diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/lib/powerpc-accton-as6700-32x-r1.yml b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/lib/powerpc-accton-as6700-32x-r1.yml index a115a2e9..dbb1187d 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/lib/powerpc-accton-as6700-32x-r1.yml +++ b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/lib/powerpc-accton-as6700-32x-r1.yml @@ -3,4 +3,6 @@ powerpc-accton-as6700-32x-r1: kernel: onl-kernel-3.8.13-powerpc-e500mc:powerpc, kernel-3.8.13-powerpc-e500mc.bin.gz dtb: onl-kernel-3.8.13-powerpc-e500mc:powerpc, powerpc-accton-as6700-32x-r1.dtb + loader: + partition: /dev/sda1 diff --git a/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/lib/powerpc-quanta-lb9-r0.yml b/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/lib/powerpc-quanta-lb9-r0.yml index 3d26cc6d..309845f9 100644 --- a/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/lib/powerpc-quanta-lb9-r0.yml +++ b/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/lib/powerpc-quanta-lb9-r0.yml @@ -3,3 +3,6 @@ powerpc-quanta-lb9-r0: kernel: onl-kernel-3.9.6-powerpc-e500v:powerpc, kernel-3.9.6-powerpc-e500v.bin.gz dtb: onl-kernel-3.9.6-powerpc-e500v:powerpc, powerpc-quanta-lb9-r0.dtb + loader: + partition: /dev/sda1 + raw: True diff --git a/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/lib/powerpc-quanta-ly2-r0.yml b/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/lib/powerpc-quanta-ly2-r0.yml index 38b1f7d4..95c591b1 100644 --- a/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/lib/powerpc-quanta-ly2-r0.yml +++ b/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/lib/powerpc-quanta-ly2-r0.yml @@ -3,3 +3,5 @@ powerpc-quanta-ly2-r0: kernel: onl-kernel-3.9.6-powerpc-e500v:powerpc, kernel-3.9.6-powerpc-e500v.bin.gz dtb: onl-kernel-3.9.6-powerpc-e500v:powerpc, powerpc-quanta-ly2-r0.dtb + loader: + partition: /dev/mmcblk0p1 From e33360beb205403d56631d08abc6057d137a389a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:46:58 +0000 Subject: [PATCH 19/22] Latest --- packages/platforms-closed | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platforms-closed b/packages/platforms-closed index ca6abea5..51991fb3 160000 --- a/packages/platforms-closed +++ b/packages/platforms-closed @@ -1 +1 @@ -Subproject commit ca6abea54088ad74ad2fe044a39522224ac90a5d +Subproject commit 51991fb381ff842d9a197fb3ab4ca4a77fc12366 From d7e3e65ff1885d82426c55d05f27bc5f4e97d7b9 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:47:37 +0000 Subject: [PATCH 20/22] Add option to regenerate all version files. --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 553bb85f..0eac1a72 100644 --- a/Makefile +++ b/Makefile @@ -58,3 +58,7 @@ docker: docker_check # create an interative docker shell, for debugging builds docker-debug: docker_check @docker/tools/onlbuilder -$(VERSION) --isolate --hostname onlbuilder$(VERSION) --pull + + +versions: + $(ONL)/tools/make-versions.py --import-file=$(ONL)/tools/onlvi --class-name=OnlVersionImplementation --output-dir $(ONL)/make --force \ No newline at end of file From b6b30e68c3d423eb0ddc7c1a65c508ecb7945cb8 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 20:49:39 +0000 Subject: [PATCH 21/22] Newlines. --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0eac1a72..2d70e971 100644 --- a/Makefile +++ b/Makefile @@ -61,4 +61,5 @@ docker-debug: docker_check versions: - $(ONL)/tools/make-versions.py --import-file=$(ONL)/tools/onlvi --class-name=OnlVersionImplementation --output-dir $(ONL)/make --force \ No newline at end of file + $(ONL)/tools/make-versions.py --import-file=$(ONL)/tools/onlvi --class-name=OnlVersionImplementation --output-dir $(ONL)/make --force + From 187e4c7ab9cdb918c120e8ef55e3f66c94577d0a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 29 Mar 2016 18:29:27 -0700 Subject: [PATCH 22/22] A bug in the dependency analysis is keeping some packages from getting built automatically. --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2d70e971..37bd1667 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ include $(ONL)/make/config.mk all: amd64 ppc $(MAKE) -C REPO build-clean -onl-amd64 onl-x86 x86 x86_64 amd64: +onl-amd64 onl-x86 x86 x86_64 amd64: packages_base_all $(MAKE) -C packages/base/amd64/kernels $(MAKE) -C packages/base/amd64/initrds $(MAKE) -C packages/base/amd64/onlp @@ -25,7 +25,7 @@ onl-amd64 onl-x86 x86 x86_64 amd64: $(MAKE) -C builds/amd64/swi $(MAKE) -C builds/amd64/installer/legacy -onl-ppc ppc: +onl-ppc ppc: packages_base_all $(MAKE) -C packages/base/powerpc/kernels $(MAKE) -C packages/base/powerpc/initrds $(MAKE) -C packages/base/powerpc/onlp @@ -36,6 +36,9 @@ onl-ppc ppc: $(MAKE) -C builds/powerpc/swi $(MAKE) -C builds/powerpc/installer/legacy +packages_base_all: + $(MAKE) -C packages/base/all + rpc rebuild: $(ONLPM) --rebuild-pkg-cache