From 7a10269fb8d817a8a395b8597b774b41673f9f6e Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:27:59 +0000 Subject: [PATCH 01/87] Customized RFS manifest. --- make/rfs.mk | 6 +++++- tools/onlrfs.py | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/make/rfs.mk b/make/rfs.mk index 1c8e0d52..f137e411 100644 --- a/make/rfs.mk +++ b/make/rfs.mk @@ -28,10 +28,14 @@ ifdef RFS_SQUASH RFS_COMMAND += --squash $(RFS_SQUASH) endif +ifndef RFS_MANIFEST +RFS_MANIFEST := etc/onl/rootfs/manifest.json +endif + RFS: $(ONL_V_at) rm -rf manifest.json $(ONL_V_at) $(RFS_COMMAND) - $(ONL_V_at) [ -f $(RFS_DIR)/etc/onl/rootfs/manifest.json ] && cp $(RFS_DIR)/etc/onl/rootfs/manifest.json . + $(ONL_V_at) [ -f $(RFS_DIR)/$(RFS_MANIFEST) ] && cp $(RFS_DIR)/$(RFS_MANIFEST) . clean: $(ONL_V_at) sudo rm -rf $(RFS_DIR) diff --git a/tools/onlrfs.py b/tools/onlrfs.py index 3cac7a1b..9875f1a4 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -354,6 +354,11 @@ rm -f /usr/sbin/policy-rc.d options = Configure.get('options', {}) if options.get('clean', False): logger.info("Cleaning Filesystem...") + onlu.execute('sudo chroot %s /usr/bin/apt-get clean' % dir_) + onlu.execute('sudo chroot %s /usr/sbin/localepurge' % dir_ ) + onlu.execute('sudo chroot %s find /usr/share/doc -type f | xargs rm -rf' % dir_) + onlu.execute('sudo chroot %s find /usr/share/man -type f | xargs rm -rf' % dir_) + if not options.get('securetty', True): f = os.path.join(dir_, 'etc/securetty') @@ -387,19 +392,21 @@ rm -f /usr/sbin/policy-rc.d ua.chmod('go-w', os.path.dirname(f)) - manifest = Configure.get('manifest', {}) - if manifest: - mname = "%s/etc/onl/rootfs/manifest.json" % dir_ + for (mf, fields) in Configure.get('manifests', {}).iteritems(): + logger.info("Configuring manifest %s..." % mf) + if mf.startswith('/'): + mf = mf[1:] + mname = os.path.join(dir_, mf) onlu.execute("sudo mkdir -p %s" % os.path.dirname(mname)) onlu.execute("sudo touch %s" % mname) onlu.execute("sudo chmod a+w %s" % mname) md = {} - md['version'] = json.load(open(manifest['version'])) + md['version'] = json.load(open(fields['version'])) md['arch'] = self.arch - if os.path.exists(manifest['platforms']): - md['platforms'] = yaml.load(open(manifest['platforms'])) + if os.path.exists(fields['platforms']): + md['platforms'] = yaml.load(open(fields['platforms'])) else: - md['platforms'] = manifest['platforms'].split(',') + md['platforms'] = fields['platforms'].split(',') with open(mname, "w") as f: json.dump(md, f, indent=2) onlu.execute("sudo chmod a-w %s" % mname) From cb96ab9a3749f2a3a0c110926e724b1176909869 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:28:48 +0000 Subject: [PATCH 02/87] Deprecated. --- .../jessie/common/overlay/etc/init.d/initdev | 26 -------- .../jessie/common/overlay/sbin/initblockdev | 62 ------------------- .../overlay/etc/udev/rules.d/60-block.rules | 1 - .../overlay/etc/udev/rules.d/60-net.rules | 1 - .../wheezy/common/overlay/sbin/initblockdev | 62 ------------------- 5 files changed, 152 deletions(-) delete mode 100755 builds/any/rootfs/jessie/common/overlay/etc/init.d/initdev delete mode 100755 builds/any/rootfs/jessie/common/overlay/sbin/initblockdev delete mode 100644 builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-block.rules delete mode 100644 builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-net.rules delete mode 100755 builds/any/rootfs/wheezy/common/overlay/sbin/initblockdev diff --git a/builds/any/rootfs/jessie/common/overlay/etc/init.d/initdev b/builds/any/rootfs/jessie/common/overlay/etc/init.d/initdev deleted file mode 100755 index df9dd898..00000000 --- a/builds/any/rootfs/jessie/common/overlay/etc/init.d/initdev +++ /dev/null @@ -1,26 +0,0 @@ -#!/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" - -ln -snf /proc/mounts /etc/mtab - -( cd /sys/class/block; for d in *; do /sbin/initblockdev $d add; done ) -if [ -d /sys/class/ubi ]; then - ( cd /sys/class/ubi; for d in *; do /sbin/initblockdev $d add; done ) -fi -( cd /sys/class/net; for d in *; do /sbin/initnetdev $d add; done ) - -initmounts - -log_action_end_msg 0 diff --git a/builds/any/rootfs/jessie/common/overlay/sbin/initblockdev b/builds/any/rootfs/jessie/common/overlay/sbin/initblockdev deleted file mode 100755 index e4b7cc3d..00000000 --- a/builds/any/rootfs/jessie/common/overlay/sbin/initblockdev +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -set -e -exec 9<$0 -flock -x 9 -case $2 in - add) - eval $(echo $1 | sed "s#^\(mmcblk[0-9]*\|ubi[0-9]*_[0-9]*\|mtdblock[0-9]*\|[a-z]*\)\(p[0-9]*\|[0-9]*\).*#dev='\1' part='\2'#") - if [ -e /etc/onl/recover ]; then - recover=$(cat /etc/onl/recover) - fi - devid= - if [ -e /sys/class/ubi/${dev}/device ]; then - eval $(realpath /sys/class/ubi/${dev}/device | sed "s#/sys/devices/\(.*\)#devid='\1'#") - fi - if [ -e /sys/class/block/${dev}/device ]; then - eval $(realpath /sys/class/block/${dev}/device | sed "s#/sys/devices/\(.*\)#devid='\1'#") - fi - while read i n; do - expr match "$i" "#" >/dev/null && continue || : - [ -n "${devid}" ] && expr match "${devid}" "$i" >/dev/null && mount=/mnt/$n && break || : - expr match "@${dev}" "$i" >/dev/null && mount=/mnt/$n && break || : - done /dev/null)" = "070701" ]; then - mount=${mount}-recover - else - mkdir -p ${mount} - [ $(stat -c %D ${mount}) = $(stat -c %D /mnt) ] - if [ "$(dd if=/dev/${dev}${part} bs=1 skip=82 count=5 2>/dev/null)" = "FAT32" ] \ - || [ "$(dd if=/dev/${dev}${part} bs=1 skip=54 count=5 2>/dev/null)" = "FAT16" ]; then - if [ ! -e /etc/onl/kdump ]; then - if [ "$recover" = "fsck" ]; then - # Try to repair FAT filesystem automatically to prevent further - # damage (but skip it in kdump to save time and memory) - if dosfsck -a /dev/${dev}${part} >/dev/null 2>&1; then - : - else - dosfsck -n /dev/${dev}${part} >/dev/null 2>&1 - fi - else - dosfsck -n /dev/${dev}${part} >/dev/null 2>&1 - fi - fi - mount -o flush,dirsync,noatime,umask=0007 /dev/${dev}${part} ${mount} 2>/dev/null - else - mount -o noatime /dev/${dev}${part} ${mount} 2>/dev/null - fi - fi - echo -e "devid='${devid}'\ndev='${dev}'\npart='${part}'" >${mount}.conf - ;; - remove) - mtab=$(mktemp /tmp/tmp.XXXXXX) - cp /proc/mounts ${mtab} - while read dev mount x; do - if [ /dev/$1 = "${dev}" ]; then - rm -f ${mount}.conf - umount -l ${mount} 2>/dev/null || : - fi - done <${mtab} - rm -f ${mtab} - ;; -esac diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-block.rules b/builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-block.rules deleted file mode 100644 index f2345a37..00000000 --- a/builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-block.rules +++ /dev/null @@ -1 +0,0 @@ -SUBSYSTEM=="block", RUN+="/sbin/initblockdev $kernel $env{ACTION}" diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-net.rules b/builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-net.rules deleted file mode 100644 index 627e65e4..00000000 --- a/builds/any/rootfs/wheezy/common/overlay/etc/udev/rules.d/60-net.rules +++ /dev/null @@ -1 +0,0 @@ -SUBSYSTEM=="net", RUN+="/sbin/initnetdev $kernel $env{ACTION}" diff --git a/builds/any/rootfs/wheezy/common/overlay/sbin/initblockdev b/builds/any/rootfs/wheezy/common/overlay/sbin/initblockdev deleted file mode 100755 index e4b7cc3d..00000000 --- a/builds/any/rootfs/wheezy/common/overlay/sbin/initblockdev +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -set -e -exec 9<$0 -flock -x 9 -case $2 in - add) - eval $(echo $1 | sed "s#^\(mmcblk[0-9]*\|ubi[0-9]*_[0-9]*\|mtdblock[0-9]*\|[a-z]*\)\(p[0-9]*\|[0-9]*\).*#dev='\1' part='\2'#") - if [ -e /etc/onl/recover ]; then - recover=$(cat /etc/onl/recover) - fi - devid= - if [ -e /sys/class/ubi/${dev}/device ]; then - eval $(realpath /sys/class/ubi/${dev}/device | sed "s#/sys/devices/\(.*\)#devid='\1'#") - fi - if [ -e /sys/class/block/${dev}/device ]; then - eval $(realpath /sys/class/block/${dev}/device | sed "s#/sys/devices/\(.*\)#devid='\1'#") - fi - while read i n; do - expr match "$i" "#" >/dev/null && continue || : - [ -n "${devid}" ] && expr match "${devid}" "$i" >/dev/null && mount=/mnt/$n && break || : - expr match "@${dev}" "$i" >/dev/null && mount=/mnt/$n && break || : - done /dev/null)" = "070701" ]; then - mount=${mount}-recover - else - mkdir -p ${mount} - [ $(stat -c %D ${mount}) = $(stat -c %D /mnt) ] - if [ "$(dd if=/dev/${dev}${part} bs=1 skip=82 count=5 2>/dev/null)" = "FAT32" ] \ - || [ "$(dd if=/dev/${dev}${part} bs=1 skip=54 count=5 2>/dev/null)" = "FAT16" ]; then - if [ ! -e /etc/onl/kdump ]; then - if [ "$recover" = "fsck" ]; then - # Try to repair FAT filesystem automatically to prevent further - # damage (but skip it in kdump to save time and memory) - if dosfsck -a /dev/${dev}${part} >/dev/null 2>&1; then - : - else - dosfsck -n /dev/${dev}${part} >/dev/null 2>&1 - fi - else - dosfsck -n /dev/${dev}${part} >/dev/null 2>&1 - fi - fi - mount -o flush,dirsync,noatime,umask=0007 /dev/${dev}${part} ${mount} 2>/dev/null - else - mount -o noatime /dev/${dev}${part} ${mount} 2>/dev/null - fi - fi - echo -e "devid='${devid}'\ndev='${dev}'\npart='${part}'" >${mount}.conf - ;; - remove) - mtab=$(mktemp /tmp/tmp.XXXXXX) - cp /proc/mounts ${mtab} - while read dev mount x; do - if [ /dev/$1 = "${dev}" ]; then - rm -f ${mount}.conf - umount -l ${mount} 2>/dev/null || : - fi - done <${mtab} - rm -f ${mtab} - ;; -esac From f170a0117c25530e7cff549a2500c561372a0937 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:35:26 +0000 Subject: [PATCH 03/87] Initial system configuration and customization interface. --- .../src/python/onl/sysconfig/__init__.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py diff --git a/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py new file mode 100644 index 00000000..b67f2420 --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py @@ -0,0 +1,60 @@ +############################################################ +# +# ONL System Configuration +# +############################################################ +import os +import sys +import yaml +import types +import onl.onlyaml +import platform as pp +from onl.platform.current import OnlPlatform + +class DotDict(dict): + """ Access keys in a nested dictionary using dot notation """ + + def __getattr__(self, attr): + item = self.get(attr, None) + + if item is None: + raise AttributeError("'%s' object has no attribute '%s'" % (type(self), attr)) + + if type(item) == types.DictType: + item = DotDict(item) + + return item + + __setattr__= dict.__setitem__ + __delattr__= dict.__delitem__ + + +class OnlSystemConfig(object): + SYSTEM_CONFIG_DIR = '/etc/onl/config' + + def __init__(self): + + platform = OnlPlatform() + self.variables = {} + self.variables['PLATFORM'] = platform.platform() + self.variables['ARCH'] = pp.machine() + self.variables['PARCH'] = dict(ppc='powerpc', + x86_64='amd64', + armv7l='armel')[pp.machine()] + + self.config = {} + + for root, dirs, files in os.walk(self.SYSTEM_CONFIG_DIR): + for f in files: + if f.endswith('.yml'): + d = onl.onlyaml.loadf(os.path.join(root, f), self.variables) + self.config.update(d) + + self.config['pc'] = platform.platform_config + + def dump(self): + return yaml.dump(self.config, default_flow_style=False) + +x = OnlSystemConfig() +sysconfig = DotDict(x.config) +sysconfig['OnlSystemConfig'] = x From 2d7ded9d0ca332b47e0e49c463b067614f547085 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:36:37 +0000 Subject: [PATCH 04/87] Onl Utility Classes. --- .../src/python/onl/util/__init__.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py diff --git a/packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py new file mode 100644 index 00000000..0a96d689 --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py @@ -0,0 +1,20 @@ +import subprocess + +class OnlServiceMixin(object): + def _execute(self, cmd, root=False, ex=True): + self.logger.debug("Executing: %s" % cmd) + if root is True and os.getuid() != 0: + cmd = "sudo " + cmd + try: + subprocess.check_call(cmd, shell=True) + except Exception, e: + if ex: + self.logger.error("Command failed: %s" % e) + raise + else: + return e.returncode + + def _raise(self, msg, klass): + self.logger.critical(msg) + raise klass(msg) + From c94cc26460d47041bfc87b113d569560cdbc2c39 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:37:56 +0000 Subject: [PATCH 05/87] Initial ONL system configuration. --- .../src/etc/onl/config/onl-config.yml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 packages/base/all/vendor-config-onl/src/etc/onl/config/onl-config.yml diff --git a/packages/base/all/vendor-config-onl/src/etc/onl/config/onl-config.yml b/packages/base/all/vendor-config-onl/src/etc/onl/config/onl-config.yml new file mode 100644 index 00000000..ea59fc6d --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/etc/onl/config/onl-config.yml @@ -0,0 +1,35 @@ +############################################################ +# +# ONL System Configuration +# +############################################################ + +upgrade: + onie: + auto-upgrade: advisory + loader: + auto-upgrade: advisory + versions: /etc/onl/loader/versions.json + package: + dir: /etc/onl/upgrade/$PARCH + fit_images: + - $PLATFORM.itb + - onl-loader-fit.itb + + +pki: + key: + name: key.pem + len: 2048 + cert: + name: certificate + csr: + fields: + C: US + ST: CA + O: Open Compute Project + localityName: Santa Clara + commonName: Networking + organizationalUnitName: Open Network Linux + emailAddress: support@bigswitch.com + cdays: 3600 \ No newline at end of file From 09d6ba8caedd262df6a6720b8e218744a202a002 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:38:48 +0000 Subject: [PATCH 06/87] - initmounts -> onl-mounts - pki -> onl-pki --- .../all/initrds/loader-initrd-files/src/bin/sysinit | 11 +++++++---- .../all/initrds/loader-initrd-files/src/etc/mtab.yml | 11 ++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit b/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit index 08500c6f..81d327e0 100755 --- a/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit +++ b/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit @@ -69,8 +69,11 @@ if [ ! -f /etc/onl/abort ]; then # Initialize net devices ( cd /sys/class/net; for d in *; do initnetdev $d add; done ) - # Initialize platform mounts - initmounts -q + # FS Checks + onl-mounts fsck all + + # Mounts + onl-mounts -q mount all # Initialize U-Boot environment if [ -s /proc/device-tree/model ]; then @@ -100,8 +103,8 @@ fi # # Initialize PKI # -if [ -f /sbin/pki ]; then - /sbin/pki --init +if [ -f /sbin/onl-pki ]; then + /sbin/onl-pki --init fi diff --git a/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml b/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml index 8026f979..cb7635b1 100644 --- a/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml +++ b/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml @@ -1,19 +1,20 @@ mounts: ONL-IMAGES: - mount: w + mount: rw dir: /mnt/onl/images fsck: true ONL-DATA: - mount: w + mount: rw dir: /mnt/onl/data + fsck: true ONL-CONFIG: - mount: false + mount: ro dir: /mnt/onl/config fsck: true ONL-BOOT: - mount: w + mount: rw dir: /mnt/onl/boot - fsck: false + fsck: true From 95f545bf270b0882e663d59d3b5a01903256c4db Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:39:24 +0000 Subject: [PATCH 07/87] - initmounts -> onl-mounts - pki -> onl-pki --- packages/base/all/boot.d/src/50.initmounts | 2 +- packages/base/all/boot.d/src/51.pki | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/base/all/boot.d/src/50.initmounts b/packages/base/all/boot.d/src/50.initmounts index 8aa7ca5b..71f7410f 100755 --- a/packages/base/all/boot.d/src/50.initmounts +++ b/packages/base/all/boot.d/src/50.initmounts @@ -2,5 +2,5 @@ . /lib/lsb/init-functions log_action_begin_msg "Mounting filesystems..." -initmounts -q +onl-mounts -q mount all log_action_end_msg 0 diff --git a/packages/base/all/boot.d/src/51.pki b/packages/base/all/boot.d/src/51.pki index 5752d4e9..fb153d5d 100755 --- a/packages/base/all/boot.d/src/51.pki +++ b/packages/base/all/boot.d/src/51.pki @@ -1,6 +1,6 @@ #!/bin/sh -if [ -f /usr/bin/pki ]; then - /usr/bin/pki --init +if [ -f /usr/bin/onl-pki ]; then + /usr/bin/onl-pki --init fi From 398eec8da5760b893d503747d342d4e950c03da4 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:40:00 +0000 Subject: [PATCH 08/87] Improved ONL Mount Manager - Better structured. - Clients can now use mounts in ReadOnly and ReadWrite contexts seamlessly. --- .../src/python/onl/mounts/__init__.py | 525 ++++++++++-------- 1 file changed, 283 insertions(+), 242 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py index e5d8c9d0..67e166e7 100755 --- a/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py @@ -10,49 +10,143 @@ import yaml import tempfile import shutil +class MountManager(object): + + def __init__(self, logger): + self.read_proc_mounts() + self.logger = logger + + def read_proc_mounts(self): + self.mounts = {} + with open('/proc/mounts') as mounts: + for line in mounts.readlines(): + (dev, dir_, type_, options, a, b) = line.split() + self.mounts[dir_] = dict(dev=dev, mode=options.split(',')[0]) + + def is_mounted(self, device, directory): + self.read_proc_mounts() + if directory in self.mounts and self.mounts[directory]['dev'] == device: + return self.mounts[directory] + return None + + def is_dev_mounted(self, device): + self.read_proc_mounts() + for (k, v) in self.mounts.iteritems(): + if v['dev'] == device: + return True + return False + + def mount(self, device, directory, mode='r', timeout=5): + + mountargs = [ str(mode) ] + current = self.is_mounted(device, directory) + if current: + if current['mode'] == mode: + # Already mounted as requested. + self.logger.debug("%s already mounted @ %s with mode %s. Doing nothing." % (device, directory, mode)) + return True + else: + # Already mounted, but not in the requested mode. + self.logger.debug("%s mounted @ %s with mode %s. It will be remounted %s." % (device, directory, current['mode'], mode)) + mountargs.append('remount') + else: + # Not mounted at all. + self.logger.debug("%s not mounted @ %s. It will be mounted %s" % (device, directory, mode)) + + try: + cmd = "mount -o %s %s %s" % (','.join(mountargs), device, directory) + self.logger.debug("+ %s" % cmd) + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError, e: + self.logger.error("Mount failed: '%s'" % e.output) + return False + + # If requested, wait for the mount to complete. + while(timeout > 0): + if self.is_mounted(device, directory): + break + time.sleep(1) + timeout-=1 + + current = self.is_mounted(device, directory) + if current: + self.logger.debug("%s is now mounted @ %s %s" % (device, directory, current['mode'])) + return True + else: + self.logger.error("%s failed to report in /proc/mounts." % (directory)) + + def umount(self, device, directory): + current = self.is_mounted(device, directory) + if not current: + self.logger.error("umount: %s is not mounted @ %s" % (device, directory)) + return False + + try: + out = subprocess.check_output("umount %s" % directory, shell=True) + self.logger.debug("%s @ %s has been unmounted." % (device, directory)) + self.read_proc_mounts() + return True + + except subprocess.CalledProcessError,e: + self.logger.error("Could not unmount %s @ %s: %s" % (device, directory, e.output)) + + + +class MountContext(object): + def __init__(self, device, directory, mode, logger): + self.mm = MountManager(logger) + self.device = device + self.directory = directory + self.mode = mode + + def __enter__(self): + self.status = self.mm.is_mounted(self.device, self.directory) + self.mm.mount(self.device, self.directory, self.mode) + return self + + def __exit__(self, eType, eValue, eTrace): + if self.status: + self.mm.mount(self.device, self.directory, self.status['mode']) + else: + self.mm.umount(self.device, self.directory) + + class OnlMountManager(object): - def __init__(self, mdata, logger): + def __init__(self, mdata="/etc/mtab.yml", logger=None): + self.mm = MountManager(logger) if os.path.exists(mdata): mdata = yaml.load(open(mdata, "r")); self.mdata = mdata - self.logger = logger + self.logger = logger if logger else logging.getLogger(self.__class__.__name__) # Needed to avoid ugly warnings from fsck if not os.path.exists('/etc/mtab'): - open("/etc/mtab", 'w').close(); + os.system("ln -s /proc/mounts /etc/mtab") + self.missing = None - def checkmount(self, directory): - with open("/proc/mounts") as f: - return directory in f.read() + def init(self, timeout=5): + for(k, v) in self.mdata['mounts'].iteritems(): + # + # Get the partition device for the given label. + # The timeout logic is here to handle waiting for the + # block devices to arrive at boot. + # + while timeout >= 0: + try: + v['device'] = subprocess.check_output("blkid -L %s" % k, shell=True).strip() + break + except subprocess.CalledProcessError: + self.logger.debug("Block label %s does not yet exist..." % k) + time.sleep(1) + timeout -= 1 - def mount(self, device, directory, mode='r', timeout=5): - self.logger.debug("Mounting %s -> %s %s" % (device, directory, mode)) - try: - subprocess.check_call("mount -%s %s %s" % (mode, device, directory), shell=True) - except subrocess.CalledProcessError, e: - self.logger("Mount failed: '%s'" % e.output) - return False - - # If requested, wait for the mount to complete. - while(timeout > 0): - if self.checkmount(directory): - break - time.sleep(1) - timeout-=1 - - if self.checkmount(directory): - self.logger.info("%s is now mounted @ %s" % (device, directory)) - return True - else: - self.logger.info("%s failed to report in /proc/mounts." % (directory)) - - - - def mountall(self, all_=False, fsck=None, timeout=5): - for (k, v) in self.mdata['mounts'].iteritems(): + if 'device' not in v: + self.logger.error("Timeout waiting for block label %s after %d seconds." % (k, timeout)) + self.missing = k + return False # # Make the mount point for future use. @@ -61,86 +155,164 @@ class OnlMountManager(object): self.logger.debug("Make directory '%s'..." % v['dir']) os.makedirs(v['dir']) - # - # Get the partition device. - # The timeout logic is here to handle waiting for the - # block devices to arrive at boot. - # - while timeout > 0: - try: - v['device'] = subprocess.check_output("blkid -L %s" % k, shell=True).strip() - break - except subprocess.CalledProcessError: - self.logger.debug("Block label %s does not yet exist..." % k) - time.sleep(1) - timeout -= 1 - - if 'device' not in v: - self.logger.error("Timeout waiting for block label %s after %d seconds." % (k, timeout)) - continue; - self.logger.debug("%s @ %s" % (k, v['device'])) - # - # If its currently mounted we should unmount first. - # - if self.checkmount(v['device']): - self.logger.info("%s is currently mounted." % (k)) - try: - out = subprocess.check_output("umount %s" % v['device'], shell=True) - self.logger.info("%s now unmounted." % (k)) - except subprocess.CalledProcessError,e: - self.logger.error("Could not unmount %s @ %s: %s" % (k, v['device'], e.output)) - continue - # - # FS Checks - # - if fsck is not None: - # Override fsck setting with given value - self.logger.debug("Overriding fsck settings for %s with %s" % (k, fsck)) - v['fsck'] = fsck + def __fsck(self, label, device): + self.logger.info("Running fsck on %s [ %s ]..." % (label, device)) + cmd = "fsck.ext4 -p %s" % (device) + self.logger.debug(cmd) + try: + out = subprocess.check_output(cmd, shell=True) + self.logger.info("%s [ %s ] is clean." % (device, label)) + return True + except subprocess.CalledProcessError, e: + self.logger.error("fsck failed: %s" % e.output) + return False - if v.get('fsck', False): - try: - self.logger.info("Running fsck on %s [ %s ]..." % (k, v['device'])) - cmd = "fsck.ext4 -p %s" % (v['device']) - self.logger.debug(cmd) - try: - out = subprocess.check_output(cmd, shell=True) - self.logger.info("%s [ %s ] is clean." % (v['device'], k)) - except subprocess.CalledProcessError, e: - self.logger.error("fsck failed: %s" % e.output) - except subprocess.CalledProcessError, e: - # Todo - recovery options - raise + def __label_entry(self, label, emsg=True): + if label in self.mdata['mounts']: + return self.mdata['mounts'][label] - if all_: - v['mount'] = 'w' + if emsg: + self.logger.error("Label %s does not exist." % label) - mount = v.get('mount', None) - if mount: - if mount in ['r', 'w']: - self.mount(v['device'], v['dir'], mode=mount, timeout=v.get('timeout', 5)) + return None + + def validate_labels(self, labels): + + if type(labels) is str: + labels = labels.split(',') + elif type(labels) is dict: + labels = [ labels.keys() ] + elif type(labels) is list: + pass + else: + raise ValueError("invalid labels argument.") + + if 'all' in labels: + labels = filter(lambda l: l != 'all', labels) + self.mdata['mounts'].keys() + + rv = [] + for l in list(set(labels)): + if self.__label_entry("ONL-%s" % l.upper(), False): + rv.append("ONL-%s" % l.upper()) + elif self.__label_entry(l.upper(), False): + rv.append(l.upper()) + elif self.__label_entry(l): + rv.append(l) + else: + pass + + return rv; + + def fsck(self, labels, force=False): + labels = self.validate_labels(labels) + for label in labels: + m = self.__label_entry(label) + if force or m.get('fsck', False): + if not self.mm.is_dev_mounted(m['device']): + self.__fsck(label, m['device']) else: - self.logger("Mount %s has an invalid mount mode (%s)" % (k, mount)) + self.logger.error("%s (%s) is mounted." % (label, m['device'])) + + + def mount(self, labels, mode=None): + labels = self.validate_labels(labels) + for label in labels: + m = self.__label_entry(label) + mmode = mode + if mmode is None: + mmode = m.get('mount', False) + if mmode: + self.mm.mount(m['device'], m['dir'], mmode) + + + + def umount(self, labels, all_=False): + labels = self.validate_labels(labels) + for label in labels: + m = self.__label_entry(label) + if self.mm.is_mounted(m['device'], m['dir']): + if all_ or m.get('mount', False) is False: + self.mm.umount(m['device'], m['dir']) + + + + ############################################################ + # + # CLI Support + # + ############################################################ + @staticmethod + def cmdMount(args, register=False): + if register: + p = args.add_parser('mount') + p.add_argument("labels", nargs='+', metavar='LABEL') + p.add_argument("--rw", help='Ignore the mtab setting and mount all labels read/write.', action='store_true') + p.add_argument("--ro", help='Ignore the mtab setting and mount all labels read-only.', action='store_true') + p.set_defaults(func=OnlMountManager.cmdMount) + else: + if args.rw: + mode = 'rw' + elif args.ro: + mode = 'ro' + else: + mode = None + + o = OnlMountManager(args.mtab, args.logger) + o.init() + o.mount(args.labels, mode=mode) @staticmethod - def main(): + def cmdFsck(args, register=False): + if register: + p = args.add_parser('fsck') + p.add_argument("labels", nargs='+', metavar='LABEL') + p.add_argument("--force", help='Ignore the mtab setting and run fsck on given labels.', action='store_true') + p.set_defaults(func=OnlMountManager.cmdFsck) + else: + o = OnlMountManager(args.mtab, args.logger) + o.init() + o.fsck(args.labels, args.force) + + @staticmethod + def cmdUnmount(args, register=False): + if register: + p = args.add_parser('unmount') + p.add_argument("labels", nargs='+', metavar='LABEL') + p.add_argument("--all", help="Ignore the mtab setting and unmount all labels.", action='store_true') + p.set_defaults(func=OnlMountManager.cmdUnmount) + else: + o = OnlMountManager(args.mtab, args.logger) + o.init() + o.umount(args.labels, args.all) + + @staticmethod + def initCommands(parser): + sp = parser.add_subparsers() + for attr in dir(OnlMountManager): + if attr.startswith('cmd'): + getattr(OnlMountManager, attr)(sp, register=True) + + @staticmethod + def main(name): import argparse logging.basicConfig() + logger = logging.getLogger(name) - ap = argparse.ArgumentParser(description="ONL Mount Manager."); + ap = argparse.ArgumentParser(description="ONL Mount Manager.") ap.add_argument("--mtab", default="/etc/mtab.yml") - ap.add_argument("--rw", action='store_true') - ap.add_argument("--verbose", "-v", action='store_true') + ap.add_argument("--verbose", "-m", action='store_true') ap.add_argument("--quiet", "-q", action='store_true') + OnlMountManager.initCommands(ap) + ap.set_defaults(logger=logger) + ops = ap.parse_args(); - logger = logging.getLogger("initmounts") if ops.verbose: logger.setLevel(logging.DEBUG) elif ops.quiet: @@ -148,160 +320,29 @@ class OnlMountManager(object): else: logger.setLevel(logging.INFO) - mm = OnlMountManager(ops.mtab, logger) - if ops.rw: - mm.mountall(all_=True, fsck=False) - else: - mm.mountall() + ops.func(ops) -############################################################ -# -# Fix this stuff -# -############################################################ -class ServiceMixin(object): +class OnlMountContext(MountContext): + def __init__(self, label, mode, logger): + mm = OnlMountManager() + mm.init() + labels = mm.validate_labels(label) + if not labels: + raise ValueError("Label '%s' doesn't exist." % label) + MountContext.__init__(self, + mm.mdata['mounts'][labels[0]]['device'], + mm.mdata['mounts'][labels[0]]['dir'], + mode, + logger) - def _execute(self, cmd, root=False, ex=True): - self.logger.debug("Executing: %s" % cmd) - if root is True and os.getuid() != 0: - cmd = "sudo " + cmd - try: - subprocess.check_call(cmd, shell=True) - except Exception, e: - if ex: - self.logger.error("Command failed: %s" % e) - raise - else: - return e.returncode - - def _raise(self, msg, klass): - self.logger.critical(msg) - raise klass(msg) - -class DataMount(ServiceMixin): - - def __init__(self, partition, logger=None): - self.partition = partition - self.logger = logger - - self.mountpoint = None - self.mounted = False - - if os.path.isabs(partition) and not os.path.exists(partition): - # Implicitly a bind mount. It may not exist yet, so create it - os.makedirs(partition) - - if os.path.exists(partition): - # Bind mount - self.device = None - else: - self.device = subprocess.check_output("blkid | grep %s | awk '{print $1}' | tr -d ':'" % self.partition, shell=True).strip() - if self.device is None or len(self.device) is 0: - self._raise("Data partition %s does not exist." % self.partition, - RuntimeError) - self.logger.debug("device is %s" % self.device) - - def _mount(self): - if self.device: - self._execute("mount %s %s" % (self.device, self.mountdir()), root=True) - else: - self._execute("mount --bind %s %s" % (self.partition, - self.mountdir()), root=True) - self.mounted = True - - def _umount(self): - mounted, self.mounted = self.mounted, False - if mounted: - self._execute("umount %s" % self.mountpoint, root=True) - mountpoint, self.mountpoint = self.mountpoint, None - if mountpoint and os.path.exists(mountpoint): - self.logger.debug("+ /bin/rmdir %s", mountpoint) - os.rmdir(mountpoint) - - def __enter__(self): - self._mount() - return self - - def __exit__(self, type_, value, traceback): - self._umount() - - def mountdir(self): - if self.mountpoint is None: - self.mountpoint = tempfile.mkdtemp(prefix="pki-", suffix=".d") - self.logger.debug("mountpoint is %s" % self.mountpoint) - return self.mountpoint +class OnlMountContextReadOnly(OnlMountContext): + def __init__(self, label, logger): + OnlMountContext.__init__(self, label, "ro", logger) -class OnlDataStore(ServiceMixin): - - # Data partition containing the persistant store - DATA_PARTITION='ONL-CONFIG' - - # Persistant directory on DATA_PARTITION - P_DIR=None - - # Runtime directory in the root filesystem - R_DIR=None - - def __init__(self, logger=None): - - if logger is None: - logging.basicConfig() - logger = logging.getLogger(str(self.__class__)) - logger.setLevel(logging.WARN) - - self.logger = logger - - self.mount = DataMount(self.DATA_PARTITION, logger=self.logger) - - if self.P_DIR is None: - raise AttributeError("P_DIR must be set in the derived class.") - - if self.R_DIR is None: - raise ValueError("R_DIR must be set in the derived class.") - - # The R_DIR is accessed here - self.r_dir = self.R_DIR - - self.logger.debug("persistant dir: %s" % self.p_dir) - self.logger.debug(" runtime dir: %s" % self.r_dir) - - @property - def p_dir(self): - return os.path.join(self.mount.mountdir(), self.P_DIR) - - def _sync_dir(self, src, dst): - self.logger.debug("Syncing store from %s -> %s" % (src, dst)) - if os.path.exists(dst): - shutil.rmtree(dst) - - if not os.path.exists(src): - os.makedirs(src) - - shutil.copytree(src, dst) - - def init_runtime(self): - with self.mount: - self._sync_dir(self.p_dir, self.r_dir) - - def commit_runtime(self): - with self.mount: - self._sync_dir(self.r_dir, self.p_dir) - - def diff(self): - with self.mount: - rv = self._execute("diff -rNq %s %s" % (self.p_dir, self.r_dir), ex=False) - return rv == 0 - - def ls(self): - with self.mount: - self._execute("cd %s && find ." % (self.p_dir)) - - def rm(self, filename): - with self.mount: - os.unlink(os.path.join(self.p_dir, filename)) - os.unlink(os.path.join(r_dir, filename)) - +class OnlMountContextReadWrite(OnlMountContext): + def __init__(self, label, logger): + OnlMountContext.__init__(self, label, "rw", logger) From a2c1a57b5e7a404d1476f8e2134878611b7bf8f4 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:41:51 +0000 Subject: [PATCH 09/87] Renamed to onl-* --- packages/base/all/vendor-config-onl/src/bin/onl-mounts | 3 +++ packages/base/all/vendor-config-onl/src/bin/onl-pki | 3 +++ 2 files changed, 6 insertions(+) create mode 100755 packages/base/all/vendor-config-onl/src/bin/onl-mounts create mode 100755 packages/base/all/vendor-config-onl/src/bin/onl-pki diff --git a/packages/base/all/vendor-config-onl/src/bin/onl-mounts b/packages/base/all/vendor-config-onl/src/bin/onl-mounts new file mode 100755 index 00000000..dca2046b --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/bin/onl-mounts @@ -0,0 +1,3 @@ +#!/usr/bin/python +from onl.mounts import OnlMountManager +OnlMountManager.main('onl-mounts') diff --git a/packages/base/all/vendor-config-onl/src/bin/onl-pki b/packages/base/all/vendor-config-onl/src/bin/onl-pki new file mode 100755 index 00000000..bd8463ff --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/bin/onl-pki @@ -0,0 +1,3 @@ +#!/usr/bin/python +from onl.pki import OnlPki +OnlPki.main() From 96c9f612b84d22ae26fc5cd348a0a0ed35d0973e Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:42:13 +0000 Subject: [PATCH 10/87] - Use the new sysconfig interface for upgrade properties. - Use the new OnlMountContext managers. --- .../src/boot.d/62.upgrade-loader | 90 ++++++------------- 1 file changed, 25 insertions(+), 65 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 12b2716a..f7111744 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 @@ -8,6 +8,8 @@ import os import sys import fnmatch from onl.upgrade import ubase +from onl.sysconfig import sysconfig +from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite class Loader_Upgrade(ubase.BaseUpgrade): name="loader" @@ -19,14 +21,16 @@ class Loader_Upgrade(ubase.BaseUpgrade): 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" + ETC_LOADER_VERSIONS_JSON = sysconfig.upgrade.loader.versions # Upgrade Loader Version file. - NEXT_LOADER_VERSIONS_JSON = "/etc/onl/upgrade/%s/manifest.json" % self.parch + NEXT_LOADER_VERSIONS_JSON = os.path.join(sysconfig.upgrade.loader.package.dir, "manifest.json") + self.current_version = self.load_json(ETC_LOADER_VERSIONS_JSON, "RELEASE_ID", @@ -51,89 +55,45 @@ class Loader_Upgrade_FIT(Loader_Upgrade): def do_upgrade(self, forced=False): - FIT_UPGRADE_IMAGE_PLATFORM="/etc/onl/upgrade/%s/%s.itb" % (self.parch, self.platform.platform()) - FIT_UPGRADE_IMAGE_ALL="/etc/onl/upgrade/%s/onl-loader-fit.itb" % (self.parch) - FIT_LOADER_IMAGE_NAME="%s.itb" % self.platform.platform() - fit_image = None + for f in sysconfig.upgrade.loader.package.fit_images: + fp = os.path.join(sysconfig.upgrade.loader.package.dir, f) + if os.path.exists(fp): + fit_image = fp; + break - if os.path.exists(FIT_UPGRADE_IMAGE_PLATFORM): - fit_image = FIT_UPGRADE_IMAGE_PLATFORM - elif os.path.exists(FIT_UPGRADE_IMAGE_ALL): - fit_image = FIT_UPGRADE_IMAGE_ALL - else: + if fit_image is None: self.abort("The FIT upgrade image is missing. Upgrade cannot continue.") - # - # The platform configuration file will describe which partition - # and which format should be used to store the FIT image. - # - partition = None - raw = False - pc = self.platform.platform_config + with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d: + self.copyfile(fit_image, os.path.join(d.directory, "%s.itb" % (self.platform.platform()))) - 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=%s if=%s" % (partition, fit_image)) != 0: - self.abort("Failure writing loader data to partition %s." % (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, FIT_LOADER_IMAGE_NAME)) - self.umount(mdir) - - self.reboot() + #self.reboot() class Loader_Upgrade_x86_64(Loader_Upgrade): def do_upgrade(self, forced=False): - X86_64_UPGRADE_DIR="/etc/onl/upgrade/%s/" % (self.parch) + X86_64_UPGRADE_DIR=sysconfig.upgrade.loader.package.dir X86_64_UPGRADE_PATTERNS = [ "kernel-*", "initrd-*" ] - # - # Mount the ONL-BOOT partition - # - mdir="/mnt/onl-boot" - self.mount(mdir, label="ONL-BOOT") + with OnlMountContext("ONL-BOOT", "rw", self.logger) as d: + for f in os.listdir(X86_64_UPGRADE_DIR): + for pattern in X86_64_UPGRADE_PATTERNS: + if fnmatch.fnmatch(f, pattern): + self.copyfile(os.path.join(X86_64_UPGRADE_DIR, f), os.path.join(d.directory, f)) - for f in os.listdir(X86_64_UPGRADE_DIR): - for pattern in X86_64_UPGRADE_PATTERNS: - if fnmatch.fnmatch(f, pattern): - self.copyfile(os.path.join(X86_64_UPGRADE_DIR, f), os.path.join(mdir, f)) + src = "/lib/platform-config/current/onl/boot/grub.cfg" + dst = os.path.join(d.directory, "grub/grub.cfg") + if os.path.exists(src): + self.copyfile(src, dst) - 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 From d0e96743da80341fe410a4eba00ca8fdfd1d479c Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:44:40 +0000 Subject: [PATCH 11/87] PKI Now implemented as part of the OnlMountContext for ONL-CONFIG. --- .../src/python/onl/pki/__init__.py | 127 +++++++----------- 1 file changed, 48 insertions(+), 79 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py index 2f8dd157..ad96778e 100755 --- a/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py @@ -13,83 +13,69 @@ import shutil import subprocess import tempfile import yaml +from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite +from onl.sysconfig import sysconfig +from onl.util import * -from onl.mounts import OnlDataStore +class OnlPki(OnlServiceMixin): + """Initialize the ONL-CONFIG::PKI credentials.""" -class OnlPKI(OnlDataStore): - P_DIR='private' - R_DIR='/private' + CONFIG_PKI_DIR="/mnt/onl/config/pki" - PRIVATE_KEY='key.pem' - CERTIFICATE='certificate' + def __init__(self, logger): + self.logger = logger + self.kpath = os.path.join(self.CONFIG_PKI_DIR, + sysconfig.pki.key.name) - KLEN=2048 - CDAYS=3650 - - CSR_FILE='/etc/onl/config/csr.yml' - - def __init__(self, logger=None): - OnlDataStore.__init__(self, logger) - self.kpath = os.path.join(self.R_DIR, self.PRIVATE_KEY) - self.cpath = os.path.join(self.R_DIR, self.CERTIFICATE) - - def init_cert(self, force=False): - if not os.path.exists(self.cpath) or force: - self.logger.info("Generating self-signed certificate...") - - # - # The csr.yml file allows the system integrator to customize - # the fields for the certificate. - # - fdict = {} - try: - fdict = yaml.load(open(self.CSR_FILE)) - except Exception, e: - self.logger.error(e); - - csr = tempfile.NamedTemporaryFile(prefix="pki-", suffix=".csr", delete=False) - csr.close() - - fields = [ "%s=%s" % (k, v) for k,v in fdict.iteritems() ] - subject = "/" + "/".join(fields) - self.logger.debug("Subject: '%s'", subject) - self.logger.debug("CSR: %s", csr.name) - self._execute("""openssl req -new -batch -subj "%s" -key %s -out %s""" % ( - subject, self.kpath, csr.name)) - self._execute("""openssl x509 -req -days %s -in %s -signkey %s -out %s""" % ( - self.CDAYS, - csr.name, self.kpath, self.cpath)) - os.unlink(csr.name) - else: - self.logger.info("Using existing certificate.") + self.cpath = os.path.join(self.CONFIG_PKI_DIR, + sysconfig.pki.cert.name) def init_key(self, force=False): - if not os.path.exists(self.kpath) or force: - self.logger.info("Generating private key...") - cmd = "openssl genrsa -out %s %s" % (self.kpath, self.KLEN) - self._execute(cmd) - self.init_cert(force=True) - else: - self.logger.info("Using existing private key.") + with OnlMountContextReadOnly("ONL-CONFIG", self.logger): + if not os.path.exists(self.kpath) or force: + self.logger.info("Generating private key...") + cmd = "openssl genrsa -out %s %s" % (self.kpath, sysconfig.pki.key.len) + with OnlMountContextReadWrite("ONL-CONFIG", self.logger): + if not os.path.isdir(self.CONFIG_PKI_DIR): + os.makedirs(self.CONFIG_PKI_DIR) + self._execute(cmd) + self.init_cert(force=True) + else: + self.logger.info("Using existing private key.") + + def init_cert(self, force=False): + with OnlMountContextReadOnly("ONL-CONFIG", self.logger): + if not os.path.exists(self.cpath) or force: + self.logger.info("Generating self-signed certificate...") + csr = tempfile.NamedTemporaryFile(prefix="pki-", suffix=".csr", delete=False) + csr.close() + fields = [ "%s=%s" % (k, v) for k,v in sysconfig.pki.cert.csr.fields.iteritems() ] + subject = "/" + "/".join(fields) + self.logger.debug("Subject: '%s'", subject) + self.logger.debug("CSR: %s", csr.name) + with OnlMountContextReadWrite("ONL-CONFIG", self.logger): + if not os.path.isdir(self.CONFIG_PKI_DIR): + os.makedirs(self.CONFIG_PKI_DIR) + self._execute("""openssl req -new -batch -subj "%s" -key %s -out %s""" % ( + subject, self.kpath, csr.name)) + self._execute("""openssl x509 -req -days %s -in %s -signkey %s -out %s""" % ( + sysconfig.pki.cert.csr.cdays, + csr.name, self.kpath, self.cpath)) + os.unlink(csr.name) + else: + self.logger.info("Using existing certificate.") + - def init(self, force=False): - self.init_key(force=force) - self.init_cert(force=force) - self.commit_runtime() @staticmethod def main(): ap = argparse.ArgumentParser(description="ONL PKI Management") - ap.add_argument("--init", action='store_true', help="Initialize /private and PKI files if necessary.") + ap.add_argument("--init", action='store_true', help="Initialize PKI files (if necessary)") ap.add_argument("--regen-cert", action='store_true', help="Regenerate certificate.") ap.add_argument("--force", "-f", action='store_true', help="Force regeneration of the key and certificate during initialization (--init)") - ap.add_argument("--commit", action='store_true', help="Commit the runtime /private directory to the persistant storage.") - ap.add_argument("--ls", action='store_true', help="List contents of the peristant directory.") ap.add_argument("--quiet", "-q", action='store_true', help="Quiet output.") ap.add_argument("--verbose", "-v", action='store_true', help="Verbose output.") - ap.add_argument("--part", help='Override Data Partition (testing only).') - ap.add_argument("--rd", help='Override /private runtime directory (testing only)') ops = ap.parse_args() @@ -103,27 +89,10 @@ class OnlPKI(OnlDataStore): else: logger.setLevel(logging.INFO) - if ops.part: - OnlPKI.DATA_PARTITION=ops.part - - if ops.rd: - OnlPKI.R_DIR=ops.rd - - pki = OnlPKI(logger) + pki = OnlPki(logger) if ops.init: - pki.init_runtime() pki.init_key(force=ops.force) pki.init_cert(force=ops.force) - pki.commit_runtime() - elif ops.regen_cert: pki.init_cert(force=True) - pki.commit_runtime() - - elif ops.commit: - pki.commit_runtime() - elif ops.ls: - pki.ls() - else: - pki.diff() From a6520e533c52b7caf3410d8c83637060a7adaed1 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:45:23 +0000 Subject: [PATCH 12/87] - Add onlyaml to the package for use in the runtime - Cleanup deprecated files - Add default sysconfig. --- packages/base/all/vendor-config-onl/PKG.yml | 23 +++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/base/all/vendor-config-onl/PKG.yml b/packages/base/all/vendor-config-onl/PKG.yml index 32109df3..4c641ae4 100644 --- a/packages/base/all/vendor-config-onl/PKG.yml +++ b/packages/base/all/vendor-config-onl/PKG.yml @@ -8,10 +8,13 @@ packages: summary: ONL Base Configuration Package files: - src/python/onl : $PY_INSTALL/onl - src/boot.d : /etc/boot.d - src/bin : /usr/bin - src/lib : /lib/vendor-config/onl + - src/python/onl : $PY_INSTALL/onl + - $ONL/tools/onlyaml.py : $PY_INSTALL/onl/onlyaml/__init__.py + - src/etc : /etc + - src/boot.d : /etc/boot.d + - src/bin : /usr/bin + - src/lib : /lib/vendor-config/onl + changelog: Changes @@ -24,10 +27,12 @@ packages: summary: ONL Base Configuration Package (Loader) files: - src/python/onl : $PY_INSTALL/onl - src/bin/initmounts : /bin/initmounts - src/bin/initubootenv : /bin/initubootenv - src/bin/initnetdev : /bin/initnetdev - src/bin/pki : /sbin/pki + - src/python/onl : $PY_INSTALL/onl + - $ONL/tools/onlyaml.py : $PY_INSTALL/onl/onlyaml/__init__.py + - src/etc : /etc + - src/bin/onl-mounts : /bin/onl-mounts + - src/bin/initubootenv : /bin/initubootenv + - src/bin/initnetdev : /bin/initnetdev + - src/bin/onl-pki : /sbin/onl-pki changelog: Changes From b03cc37db0ca2f28d8797b160db3199a4cd9854a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:46:53 +0000 Subject: [PATCH 13/87] Upgrade organization improvements. --- .../all/vendor-config-onl/src/bin/initmounts | 3 -- .../base/all/vendor-config-onl/src/bin/pki | 3 -- .../src/python/onl/upgrade/ubase.py | 30 ++++--------------- 3 files changed, 5 insertions(+), 31 deletions(-) delete mode 100755 packages/base/all/vendor-config-onl/src/bin/initmounts delete mode 100755 packages/base/all/vendor-config-onl/src/bin/pki diff --git a/packages/base/all/vendor-config-onl/src/bin/initmounts b/packages/base/all/vendor-config-onl/src/bin/initmounts deleted file mode 100755 index a2ccaecd..00000000 --- a/packages/base/all/vendor-config-onl/src/bin/initmounts +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/python -from onl.mounts import OnlMountManager -OnlMountManager.main() diff --git a/packages/base/all/vendor-config-onl/src/bin/pki b/packages/base/all/vendor-config-onl/src/bin/pki deleted file mode 100755 index eb5105a8..00000000 --- a/packages/base/all/vendor-config-onl/src/bin/pki +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/python -from onl.pki import OnlPKI -OnlPKI.main() 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 aacffaa8..4c7784b7 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 @@ -13,6 +13,7 @@ import shutil import json import string import argparse +import yaml from time import sleep from onl.platform.current import OnlPlatform @@ -36,32 +37,11 @@ class BaseUpgrade(object): self.arch = pp.machine() self.parch = dict(ppc='powerpc', x86_64='amd64', armv7l='armel')[self.arch] self.platform = OnlPlatform() + self.init() + + def init(self): + pass - # - # 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 From c5de27cc3a5e020aaf21329064c86375f5ae9f72 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:47:53 +0000 Subject: [PATCH 14/87] RFS Manifest updates. --- builds/any/rootfs/wheezy/standard/standard.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/builds/any/rootfs/wheezy/standard/standard.yml b/builds/any/rootfs/wheezy/standard/standard.yml index 1ba7a3d4..4f6d1491 100644 --- a/builds/any/rootfs/wheezy/standard/standard.yml +++ b/builds/any/rootfs/wheezy/standard/standard.yml @@ -90,6 +90,7 @@ Configure: root: password: onl - manifest: - version: $ONL/make/versions/version-onl.json - platforms: $PLATFORM_LIST + manifests: + '/etc/onl/rootfs/manifest.json' : + version : $ONL/make/versions/version-onl.json + platforms : $PLATFORM_LIST From 8f8109c298429a96e8c5f5fe66850995ec20a853 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 27 May 2016 19:48:02 +0000 Subject: [PATCH 15/87] Update mount settings. --- builds/any/rootfs/jessie/common/overlay/etc/mtab.yml | 8 ++++---- builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml b/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml index e6c3ab22..598e4c69 100644 --- a/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml +++ b/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml @@ -1,19 +1,19 @@ mounts: ONL-IMAGES: - mount: r + mount: ro dir: /mnt/onl/images fsck: true ONL-DATA: - mount: w + mount: rw dir: /mnt/onl/data ONL-CONFIG: - mount: false + mount: ro dir: /mnt/onl/config fsck: true ONL-BOOT: - mount: false + mount: ro dir: /mnt/onl/boot fsck: false diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml b/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml index e6c3ab22..51ca0f49 100644 --- a/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml +++ b/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml @@ -1,11 +1,11 @@ mounts: ONL-IMAGES: - mount: r + mount: ro dir: /mnt/onl/images fsck: true ONL-DATA: - mount: w + mount: rw dir: /mnt/onl/data ONL-CONFIG: @@ -14,6 +14,6 @@ mounts: fsck: true ONL-BOOT: - mount: false + mount: ro dir: /mnt/onl/boot fsck: false From 24cf1f780ef21a15d2853515b271a192e874c8c4 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 1 Jun 2016 22:13:44 +0000 Subject: [PATCH 16/87] Separate base system packages from ONL RFS specific packages. - This allows the base package files to be shared with superprojects which won't use things like the upgrade packages. --- .../{common-packages.yml => all-base-packages.yml} | 0 .../{amd64-packages.yml => amd64-base-packages.yml} | 0 .../any/rootfs/jessie/common/amd64-onl-packages.yml | 11 +++++++++++ .../{armel-packages.yml => armel-base-packages.yml} | 0 .../any/rootfs/jessie/common/armel-onl-packages.yml | 9 +++++++++ ...powerpc-packages.yml => powerpc-base-packages.yml} | 0 .../any/rootfs/jessie/common/powerpc-onl-packages.yml | 9 +++++++++ builds/any/rootfs/jessie/standard/standard.yml | 5 +++-- .../{common-packages.yml => all-base-packages.yml} | 0 .../{amd64-packages.yml => amd64-base-packages.yml} | 0 .../any/rootfs/wheezy/common/amd64-onl-packages.yml | 11 +++++++++++ ...powerpc-packages.yml => powerpc-base-packages.yml} | 0 .../any/rootfs/wheezy/common/powerpc-onl-packages.yml | 9 +++++++++ builds/any/rootfs/wheezy/standard/standard.yml | 5 +++-- 14 files changed, 55 insertions(+), 4 deletions(-) rename builds/any/rootfs/jessie/common/{common-packages.yml => all-base-packages.yml} (100%) rename builds/any/rootfs/jessie/common/{amd64-packages.yml => amd64-base-packages.yml} (100%) create mode 100644 builds/any/rootfs/jessie/common/amd64-onl-packages.yml rename builds/any/rootfs/jessie/common/{armel-packages.yml => armel-base-packages.yml} (100%) create mode 100644 builds/any/rootfs/jessie/common/armel-onl-packages.yml rename builds/any/rootfs/jessie/common/{powerpc-packages.yml => powerpc-base-packages.yml} (100%) create mode 100644 builds/any/rootfs/jessie/common/powerpc-onl-packages.yml rename builds/any/rootfs/wheezy/common/{common-packages.yml => all-base-packages.yml} (100%) rename builds/any/rootfs/wheezy/common/{amd64-packages.yml => amd64-base-packages.yml} (100%) create mode 100644 builds/any/rootfs/wheezy/common/amd64-onl-packages.yml rename builds/any/rootfs/wheezy/common/{powerpc-packages.yml => powerpc-base-packages.yml} (100%) create mode 100644 builds/any/rootfs/wheezy/common/powerpc-onl-packages.yml diff --git a/builds/any/rootfs/jessie/common/common-packages.yml b/builds/any/rootfs/jessie/common/all-base-packages.yml similarity index 100% rename from builds/any/rootfs/jessie/common/common-packages.yml rename to builds/any/rootfs/jessie/common/all-base-packages.yml diff --git a/builds/any/rootfs/jessie/common/amd64-packages.yml b/builds/any/rootfs/jessie/common/amd64-base-packages.yml similarity index 100% rename from builds/any/rootfs/jessie/common/amd64-packages.yml rename to builds/any/rootfs/jessie/common/amd64-base-packages.yml diff --git a/builds/any/rootfs/jessie/common/amd64-onl-packages.yml b/builds/any/rootfs/jessie/common/amd64-onl-packages.yml new file mode 100644 index 00000000..984f2fc3 --- /dev/null +++ b/builds/any/rootfs/jessie/common/amd64-onl-packages.yml @@ -0,0 +1,11 @@ +############################################################ +# +# These packages are specific to the ONL root filesystem build. +# +############################################################ +- onl-upgrade + + + + + diff --git a/builds/any/rootfs/jessie/common/armel-packages.yml b/builds/any/rootfs/jessie/common/armel-base-packages.yml similarity index 100% rename from builds/any/rootfs/jessie/common/armel-packages.yml rename to builds/any/rootfs/jessie/common/armel-base-packages.yml diff --git a/builds/any/rootfs/jessie/common/armel-onl-packages.yml b/builds/any/rootfs/jessie/common/armel-onl-packages.yml new file mode 100644 index 00000000..e58df638 --- /dev/null +++ b/builds/any/rootfs/jessie/common/armel-onl-packages.yml @@ -0,0 +1,9 @@ +############################################################ +# +# These packages are specific to the ONL root filesystem build. +# +############################################################ +- onl-loader-fit + + + diff --git a/builds/any/rootfs/jessie/common/powerpc-packages.yml b/builds/any/rootfs/jessie/common/powerpc-base-packages.yml similarity index 100% rename from builds/any/rootfs/jessie/common/powerpc-packages.yml rename to builds/any/rootfs/jessie/common/powerpc-base-packages.yml diff --git a/builds/any/rootfs/jessie/common/powerpc-onl-packages.yml b/builds/any/rootfs/jessie/common/powerpc-onl-packages.yml new file mode 100644 index 00000000..e58df638 --- /dev/null +++ b/builds/any/rootfs/jessie/common/powerpc-onl-packages.yml @@ -0,0 +1,9 @@ +############################################################ +# +# These packages are specific to the ONL root filesystem build. +# +############################################################ +- onl-loader-fit + + + diff --git a/builds/any/rootfs/jessie/standard/standard.yml b/builds/any/rootfs/jessie/standard/standard.yml index c3b22d8e..ff1e4208 100644 --- a/builds/any/rootfs/jessie/standard/standard.yml +++ b/builds/any/rootfs/jessie/standard/standard.yml @@ -8,8 +8,9 @@ # ############################################################ Packages: &Packages - - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/common-packages.yml - - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-packages.yml + - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/all-base-packages.yml + - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-base-packages.yml + - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-onl-packages.yml - !script $ONL/tools/onl-platform-pkgs.py ${PLATFORM_LIST} Multistrap: diff --git a/builds/any/rootfs/wheezy/common/common-packages.yml b/builds/any/rootfs/wheezy/common/all-base-packages.yml similarity index 100% rename from builds/any/rootfs/wheezy/common/common-packages.yml rename to builds/any/rootfs/wheezy/common/all-base-packages.yml diff --git a/builds/any/rootfs/wheezy/common/amd64-packages.yml b/builds/any/rootfs/wheezy/common/amd64-base-packages.yml similarity index 100% rename from builds/any/rootfs/wheezy/common/amd64-packages.yml rename to builds/any/rootfs/wheezy/common/amd64-base-packages.yml diff --git a/builds/any/rootfs/wheezy/common/amd64-onl-packages.yml b/builds/any/rootfs/wheezy/common/amd64-onl-packages.yml new file mode 100644 index 00000000..984f2fc3 --- /dev/null +++ b/builds/any/rootfs/wheezy/common/amd64-onl-packages.yml @@ -0,0 +1,11 @@ +############################################################ +# +# These packages are specific to the ONL root filesystem build. +# +############################################################ +- onl-upgrade + + + + + diff --git a/builds/any/rootfs/wheezy/common/powerpc-packages.yml b/builds/any/rootfs/wheezy/common/powerpc-base-packages.yml similarity index 100% rename from builds/any/rootfs/wheezy/common/powerpc-packages.yml rename to builds/any/rootfs/wheezy/common/powerpc-base-packages.yml diff --git a/builds/any/rootfs/wheezy/common/powerpc-onl-packages.yml b/builds/any/rootfs/wheezy/common/powerpc-onl-packages.yml new file mode 100644 index 00000000..e58df638 --- /dev/null +++ b/builds/any/rootfs/wheezy/common/powerpc-onl-packages.yml @@ -0,0 +1,9 @@ +############################################################ +# +# These packages are specific to the ONL root filesystem build. +# +############################################################ +- onl-loader-fit + + + diff --git a/builds/any/rootfs/wheezy/standard/standard.yml b/builds/any/rootfs/wheezy/standard/standard.yml index 4f6d1491..e7ca7cb7 100644 --- a/builds/any/rootfs/wheezy/standard/standard.yml +++ b/builds/any/rootfs/wheezy/standard/standard.yml @@ -8,8 +8,9 @@ # ############################################################ Packages: &Packages - - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/common-packages.yml - - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-packages.yml + - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/all-base-packages.yml + - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-base-packages.yml + - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-onl-packages.yml - !script $ONL/tools/onl-platform-pkgs.py ${PLATFORM_LIST} Multistrap: From f0f6fd88bbcb02117ee50523cd9aabb88344446c Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 1 Jun 2016 22:24:15 +0000 Subject: [PATCH 17/87] Upgrade packages only. --- builds/any/rootfs/jessie/common/armel-base-packages.yml | 1 - builds/any/rootfs/jessie/common/powerpc-base-packages.yml | 2 +- builds/any/rootfs/wheezy/common/powerpc-base-packages.yml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/builds/any/rootfs/jessie/common/armel-base-packages.yml b/builds/any/rootfs/jessie/common/armel-base-packages.yml index edd63d6f..71c41a67 100644 --- a/builds/any/rootfs/jessie/common/armel-base-packages.yml +++ b/builds/any/rootfs/jessie/common/armel-base-packages.yml @@ -1,2 +1 @@ - u-boot-tools -- onl-loader-fit diff --git a/builds/any/rootfs/jessie/common/powerpc-base-packages.yml b/builds/any/rootfs/jessie/common/powerpc-base-packages.yml index e55a7d8b..e876f6bd 100644 --- a/builds/any/rootfs/jessie/common/powerpc-base-packages.yml +++ b/builds/any/rootfs/jessie/common/powerpc-base-packages.yml @@ -4,7 +4,7 @@ # ############################################################ - u-boot-tools -- onl-loader-fit + diff --git a/builds/any/rootfs/wheezy/common/powerpc-base-packages.yml b/builds/any/rootfs/wheezy/common/powerpc-base-packages.yml index 0f9eb5bc..618f3581 100644 --- a/builds/any/rootfs/wheezy/common/powerpc-base-packages.yml +++ b/builds/any/rootfs/wheezy/common/powerpc-base-packages.yml @@ -4,7 +4,7 @@ # ############################################################ - u-boot-tools -- onl-loader-fit + From 2afb37ce01d55751d9e86992707ace779bd2c849 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 2 Jun 2016 01:22:05 +0000 Subject: [PATCH 18/87] Custom file and /etc/issue* generation. --- tools/onlrfs.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/onlrfs.py b/tools/onlrfs.py index 9875f1a4..be985bec 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -411,6 +411,33 @@ rm -f /usr/sbin/policy-rc.d json.dump(md, f, indent=2) onlu.execute("sudo chmod a-w %s" % mname) + for (fname, v) in Configure.get('files', {}).iteritems(): + if fname.startswith('/'): + fname = fname[1:] + dst = os.path.join(dir_, fname) + onlu.execute("sudo mkdir -p %s" % os.path.dirname(dst)) + onlu.execute("sudo touch %s" % dst) + onlu.execute("sudo chmod a+w %s" % dst) + if os.path.exists(v): + shutil.copy(v, dst) + else: + with open(dst, "w") as f: + f.write("%s\n" % v) + + if Configure.get('issue'): + issue = Configure.get('issue') + fn = os.path.join(dir_, "etc/issue") + onlu.execute("sudo chmod a+w %s" % fn) + with open(fn, "w") as f: + f.write("%s\n" % issue) + onlu.execute("sudo chmod a-w %s" % fn) + + fn = os.path.join(dir_, "etc/issue.net") + onlu.execute("sudo chmod a+w %s" % fn) + with open(fn, "w") as f: + f.write("%s" % issue) + onlu.execute("sudo chmod a-w %s" % fn) + finally: onlu.execute("sudo umount -l %s %s" % (os.path.join(dir_, "dev"), os.path.join(dir_, "proc"))) From 08267c2cde39709cbc05c7ab43db69144992008a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 2 Jun 2016 01:22:27 +0000 Subject: [PATCH 19/87] Set /etc/issue* to ONL version string. --- builds/any/rootfs/wheezy/standard/standard.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builds/any/rootfs/wheezy/standard/standard.yml b/builds/any/rootfs/wheezy/standard/standard.yml index e7ca7cb7..6bd5fbbf 100644 --- a/builds/any/rootfs/wheezy/standard/standard.yml +++ b/builds/any/rootfs/wheezy/standard/standard.yml @@ -7,6 +7,9 @@ # # ############################################################ +variables: + !include $ONL/make/versions/version-onl.yml + Packages: &Packages - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/all-base-packages.yml - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-base-packages.yml @@ -95,3 +98,5 @@ Configure: '/etc/onl/rootfs/manifest.json' : version : $ONL/make/versions/version-onl.json platforms : $PLATFORM_LIST + + issue: $VERSION_STRING From d2f0cf340d89a7fd63832715558c65e856ab0962 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 2 Jun 2016 19:33:12 +0000 Subject: [PATCH 20/87] Add generic dictionary merge routine. - Poached from YamlUtils. - YamlUtils should be updated to use this as the base merge routine. --- .../src/python/onl/util/__init__.py | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py index 0a96d689..c085b3f2 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/util/__init__.py @@ -18,3 +18,74 @@ class OnlServiceMixin(object): self.logger.critical(msg) raise klass(msg) + +def dmerge(d1, d2): + """ + dictionary merge. + + d1 is the default source. Leaf values from d2 will override. + + d1 is the 'default' source; leaf values from d2 will override. + Returns the merged tree. + + Set a leaf in d2 to None to create a tombstone (discard any key + from d1). + + if a (sub) key in d1, d2 differ in type (dict vs. non-dict) then + the merge will proceed with the non-dict promoted to a dict using + the default-key schema ('='). Consumers of this function should be + prepared to handle such keys. + """ + merged = {} + q = [(d1, d2, merged)] + while True: + if not q: break + c1, c2, c3 = q.pop(0) + # add in non-overlapping keys + # 'None' keys from p2 are tombstones + s1 = set(c1.keys()) + s2 = set(c2.keys()) + + for k in s1.difference(s2): + v = c1[k] + if type(v) == dict: + c3.setdefault(k, {}) + q.append((v, {}, c3[k],)) + else: + c3.setdefault(k, v) + + for k in s2.difference(s1): + v = c2[k] + if v is None: continue + if type(v) == dict: + c3.setdefault(k, {}) + q.append(({}, v, c3[k],)) + else: + c3.setdefault(k, v) + + # handle overlapping keys + for k in s1.intersection(s2): + v1 = c1[k] + v2 = c2[k] + + if v2 is None: continue + + # two dicts, key-by-key reconciliation required + if type(v1) == dict and type(v2) == dict: + c3.setdefault(k, {}) + q.append((v1, v2, c3[k],)) + continue + + # two non-dicts, p2 wins + if type(v1) != dict and type(v2) != dict: + c3[k] = v2 + continue + + if type(v1) != dict: + v1 = { '=' : v1, } + if type(v2) != dict: + v2 = { '=' : v2, } + c3.setdefault(k, {}) + q.append((v1, v2, c3[k],)) + + return merged From f34662cb60701d40ba4e4a28f36df7c8732fc53e Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 2 Jun 2016 19:34:18 +0000 Subject: [PATCH 21/87] The system configuration is now a heirarchical merge of the sorted files in /etc/onl/config. The only required file is the existing 00-defaults.yml --- .../src/python/onl/sysconfig/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py index b67f2420..9be682b0 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py @@ -8,6 +8,7 @@ import sys import yaml import types import onl.onlyaml +import onl.util import platform as pp from onl.platform.current import OnlPlatform @@ -43,12 +44,10 @@ class OnlSystemConfig(object): armv7l='armel')[pp.machine()] self.config = {} - - for root, dirs, files in os.walk(self.SYSTEM_CONFIG_DIR): - for f in files: - if f.endswith('.yml'): - d = onl.onlyaml.loadf(os.path.join(root, f), self.variables) - self.config.update(d) + for f in sorted(os.listdir(self.SYSTEM_CONFIG_DIR)): + if f.endswith('.yml'): + d = onl.onlyaml.loadf(os.path.join(self.SYSTEM_CONFIG_DIR, f), self.variables) + self.config = onl.util.dmerge(self.config, d) self.config['pc'] = platform.platform_config From 9e2ab9b853f9b668685b37a1e7f52852bd6fab3a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 2 Jun 2016 19:35:12 +0000 Subject: [PATCH 22/87] ONL Configuration Defaults --- .../all/vendor-config-onl/src/bin/onl-sysconfig | 14 ++++++++++++++ .../onl/config/{onl-config.yml => 00-defaults.yml} | 12 ++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100755 packages/base/all/vendor-config-onl/src/bin/onl-sysconfig rename packages/base/all/vendor-config-onl/src/etc/onl/config/{onl-config.yml => 00-defaults.yml} (85%) diff --git a/packages/base/all/vendor-config-onl/src/bin/onl-sysconfig b/packages/base/all/vendor-config-onl/src/bin/onl-sysconfig new file mode 100755 index 00000000..3b651d5a --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/bin/onl-sysconfig @@ -0,0 +1,14 @@ +#!/usr/bin/python +import os +import sys +from onl.sysconfig import sysconfig +import yaml + +if len(sys.argv) == 2: + try: + print yaml.dump((eval("sysconfig.%s" % sys.argv[1])), default_flow_style=False) + except AttributeError, e: + print "Path %s is not in the config." % sys.argv[1] +else: + print sysconfig['OnlSystemConfig'].dump() + diff --git a/packages/base/all/vendor-config-onl/src/etc/onl/config/onl-config.yml b/packages/base/all/vendor-config-onl/src/etc/onl/config/00-defaults.yml similarity index 85% rename from packages/base/all/vendor-config-onl/src/etc/onl/config/onl-config.yml rename to packages/base/all/vendor-config-onl/src/etc/onl/config/00-defaults.yml index ea59fc6d..8a42968f 100644 --- a/packages/base/all/vendor-config-onl/src/etc/onl/config/onl-config.yml +++ b/packages/base/all/vendor-config-onl/src/etc/onl/config/00-defaults.yml @@ -1,9 +1,10 @@ ############################################################ # -# ONL System Configuration +# ONL Default System Configuration. +# +# These provide the base default values for all sysconfig keys. # ############################################################ - upgrade: onie: auto-upgrade: advisory @@ -16,7 +17,6 @@ upgrade: - $PLATFORM.itb - onl-loader-fit.itb - pki: key: name: key.pem @@ -32,4 +32,8 @@ pki: commonName: Networking organizationalUnitName: Open Network Linux emailAddress: support@bigswitch.com - cdays: 3600 \ No newline at end of file + cdays: 3600 + + + + From fe2c6026ce3f706e6cdbbb1404ae1ee20fd79ce8 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 17:14:20 +0000 Subject: [PATCH 23/87] Replaced by sysconfig interface. --- .../rootfs/jessie/common/overlay/etc/onl/config/csr.yml | 7 ------- .../rootfs/wheezy/common/overlay/etc/onl/config/csr.yml | 7 ------- 2 files changed, 14 deletions(-) delete mode 100644 builds/any/rootfs/jessie/common/overlay/etc/onl/config/csr.yml delete mode 100644 builds/any/rootfs/wheezy/common/overlay/etc/onl/config/csr.yml diff --git a/builds/any/rootfs/jessie/common/overlay/etc/onl/config/csr.yml b/builds/any/rootfs/jessie/common/overlay/etc/onl/config/csr.yml deleted file mode 100644 index c64b4847..00000000 --- a/builds/any/rootfs/jessie/common/overlay/etc/onl/config/csr.yml +++ /dev/null @@ -1,7 +0,0 @@ -C: US -ST: CA -O: Open Compute Project -localityName: Santa Clara -commonName: Networking -organizationalUnitName: Open Network Linux -emailAddress: support@bigswitch.com diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/onl/config/csr.yml b/builds/any/rootfs/wheezy/common/overlay/etc/onl/config/csr.yml deleted file mode 100644 index c64b4847..00000000 --- a/builds/any/rootfs/wheezy/common/overlay/etc/onl/config/csr.yml +++ /dev/null @@ -1,7 +0,0 @@ -C: US -ST: CA -O: Open Compute Project -localityName: Santa Clara -commonName: Networking -organizationalUnitName: Open Network Linux -emailAddress: support@bigswitch.com From e6e16a5f48d31850ca19e147d51cffd4bc368896 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 17:40:04 +0000 Subject: [PATCH 24/87] Now provided by sysconfig. --- .../initrds/loader-initrd-files/src/etc/onl/config/csr.yml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 packages/base/all/initrds/loader-initrd-files/src/etc/onl/config/csr.yml diff --git a/packages/base/all/initrds/loader-initrd-files/src/etc/onl/config/csr.yml b/packages/base/all/initrds/loader-initrd-files/src/etc/onl/config/csr.yml deleted file mode 100644 index c64b4847..00000000 --- a/packages/base/all/initrds/loader-initrd-files/src/etc/onl/config/csr.yml +++ /dev/null @@ -1,7 +0,0 @@ -C: US -ST: CA -O: Open Compute Project -localityName: Santa Clara -commonName: Networking -organizationalUnitName: Open Network Linux -emailAddress: support@bigswitch.com From 286a9e48726e1c8c954ef276fc0ba02038135624 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 18:33:44 +0000 Subject: [PATCH 25/87] Renamed to sysconfig. --- .../src/etc/onl/{config => sysconfig}/00-defaults.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/base/all/vendor-config-onl/src/etc/onl/{config => sysconfig}/00-defaults.yml (100%) diff --git a/packages/base/all/vendor-config-onl/src/etc/onl/config/00-defaults.yml b/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml similarity index 100% rename from packages/base/all/vendor-config-onl/src/etc/onl/config/00-defaults.yml rename to packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml From 58e03edf42b59b59f36363272a29b0dd926344b4 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 18:34:24 +0000 Subject: [PATCH 26/87] - Support custom /etc/issue[.net] - Support generic file operations. --- tools/onlrfs.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/onlrfs.py b/tools/onlrfs.py index be985bec..04d1f940 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -411,7 +411,7 @@ rm -f /usr/sbin/policy-rc.d json.dump(md, f, indent=2) onlu.execute("sudo chmod a-w %s" % mname) - for (fname, v) in Configure.get('files', {}).iteritems(): + for (fname, v) in Configure.get('files', {}).get('add', {}).iteritems(): if fname.startswith('/'): fname = fname[1:] dst = os.path.join(dir_, fname) @@ -424,12 +424,19 @@ rm -f /usr/sbin/policy-rc.d with open(dst, "w") as f: f.write("%s\n" % v) + for fname in Configure.get('files', {}).get('remove', []): + if fname.startswith('/'): + fname = fname[1:] + f = os.path.join(dir_, fname) + if os.path.exists(f): + onlu.execute("sudo rm -rf %s" % f) + if Configure.get('issue'): issue = Configure.get('issue') fn = os.path.join(dir_, "etc/issue") onlu.execute("sudo chmod a+w %s" % fn) with open(fn, "w") as f: - f.write("%s\n" % issue) + f.write("%s\n\n" % issue) onlu.execute("sudo chmod a-w %s" % fn) fn = os.path.join(dir_, "etc/issue.net") From 5ac829e85f8de7d3c1e7e4229704b69be4cdd160 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 11:36:09 -0700 Subject: [PATCH 27/87] Don't copy the local sysconfig directory. --- packages/base/all/initrds/loader-initrd-files/src/lib/boot1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/base/all/initrds/loader-initrd-files/src/lib/boot1 b/packages/base/all/initrds/loader-initrd-files/src/lib/boot1 index dcb3814c..814c9451 100644 --- a/packages/base/all/initrds/loader-initrd-files/src/lib/boot1 +++ b/packages/base/all/initrds/loader-initrd-files/src/lib/boot1 @@ -82,7 +82,11 @@ else fi mkdir -p /newroot/etc/onl -cp -R /etc/onl/* /newroot/etc/onl +for thing in /etc/onl/*; do + if [ $thing != "sysconfig" ]; then + cp -R $thing /newroot/etc/onl + fi +done if [ -f /etc/fw_env.config ]; then cat /etc/fw_env.config >/newroot/etc/fw_env.config From 96a82eb880a7c653de2f146834dfbeed2d316b00 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 11:36:51 -0700 Subject: [PATCH 28/87] Moved to sysconfig. --- .../all/vendor-config-onl/src/python/onl/sysconfig/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py index 9be682b0..856755b3 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/sysconfig/__init__.py @@ -31,7 +31,7 @@ class DotDict(dict): class OnlSystemConfig(object): - SYSTEM_CONFIG_DIR = '/etc/onl/config' + SYSTEM_CONFIG_DIR = '/etc/onl/sysconfig' def __init__(self): From a225f5b9bdcc6ed9a914ee2203cb956517825268 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 11:37:33 -0700 Subject: [PATCH 29/87] Issue and manifest changes. --- builds/any/rootfs/jessie/standard/standard.yml | 16 +++++++++++++--- builds/any/rootfs/wheezy/standard/standard.yml | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/builds/any/rootfs/jessie/standard/standard.yml b/builds/any/rootfs/jessie/standard/standard.yml index ff1e4208..44ff5a87 100644 --- a/builds/any/rootfs/jessie/standard/standard.yml +++ b/builds/any/rootfs/jessie/standard/standard.yml @@ -7,6 +7,9 @@ # # ############################################################ +variables: + !include $ONL/make/versions/version-onl.yml + Packages: &Packages - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/all-base-packages.yml - !include $ONL/builds/any/rootfs/$ONL_DEBIAN_SUITE/common/${ARCH}-base-packages.yml @@ -89,6 +92,13 @@ Configure: root: password: onl - manifest: - version: $ONL/make/versions/version-onl.json - platforms: $PLATFORM_LIST + manifests: + '/etc/onl/rootfs/manifest.json' : + version : $ONL/make/versions/version-onl.json + platforms : $PLATFORM_LIST + + issue: $VERSION_STRING + + files: + remove: + - /etc/motd diff --git a/builds/any/rootfs/wheezy/standard/standard.yml b/builds/any/rootfs/wheezy/standard/standard.yml index 6bd5fbbf..3f046beb 100644 --- a/builds/any/rootfs/wheezy/standard/standard.yml +++ b/builds/any/rootfs/wheezy/standard/standard.yml @@ -100,3 +100,8 @@ Configure: platforms : $PLATFORM_LIST issue: $VERSION_STRING + + files: + remove: + - /etc/motd + From 1435153b75e19127e8d3082a78613e412bd91ce8 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 21:42:18 +0000 Subject: [PATCH 30/87] The cannonical name for all ITB files is .itb. --- .../vendor-config-onl/src/python/onl/install/BaseInstall.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py b/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py index 274268f9..d09af9d9 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py @@ -600,8 +600,7 @@ class UbootInstaller(SubprocessMixin, Base): % self.platformConf['loader']['loadaddr']) cmds.append("setenv onl_platform %s" % self.installerConf.installer_platform) - itb = self.platformConf['flat_image_tree']['itb'] - if type(itb) == dict: itb = itb['='] + itb = "%s.itb" % self.installerConf.installer_platform cmds.append("setenv onl_itb %s" % itb) for item in self.platformConf['loader']['setenv']: k, v = list(item.items())[0] @@ -695,7 +694,7 @@ class UbootInstaller(SubprocessMixin, Base): self.log.info("Installing ONL loader %s --> %s:%s...", loaderBasename, dev.device, loaderBasename) with MountContext(dev.device, log=self.log) as ctx: - dst = os.path.join(ctx.dir, loaderBasename) + dst = os.path.join(ctx.dir, "%s.itb" % self.im.installerConf.installer_platform) self.installerCopy(loaderBasename, dst) return 0 From d40845d7c924b95d4770a02ebdbb318eb5044b80 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 21:48:05 +0000 Subject: [PATCH 31/87] Auto upgrade policy inherited from subclass. Needs work. --- .../base/all/vendor-config-onl/src/boot.d/62.upgrade-loader | 5 ++++- .../all/vendor-config-onl/src/python/onl/upgrade/ubase.py | 6 +++++- 2 files changed, 9 insertions(+), 2 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 f7111744..94208553 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 @@ -20,6 +20,9 @@ class Loader_Upgrade(ubase.BaseUpgrade): current_version_key="Current Loader Version" next_version_key="Next Loader Version" + def auto_upgrade_default(self): + return sysconfig.upgrade.loader.auto + def init_versions(self): # @@ -68,7 +71,7 @@ class Loader_Upgrade_FIT(Loader_Upgrade): with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d: self.copyfile(fit_image, os.path.join(d.directory, "%s.itb" % (self.platform.platform()))) - #self.reboot() + self.reboot() class Loader_Upgrade_x86_64(Loader_Upgrade): 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 4c7784b7..b9653815 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 @@ -58,13 +58,17 @@ class BaseUpgrade(object): if os.getenv("DEBUG"): self.logger.setLevel(logging.DEBUG) + + def auto_upgrade_default(self): + return "advisory" + 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("--auto-upgrade", help="Override auto-upgrade mode.", default=self.auto_upgrade_default()) self.ap.add_argument("--summarize", action='store_true', help="Summarize only, no upgrades.") def banner(self): From 6957c7563205e66e6e06ea235479a3baab684635 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 8 Jun 2016 21:48:47 +0000 Subject: [PATCH 32/87] Simplify key name. --- .../vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml b/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml index 8a42968f..6597f9c3 100644 --- a/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml +++ b/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml @@ -7,9 +7,9 @@ ############################################################ upgrade: onie: - auto-upgrade: advisory + auto: advisory loader: - auto-upgrade: advisory + auto: advisory versions: /etc/onl/loader/versions.json package: dir: /etc/onl/upgrade/$PARCH From aa03cdae1f67ab2eb02419c8910a3bc27ca94b4a Mon Sep 17 00:00:00 2001 From: Steven Noble Date: Wed, 8 Jun 2016 20:11:48 -0700 Subject: [PATCH 33/87] Update SupportedHardware.md Fixing incorrect Nephos (MT3258 not MT3257) chip id. --- docs/SupportedHardware.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/SupportedHardware.md b/docs/SupportedHardware.md index b3b14899..fba20e1b 100644 --- a/docs/SupportedHardware.md +++ b/docs/SupportedHardware.md @@ -31,7 +31,7 @@ Accton/Edge-Core Accton AS5610-52X 48x10G + 4x40G FreeScale P2020 Broadcom BCM56846 (Trident+) Yes Yes Yes No No No Accton AS5710-54X 48x10G + 6x40G FreeScale P2041 Broadcom BCM56854 (Trident2) Yes Yes Yes Yes*** Yes*** No Accton AS6700-32X 32x40G FreeScale P2041 Broadcom BCM56850 (Trident2) Yes Yes Yes No No No - Accton AS5512-54X 48x10G + 6x40G Intel Rangeley C2538 x86 MediaTek MT3257 No No No No No No + Accton AS5512-54X 48x10G + 6x40G Intel Rangeley C2538 x86 MediaTek/Nephos MT3258 No No No No No No Accton AS5712-54X 48x10G + 6x40G Intel Rangeley C2538 x86 Broadcom BCM56854 (Trident2) Yes Yes Yes Yes*** Yes*** No Accton AS6712-32X 32x40G Intel Rangeley C2538 x86 Broadcom BCM56850 (Trident2) Yes Yes Yes Yes*** Yes*** No Accton AS5812-54T 48x10G + 6x40G Intel Rangeley C2538 x86 Broadcom BCM56864 (Trident2+) Yes Yes No No No No From cf26d4164e074570018b81daa54ade715ef83aa5 Mon Sep 17 00:00:00 2001 From: Steven Noble Date: Fri, 10 Jun 2016 00:43:50 +0000 Subject: [PATCH 34/87] adding wedge-100 platform and updating wedge-40 to use 3.18 kernel --- .../r0/src/lib/x86-64-accton-wedge-16x-r0.yml | 2 +- .../x86-64/x86-64-facebook-wedge100/Makefile | 1 + .../x86-64-facebook-wedge100/onlp/Makefile | 1 + .../x86-64-facebook-wedge100/onlp/PKG.yml | 15 ++++++++ .../platform-config/Makefile | 1 + .../platform-config/r0/Makefile | 1 + .../platform-config/r0/PKG.yml | 1 + .../src/lib/x86-64-facebook-wedge100-r0.yml | 34 +++++++++++++++++++ .../x86_64_facebook_wedge100_r0/__init__.py | 16 +++++++++ 9 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/PKG.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/Makefile create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/PKG.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/lib/x86-64-facebook-wedge100-r0.yml create mode 100644 packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py diff --git a/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/lib/x86-64-accton-wedge-16x-r0.yml b/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/lib/x86-64-accton-wedge-16x-r0.yml index 1c42ce71..133874d1 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/lib/x86-64-accton-wedge-16x-r0.yml +++ b/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/lib/x86-64-accton-wedge-16x-r0.yml @@ -18,7 +18,7 @@ x86-64-accton-wedge-16x-r0: --stop=1 kernel: - <<: *kernel-3-2 + <<: *kernel-3-18 args: >- nopat diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/Makefile b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/Makefile new file mode 100644 index 00000000..dc1e7b86 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/Makefile b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/Makefile new file mode 100644 index 00000000..dc1e7b86 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/PKG.yml b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/PKG.yml new file mode 100644 index 00000000..10caa7f6 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/onlp/PKG.yml @@ -0,0 +1,15 @@ +variables: + platform: x86-64-facebook-wedge100-r0 + install: /lib/platform-config/${platform}/onl + +common: + version: 1.0.0 + arch: amd64 + copyright: Copyright 2013, 2014, 2015 Big Switch Networks + maintainer: support@bigswitch.com + comment: dummy package for ONLP on Wedge +packages: + - name: onlp-${platform} + summary: ONLP Package for the ${platform} platform. + + changelog: initial version diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/Makefile b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/Makefile new file mode 100644 index 00000000..dc1e7b86 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/Makefile b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/Makefile new file mode 100644 index 00000000..dc1e7b86 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/PKG.yml b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/PKG.yml new file mode 100644 index 00000000..41ac0a89 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=accton PLATFORM=x86-64-facebook-wedge100-r0 diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/lib/x86-64-facebook-wedge100-r0.yml b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/lib/x86-64-facebook-wedge100-r0.yml new file mode 100644 index 00000000..fdcbd263 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/lib/x86-64-facebook-wedge100-r0.yml @@ -0,0 +1,34 @@ +--- + +###################################################################### +# +# platform-config for WEDGE +# +###################################################################### + +x86-64-facebook-wedge100-r0: + + grub: + + serial: >- + --unit=0 + --speed=57600 + --word=8 + --parity=0 + --stop=1 + + kernel: + <<: *kernel-3-18 + + args: >- + nopat + console=ttyS0,57600n8 + rd_NO_MD + rd_NO_LUKS + intel_iommu=off + + ##network + ## interfaces: + ## ma1: + ## name: ~ + ## syspath: pci0000:00/0000:00:14.0 diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py new file mode 100644 index 00000000..b6a287be --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py @@ -0,0 +1,16 @@ +from onl.platform.base import * +from onl.vendor.accton import * + +class OnlPlatform_x86_64_facebook_wedge_100_r0(OpenNetworkPlatformAccton): + + def model(self): + return "Wedge-100" + + def platform(self): + return "x86-64-facebook-wedge100-r0" + + def baseconfig(self): + return True + + def sys_oid_platform(self): + return ".100.1" From 00e16b1f051e8e9f1f19a812812ef2c7006de1ef Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:50:08 +0000 Subject: [PATCH 35/87] Platform class mini-cleanup - Platform objects now export their physical port configuration - Property updates. --- .../arm_accton_as4610_54_r0/__init__.py | 18 ++++----------- .../powerpc_accton_as4600_54t_r0/__init__.py | 21 +++++------------ .../powerpc_accton_as5610_52x_r0/__init__.py | 23 +++++-------------- .../powerpc_accton_as5710_54x_r0/__init__.py | 21 +++++------------ .../powerpc_accton_as5710_54x_r0b/__init__.py | 17 ++++---------- .../powerpc_accton_as6700_32x_r0/__init__.py | 15 +++++------- .../powerpc_accton_as6700_32x_r1/__init__.py | 21 ++++++----------- .../src/python/accton/__init__.py | 21 +++-------------- .../x86_64_accton_as5512_54x_r0/__init__.py | 19 ++++----------- .../x86_64_accton_as5712_54x_r0/__init__.py | 14 ++++------- .../x86_64_accton_as5812_54t_r0/__init__.py | 19 ++++----------- .../x86_64_accton_as5812_54x_r0/__init__.py | 18 ++++----------- .../x86_64_accton_as6712_32x_r0/__init__.py | 16 ++++--------- .../x86_64_accton_as6812_32x_r0/__init__.py | 16 ++++--------- .../x86_64_accton_as7512_32x_r0/__init__.py | 16 +++++-------- .../x86_64_accton_as7712_32x_r0/__init__.py | 15 ++++-------- .../x86_64_accton_as7716_32x_r0/__init__.py | 15 ++++-------- .../x86_64_accton_wedge_16x_r0/__init__.py | 15 +++++------- 18 files changed, 96 insertions(+), 224 deletions(-) diff --git a/packages/platforms/accton/armel/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py b/packages/platforms/accton/armel/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py index 94190515..f2a47419 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py +++ b/packages/platforms/accton/armel/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py @@ -1,16 +1,8 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_arm_accton_as4610_54_r0(OnlPlatformAccton): - - def model(self): - return "AS4610-54" - - def platform(self): - return "arm-accton-as4610-54-r0" - - def sys_oid_platform(self): - return ".4610" - - def baseconfig(self): - return True +class OnlPlatform_arm_accton_as4610_54_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x1_4x10): + PLATFORM='arm-accton-as4610-54-r0' + MODEL="AS4610-54" + SYS_OBJECT_ID=".4610" diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/python/powerpc_accton_as4600_54t_r0/__init__.py b/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/python/powerpc_accton_as4600_54t_r0/__init__.py index b0f245e8..c5993ffb 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/python/powerpc_accton_as4600_54t_r0/__init__.py +++ b/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/platform-config/r0/src/python/powerpc_accton_as4600_54t_r0/__init__.py @@ -1,20 +1,11 @@ #!/usr/bin/python -############################################################ -# -# -# -############################################################ + from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_powerpc_accton_as4600_54t_r0(OnlPlatformAccton): - - def model(self): - return 'AS4600-54T' - - def platform(self): - return 'powerpc-accton-as4600-54t-r0' - - def sys_oid_platform(self): - return ".4600.54" +class OnlPlatform_powerpc_accton_as4600_54t_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x1_4x10): + PLATFORM='powerpc-accton-as4600-54t-r0' + MODEL='AS4600-54T' + SYS_OBJECT_ID='.4600.54' diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/python/powerpc_accton_as5610_52x_r0/__init__.py b/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/python/powerpc_accton_as5610_52x_r0/__init__.py index f609f450..233179ab 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/python/powerpc_accton_as5610_52x_r0/__init__.py +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/platform-config/r0/src/python/powerpc_accton_as5610_52x_r0/__init__.py @@ -1,23 +1,12 @@ #!/usr/bin/python -############################################################ -# -# -# -############################################################ + from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_powerpc_accton_as5610_52x_r0(OnlPlatformAccton): - - onie_base_address = "0xeff70000" - - def model(self): - return "AS5610-52X" - - def platform(self): - return 'powerpc-accton-as5610-52x-r0' - - def sys_oid_platform(self): - return ".5610.52" +class OnlPlatform_powerpc_accton_as5610_52x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x10_4x40): + PLATFORM='powerpc-accton-as5610-52x-r0' + MODEL='AS5610-52X' + SYS_OBJECT_ID='.5610.52' diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/python/powerpc_accton_as5710_54x_r0/__init__.py b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/python/powerpc_accton_as5710_54x_r0/__init__.py index aa528a4c..931b0330 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/python/powerpc_accton_as5710_54x_r0/__init__.py +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0/src/python/powerpc_accton_as5710_54x_r0/__init__.py @@ -1,22 +1,13 @@ #!/usr/bin/python -############################################################ -# -# -# -############################################################ + from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_powerpc_accton_as5710_54x_r0(OnlPlatformAccton): +class OnlPlatform_powerpc_accton_as5710_54x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x10_6x40): + PLATFORM='powerpc-accton-as5710-54x-r0' + MODEL='AS5710-54X' + SYS_OBJECT_ID='.5710.54' - CPLDVERSION="cpldversion" - def model(self): - return "AS5710-54X" - - def platform(self): - return 'powerpc-accton-as5710-54x-r0' - - def sys_oid_platform(self): - return ".5710.54" diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/python/powerpc_accton_as5710_54x_r0b/__init__.py b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/python/powerpc_accton_as5710_54x_r0b/__init__.py index bd9f9834..866b67b6 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/python/powerpc_accton_as5710_54x_r0b/__init__.py +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/platform-config/r0b/src/python/powerpc_accton_as5710_54x_r0b/__init__.py @@ -6,16 +6,9 @@ import os from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_powerpc_accton_as5710_54x_r0b(OnlPlatformAccton): - - CPLDVERSION="cpldversion" - - def model(self): - return "AS5710-54X (R0B)" - - def platform(self): - return 'powerpc-accton-as5710-54x-r0b' - - def sys_oid_platform(self): - return ".5710.54" +class OnlPlatform_powerpc_accton_as5710_54x_r0b(OnlPlatformAccton, + OnlPlatformPortConfig_48x10_6x40): + PLATFORM='powerpc-accton-as5710-54x-r0b' + MODEL='AS5710-54X (R0B)' + SYS_OBJECT_ID='.5710.54' diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/python/powerpc_accton_as6700_32x_r0/__init__.py b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/python/powerpc_accton_as6700_32x_r0/__init__.py index 5b719ea0..e278c5a4 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/python/powerpc_accton_as6700_32x_r0/__init__.py +++ b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r0/src/python/powerpc_accton_as6700_32x_r0/__init__.py @@ -5,19 +5,16 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_powerpc_accton_as6700_32x_r0(OnlPlatformAccton): - - def model(self): - return "AS6700-32X" - - def platform(self): - return 'powerpc-accton-as6700-32x-r0' +class OnlPlatform_powerpc_accton_as6700_32x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_32x40): + PLATFORM='powerpc-accton-as6700-32x-r0' + MODEL="AS6700-32X" + SYS_OBJECT_ID=".6700.32" def baseconfig(self): with open("/etc/default/watchdog", 'a') as f: f.write("run_watchdog=0\n"); return True - def sys_oid_platform(self): - return ".6700.32" + diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/python/powerpc_accton_as6700_32x_r1/__init__.py b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/python/powerpc_accton_as6700_32x_r1/__init__.py index 3098e3b5..614f4f45 100644 --- a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/python/powerpc_accton_as6700_32x_r1/__init__.py +++ b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/platform-config/r1/src/python/powerpc_accton_as6700_32x_r1/__init__.py @@ -1,24 +1,17 @@ #!/usr/bin/python -############################################################ -# -# -# -############################################################ + from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_powerpc_accton_as6700_32x_r1(OnlPlatformAccton): - - def model(self): - return "AS6700-32X" - - def platform(self): - return 'powerpc-accton-as6700-32x-r1' +class OnlPlatform_powerpc_accton_as6700_32x_r1(OnlPlatformAccton, + OnlPlatformPortConfig_32x40): + PLATFORM='powerpc-accton-as6700-32x-r1' + MODEL='AS6700-32X' + SYS_OBJECT_ID='.6700.32' def baseconfig(self): with open("/etc/default/watchdog", 'a') as f: f.write("run_watchdog=0\n"); return True - def sys_oid_platform(self): - return ".6700.32" + diff --git a/packages/platforms/accton/vendor-config/src/python/accton/__init__.py b/packages/platforms/accton/vendor-config/src/python/accton/__init__.py index 0dbb90fb..cd90d20b 100644 --- a/packages/platforms/accton/vendor-config/src/python/accton/__init__.py +++ b/packages/platforms/accton/vendor-config/src/python/accton/__init__.py @@ -1,22 +1,7 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for Accton platforms. -# -############################################################ + from onl.platform.base import * class OnlPlatformAccton(OnlPlatformBase): - def manufacturer(self): - return "Accton" - - def sys_oid_vendor(self): - return ".259" + MANUFACTURER='Accton' + PRIVATE_ENTERPRISE_NUMBER=259 diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/python/x86_64_accton_as5512_54x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/python/x86_64_accton_as5512_54x_r0/__init__.py index de3685dd..972a3b28 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/python/x86_64_accton_as5512_54x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/python/x86_64_accton_as5512_54x_r0/__init__.py @@ -1,20 +1,11 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as5512_54x_r0(OnlPlatformAccton): - - - def model(self): - return "AS5512-54X" - - def platform(self): - return "x86-64-accton-as5512-54x-r0" - - def sys_init(self): - pass - - def sys_oid_platform(self): - return ".5512.54.1" +class OnlPlatform_x86_64_accton_as5512_54x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x10_6x40): + PLATFORM='x86-64-accton-as5512-54x-r0' + MODEL="AS5512-54X" + SYS_OBJECT_ID=".5512.54.1" def baseconfig(self): ########### initialize I2C bus 0 ########### diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/platform-config/r0/src/python/x86_64_accton_as5712_54x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/platform-config/r0/src/python/x86_64_accton_as5712_54x_r0/__init__.py index c323c6e9..0fc60af9 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/platform-config/r0/src/python/x86_64_accton_as5712_54x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/platform-config/r0/src/python/x86_64_accton_as5712_54x_r0/__init__.py @@ -1,16 +1,12 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as5712_54x_r0(OnlPlatformAccton): +class OnlPlatform_x86_64_accton_as5712_54x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x10_6x40): - def model(self): - return "AS5712-54X" - - def platform(self): - return "x86-64-accton-as5712-54x-r0" - - def sys_oid_platform(self): - return ".5712.54" + PLATFORM='x86-64-accton-as5712-54x-r0' + MODEL="AS5712-54X" + SYS_OBJECT_ID=".5712.54" def baseconfig(self): ########### initialize I2C bus 0 ########### diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/platform-config/r0/src/python/x86_64_accton_as5812_54t_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/platform-config/r0/src/python/x86_64_accton_as5812_54t_r0/__init__.py index bd554c23..106910fa 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/platform-config/r0/src/python/x86_64_accton_as5812_54t_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/platform-config/r0/src/python/x86_64_accton_as5812_54t_r0/__init__.py @@ -1,20 +1,11 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as5812_54t_r0(OnlPlatformAccton): - - - def model(self): - return "AS5812-54T" - - def platform(self): - return "x86-64-accton-as5812-54t-r0" - - def sys_init(self): - pass - - def sys_oid_platform(self): - return ".5812.54.2" +class OnlPlatform_x86_64_accton_as5812_54t_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x10_6x40): + PLATFORM='x86-64-accton-as5812-54t-r0' + MODEL="AS5812-54T" + SYS_OBJECT_ID=".5812.54.2" def baseconfig(self): ########### initialize I2C bus 0 ########### diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py index 9b3750e9..536b1879 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/platform-config/r0/src/python/x86_64_accton_as5812_54x_r0/__init__.py @@ -1,20 +1,12 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as5812_54x_r0(OnlPlatformAccton): +class OnlPlatform_x86_64_accton_as5812_54x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_48x10_6x40): - - def model(self): - return "AS5812-54X" - - def platform(self): - return "x86-64-accton-as5812-54x-r0" - - def sys_init(self): - pass - - def sys_oid_platform(self): - return ".5812.54.1" + PLATFORM='x86-64-accton-as5812-54x-r0' + MODEL="AS5812-54X" + SYS_OBJECT_ID=".5812.54.1" def baseconfig(self): ########### initialize I2C bus 0 ########### diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/platform-config/r0/src/python/x86_64_accton_as6712_32x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/platform-config/r0/src/python/x86_64_accton_as6712_32x_r0/__init__.py index b96aba1f..d1779f7d 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/platform-config/r0/src/python/x86_64_accton_as6712_32x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/platform-config/r0/src/python/x86_64_accton_as6712_32x_r0/__init__.py @@ -1,17 +1,11 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as6712_32x_r0(OnlPlatformAccton): - - def model(self): - return "AS6712-32X" - - def platform(self): - return "x86-64-accton-as6712-32x-r0" - - def sys_oid_platform(self): - return ".6712.32" - +class OnlPlatform_x86_64_accton_as6712_32x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_32x40): + PLATFORM='x86-64-accton-as6712-32x-r0' + MODEL="AS6712-32X" + SYS_OBJECT_ID=".6712.32" def baseconfig(self): diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py index f366c160..b7abeda4 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/platform-config/r0/src/python/x86_64_accton_as6812_32x_r0/__init__.py @@ -1,17 +1,11 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as6812_32x_r0(OnlPlatformAccton): - - def model(self): - return "AS6812-32X" - - def platform(self): - return "x86-64-accton-as6812-32x-r0" - - def sys_oid_platform(self): - return ".6812.32" - +class OnlPlatform_x86_64_accton_as6812_32x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_32x40): + PLATFORM='x86-64-accton-as6812-32x-r0' + MODEL="AS6812-32X" + SYS_OBJECT_ID=".6812.32" def baseconfig(self): diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/python/x86_64_accton_as7512_32x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/python/x86_64_accton_as7512_32x_r0/__init__.py index 8ff578c9..e8770bda 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/python/x86_64_accton_as7512_32x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/python/x86_64_accton_as7512_32x_r0/__init__.py @@ -1,16 +1,11 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as7512_32x_r0(OnlPlatformAccton): - - def model(self): - return "AS7512-32X" - - def platform(self): - return "x86-64-accton-as7512-32x-r0" - - def sys_oid_platform(self): - return ".7512.32" +class OnlPlatform_x86_64_accton_as7512_32x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_32x100): + PLATFORM='x86-64-accton-as7512-32x-r0' + MODEL="AS7512-32X" + SYS_OBJECT_ID=".7512.32" def baseconfig(self): ########### initialize I2C bus 0 ########### @@ -70,6 +65,7 @@ class OnlPlatform_x86_64_accton_as7512_32x_r0(OnlPlatformAccton): self.new_i2c_device('as7512_32x_sfp2', 0x50, 19) self.new_i2c_device('as7512_32x_sfp3', 0x50, 20) self.new_i2c_device('as7512_32x_sfp4', 0x50, 21) + self.new_i2c_device('as7512_32x_sfp5', 0x50, 22) self.new_i2c_device('as7512_32x_sfp6', 0x50, 23) self.new_i2c_device('as7512_32x_sfp7', 0x50, 24) diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/platform-config/r0/src/python/x86_64_accton_as7712_32x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/platform-config/r0/src/python/x86_64_accton_as7712_32x_r0/__init__.py index c6013ede..06580f03 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/platform-config/r0/src/python/x86_64_accton_as7712_32x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/platform-config/r0/src/python/x86_64_accton_as7712_32x_r0/__init__.py @@ -1,16 +1,11 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as7712_32x_r0(OnlPlatformAccton): - - def model(self): - return "AS7712-32X" - - def platform(self): - return "x86-64-accton-as7712-32x-r0" - - def sys_oid_platform(self): - return ".7712.32" +class OnlPlatform_x86_64_accton_as7712_32x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_32x100): + PLATFORM='x86-64-accton-as7712-32x-r0' + MODEL="AS7712-32X" + SYS_OBJECT_ID=".7712.32" def baseconfig(self): ########### initialize I2C bus 0 ########### 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 69069792..76f0da9e 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 @@ -1,16 +1,11 @@ from onl.platform.base import * from onl.platform.accton import * -class OnlPlatform_x86_64_accton_as7716_32x_r0(OnlPlatformAccton): - - def model(self): - return "AS7716-32X" - - def platform(self): - return "x86-64-accton-as7716-32x-r0" - - def sys_oid_platform(self): - return ".7716.32" +class OnlPlatform_x86_64_accton_as7716_32x_r0(OnlPlatformAccton, + OnlPlatformPortConfig_32x100): + PLATFORM='x86-64-accton-as7716-32x-r0' + MODEL="AS7716-32X" + SYS_OBJECT_ID=".7716.32" def baseconfig(self): ########### initialize I2C bus 0 ########### diff --git a/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/python/x86_64_accton_wedge_16x_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/python/x86_64_accton_wedge_16x_r0/__init__.py index bfe7f195..f184516b 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/python/x86_64_accton_wedge_16x_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-accton-wedge-16x/platform-config/r0/src/python/x86_64_accton_wedge_16x_r0/__init__.py @@ -1,16 +1,13 @@ from onl.platform.base import * from onl.vendor.accton import * -class OnlPlatform_x86_64_accton_wedge_16x_r0(OpenNetworkPlatformAccton): +class OnlPlatform_x86_64_accton_wedge_16x_r0(OnlPlatformAccton): + PLATFORM='x86-64-accton-wedge-16x-r0' + MODEL="Wedge-16X" + SYS_OBJECT_ID=".16.1" - def model(self): - return "Wedge-16X" + PORT_COUNT=16 + PORT_CONFIG="16x40" - def platform(self): - return "x86-64-accton-wedge-16x-r0" - def baseconfig(self): - return True - def sys_oid_platform(self): - return ".16.1" From 5c3345bef4efbc68fecf034966bc94a1de16f550 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:52:00 +0000 Subject: [PATCH 36/87] Platform class mini-cleanup - Platform objects now export their physical port configuration - Property updates. --- .../src/python/celestica/__init__.py | 21 ++------------ .../x86_64_cel_redstone_xp_r0/__init__.py | 17 ++++------- .../vendor-config/src/python/dell/__init__.py | 22 ++------------- .../vendor-config/src/python/dni/__init__.py | 21 ++------------ .../vendor-config/src/python/kvm/__init__.py | 21 ++------------ .../python/x86_64_kvm_x86_64_r0/__init__.py | 17 ++++------- .../src/python/arm_qemu_armv7a_r0/__init__.py | 17 ++++------- .../vendor-config/src/python/qemu/__init__.py | 21 ++------------ .../python/powerpc_quanta_lb9_r0/__init__.py | 28 ++++--------------- .../python/powerpc_quanta_ly2_r0/__init__.py | 19 +++++-------- .../src/python/quanta/__init__.py | 22 ++------------- .../x86_64_quanta_ly6_rangeley_r0/__init__.py | 15 ++++------ .../x86_64_quanta_ly8_rangeley_r0/__init__.py | 15 ++++------ .../vendor-config/src/python/wnc/__init__.py | 21 ++------------ 14 files changed, 59 insertions(+), 218 deletions(-) diff --git a/packages/platforms/celestica/vendor-config/src/python/celestica/__init__.py b/packages/platforms/celestica/vendor-config/src/python/celestica/__init__.py index 722f43d9..08a5db35 100644 --- a/packages/platforms/celestica/vendor-config/src/python/celestica/__init__.py +++ b/packages/platforms/celestica/vendor-config/src/python/celestica/__init__.py @@ -1,23 +1,8 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for Celestica platforms. -# -############################################################ + from onl.platform.base import * class OnlPlatformCelestica(OnlPlatformBase): - def manufacturer(self): - return "Celestica" - - def sys_oid_vendor(self): - return ".12290" + MANUFACTUTER='Celestica' + PRIVATE_ENTERPRISE_NUMBER=12290 diff --git a/packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/platform-config/r0/src/python/x86_64_cel_redstone_xp_r0/__init__.py b/packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/platform-config/r0/src/python/x86_64_cel_redstone_xp_r0/__init__.py index 0226ddd8..f3d6c214 100644 --- a/packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/platform-config/r0/src/python/x86_64_cel_redstone_xp_r0/__init__.py +++ b/packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/platform-config/r0/src/python/x86_64_cel_redstone_xp_r0/__init__.py @@ -1,16 +1,9 @@ from onl.platform.base import * from onl.platform.celestica import * -class OnlPlatform_x86_64_cel_redstone_xp_r0(OnlPlatformCelestica): +class OnlPlatform_x86_64_cel_redstone_xp_r0(OnlPlatformCelestica, + OnlPlatformPortConfig_48x10_6x40): + PLATFORM='x86-64-cel-redstone-xp-r0' + MODEL="Redstone XP" + SYS_OBJECT_ID=".2060.1" - def model(self): - return "Redstone XP" - - def platform(self): - return "x86-64-cel-redstone-xp-r0" - - def sys_oid_platform(self): - return ".2060.1" - - def baseconfig(self): - return True diff --git a/packages/platforms/dell/vendor-config/src/python/dell/__init__.py b/packages/platforms/dell/vendor-config/src/python/dell/__init__.py index 8c2ee967..3b69223e 100644 --- a/packages/platforms/dell/vendor-config/src/python/dell/__init__.py +++ b/packages/platforms/dell/vendor-config/src/python/dell/__init__.py @@ -1,23 +1,7 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for DELL platforms. -# -############################################################ + from onl.platform.base import * class OnlPlatformDell(OnlPlatformBase): - - def manufacturer(self): - return "Dell" - - def sys_oid_vendor(self): - return ".674" + MANUFACTURER='Dell' + PRIVATE_ENTERPRISE_NUMBER=674 diff --git a/packages/platforms/dni/vendor-config/src/python/dni/__init__.py b/packages/platforms/dni/vendor-config/src/python/dni/__init__.py index 83562176..6878a215 100644 --- a/packages/platforms/dni/vendor-config/src/python/dni/__init__.py +++ b/packages/platforms/dni/vendor-config/src/python/dni/__init__.py @@ -1,22 +1,7 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for DNI platforms. -# -############################################################ + from onl.platform.base import * class OnlPlatformDNI(OnlPlatformBase): - def manufacturer(self): - return "DNI" - - def sys_oid_vendor(self): - return ".5324" + MANUFACTURER='DNI' + PRIVATE_ENTERPRISE_NUMBER=5324 diff --git a/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py b/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py index 62338900..c6122468 100644 --- a/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py +++ b/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py @@ -1,22 +1,7 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for the KVM simulation platform. -# -############################################################ + from onl.platform.base import * class OnlPlatformKVM(OnlPlatformBase): - def manufacturer(self): - return "KVM" - - def sys_oid_vendor(self): - return ".42623" + MANUFACTURER=KVM + PRIVATE_ENTERPRISE_NUMBER=42623 diff --git a/packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/platform-config/r0/src/python/x86_64_kvm_x86_64_r0/__init__.py b/packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/platform-config/r0/src/python/x86_64_kvm_x86_64_r0/__init__.py index d4d79074..29d18aba 100644 --- a/packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/platform-config/r0/src/python/x86_64_kvm_x86_64_r0/__init__.py +++ b/packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/platform-config/r0/src/python/x86_64_kvm_x86_64_r0/__init__.py @@ -2,15 +2,8 @@ from onl.platform.base import * from onl.platform.kvm import * class OnlPlatform_x86_64_kvm_x86_64_r0(OnlPlatformKVM): - - def model(self): - return "KVM X86_64" - - def platform(self): - return "x86-64-kvm-x86-64-r0" - - def sys_oid_platform(self): - return ".1" - - def baseconfig(self): - return True + PLATFORM='x86-64-kvm-x86-64-r0' + MODEL="KVM X86_64" + SYS_OBJECT_ID=".1" + PORT_COUNT=0 + PORT_CONFIG="None" diff --git a/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/src/python/arm_qemu_armv7a_r0/__init__.py b/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/src/python/arm_qemu_armv7a_r0/__init__.py index 91cf4771..8454c3c8 100644 --- a/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/src/python/arm_qemu_armv7a_r0/__init__.py +++ b/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/src/python/arm_qemu_armv7a_r0/__init__.py @@ -2,15 +2,8 @@ from onl.platform.base import * from onl.platform.qemu import * class OnlPlatform_arm_qemu_armv7a_r0(OnlPlatformQEMU): - - def model(self): - return "QEMU ARMv7a" - - def platform(self): - return "arm-qemu-armv7a-r0" - - def sys_oid_platform(self): - return ".2" - - def baseconfig(self): - return True + PLATFORM='arm-qemu-armv7a-r0' + MODEL="QEMU ARMv7a" + SYS_OBJECT_ID=".2" + PORT_COUNT=0 + PORT_CONFIG="" diff --git a/packages/platforms/qemu/vendor-config/src/python/qemu/__init__.py b/packages/platforms/qemu/vendor-config/src/python/qemu/__init__.py index 82b0e38e..0557dc29 100644 --- a/packages/platforms/qemu/vendor-config/src/python/qemu/__init__.py +++ b/packages/platforms/qemu/vendor-config/src/python/qemu/__init__.py @@ -1,22 +1,7 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for the KVM simulation platform. -# -############################################################ + from onl.platform.base import * class OnlPlatformQEMU(OnlPlatformBase): - def manufacturer(self): - return "QEMU" - - def sys_oid_vendor(self): - return ".42623" + MANUFACTURER='QEMU' + PRIVATE_ENTERPRISE_NUMBER=42623 diff --git a/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/python/powerpc_quanta_lb9_r0/__init__.py b/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/python/powerpc_quanta_lb9_r0/__init__.py index 61872744..abb2c5ac 100644 --- a/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/python/powerpc_quanta_lb9_r0/__init__.py +++ b/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/platform-config/r0/src/python/powerpc_quanta_lb9_r0/__init__.py @@ -1,27 +1,13 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# Platform Driver for the Quanta LB9 -# -############################################################ + from onl.platform.base import * from onl.platform.quanta import * -class OnlPlatform_powerpc_quanta_lb9_r0(OnlPlatformQuanta): - - def model(self): - return "LB9" - - def platform(self): - return "powerpc-quanta-lb9-r0" +class OnlPlatform_powerpc_quanta_lb9_r0(OnlPlatformQuanta, + OnlPlatformPortConfig_48x1_4x10): + PLATFORM='powerpc-quanta-lb9-r0' + MODEL="LB9" + SYS_OBJECT_ID=".1048.1" def baseconfig(self): platform_fancontrol="%s/etc/fancontrol" % self.basedir_onl() @@ -35,7 +21,5 @@ class OnlPlatform_powerpc_quanta_lb9_r0(OnlPlatformQuanta): return True - def sys_oid_platform(self): - return ".1048.1" diff --git a/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/python/powerpc_quanta_ly2_r0/__init__.py b/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/python/powerpc_quanta_ly2_r0/__init__.py index 79f42461..49319b5e 100644 --- a/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/python/powerpc_quanta_ly2_r0/__init__.py +++ b/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/platform-config/r0/src/python/powerpc_quanta_ly2_r0/__init__.py @@ -1,18 +1,14 @@ #!/usr/bin/python -############################################################ -# -############################################################ + import subprocess from onl.platform.base import * from onl.platform.quanta import * -class OnlPlatform_powerpc_quanta_ly2_r0(OnlPlatformQuanta): - - def model(self): - return "LY2" - - def platform(self): - return "powerpc-quanta-ly2-r0" +class OnlPlatform_powerpc_quanta_ly2_r0(OnlPlatformQuanta, + OnlPlatformPortConfig_48x10_4x40): + PLATFORM='powerpc-quanta-ly2-r0' + MODEL="LY2" + SYS_OBJECT_ID=".3048.1" def baseconfig(self): subprocess.check_call("%s/sbin/gpio_init" % self.basedir_onl()) @@ -39,8 +35,7 @@ class OnlPlatform_powerpc_quanta_ly2_r0(OnlPlatformQuanta): return True - def sys_oid_platform(self): - return ".3048.1" + diff --git a/packages/platforms/quanta/vendor-config/src/python/quanta/__init__.py b/packages/platforms/quanta/vendor-config/src/python/quanta/__init__.py index 8d5adc04..44a2951b 100644 --- a/packages/platforms/quanta/vendor-config/src/python/quanta/__init__.py +++ b/packages/platforms/quanta/vendor-config/src/python/quanta/__init__.py @@ -1,23 +1,7 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for Quanta platforms. -# -############################################################ + from onl.platform.base import * class OnlPlatformQuanta(OnlPlatformBase): - - def manufacturer(self): - return "Quanta" - - def sys_oid_vendor(self): - return ".7244" + MANUFACTURER='Quanta' + PRIVATE_ENTERPRISE_NUMBER=7244 diff --git a/packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/platform-config/r0/src/python/x86_64_quanta_ly6_rangeley_r0/__init__.py b/packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/platform-config/r0/src/python/x86_64_quanta_ly6_rangeley_r0/__init__.py index 8c7095e4..66694cb1 100644 --- a/packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/platform-config/r0/src/python/x86_64_quanta_ly6_rangeley_r0/__init__.py +++ b/packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/platform-config/r0/src/python/x86_64_quanta_ly6_rangeley_r0/__init__.py @@ -1,16 +1,11 @@ from onl.platform.base import * from onl.platform.quanta import * -class OnlPlatform_x86_64_quanta_ly6_rangeley_r0(OnlPlatformQuanta): - - def model(self): - return "LY6" - - def platform(self): - return "x86-64-quanta-ly6-rangeley-r0" - - def sys_oid_platform(self): - return ".6.1" +class OnlPlatform_x86_64_quanta_ly6_rangeley_r0(OnlPlatformQuanta, + OnlPlatformPortConfig_32x40): + PLATFORM='x86-64-quanta-ly6-rangeley-r0' + MODEL='LY6' + SYS_OBJECT_ID='.6.1' def baseconfig(self): # fixme diff --git a/packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/platform-config/r0/src/python/x86_64_quanta_ly8_rangeley_r0/__init__.py b/packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/platform-config/r0/src/python/x86_64_quanta_ly8_rangeley_r0/__init__.py index c86405b1..899e821c 100644 --- a/packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/platform-config/r0/src/python/x86_64_quanta_ly8_rangeley_r0/__init__.py +++ b/packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/platform-config/r0/src/python/x86_64_quanta_ly8_rangeley_r0/__init__.py @@ -1,16 +1,11 @@ from onl.platform.base import * from onl.platform.quanta import * -class OnlPlatform_x86_64_quanta_ly8_rangeley_r0(OnlPlatformQuanta): - - def model(self): - return "LY8" - - def platform(self): - return "x86-64-quanta-ly8-rangeley-r0" - - def sys_oid_platform(self): - return ".8.1" +class OnlPlatform_x86_64_quanta_ly8_rangeley_r0(OnlPlatformQuanta, + OnlPlatformPortConfig_48x10_6x40): + PLATFORM='x86-64-quanta-ly8-rangeley-r0' + MODEL="LY8" + SYS_OBJECT_ID=".8.1" def baseconfig(self): # fixme diff --git a/packages/platforms/wnc/vendor-config/src/python/wnc/__init__.py b/packages/platforms/wnc/vendor-config/src/python/wnc/__init__.py index 2002920a..1d5c41fa 100644 --- a/packages/platforms/wnc/vendor-config/src/python/wnc/__init__.py +++ b/packages/platforms/wnc/vendor-config/src/python/wnc/__init__.py @@ -1,22 +1,7 @@ #!/usr/bin/python -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# OnlPlatform support for WNC platforms. -# -############################################################ + from onl.platform.base import * class OnlPlatformWNC(OnlPlatformBase): - def manufacturer(self): - return "WNC" - - def sys_oid_vendor(self): - return ".15756" + MANUFACTURER='WNC' + PRIVATE_ENTERPRISE_NUMBER=15756 From b4b6fea591f0d02163c1d092f505832696676b8a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:53:23 +0000 Subject: [PATCH 37/87] Latest --- packages/platforms-closed | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platforms-closed b/packages/platforms-closed index 5628d2f2..f46ee6c6 160000 --- a/packages/platforms-closed +++ b/packages/platforms-closed @@ -1 +1 @@ -Subproject commit 5628d2f2e43a78b9faa33428575e8e322899d3c7 +Subproject commit f46ee6c6480819d4fe5f56ccf9af0e17239d2b5a From 6985ec5cad1464252ef058f16ff1c3eeaf347474 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:54:19 +0000 Subject: [PATCH 38/87] X86 Fixes. --- .../vendor-config-onl/src/boot.d/62.upgrade-loader | 13 +++++++------ 1 file changed, 7 insertions(+), 6 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 94208553..bf9459a4 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 @@ -79,18 +79,19 @@ class Loader_Upgrade_x86_64(Loader_Upgrade): def do_upgrade(self, forced=False): X86_64_UPGRADE_DIR=sysconfig.upgrade.loader.package.dir - X86_64_UPGRADE_PATTERNS = [ "kernel-*", "initrd-*" ] + X86_64_UPGRADE_PATTERNS = [ "kernel-*", "*initrd*" ] - with OnlMountContext("ONL-BOOT", "rw", self.logger) as d: + with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d: for f in os.listdir(X86_64_UPGRADE_DIR): for pattern in X86_64_UPGRADE_PATTERNS: if fnmatch.fnmatch(f, pattern): self.copyfile(os.path.join(X86_64_UPGRADE_DIR, f), os.path.join(d.directory, f)) - src = "/lib/platform-config/current/onl/boot/grub.cfg" - dst = os.path.join(d.directory, "grub/grub.cfg") - if os.path.exists(src): - self.copyfile(src, dst) + # Disabled until it can be resolved with the new installer. + #src = "/lib/platform-config/current/onl/boot/grub.cfg" + #dst = os.path.join(d.directory, "grub/grub.cfg") + #if os.path.exists(src): + # self.copyfile(src, dst) self.reboot() From deb24fa9b704bb0b187e7e74f64bb77cfc7fe01e Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:54:50 +0000 Subject: [PATCH 39/87] Platform method updates. --- .../src/python/onl/platform/base.py | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) 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 874782a4..fca8e0c5 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 @@ -13,7 +13,6 @@ import pprint import json import os import re - import yaml import onl.YamlUtils @@ -173,14 +172,8 @@ class OnlPlatformBase(object): def baseconfig(self): return True - def manufacturer(self): - raise Exception("Manufacturer is not set.") - - def model(self): - raise Exception("Model is not set.") - def platform(self): - raise Exception("Platform is not set.") + return self.PLATFORM def baseplatform(self): p = self.platform() @@ -188,8 +181,7 @@ class OnlPlatformBase(object): return p def description(self): - return "%s %s (%s)" % (self.manufacturer(), self.model(), - self.platform()) + return "%s %s" % (self.MANUFACTURER, self.MODEL) def serialnumber(self): return self.onie_info.SERIAL_NUMBER @@ -200,8 +192,8 @@ class OnlPlatformBase(object): # ONL Platform Information Tree - def opit_oid(self): - return "1.3.6.1.4.1.37538.2.1000" + def platform_information_tree(self): + return "1.3.6.1.4.1.42623.1.1" # ONL Platform Information General Tree def opitg_oid(self): @@ -215,16 +207,11 @@ class OnlPlatformBase(object): def opitv_oid(self): return self.opit_oid() + ".2" - def sys_oid_vendor(self): - return ".37538" - def sys_oid_platform(self): raise Exception("sys_oid_platform() is not set.") def sys_object_id(self): - return ( self.opitv_oid() + - self.sys_oid_vendor() + - self.sys_oid_platform()); + return "%s.%s%s" % (self.opitv_oid(), self.PRIVATE_ENTERPRISE_NUMBER, self.SYS_OBJECT_ID) def onie_version(self): return self.onie_info.ONIE_VERSION @@ -270,19 +257,18 @@ class OnlPlatformBase(object): return 2 def __str__(self): - s = """Manufacturer: %s -Model: %s -Platform: %s -Description: %s + s = """Model: %s +Manufacturer: %s +Ports: %s (%s) System Object Id: %s System Information: %s %s """ % ( - self.manufacturer(), - self.model(), - self.platform(), - self.description(), + self.MODEL, + self.MANUFACTURER, + self.PORT_COUNT, + self.PORT_CONFIG, self.sys_object_id(), str(self.onie_info), str(self.platform_info), @@ -298,7 +284,22 @@ Warning: %s return s +class OnlPlatformPortConfig_48x1_4x10(object): + PORT_COUNT=52 + PORT_CONFIG="48x1 + 4x10" +class OnlPlatformPortConfig_48x10_4x40(object): + PORT_COUNT=52 + PORT_CONFIG="48x10 + 4x40" +class OnlPlatformPortConfig_48x10_6x40(object): + PORT_COUNT=54 + PORT_CONFIG="48x10 + 6x40" +class OnlPlatformPortConfig_32x40(object): + PORT_COUNT=32 + PORT_CONFIG="32x40" +class OnlPlatformPortConfig_32x100(object): + PORT_COUNT=32 + PORT_CONFIG="32x100" From a7d40d389839a7ac9a46551e68e3fef37240abe9 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:55:08 +0000 Subject: [PATCH 40/87] Copy filenames as-is. --- packages/base/amd64/upgrade/builds/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/base/amd64/upgrade/builds/Makefile b/packages/base/amd64/upgrade/builds/Makefile index b95deb4a..0aa20caa 100644 --- a/packages/base/amd64/upgrade/builds/Makefile +++ b/packages/base/amd64/upgrade/builds/Makefile @@ -12,7 +12,7 @@ MANIFEST := $(shell $(ONLPM) --find-file onl-loader-initrd:amd64 manifest.json) all: mkdir -p files cp $(KERNELS) files - cp $(INITRD) files/initrd-amd64 + cp $(INITRD) files cp $(MANIFEST) files From 6adf798d6fc76e8096ec448251ec62b7aac53c7f Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:55:31 +0000 Subject: [PATCH 41/87] Add argparse with help. --- tools/onlplatform.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) mode change 100644 => 100755 tools/onlplatform.py diff --git a/tools/onlplatform.py b/tools/onlplatform.py old mode 100644 new mode 100755 index 633bc722..119213d3 --- a/tools/onlplatform.py +++ b/tools/onlplatform.py @@ -8,6 +8,7 @@ the platform package metadata. import sys, os import itertools +import argparse toolsdir = os.path.dirname(os.path.abspath(__file__)) sys.path.append(toolsdir) @@ -23,9 +24,11 @@ from onlpm import * pm = defaultPm() -platform = sys.argv[1] -arch = sys.argv[2] -key = sys.argv[3] +ap = argparse.ArgumentParser("ONL Platform Data Extractor.") +ap.add_argument("platform", help="Platform name") +ap.add_argument("arch", help="Architecture") +ap.add_argument("key", help="Lookup key.") +ops = ap.parse_args() def extractKey(platform, arch, key): @@ -71,12 +74,12 @@ def extractVendor(platform, arch): l = [x for x in l if x.startswith('onl-vendor-config-')] return "\n".join(l) -if key in ('kernel', 'initrd', 'dtb', 'itb',): - print extractKey(platform, arch, key) +if ops.key in ('kernel', 'initrd', 'dtb', 'itb',): + print extractKey(ops.platform, ops.arch, ops.key) sys.exit(0) -if key == 'vendor': - print extractVendor(platform, arch) +if ops.key == 'vendor': + print extractVendor(ops.platform, ops.arch) sys.exit(0) -raise SystemExit("invalid key %s" % key) +raise SystemExit("invalid key %s" % ops.key) From e731daed092d1a438909c6d4b610eeaabe9ffce0 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 14 Jun 2016 15:58:43 +0000 Subject: [PATCH 42/87] Platform mini-cleanup. --- .../x86_64_facebook_wedge100_r0/__init__.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py index b6a287be..5a948e2c 100644 --- a/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py +++ b/packages/platforms/accton/x86-64/x86-64-facebook-wedge100/platform-config/r0/src/python/x86_64_facebook_wedge100_r0/__init__.py @@ -1,16 +1,8 @@ from onl.platform.base import * from onl.vendor.accton import * -class OnlPlatform_x86_64_facebook_wedge_100_r0(OpenNetworkPlatformAccton): - - def model(self): - return "Wedge-100" - - def platform(self): - return "x86-64-facebook-wedge100-r0" - - def baseconfig(self): - return True - - def sys_oid_platform(self): - return ".100.1" +class OnlPlatform_x86_64_facebook_wedge_100_r0(OnlPlatformAccton, + OnlPlatformPortConfig_32x100): + MODEL="Wedge-100" + PLATFORM="x86-64-facebook-wedge100-r0" + SYS_OBJECT_ID=".100.1" From 111b433e05ce8e8d3e6fc48df91e86c8c1ff6fdb Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 15 Jun 2016 20:38:41 +0000 Subject: [PATCH 43/87] Fix manufacturer value. --- packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py b/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py index c6122468..9ab43132 100644 --- a/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py +++ b/packages/platforms/kvm/vendor-config/src/python/kvm/__init__.py @@ -3,5 +3,5 @@ from onl.platform.base import * class OnlPlatformKVM(OnlPlatformBase): - MANUFACTURER=KVM + MANUFACTURER='KVM' PRIVATE_ENTERPRISE_NUMBER=42623 From d763000af8a3fe36b477d201db2efb4a05ac9f1f Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 17 Jun 2016 17:17:53 +0000 Subject: [PATCH 44/87] Add module declaration file. --- packages/base/any/faultd/src/.module | 1 + packages/base/any/onlp/src/onlp/.module | 1 + packages/base/any/onlp/src/onlp_platform_defaults/.module | 1 + packages/base/any/onlp/src/onlpie/.module | 1 + packages/base/any/onlp/src/onlplib/.module | 1 + packages/base/any/onlp/src/sff/.module | 1 + packages/base/any/oom-shim/src/.module | 1 + .../onlp/builds/src/arm_accton_as4610_54/.module | 1 + .../powerpc/powerpc-accton-as4600-54t/onlp/builds/src/.module | 1 + .../powerpc/powerpc-accton-as5610-52x/onlp/builds/src/.module | 1 + .../powerpc/powerpc-accton-as5710-54x/onlp/builds/src/.module | 1 + .../powerpc/powerpc-accton-as6700-32x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as5512-54x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as5712-54x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as5812-54t/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as5812-54x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as6712-32x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as6812-32x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as7512-32x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as7712-32x/onlp/builds/src/.module | 1 + .../x86-64/x86-64-accton-as7716-32x/onlp/builds/src/.module | 1 + .../onlp/builds/src/x86_64_cel_redstone_xp/.module | 1 + .../x86-64-kvm-x86-64/onlp/builds/src/x86_64_kvm_x86_64/.module | 1 + .../arm/arm-qemu-armv7a/onlp/builds/src/arm_qemu_armv7a/.module | 1 + packages/platforms/quanta/any/src/quanta_sys_eeprom/.module | 1 + .../quanta/powerpc/powerpc-quanta-lb9/onlp/builds/src/.module | 1 + .../quanta/powerpc/powerpc-quanta-ly2/onlp/builds/src/.module | 1 + .../onlp/builds/src/x86_64_quanta_ly6_rangeley/.module | 1 + .../onlp/builds/src/x86_64_quanta_ly8_rangeley/.module | 1 + 29 files changed, 29 insertions(+) create mode 100644 packages/base/any/faultd/src/.module create mode 100644 packages/base/any/onlp/src/onlp/.module create mode 100644 packages/base/any/onlp/src/onlp_platform_defaults/.module create mode 100644 packages/base/any/onlp/src/onlpie/.module create mode 100644 packages/base/any/onlp/src/onlplib/.module create mode 100644 packages/base/any/onlp/src/sff/.module create mode 100644 packages/base/any/oom-shim/src/.module create mode 100644 packages/platforms/accton/armel/arm-accton-as4610-54/onlp/builds/src/arm_accton_as4610_54/.module create mode 100644 packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/onlp/builds/src/.module create mode 100644 packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/.module create mode 100644 packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/onlp/builds/src/.module create mode 100644 packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/onlp/builds/src/x86_64_cel_redstone_xp/.module create mode 100644 packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/onlp/builds/src/x86_64_kvm_x86_64/.module create mode 100644 packages/platforms/qemu/arm/arm-qemu-armv7a/onlp/builds/src/arm_qemu_armv7a/.module create mode 100644 packages/platforms/quanta/any/src/quanta_sys_eeprom/.module create mode 100644 packages/platforms/quanta/powerpc/powerpc-quanta-lb9/onlp/builds/src/.module create mode 100644 packages/platforms/quanta/powerpc/powerpc-quanta-ly2/onlp/builds/src/.module create mode 100644 packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/onlp/builds/src/x86_64_quanta_ly6_rangeley/.module create mode 100644 packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/onlp/builds/src/x86_64_quanta_ly8_rangeley/.module diff --git a/packages/base/any/faultd/src/.module b/packages/base/any/faultd/src/.module new file mode 100644 index 00000000..7c16ebc0 --- /dev/null +++ b/packages/base/any/faultd/src/.module @@ -0,0 +1 @@ +name: faultd diff --git a/packages/base/any/onlp/src/onlp/.module b/packages/base/any/onlp/src/onlp/.module new file mode 100644 index 00000000..7e44ab77 --- /dev/null +++ b/packages/base/any/onlp/src/onlp/.module @@ -0,0 +1 @@ +name: onlp diff --git a/packages/base/any/onlp/src/onlp_platform_defaults/.module b/packages/base/any/onlp/src/onlp_platform_defaults/.module new file mode 100644 index 00000000..170382ab --- /dev/null +++ b/packages/base/any/onlp/src/onlp_platform_defaults/.module @@ -0,0 +1 @@ +name: onlp_platform_defaults diff --git a/packages/base/any/onlp/src/onlpie/.module b/packages/base/any/onlp/src/onlpie/.module new file mode 100644 index 00000000..ae83c4af --- /dev/null +++ b/packages/base/any/onlp/src/onlpie/.module @@ -0,0 +1 @@ +name: onlpie diff --git a/packages/base/any/onlp/src/onlplib/.module b/packages/base/any/onlp/src/onlplib/.module new file mode 100644 index 00000000..215a822f --- /dev/null +++ b/packages/base/any/onlp/src/onlplib/.module @@ -0,0 +1 @@ +name: onlplib diff --git a/packages/base/any/onlp/src/sff/.module b/packages/base/any/onlp/src/sff/.module new file mode 100644 index 00000000..05da7c63 --- /dev/null +++ b/packages/base/any/onlp/src/sff/.module @@ -0,0 +1 @@ +name: sff diff --git a/packages/base/any/oom-shim/src/.module b/packages/base/any/oom-shim/src/.module new file mode 100644 index 00000000..4375dfb7 --- /dev/null +++ b/packages/base/any/oom-shim/src/.module @@ -0,0 +1 @@ +name: oom_shim diff --git a/packages/platforms/accton/armel/arm-accton-as4610-54/onlp/builds/src/arm_accton_as4610_54/.module b/packages/platforms/accton/armel/arm-accton-as4610-54/onlp/builds/src/arm_accton_as4610_54/.module new file mode 100644 index 00000000..5d4aa1c0 --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610-54/onlp/builds/src/arm_accton_as4610_54/.module @@ -0,0 +1 @@ +name: arm_accton_as4610_54 diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/onlp/builds/src/.module b/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/onlp/builds/src/.module new file mode 100644 index 00000000..d0bb8fce --- /dev/null +++ b/packages/platforms/accton/powerpc/powerpc-accton-as4600-54t/onlp/builds/src/.module @@ -0,0 +1 @@ +name: powerpc_accton_as4600_54t diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/onlp/builds/src/.module b/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/onlp/builds/src/.module new file mode 100644 index 00000000..0473ac44 --- /dev/null +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5610-52x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: powerpc_accton_as5610_52x diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/onlp/builds/src/.module b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/onlp/builds/src/.module new file mode 100644 index 00000000..995be2d9 --- /dev/null +++ b/packages/platforms/accton/powerpc/powerpc-accton-as5710-54x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: powerpc_accton_as5710_54x diff --git a/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/onlp/builds/src/.module b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/onlp/builds/src/.module new file mode 100644 index 00000000..d67e500e --- /dev/null +++ b/packages/platforms/accton/powerpc/powerpc-accton-as6700-32x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: powerpc_accton_as6700_32x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/onlp/builds/src/.module new file mode 100644 index 00000000..a0ea32d6 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as5512_54x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/onlp/builds/src/.module new file mode 100644 index 00000000..640b7bc3 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5712-54x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as5712_54x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/onlp/builds/src/.module new file mode 100644 index 00000000..c4ba62ca --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54t/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as5812_54t diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/.module new file mode 100644 index 00000000..ffe27dc2 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5812-54x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as5812_54x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/onlp/builds/src/.module new file mode 100644 index 00000000..e6be11ba --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6712-32x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as6712_32x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/.module new file mode 100644 index 00000000..fd83f048 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as6812-32x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as6812_32x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/onlp/builds/src/.module new file mode 100644 index 00000000..74536d1b --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as7512_32x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/.module new file mode 100644 index 00000000..f49c1f82 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7712-32x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as7712_32x diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/onlp/builds/src/.module b/packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/onlp/builds/src/.module new file mode 100644 index 00000000..1bc87a11 --- /dev/null +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7716-32x/onlp/builds/src/.module @@ -0,0 +1 @@ +name: x86_64_accton_as7716_32x diff --git a/packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/onlp/builds/src/x86_64_cel_redstone_xp/.module b/packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/onlp/builds/src/x86_64_cel_redstone_xp/.module new file mode 100644 index 00000000..2aa1d02a --- /dev/null +++ b/packages/platforms/celestica/x86-64/x86-64-cel-redstone-xp/onlp/builds/src/x86_64_cel_redstone_xp/.module @@ -0,0 +1 @@ +name: x86_64_cel_redstone_xp diff --git a/packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/onlp/builds/src/x86_64_kvm_x86_64/.module b/packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/onlp/builds/src/x86_64_kvm_x86_64/.module new file mode 100644 index 00000000..b2f88a96 --- /dev/null +++ b/packages/platforms/kvm/x86-64/x86-64-kvm-x86-64/onlp/builds/src/x86_64_kvm_x86_64/.module @@ -0,0 +1 @@ +name: x86_64_kvm_x86_64 diff --git a/packages/platforms/qemu/arm/arm-qemu-armv7a/onlp/builds/src/arm_qemu_armv7a/.module b/packages/platforms/qemu/arm/arm-qemu-armv7a/onlp/builds/src/arm_qemu_armv7a/.module new file mode 100644 index 00000000..731284a9 --- /dev/null +++ b/packages/platforms/qemu/arm/arm-qemu-armv7a/onlp/builds/src/arm_qemu_armv7a/.module @@ -0,0 +1 @@ +name: arm_qemu_armv7a diff --git a/packages/platforms/quanta/any/src/quanta_sys_eeprom/.module b/packages/platforms/quanta/any/src/quanta_sys_eeprom/.module new file mode 100644 index 00000000..84e84b53 --- /dev/null +++ b/packages/platforms/quanta/any/src/quanta_sys_eeprom/.module @@ -0,0 +1 @@ +name: quanta_sys_eeprom diff --git a/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/onlp/builds/src/.module b/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/onlp/builds/src/.module new file mode 100644 index 00000000..f20123ae --- /dev/null +++ b/packages/platforms/quanta/powerpc/powerpc-quanta-lb9/onlp/builds/src/.module @@ -0,0 +1 @@ +name: powerpc_quanta_lb9 diff --git a/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/onlp/builds/src/.module b/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/onlp/builds/src/.module new file mode 100644 index 00000000..1c498acd --- /dev/null +++ b/packages/platforms/quanta/powerpc/powerpc-quanta-ly2/onlp/builds/src/.module @@ -0,0 +1 @@ +name: powerpc_quanta_ly2 diff --git a/packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/onlp/builds/src/x86_64_quanta_ly6_rangeley/.module b/packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/onlp/builds/src/x86_64_quanta_ly6_rangeley/.module new file mode 100644 index 00000000..c8d72261 --- /dev/null +++ b/packages/platforms/quanta/x86-64/x86-64-quanta-ly6-rangeley/onlp/builds/src/x86_64_quanta_ly6_rangeley/.module @@ -0,0 +1 @@ +name: x86_64_quanta_ly6_rangeley diff --git a/packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/onlp/builds/src/x86_64_quanta_ly8_rangeley/.module b/packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/onlp/builds/src/x86_64_quanta_ly8_rangeley/.module new file mode 100644 index 00000000..d49ebd6d --- /dev/null +++ b/packages/platforms/quanta/x86-64/x86-64-quanta-ly8-rangeley/onlp/builds/src/x86_64_quanta_ly8_rangeley/.module @@ -0,0 +1 @@ +name: x86_64_quanta_ly8_rangeley From bdaa49a88ded35a7fd5616dd49a9b7d7e5ce74e8 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 17 Jun 2016 17:27:00 +0000 Subject: [PATCH 45/87] Latest --- packages/platforms-closed | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platforms-closed b/packages/platforms-closed index f46ee6c6..2292f628 160000 --- a/packages/platforms-closed +++ b/packages/platforms-closed @@ -1 +1 @@ -Subproject commit f46ee6c6480819d4fe5f56ccf9af0e17239d2b5a +Subproject commit 2292f6285fafac230cbf0b1e9bc49321bc2a0b96 From ccbca0e30b254bcb8db65a73adac7375ebea5b7f Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Sat, 18 Jun 2016 00:32:44 +0000 Subject: [PATCH 46/87] Add module declaration file. --- packages/base/any/onlp-snmpd/builds/src/onlp_snmp/.module | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/base/any/onlp-snmpd/builds/src/onlp_snmp/.module diff --git a/packages/base/any/onlp-snmpd/builds/src/onlp_snmp/.module b/packages/base/any/onlp-snmpd/builds/src/onlp_snmp/.module new file mode 100644 index 00000000..d299f1b9 --- /dev/null +++ b/packages/base/any/onlp-snmpd/builds/src/onlp_snmp/.module @@ -0,0 +1 @@ +name: onlp_snmp From 04369e5469891c43a2dd1e37b58fdda5764e2c90 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Sat, 18 Jun 2016 00:35:21 +0000 Subject: [PATCH 47/87] Latest --- sm/bigcode | 2 +- sm/infra | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sm/bigcode b/sm/bigcode index a5e6bc1d..fdc0f796 160000 --- a/sm/bigcode +++ b/sm/bigcode @@ -1 +1 @@ -Subproject commit a5e6bc1d768a40a527e853e6c789c5a9eaf5159d +Subproject commit fdc0f7964694f3b2c4c6d57f974af2bd7a877386 diff --git a/sm/infra b/sm/infra index a7a62f56..e501832c 160000 --- a/sm/infra +++ b/sm/infra @@ -1 +1 @@ -Subproject commit a7a62f563a992eeefdb53c4f2b9fb634304fe860 +Subproject commit e501832cf585405ab8ba66fa0ee4a42d27ead088 From abf7e4f94537c330f57f2e9a3badf467c40ea7fa Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Sat, 18 Jun 2016 00:35:50 +0000 Subject: [PATCH 48/87] New config format for the module manifest generator. --- make/config.mk | 2 +- make/mmg.yml | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 make/mmg.yml diff --git a/make/config.mk b/make/config.mk index cd957fba..0e8c23aa 100644 --- a/make/config.mk +++ b/make/config.mk @@ -27,7 +27,7 @@ export ONL_DEBIAN_SUITE_$(ONL_DEBIAN_SUITE)=1 export BUILD_DIR_BASE=BUILD/$(ONL_DEBIAN_SUITE) # Generate manifest if necessary -export MODULEMANIFEST := $(shell $(BUILDER)/tools/mmg.py --dirs $(ONL) $(ONLPM_OPTION_PACKAGEDIRS) --out $(ONL)/make/module-manifest.mk --only-if-missing make) +export MODULEMANIFEST := $(shell $(BUILDER)/tools/mmg.py $(ONL)/make/mmg.yml $(ONL) --only-if-missing) # Generate versions if necessary. $(shell $(ONL)/tools/make-versions.py --import-file=$(ONL)/tools/onlvi --class-name=OnlVersionImplementation --output-dir $(ONL)/make/versions) diff --git a/make/mmg.yml b/make/mmg.yml new file mode 100644 index 00000000..e6c9626e --- /dev/null +++ b/make/mmg.yml @@ -0,0 +1,9 @@ +directories: + - . + +manifest: make/module-manifest.mk + + + + + From b46c31370ea93170944193c22e00ae9c03a285fa Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Sat, 18 Jun 2016 19:05:28 +0000 Subject: [PATCH 49/87] OpenSSL Parallel Build Patch The patch incorporates the functionality of the existing dont-build-docs patch (which is now removed at setup). --- .../any/initrds/buildroot/builds/Makefile | 2 + .../openssl-1.0.1-parallel-build.patch | 354 ++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 packages/base/any/initrds/buildroot/builds/patches/openssl-1.0.1-parallel-build.patch diff --git a/packages/base/any/initrds/buildroot/builds/Makefile b/packages/base/any/initrds/buildroot/builds/Makefile index 609e382d..57b5ed0c 100644 --- a/packages/base/any/initrds/buildroot/builds/Makefile +++ b/packages/base/any/initrds/buildroot/builds/Makefile @@ -31,6 +31,8 @@ clean: setup: setup-pyroute2 setup-dnspython setup-libyaml setup-pyyaml setup-jq setup-pyparted cp $(wildcard patches/busybox*.patch) $(BUILDROOT_SOURCE)/package/busybox/ cp $(wildcard patches/kexec*.patch) $(BUILDROOT_SOURCE)/package/kexec/ + cp $(wildcard patches/openssl*.patch) $(BUILDROOT_SOURCE)/package/openssl/ + rm $(BUILDROOT_SOURCE)/package/openssl/openssl-do-not-build-docs.patch sed -i 's%^DOSFSTOOLS_SITE =.*%DOSFSTOOLS_SITE = http://downloads.openwrt.org/sources%' $(BUILDROOT_SOURCE)/package/dosfstools/dosfstools.mk sed -i 's%^UEMACS_SITE =.*%UEMACS_SITE = http://www.kernel.org/pub/linux/kernel/uemacs%;s%^UEMACS_SOURCE =.*%UEMACS_SOURCE = em-$$(UEMACS_VERSION).tar.gz%' $(BUILDROOT_SOURCE)/package/uemacs/uemacs.mk mkdir -p $(BUILDROOT_ARCHDIRS) diff --git a/packages/base/any/initrds/buildroot/builds/patches/openssl-1.0.1-parallel-build.patch b/packages/base/any/initrds/buildroot/builds/patches/openssl-1.0.1-parallel-build.patch new file mode 100644 index 00000000..8c0fc1b7 --- /dev/null +++ b/packages/base/any/initrds/buildroot/builds/patches/openssl-1.0.1-parallel-build.patch @@ -0,0 +1,354 @@ +http://rt.openssl.org/Ticket/Display.html?id=2084 + +--- a/Makefile.org ++++ b/Makefile.org +@@ -247,17 +247,17 @@ + build_libs: build_crypto build_ssl build_engines + + build_crypto: +- @dir=crypto; target=all; $(BUILD_ONE_CMD) ++ +@dir=crypto; target=all; $(BUILD_ONE_CMD) +-build_ssl: ++build_ssl: build_crypto +- @dir=ssl; target=all; $(BUILD_ONE_CMD) ++ +@dir=ssl; target=all; $(BUILD_ONE_CMD) +-build_engines: ++build_engines: build_crypto +- @dir=engines; target=all; $(BUILD_ONE_CMD) ++ +@dir=engines; target=all; $(BUILD_ONE_CMD) +-build_apps: ++build_apps: build_libs +- @dir=apps; target=all; $(BUILD_ONE_CMD) ++ +@dir=apps; target=all; $(BUILD_ONE_CMD) +-build_tests: ++build_tests: build_libs +- @dir=test; target=all; $(BUILD_ONE_CMD) ++ +@dir=test; target=all; $(BUILD_ONE_CMD) +-build_tools: ++build_tools: build_libs +- @dir=tools; target=all; $(BUILD_ONE_CMD) ++ +@dir=tools; target=all; $(BUILD_ONE_CMD) + + all_testapps: build_libs build_testapps + build_testapps: +@@ -497,9 +497,9 @@ + dist_pem_h: + (cd crypto/pem; $(MAKE) -e $(BUILDENV) pem.h; $(MAKE) clean) + +-install: all install_docs install_sw ++install: install_sw + +-install_sw: ++install_dirs: + @$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \ + $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \ + $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \ +@@ -508,6 +508,13 @@ + $(INSTALL_PREFIX)$(OPENSSLDIR)/misc \ + $(INSTALL_PREFIX)$(OPENSSLDIR)/certs \ + $(INSTALL_PREFIX)$(OPENSSLDIR)/private ++ @$(PERL) $(TOP)/util/mkdir-p.pl \ ++ $(INSTALL_PREFIX)$(MANDIR)/man1 \ ++ $(INSTALL_PREFIX)$(MANDIR)/man3 \ ++ $(INSTALL_PREFIX)$(MANDIR)/man5 \ ++ $(INSTALL_PREFIX)$(MANDIR)/man7 ++ ++install_sw: install_dirs + @set -e; headerlist="$(EXHEADER)"; for i in $$headerlist;\ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ +@@ -511,7 +511,7 @@ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; +- @set -e; target=install; $(RECURSIVE_BUILD_CMD) ++ +@set -e; target=install; $(RECURSIVE_BUILD_CMD) + @set -e; liblist="$(LIBS)"; for i in $$liblist ;\ + do \ + if [ -f "$$i" ]; then \ +@@ -593,12 +600,7 @@ + done; \ + done + +-install_docs: +- @$(PERL) $(TOP)/util/mkdir-p.pl \ +- $(INSTALL_PREFIX)$(MANDIR)/man1 \ +- $(INSTALL_PREFIX)$(MANDIR)/man3 \ +- $(INSTALL_PREFIX)$(MANDIR)/man5 \ +- $(INSTALL_PREFIX)$(MANDIR)/man7 ++install_docs: install_dirs + @pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \ + here="`pwd`"; \ + filecase=; \ +--- a/Makefile.shared ++++ b/Makefile.shared +@@ -105,6 +105,7 @@ LINK_SO= \ + SHAREDFLAGS="$${SHAREDFLAGS:-$(CFLAGS) $(SHARED_LDFLAGS)}"; \ + LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \ + LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \ ++ [ -e $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX ] && exit 0; \ + LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \ + $${SHAREDCMD} $${SHAREDFLAGS} \ + -o $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \ +@@ -122,6 +124,7 @@ SYMLINK_SO= \ + done; \ + fi; \ + if [ -n "$$SHLIB_SOVER" ]; then \ ++ [ -e "$$SHLIB$$SHLIB_SUFFIX" ] || \ + ( $(SET_X); rm -f $$SHLIB$$SHLIB_SUFFIX; \ + ln -s $$prev $$SHLIB$$SHLIB_SUFFIX ); \ + fi; \ +--- a/crypto/Makefile ++++ b/crypto/Makefile +@@ -85,11 +85,11 @@ + @if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi + + subdirs: +- @target=all; $(RECURSIVE_MAKE) ++ +@target=all; $(RECURSIVE_MAKE) + + files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO +- @target=files; $(RECURSIVE_MAKE) ++ +@target=files; $(RECURSIVE_MAKE) + + links: + @$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER) +@@ -100,7 +100,7 @@ + # lib: $(LIB): are splitted to avoid end-less loop + lib: $(LIB) + @touch lib +-$(LIB): $(LIBOBJ) ++$(LIB): $(LIBOBJ) | subdirs + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + +@@ -110,7 +110,7 @@ + fi + + libs: +- @target=lib; $(RECURSIVE_MAKE) ++ +@target=lib; $(RECURSIVE_MAKE) + + install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... +@@ -119,7 +119,7 @@ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; +- @target=install; $(RECURSIVE_MAKE) ++ +@target=install; $(RECURSIVE_MAKE) + + lint: + @target=lint; $(RECURSIVE_MAKE) +--- a/engines/Makefile ++++ b/engines/Makefile +@@ -72,7 +72,7 @@ + + all: lib subdirs + +-lib: $(LIBOBJ) ++lib: $(LIBOBJ) | subdirs + @if [ -n "$(SHARED_LIBS)" ]; then \ + set -e; \ + for l in $(LIBNAMES); do \ +@@ -89,7 +89,7 @@ + + subdirs: + echo $(EDIRS) +- @target=all; $(RECURSIVE_MAKE) ++ +@target=all; $(RECURSIVE_MAKE) + + files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO +@@ -128,7 +128,7 @@ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx ); \ + done; \ + fi +- @target=install; $(RECURSIVE_MAKE) ++ +@target=install; $(RECURSIVE_MAKE) + + tags: + ctags $(SRC) +--- a/test/Makefile ++++ b/test/Makefile +@@ -123,7 +123,7 @@ + tags: + ctags $(SRC) + +-tests: exe apps $(TESTS) ++tests: exe $(TESTS) + + apps: + @(cd ..; $(MAKE) DIRS=apps all) +@@ -365,109 +365,109 @@ + link_app.$${shlib_target} + + $(RSATEST)$(EXE_EXT): $(RSATEST).o $(DLIBCRYPTO) +- @target=$(RSATEST); $(BUILD_CMD) ++ +@target=$(RSATEST); $(BUILD_CMD) + + $(BNTEST)$(EXE_EXT): $(BNTEST).o $(DLIBCRYPTO) +- @target=$(BNTEST); $(BUILD_CMD) ++ +@target=$(BNTEST); $(BUILD_CMD) + + $(ECTEST)$(EXE_EXT): $(ECTEST).o $(DLIBCRYPTO) +- @target=$(ECTEST); $(BUILD_CMD) ++ +@target=$(ECTEST); $(BUILD_CMD) + + $(EXPTEST)$(EXE_EXT): $(EXPTEST).o $(DLIBCRYPTO) +- @target=$(EXPTEST); $(BUILD_CMD) ++ +@target=$(EXPTEST); $(BUILD_CMD) + + $(IDEATEST)$(EXE_EXT): $(IDEATEST).o $(DLIBCRYPTO) +- @target=$(IDEATEST); $(BUILD_CMD) ++ +@target=$(IDEATEST); $(BUILD_CMD) + + $(MD2TEST)$(EXE_EXT): $(MD2TEST).o $(DLIBCRYPTO) +- @target=$(MD2TEST); $(BUILD_CMD) ++ +@target=$(MD2TEST); $(BUILD_CMD) + + $(SHATEST)$(EXE_EXT): $(SHATEST).o $(DLIBCRYPTO) +- @target=$(SHATEST); $(BUILD_CMD) ++ +@target=$(SHATEST); $(BUILD_CMD) + + $(SHA1TEST)$(EXE_EXT): $(SHA1TEST).o $(DLIBCRYPTO) +- @target=$(SHA1TEST); $(BUILD_CMD) ++ +@target=$(SHA1TEST); $(BUILD_CMD) + + $(SHA256TEST)$(EXE_EXT): $(SHA256TEST).o $(DLIBCRYPTO) +- @target=$(SHA256TEST); $(BUILD_CMD) ++ +@target=$(SHA256TEST); $(BUILD_CMD) + + $(SHA512TEST)$(EXE_EXT): $(SHA512TEST).o $(DLIBCRYPTO) +- @target=$(SHA512TEST); $(BUILD_CMD) ++ +@target=$(SHA512TEST); $(BUILD_CMD) + + $(RMDTEST)$(EXE_EXT): $(RMDTEST).o $(DLIBCRYPTO) +- @target=$(RMDTEST); $(BUILD_CMD) ++ +@target=$(RMDTEST); $(BUILD_CMD) + + $(MDC2TEST)$(EXE_EXT): $(MDC2TEST).o $(DLIBCRYPTO) +- @target=$(MDC2TEST); $(BUILD_CMD) ++ +@target=$(MDC2TEST); $(BUILD_CMD) + + $(MD4TEST)$(EXE_EXT): $(MD4TEST).o $(DLIBCRYPTO) +- @target=$(MD4TEST); $(BUILD_CMD) ++ +@target=$(MD4TEST); $(BUILD_CMD) + + $(MD5TEST)$(EXE_EXT): $(MD5TEST).o $(DLIBCRYPTO) +- @target=$(MD5TEST); $(BUILD_CMD) ++ +@target=$(MD5TEST); $(BUILD_CMD) + + $(HMACTEST)$(EXE_EXT): $(HMACTEST).o $(DLIBCRYPTO) +- @target=$(HMACTEST); $(BUILD_CMD) ++ +@target=$(HMACTEST); $(BUILD_CMD) + + $(WPTEST)$(EXE_EXT): $(WPTEST).o $(DLIBCRYPTO) +- @target=$(WPTEST); $(BUILD_CMD) ++ +@target=$(WPTEST); $(BUILD_CMD) + + $(RC2TEST)$(EXE_EXT): $(RC2TEST).o $(DLIBCRYPTO) +- @target=$(RC2TEST); $(BUILD_CMD) ++ +@target=$(RC2TEST); $(BUILD_CMD) + + $(BFTEST)$(EXE_EXT): $(BFTEST).o $(DLIBCRYPTO) +- @target=$(BFTEST); $(BUILD_CMD) ++ +@target=$(BFTEST); $(BUILD_CMD) + + $(CASTTEST)$(EXE_EXT): $(CASTTEST).o $(DLIBCRYPTO) +- @target=$(CASTTEST); $(BUILD_CMD) ++ +@target=$(CASTTEST); $(BUILD_CMD) + + $(RC4TEST)$(EXE_EXT): $(RC4TEST).o $(DLIBCRYPTO) +- @target=$(RC4TEST); $(BUILD_CMD) ++ +@target=$(RC4TEST); $(BUILD_CMD) + + $(RC5TEST)$(EXE_EXT): $(RC5TEST).o $(DLIBCRYPTO) +- @target=$(RC5TEST); $(BUILD_CMD) ++ +@target=$(RC5TEST); $(BUILD_CMD) + + $(DESTEST)$(EXE_EXT): $(DESTEST).o $(DLIBCRYPTO) +- @target=$(DESTEST); $(BUILD_CMD) ++ +@target=$(DESTEST); $(BUILD_CMD) + + $(RANDTEST)$(EXE_EXT): $(RANDTEST).o $(DLIBCRYPTO) +- @target=$(RANDTEST); $(BUILD_CMD) ++ +@target=$(RANDTEST); $(BUILD_CMD) + + $(DHTEST)$(EXE_EXT): $(DHTEST).o $(DLIBCRYPTO) +- @target=$(DHTEST); $(BUILD_CMD) ++ +@target=$(DHTEST); $(BUILD_CMD) + + $(DSATEST)$(EXE_EXT): $(DSATEST).o $(DLIBCRYPTO) +- @target=$(DSATEST); $(BUILD_CMD) ++ +@target=$(DSATEST); $(BUILD_CMD) + + $(METHTEST)$(EXE_EXT): $(METHTEST).o $(DLIBCRYPTO) +- @target=$(METHTEST); $(BUILD_CMD) ++ +@target=$(METHTEST); $(BUILD_CMD) + + $(SSLTEST)$(EXE_EXT): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO) +- @target=$(SSLTEST); $(FIPS_BUILD_CMD) ++ +@target=$(SSLTEST); $(FIPS_BUILD_CMD) + + $(ENGINETEST)$(EXE_EXT): $(ENGINETEST).o $(DLIBCRYPTO) +- @target=$(ENGINETEST); $(BUILD_CMD) ++ +@target=$(ENGINETEST); $(BUILD_CMD) + + $(EVPTEST)$(EXE_EXT): $(EVPTEST).o $(DLIBCRYPTO) +- @target=$(EVPTEST); $(BUILD_CMD) ++ +@target=$(EVPTEST); $(BUILD_CMD) + + $(ECDSATEST)$(EXE_EXT): $(ECDSATEST).o $(DLIBCRYPTO) +- @target=$(ECDSATEST); $(BUILD_CMD) ++ +@target=$(ECDSATEST); $(BUILD_CMD) + + $(ECDHTEST)$(EXE_EXT): $(ECDHTEST).o $(DLIBCRYPTO) +- @target=$(ECDHTEST); $(BUILD_CMD) ++ +@target=$(ECDHTEST); $(BUILD_CMD) + + $(IGETEST)$(EXE_EXT): $(IGETEST).o $(DLIBCRYPTO) +- @target=$(IGETEST); $(BUILD_CMD) ++ +@target=$(IGETEST); $(BUILD_CMD) + + $(JPAKETEST)$(EXE_EXT): $(JPAKETEST).o $(DLIBCRYPTO) +- @target=$(JPAKETEST); $(BUILD_CMD) ++ +@target=$(JPAKETEST); $(BUILD_CMD) + + $(ASN1TEST)$(EXE_EXT): $(ASN1TEST).o $(DLIBCRYPTO) +- @target=$(ASN1TEST); $(BUILD_CMD) ++ +@target=$(ASN1TEST); $(BUILD_CMD) + + $(SRPTEST)$(EXE_EXT): $(SRPTEST).o $(DLIBCRYPTO) +- @target=$(SRPTEST); $(BUILD_CMD) ++ +@target=$(SRPTEST); $(BUILD_CMD) + + #$(AESTEST).o: $(AESTEST).c + # $(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c +@@ -480,7 +480,7 @@ + # fi + + dummytest$(EXE_EXT): dummytest.o $(DLIBCRYPTO) +- @target=dummytest; $(BUILD_CMD) ++ +@target=dummytest; $(BUILD_CMD) + + # DO NOT DELETE THIS LINE -- make depend depends on it. + +--- a/crypto/objects/Makefile ++++ b/crypto/objects/Makefile +@@ -44,11 +44,11 @@ obj_dat.h: obj_dat.pl obj_mac.h + # objects.pl both reads and writes obj_mac.num + obj_mac.h: objects.pl objects.txt obj_mac.num + $(PERL) objects.pl objects.txt obj_mac.num obj_mac.h +- @sleep 1; touch obj_mac.h; sleep 1 + +-obj_xref.h: objxref.pl obj_xref.txt obj_mac.num ++# This doesn't really need obj_mac.h, but since that rule reads & writes ++# obj_mac.num, we can't run in parallel with it. ++obj_xref.h: objxref.pl obj_xref.txt obj_mac.num obj_mac.h + $(PERL) objxref.pl obj_mac.num obj_xref.txt > obj_xref.h +- @sleep 1; touch obj_xref.h; sleep 1 + + files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO From 76d8a0aea30709fd47c136a38c25cd2544a79f98 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 20 Jun 2016 15:05:48 +0000 Subject: [PATCH 50/87] The legacy installers have been removed. --- builds/amd64/installer/legacy/Makefile | 1 - builds/amd64/installer/legacy/PKG.yml | 2 - .../amd64/installer/legacy/builds/.gitignore | 6 - builds/amd64/installer/legacy/builds/Makefile | 43 -- .../legacy/builds/amd64-installer.sh | 437 ------------------ .../amd64/installer/legacy/builds/boot-config | 4 - builds/any/installer/legacy/APKG.yml | 27 -- .../any/installer/legacy/fit/builds/Makefile | 43 -- .../installer/legacy/fit/builds/boot-config | 4 - .../legacy/fit/builds/fit-install-lib | 412 ----------------- .../legacy/fit/builds/fit-installer.sh | 116 ----- builds/armel/installer/legacy/Makefile | 1 - builds/armel/installer/legacy/PKG.yml | 1 - .../armel/installer/legacy/builds/.gitignore | 3 - builds/armel/installer/legacy/builds/Makefile | 2 - builds/powerpc/installer/legacy/Makefile | 1 - builds/powerpc/installer/legacy/PKG.yml | 2 - .../installer/legacy/builds/.gitignore | 3 - .../powerpc/installer/legacy/builds/Makefile | 3 - .../installer/legacy/builds/ppc/libblkid.so.1 | Bin 134556 -> 0 bytes .../legacy/builds/ppc/libcom_err.so.2 | Bin 9896 -> 0 bytes .../installer/legacy/builds/ppc/libdl.so.0 | Bin 13348 -> 0 bytes .../installer/legacy/builds/ppc/libe2p.so.2 | Bin 23312 -> 0 bytes .../legacy/builds/ppc/libext2fs.so.2 | Bin 216796 -> 0 bytes .../legacy/builds/ppc/libpthread.so.0 | Bin 71544 -> 0 bytes .../installer/legacy/builds/ppc/libuuid.so.1 | Bin 13968 -> 0 bytes .../installer/legacy/builds/ppc/mke2fs | Bin 71408 -> 0 bytes .../installer/legacy/builds/ppc/mkfs.ext2 | 3 - 28 files changed, 1114 deletions(-) delete mode 100644 builds/amd64/installer/legacy/Makefile delete mode 100644 builds/amd64/installer/legacy/PKG.yml delete mode 100644 builds/amd64/installer/legacy/builds/.gitignore delete mode 100644 builds/amd64/installer/legacy/builds/Makefile delete mode 100644 builds/amd64/installer/legacy/builds/amd64-installer.sh delete mode 100644 builds/amd64/installer/legacy/builds/boot-config delete mode 100644 builds/any/installer/legacy/APKG.yml delete mode 100644 builds/any/installer/legacy/fit/builds/Makefile delete mode 100644 builds/any/installer/legacy/fit/builds/boot-config delete mode 100644 builds/any/installer/legacy/fit/builds/fit-install-lib delete mode 100644 builds/any/installer/legacy/fit/builds/fit-installer.sh delete mode 100644 builds/armel/installer/legacy/Makefile delete mode 100644 builds/armel/installer/legacy/PKG.yml delete mode 100644 builds/armel/installer/legacy/builds/.gitignore delete mode 100644 builds/armel/installer/legacy/builds/Makefile delete mode 100644 builds/powerpc/installer/legacy/Makefile delete mode 100644 builds/powerpc/installer/legacy/PKG.yml delete mode 100644 builds/powerpc/installer/legacy/builds/.gitignore delete mode 100644 builds/powerpc/installer/legacy/builds/Makefile delete mode 100644 builds/powerpc/installer/legacy/builds/ppc/libblkid.so.1 delete mode 100644 builds/powerpc/installer/legacy/builds/ppc/libcom_err.so.2 delete mode 100644 builds/powerpc/installer/legacy/builds/ppc/libdl.so.0 delete mode 100644 builds/powerpc/installer/legacy/builds/ppc/libe2p.so.2 delete mode 100644 builds/powerpc/installer/legacy/builds/ppc/libext2fs.so.2 delete mode 100644 builds/powerpc/installer/legacy/builds/ppc/libpthread.so.0 delete mode 100644 builds/powerpc/installer/legacy/builds/ppc/libuuid.so.1 delete mode 100755 builds/powerpc/installer/legacy/builds/ppc/mke2fs delete mode 100755 builds/powerpc/installer/legacy/builds/ppc/mkfs.ext2 diff --git a/builds/amd64/installer/legacy/Makefile b/builds/amd64/installer/legacy/Makefile deleted file mode 100644 index 003238cf..00000000 --- a/builds/amd64/installer/legacy/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/builds/amd64/installer/legacy/PKG.yml b/builds/amd64/installer/legacy/PKG.yml deleted file mode 100644 index a2932590..00000000 --- a/builds/amd64/installer/legacy/PKG.yml +++ /dev/null @@ -1,2 +0,0 @@ -!include $ONL/builds/any/installer/legacy/APKG.yml ARCH=amd64 - diff --git a/builds/amd64/installer/legacy/builds/.gitignore b/builds/amd64/installer/legacy/builds/.gitignore deleted file mode 100644 index 80d5c25e..00000000 --- a/builds/amd64/installer/legacy/builds/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*INSTALLER -kernel-* -initrd-* -lib/ -usr/ - diff --git a/builds/amd64/installer/legacy/builds/Makefile b/builds/amd64/installer/legacy/builds/Makefile deleted file mode 100644 index e5c06989..00000000 --- a/builds/amd64/installer/legacy/builds/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -include $(ONL)/make/config.amd64.mk - -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) - -INITRD := $(shell $(ONLPM) --find-file onl-loader-initrd:amd64 onl-loader-initrd-amd64.cpio.gz) -PLATFORMS := $(shell $(ONLPM) --platform-manifest onl-loader-initrd:amd64) - -MKSHAR = $(ONL)/tools/mkshar -MKSHAR_OPTS = --lazy --unzip-pad --fixup-perms autoperms.sh -MKSHAR_PERMS = autoperms.sh - - -# Hardcoded to match ONL File naming conventions. -include $(ONL)/make/versions/version-onl.mk -INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_LEGACY_INSTALLER - - - -__installer: - $(ONL_V_at)rm -rf *INSTALLER* *.md5sum - $(foreach k,$(KERNELS),cp $(k) .;) - $(ONL_V_at)cp $(INITRD) initrd-amd64 - $(foreach p,$(PLATFORMS), $(ONLPM) --extract-dir onl-platform-config-$(p):amd64 .;) - # Fixme - $(ONLPM) --extract-dir onl-swi:amd64 . - mv ./usr/share/onl/packages/amd64/onl-swi/*.swi . - rm -rf ./usr - $(ONL_V_at)cp /dev/null $(MKSHAR_PERMS) - $(ONL_V_at) cp $(ONL)/make/versions/version-onl.sh . - $(ONL_V_at)echo "#!/bin/sh" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -e" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -x" >> $(MKSHAR_PERMS) - $(MKSHAR) $(MKSHAR_OPTS) "$(INSTALLER_NAME)" $(ONL)/tools/scripts/sfx.sh.in amd64-installer.sh $(notdir $(KERNELS)) initrd-amd64 lib *.swi version-onl.sh boot-config - $(ONL_V_at)rm -rf ./lib ./usr kernel-* initrd-amd64 $(ZTN_MANIFEST) *.swi version-onl.sh autoperms.sh - md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum" - - -shar installer: installer - -clean: - rm -f *.swi *.installer $(notdir $(KERNELS)) initrd-amd64 diff --git a/builds/amd64/installer/legacy/builds/amd64-installer.sh b/builds/amd64/installer/legacy/builds/amd64-installer.sh deleted file mode 100644 index 5eac7de1..00000000 --- a/builds/amd64/installer/legacy/builds/amd64-installer.sh +++ /dev/null @@ -1,437 +0,0 @@ -#!/bin/sh -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -# -# Open Network Linux Installation Script for AMD64. -# -# The purpose of this script is to automatically install Open Network Linux -# on the target system. -# -# This script is ONIE-compatible. -# -# This script is can be run under a manual boot of the Open Network Linux -# Loader as the execution environment for platforms that do not -# support ONIE. -# -############################################################ - -IARCH="x86_64" -ARCH=`uname -m` -if [ "$ARCH" != "$IARCH" ]; then - echo - echo "------------------------------------" - echo "Installer Architecture: $IARCH" - echo "Target Architecture: $ARCH" - echo - echo "This installer cannot be used on this" - echo "target." - echo - echo "------------------------------------" - sleep 5 - exit 1 -fi - - -############################################################ -# -# Installation utility functions -# -############################################################ - -CR=" -" - -PATH=$PATH:/sbin:/usr/sbin -DEV= -START_MB= - -visit_parted() -{ - local dev diskfn partfn rest - dev=$1; shift - diskfn=$1; shift - partfn=$1; shift - rest="$@" - - local ifs ifs2 dummy - ifs=$IFS; IFS=$CR - for line in `parted -m $dev unit mb print`; do - IFS=$ifs - - line=`echo "$line" | sed -e 's/[;]$//'` - - case "$line" in - /dev/*) - ifs2=$IFS; IFS=: - set dummy $line - IFS=$ifs2 - - local dev sz model lbsz pbsz typ modelname flags - shift - dev=$1; shift - sz=$1; shift - model=$1; shift - lbsz=$1; shift - pbsz=$1; shift - typ=$1; shift - modelname=$1; shift - flags=$1; shift - - eval $diskfn "$dev" "$sz" "$model" "$typ" "$flags" $rest || return 1 - - ;; - [0-9]:*) - ifs2=$IFS; IFS=: - set dummy $line - IFS=$ifs2 - - local part start end sz fs label flags - shift - part=$1; shift - start=$1; shift - end=$1; shift - sz=$1; shift - fs=$1; shift - label=$1; shift - flags=$label - - eval $partfn "$part" "$start" "$end" "$sz" "$fs" "$label" "$flags" $rest || return 1 - - ;; - - *) continue ;; - esac - - done - IFS=$ifs -} - -do_handle_disk() -{ - local dev sz model typ flags - dev=$1; shift - sz=$1; shift - model=$1; shift - typ=$1; shift - flags=$1; shift - - if test "$typ" != "gpt"; then - installer_say "*** invalid partition table: $typ" - return 1 - fi - - return 0 -} - -ONL_CONFIG_TARBALL=/tmp/onl_config.tgz -ONL_CONFIG_MOUNTPOINT=/mnt/onl_config_partition - -do_handle_partitions() -{ - local part start end sz fs label flags - part=$1; shift - start=$1; shift - end=$1; shift - sz=$1; shift - fs=$1; shift - label=$1; shift - flags=$1; shift - - installer_say "Examining $DEV part $part" - - case "$label" in - ONL-CONFIG) - installer_say "Preserving the contents of the existing ONL-CONFIG partition..." - rm -rf $ONL_CONFIG_MOUNTPOINT - mkdir -p $ONL_CONFIG_MOUNTPOINT - mount $DEV$part $ONL_CONFIG_MOUNTPOINT - tar -C $ONL_CONFIG_MOUNTPOINT -cvzf $ONL_CONFIG_TARBALL . - umount $ONL_CONFIG_MOUNTPOINT - parted $DEV rm $part || return 1 - ;; - ONIE-BOOT|GRUB-BOOT|*-DIAG) - installer_say "Partition $DEV$part: $label: Preserving..." - ;; - *) - installer_say "Partition $DEV$part: $label: Deleting..." - parted $DEV rm $part || return 1 - ;; - esac - - return 0 -} - -get_free_space() -{ - local free start - free=`parted -s $DEV unit mb p free | grep Free | tail -1` - echo $free | awk '{print $1}' | tr "MB" " " -} - -get_part_number() -{ - local dev name part - dev=$1; shift - name=$1; shift - part=$(parted -s $DEV unit mb p all | grep $name | awk {'print $1'}) - if [ -z "$part" ]; then - installer_say "Failed to discover the partition number for $name" - return 1 - else - echo $part - return 0 - fi - -} - -partition_gpt() -{ - local start end part - - start=$1; shift - - ############################################################ - # - # ONL Boot Partition. - # - ############################################################ - installer_say "Creating 128MB for ONL Boot partition..." - end=$(( $start + 128 )) - - parted -s $DEV unit mb mkpart "ONL-BOOT" ext4 ${start} ${end} || return 1 - if ! part=$(get_part_number $DEV "ONL-BOOT"); then - return 1 - fi - - parted -s $DEV set $part boot on || return 1 - mkfs.ext4 -L "ONL-BOOT" ${DEV}${part} - start=$(( $end + 1 )) - - - - ############################################################ - # - # ONL Configuration Partition. - # - ############################################################ - installer_say "Creating 128MB ONL Configuration partition..." - end=$(( $start + 128 )) - parted -s $DEV unit mb mkpart "ONL-CONFIG" ext4 ${start} ${end} || return 1 - if ! part=$(get_part_number $DEV "ONL-CONFIG"); then - return 1 - fi - mkfs.ext4 -L "ONL-CONFIG" ${DEV}${part} - start=$(( $end + 1 )) - - if [ -f $ONL_CONFIG_TARBALL ]; then - installer_say "Restoring the contents of the ONL-CONFIG partition..." - rm -rf $ONL_CONFIG_MOUNTPOINT - mkdir -p $ONL_CONFIG_MOUNTPOINT - mount $DEV$part $ONL_CONFIG_MOUNTPOINT - tar -C $ONL_CONFIG_MOUNTPOINT -xvzf $ONL_CONFIG_TARBALL - umount $ONL_CONFIG_MOUNTPOINT - fi - - ############################################################ - # - # ONL Image Partition. - # - ############################################################ - installer_say "Creating 1G ONL Image partition..." - end=$(( $start + 1024 )) - - parted -s $DEV unit mb mkpart "ONL-IMAGES" ext4 ${start} ${end} || return 1 - if ! part=$(get_part_number $DEV "ONL-IMAGES"); then - return 1 - fi - mkfs.ext4 -L "ONL-IMAGES" ${DEV}${part} - start=$(( $end + 1 )) - - - - ############################################################ - # - # ONL Root Partition. - # - ############################################################ - installer_say "Creating the ONL Data partition..." - parted -s $DEV unit mb mkpart "ONL-DATA" ext4 ${start} "100%" || return 1 - if ! part=$(get_part_number $DEV "ONL-DATA"); then - return 1 - fi - mkfs.ext4 -L "ONL-DATA" ${DEV}${part} - - return 0 -} - - -installer_standard_gpt_install() -{ - DEV=$1; shift - - if [ -z $DEV ]; then - # Install NOS to the same block device as ONIE image - DEV=$(blkid | grep ONIE-BOOT | awk '{print $1}' | sed -e 's/[1-9][0-9]*:.*$//' | sed -e 's/\([0-9]\)\(p\)/\1/' | head -n 1) - [ -b "$DEV" ] || { - echo "Error: Unable to determine the block device to install NOS" - exit 1 - } - fi - - visit_parted $DEV do_handle_disk do_handle_partitions || return 1 - partition_gpt $(get_free_space) || return 1 - - installer_say "Installing boot files..." - mkdir "$workdir/mnt" - - if [ -f "${installer_dir}/boot-config" ]; then - installer_say "Installing boot-config..." - mount LABEL="ONL-BOOT" "$workdir/mnt" - cp "${installer_dir}/boot-config" "$workdir/mnt/boot-config" - umount "$workdir/mnt" - fi - - SWISRC=`ls ${installer_dir}/*.swi` - - if test -f "${SWISRC}"; then - if test ! "${SWIDST}"; then - SWIDST="$(basename ${SWISRC})" - fi - installer_say "Installing Open Network Linux Software Image (${SWIDST})..." - mount LABEL="ONL-IMAGES" "$workdir/mnt" - cp "${SWISRC}" "$workdir/mnt/${SWIDST}" - umount "$workdir/mnt" - fi - - installer_say "Installing kernels" - mount LABEL=ONL-BOOT -t ext4 "$workdir/mnt" - echo ${installer_dir} - cp ${installer_dir}/kernel-* "$workdir/mnt/" - cp "${installer_dir}/initrd-amd64" "$workdir/mnt/." - mkdir "$workdir/mnt/grub" - cp "${installer_platform_dir}/onl/boot/grub.cfg" "$workdir/mnt/grub/grub.cfg" - - installer_say "Installing GRUB" - grub-install --boot-directory="$workdir/mnt" $DEV - - # leave the GRUB directory mounted, - # so we can manipulate the GRUB environment - BOOTDIR="$workdir/mnt" - - return 0 -} - -set -e -cd $(dirname $0) - -installer_script=${0##*/} -installer_zip=$1 - -BOOTDIR=/mnt/onie-boot -# initial boot partition (onie) - -# Pickup ONIE defines for this machine. -if test -r /etc/machine.conf; then . /etc/machine.conf; fi - -# -# Installation environment setup. -# -if test "${onie_platform}"; then - : -else - echo "Missing onie_platform (invalid /etc/machine.conf)" 1>&2 - exit 1 -fi - -# Running under ONIE, most likely in the background in installer mode. -# Our messages have to be sent to the console directly, not to stdout. -installer_say() -{ - echo "$@" > /dev/console -} - -workdir=$(mktemp -d -t install-XXXXXX) - -# Installation failure message. -do_cleanup() -{ - installer_say "Install failed." - cat /var/log/onie.log > /dev/console - installer_say "Install failed. See log messages above for details" - - grep "$workdir" /proc/mounts | cut -d' ' -f2 | sort -r | xargs -r -n 1 umount - cd /tmp - rm -fr "$workdir" - - sleep 3 - #reboot -} - -trap "do_cleanup" 0 1 - -if test -z "${installer_platform}"; then - # Our platform identifiers are equal to the ONIE platform identifiers without underscores: - installer_platform=`echo ${onie_platform} | tr "_" "-"` - installer_arch=${onie_arch} -fi -installer_say "Open Network Linux installer running under ONIE." - -# -# Remount tmpfs larger if possible. -# We will be doing all of our work out of /tmp -# -mount -o remount,size=1024M /tmp || true - -# Unpack our distribution -installer_say "Unpacking Open Network Linux installer files..." -installer_dir=`pwd` -if test "$SFX_PAD"; then - # ha ha, busybox cannot exclude multiple files - unzip $installer_zip -x $SFX_PAD -elif test "$SFX_UNZIP"; then - unzip $installer_zip -x $installer_script -else - dd if=$installer_zip bs=$SFX_BLOCKSIZE skip=$SFX_BLOCKS \ - | unzip - -x $installer_script -fi - -if [ -f "${installer_dir}/versions.sh" ]; then - . "${installer_dir}/versions.sh" - installer_say "${VERSION_STRING} Installer" -fi - -installer_say "Detected platform: ${installer_platform}" - -# Look for the platform installer directory. -installer_platform_dir="${installer_dir}/lib/platform-config/${installer_platform}" -if test -d "${installer_platform_dir}"; then - # Source the installer scriptlet - . "${installer_platform_dir}/onl/install/${installer_platform}.sh" -else - installer_say "This installer does not support the ${installer_platform} platform." - installer_say "Available platforms are:" - list=`ls "${installer_dir}/lib/platform-config"` - installer_say "${list}" - installer_say "Installation cannot continue." - exit 1 -fi - -# The platform script must provide this function. This performs the actual install for the platform. -platform_installer - -trap - 0 1 -installer_say "Install finished. Rebooting to Open Network Linux." -sleep 3 -#reboot - -exit - -# Do not add any additional whitespace after this point. -PAYLOAD_FOLLOWS diff --git a/builds/amd64/installer/legacy/builds/boot-config b/builds/amd64/installer/legacy/builds/boot-config deleted file mode 100644 index 40fb0d31..00000000 --- a/builds/amd64/installer/legacy/builds/boot-config +++ /dev/null @@ -1,4 +0,0 @@ -NETDEV=ma1 -NETAUTO=dhcp -BOOTMODE=SWI -SWI=images::latest diff --git a/builds/any/installer/legacy/APKG.yml b/builds/any/installer/legacy/APKG.yml deleted file mode 100644 index 26106bd6..00000000 --- a/builds/any/installer/legacy/APKG.yml +++ /dev/null @@ -1,27 +0,0 @@ -variables: - !include $ONL/make/versions/version-onl.yml - -prerequisites: - broken: true - packages: [ "onl-swi:$ARCH" ] - -common: - arch: $ARCH - version: $FNAME_RELEASE_ID - copyright: Copyright 2013, 2014, 2015 Big Switch Networks - maintainer: support@bigswitch.com - -packages: - - name: onl-legacy-installer - summary: Open Network Linux $ARCH Legacy Installer - - files: - builds/*INSTALLER : $$PKG_INSTALL/ - builds/*.md5sum : $$PKG_INSTALL/ - - changelog: Change changes changes., - - -release: - - builds/*INSTALLER : $ARCH/ - - builds/*.md5sum : $ARCH/ diff --git a/builds/any/installer/legacy/fit/builds/Makefile b/builds/any/installer/legacy/fit/builds/Makefile deleted file mode 100644 index 7052ebab..00000000 --- a/builds/any/installer/legacy/fit/builds/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -ifndef ARCH -$(error $$ARCH not set) -endif - -THISDIR := $(dir $(lastword $(MAKEFILE_LIST))) - -# Hardcoded to match ONL File naming conventions. -include $(ONL)/make/versions/version-onl.mk -INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_LEGACY_INSTALLER - -FIT_IMAGE_ALL := $(shell $(ONLPM) --find-file onl-loader-fit:$(ARCH) onl-loader-fit.itb) - -# Fixme -- should come from the FIT manifest, not the initrd manifest -PLATFORMS := $(shell $(ONLPM) --platform-manifest onl-loader-initrd:$(ARCH)) - -MKSHAR = $(ONL)/tools/mkshar -MKSHAR_OPTS = --lazy --unzip-pad -MKSHAR_PERMS = autoperms.sh - -__installer: - $(ONL_V_at)rm -rf *INSTALLER* *.md5sum - $(ONL_V_at)cp $(FIT_IMAGE_ALL) . - $(foreach p,$(PLATFORMS), $(ONLPM) --extract-dir onl-platform-config-$(p):$(ARCH) .;) - # Fixme -ifndef NO_SWI - $(ONLPM) --extract-dir onl-swi:$(ARCH) . - mv ./usr/share/onl/packages/$(ARCH)/onl-swi/*.swi . -endif - rm -rf ./usr - $(ONL_V_at)cp /dev/null $(MKSHAR_PERMS) - $(ONL_V_at) cp $(ONL)/make/versions/version-onl.sh . - $(ONL_V_at)echo "#!/bin/sh" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -e" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -x" >> $(MKSHAR_PERMS) - $(ONL_V_at)sed s/@@IARCH@@/$(ARCH)/g $(THISDIR)/fit-installer.sh > fit-installer.sh - $(ONL_V_at)sed s/@@IARCH@@/$(ARCH)/g $(THISDIR)/fit-install-lib > fit-install-lib - $(ONL_V_at)cp $(THISDIR)/boot-config . - $(MKSHAR) $(MKSHAR_OPTS) "$(INSTALLER_NAME)" $(ONL)/tools/scripts/sfx.sh.in fit-installer.sh fit-install-lib *.itb lib *.swi version-onl.sh boot-config $(INSTALLER_EXTRA_FILES) - $(ONL_V_at)rm -rf ./lib *.swi version-onl.sh autoperms.sh *.itb - md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum" - - -shar installer: __installer diff --git a/builds/any/installer/legacy/fit/builds/boot-config b/builds/any/installer/legacy/fit/builds/boot-config deleted file mode 100644 index 40fb0d31..00000000 --- a/builds/any/installer/legacy/fit/builds/boot-config +++ /dev/null @@ -1,4 +0,0 @@ -NETDEV=ma1 -NETAUTO=dhcp -BOOTMODE=SWI -SWI=images::latest diff --git a/builds/any/installer/legacy/fit/builds/fit-install-lib b/builds/any/installer/legacy/fit/builds/fit-install-lib deleted file mode 100644 index 172d2352..00000000 --- a/builds/any/installer/legacy/fit/builds/fit-install-lib +++ /dev/null @@ -1,412 +0,0 @@ -# -*- sh -*- -###################################################################### -# -# lib.sh -# -# Common files for install/recovery -# -###################################################################### - -############################################################ -# -# Installation Utility Functions -# -############################################################ - -case "`/usr/sbin/fw_setenv --help 2>&1`" in - *"-f"*"Force update"*) - fw_setenv_dash_f="-f" - ;; -esac - -fw_setenv_f_s() { - local f - f=$1; shift - - /usr/sbin/fw_setenv ${fw_setenv_dash_f} -s "$f" -} - -############################################################ -# -# installer_create_device_file -# The block device name -# The partition number. -# -# Set the global variable 'installer_df' with the name of -# the created device file. -# -# We can't always rely on the existance of a partition's -# device file after the device has been formatted. -# -# This function creates the appropriate device file -# for a given block partition to avoid this problem. -# -# - -installer_create_device_file() { - local blockdev=$1 - local partno=$2 - - # Determine the device major number for the given block device: - local major=`ls -l /dev/${blockdev} | tr "," " " | awk '{print $5}'` - - # Create a new device file matching the given partition - installer_df=$(mktemp) - rm ${installer_df} - mknod "${installer_df}" b "${major}" "${partno}" -} - -############################################################ -# -# installer_partition_cp -# -# The block device name -# The partition number -# The local source filename -# The destination filename -# -# Copy the source file to the given partition. -# The partition must be formatted/mountable. -# -############################################################ - -installer_partition_cp() { - local blockdev=$1 - local partno=$2 - local src=$3 - local dst=$4 - - installer_create_device_file ${blockdev} ${partno} - mkdir -p "${installer_df}.mount" - mount "${installer_df}" "${installer_df}.mount" - cp "${src}" "${installer_df}.mount/${dst}" - umount "${installer_df}.mount" - rm "${installer_df}" - rmdir "${installer_df}.mount" -} - - -############################################################ -# -# installer_partition_dd -# -# The block device name -# The partition number. -# The source file. -# -# 'dd' the contents of the src file directly to the given partition. -# -############################################################ - -installer_partition_dd() { - local blockdev=$1 - local partno=$2 - local src=$3 - - # installer_partition_dd - installer_create_device_file ${blockdev} ${partno} - dd if=${src} of="${installer_df}" bs=1024 - rm "${installer_df}" -} - -############################################################ -# -# installer_partition_format -# -# The block device name. -# The partition number. -# The formatting tool. -# -############################################################ - -installer_partition_format() { - local blockdev=$1 - local partno=$2 - local mkfs=$3 - local options=$4 - local partition="$1$2" - - installer_say "Format ${partition}..." - installer_create_device_file ${blockdev} ${partno} - "${mkfs}" ${options} "${installer_df}" - installer_say "Format ${partition} complete." - rm "${installer_df}" -} - -############################################################ -# -# installer_umount_blockdev -# -# The block device name. -# -# Unmount all partitions of the given blockdevice. -# -# Required to avoid errors when repartitioning block -# devices that are currently mounted. -# -############################################################ - -installer_umount_blockdev() { - local blockdev=$1 - local mounts=`cat /proc/mounts | grep ${blockdev} | awk '{print $2}'` - if [ "$mounts" ]; then - umount $mounts || : - fi -} - - -############################################################ -# -# installer_blockdev_format -# -# The block device name. -# The size of the boot partition. -# The size of the config partition. -# The size of the image partition. -# [Optional] The size of the data partition. -# If p4size is unset, the remainder of the device will be used -# for the data partition. -# -############################################################ -ONL_CONFIG_TARBALL=/tmp/onl_config.tgz -ONL_CONFIG_MOUNTPOINT=/mnt/onl_config_partition - -installer_blockdev_format() { - local blockdev=$1 - local partition1size=$2 - local partition2size=$3 - local partition3size=$4 - local partition4size=$5 - - if [ -n "$ONL_BOOT_SIZE" ]; then - echo "Using ONL_BOOT_SIZE override ($ONL_BOOT_SIZE)" - partition1size=$ONL_BOOT_SIZE - fi - - - - onl_config_partition=$(blkid | grep ONL-CONFIG | awk '{print $1}' | tr -d ':') - - # - # If an ONL-CONFIG partition exists, we need to save and restore its contents. - # - if [ -n "$onl_config_partition" ]; then - installer_say "Preserving the contents of the existing ONL-CONFIG partition..." - rm -rf $ONL_CONFIG_MOUNTPOINT - mkdir -p $ONL_CONFIG_MOUNTPOINT - echo mount "$onl_config_partition" $ONL_CONFIG_MOUNTPOINT - mount "$onl_config_partition" $ONL_CONFIG_MOUNTPOINT - tar -C $ONL_CONFIG_MOUNTPOINT -cvzf $ONL_CONFIG_TARBALL . - umount $ONL_CONFIG_MOUNTPOINT - fi - - - - installer_umount_blockdev ${blockdev} - installer_say "Formatting ${blockdev} as ${partition1size}:${partition2size}:${partition3size}:${partition4size}." - echo -e "o\nn\np\n1\n\n+${partition1size}\nn\np\n2\n\n+${partition2size}\nn\np\n3\n\n+${partition3size}\nn\np\n4\n\n${partition4size}\np\nw\n" | fdisk /dev/${blockdev} - - - _mkfs="mkfs.ext2" - _archtools="${installer_dir}/`uname -m`" - if [ -f "${_archtools}/mkfs.ext2" ]; then - chmod a+x ${_archtools}/* - echo "Using installer archtools mkfs.ext2..." - _mkfs="${_archtools}/mkfs.ext2" - ls -l "${_archtools}" - fi - - installer_partition_format ${blockdev} 1 $_mkfs "-L ONL-BOOT" - installer_partition_format ${blockdev} 2 $_mkfs "-L ONL-CONFIG" - installer_partition_format ${blockdev} 3 $_mkfs "-L ONL-IMAGES" - installer_partition_format ${blockdev} 4 $_mkfs "-L ONL-DATA" - - if [ -f $ONL_CONFIG_TARBALL ]; then - installer_say "Restoring the contents of the existing ONL-CONFIG partition..." - installer_create_device_file ${blockdev} 2 - mkdir -p "${installer_df}.mount" - mount "${installer_df}" "${installer_df}.mount" - tar -C "${installer_df}.mount" -xvzf $ONL_CONFIG_TARBALL - umount "${installer_df}.mount" - rm "${installer_df}" - rmdir "${installer_df}.mount" - rm $ONL_CONFIG_TARBALL - fi -} - -############################################################ -# -# installer_platform_loader -# -# The block device name. -# The partition number. -# -# Install the platform loader to the given partition. -# -# The default is to copy the loader to the partition's filesystem. -# If 'platform_loader_raw' is specified by the platform, the -# loader will be written directly to the partition instead. -# -############################################################ -installer_platform_loader() { - local blockdev=$1 - local partno=$2 - - - if [ -f "${installer_dir}/${installer_platform}.itb" ]; then - # - # Platform-specfic FIT Image already provided. - # - local loader="${installer_dir}/${installer_platform}.itb" - - elif [ -f "${installer_dir}/onl-loader-fit.itb" ]; then - # - # Common FIT image. - # - local loader="${installer_dir}/onl-loader-fit.itb"; - else - installer_say "There is not FIT image available in the installer. This is a bug." - exit 1 - fi - - # - # Cannonical name for all ITB files for each platform - # is .itb. - # - # This allows you to use the ONL platform configuration settings - # with your own initrd with constant and consistent naming. - # - loaderdst="${installer_platform}.itb" - - installer_say "Installing the Open Network Linux Loader..." - - if [ "${platform_loader_raw}" ]; then - installer_partition_dd ${blockdev} ${partno} ${loader} - else - installer_partition_cp ${blockdev} ${partno} ${loader} ${loaderdst} - fi -} - -############################################################ -# -# installer_platform_bootconfig -# -# The block device name. -# The partition number. -# -# Generate and write the platform boot-config file -# into the given partition. -# -############################################################ - -installer_platform_bootconfig() { - local blockdev=$1 - local partno=$2 - - # - # Is there a static boot-config in the installer package? - # - if [ -f "${installer_dir}/boot-config" ]; then - installer_say "Writing boot-config." - installer_partition_cp ${blockdev} ${partno} "${installer_dir}/boot-config" - fi - - # - # Unless the installer contains a boot-config - # file it will have to be generated by the first-boot - # script in the Loader. - # - -} - -############################################################ -# -# installer_platform_swi -# -# The block device name. -# The partition number. -# -# Install the SWI to the given partition. -# -############################################################ - -installer_platform_swi() { - local blockdev=$1 - local partno=$2 - - SWISRC=`ls ${installer_dir}/*.swi` - - if [ -f "${SWISRC}" ]; then - if [ ! ${SWIDST} ]; then - SWIDST="$(basename ${SWISRC})" - fi - installer_say "Installing Open Network Linux Software Image (${SWIDST})..." - installer_partition_cp ${blockdev} ${partno} ${SWISRC} ${SWIDST} - else - installer_say "No Open Network Linux Software Image available for installation. Post-install ZTN installation will be required." - fi -} - -############################################################ -# -# installer_standard_blockdev_install -# -# The block device name. -# The size of the loader partition. -# The size of the /mnt/flash partition. -# The size of the /mnt/flash2 partition. -# -# Performs a standard installation for the platform. -# Most platform installers will just call this function with the appropriate arguments. -# -############################################################ -installer_standard_blockdev_install () { - local blockdev=$1 - local p1size=$2 - local p2size=$3 - local p3size=$4 - local p4size=$5 - - # Standard 3-partition format for loader, /mnt/flash, and /mnt/flash2 - installer_blockdev_format "${blockdev}" "${p1size}" "${p2size}" "${p3size}" "${p4size}" - - # Copy the platform loader to the first partition. - installer_platform_loader "${blockdev}" 1 - - # Set the boot-config file - installer_platform_bootconfig "${blockdev}" 1 - - # Copy the packaged SWI to the third partition. - installer_platform_swi "${blockdev}" 3 - - sync - installer_umount_blockdev "${blockdev}" -} - -############################################################ -# -# installer_standard_blockdev_install -# -# The block device name. -# -# Performs a standard recovery for the platform. -# -############################################################ -installer_standard_blockdev_recovery() { - local blockdev=$1 - - # Standard 3-partition format for loader, /mnt/flash, and /mnt/flash2 - installer_umount_blockdev ${blockdev} - installer_say "Re-formatting ${blockdev}." - installer_partition_format ${blockdev} 2 mkdosfs - installer_partition_format ${blockdev} 3 mkdosfs - - sync - installer_umount_blockdev "${blockdev}" -} - -############################## -# -# End of lib.sh -# -############################## diff --git a/builds/any/installer/legacy/fit/builds/fit-installer.sh b/builds/any/installer/legacy/fit/builds/fit-installer.sh deleted file mode 100644 index fa1f31c8..00000000 --- a/builds/any/installer/legacy/fit/builds/fit-installer.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/sh - -IARCH=@@IARCH@@ - -# Convert build architecture to local architecture -case $IARCH in - powerpc) - IARCH=ppc - ;; - armel) - IARCH=armv7l - ;; - *) - ;; -esac - -ARCH=`uname -m` -if [ "$ARCH" != "$IARCH" ]; then - echo - echo "------------------------------------" - echo "Installer Architecture: $IARCH" - echo "Target Architecture: $ARCH" - echo - echo "This installer cannot be used on this" - echo "target." - echo - echo "------------------------------------" - sleep 5 - exit 1 -fi - -set -e -cd $(dirname $0) - - -installer_script=${0##*/} -installer_zip=$1 - -if [ -f /etc/machine.conf ]; then - . /etc/machine.conf - - # Running under ONIE, most likely in the background in installer mode. - # Our messages have to be sent to the console directly, not to stdout. - installer_say() { - echo "$@" > /dev/console - } - # Installation failure message. - trap 'installer_say "Install failed.; cat /var/log/onie.log > /dev/console; installer_say "Install failed. See log messages above for details"; sleep 3; reboot' EXIT - - if [ -z "${installer_platform}" ]; then - # Our platform identifiers are equal to the ONIE platform identifiers without underscores: - installer_platform=`echo ${onie_platform} | tr "_" "-"` - installer_arch=${onie_arch} - fi -fi - -# -# Remount tmpfs larger if possible. -# We will be doing all of our work out of /tmp -# -mount -o remount,size=1024M /tmp || true - - -# Unpack our distribution -installer_say "Unpacking Open Network Linux installer files..." -installer_dir=`pwd` -if test "$SFX_PAD"; then - # ha ha, busybox cannot exclude multiple files - unzip $installer_zip -x $SFX_PAD -elif test "$SFX_UNZIP"; then - unzip $installer_zip -x $installer_script -else - dd if=$installer_zip bs=$SFX_BLOCKSIZE skip=$SFX_BLOCKS \ - | unzip - -x $installer_script -fi - - -if [ -f "${installer_dir}/versions.sh" ]; then - . "${installer_dir}/versions.sh" - installer_say "${VERSION_STRING} Installer" -fi - -installer_say "Detected platform: ${installer_platform}" - -. "${installer_dir}/fit-install-lib" - -# Look for the platform installer directory. -installer_platform_dir="${installer_dir}/lib/platform-config/${installer_platform}" -if [ -d "${installer_platform_dir}" ]; then - # Source the installer scriptlet - ONL_PLATFORM=${installer_platform} - . "${installer_platform_dir}/onl/install/${installer_platform}.sh" -else - installer_say "This installer does not support the ${installer_platform} platform." - installer_say "Available platforms are:" - list=`ls ${installer_dir}/lib/platform-config` - installer_say "${list}" - installer_say "Installation cannot continue." - exit 1 -fi - -# The platform script must provide this function. This performs the actual install for the platform. -platform_installer - -installer_say "Configuring system to boot Open Network Linux..." -envf=/tmp/.env -cp /dev/null "${envf}" -echo "nos_bootcmd ${platform_bootcmd}" >> "${envf}" -fw_setenv_f_s "${envf}" -installer_say "Install finished. Rebooting to Open Network Linux." -sleep 3 -reboot -exit 0 - -# Do not add any additional whitespace after this point. -PAYLOAD_FOLLOWS diff --git a/builds/armel/installer/legacy/Makefile b/builds/armel/installer/legacy/Makefile deleted file mode 100644 index 003238cf..00000000 --- a/builds/armel/installer/legacy/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/builds/armel/installer/legacy/PKG.yml b/builds/armel/installer/legacy/PKG.yml deleted file mode 100644 index a6d0a7fe..00000000 --- a/builds/armel/installer/legacy/PKG.yml +++ /dev/null @@ -1 +0,0 @@ -!include $ONL/builds/any/installer/legacy/APKG.yml ARCH=armel diff --git a/builds/armel/installer/legacy/builds/.gitignore b/builds/armel/installer/legacy/builds/.gitignore deleted file mode 100644 index 18bb2d6e..00000000 --- a/builds/armel/installer/legacy/builds/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*INSTALLER -fit-install* -boot-config diff --git a/builds/armel/installer/legacy/builds/Makefile b/builds/armel/installer/legacy/builds/Makefile deleted file mode 100644 index a6feb7a9..00000000 --- a/builds/armel/installer/legacy/builds/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -include $(ONL)/make/config.armel.mk -include $(ONL)/builds/any/installer/legacy/fit/builds/Makefile diff --git a/builds/powerpc/installer/legacy/Makefile b/builds/powerpc/installer/legacy/Makefile deleted file mode 100644 index 003238cf..00000000 --- a/builds/powerpc/installer/legacy/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/builds/powerpc/installer/legacy/PKG.yml b/builds/powerpc/installer/legacy/PKG.yml deleted file mode 100644 index feb80aad..00000000 --- a/builds/powerpc/installer/legacy/PKG.yml +++ /dev/null @@ -1,2 +0,0 @@ -!include $ONL/builds/any/installer/legacy/APKG.yml ARCH=powerpc - diff --git a/builds/powerpc/installer/legacy/builds/.gitignore b/builds/powerpc/installer/legacy/builds/.gitignore deleted file mode 100644 index 18bb2d6e..00000000 --- a/builds/powerpc/installer/legacy/builds/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*INSTALLER -fit-install* -boot-config diff --git a/builds/powerpc/installer/legacy/builds/Makefile b/builds/powerpc/installer/legacy/builds/Makefile deleted file mode 100644 index 43f77a9d..00000000 --- a/builds/powerpc/installer/legacy/builds/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -INSTALLER_EXTRA_FILES=ppc -include $(ONL)/make/config.powerpc.mk -include $(ONL)/builds/any/installer/legacy/fit/builds/Makefile diff --git a/builds/powerpc/installer/legacy/builds/ppc/libblkid.so.1 b/builds/powerpc/installer/legacy/builds/ppc/libblkid.so.1 deleted file mode 100644 index 0860ab902dfff92e9dbf2d5ea4ce574d241fa10d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134556 zcmbrn4SZGAmGHgqN0JMK@j71Hs8NGN8^=_ljZZHGG*oP_65H5`6NLhRWC=*rEmuiVjxn;FLatEgxaT4o0!(f?#YqM5pHOEyV?Z) zd+)#@xw|8*_pjspS%3Cz}qT+gwbBdXy)<9wsCf0_)49^@~<(PU}xpUV{MIL}nB<~*BY8OKjK9_081 z$3Jm=*54cg|D9u--rUale&uiJSx#G&zpm%4dVZ4gaQ)`#y+`%@O+7!Q=YQ6-fBLaP zH|HO5%;(t2aTAC9ZFZ+2|K6roEu1%UoWb!d$6AhY9P;-t$3JrXfMY4g0*-&>_}?6N zaJ;~=i$ne&mE|3c6Aa{dZOilda{?>VmKkiUQ9c*K(X=Xy>J zdflt%r#Y|Un9kA8v5q6gL0hnYtNHhFj_2H^SKC5PC({QZMF*?+&Gydo>?{|}D-zj%1m|3w_}BmUp#eaJfh4IIk4{w)04 z&kFoMgq_d5;IR7_>UF`e@Go=yMUE*N{?)Ae=fJ0DT@S}E5HObG?>MgD_!`HTIEMet zAmCh%8jcaeZeF0*mvYV-cJH$;3ke+0@j1O&$$6x*f4azrtaBsW%JE%}JF~(CzoXZ= zoGX;uIDeaC7RSXJc8#91Ph+@9a};afJ)F@RiH*K@r2)X*&?nhEX{5?%k(%i!}x(`sNbrPjpuLo?;#Sfnx`g{O?mn`79l#3q{ z-(vq<{9OFtM;izz*7QC!<~FI1E{*T|JfrbXxTlR?=R}8IN5UqMTSSE(TMX#DV#xU#*3?biE`6JOG7b=QF#hsMuEKKI9c{zgx6R|cn?`4d|7`yQ1qFX`WR z@q@n}dYw0O=(X6+^jgCDUH&6aHGxINTx)s4)WY4=**+_#55pDVUv|6KYy`XWU0muKytyFVf^ z^g8$bq1SoShhFC{9eQov9D1F1`OxcNJKf);4lI zU9ZK@**~uN3qNX4{Nt`i4AW=sokQ=BEH{D9BZO&t%-uKiet0Xxj&;bV`RAN7^nP%` z(ChGjFwFFbFZtuoMxWu|ckOr77!&A{`civ0!|ZufF88BZ_y5h98T+}eap?_=mDL_c zePROtAU3P@5qt&x#JG;S_@f>-fu&Mke*30B`C%2;)7<_1HrW2T`Uqd`UvrgH1QKVq1@1$X%I-SdGz4!s^d*1y*Dp7gI>{NTVC$6e

486{)8G0SrZ34GN2~&H?p*;UA_Nw+gYP$)1U+$~D1eOeaK6us8>)hWBy&m;_ z>{HUy^z+Jx-p~0F`fejk^&NO-=>0HtxAF*KJx+hQi~akqeFl-&{W*PwE?{bhyrHPZ zC%s>G)1RvTb0*~KkhZd6FI<9?v54XQ1 z^e2?Zj~{#w|5nWPGM8RnD{TK<{&`;;dL8~2)5;^{ul_iY7T`=|1XuClJf_Yb|!eQM}+!!Uu19Oy-WFzgDQ{kM_KZP@oztr`c-`e>0cJEB7OD$xjR{Y z5dE!k`HiTt$?}gYPoQ<^b>z$RH=-}qcj#T(OE1?de@+$S*HW%4U3zxyhs%NVD(!`T zJ!3|FvTnxA<~emO&387M88aFh=QZBiJio1R-i(>^>Sj02Xr423F5#aUdd=-KzNxXV zY^j?+zj3~~wXv;n&h2J?+q|~93tG%AEwh>%W)L`|zOKHh(bU(qw9Kv7;MN6xu!}Zx zUSs2o)_HSpX*7cV!}a>Ci`39~J3`(*2iXh>)Hl`5(};4X8Nut?8fV;sSaZzm?A+w` zd<2=_SU0b}NhEA(oFk|D)`eLq%xO%vWnDJa&7aX$cWYLNpGD)G1~YSRYvY{%RgQid z=gpflcLrsvYipislO<&CJTrfOechayW+p0_Z)VoF%$+|_E@VL_E5YnmQ&(T#IDfw8 zb9>{w=9vpgw!Up)E2WW0bLxpTzja>ooVJ;R;*e?E+yRBmYpiQ%Xr6~eHYd=uHKQmV z=l_Q5nGO1^)$k zY-pZ8%jVpO+#-M7{6<@bws};5Uu$9;wra%wTIM%4&O&-u)d-^I;I8L2O8q$lA$u;2 z6xfP_Zf>7HXNY!O2{rvWbBB~kLI;Gj>Kl5$dH&$-ArFcKh}&F`_065%oSZSUuHp9P z`HcuYbADT08|UV^^=-aZ2Z}&znme0@hRuoPx&jSKIA2OXJaF#JnNr5#!NaOhih^R> z=Fa=fMD*5>ROT$0J$L4e+v{2u&|-%tZ-a+~w#=P7YeB1vKjelq4i|mF0-E`PIjwc` z2JE|G?u?lWT3TFnxl9O}UpKRHSdhD%*&uC63`J~%llYGo2fj9?s5HhQlKAzTrBxBa z#v_&HIey#4$u(F@yQ8_S$+qd)v+#4XTczsin`Y0YIjj9FnA6fcXBNhlRacU)-}Ie# zab=S5ET54bO+18Z*NQ}|o{w{wF+?npzoq$>d3Ey^&d><{L*fZ%AOp>A#{31Xjq`57 zzswq1V`7h4_h!s&sk?P(3~Wxkd3GdmDnl}9o?{zZJbj-w*j%UYe4GW58=if=YQ#O=9!t~VC!Cegj3smG&o~Hs->R2#Zk;F17P&CI*>y>SSV=X% z79)!xpmHLs(r=~A2=k=?B+Smvlq;s z(Tr0W^qxba%x%SX>stO#Q4p<}s#OpAKc>{$v~d1k#cOS*8O@wKZ%xwW*I3ARi;$f;H}SS%-RJGJS{y6t^2bYb9Op^9Z9P#D^iwW zxeAm@8oV#fC~NHI%(1mC`zfSqVdyx+buU?u4md$~-`2hzOnkz9awH@FfnF__@stsy2fki4}s8!77{TO~8-{OJg0n>7UM(QQe&2DcQq-GsWtu8 zV-6i-3L$;xXFega4vt%fJi}0fRj9$zI>9BIthOM}+X`X8;>L*srT@%Fht=g^ znsUQ;+@F=F>vZVFq$n59pL_8ohKpP4>u1a#xT+T_lacbA+neVxL?(t!%f%SiGgFsQhZ|rF zO2C5VmWFwA=e9Y@3ix8{+&dcQwbr{E;}*0vw|o(Iy&(C;OE12(?BYwtspRA4&#NDI zF&FdASE{C7J!Qrv2<+(6i!Zrs5WhT#@d3QF%v^uHKJ>M!tG{yPj7xc3|Jc1?N&XEh zvuI&=FZlOz{m9&xI4(Rq@Lb-&eHS)xsoe?BKgTZ$wP9Ilq5|T zORfjgmUt4!-FNcY2sVz3EBEAZx^<~b9Cn+?|3*K3+HG9LI0|{?pORaIi`0QrUTcg( zdQaD}^^jfzH#F4lz5A;f$&0I+yl8&sMNF28Y zD|zMGIK7a>;m^JglQ?djMM`1vWldIOEgJFK7dCR1``_T~%4zby4at2oy17}-SkmZe za&3a|RP!%uGQT+j*C>Ak%Y6wy4o`RdQUI=1&Vw72^Wi4t&%vyB$+It=3AZYbh1--b zgph(3yBtRj!CFVZ9RX{-{5A%=dI{L@E&8m4?^c%h`?JCiXN4ah3_qMd z7=E}gD}18z#U^;T%JGPuaIJ<{!D@%2BJdIoUkI;sJQ|xhyk5hX!J8fb%@){~^B-ZA z^Av39@DYvwoRMW&Ys05fuJ_bVUZGs?6}#}iod&CJU-<&8x;+gWdvCgn^U7D?7RRxp zu&3dRVYT@)t6`P-m3!b#F3xK!;GK@oDu;LJv-iS>lz$B$b3BH2@!oOA`%X2%_X{=7 zZ{bqM=QY7)S#heBDdYRKj>n?g_Zza}sBT|*fpC>`EOqhzs;oGw+kIycu5uP9Vb!yh z=di}dKfJGUo?mN%etL1h zf(E!p!*75$Wbu|P_GOkhzRX{ORpu|?8;=m(%6v0iq&y#1nM+o}zRY*QzRaDl%6wrl z?8}UO9!Y9C55T_skHEg3CC++{BfLxbNqC>*zbl0IYxqCGD)YWR6Z})Y##sVKHO}*} z%DnGGxYC7}VUvHFqH+EV`|=-#RsMZ{gqOHDuhWD6X{F6t=bu%6N$1a%8vZS~T6qFot6T}U zDo=;I9lv%O-0OG(ZRF4EG`s-bq55K~6} z4~mtm;3>-AfNLCI-VaaH@bAD$m3P%j_!Yxw=} z5yzG2_5)w$ADQ4$UrzkVQI&IY5nQ6rJ_^T`>A#L9l-I+)%um5h8vYYlWqxfxyvl`t zWgWahdM`6R3|UloIWnU9*_hpOk-^I%{8k71Sn^?X?M{5n4B z!y1?7RR>{}`E~r#he;RyI=1wo%KTO2`A~KH`gmAn{%R85sPU=m5Brp_g!`4h2CK|p z+XJi2uU~6|e^EJK$A|x=MC1PsPADIMRkp+~c)Et8lfR^tX*7?`!0R+Vw)fFaWo+-Gy^gPwXZLCNTKJgqUK2bPaoki0=WF<@aG^5# zJXV?&J~1nNx-xn`rZPA0hFdipn>?m6zi|rO>%zZFdpV{uzi~Re%Z2|Ae|5~s8DbAx z@L0bKpFJHun8k-2w_yLr4mF|M3*Z z3l724G`t^fa=Z|m|2XBik1~F|Ov5+8y^i1fJ-pHJU2U+IWd}O^Sj!TL!2K@HedzpS zEsJF>ORAS}Ez5y7VJ*vw5)=G{N2RYkfDE4$DIbQ*9IsdfYq<_S0&BS}*SI*A+mzAU zCrcbZAn9~z_&e}=$8Te|pKNygBW&rDEgC)(-mi?keWEfyxDP&};X6(6)2Q+XaFOF4 z0~c%fN3hEI_HkI{T%CZmE)F~aCtdtk--lJsN6_=9S{JWX!5dth*O2p5mGd#`=+iz8 zmpJ{7fBzd;<$N4FIUaW5|4q9%9&`LuHC$pj_zt=~Uh4Q5uil zx%ls(x8ps^Q{Z)$1BW88(@*FWNq?ipK_|yu{e~hEe~XL1?GW6j{4Tsxnff}u%klO? zc(*eB`0+i;^xenzDodLClpEpw%Ji+r`;~tPA5^AKJbp-d6MR^?4?dzy-5o!wjBh!9 z%yA!c@Z-mo|JDRgfYM(2@UbVt%J|X~5#_7le9N}%C!!ioy`P9>g%`N+U;Ui$LdUPa z2NyZ+yA>{0rXEj}C@+RfEr)Vz;W8KgYueX|xW-uxPgH&qu2lXfc#85*;e;}JI8mj% z8?ILV6<>;wsE3I!$r1U<*&o*l<`F;)+?vr z4a&6H6C0KP8Q!G47v8K)zjk7a;}`z~_gQxKu+xP14({lp#(XUubA zukuCkK4to&6Z;+SXMB62U&Cj?2bD#KhaCT!wszvMhPT5;oFX!vnB-|^0TII3I#$1K~jpDfVu$%Gdw*TF@~55UEi#YYBD zmT34-;8JDgL?_FX(fP@8WsxoJ`1xFTqVgqhrSc8%6lLo4WI}ltT%|1KtyadCPSz-6 zODCr}-i1FuIbFjUvz@GU{7WfsgYs2ylkzQai}F9ft;*}+r1BOxrTp)(r+frnqI?YQ za{O=jrIX8)v7eLO%4P6MW&H5T9?MSuy&BG(_vAX|74Uk;woW%__>T$SsEp4%xk*{% z+^qatc#AS^|74%zU8lf1l|{B)%3p$aD^G*>DBlk6RbB$`Q(gn_S6&DAD~sL^Iu<{C z@{oq(A5I=t#&?}OV%e4bsD|SwPabpp(%-|!9ZNgPfMVynGH}@O3lTV?j1S4=JKj#; zl!;ol>1SdZ2YE6D%2&dL%Gi0P$nop@;bIM^&1OoJ?}JN~>9aCr$}hm>%J{lWTv^hY zs7#-gsdW7BL3oPt2soj94qRo~$y}}B)JvwuaUXqIW}32;WxB?p|H{-V(~dF?j{ob| zaFd45fm<9OpkL0kYB>E@rcHSjoK*f7*i)8rEm3|A?y~IUT&CglHJNV5zd8$EsXPf@ zr7Y?9DE|`fRi^D^);Zo?0Iydrg*PZ)25(ZH2yeFRWa!gysneax3*lYL_rSZAzYp(G zrmxBDb^Pmkc%O#%!uypUhx?U94+oY10v~exB0ep1Sef}?=7?iyvzenBei3|3S?cJx zV{FyEGs3oCY_jiXtew9&7mnCCQpS+|4W`7o9gb=`%i)+~>^5WyH2i6}P` z*fBN`vcIR1H2dLF7yj>a;4+Q>0bK6**LiSU`D}Qi@?~(P^0n|3WhqO-F>N_ye|Je< zwB?Yg);Lne8s$!Sn(|}tbjzV!53belpTiBx&%sTO(R0YOX!xsetMVZ@seA-ZS(f)a zA=Bl;U%C-q=D2S++^ylaz$=x%3$IdcgL|^#_bUI2@O2tzA-rB$Degg7<2;)Z;$KePSp3EjzpF*ElB# zKj^}FXB0ArT=?E%_^@&*d_?0*UPm>&0zRhvRrt8_R1=aHcjCAAeiIHWPlF@MwQ#=j zy>L|dVK}Dz1YF=4pB4%fYWQZjNO>Dvto&!V#PQ4L!==iz;WFg~aJgf#`9NI5)9^&c z(nbQ6j$aX;qH!LF6Uyj0P^J7VT&;|K25OXFgr_OL0#8?d3$9iE1KglYeFd77Pr@yZ zd1n-|d!W(hD|K+2hR5Kf<5#4NDGkSO1U%*G@DgPydzbQ3c$wo@u=7B-hWElNmAAmF zG>)X-qv8ADUS-->V4cR1bk-|N{0+)t0~?jU18-8E0dH2Whqox-3il~@!#f>Iy9n&o z@JHc2%3=e1mH!pqXE~I|w-N&T9iP$%_iLON;DgFySBI2;3m>*@+eqMuhQChuQRUGt94>IY|6RCH!||)ZBIQ|du`<3i zSmJp5d2p$Q(?)`2%6s5)<->4X`H%2KW!g@#QW>8RoZ|S^5S&mx1+G#)4X#%HJY1uE z7CcRP0z6&060WsubsKEZaOyhPr2GinqKxeYTa}-O+mxxVU{ZN6oKnV520i6|c!^`F zqhObYOWBtxOL@DMKY~{(nv|@%=^1g zaHC`K$-zyIU)uz4*7*3A;1*@tb+Aw4i2OU1tKePAZ^OHlMV>v5ZN7Uo{3zl3ls|^| zYaFr9e#ftiYzLL`^T9(Jhjtn~?D(Yz;3FDm6?{~A8hp&MtH?%~E;nYQ_RKw{z zLS@SIv!Qb39dKNEH$2gD=oH~f7cTk?P0={`oKV8?8zN_wV_U{*%T^De8jW)fai%F> z4o`P+Sl1#r*%J`p9o8#X_;iU2yIHima33--7dDv%Y ziEQ)OEN)`BAt@8G8t~D8B@^IzEsKw<$}SN#$$cl=8P>PZ?hqUZQ*_ z+@;JIFT6~dHWKbu{t>*=vDkcgm4-hF_b7`FdzH7t>y-ZkUhnuN`k?Rz4Sy5fsEni1r%1UDE>>O)mpB&N&MCDVJU$IBbK$S`z~z=* zzHt}+`v(c1sQeqaGAqs$4S$vJgtDYx<@mo(hpUw*!8OV^!_$=8;OWZu!nMk4;Ra>= zd`^?);5*cBu8S|{P_D**>19~s|LaNE#Sc7(ZgX2*I+oiU+c-(b_Sq$t<^5GCx63j6 z!a}*rl<|$Z-O9AV+?9^mlNHKcrA)ia?a?^cZEmlI$KZ92*+UV^U9X&kH#j~#5#Ff0 z9^T}b_uir0&5n6LAIjaLoPhh3CH$IcA?)DEGKy_Tz-| zK-z-r zp}Z0e-vyUCW`9a3ugo#~#X@=Ij^D>G<;68zc%rh%P^nCL^QJidK;%z2W{*iIugWp| zL_&Gh$`W4Vm^~4pylKjDc)IdVxK{ZX+~D}wbht^GI%Ujcb@=f#IHlntr>Eg5c!_cp z?ouv?mnrwc-IfEtyB=QUc&_NDN5f~ry^dQ8;Po0V>2J_*k!_QPGcL{Btl^S=pW`>L zgm)@`2i~Q8ExcR#pW!{qyWzdcTi|}jR<=WqtvpASks$(#k8LGi#sp43=p>Tw_*3){ zi8|)JeJB#s@FZN|n0MfzNTG&Pcab7x>Mm03n0MKsNQrVAT&lbtF4OoMcn`ab&wT~B zHgK;o-|~6AG3Wb?-nJ>9DCg5%$|u{hn0oQUGt~6}Zyex|8H^t?)VszB1$GT^Ftdfv zzq#~7#^bv)$`R5Jo-Se{e=pnmeMZh)pUErFXX-cNb043r@|nCw`n<=OQ9kcu54z9& z>@D~C5ZlguKEfxwd_Kl@cI6QW^*Ns-#(duAC_icUxqwgm`CP;&!F(<;<}9Df*uw8~ zoKJiCTxrZXJ}1~B?{l>=V|<>**NuFx=T_>}=Oo{z^w~4!3qE)8X+592 zjk(b0RmNQ8b1$DV@OeG<K8a@H%bA(T}`5fibgFYAVxkI0e_&lA@CB{tlxs1=G`5fnS zO+HuhSv8*%#(dT1YCdu2^E5thA2FuE=VQh+DvvV8%=9^8Oq0)1W14*~;L~|N7a23h=MrP)`dr2*I(&}v%?_U{ z`IM&52|m;2b2XpB^m!VeJoUMj&tm%A#AnZZZsofbJ}3F?pU)nj*7LcG&tLl7&3C(e zUd1<&eD38Fe?G70^OQbsjM<_*+8DFd=ZG37=N=xs30q_#Ef6u0B`t zXC^E0aKhXfwL2V#tsjTk1<85Na%^Ldxn00Y>yxBE036*6+28pdY5}< z#apJ(J128wMV-k{_x(AxqQgWx*%q;4t%-G=i^ukisa#_`?;I~IJb8_Yc3kd7yk@*x zaN~l`MP96PjTi0Q=H;g!?yv5cL`&%TTx&&7CX-&;Us>5>O2%Jk0@oKsCoJb)>MV0{ zYJ|uY9%JJYXL3)bpY#hf{d{kcSC|Msa|Q(ttU?AUPbcz8c{)WtWb331oyacblrmDj zBdUiO@neKX2g`q+l;7Uh@<+7%F)6#0oBWIX@=5;Q8m~AJ{HL4X5-;TRK-mk3SL(~@ zmqYSHo=A3{ety);XUQ|szc2D^=h@-%bX@Kkk6}dXD9=FTCIa=vCNyS%)VS?J2U;RI;} z&=Ga}lV{>4b2ODYYa!1h9ZD6o^rn|$gwG5 zu4x`p9#_Xj)KvgoMiM4?x0j}ToyTaG8TsKswRaXHoDrF0t)nPEHsCGAo{-IZ(r7(z z$VrEuL)NdqENN6sG7;KdB)xQ(q_H#o*t>G?S?)zU7kQ>)hKbOoi#xXyXZ0S5vxhuI zhPOG>HaCv8=4wP|>S)%nOWn7n4#;(p2*d+OMqVvwnz0%H` zy%O?nBJEhbgE9u6S|DW-yF%}Q$}Ogha>cOWSo+GBlCCbFy2R-?u)sUp6i_YUZqB4r zFc5d_ul%?<=|>JEJE`0BBZs6stB|`Fxr_aFNWF?(R3d9E5!~R~(_-3F2s^09?&?Wj zID`!oC%dhC^(N;0>^Uok*sl0gX*aH(2igtoK-wT}^roTrmdVT8ms6X^vNL`9v%CvnJdaJQNv5&1r z<39N|_w&>BuO}11A3xZ+6+NxC_O%DSj7$WdY!};31a3ZVLT7IrQbyl53@anHyaYQg zwmxix33DxFDv+{{yW9G*h_}s?GL|@bpR5}aA73H$OIv%U;|de5pe!BO{ql=Uc)9dF zwk=fUU^Cddt<$4oKiKGP&NiQJR++0)7mZ5#^_&RYbVB?R<%+qwe)28rI~SW0KHmTM ziUWp4?UE|$*@$oC9F?~1*F9rA24Z|WBpiEk{&r(`JWdXaT@bKvoD zOG~QgKUZ1byT)`&+3_h|sm`&f-e#fR1m(7bRUCY`9j#t{R8Udc+goD|N=R z`BIPgwgT+*ZrgT)8`>pbspCZOA74#3yqud!FxM~^TO>vL$sqI+l0Pb{bJiD;X8TgFII zhRR2&PM)jq@Y%i8t@QEk`EJ_Y`JD%7d(syMpQy9-`1YsC)XcMzgYEu_@#wE1jvc0# z97x93n*2E92bbsim(g_)+bHz#Jz_WXKciEt$0o(Lc&=EUi+f>{CSCIQ2iteA$!zlF zae1$QetccHOzbVaj=mxA9oCo5IOyBF?Zd|Cn1KFM`eU(uX#=)QI;NVuIB>+-ec(_h zbx;0@&YO6SzFGWuBDmh>kG{!=1{6^<=uyUwqs{1M%Vm z@vJ`oagxSslC+Sa9Nk7`yoyaQ)-u(~2}y(d@nQGN^nQu0d+I3>Tz8?2-Dr0)Y}J+N zQL(F!Po&eYCp+(wKGoJoRQ!o;^MPrsgMNO~$}uN4`s0Ci&s=bEgjK_}!D7EHIlBqg zq_$j?Oug}?S$xducDh%nRu%qgoGUqoCz1PVKu7cKssSF-q|SBhMl z7w!CMGW~mOy)K~r{^JX!eDRJzG~O%r|LB8S#{Z!V=CC}=I4err(Z2lTSyW@f7mV|2 z4K`6c&MOj~P7%2m9sEU-v?=ep(=~o6@yoOhir{jsgP5e9Frz0+8IgB-MS%%>n`w{I z=da0387$lXRQ|uoD!&_JTOSl$d#bNH>S2@kHj&Bs*R_vR<|ICkzV7kc#yueIBhanw zB!9*Aj9E>f#an=F^qNuBA^qfISKG2|3(#lVaaB31A&hMwdrRg7`04#T6R&v8oF?UW zec5Ag$TR3?k6f!wy`W)RY?y5`kJ)-A-g+B`|8n|!RQxk~Fx@V_b&VHwn*PaKjhB9$ z^yoXpKRaLk*ji!axlViy@=yjdjd8(g;y)!^^DT5~J^GBD6E4p5Pv~Pj!T5-?(R|Jy z_e1iPF#~1Amg3meM8@5Por}Cm=hGg&O`ng-^DgYM_vAUsQPy!8bL|l(hv$pXpS26h z6vT!CTBdyTI8t<|e$2M9TI3+Ctb?{azAjkZ?sYJZtm!eK(-yF&GKUPlJ zu}AI_f6hR?s@2o!NHVchVC$&2&W+#@T_*osJC8rtY%& zBo`Imn@s0CXZ@B-yZ1xa4tpO@-FcRdVb{JR?GIfYA>VSb+eK4WB)jW!OUUB^o5vcn z*W-Fo!^4tqhs)RWX}(vJA8lIVubq^->&%$Saf!%5dx*L*#M-OT-9hgy(#h$xGA&y2 zn3lQsCXs7u<}a6dJ90}zm*ih2Vci|MrR@jr^5b2GkN4}dz+20`=jPk?=*rjgJYi*0 zU(!ZNtCaeTNqxHd`}hnk|A$VdN6y!_l<%&4A4kSA{CJ$UH<7kiv*1i*?vvHo8NZO^O z-GU9ZqVF1OpKe?kT~zTbf7 z)EoL-bma=ML*M`Hlj}w6o{})%|LwG4*j6IA`bDkZjW*2M)ta?hzdcS@t9LLDHH)rV zk))j^r2k8p_A?|7{xL~EF>P_cG)bSdc#LV${;2j_ruTE-y6~}!+b;|yzg3ibdHY2n z8JoyBz#m7;{MLxRB<)2P-0PP;VEZy`Q0zp)$@9{|I{fH*m8)5Ge%M{Fd8cBl2}_zX z)~Z}{ay{*;&H0W;M&o}zN+qRTgo@F<9n)9Tvg&`imt1_aSCszJuafD@ekJwPmHsm4 z-+4km8Vv)-bwZSv<8 zJ%2(+_@Lkv{7V7;h4r)#E{q2xje>Z4(KRve4AxoiV@%#`%DR`Dav6h2yOTLe`+>W% z?E1m?w9Icv{vwCu&vP+pZ(X5GrsGoikALO04H?fYHm%<02iwb{5bch3(f<5=)%Al9 zP=9VL$@mj4zsO@9XEkd8YiWntj@o}Y-;R3*>)^xxbmfRnkaENget(3C-SFg~Y^-V7 z^#g2lJ!{Z~l5ZmTaJ$;g%8oaAoj5$y&eG}snY|hRH@#l%)D%InO zmh7@H?ias6pI}OF*jf;`_4m{tV%8UKHD!{YAz(?2fy~v z*-}UH441*~w24YxA;0(r|9R%wKl&MZEwcSgpo)DvqayzLke%D^U`@%b+led#?+89a zmX)Ms*BOu}fGn3t9On7SVR^11-emHOT73kj_LZOEE4GT8Mg z>?S{T2Wv2^bPeWN)?jLBtBY;^IWmSCw@Pfq_U}>GE`Ri%tOvq>(ZaR7L)Z#!V9dA zV9sslx0(N9U3TRqcKzAES4_Xicr2aygWNk^^dRs0&_kIWGX)a(h)992YuhgCbUhu} zY3~uK$JE1&r?*}-@IHvNPL(!*oCzzZTQiN(Uz;>?vYz|`_09Ul$<<=3_y`%Jx^@}- z(Pd(DvX+V82upoSy(9t&*1z(WAxpJCUukDOW7}GN$3Y#-8V2%gO1=K2Wa>l(YZ=CC zKmE!qxgJ<5_5i#~4$>J6b7!HC&or z%K8U$eyc0#qe*9K=EQ@vt#ImA);<@|uQ*>CrTy>5??i0<&h*D7%U7enO{~N8j`J!d zEx(*nu4R-3si>Xt_Uip{z<45FOSa3y$*mLFLlSy~|K%j#JHA#XFqwCdl7ffuGxmO?4lC8C>We~{$MHPC>0yZiX&@Zg}%(`|Nd0V@`Ibk*G26- zD-oEojJ@cz|37B+kx|!2;?q(OiNA~1q_(qmxZkz8ilR)$uZL7EebnM$t;j9yez1>P z&|%x*;-J{MT@O!~+g}tPDsd|xWsP=?ypO!|HmL{Z*3221=da=Y+ZwNwIIJ1mf4bIj z0bynFUgHY7F`;qvwp zOa!~1ZNK8b?AUkJh)l-z^VkmYizQv@6KE%=vR-XcNp!Hcj89P5eDR z_#l3!MdD*$CGoyfct3ReskZOzmG?G*e9hnW)vPJm{LNi!iFDltJ!SjAgA{))#xMjLrtc z*GTyvk$&O_&puq}%1ykY!7|S~JJmdPp_E(7Onz0O*NP&mk86k6m+Y4iyXF0V=SffA zF_w!Bq`&%7Qfy70acyUre6Vz)OGnV;Z;=<*XP?1Vt8HBe zChv7^;p9g871q83we%HHzpvmO;eI=|!(T{$MO!;s(N9|b-jhY1*kXdbWGqV`A$umw zA+ZbAiK?(KFA==&LF*T`(XSiRM7gB=Rp{ET9VUXycBtQwv0p;&iGP*x7kz=QN!|A| z;>i1;9e)vI3jvS$6`yPi8o~2WJ0EpI0HU?djS97#`?qeVr<6u zR`K4sO4hb1!+Of6{a;w#IoWsiqGM+d-(M>>F196OrwU|7Kjj_und4u&3mttsu(IRI z%(0HKyz?ACEtW30F4j>`d#TSH8hEE2yzgiD>?(bqy=z#0V#g7GtepNDwmh&V@cr|7 zpIgOIjXv3raRo~YnQ~tjw(mlo?K|AOMs(xb-qg(N3mHoV;@-%3B6#m=9XmA)%UjBt zKUmhKKkK;Ji>BXU{qnn+StRhdgytMlz!(@{=A$7g5?(^MTo)2vL|8F#$_OhWteE>{E8ZDdCbGAW zoyvRBNqq0*#BOA_@6PQQwPT1q75jQd?p_&dpFPPGqL1qKE3S!EEH&Yd3yt)Pyl=5S z-p%8COu@k3vXt2Iveo$FAnQ;8^w=jdF&2=u?wFT$ZDVqe^h?WblD0(OKgLUsEN9-3 zwU=nXW(x-E@q6#twijGBi83+Hog{m&Y}-KR<=e+F#*witbG{1X6Zt#qN0wGxX*OWn z)rG4~RqB!RV(}$rgBNDq+}kDXq#)gMNcK_%@H4SgVTkdrDXO^3?oTKvOj&gmM}4r(XS%o$E+@leSj)&~SPB zr4J}5yvyZTK|4&fOP=3*yyDxM=R@=pJ@~(ek-aC=C;8envA{%G6L5PX@HtiwKeuE2 zVtGFyx~QnPdMII!P@u4$c8d?~rX2X|Dk)P%5Av{%Mt+yseN;Wz9A(3Yo?E#(v)k#s zVjcU3*4upt!B0KEyw;Y`zpe=kyknPo$g-)FzW;6OD7Jem0u{BH4DXWH^PaezesVqU zv&-4Pk&lfPu4rJ+t9vim2a+$od+)r21BK#_OmNb{yGWVDzoP(2Bn^fTv+7x3y?65l3d0wpIAin4d+Ilf# z=Ma9onQ<(B3EQluy~MPSE0uSWsoJw-PfeWi6<9yGg!iCJ4t;kJudgY_W*4$Ci1%Vtno+r-set{nff~-btf{3+`b>H=pU3%>aU}Len9q}j&kF0 zWSEA$1>=@lIjcHmq2pPm==xc&F5(<$Zw@_yEbDQt{1ro5)EWJ7cD;#D zWbCp;)<4wGj+Z@%wr|8fbzR})gVH~i)n_uP`ZJ>RqtSsqv%zCWvu#o4y90eCV{Xz2 zh>x)A1+)j|yZJKrt*9IvgEJNy@5a1l-?=@e@P_`($s69yJ8AnzV*)JAnlDl>>8<}2 zqrKEnz7+m2c0*-!g6u6wFEtli{ZnA-qfY7#Jr&w{(j)jiyUvn1D0V?S+1C_c?&;<= z*fL?!$@dNT*1{Vq4}EgO)ww6z7n+OHBNAop%~RQH5V%-;LB}Mkzk>8brV>Ap>R5zM zD+wDV>)Zprvv{x_EPjUhqTNF!>lN)C9r({L@8R3LTe9`GP5WHyKiK17b;epj`x#dz zQ^zU>=8YZaVy{@)wLgr}t?tV#Y8Zzdm?>QuCReA3){uz-u-afN3)_&FaSo(+6QdaRh`RN}a z+t%#;KUU|m-?2o-8E%Z#A^U$~*od)f6>BoxT<7b1#ywK*c)u|d`WS;yZrZv@y)iA8 z+HxIhXdk{~?Wf1=vhDmq8QU*@THeX%y4FT%NAWXF(S+AbLHC)iJ*_y?L|aFM&58-^ z4|<6G!9O?o_j8}4kTGB}@|6zEWAmO%rc0Q|49M&KgUGPx?O!Clhs1^#KcDWTpON(@ zyI*ICtZ~YIw(1pklIEMH`u-Ofn@m9O-n$DIzeb(2Ug(`E{}Go%)r)=`6n|vj>(j2w zL-Lp59@7OgVc6qcSE*U;R?j zdy_uzyRRp`40e33UGFdBHwh7bkDzmy^myI7R3>{FYfRo|*~_?M2K^ZRntr4VTPwq+ zVv~x@=jtx>Oj>OjJ(pg8A$wew7KtCpuXXQo%G{XggZD&-qF3kB%lXFU2S>8Yx$Q0N zRLc3#*oCqdZp+DftMz->T~@ywsrZDp{4n*m274pj?z60q+Cp2+ukf&6)}WBbuAhm` z)|h|ZHr|Bs?bpO=&aVDD*%LH1^Xapx20Nbh7H6D2f2%)d8~O^TmS77(&#mokKD9E( z@wavzh_c9-S$`9fVINxNu*QvfcQV$iH{~_;uP$n0y;$^^2wb{F+MM4nqA$CyK{|ys zcVBz5=AMMSM`z7HD0?7Yl)hMW|5tOi;Gbo0x$V2`xJZ4f^m&q|ulJNEYd-X&V;N&D zHRp=YIlI|Z(N6~GLwnonza8ryh5p}VF2I;;dDzF6Sen`I` zy)?{kz{UOt$NXz`oaW{#17m)*_tp*>^Wm>4cZ1|LepV)P_ALCN)|Ztn{q0!AQ}}Au z9O#P@58BGt|s_!Mmynr_+f_a8|a+jOsG z&c4I0BTD+$OWN#ZDB4MefQ(F!iALq)OSp!T6E5_IC&Jj=|PvyP1Nn?V4C3 zP}WTuy6t>^haFF~b-%@2jJf}E)~=UNHl>yKnBsk7OxeE4CcdxERPO6AiG6EL^}Zcu z+P=3;?W^n|K>iSGAdyu8=i@k!hzE?c-+az?O_o0Gi`ZRTe2i)J$3V;_lZ?&f_Y{TV zOJzK&w%pIN#fiYUXQW?ePG5xIEpBHo0_Cb6Ur9aG;xi{R@2r#eFsYmTFuN}KDEq{F zslz^ww`AV7$nJ*`pXIM_ENA|SeHPQF*?Fj}bBJDK&4YYpUgYK`q%ZGytnNgn;9Y-` zb!l0XPD^`ulr?_ViW9;1XWW`7zPjhkWP0m)+<$jry5C%IL+0F*gE}9_cRSxdM*6i< zR@>eJtTFliopdStI+=T=He*wtvR||CO6%ig>?dPd)?If|=2M+teP71P|HFK>{b{-9 z>xMGhJ&d9k{Q6%ge@y&?_;hQ7#l`e>cOT zn&tE(v}NAY6q!oqxYSt*Yf`1;XXQyZ9}qtz{ZW)YO8V>`d5*aDooDVE>QwEaXPxbRfgXd5IC)sL*37PQEk@KTY*<{KwpDQA>&#$^0s$B}9Jsqa^sjw_gh ztqv3sH$Q!^jOPNe_F0K&`!$oJ{xj&`j+gP3apK8*FE)`Muh$y-&83WmS7X}&|GkmZ zhtyfE_MLtbpIwBmJgX~Nf2<^rYDve*b^D*F zmm-%obC$uhW$sjy2;Q-rHqq!bD3arIle*c zpj_UC47B%te1nm(;KElWO{quKOHlNJOa*Q|_0Hu|M#+b?WSvxfB0FhT zA8DHd{SRqHQs;(}PFHs{YknJ8Ytg+qnS<`0l{+bGMyks){8@qB(<^;GYo=+}77E;N zR_=I1+9Q2VIs16GhR1T|a(eJcG@b*hw+}m%HxRP%-`J+$l zWMsL>F5yycHy-=DF6lSM<739x+HqvQKR)%>f&KCBus9JJ(+-cLeRG7e8A;#w@6@p! zXCwj_zAW{JJ{hwFWgI?*dMdHyl=T99P1d{AA{pn?u6b`1cm8A>c1(QA!M@m__^=Yn zqU!}0?i^N@f)0LX)G^k?uD|H#i>@2BIodw*>#hH@%p*&EnX|_C#WEje9k5WwKj|e2 zS=WlP4pEh=XN@joHu%r*-vTV~ZQ0rneTen%@-EGd-;2esv!`U>eH#6v{S7C2m?rD` z)RU|!Nx6)^C(4hHV7=vRt{)z_KSjp9b}o&544X?&r(e~!IKR=_w_Q&vS!IHUlE}Ab zp#K@8<160R%336KQZDOn{FYt4FbU3BwkqET5EZ|6dqbBlmrY*k&Tw zb}Bx2VC>EKCF+k~d|P($=Ko3JW#2c!|Bm``tR3ud?+0W|BhUEyO#~Ngr4850I;V_D zWepJ>6vf#e*q$~&xqen;VtezqFTU-&?6G3siP#zIQg&U&+Wfg^{3H>$V7CeWe&8LC zqQ0@V0lff3$O8`nA96 z`;paSJz%|#!P`1Uq3bTI=ca-6w;nT{*F5;Vxcp|ln*KB)cDwuv@}0$4Zibn1+pS^K zz1_sS-{iL@kFr+UB>ON}tNPx7q}RoqY}c2P?X%3q$kpUM<=b}aQnBqs;QXEPZo=2M z=$En;OMOdyvYxlzjtBcKmrEbP*!bn)b@u-ujlbGEWP)!?`|tDH*EV1OjM*#jt;jaT zuX|+Njon@?`;seaX;+@zN6|Wgv%GI#e9~*{JjZJ}cRK4(vWJ@aC+lg|>6?BNV-75P zXx88Vh@AtJ;t#`%p8sjGV*>L`o|m;WY~8-ol09awea*d5;>msPl}lXdCuDtqv0D_M zQ#i1O&9&{XdQ1WRXhhccY1cv4-Q_(=t9|Y+!+VgEFWzt$>!{2R+}eIIW88zWAv*AV zAp5!Od}gQ)_L0U_?BTV3MaB^5qgC`Vfn)LSykrIK8eO!UTY(;8s)zCDVdB5XDwtRE zo3i!yx2qn`Mh}lamF!@`pREU3CmP&$I_El%cmsMMuFRKYEV1HjtB0ZiJ#cNu8XkJ! zJ-n=E;tPYK532_|&pPpf_1p5UV}>ceA*1?WjFAY8Wlnn_j6Mc@?zXqIPrxRyhjQN@ zT)!E}r_N0U>xvWlc_+l4^Uj;SROcf0pHtuVT{!Putp3?U$NQ)eyoXp%J8a6TTbbL) z7&YpRWUadye|oR;edCs9GL`(Ei+iT?9qbHW%N$kK`U}p@FcvxSiTK|du`SY!Nj_6E z$KRnX$?slTy#l^qk}>&qErhwJ$0oMWSpI7pT)Z9HREIA`xy^ZrnjEoolv=ND) zSYB+`YV4Tl7vw2E7+-I{jbVasl~}p_`P>fbM&@(H%x9giAMm##^UARO-RNaH7OcVt zxjma}vV5>xXA&RmC4w!DGLH27r8qX>{MRR^%lJ_4P0bv5()q!noya5a;O#goyWh#~ zb2={fjPy0sXGGQp*rzJ{&=;UXe6IesZj>piTx|Dd^4_SZ#RU6z{=Y~!K|N2$&I*^3 zzVvPMU$Q<~Nq#}{EvXqb*ssy9N{K%aeHU}SoO5BeT*$FWWEH(rPUJb4|87YCkazIg zwSUbnCw}E)se?pt&W%!L(LZ|vGO0B04UqxaOvlxHb!b*zo9$=6JJ8P-tU@OecWK%f zksTTKO5S!%AHX9A-`vFhsWRWsZ`~2?vh|LSWAD^nzfDhGoU_|YQ6A6lvszws{v>A; zdokF@Hp|&UPtLNAF{ailq|GfwF7|YxhbY$t{1(dn#(#wPKJ4<*oLX!n;xQg|ZL7H> zVRGD>m-|kI-BXZtzmEBvlRY@=gzU#cu0s4uxS|LjdpW;T`#O6bzQJ!^ZszxA)ts3p zr)xNG^LYOd-qgjKPQ`c=Ab;vHyw1&SW(VS(_T966w=Vaw*Y_k0UGaN|^I}~iOslm8 z>h_`~r<|az@tgkhV&adBmPDC5X;dA3W>{+_|^di&LwPRm+|dm*=f-be(1L(kDJms*Oh~e&Oa}BEu^FYvaf>5q;QwK-7H| z>5ivdC6sG~l$m?-`xKei${gR{^XHeZRQCU9Ubl^VIP*~@dyy#5U|gpQSq~^1+^2Bs zRZ?bY8>`MDA7sY=1;i%~%_G>&b9TP1d5mTwOiI?;r)GY0t+naJ!4{9NFlFgHKA6wU zH*6n^J}D1&a_hB}X`z%Iy|ZpK>vYm9tCy^IjO%ieF+ z@lUt@3*DpF^U%#Seuo#}+4H1-;rZFpcaX=R9&9~Y8=IIV-z4U~e_mb}l|95&>Fw_( zA9{}dk+jfH5&7iUeAvV7+JMRT?~4xPcSY3C8Mc0y=SaDb!Hz!@!KP=%*YZyHE>qO~ zFzc%}53|KSH)RFSHNB7HL{0N_I24j zdu2_dX|hMy_#&Qtn7I%(vwTcc-o+=R4Cv`%Y-6JM*ulJ-MiW=;#mYcg&X?cd%38I2 zBf*aC%!u}GWVd55XG;Z(9(&6ER#)OVyJ+~(Lss%&j(l>WcNXv6g|Wq<_GI;6?LF+T zMKx@dJf>!T5g3T)^2m4LKhN>goxF{;Ti^Z%+jouZb5t2_t9Z+x|ELk2h_6Wm8{Gc8 zHJ`@qZ!UtjP7>cL@3`bU1oXqToTXo|zd=Wbvtjpr63W9ko!<*Z_ap*m6q(>_GPfHT z&u!;BB|67Sy5HCG?w&m~QZIf#fV}z+$$0o9`9_Vt|EPc7?nAA$o zzbEg5r4CttsFHfsHLp+w&u~A--dn>O))MxNnA{U$7xcAJ*4KGA`yZ!@@6dGf<@rRg zUe@2r+<3i!ogS}Ner92i{39hP_5Oi>|WvRo(J{JV*Q~+Q#q^ zGnYypa?LYUw1s@xn~84DU@vvP$SvjPUYzfnMRZN26kWJ?qwHmOy1d1vLp=KB`bkqW zFTO0gBOd-~<^rd?nX^Sc@)una@0P0ub@_RgqxOkyRQltBZT`2KSYMe?nfU|y+Ue_$ z-!;nb4NThGBeKapborfinDLOc?+KOY!S*`=L%$<^3T3+GditjP&QJI)IAuZ(*@tV( zEyZ00)vN6Lw&Mx0d-BSWcp~4RE@-c66Ee?mdDXV-^VCVh_{CSs_%^V= z^XH6jXlu+bix|t4EOx);E$%$Wli&RB^0wli*sFy8H!~-ccPSD2iVfas6BB)Og{}U^ zp}$q`_k+|0ZA<*H=9@zr#nQLQZ+ZEhUWs?Yl)8I$Z*i~Crq80X&MCCWX-fw(=SoiqiZ(Z&Zj}nnp+GR^qtth{ea< zZ+%3Jaug6JV0{}b&r?^|rXM~g<=iFlDz_lBeRoy&wAC$Rf-L>6Lnf{3`m?F)oJ6oz zzstf}&Kkx61OEP&>s>!vXXh#6o5*X2`lPHegxIjHH#;Vf-;cO5-2A+IzW#KPNBU#( zx^7r~%Xo0&;P~d|<<72dd5gB!XMaB(IBg~4=Ys5a6O-4RsHrHDwI2R^r@_6OX_xlB zo}Cvl_V&l?@;;AtSzOUidmH$^j+t)PeAk$o?;W>wRLMGY)RnL967_XbK5e6{WAi=` zIl~gimF=c?&||DKLmfTRZ^yWj2QnAgb`&@*ADQf2EzbBL?zw$!iQo+Ty$I~=|LPlQ zCiv2RKOMXF$6DBD&4;jS@ujren|c3b>mr|ZqA2gc^?lGyS|Tq*dFQ6z zA|ouHu!w(+ZM?^Q)@EzpcD|_g4JY%dyZriFK4srKp>0m;Q~J!{ z4EG+5`M#?w`^~e1L+k3)TB-A__tZzmvqqN)oH|1EA#2gJttz#dDU@e{_-8vtqwTjB znG3GJ@Z6Kl?3Y0I#mG}A{j;<8o8L+`oAT=~e034`WZWh;5_S8aqwIhDPuUkRINlh; zbF#+3_<7*_P+7mzV;za_b_5PNSpxm3$9VU!^GoRXm+}n>ndjK=NfPfU?_K+7&-OQk z6&2EF+SILQSpThK(VIVJ53P*N_AvJUPx=E{@3H+D zWxAxJg8u$2_DH0t_XhgwyLdM|-R(tPkz&7DA@8RjW*-yt>g9ZsihAl|JpZAU?NL)p zn(elKT5S4;*{1lN;=wt>x6g34`utWYGryOS@3Ac-|0w%l^ZBk-KKo%J@@`={door$ z#XNozvdQ-@&t@F5m3QP@xId9G6aBjG8H%j9k$9vbW!62arKDF-H_LvHuYhtFx;!6nn3IzxNsC zFBvTVjc15WSFnyvxqC$y_$H;vG}sLPywcCOYsN~N#ZRW0R86~6G3^zna>bv?rR z-jcjFZ1X(Qh;jY`=X_a*q-;f;gU%+teZ7ujOXYc4kI}RzYq)$<%#Jm>?-X01EmMAx zEfJjlg6PGKZ%6m|d!1!WmI#c#QReCRTlrlce&ohUnqJ|=zy3y{e3SD3q3!MCqpGgG z@qH!}93beZBSs85XtW8$5N&KHnUG8*=s>hL=!7@p<4~Z2U>hs6gPzGu2-L)vUQo1v zL4(4*;@d^5ErMPV(x9XY`{5>Rd&f+ZdCn=eNlNMFv1-;VL;m_`Wu^pLP-Q z=!)y7Af~b>m127sqj2(C(67kcsUI4-QPNzFIS9UoL~^4Fbs}D24*Ha2|E5heWpY}s zRo+Eksl1kHpo3N2oJ%(vpJXZ4nAF=W$h8L910_1@q!%b3tM5+D>wTY!0)_zjE(Dom z=T(V}HY-vI!Wo85jE)kKR@bo8*L}7Qp7XL(|@%56~v< z%)MVqfexwlYXdY!Umgjy?e3fFu(PeSH8 zWd-QY&laNW?h))@NMKnkF6Ahr%|pg3EsjwMQrZ44xvoI)rI+~f;g0VVUxx>h<0%g^b4a;M3!J(vL8A}K|I(~ zC$|4~&>8HNi6s00?XY8GUo>KQ?10MJ8=srC3u9d*{t(39K;9yEifbdDmB4Pr9LG6$ zhJ048we(SHzq<6NpxM%Op#7YrqHK z4Z8B8O{}vgoh5DDnc6M#+coJ^-PR?qo3@2Nb-(Uq&gHjYD>3q--jNry=P+Km0M}ex zY1i^<8m_Nj3i{=EldqerRTviw^ufJzC0skfAMM98H~iH3EtkP&$2FA1luw$Dd5-<4 z;D5>*z?{xy23+d);h%$VM*4|3%^bvOV$b+z)j{r6)O(?}rDuG9UG4A<9*3-tKbbN@-V;MW?k(acTQ>8TnbGX_)!lyXJp3@8OHcVk?`xc?rW zW#NAh{s-_sfd6j%{}}%Z@V^}Yv+;jF{^z2O3jAm6(18$ic-#-5|Aljua{Z3Jpx(9A z8l#V5UWM$-r!H~hJ&@CgS4`Y<)O_e6)KyGuhBY5`TBr}aZp|+9gNC!fgB_qvJR^<7 z6XA#GlVMCjsND)N#<&#ULmuuen~^%ix<=gyJ#Mun>#zE`-tx(v11jx-Q;M0dCtfHy z@cnpph~qxF^QcN(J-9ZJhR~+=F?PZRs@p8ZyDq@_7OsbIeT^{GUpe3$$m}F+%1=!0 zEIFrs?trd%{QX!4Jg-65N)R5z__mK;eN+ndxo}^DHmECPO)o^;CNekRS;-i`Iu*~{ z8PA||WTm3`p8NCSvPSs)5Mq6@6Uki6ajFL2c%Aaq*l#xZepPVQ9L6akJ_dTlm@)9R z6uL@AAtoDb_$GI{D}S<{?*S8Za>52WF>zk*4&{2rlR0)6_e!ppMD{a3Nqc%NY&kk1 zVxV_K)PPDv#|=aq4fwys{67i*5d)sOtG*EL+Z6wEFS4wG!>)@zA-+LBvL8R#BQi$h zlU_$(yfYow4qHCq)byOi{ZT!n6XLNf3S350$+Bdsdkbg{F$6sr&uysJ*E#_6<@tw$&xE(F*N9j<^~3_=oVmeH6&DdL?|~wD#mh= zfxEi+O}r3z#WyPpketM$T!CklD?a{`80LCcVlZN2R;I{{YBT!AH6P*W^)GLm0$g;b z?THSrAupjBs~YA8PLCDF8*|tPX6~0YEMurzpaY=)_tIXEHNrUJ7Hh#6#;e3Wb$1=; zErhvpgKdB5qa7+S?oY8`Cw1wIUP`3?=u33|k?XH1$XVF{y31uOMIb4*mB(a^u_ui6 zfJU-V=WNzP|G}iU2UJ3*H@5D&Le$|icBq=B17AEuy&rp*v#?*Du|Xx=+u8KR-iMkt zz2|HCOmv_+mM0yfUF?ba;vwP+^*FR0qFf4F)>`FystCCHy6$@y^4P4E{iU*}&cPM> zwi9xgF=7^VY!iD0pLi;DUI_8vW00q9ApFJ3CI?x@^zjH)?p8P zg}Hgzubev?^jO_d0me)0eJF7ka+_Tz`T~_QcxDzIzYkYUjI%2Y1cXWtngP2bXcK4Bd_W^x_|^ zJ=gT#XUafV{XrS}TFN;(*pV{v%O2SGTzPorme`g%p@V{Ew4PJ@1=_$omP*|*7X7>f zeqzXC=J*5th5&z_JH`SQ?7Kw09@0F|y&$dNy}!CE^)apktM5$h#TEKhim|ZpYo};y z5&IbQCFn-ATAsqUjqitWe1T{1yR{hQyzqw(L7BG&5AY{oNG#YsFy7Wo*d2JK?N;TsBdt(zPqhb)HS#^_2^5qso=YOd?z*{d^Zr^%`xBg;Jbmn->C!W+rXfb zxFyCH_=8cQsl`dyK+q@pm6wYCm*o23!kxzM;<;lu@CLn*K0MUFQ^p8uF@DE5K-;z` z-^CupoaHF9f{FVT;v8-WJ7rbb-) z@Mnn!tUWy~UC4t2oI$o?{V;xx_I+Cc!a^Ac9aUn38wYB5gdRcv7@yK!dK^Co{{x1; z^*ZBj)yO(B`pExo@(#*YWPE!T`V^s#NxKi`imQlc==}7bXMVplDYoh-8+9k&u=i@f2g5qRn}Hn}|7Uo>rupUU=wg17Klefj`9 zK6wUhFc%nY_zHc>1+0x)=8YQynipOUt1n>_c>=zSkD?B)y7nM!lDMKyxr#cacdd>6 zoZo;izu1oz+%(&t~t*rRbP9omMBqko$F^bC!29Ifr>b4JWd%}FTtXdgV?4f?@; zM&QN3J@!+!%k?Z^7^uh8s=yffS$FTaTJr=>HL%n0cmv?sq{qne1|TcLuJb>^b&#g# z^T!yuY37{smvFrg`vK&{1>+?~_OCM6HnO~|O*_D6-T0y1GDY4ve``7JSytep4;^Iz zr_S32xhLPkhKF^n{Ch$=hbj(obfH)q~KyB)lPgp1TL1J6NuIeu|-;c8xb0Iv6 zm^Y`MuzMjNN$l3N(3GvcrOpx;*xS!(G$v6}( zcS7fCn7-Jl<2!2NxPsnm7BqtvFgJty0hVSY!A497{4m(9;F;Mb6yYmA8_P{)xOL49m-B5e1g|@Jx2l#p7{WoQysUXhZ^lHRTojm z$lg_1U#WfboW6E#Ri4V81mb9QY!G#F(p)e}`f{ruex6E|cc*B3nKBw@6_VaZuac$1Qa<0ostlq%?xsyANIW&0%)&3}C$CA<>bm zp(7{C@$BTMsF&v?DsVsiso2?Z?7eBQUQFDu1F)qw;HqK0aX0^qECH@WwmSL8Q0Fp% zIYeKF*jyynD&=rk{eyn~I*!SfHQ3+FIq@#BvpkA*!?+6QKv9*QN>IF;$^|l)VEx}b zLIpD8FEGBj&DF>mFkLmkrmA31Wt#;oM_pFui-?L&$ok+PUIU#^Exk*(1$y3~Y44N0 z4lNUhVfD#v#2;yvbPe3EV|@k=+I&4|BPW8rei8L}Q+?s%O@y29#|tlwEvr&))U9n| z>XYRd8}X~yOHPjwkHFz<)NA|;!Gov|d%zAg!Y1SGzyHfVV=!%=zU500IIq9GPUA56 zG{2K?@NLF-VmCEqujN>=59XU?&X@xCJloP^V;ve%$ortMu7;fh&-$J}>U!kk8~|zaXb_u&`BH{%_7L_$D8+h&kzVA~TYwhz)KAa_q1lxN>aErd!=% z^|4R69zo3ELBWOi&=6x9K*23*ToT)Wvu-?;*-I@~dc8y)RJUKgRl{aM?p406^(Q&E z3o(M~$2|z}M4P7m>AVL{WL^@P z>KX%m*QN8CtBBi`KL;Js_QU+WMO|L>1v>I~Sk|5|Gv=Inu3@3*PZkUQbv zbZ<@|c}z;{KozpCufEgO!2gNWl=oxSCBB0F=~S^H@Ebp9V>E3C_Q}}u2fNP-%bOE? z0=XUbc!vam|DeKegg1veUU^iFE^qc?&afW9JT2ejS`1m-(K;M;==~n_u`#yI*nX^} zDPyCIt6!Pf@zVWuv;%Q%T{glyBykt^y+e;1-Tcx2pbpsMw4ENh5%QW~??e?~M}Og~ z{Qz*}iwz&KC&24Ul*N3crmU<2%&-};U-<8jGhSez*NTtWUsqQ6(Z11bUIiMHy4%Kp ze@Dqal^pm6Snr0>D=^-Vy&ppv(r`8EEr3rQv}k!&rJ!?R52~KqsPC5@EAcNKDi>u> zNTMA2JG8n>*=T!re8eAptKL1(B0@G@T=)7xJh(u zn5)1yIe`wyVOQBYBQHx~6LCW~^0J@Jg zrX=p=%uvYn4ah6&Nj{}=I`^oYF&E_f7XcQ#yF4~#z~1f6r(+)Q{B}~=gvM7F)hIRQ z>Oar5k>0gz?%G%j^4rDd-r}>>IkD!&kY9scKKuO%u|;ojJ`7aGJ-_$0ti^nQoI>#l zKlCkHi#cNOlt9J$tz9iM;lr9+9t*7d!`~OpRC#gFG`yP-YpH?n-xIC0*FElQal>Ej zarqW)!?_apE4=8F$@#p)-tR+fEq;SKQ#=lSBbeD8|IXHD}}bbe|F z)*bU-^>a5=#^+w_v$I{u_jMlL6$I>c=fTe~(pT}=1+9T~&x|CTwnBZ`sAJZ}F*}=O zE{?@LD6{$AlEAw2k0(5YBR-CGO^d~)46YMU=GO-=2&}u!A}j(2+K*=gj&ZC9*SRS3 z_?+gzx)r;>37+Iyl}}iz-o9}h;R&Wb|F8I|fGGi(PTe0!qzKcOzN-Duol=)RoQCOg zz;r5LkurqoOJB=d$TJ0as_tsLj4%b;|J)U~0aqU2Y3K$L<8EE2l!XjU#d;Fv2UeAa$&Kd!m7ckYa3}Hi=lRi6z zaFu({_@RuU7qB&69BcB1PzG%)lsUP(I-&|t=GP$^L+^RgR+G0*x8*^ZQ_uWA^`0=w zOq(cU2zc05lXnWrpe@34+`GT6pU{Xhzq?Pyknq%zrZoUZka`84$<;VAp4>^ymYNez#o<;vyvFDIRrFF*Z1H9fE0Qto}Prhe{5Et5#kfW4}0$zt+Fu^`<*ZQ!&iCnzCyxRe(`BF z0^f-*epK!)S@JdbKL7V20^jG)-y-mx>~1ah4$uA?eAnG$34GU$Mb04bU-ru{m3w!T z^@lH*`k!+NU&XrjuNU}+{_VAL@5;Bo2H&n(mkNBlramR`xlg^j+-vXe4`0RNLuV1b zz~aC42z)u)9w_%tn$;gZ`#2Y9@#5H+n?~*?d}TNNaWi2Htoze4(p|i9Y#@I8c~XXO zMO2B~qg`Qh{^`1ISU&mh>h%W$rUqhL+%2z)jrs*k?6|je*t>vWe zyM6U@?-lxqFF^e#qW;Gy3-9Z#e<OXkpMv^_VLg${ z`k(BreAvA2FV>c<>|ynv|xwBGt_Q2%h~1&dif zo;&c*ME#iG?8U7AwBGvNsQ*ID8H=aIn*28)FX(B$TcD2+Pn)2hP$po#SQlq|m}}Xd zz5N{M7pM7_LWfD?4eiE9PLOutLk11uJ@g!Dzi^sw8T1;)=|KOH^%eFtCb`ChjY`ht z;o3RrR#+SVz02RBs_dCA->4<(sFgFY-ykV^*h$r$$OD5ouCS{l8_!HWxz9%Q+5taX zN1am2cc=jMV$}70{mtl|cz!hBBRA-W^zAs`VI5wF|BTIwASO!ev?%LFxu@+di|?~L zm)ys)rrs%G*XSi&tB2K|9`t7i*IVdIX`~}JfS5&{LmM$G+@IDmgZkJjKE@J22lOJI zK=S^GFAzH6*vrMU{%j#Ha(ek@_2|K~zG@rv*C>tNSgy*mUQRG%RPzZljwt@QN< zFDD*~UZCw8a3K!wQ;7qo9}@Sg6YXeo^WM6|ruSpCRRt5GdzbP(bnOszaO91E&AO`Tv2UW>EyP|j{Y%{O`7fG&JD5jcRKum?GC?@8;~ zTsH^S={N*?eb#?a-{#t%_6TSF$rwhAjo)_bxB*)Y!`a+VRz}nbkK2P)v7I$6#`px( z51&^L_5$AB?cka96UU~`(sZ4bNjH4El0Sm`nNk02y&tFe6Z&t(&jR?vuCv7cgtcK& zVm;P7ShK?a=w1qcDqG{jn@4kD%)xUyPd^MG&Hnn_ql z1KN&aO=+8hxE&qWI0v{bz<(EE0&M4nx~#gkLXN##T|G*2WgrH@s?hILF5bBU$*jHR zT`u0`;T`Hn`-s=)cYtjwY!;T z*NgBxgzH@V=a~C(KMVKF-*5%4HMmX-b*Z%|HyihjcoxQWKCY#>UWIqajUYZ+=9;8E zCj#3W?-@J9b5nSqg?l*{2KVH3`fK?-8~6F5 zM;>KEhx)nL-$R-&UQNg9BZs|ZuRCgfrhNkCy%HyGa*muALJT474cZQq+Dm%Yvhmf~ z%C-7|KC-cQ-#2nQ39rj}Rku!u%>gt_`o;Vbbz)9nOCkTSHolfYx6VL2;8TIq^__E* zd78dpH!mXnCGH9{Mu0Kuyn0DbI(9|pMh~l3wxhm_=vyTp(ZnES%18}(Y0XMD!k;Xsly`q{Ibxhy_y ze;|I{hQKwD-K#c2?geB&jDPfUbsp-{m<{Hug_ZD3RC z1L|bj@40;$yU#BSM9m(cqgM$mtUccIBqZ+TGmmh27L39A_Eo>H9S=)fd#AKwRliN_loFjmtf z{+2!uZ!jwPn>@IRz9#+x_2O*wUF)*duzfSGLF0yIFJF(MQArB-;1rK0eW-`?wl?Y?nTUp#!szQ|uP(s7|1gkAor+P8wX;PXXU_;`(v+JWhBLGe2S zu5tb0Qm)&$MwIcBH5|rJPyiF@#C0ww%{ur%Oci{b z!^a!`mv|(=1E24(gNA-`5tCNZvIen+$dMnqTfHXzO=0iZ9gri8orL}Z+9N)56F&k? zzT?R7Vb7wh56|~&KAoo8ZLL}rB5A9fNJ;vVoYw}_5&Yv*E|m_<#!!=?d$scZD{ww!>I>SeM3g-U)J+Pg2%vq_3A)4lx}$94p3* z5RZrjapSxg&#jE92JNG*2a%UkQ9dNvnZMx>=2x$u?E+>uqQ4t6d6D$EWjf@6qenUO z4*J5_rzH2BV19RG2X!j!M;W8z8M(g78;X&H6)C&!OQ+SZL!nl$5#)Ce1X&3TC@Wt(-Gn=(A?8v42&$G*o-=G3)J{LOQ)gZ`4Smogp#C*smc zGaMJ3m6AvJc%F&akbtXYBfkBaCgdB8{}}B3c~5wOdDkFMfUB)WesJGt7W)YOU3ii- zfqR~P(h3;TXP=1ta{F?TsPA$md3Ti=dk1I9I|H)cGeLxXWw={ z=oIu0{1q+xk=|2Bej+aePUItotpI#T8BvXS8nJhBo~t7-IL=z1_&xUj-?aZZ9m$!Guu8=f7w^|W%&T;2wlli(h2%IB%@7<{Wks0X&!;xDpi^K-LsFPE${LX zUx~~WI@#(LU5IjjsfE0u#!iF!1G@f$53)XkPp&DzBSYWS`k343W6x3+XnusQ5bTjT z6mf_LE~BmtUdsWGF_(#)r2;>PiIId&NbJ)mej+?4cH3te8>;IfZ|ilL*o{%&5Y}z# z%tM_ej0MK?=|Y!xV(#i~<5-?&#rm9FcIghX%`abkNtyGWc7xf+S^{`&RP@Mq-Z8p-+z|*M| z+vl1hki^^o*-Lo_S@wdN%R?Lkyc=yJzrE%i-#D`t%x6wc-QLh%j(ox%>@6K2ehK)bpqDg=PY6C6#8e@t+OeNt?XLIZH6!+I zPSJhw#98;@`A&{6aSkzA(z|B_a?OH`A=$%sjI*qf^OGURiErS#L-3%Ud4RYgpKy*? z+M=cqpX7bcP5s_AWWEEQgjYB&7!%B`Hy5Iv{&P{kGB?dSQW@@XU_CfLOvc*AT!1>W z`2qv(+IX_<54xK9PPP47D4 z0rI_i8Wxl5>8BAsF!PpP8%f+~@7j!Gg8o&sbR|8(gQ)}Xf4#M&3NT{M;a)q?`h%vw zzQkQRUm3q4%+k-atlxGo+Pu&iSGI{b*fPl6ulWjvURHzOv7Sf2bI~VH1hxg(^NQIo z=8)lxYcKR_iw7!^Wm_qf z)p`;6h-ZXxO%GV=WX}+EQo!M99O&X6y9&(7dS43SEV)j=J`yL_uOIKU&-r@b3pSs` zy?TEK_U0gtm;U6ZS^-}v;M?HHg|2Ed?_w;>IyDlEYJU`E0P=PE;b!r2KVo%z7I@bs!6?>0g@>+VzLy(_3Pj?_O`A;##Sojvbkt}UFh5Jff zHK@bq=oPmB|Ez0SHS+6C$C;aP$m)M=F9v=qCeOwBtx=rcTF4w4Zpo(v`pegQd3Yv> z^)c4da<-z@*M=~*_%-)$j6(mJ&m3{W)&}hJ_koYO z*V7FWv~{7F2;Cu z$mW|xABKOd6!l`<1kReIIYR<%z2zI->_sM)+PKd3A{$G z2`N`gQ<7&&6kRi3xpAL|dq19gaPP;x56`{0FF<)dGx<7?xf$(*`n9v5d4wKYj6)vw z=jpy|1x>xH+|A%!=nM;+DWjs$-SOYZs5;PV4aYSJ+SGU)d@lMJpgj?GXZNT(R9R^C z!6(eOR>rra^>8n(52D?)PTLQ=bChe*Zs=VdY2Mo7u8{dQZ3A-8BrHLU3HSH}l{(tt zf6%xGFf?*5t4-Y?UsK`+TDF<72RsYAx%6O|sO;p8)ZId}fCP z4}-}Uur=U(HOgg;zk#0u_Ib2vmiNFG*`=bRSBjlh?_HNRn!jLsT<0)9d~Iscr#L5E z`h{<3?*jiw{&m^=Zsad{hPl1CC%P1<?&~uu(x3PC_Sp(Xoj)V1w zW50E9j5gmTJyO0l4z$=0tt+~QoCW%-qfRDtEPCF}Cuo`36-65gZ6uv>-LeLIz1arF z6}-I|XI1914X(i`Gyjz{C5ao#U%)u7AB?2|^jqMAjZfBISZ|TnS4>v}`5jQF;=4W|!Cv5;2f9h8u?kAKn0N(=!$sa*o zk+vwF&j=kvVmmN)Hp|ia4ol4a*#R1$65WXp{9<1uwbCW?bwNHcH+&7gH#s41;QG=px~F;qeNIHs=N;*>8e!;x zJScmzVY7fv#q%b6`<>iLoD(N~`bz#V^DNIULtoiG>2x0DA^F(!l{qG+a4dAWwsl;; zfNpDWri~lAT8Mp1oR2V7s9mFZm4kX%JsAanwOvwmoKW*&%d;Z-7hgy;ur*ccXk%XxswL;v3o+ zI2L!TQOrG?171T+TAR)x!5oMv6Lt-hym7p*O)V=kYo`!$Q`Qh>$t43H3t%gV&zRtA ztHsz1O6PUThCY%5UD>}9&rM%mBQMFiOFe!eq-!7h!4}762fpQ+O85!9)k{}R3mGFs z9g{e$M!s$C=MmioISnTq%&(6)jA9=4q=48kK@*ecX1+3TLFxni{HW|dq z5QlZdpPrAeKS|n$eg}FCWb&TKJH#<@4hXy4d*T&x4w7~20ewdA3dmlJMTYNa6L4_d zzCJR=!9j++C4cqeAPzW{m-r{m$lCMNG|hM&n!%XZoNtJ0>Nntla1wb?Kog`N-G9EL zjPB;xU!U3kP&4zN09Jm_z8gFgKwmwH{72pvIs!kEHc<8qbGU2z2r9Rmwl#gr2X`vM)3d5LO1%n@La*&V%Whui2E}qrK}4v^ShKThQnVjGv4nXtI;^4cU?hTA+?VdtVIq z=1eWf;XLpW@QmkmxZhyzYg+S=gC5Vpb27&Vu&^%h=@<6%!NxX_?+ibQ zeM0L-pRWr>HH~OJ?>AUtEaV)M);Wr>M%>a2{j*mmNc$VnpB>n9qp)v^GEJYk1|AN( zvZhMky6_$372Z+*TZ(Ir!{;dD*pHnu^e=E;)%v-v=h%Mr54vY-L>#o$@7FHXPU`?*l}NAyC;#}`(Q&Q`9U_qEM9 zx>LV?L2uA&EbPU^noHroZ&VWTiL2GV<|^#l$~ZR|v?zQ;eJJcwPTzMlV;xo&g6u+H z@Qsh}8f2aRW6fimY?FV;sdI#hpIxX2#< zeyrXO7s(upIh#1HOn`QJFUDs=1{ z--6Gx)l?5xb8foZR|rG zgSPQ5J_>D*F>Pm*Gi7GPM`p$1p-V-Ft)B%N3xT#k2lhJnfPWM&GCb_o@^s;J!?Q_Q zXEMgsI<(O6-n;m zt~Y>xwCSczt2Xt)nl$arFtmqyL3>dxqc^lF*ENhE>6K02ihtF<4F28wjr?mJm}C09 z?c4FMD(T0+hyFSL#&`xA#~@1nBo4#YK`s9@&$@}Tz-FB{w>I_3Wqt4l87Th79`K~_ z?E7=lcsnf5{ukulPy5 zTVK6va6{c#@CI3z)%vP(X?gdtgV+A@&ZTkp-dW#_yN8OD>*|~S1)AHPfxG9w8FydE zdXrd;CGSOII}OQ zo3bTrecl|voU37%9K;)&FNYotd2OGZ6@%Xi`ihp_@$twP(}TTzWz<`?LvPvYtDgg% zWju72FwUR9F6@m@tJZVtWX!84ZjROeEL_Cc+@@!K9m9GAvj3VB>;)q8#J;Fy-u|xxlWu2yb`jwPpZ0t^KDF}u(PFQRgAPLdqdt!Lm-8TUb`i(5sjELUv}l)I zr=k^Vw2J#1il7^DEi}7hvvnGA)$yw3kF0;PlJrV?jC6x8pCMh=#_VSt+I;_vOxi4Y z9lF93)^g6bWhe8jn77Y%@OyY&Z+(e!&HGpMWo++p^ku8)n{m4D3yo9D^X+h|zI#NR z9#LOzTxoE+w&P^%7Z?~q?AwzP_lCVO*za>+J#gEKdBcUhqdY&_F7vB%sJp}qv;G4) z!I9r-Kqct>A?}A~+#LL*AG8J4In?RR*l=wox{j6$@2=0peTJTG=AFMj_RYBePsDr7 zEy6MuxN7f@uqkb*Y)6Se^zYr`p26RHz4Ob*5^ED0@p^- zP41w*;P1}-5rtn;`X0DL-HY>9HkrPMO<6zq-Cvt}SNI2Y^q+6c+T$<1`rl#onE&Wd zt}F8>CxMp@^#7vok*;d!pj>~z76h3nIihHbL#&=pe4X$|!UtJXq2SAc?K9Nr3QTTS zr*K@WY>Xf6Pwl(CjOUgZ&Gv8|c~awBg=$kj<~cji*R0)v>CkzTSnI;(5VrpD7-(Bn zsP&_w>IVnvM?sGt1wDS$wqn5*{3T^r_mv?YGVZ^yXxRviTd1LE)G9R<>&ODUE5*A2 z-^HU1e4m476;c*982snAZam9LsD>ik`x7h+dB8QX&|Q~RlQh1_7Q`x=y7Ta?6u8O3 zHGnJqEETx=T3~x`L4D0tSUbb_)EtLD7yW_l`#}A$@sHMc(q4HhP;hAJ5Y-gzvT`miL4bw?Kwn^D6h~J&OOj+-(vkvbK55*VfB& z7JJzG_@L%}tl=>R_Dd_g_M^+ZO~3nftZDCN*v98NYgOvWVo#-yN$l<4dCttgf2%gM zR>3;3{($}AgA>fN0vTJ%SNPN^_Y!+)SLo@DGw#A!Cc{A|__p~n?3Wp=&MbMZN7?sT zFT&5b1ns&Fj3KGN17qJ!Iemb6iFKSSb3d|edB?cZ0~htqt?*mY_JjA7x0ETEv+DGm zbcXPPAjtoLkY^KWV~|@`d{kWt z+OZO?Q#cMWl+7!Pt6aOMp(x_PJTbVYI6il5Ebgz3#S5mCB(4v!Tph{{jnA#CiwxqP zYRn}b!~>&D;zoI2g7xeQ*lkm=+v+%<)yS7AcEh(92%oR!S!D06G<`I-*SphmvgzZB zBlq#jPcr(*_U83#Zywr%P4De&(;j5XdxiblYwe3um)P)R-|(A=iIOpLOH3MLacWan z#*IIrROlJLSwe?1rKFQ=x((SF$mlnO8Fu_%dqvK&@tNF%RFAe zYQ#W7h%vWSI^WUY%(zrT+09V&y~3LMX4#YtK$6`8kgDK z8kcuXQLZ2Mv7ZE@uyLF92Kh1rk6*xcm)r6#?DKcQ?g{yT|9OlRuvISXjfj)RnKL|_ zE7*frp01={%eVug&!N2Rw}EYWyui%(&K}v{mwPMfB<~1r)SbHlQ#uBfbNV;HG|Rx` z?gta}nLaSN4NM}JA&+Mnycw7dK6V(GB#)+n2{!QQ+Z{Rb%`m;sb2o@5Pd}JE{a|AM zi6@zp5S!ufg#(jgr^v(;&+9XITD<`G{G1Kn2u*mLi&}aQx?;ONFZ~Dx&tmoWz7xuDH58$sZ2O3nKnwW+^83|poPJQ9Ep$Ah?*5aa{(m?-4@hty-@qY#sGx1!BI zAm4SXY}5g{KKH7QHxEStaH+9oHrycH>}zz_a#1nHpsvl<=N5< zpT<_%FH_3-l=~py$A8bvq05tyses!PTBKTW&%JzZz=D|J1A7d;l)#T5Itu6+F}(-H z4p$A@u1(!PwF2=QQ8fVm7|aVed!}rR6_xriCks9nDSlsQ>Vm#}@L@xD+V2J);<_N1 zq&{(|5Mym(0`8!#?w|E#IAan_Umjpz*tY3UyYy$U^an5;(0Y{agRHrAAMU%YUmx=E zT~1^m#$*x31a+4AQ-U*&6UMHFeYDv>)Q$fbrvu~JuIU$Wbl?TvW6TfJ$AkKOafy3a z^_uZniY=Gp#c`ty3aeGk95+2?`_Bcfyob2sg=nv$d4%#_JyP11Jx%qbAH??Ixd*v{ z-i==w=6|i9BvlsRk@?!*<$4y^XlfF>TH?ZGLFl zj3DOQS@V^Gzn?ZZ!MJ}V>u}&C59im77~|(&&qmIP~?mM=_SbSzmv90q_AC^2!)fxAC|C z>P6+c^l&(ca-2CP-;9IHAI`)9agIKDb)R0|iTgTz|Hh{so%+1Jj@Q+bhqWU?zS5SY zZ5g{??~8+9)|>=kHw#nKMQ%WsiUgfRw&oh*w=YR z*81OqUM>?Gu$e>18_2f-*==-n`1kVlod4(Ba4&Gzre515unC{+n%XjtpwYu8j@uMT8dec@+YApe&q5uaDqfc$dN2<#xWx8vR0 zIG33Ah#2@>A-B)~oay%m+URh8n*~2}5n@JW_K`>J$geHB%&t!27cnG|-LLN9_x#Us zMShwATxS6v--X(M#b~Rh%fT;VfT15~40te?x;;0- z4ip5Apz95uTn4_mTn$P1fA1T;(n6d=)?U5;CyVD|g$yoKqGRW-MCY@+LQlXB)S-4H zR_`ro!-rkl)@oo|tD%qlmqXevSEX$UbuPaD-q-x`m*X5j`r{Mo`)PlCLYjfhUp~_(U%lG38_yNwK~CaEKWNRh9qm`3{xPVt@-XcO zOnp@u?U$i!`9Entc-ZzkT~nle*dnC;PFJ{T6UO1U*q@N~RIKTp%{Zg+{aDk=9k+8l z<0IGavVBu`+4tW&)P4^4$PZ|DjD(Dtx=ib4t{kjsX~T5O8D-WR>qJ-Svi1?LPM!ZR z_|<1t${2jt!F6W517UPx9tb<(P1N2yG%;7h%baXZjBage%F7yVD?)e)ci4LU69aQ7 zZ#ed^X5hgdjJazN&MA0xiqC$0BKkdLrCt|9_V#{nba6{{3{yVZ&mws>#ff&<#LEBT zi(mUzQ5n_)9oX9u57qGAYj@NXCEAfwvwbghwhEl5NLT<9y1P=Kj~_UElYArTc6b5h z!-gOJErWN)qx^*WD-7>k@ipG5op^=eoiKPO4BiQEE7o(!pKilE#x@xjCFdZ9)xQ@h z*CjQOEsg0p9dKa{)q76ZU9!ep&i&nvoq)bYi8Hlc!(3qE?Cw>wG={S3x2db&SgALh5D5J z`Z?gU`m@cM(gl5WIG5}v?4A4S2eKUVVX|L{bDB?F%lQU^&sQ9~r-qT|9;9J>S=*QH zv_dj>ucRH~;6*JfRRQZ7)y}yK`}#>&D=qq+LJ~V<{h6`4p2Yn)^EjmEdG;x;dWNF! zD(>I2%YH8Gv+rX}o*!csnPu#pyWvyv!3K=Aj#6u~U_-f6ZL>Yrt};K@oZ3fdtH0i! znDc5ZK7PuNn+xHiMp=|wk-!mI@R9iJfvOI1>K^zFnIj}=4?=$2ZrIX#_Uy`piLfO8 zbBZtVi-|tM=lF(eQqJCMU)@UvJA zWjm2|9@sVhuvPdTZGa9N#m=a(!Oit=w7+d|=x~b#JA~mC6Vn?Zzb9t`9;~-8Rw``m z{v!E0a10npGi=KlU#zoA%9N@D%p)ihG*4NxWsF5{e7;a%gUtjs?;4bi)}}80lw~!} ztqSa$D4-1B{we5LUi%*RefHYy`=}>@p9^MmwyKt5=%&7PpfTDE zUTZxGFak#yj~%!&AIiqyNwCo)&#K7b4&-sP{=CNUh0K46nZnzA-e#WXu`Ks{fTsBT zYT=bG#eNyx_&KbPq2m@l7h_C3X#;v>0otVBw4kgSXGjcGh4Bef9!g;Dz%w8BE+AIk z1-jUcu@S#$0JMxY{2aI1)C<^~2-@!SD9~@gx&BmY8S+2CRxkTSi6fS+O+ELC(MRjF zJZzh%To=(Vk=7L*{jj_Te5VADHKLmWzF>z3XI&*F7sia-q>Quu`s30syR*b=uPgL& ztnGC@b-?dY%nw|fnpmB<-JDCPey`j%+7mec=&`SYg4>TX^agEp3uP8=R!`)s>5RrjoEuQA;oa+H>1 z4-wBNX==HLW0W1XUUFijFX(~s!=6OvM$G9C`wVVj4@}*Jwl)6%?#X9{ zicQ-Av@O0pBO4BMWM#w?6lSr%h#5dkL7O6-y;e2@di)IVKWwDIB=&iB=M^RV&)trG zcO>#2(fB=i>n^8$d*hCw_U@g#w7&LldkoLFuE|IIjsHpL$?)Czvq;x=*-Wg1U_(u` z5ntG+r+L2yGJ$zgJ!oIs;1;Ws(C<@gQ_sGDcA5Lsi+6cOKFB*wYrkKE_xaq9m}uY5 zF^J+n_iWK$<0XIMD*G|0H)uNh#XjY#g@2}(&f+|Wa4XuT41t{2IeS!%?2SgAFq}h} z&Q$^XbmksT?!$E3Zv~ByX6FLV38Yuh+Bm~+1$^ev#N>C14^7@%P+H#2GCz1&?{`$& zNZ-XLO6>RpO`mO!g&t7_lTR)v4TeC6_}+efx6giJr^r~)6!_-{3wZtw&IG62PPPse znZbLm0pG^8p<}4_l>^sxxF3e+#Cr|O4vq{Q(1kHS2IWejr|dWQFX-35BJ|HgI@CU> z9n`~ed1g-e=UC&d*iW2C*cY77=Od1}FIbG>E>NH31hi^8PE|(}ADGJn&}mN?)uuj2yE(wg$7mxTYl$IJ{zfU| zD;tbBch3~qYAp}S=fqDQ8^hXTaJ`(RbFuGg#AblTKPVfIa$&LQ_Ka$?QY?qqi5ExV zEG5+cd}~4-2mSci$c#{NYf2q&&p6K~K5qE0BQxBUwj1>#KBC?OJIg!god6qdPT8rj z1^3hx0p_7nHXFM7y<->RohPn7D2jW|-WB;#K`HwaKObiVjI6yqo{t>$?*{7Zy@9&; z6_?(QanGf_ph6v!imKFSobU0>H|oY?_5nWTXHa;)4{;zN_8WExzsaZJSvCxKgRH}I z3-sba&S}oaB|65rWutOk0NYw`e7%+pF3x*1!B>Iw+`I~UA?iN-I=^rtO-!q0K4w*ov$>L6O}ibK2ZyWU>{rh5wH{Q*+RwbaOV)?) z(C+n>k>!}sN^yKfDYJ${Tlo5AF@~Btf`L<;kqNy$^8D-HrSE0t?N!#Q6x81i5!bV z$`Gegm)m{xBJ>?P;>@~S#PPJhysN4E!lI@xANOJJLO~+;%!{0)ds?wNhgFo7zO{O;U7QItd9<042m!|Scm^%j)Aun z&q~CHr=L$W&-3tH`vmp#GBcJNgK?}g;P+!aT1WrGaKdH2qwZg7)>yJ1A#A;H(0pqf zUMfNv*_Wc}9{;Maegi*MQ>$J+Acta+IU(Htc9=tH9Y_ z4UUa<+X55&p><2y=e~6Tc@2CT)qI+CD_0HI%V~Lxx)^KX7ye|vE7-olv!&F1ob_@* znH*5adjS3u{RDD@J|@X$0T>&T&mM_iFW6~f6fR`>%(3D(y?lMadgCw4mvYou*MYCQ z;WO$1EOWS5@{3IvOXh@=F$=52g~~N{Bl;u$xQzAl4)h^^%Rlu!TySo$t`B?QYUH!& z0KWj&wW)3EFix^Y0R0WnHi+&v;sWg(|4)aJlzchJ zh1N;1p(uxWh&H0=@l-FMzKcyo0{7d8f$44#>IJ0Z$L(+_M{MQ@|S-g_r{iFb96e z(BjpoThD*+Lk6SH-1zuT(xsjQ7lP-qS4H3W zxE{(Jm)%E}86Q9ShrHMugAh7f`eJf~z~3(UD{50)mSEl!Ug~&V4f^N)_Dxsyh3n^; zXP|$q=~H4@Ayg)H91u`GMI89 zHzI6wlH;Pv+5gy>JlWcB_S)u{y|!VIr*~Kz4ZJ6@FJ{bZ(z5nVYrp1iYkzI(k@WsY zGZ*G%$dpFllJ*NnrW(7&&%pP=w9mFz-*Julc4J*RE@P}it-~$suYg=Lx+lgSJjXbf zjZ>iu`8Dr##t|o=Wy5L ziA~1#)Rke4oU?KUWX254SvVJq@x08vu@dtepV8iI+VHNxv#?qKyI^@P+DXq5M&3Pu zdLvubs2Yc74=?M+WZJ(X9a+jH>p#Ye53HsA3-(Od;oHRbUK+dyy5MxszUa`YGa!4U z|7JgNlIu(@Z#F>}5?(a+%lX~PRmNDYesH=%0%vu`IvBA8wEZI=gTw_*{zWEFR;<=@ zl+_MfvKutzncVKF(6Px|A2f4xLGU`zC+)%7rvqEZ)@8wvUi)JIf0Q<{wv$y3_WTTK zJy{*?`03)#K5XPj5+7Yq9h3Ia1=T>59pw1I>t|z5oZWr2_?&0c=Zt;ZK{a@EE9?yP zagWFQ@t8BmZ{yk4dlPLvocDUlLe>Wr>eF9=&pgcci2XZ0(nM7K$A7~%@({;69&*JZ zgZ3b9f9T_K7TTbTWA&ju@J$bWJYHK@%=e&$7qO=d`+8tA#GG0Uy%P4R9QHFKK6E~8 zR9>!+I4)tU^Aqq+G^_D#ocw9hLU;`?1HqO1ZfIU)!t1&z%*YQ@b#Py%F}{Cu1Y#qK<2= z8;IX>>qhJ zal>C@lkZo<_`Kw~5ckq>&mqR0dt=ImXnoy^Ar?M|aL_No#o{yv+PxCP<7j@a^UX%J5^~{(4FTN+%H11Y|gQ^9nuR-d|ztO2r z>}b@@q(0QedXUr0gM3~&tRFDaW}jbrywsZ~@HLA*>1q0#gWq4jOu9)91Anbxz6|K6 zsvCMNcu6TWY6bp-mS}@qbS>A2D@crQ#^Cay8^YmQ!8|s%LBa)rS@$ zY&sXiyyojv#Z_}!=8tZ3&BeD3M!tElr?DXUm9}LxpR6QC9yBu%@Jsw(ZR)?Kn))kD z{oG#*f9v|4X}s$F%Z?6W`gYZe%5@H7z5C5^>K2*fn&G?V8eR0RBdtBo?bNbN?EtT~ zQa=hNVQ+m?ErC6JG2}rD_;?XyS{v$Q?3#iO;zrr)@t<<#7r1(Hy%AR*t~cPCi|b9e z=HYrXu6|s9iEBQt|Bh<`u1j$(!gU#9^xe2G(c@PkdAre$hq3zl*+Z)%g!R;303M_luHFz&?9F}Npwj>eVv8G|MU&ev%I4RAWBy$YOUT%H~CqPgb&gWHEF-)M+oy!h#8HZGny_ z^PXaR8oS9YNP zvPS7zgP5%POPq6@YUmT9zbihbR%o9&Q0+~lVjWA=fTpkZ`kG$Z;}bY=uFXI1L&Lj? z+jHq#dIGW-dtDjthx}u=X*p^qpVzqT#ouA@+px}*KMZ~w+W5}?74W+f_=V5$+vBL= zqQv!o)vStzXLG&p<{r%x7i6F(dAZBsAd znHv#%KJbLtBKTvy%pDp(5qSJ87;DW&zM(VJEXG0C7cN4sp)5Z8k&fwuE_4RY&_sS( z(KoVH6#u8={SW)=#G)shp=LOGFLjNH(0i%p#s`m$Il6A#UrRbFfnPh;Hcr>qHVgGJ z&ywUYf}S-uggvX$_Kf(bOR*<)1ILIm9yyveavn?;p9I?b@+*mzuD(V2JBES&7}qDU zc-R|@SYku#IUTFifaDVn-A?<|z7n{&5j1y$sh8`x#i+MaPsi*X^C~$v zb*9lVqbNVU{#wy7W!xuTYjn(OzouhK&MEj>e_VfQNc##g9uqI^KH6Ta$7JHASPN+x z6^I8#_muhp5AtW}dOPk?KX&v_j+@azXT-}9a{+p%k0q?8o>dmY8e@x^ZAW2iIPCev*(Vs9Dg>)reA+UU^Q zcX=M(G;4X{wjH4PR1$g9HY8SXZ+&V$=yEOav>4;Dq#xb=B7^R(&!D>`$~NPhMMt2! zmj5N)NqwNZMMt2!mNdVLPG;@X{AzswID}^a%YuG%*Pmw`x)YwM|EbWO@Xf@Z8oK-G z*XZsV${WyKQ~f0wbazPx-CdGFci$Dd>*dK_x@$TN-CYwuCzI|bJ;r&Gb7msMvn~-k z6gt#MTGaHn8}zpmIdghx&!M}f^-rO^dJ8lwaZ990(k*gXo?!I4?e?&(yPB>6OI$oA&FT4<^CxU7sAqU&F}_EB-bCs&nQLV4GIA-P{6zXKI8SrFW*cm? zsqn^FVx+)dPra4%5qT5wEMC#+pyTLxmLF~?%7!o0tSjuc)2YkAAEWmp^E^S|rHHnX zKz1rcyB26TH$Kx8?zy-XEe54s(s1 zv1M<=nR@Hom0|0@&fuDs@gsI(ZyoyS533)tZyVy6cgxVHGC%e|KzHk^R=M_pU@SOJ zg}F{9ZaEiIA7)&X=q@XPQ=H!d8W;y0E-Zs>3ws+850l*iyCz{r+}8)9hcu6249c9( zSSG5T+{iEOTilZ{-_5zvPYiuQTvJEd|aS#V`T-*b_Vz@d{ zc>f*5=V&;N<(@3ccb+|n_s82u1!Ki|==Uw4p*Zr?zwj1rMRxhz@~HL-ao{0NX$d7g}1uW|l6ibu2<=sk`jz7wYNuC(+u z>QjU?-^I8@(O?p2fN@8!G?>&o4T82+v?C3;N&~F#LPy5}?qyy9T}OB!ejU=p8!i1@ zS9nLDPmIPL%F#lbyE{G&@2SPn$C@c)cHH&e{F|QIfmi?h?_g8s`$e{m)Y=d@&O zk@GHb8NZfut}z+=agPLak#Ey30bkSsIj7Sm5;Ho%XMhWy8Q=WHuS}lV3!d3aIZrU- zbe60531ybzHx28ms%~Q+&~AM3M2h!&zly{CAW_6Ic>OzTL0{66d#*6HkLCD*{6xMo z_h(&3n?;U0CQ%;DyK|gTY%kag-p-fqyqL-At;vI>;19jm#O4FA8F5{%mwdB3R+}l&Z zy*(Z4PXi)uZ-|O+-EW55xYLzPOVtW%y-*$GDaZ z@CMg1cZmJ?PQ+bd7%zmM)dv4~huF&Wj0ZjVy@Bb~c<+Mr^r==MK9=#OkF_*yCC&$i z&)T8w8Y}q_ck-I`idW^DXCT4Xj=a%D{i7zP^~YKd_*Ppm_G?)wV(wdjKHHG|ej4qG zF~kw_Yqb9=*diuA$S?MXMMbZ$2js0_`Z}zIMS3|8V5U!HU8zHR)a4@SF$S(P;q%U= ziQ8A2;}dgEj`kAjKCsvYyJn=cnPScM4BVa}`g%vg9|yXzZ74G~J)QeK^Hp00i!5(C z;{#`W527t?UD>!BNu&wL`grL7#hCM06>-|+jrjBxB9;BKxgM5ykMj@49y#Cv^_-9I zgzf1ft$38Vmi>m?xb8NK>DmY59s`vQ{vMewqer?&MLhbA)ySXWJN{LZT8|UakoJs_ z>jb53D(9C!J|_8Ao*5BQ)Xle}RhwXUem&nt==A+cUpdd}`GD&t{&f>|IPZS5`y+(0 zWcUi=0Ji>TCVZZIZ21?W{n&Tx5Yx9Yj(6tq4nFWfZ2IlEqe2wPdbA9IPZ|9OZNI$0 z(9gT;thN8|*I9Ej&jh_VziedwG+CBYj5ma`mHd71-hVphXEC>h{(L0*bGe>LONIaD z2=l^+^I8v^q>oVRbYY7j&Fg?^`FsxJ`xT^rwO5-YN&KZZyU?;pTsrj3fGOntG}GrJ z;Z;Ev;P-j8*Ks6ZavX`XwO4p`-eEkni)~SD5Ou8o_9X0|94UR3am9L8O7TdX7X$g_ zehe4pNH1u62j-AD9|9Ue9DycWo@gMkB0Fg?*Si#@~7g!r~E@ zsKO>AY+4RzSx`M{@>Hp-?~$-h;4HxGY8T+FlW>mUyRO;=80#dA1NctN^ka^t*&ki) z0-SXcPAurS3t>@+lXq82d~U}W=}y|?XIrpOllR`QhArP?kGo7K*KqylCeEL54mmHd zWsv_puGN5kf&bn3a0Rh-UYrgy!n|Dc&V>8rk1LQu2ZQ0=k zUzg@{T{QY%&q&U-;2mq$JVWMT{4wtij76RB8{jO3w4H&E5#9%R(f{Y;9t5c$vw@>s zJu9l;Zp&rJw^hxZJ;eC}Irl_*80{aM^DLWh;@DH3{e`iyh=}KzNWpbICLb;Z z?`3y@*Q~jv-serOR_j0IyoqMO?_Y|!iR!dc^wIwO(fFR9nT2<>canZ7?>y7e+5%nW z>4ASaM9xm6bsMYUmo9$=Ym{;}2mK=$|66_rvp#xW;HtBxydB1VE_G)Z_E@4XXvLb) zn7e(#4Ih|J9~f-9YIz=7->o+Ci}4cV5cirmMDFuO>2UNVfp*lbpxOCQlYx4&zVo(x zw`1OqVlz;WL1vjz#(_O?#*QcB)cng;E6nl>eEx*dqp;QkWBhFFfr5`sjAvV|wl}u} zCfZ3m)*-U@sdnx{JGY~q*}t&b3HvKv&L2J^&zgwBT+cV%#jea{Se@YhUBXGi?}n4R>VB^kV@=#FY)9{Qul`a~~1bwwe2g5;s7GsGo2rlhjXn zf$zxqQr;^_d|`h_4ETRM_W)78pi^uu!{weIzQ^J{-Z*rMcN)a|JJ6p7*N5oE=H6{{ z9<%`Spx-%x`ULf7$Meu1v{P{ohzY9@RemTiiD_q1Q`cZFZ14f_ZZtotTQVP|MZ z5Xbp+)}yFpqCZNlZ;^N0@h(%W?|JAL?xnZ(8pNd`EpQ23ZF>*()xkF!!tmYpB+I3Z zi2LE=!H;rYO6_02{CpT}?q7?+9fa!sLG3}F53BY`v9E1|FU%#hRqyy?<-M0#So_fB zk8kdbh-TFy0?e-6`uI=idgo!=5bii9>sEHq*&H z^JoLt-p=$#4U;x4_aDnSv@5JVHf#NnLA)f8K4$+J3;aZxwpTp!&^FEsT(^^O>^S>R z>J+W5+Ngvs#~K&#th|Q?IKx>e=bs@SGE2b|{e$)7eT+Kmiupkk9}nzA`_z4mx61n% z`(Uk0oS8TLKE}juJU&oO-7Ux3V&;1C9{Vlu9`6HgAn#E|$k!I{Lr&_*`+0%Ox$irS z_pfNO(oy#tcj{-1mvF{;JA98O-!ZSnYqa@{zP2>NLA&9{!#y)dM|r|oU3*2u6(f4W z8_s#|sNP_iFyg~tKv!Q*{+DvA>Lg)Ae+`V$VK7nwqrDdxv0nqj))U58rxk8NbNDjB zD?z-5g-2QV4hxUINO;Ue!egy))SYV*{nT4*Kl-P9DgT%s1z%~P$7+in4()-PaF%?N zv1xcyb36R)k7`CH_GZ!N#=e2JHuXI2A=;jd{;Le3uGd^^XeO{21`X`c}77&+Kh3 ze<*Zq4a=Wk!g^Z5M>+SGi8Pe4M#>fDE+N-a?vQ_kl_qUF^aR?R7idxI!#hL;(?ND@ zcyhl#%getoyJ_g_5cccHfF9Lz)FP@3@-LWSPa_LucIsK%Fh@B4_qK{EDd``oD zJLqt%2_C_@0MPI=i-s-Deyka;z@7u=&nW*P_XElMd>z`4W=p>W=BIt=*X@r+*oyow zPMp^yuA~0;#l!a+^#XKM^z#ar5wWyKSXNpK_Go?SNMV2D&^D`eTpiG*kHE(2;22Un zfwgu#3zvHi4&(a>+vd==NV;GzNFwSK)2++2rybhXC;iZcC>!>!mWcY{Tma~xhs8OT z??-<0JMrL64exOXKR6V(0S;ZmfJ zm3I<>SA0o-Y?^mR`;|)1Z+c+fojX!8x5Hoa(wj~5+WJnEX_3Zw>2FQ60nBtu{nz-_ zzV8;1z41Mf4ZJ%Lmax$-3hA3M`O}8Wv2s2Lx>;H zsDU;H+f=mLF&g_OcS3K1dbCC{@1ZzZA);Nz$R79SIT7vp8% zH3q+EjPp#M-sH9HLp4trQ8h1HTsN=u#fe-?gS*Nzz%vQtZ%aqz1^T=vc?Rd#GmLcr zf7^W6lSBMCwELHuIE&?;Mc|G;l30wFqOoS#c!n;4e87&qfbZ}B0m}QSL)-X?Y(pFTKid5* zfccvF?I8Zx4)9|<+7%Cc=^Ih?n7*V*<~{n0&oihGD%p`g!b6 z-k2nD*df=tZzZ0o!_BlVz@~ktL&g(ZzwaN>+U)0=_^oOFD8cze;7IBDhXa1_xw2b3 zaQ`!906MH_b-@jo*V-;+0N>>IZaI)~hm?J`X`AASjme}1+Rk;T`4%skY2@9d;4``2 z4s~ZA5Jx(8%f_Y&%->U9HsO5QsQpS_a$-fqfWy%BL3V@3~yclgF#b-pA^!p+94@-U;@5dT?wprSt9eBq*6>Lvv{{>!4fF6&;S~9M^ zc^q|*mGnoS#ryss(>9F54Ad_b_1j>{aC#PGrxf;G8Sa$jxB_y_eh>9*u>3Iezt9ik z&^El*v#;0c=Bg6H3s{PD0xy~H-g z_*#$CcEB2=lhTH0eNN6Lq&l>FXR}^PM#Y&lzuI>N9w}oVs%Uus?lD-`iaH!+Jb2In zegd!Gmo(m=;1G& z+&xIyOJv>IM${qx!us6zJZM;_Y>LTP`x)J14&%A)YHyOHU%RAVkk1_24~NhPfIen* zQ91nSt3j`d;nb^*-SiSt-`P8G{c-RLO|*$WQ_k1_3Hk(mhSaMz zv_r}xb&TqNJ{yEK$}q&mu#IMTI{8q_qOhL$CYuubtgrdD{vBW@G{EN zv7=+XbuKN-!*@Ey&MYqu<;i_<=-(RAZt%*6rK-={;6h&5Gy61W8FXeG1O6cfq|;uei-L$3=R4THW9}mxTKDX#yDD@9qZ8UPGVZ}C3(49 zuVVfQV;k}y<3L*{#`HY@KO7c)8z!uE$HL;{QC2MX7KEhXo%QCK<`X{_5mCE(@RuF3 zL;iwZ<2qEdGm*L+^wPQh#dvm9a4yoJ-7}K11Kz8Ezat8KMP7;n55?n|u(3o$Z}f?n zmI?SCf-`mYi8%0G{08_V?wceM!s@D{u5q+&KN!hL}VdFB-IpKTehctO@XLBs;5pHZ%fEBLw`dldF{GsYOiAJ^SfzS-pK_d=6z1lHlKv-XYM^^BxF$6#Xo@i06_h03XlL!YF4 z4nf}nWtZ})WJv2ny}`6d*VA_epO#_Hw~{vDvepxh*vGO>IP`HypG9~c5uu$6rCkSP zG03ZsMJbb*L$~BHjKAW!{+{dOfTsjy2j2Np+UFVj*>7uY9E;+)sl^9-U?|peVO|S9 z&DAZFL{!UA>|weAce7?XMw70^SK&DXXA|8DT(9LCP>~PYA;z~(-mjEZGyrLFpDpHR z;=J=;Q1=)O#{F_%9gH*Hcs|a$YuI;Z0nZ_#y`Jj3Yd+UZbN`>LQ@760IL6ieZI+y` z;r_pmsTWxHysmRC<{4W@!)c!v==&Y1Ke__9Y*;RKDP8i_VDbt19XjQF%X0A9Z^UCf zo1x`<=$BM|vQ0nacz;5-f0Ado`tF|3_9n{q@+`$|SXcD7-^%rd7#AMm`gznZI%7Zd z2Ixw@-|$`Wm@51H517`W-Blb$AC9pSNgv)%7}C~03k3V_9{nMF($rNJ z?O85(a(pZ9_Q*URI0xM`Vh!lXHIX=L1^xA1YMf7d?-AO2ffLNbdgCee4f)m~(hr8n zNsu>XKcNNO;K$%xPKTvCxpw328_AFIe6>(L!hRyG-LYu5+=JrKRu86)MW0Dt*O$Lg zG}RU$JXh&itpN3IRC{x@Y+w4xIA8pGar1UR+g!MLPpog#%({6u;{6J|Up})AdRwGL z2@UIh*ave=v3|&KjI+@9``^UxE7(3er^gk2^lWp%ANRx>f0$X<3K?nLDWY2Y;GD-K z$iM{LEt&9q9M9tboq0wb?l=RV;+`3{gLUoZQ}G03%)v7sWuMdRPqTE8lDF1$)`5GV zQw8>btqL^24wQ4TvYvYd&#PcPi-ue;&Oi>a)^2*7<%ja!-Of6sO1`^i7x``k))qy# zj6^-nySsh&2jxlkZItp9pY}npyvJEz(il%o@!{$}^`Hmt&)_*m^oKx)b8i;Uha0cz zziI_|F^l7Nhxp#w5FHt}2IrXg)?tqd^1u#18QLF_ufU6mY%BT=>d9!|YFJTi=m*em zK;L1$@!Ghad1N0(U%Ir@dd5k3U*`+%0n1tog*wDw?mQZ2_{7MyP*@j5J`QOIVSZ+n zCA4##w~}_Ul(p?>qiK8c{(w+<18l!TYkA&0o2G#>#=a2vr~-e)!9LG7$B^@Z(=2?0 zmsjVSc6>JUt;0+c1^tssn+V@I$kPWfcrF*S{Te(P08>Z&lipq~Qht5ryX}@Ep&H3iEU8l^n z`4>s6#uu>HIc_Ab%=wY=xX;p;xmPUZ{vPQ2=*;87N4+QOulZl}o%=G5JhOGESgLg9 zB{*+E&Xwz=jYHg&N}92a!Lh|pMm5pyVLKcm^)_ei{BGF#dy_YokxDSQ)8q?(WOe1B0Jn0Ax594P6evS&~=dd&v@VwB@a_?R{+bVf` zSoawVrtYrbdOWK?>7gSYh3;(jXDgl1?8G=<581zqadyQqllOJ0Bio@*n*GvtQ}cxp z@NGpbfE?sAFMR@;evZ$p41!i14!g($j{ry`JUc~Ucfa?b=L+-zaj|8$& zhq(EOi-8=Dg-?@qIm=i8x?$|*lV{yzbpV%%1DmkcF6u`(n*njSSI#%MWf*KOj5mA_ z$}c#PGg+ue+ zLOLLPiKFzlSR=m$I%eLV?!H01G>X)d>_cgLyGhUX*gUL`8jWC(Guc`8$>TZP_N2 zXYk8>;GmKIaE`UOcgCSLZ}UBPoc(SZ+8X0~=p_4HoG*S5=kvlYxI>rwN_}mIIS$hh zM;js5x9uoxS?R~2{igJm%^lX)1m_y9e&)HB3-o0c^kpLSWn759ly)N92cIMSCU;;> zEO@f*OUXN16S%%7`hA9>Y*T02#JA9G=r5wzF(2y-I((gOiwn_PJ^EWyXU1;WfxCVH zYr_k$14DFQdY1Bg0^jV9v!K7SL-m)?K92)Fg8m2YEw=hy&UHe^r)HLhuDghe0*iy^ zp)cDa&*XJ|de)CIC;MCQUr{UUbIK#=l8{y^$MWz4-BE4&GgCJro<2<65&S?8nSE5y zf8drjGwv2qGP|M?3_}k^VLj6Tth3P3 z4-~P@j6)uy8&6F$#MWtDaSY5GXH2Oj{Yi#D(|*9#sREp1+{=}EI+ zA^$jm2S3M~-FWzFhSFs#mWHI8fOMJDw? zDc%_pmi86k(A33E+p)H31Jht_jMQbML0;Ea(w;(F-{V?g==~82e$y*Rzm@yuP=`%& z?;LPw=9ysDVK>sWBfc#R<`5Ic1n}@K6UJi_25>`KC^%n!Zo-+tdYkDU?^)KDugt5& zoW@-{Qc%tloM)cre{mwpecJdy%`Z#6{8A+LVf~GBCF=gEt}h>;j#d8oQ87XJaoy906IfU9E`2v>`zPtG*ZAe# zv#Nhvwg%rZXv>em*A6^?itlK=kH`B?yhq{P1{}sRU&z>2uB~!t%W^ROrVq)SD{FB2 z-$gxX4@JEo>q^`hFU_q}cZhw6HlaR^vOc4IC3EZM-HNlW0w2cB+lPDHpXC$xb(}v_ zFf@Su#Am;ZYsYyXp?l;Jw9}Hd%rxDuliFr3iD$iWQJ|nMr#ysSl=U#p>628() z(XJTM4gRvx#2M*DUw}m~>NrKO>l%di3Fmu*Iso+2z8$^(%RCEAdjdF!<(gseJ?AFL z^C2>cd!#WhrTDMzZL9&3_Y^5wp1MWiq(gIe)AB!unL1;BUf|R)(30aH**^AlY;RuR zKR-8RH5D|wM#|xp*jL(_*EDy36z{K#g&fki89TQ#ig)2UKxaWZr(6x+8FUM9aze@# z>Wyc#FAMd5P}*V#08?B@Z^;L{K;HtX!?mTK@+oDg?OJ&*57+Jc9Hh%+sKCtGp^HqJ!eN|C;fd9#w_IE{ur3ZMwuXVRC=8BU{ znT_$`>SM@k!q@XaBIk*vFD89>gn;eIH3;x+Xxek=e>m5Ldd57~KhR}FUez>N1kSJz zafrkPLi>pGo}s)WB=4ZVkhU;nFY|a%)?p4Xmk z{zB`t%4z<*s}42>{n|0G>-NGH^y942^@?9>l40BJb@zuJS|{~TBJ5p1+9bzJuwilD zvdG?XUaTMW2+mrA-;;eF@MQ~2N4=b|eS%m|yVsC=)&gBfN54{Z<~D6F`U{aFq^xfB zCt#hWj$bLp=NKn}=i+vF#l1Twhz%IKQy;}}PcdM|lBdwlCjqO-dz045Z=UZ)J~G<( zTxslorqlQ-&oDUgB+jj&PIGYlZ|67>>uq2gr1Sh0e9Ln_BtOe@6#n@(@4SaC%=22J zd=H)>FIAzwN}n8;`XmOtAlHB?eR8d?#xsE^wu^lQ=!-t#Fb(skh{9Pdb+--z=ui$}#~c<-2xGYoEx123L7$4^q{pv=&< z&<7R&RF4F1_EP7u?!d$QO6RC~mQ1uGFYw+k%yHJHp8WIIADH&6k$H!f#{BZGs{Utc zh<}_NAJzI(&>iy=(7SylUACEYL4O6l9E`F@kWbAs^`##j;gW}uUgx?O=(*jP*Ls?I z8#=q4g(Tl8g%h@OItNLqI?QeAJ3-U%f_%yHUr1Dv< z(j4tWxF(?hXNlA9C@ReAF#A`DGu%f`+oD60<12-;<10+r;u+E*w&r`cnEmW$J2G(2 zBxur#vj^s-Kido)90lErvt7jA_Giud5T_@n7IY z+`A~>okyuR68+S%1LQb1Ug}uzb=q@*fRf?GE~J%fdZ}YEAISS!Bpr-nV>`Wr?O0#) z-eyxa#$&G#*I?+N$@@H)1K&1&gEm-K{146d2z@4jY?DTuSEjsMw34#m5JThPSM85I zIXJ_V`)aX2nrA^_&eVJkYk=@he|v0I zsaRu#%;VC3E425yKB7HT=Jq`gAA%)wrBW|fbo0tb&nOv){LG{$bnlWENq2ikaHJ`=gP2fro6=Eh=NL)?uLENH?GxFt5F~zt&;O>1aIt&^46T zs7%x$B)>r&?9g1;-xyhkdG}bz_dzrN?~w2BSsk*EQ2DTCA|!7X^vpr#!MvA%3>{{D zC7t(c9VWj|MtPXCJ9mp}%W<`~tRqscmCG!p9(bE~pP9bE#k{XK&Vo_o!#F_N9`CF$ z>ZwN~Ud|Y=bv5tB+IcDKU6)DwM7@voMxK40>EQ!`9sTZQz)hO*=Go5X?2W2k;CqA* zQF<=ISldQ_*!#a&`xfNEv@6ih-va#`>uX!fHnmAx4|6Sffp>N`KZ|lP$Axj@13df0 ze1E37_3Z2D@0!-GB)s#=U)iBm`Qp!Zs&>Eie7cUc9mCMK*CO8)=r7`a7uSMsu602F zRKYm=HpoA4$g>&px=w8~=Q;JY-_^Q63*Lnkhj;5Pr0C2aX&o8+QTKrj7`t!;px z+k7A9eS!57YuCcBg18CfBlKTQC^rW8uV_a9vz^BN2YLQxqHziQ%l>xyFkv6<&%%6M zfzh`fVSa{Xdk=b=ynnl+sV6Sqe#NLET{PR;hgimmvbArb-@rMiq+wp*<3U!tQC=kc zJFz@J0eCIS_(JPaG(0z>xg2wA#2>Z&5{6u-SMWe9C;!+Oqm=nK)j@R`qe1Ag~KoBhAV*?1WHDq6p@!dxRN*M4T~ z#<*0i|MatN$RAC|^#d(da)g zZqqtw)56~rjd3#ffdHO3d=Ji{d9V?cF0`w$)Iq)eY`Z z1;2&aR_|MP;p}M{ukESUarUo&bhIe#ylfc+Dk{hX5ZY< zv+qB4yVVc3191;YBOe(@cyr3>=6#oKa@<*Q7! zKFRcb8Nb2Y3(m%5AL*T6*re7tS8V6n8Pe6ERct0bn-4zKWL!PC)7WwFO5=q?Qh&&M z2)o|BMcH3b+3T*t`6?Nr&sv;M5x(~yacBq53dq1&**MP!K6}1vNE>0DfzC5ecs78U zE|TY=^GrydWl}AQ=J0IDF@Af2byh&u!;vpn>pJ$VPtC#m{`3s2^=gNYV$BoKp^;Bu zzUDUERlW=1a_s`|>f$=+l?xKa#8+N*-+$J~JZ={K0? zyjypRuM}7N?mjBQ?-mD-;!f{_(*EPPPS!2xXNx#O+r*)jCBt`r5cnMpd?ur;3-4FI z3VW;+?$!P3*Gt@wMA{odac`y>Rdh0IV!=t!=(@hj74} z9}X+TF4OV>%K(2AaIZd|MLzQ2KJ9hbMWN-(c_ZZ~(c+QEVUCyNJs=LPq!|0Zw0&4#(r!4 zXw;syk(T`z^*G*5`!A|J9dt@EQ% zvA#_7$5#Os%0e905|(Oa8PUd7!#a)fW1Yrhpz8rVasHvPWH~BH$teeKhzusE<~C-wz+h6nVB4(kq=bNl2Zv3j3eD>=P!5k;rqQUYaCE z^>%Iy&d1+s^#`!&+W;chJhP20f(er50C4v@rknIdWJ)i{F&eO#z+MVv0n&J@=N%gz+T zkoMZ*WoFsSy30oT(PsMLvzOsqWcHbmVZcvDo|NKwW}bOH@+h2UiZQe2nR$rQOyKlt z;M6el7~OfyGDgid%r@SRHr|dl-cB8{;8WwbxVz`+H9wQ*cVe7m?8f&~xC;#JM!Xy^ zKo06K#@Xsy$9@;8?IUp?ApIPr@b-el|; zCD*_iesP$#sZo(=v%-4K?~k$>**3#J-{u_vT)O7liUzL6+1|M0_h+|l zDIUIhqVN4%I=M&3+h<@B5Z1*wuLF5- zeiY$(oq)ymtO2Y%6IN~>)>+_AK-e5SGc6tG(&8Q+@;>g%k>Sw@>nhrhaz$hl`Vukb zE{q8VOldL(Mm9l)V&uIr)3puO8k|<(sug%@1)f@gC#-MOY2VX6VIM~r_I-i9#vg%? zfuQq)+5z|xfT#E@gg=Hf8q>gUv=#GKl&_fdQjAjv4&P$n+)i_>a?tB9D6sH_^qS!Y z&L*v%=$(RgIzhh|(9Y?lCeFTUV)^7LiL)I+oW&@+DI(Q7)x_0e;Hn%ju=c@dy*RGY zUbqlf2zm;DsHiQx)p8V^}BWyXWEL7~>_hYmJTVO5}WbdL-*) zBmLsc@EC-3G0u3=R#035UZ_O-S{07GQ_$bOY%3^w8T4HbSa+97Sl;#ED~Y301xtm; zAgqgV#W+RBdv|F8?wDpf*XrPB<0bI(-H^AvQ8w>X$j(mi^B=&^@8X={y@gwhQpBxB z8ZoM=s1N8gWOk?TaqNZlp6&ETA1{zFqesCm$WnEP9v7F6eU-jDO?y{`#~`fBi#Ts& zRsqij^zAC#;=LWP;Meh;2dwE?Ce7g&c*K&EadBy0!ZPJVg~uQaaspVCt+l{s75Ms~ zex>hj*!63Nb*4pgO&Db1ZX3rl30^Tp$^d*s=Oiv5W1#Cn@5uQ!-#R@jYj5DV;@xv^ z1@(!kLwFXyrB^n>#-RS9UJ27FyyqVCIT2CbNa&Po=n^+{$s|*^EW$hPE{2T`|0~<3 zrSj}M&Rs!9SV!GEDz6DVr+e4sgASUS3(z=l2mcAcb8mOSeW`jTf^OPylM3~ScsIZtO=p zh@)uLzM{W@PqTA7jn(!};}3}YgQPz|VESPhWed zH`mm+(}16~5sY3rUpZixA|VR?|b7m6fJjaJZ; zb^fr(Cgt!0&>S*I`SYDH>+g#%C@Sw!f2j-2`a|DKT13l!gKc;T@b1prVpOR7-YI4q z0N1y=7ambziboFE*oOVGj^(I}j(WA>hd$W57Ik*5#`zH7&Aq@8`t_pHsEI`np{@a> zU60?8+)l2wGtO%vy5Y?x-(8k&xGFB~ZOAipg4A^?JO*LV4Ohi^`$0FfQ8xho1i<u`Q( z^x01E+6cUpU$cyprLkUrZme;9fz5k&fz7*ifz9Y&2!1?aue!MoHK&`ra1@WW!* zOOSh>A?LjTHpM-{RP8iMfJ8HU|(LtOeK)CqQklqDs{F$ja*fH4VVxp+EY|0iGv01JB`y@d69=tK4yuupvJ zE#A2yF6|M*GW%H-9)mFO&JA%=_VNn~jJu$df1f4$S#LjkC;2U;pFKzZl)UjZd||xg zunlto9~BF1q^EIW3UoQ-uH0esmcvdO=&+IRi+qSf8ODd;`RhR!zg|$Z+JBAjICvhi zENv&!c3P0O*o!8^V-VIwx*PpL%krp+259U%0azBFV2mSa487*Ni!up2tlZ+0c!f_D z9s}O#VjOLFV^Mqo4JmO9CHnyeDvaFj#!hmr64%FKj3n2PU>q2Su~Kk-QEL|_nTH0>$+h;- zS(yRAfp3cE`>i&^F|Tmik9-(EM6(QxA!4{kiuJe3AY7(lIMbMMavcle67#wq9EA8p zjyF&0`(D%9tI_O zMh*~_^-d>0WOCipP~TYIAeNWa*B~%MZ>(W_h2BucjLWf}U+;{1H;y{4?%sZT(nU~G2I+?lf`T+7C|-A&g9!;5lfBP0frJQ;Ya z7%6Lr7_Oq@S=2HSvkc|gz# zXT5Bxtn`?CT+9)CV=K(WNJ9QwR%7xUuxx=Vo}8(%5lns-0lkijX#%*hdwD%|_Kw!sxInF0ZO}I~mqX++^n>P)~|M37g_9 zDRa9=j1)Pb@P(nhrY@;*F7G{u8Pj{NdS`X*va*G4C-Mg0dn>mj7>kr-uu6}~g5Y#W zieA=$h7Ay&s%lZ;s&|$*)Yh+%A+iA(dUazM3kb1J=!W9h=l!ZVnzsQOsMndYrEYz2H)|R6@y-Wu;01`M!C$NwR6Y6M4_`nP>8zAVrv>!)H#!b$)EzXO;lc0Rs(r~rZG`h21F>lW#}Fh zH-Xq0t;!&tk{fE1C-xSDYE_pla+T|zg|b4(v_!qRQRT*(WRTFch}{iQa$Az;_5tFS zoWc-xT7(8-1F+U3b+1!Yx0Znku^S&zjiK=NHO8IRq=Xta6}P)7~l zgJtXLosa=i)hsCtd?Vq^$DTrvNCt0bAVXstgi)@z?AGDrwYKRNhooo~l}C2xg?Bm-Yy^!u*_Xn zQx0@3ZLFnYC~HvZq!A-vn+TdMRZgi`w3U23%FoELiUo4 zt&wJXEd&@E$%QCNsy@POjteGvlDiRhHq^0%+7KEvpuhZt3_*I`Wgd(sXn8UVI6+xU zUsvPWI;W}7*{_+pr4pn=&&6ug)Hdj{THqyxOe#6q*Fbkt&4Jr2(-Q_n2+Ii}0$m@M z;#Y-V9e(Ta+cbPsa!SU8tP-&RV}fx_VvL@cG--6mSPC{trE8Jo{S4jG4J%wra=NT$(= zArqlnLGH4JPWKon2Tx;N9eN9jd+idZ(vHriI@OCwh|~>AEvr6KS3&_pO^uO4ty8l? zu#;4E*qzoaa)wqEHROK-Lc@?+GQLi-TTPHHvB-`3ndWp7MzH)pY|sbWn#OOBQDTw@ zpVi4=Yx%dlpKZ(EFDV=SK>yj#_NzWHxNh-hKRi{w^QMO@Ht)FP&9&oJytU`CV4C%NB-=Z4%ja@N?z2FX|E1ibAIQ5-AiuTz3a=#zuM}4^S6gOAK!a6Yur)y-*Vnv z(D+v8pg;fol?k_8cg*(q>~}=Q!PjT|pF3Q3<*=te+dcQG1H=FP?B)md?Av+ih=@H8 zm-Ja1{Zh=aUp+bSRN|Og@E8S?aifqx4x?H{l{yuH!OW} z&APt7-aYh@=T7WAx#!4@P5ll%dZ{>@x~2cFd*8ccYrJpqpx;JUPe{J6!u_NFEMK54 zSu*>x1Tf7Sr|sxJ7mAtgzMDU}THATYs_4(2|NPPe^PEo{d+GAuoGQ4dW6y`@o>^-w ze0#{d-+3cBcl}?C|N81kzH`Q}%I0V6p8X#?_KJohzqS2!`nx;r6OL|v{jpaLRR5*( zv#+MOPAyKYId<+Bi`Gtkqjb;V?5JeVjgdp%|Ji{2lD7vLhYI>E9e;g<{bwBmV`C4+ z=y%Sm+MT4=u6gR2$|L>%qwK^Z-+$-qB_od=+WN%dt=Ink^<7Wj^3;UyraV2U>NVOwt6Y75*Y(B1dAIwW zi~cy+ee=?qC4E2WI&$^0b$=OkJob&1w=Q~n`pajZdAIi7j(?o}?r%D#ls<9qYn`1t zPHul?V{_Wk-yN9s?my?e^4mq9{&?@aMU!^-ecSP?oAZti8uiBi8gO;~&5_gpWsh1} z`flkzUf8wh-Quw|_x@w5t7F9<%br@lx3cxBq}o^8=T!am=9goZZ~pDTX_41PT=`6K zpX8t*_XJywg9=U0he$H}emdX#*Gh(D`uS%)(!~%9aHFa;5vvIqd`f+VuLMSN}dUsATCZ~pR?#nX><-uhP7y8|n~cQo_#Pxt<^@SWd2{Nl7<{n=;R z9XPdb-#-)n@a*sIE_`aEE%E6cKYsS`&3*p#df$yj@5~!H{Me%Bo~m4#a-eMbp4+Rg zj<}(A)TXBgc6{%Jn0vS1+UMP?lOz7|gOWM<*(DRiWP72bBxmN_3BoZ8{xFd{wQz#S zn=`qDeZT~PGy)#O0(+5Tf|voFJweROFI1m}j+}ga7dnujL&6rkHkb}`R)ZJqIBi{rRexuX$UxllC>Z@M50j1Nz^c`G4$Q~BRkfg?p zq()R@3`~#u27#eu1^+?NSlc*`@^2SChrErRvPHd(c}3ym8TM(pQ>e17G(X3x`tX&+fe1KM~5PNX_3qUD=R>2j>9HCVT;%4w-pw{!CI)R;S&a= zfX6|3ZKG-Y-^?yQ;M6qvy!bL{g(aWP!dd#;K73W)FjczOKlNTaRZJqmmjA&?Vs;$A$4van1kvrLDvyFx6 zR#W9#C|?Wb*$a}v;!{u@Ugg_3;aP6M@hmT^6J-@;b!c7*>0MIotX>F8%RdcEaI}hw z${sPfH4RR;J_l*_+`<|9l*&bVp=(i!E|PBcz$3N1N8;%-#NujKd3|k7kKn}lx!F01 z!tHUPyhUX_;%3gx&Ca!pnq{sESI-z(r%CuXfO_#G7SA8@r2ykR7seAs&ho07T6gWD z6{Gdsn(`Ew&@!T=5|%iIyX8xI6y0p=>kRM%ECLfYunHeXXJoOL2)NiBaV zi&hF}Q^Pp^lS5@tm3Ve3;`?N;r%b zh5um28^z*<6=G4PXPnTk99+jYQCnW=87pcU_!Ki{70)aZwLlc)&r>aC&6$!9pGuxg zHBQW$GPQ6n9x@*9V)`6$W6I6=-2@981gK9HbDX)J96Z%GV5)$r*2}oy+l_bwd5|O- zkFk}WWRYYWd$Zd;AJswV%%Z7<98{9PA%9Q(_0sfz-hWx=j~){?=ai2hcZ?E_`C@Xm zsH*hTxf?O$$euH6hH$tRRe>>KsF#VPFm#5&>RnFyo#0i2%L*Pgyf3CpslOU%V^}A32A$JP4R-;C3g8;HS{IH2v;9-;MPqNq zAfxEUar}2I>NiWDX`hiJlT~{vYJuE2Wp?~iVHfrFcC^?wZa#m>){9tHS=JzC6wb?? zsUWe08HL%iIC=qieoENp3qkARBXLR;|IF+IO7e^I3I+dp7FX5QHQe~Uo-BX*%BEYz zdH#dQ)SG%nE^7isKR>7K6xFU8SCjBvA%1v;s7e$~iQ?87A>@t5dluz;aFI4xXoHKy z;JKHJ{snQOY}n>L!v}9_1fbmb`_4-IpeTNx+3*C=W{9#L2@`KImy`{VUe{4R$^UnZI``fkGdZnzSQM~Q_E^?*_`*)gZGu*9k) z#|pIfX|vPrrtM7omo_ZzP}-8T2WivME~9Nl`-nD!l{!*jmu3vmYT}SR#lPP@h__r{18c1P|#J4P<>?nocUmIay1yx^!#H~TqnDW z&6xi6bBBf2Rju&2fUOc~Z>jVF^A9~7?3iS8 zVt8tBN{k*cy$()z>Ee?!UjnoBZl_3IERw55cS>iIv%FDy>q3%tN5j8IUvWqrt!G{S zgV}rO=7)8M|1p&(#x#2B$8f^RJ;np`7M=zu@Wwh7-XjFc!)gQOk42#b1vR6dfM>p{ zDHs(j-}MoBlQCn4>2tU{!isY*gD%RT!y| zT`*)a4fG4S68=Lu$3bgbSL~vkT41VV_^iumPOyU_Q1Uh0X5I63H20-bNMauo|8>f_ z2!q_};5fAvlE17XbS@eh)SyA8vSyl)0boc^Oe}U6jS8U&sIaGTp{z67XL{505vU&6 zP^CAmc(cZANV4+2Ss5`=2bWeQCcJ`HJluXg(uWpPfvLxk5-{ymuI7Pq3&jK=)mlg3 zs=Qzx3bVH;3BD{iyb6j`846>=!Bkc)JoM0VZfAs?$07?_vw}q3c&_&dhXhtyfe}{7 z1TkPJFRwXC%=XB#y8U(NPh99nD7%0MtG%f~Na>Ol%${NSIhhr(XnS~^W%cD%9Cx7! zO3KGbp{Cne87;wrq}`*MVqvpev4+sy0|znKQ?iR{D4Y2;Bgg{#oT88cWI>U%U@xxs zy0v9k&WmSJypJ(qSPp)|flxH(mXbpFtuZ+j5<-hB^qWJ1&~I5yEH`Kh4V;>9pH?W; zB81TJnZ+|E=gbKWF~{Gq5JN*{?-5c7X^oe`MmhAmBhSkz@`auXQR8gjgQ}9xdG$&Oa>=!kAi{` zYE6*E??I^>ZO)k@Th827@FlpKuv*I54a5rRF5(*@4Jv*A51|0M{oS5gcUe6aNHnG0 zOqVuIeXw|U9nARd%vOeP-;BS%GpJMq5lh>x5#wlxb0g*qxL!lqcTh+Qjc^Clh(bip zEt)k&_mn|AS4>E1w5rF~8kPq$8DxXpIE8mXwSqzd^79R}wPl=BLmwo`XYtZATy z814XM1v+)Cs0m3B%r~tdG+&Tm-FGzLQ`|%P-!N<8JIkA#)|yO zc1}-WinzQ=EotE-tX@~^k&00zyJM=W-qSETAN~Muv4`Cbv%xzBb*IKcA*Pkf0AwYICXDVNOPC$PRD4BPC?}klqepOel^4}D1Y=g*25g6P4_(<@!at;nE zv1?byX#7mXFCItuoWM5X0x|g#J?|0i;fQUKZBY@^2V5fFedq1B?AXO6m_G|;#2{T7 z)8$*~9_ka3XQq5pCKarY8}&fBQL#)rO{HC_lGz7FOdjy|JMUg1Lf?>w^?NK3IC2`# zeEj$~p8tf_dCS;FbYD>c2JmfqoD6eW*`c)V9cn zBOZ~h!`VN`o(-5M@tiO0|6%{L{jmKN`>Xc9*pJv>vv=BGw;#11v%g_~)BcwIZTmZu z-?jI(+Xt!KwB=a7_2m2iz~5rPWPxUtMMf`WMD!9C6&4o$9Tu(VFGPE2ILFwbe;fnj z@6vy%r}(CCa3lZ1(+>^Hf6;F2SOHuHza`@-^H^xMoI9v=wHf6;FU{+%WqYdycE z{8|ETMiFOv&tyHmzKzWH$bgUD@-U1=Qy2F3_y6TQru_7%_P1(JSfhyRtR7H$e#qqi zCwY2;5tcsH!@{jkSw!Fc)~9^-#lNAf!SB$j@H%6B zrPDWkhl6JNaJb_?yGxzwNixHZywk|i_p!0@NX-f_3RCX z6=ywr!zc5Fx7kY1XK#5J#ypnZ{XhMN?ceKPZ)Juj>@5x3(i{G*ycf%3#q$}C$8Y)$ z&CB)Agav2vaut&=7kKW?H zsg1qmF=-iL@rgy-&~Nf#*mp2}ca7AWETgxALK5~?&u_?bQJRNTjVgm@f21<+;)y8fF!un}HYk?xCNMH256~i|@VFi(#bS#q?uud8~$z*Teq^ ztGB<4!S5~Y|IK0H__FXp-^{o9vuONn(pqWEJi($Z7+Gcl>)UT-==FJ}->NI4ndcJh z_P55Ky=DmuwCVxh)3^RJE3KXT);YdG_$~q`h@6YW_ZDo`?P7Mue^;K~;0V!^9=)eg zp%#66O|#Ps{i*rIw}+4+0$93-@kgLu-`I)Wd3Tvxn|C&o4X67a;_&!B~P z($432JyJwQ7vKpSvLDAw^pnz0i<@|6KcU`-Ge6=|KgN?j!I)Z{!z0AC2k<f;CWhzVJUc?MG-F|?7!{re|YZnzpbAC9e~(Y>+in<-q*p<#pNrlc)T}- zysrp(zr%X}-+9jTi(w+NkK4*)$IGRQY8vH;zF(9kQm~S`p`HgNrC^7Cl}M>rQR7)r zt)30_A_a+4%%wIxK1wQjej;hT(_O~==3AY+L8Nf?m`IV!)Kajd!iBh6Zp;=b&Z?41 z?4EI!R8=6a^(9hxii-#3tHJVpM)T9;vS zh-)F%j(V)tf2$|ulm2Or?I_3i^>vuvcu4uCj9-Qy(^7sR-~7c;Zt3%2UZ#n~Z!msl z81(^vQV$?l{z1RUzhRaPQ-0M?+kzOv;vb*4vXYKaqv+(E8z1uFqf|rbFHMOFp5#87<+(;5pZPM>^^!{-oZ*xAg512Gf<|$2OrZ z)QeI#CgR)rV>Doim2GT`Df+%6~4`M=hg}hKM{SxN@T|IlYJQZ z2mKQCMTFEDr{y>P!5`rP2jY4B6uij33q%BdLOY5u>(46p_XuFRe(2{?MFf7`a}i9- zbo{-HAK|h;%tpFwyvN{Y{aNsCLjcneUV%#24{Z+qS?OLyhzak~b`zd0n5r9puR}gQ d4~DC9V}swS?)+43wIU*-i}3n^^=Zb7{|Av?%ccMT diff --git a/builds/powerpc/installer/legacy/builds/ppc/libcom_err.so.2 b/builds/powerpc/installer/legacy/builds/ppc/libcom_err.so.2 deleted file mode 100644 index 00ae647dfec36121ffd241f70a533f8b5df54095..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9896 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 T{xfY*y;RTs{6(>8+DQKek`_-P diff --git a/builds/powerpc/installer/legacy/builds/ppc/libdl.so.0 b/builds/powerpc/installer/legacy/builds/ppc/libdl.so.0 deleted file mode 100644 index 1533f23c03dd17dc151da732fd6ff5effc0b737d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13348 zcmeHOeQ;CPl|N6GLAFJr1OX;C@uQH|1R|T(p_1(eDRDaTN2!yT;06*QEP)k-q?P1E z5XtY!q75!dYXeCjF<|n+CYJ6zv$?>+b2^L_8rdnmVe{7|w;R4gUr1dM_5b7&igmM$Su8Is9H zwKS8i#rQORj_0}ZdO@QUfEBfbXg(UV3Ytup=eP=Fv__f#EO1e&)R@71ot-43k~BnQ zc@^{1jd=^^y_nZ4(KzO~GGEqE`jbx3!+vI+yg%me0NythbN!u@_owqf=F0Lh?>C^< zq1K`T=-vPk7XjZE&atY)b&fZ67N(O!f0Is=}8_9_GB2KuLJ z)GF?vT&*|7zYYUpU0#oRV{v8@ApDR81HaOXhF`WoaolJ6qUegWbYQ#F80gUFEnQ%t z0eF4`|Gx}$VGNA3jz!Ve(`vKNf}tGJ8zQ|gJz@5Be93)9|K2P5g~@&T?c~0t=nw21 z@bUZMHd*j>NavT{yaK-k@@>P|T4SDdEQ-#b8IEmnfa4NDT zEatHw78ejR#k;4X@pL4%J|2ihQt9H1!AD;z91>&6zF1&=Bo+w-lgZ#_F|q z>-shXf}xPk!lqy}8t)0L?~C;m#bw+}BOAi$aO?p=g!v7mdV@(Y9gVC@29r8*oru0q zB-57=5cW?849>v57)vDM>2OavkPJtYx?o@=kd7DS5?FnSP%s^yJjNmkin>U!Q%^J; zjA5@(G@b~OrS3Yxi(U9)Ibj;`cl1tPMKLZ8+rl95Nrm$@7J6G%=reeTmhKR9fq$1 z%z2pM?*Wz#_%^_NcJcTcz_kYa0N^DC{Bywd2D}$A=Lg0=4488(!|wxbHsC)Z9*uo# zwgT4oWgew^S>Q+@C)MlwN=wH88~fJm0&MJCGYZ()x8^m##=bT00yg%oISbg>x8^)} zup>X~`A4ev;^<^u@LtHtWhU$=sxaXW9N#9~iR0XayC9YccO(Cq@ERPYCcGAT-h@Lq z6HK@l*9a4i;_6|-30xCQIF0Lx31@KqFySoGcT8Bt)y0Ij;(B4i+i*F`(3RbUL2rf$SL2Fc!V8J6HsK{WVNJLJR|gYr#&yVq zTX5Ae;SO9GOt=d^V!~^1bu!@)u3{z}gfT#sjYB|x?w=MZa*#%=z9;-640$z_mh?96J;cOpC+gB%$ZEPrv0j`$I+;~ex0+R z;Zlh;*lR)=JKc%>WaXLJ2|vvo=lytJzqIhfY@{l~`(;ZjJC7V7XZFbA49k(-yC9=J zOQfi^Uf&4z+e+5Dtwg?kv@3h$Mkn@q9nLN3^3d~n+zxWf+nnGn4a3-TA&XP3AV(d% z18b`D_h}RPHX?U9F5nep9&!il#|!DM|+jWSqIsYl8m3O9f$lw zy6qPHE~nDBUw?yYh1@yV-~@P+C_S8~g|OwgiW|8Cd-(R1HnVL#Yq1}0+1T5u44!8B zYIBR*GZ?eh4eIs<-XZK+4qDO>*86eYuiH+f&Lb=E?U3Dy^>(Jm^Q^xE5%L2^0{;%| z*^wxBknd@#_H5KNw(rZBXWn49Qa@P_>{HIR^9$YQ zva2(7Bf<{#`7GI(5BS9g##nW}nQV=t@E7n7-W&rjkPURi82B4&TB~VIgz6<~#Qp>O zwDV1}rZo~^>^*RwHtw=QhOf1^^B-wP2R_nX9iC72fm^h5ek!SjY__{kz%M@|*Ma5a zcb92e7g=wqQ{mG!D8t~(>)S!iqc!k(_z!%(el2+9 zm;#M9zx1t_&2_%Rh{5GVS!#1;%SsNeP_6UPzsPoDKY(n_`Bun_6T^F$Y607nJ)K_f zUb5wWa#to_M$TN@txiS7*a*hFcV#?_NcL=mp9biHvb_^Ap^bxPwb0pNI z82tmaxkq6Gg_d-^^~KllrOI~g;-e~BBVHW&rO=m;?87&rT~4)igPH~zo0Y){$}3b2 zzU<1ziB9mE&PDEVD%;0d2ci7kuPmE1AHxkeWd)lUtV0~z%?1Wh;Z4|_P^D^9;Oe>3Ce(a)pLxVgo5xR^K4vFF_F89@h`6Z|)LB8bC9bTqfo z;#53-cP`?0Lx-!gd;Fa(IK;9z6w(#KPi;fEvG&W`Gg!B#|2MB>l)pcdQNH?;`Kv@8 z#DIQuXA!fMecVPd43GKu=*u=CE{M}30ynInla{M z9ia6zenArE?aCAI@sW$ijkvV!7$cjC_y*1_HK)r2Jvz`Yy-a`SFbABP&pAh+{jBau zAxkG>cLF(r+Kgqq8t}oiJOxTZe(c923p?y{8=qZ73+lh4rrUUZI~o$ieWHE{@gg$b!sJ4cQVZP3LnCyotQ3=hW#o_y-|gtr*|64SX7TL&&%r zef4_nHO!r2e83j~pJ15z20RXZ*dYgU!ZeZRo7Q4a_>CWD5bF-Pv_aV>azk|;^a1-h z)Gsmiu#p=Of2I#1rygZq3(KLGJqGSv_<}0(?P;}N+l@SH@k{gmMfe9|c-3Rm$5Mm1 zBVb?O0M5m=&|~=hjB@Zy#=Rf?6W~pn_h{27_nvu|KpC2$Z&^Y$R0O%pnTzB~)4 zG8ZX12)=E(R^+Qz?cz|Gc9GAHTS+^oR#C^Q$4mcnXO8pYD;b=}$A>UBT1Eama?oOx zq@6D!hJJwa>2->NPFjzX3HF(8O2$ytFC*a3<5J;ztR@?;-S& zD`=ObooMpWoK^SGvYlJVs@!!fqpUfW8Qy|34~Tw}obXHQjzQ`!fIskY4my|mPyRXs z-ab&rbp5hE)d|2S;0vXc&Aw$pKCE7vO|o9ChtzASgLTXL83K&Co1x!nLl2UJ^~+}o z>zDllXV}FZgW5&t_WX|9K+oXQGoR+HTtv%uw8AH|WW^n*oBa*>p<8J^#(uRBINzO$(+oo_sC`K9YV z?;k{dNm6sJ`H+k6K06}h^?YB`*vCQBiTIarPD{Iy@7M>~?>S~YG6bm-XT8V^z^z`n z7=8-eT(;YFpq<)QwoUu*m(iMj3f)S|?g>8UyO}TS@58#$Tx4}-rR-?TWyz&p2Rm*D z{Rn99(@tYPy>cz)s>zl23;lH?2CM?_VPWr&^%*jZlO&(|Qoy{isF z_N~;M9bCYA7rra*EczYOCUlSIkv#GOpCA3ty_CUu(F~u3o##HPpJUQ4&S!`vXA{A{ zK!4zC?JVf+R*~P($~f~#Es?BD5BD!#Dp-yrBQ|W6sSC8uF>g=!ZTq&E+a~$(-+$V6hHWa?rhSYu9o60AA z2br^1zl+SdNqH7`w!%ro;e{~hOIbx<1DsZz-}M5IO0(EQJV*Ma*?X`@z1Rb1wSixW zJz5HfjXj>@d&wM+em|N0&*FJ)zOFAmyMgOK<+FVpK4vd`#yK6&0Q<%LwFN#z%6?%3 zH*k*U7m0ZX-w|P#H2UT_at`z6bC!HXl;j%Nbno(TQF%XHk(IiA5uHFyJkTlS|5gzh-rn#Wagf6RBa*^BbH zE3#e;KXM~a*}G^uKmSa_x?0RTjk#*jTQU^H*{a(KaWw1Wrjx4vEPojBugh1#X9{pC z*+#(mJJ`mn+ot5iCHp(SI&y#(n$NZ0Z2MUUblcBb%Cy)O z%WdP|J)C>p(5Ly^M{ZlmLFSKjQuOJ5?GcgFHj<0ugZcjT8@Sg%Co5EvFZq%4jw3$( z8N4Yk{DJ-FG<JwR8Y`evCcdE%a;K3_oe{EXQ+G3v$2;`@94BfPc>hFJ1E&@94ujSS@OYfpGmqf?Z^7^LSnKCC%qzzoKN}fq zX9&8lV=nam6?A8QUU(gJ_lnp*fjz9o9gYt6`6E;2r@q3MU=0ZFi zXWwm7Id&u`Y;Q#>B##%m86?#`3O^l(-D}VKb=60^Zd%U0#+4 zo$RSb=jaByD!&187FcF|AH-$v_6=lT^$_CbDVm0UcW&c4r?R)3f1m1LT#Px?4am{P zI?VByQ~eaNd8QG#ZjNcWZkxchE8Duc@5uG8&SXnVGT>PPPa)y2735+chJ3y5xA1&c zhWz?7em>JW`258gSKalTyew<2bq&`bUsqe4e9l1@`*474sCMW?V%>8r`K4>iL=3Uc zp_2SNcrH1kjSW<2;{%JeHwW6aw+A+A?+$Fo?cu6~7ct^VcJ6Q{7w2N6=$-!K3b%x`qBeITe&xENpmZl%YL)6g{xV3df zOJK#1S5XIEyvXtOvi|NyHs0NoQ`rp(+4z@|ZwSdZq{^uri}}rtygr_kgNZ~m(j#6f z$+b5m7Bw1cfOk2X{=x{P%ISxZXjqQL(^%ezw*V_+{8~v)$7O!uA=ib%57cc5<2}j> zpaf$wJ{*wOV+jzG;hy-07+xcVj3`Q+{#nFRvML3}3zDs+}`-*&nNTy!?r>-L^f`pPcqo>4~I+`F`u0@cqvBd*A!M4}2f`KDzY} zzG*(+3}ZD@m?~2mn9{(M2BtJHrGY68Ole?B15+B9(!i7krZn)^)BqmPEDwMIZvO@? zzJa#vMvL#E#kb2=OySKu;d|;*{F21qEn6NzTaNY_v=ylQtXV?(x2_hz6R1v9{w5s1 zmY4H0C}5k6)`oRQ(UzgwQF)Hyn)W3c3GM%)#a9M@QTeMrY~r_&`FIQFEpqNk^`_EE zeBMef@$I7vKM?R2k)ll}$%QBVAa@KX5lxc|Ut{8LGA_Ptbm8;Ia56!zaBpCJGPo%m z=*5?)#U3c(L(3Ezdw=|GcNGhCqzAmeu+LNaM(BIUK(Q`;wpRx!=jjWn~xsT1wHl^uF?g)kH7jH`^;hk z1|IvC@UIDsp)Y)qX)xZ+s7xC^%f8IjxeI->Fdi5Fy@c_w9^Yk(Dm}y#Mlt!j4SfS| zK0vO*&$;Dd(rX87;vo+B|8aaH-cK&Ws|6k^UdLQ2CcPd54>88yadIv0#n>j^{g>fE z@8a9ndPXpciT5D-&XKTanZ*g6vjiGl8VZ5aBQOyq@eF&G3osbBaDat-@@Ow zif>%E7O`}CjLQU=F5``$iz>Fqs$^ZZW diff --git a/builds/powerpc/installer/legacy/builds/ppc/libe2p.so.2 b/builds/powerpc/installer/legacy/builds/ppc/libe2p.so.2 deleted file mode 100644 index 822c8d7f8ca58b147d7e789d94bd289b6d3006c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23312 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 diff --git a/builds/powerpc/installer/legacy/builds/ppc/libpthread.so.0 b/builds/powerpc/installer/legacy/builds/ppc/libpthread.so.0 deleted file mode 100644 index b320f2460b02455999ba8b21cd91d86a3878e9e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71544 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%0A=;J-i*z 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 HQtp2Nmk1Hl diff --git a/builds/powerpc/installer/legacy/builds/ppc/mkfs.ext2 b/builds/powerpc/installer/legacy/builds/ppc/mkfs.ext2 deleted file mode 100755 index 2ac41d2d..00000000 --- a/builds/powerpc/installer/legacy/builds/ppc/mkfs.ext2 +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -export LD_LIBRARY_PATH=$( cd $( dirname -- "$0" ) > /dev/null ; pwd ) -$LD_LIBRARY_PATH/mke2fs $@ From 760fa4d1560389d512fabe418bb1d75a4f7ac7ac Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 22 Jun 2016 20:55:50 +0000 Subject: [PATCH 51/87] The ONL-CONFIG partition should be mounted RO. --- builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml b/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml index 51ca0f49..598e4c69 100644 --- a/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml +++ b/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml @@ -9,7 +9,7 @@ mounts: dir: /mnt/onl/data ONL-CONFIG: - mount: false + mount: ro dir: /mnt/onl/config fsck: true From 0fcad8f65e1066baf1bb4340278ada06e4373cc8 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 22 Jun 2016 20:56:15 +0000 Subject: [PATCH 52/87] Use -sha256 for certificate signing. --- .../base/all/vendor-config-onl/src/python/onl/pki/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py index ad96778e..f5c27b73 100755 --- a/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py @@ -58,7 +58,7 @@ class OnlPki(OnlServiceMixin): os.makedirs(self.CONFIG_PKI_DIR) self._execute("""openssl req -new -batch -subj "%s" -key %s -out %s""" % ( subject, self.kpath, csr.name)) - self._execute("""openssl x509 -req -days %s -in %s -signkey %s -out %s""" % ( + self._execute("""openssl x509 -req -days %s -sha256 -in %s -signkey %s -out %s""" % ( sysconfig.pki.cert.csr.cdays, csr.name, self.kpath, self.cpath)) os.unlink(csr.name) From e7456386f7302a1e4e1daaf942bfbf96f0100f19 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 22 Jun 2016 20:56:55 +0000 Subject: [PATCH 53/87] Fix useradd/userdel. --- tools/onlrfs.py | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/tools/onlrfs.py b/tools/onlrfs.py index 04d1f940..b2a11e93 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -61,12 +61,13 @@ class OnlRfsSystemAdmin(object): onlu.execute("sudo chmod %s %s" % (mode, file_), ex=OnlRfsError("Could not change permissions (%s) on file %s" % (mode, file_))) - def userdel(self): - pf = os.path.join(self.chroot, 'etc/password') + def userdel(self, username): + pf = os.path.join(self.chroot, 'etc/passwd') sf = os.path.join(self.chroot, 'etc/shadow') - self.chmod("a+w", pf); - self.chmod("a+w", sf); + self.chmod("a+rwx", os.path.dirname(pf)) + self.chmod("a+rw", pf); + self.chmod("a+rw", sf); # Can't use the userdel command because of potential uid 0 in-user problems while running ourselves for line in fileinput.input(pf, inplace=True): @@ -76,23 +77,38 @@ class OnlRfsSystemAdmin(object): if not line.startswith('%s:' % username): print line, - self.chmod("go-w", pf); - self.chmod("go-w", sf); + self.chmod("go-wx", pf); + self.chmod("go-wx", sf); - def useradd(self, username, uid, password, shell, deleteFirst=True): - args = [ 'useradd', '--non-unique', '--shell', shell, '--home-dir', '/root', - '--uid', '0', '--gid', '0', '--group', 'root' ] + def useradd(self, username, uid=None, gid=None, password=None, shell=None, home=None, groups=None, deleteFirst=True): + args = [ 'useradd', '--create-home' ] - if deleteFirst: - self.userdel(username) + if uid: + args = args + [ '--non-unique', '--uid', str(uid) ] if password: epassword=crypt.crypt(password, '$1$%s$' % self.gen_salt()); args = args + ['-p', epassword ] + if shell: + args = args + [ '--shell', shell ] + + if gid: + args = args + [ '--gid', gid ] + + if home: + args = args + [ '--home', home ] + + if groups: + args = args + [ '--group', groups ] + + if deleteFirst: + self.userdel(username) + args.append(username) onlu.execute(args, + chroot=self.chroot, ex=OnlRfsError("Adding user '%s' failed." % username)) if password is None: @@ -347,8 +363,11 @@ rm -f /usr/sbin/policy-rc.d for (user, values) in Configure.get('users', {}).iteritems(): ua = OnlRfsSystemAdmin(dir_) - if 'password' in values: - ua.user_password_set(user, values['password']) + if user == 'root': + if 'password' in values: + ua.user_password_set(user, values['password']) + else: + ua.useradd(username=user, **values) options = Configure.get('options', {}) From 69cc9ebd98e8fc37ccc3dc316696460bee0e3214 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 22 Jun 2016 16:44:47 -0700 Subject: [PATCH 54/87] Add user sudo option. --- tools/onlrfs.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/onlrfs.py b/tools/onlrfs.py index b2a11e93..8dedc172 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -61,6 +61,11 @@ class OnlRfsSystemAdmin(object): onlu.execute("sudo chmod %s %s" % (mode, file_), ex=OnlRfsError("Could not change permissions (%s) on file %s" % (mode, file_))) + @staticmethod + def chown(file_, ownspec): + onlu.execute("sudo chown %s %s" % (ownspec, file_), + ex=OnlRfsError("Could not change ownership (%s) on file %s" % (ownspec, file_))) + def userdel(self, username): pf = os.path.join(self.chroot, 'etc/passwd') sf = os.path.join(self.chroot, 'etc/shadow') @@ -80,7 +85,7 @@ class OnlRfsSystemAdmin(object): self.chmod("go-wx", pf); self.chmod("go-wx", sf); - def useradd(self, username, uid=None, gid=None, password=None, shell=None, home=None, groups=None, deleteFirst=True): + def useradd(self, username, uid=None, gid=None, password=None, shell='/bin/bash', home=None, groups=None, sudo=False, deleteFirst=True): args = [ 'useradd', '--create-home' ] if uid: @@ -118,6 +123,14 @@ class OnlRfsSystemAdmin(object): logger.info("user %s password %s", username, password) + if sudo: + sudoer = os.path.join(self.chroot, 'etc/sudoers.d', username) + self.chmod("777", os.path.dirname(sudoer)) + with open(sudoer, "w") as f: + f.write("%s ALL=(ALL:ALL) NOPASSWD:ALL\n" % username); + self.chmod("0440", sudoer) + self.chown(sudoer, "root:root") + self.chmod("755", os.path.dirname(sudoer)) def user_password_set(self, username, password): logger.info("user %s password now %s", username, password) From bba8cfc48e29be968db3f15ae7f942b7ec34b004 Mon Sep 17 00:00:00 2001 From: Steven Noble Date: Thu, 23 Jun 2016 13:27:25 -0700 Subject: [PATCH 55/87] igb bcm54616 patch ported to kernel 3.18 (#90) Ported the driver-support-intel-igb-bcm54616-phy.patch from the 3.2 kernel to the 3.18 kernel. --- ...river-support-intel-igb-bcm54616-phy.patch | 67 +++++++++++++++++++ .../base/any/kernels/3.18.25/patches/series | 1 + 2 files changed, 68 insertions(+) create mode 100644 packages/base/any/kernels/3.18.25/patches/driver-support-intel-igb-bcm54616-phy.patch diff --git a/packages/base/any/kernels/3.18.25/patches/driver-support-intel-igb-bcm54616-phy.patch b/packages/base/any/kernels/3.18.25/patches/driver-support-intel-igb-bcm54616-phy.patch new file mode 100644 index 00000000..c83708ac --- /dev/null +++ b/packages/base/any/kernels/3.18.25/patches/driver-support-intel-igb-bcm54616-phy.patch @@ -0,0 +1,67 @@ +diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c +index 051ea94..2a04baa 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_82575.c ++++ b/drivers/net/ethernet/intel/igb/e1000_82575.c +@@ -286,6 +286,9 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) + phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580; + phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; + break; ++ case BCM54616_E_PHY_ID: ++ phy->type = e1000_phy_bcm54616; ++ break; + default: + ret_val = -E1000_ERR_PHY; + goto out; +@@ -1550,6 +1553,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) + case e1000_i350: + case e1000_i210: + case e1000_i211: ++ case e1000_i354: + phpm_reg = rd32(E1000_82580_PHY_POWER_MGMT); + phpm_reg &= ~E1000_82580_PM_GO_LINKD; + wr32(E1000_82580_PHY_POWER_MGMT, phpm_reg); +@@ -1593,6 +1597,8 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) + case e1000_phy_82580: + ret_val = igb_copper_link_setup_82580(hw); + break; ++ case e1000_phy_bcm54616: ++ break; + default: + ret_val = -E1000_ERR_PHY; + break; +diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h +index 217f813..5322fbf 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_defines.h ++++ b/drivers/net/ethernet/intel/igb/e1000_defines.h +@@ -860,6 +860,7 @@ + #define M88_VENDOR 0x0141 + #define I210_I_PHY_ID 0x01410C00 + #define M88E1543_E_PHY_ID 0x01410EA0 ++#define BCM54616_E_PHY_ID 0x3625D10 + + /* M88E1000 Specific Registers */ + #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ +diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h +index 2003b37..d82c96b 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_hw.h ++++ b/drivers/net/ethernet/intel/igb/e1000_hw.h +@@ -128,6 +128,7 @@ enum e1000_phy_type { + e1000_phy_ife, + e1000_phy_82580, + e1000_phy_i210, ++ e1000_phy_bcm54616, + }; + + enum e1000_bus_type { +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index e0f3664..013c1f1 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -108,6 +108,7 @@ static const struct pci_device_id igb_pci_tbl[] = { + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_SGMII), board_82575 }, + /* required last entry */ + {0, } + }; diff --git a/packages/base/any/kernels/3.18.25/patches/series b/packages/base/any/kernels/3.18.25/patches/series index f6b71ff1..661d5eac 100644 --- a/packages/base/any/kernels/3.18.25/patches/series +++ b/packages/base/any/kernels/3.18.25/patches/series @@ -1 +1,2 @@ aufs.patch +driver-support-intel-igb-bcm54616-phy.patch From b1c2e0d2767e187368764c16104e6aaf0f94b1b1 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 24 Jun 2016 02:19:47 +0000 Subject: [PATCH 56/87] Allow build-specific additions to the MODSYNCLIST. --- make/kbuild.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/make/kbuild.mk b/make/kbuild.mk index 78f3b978..7bfa8117 100644 --- a/make/kbuild.mk +++ b/make/kbuild.mk @@ -153,7 +153,8 @@ endif endif -MODSYNCLIST := .config Module.symvers Makefile include scripts arch/x86/include arch/x86/Makefile arch/powerpc/include arch/powerpc/Makefile arch/powerpc/lib +MODSYNCLIST_DEFAULT := .config Module.symvers Makefile include scripts arch/x86/include arch/x86/Makefile arch/powerpc/include arch/powerpc/Makefile arch/powerpc/lib arch/arm/include arch/arm/Makefile arch/arm/lib +MODSYNCLIST := $(MODSYNCLIST_DEFAULT) $(MODSYNCLIST_EXTRA) mbuild: build rm -rf $(K_MBUILD_DIR) From b53e3fd6f5b194e3636a33547e931c1b15d3088a Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 24 Jun 2016 02:20:26 +0000 Subject: [PATCH 57/87] Add iproc platform include directory to the modsynclist. --- .../armel/kernels/kernel-3.2-deb7-arm-iproc-all/builds/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/base/armel/kernels/kernel-3.2-deb7-arm-iproc-all/builds/Makefile b/packages/base/armel/kernels/kernel-3.2-deb7-arm-iproc-all/builds/Makefile index c4b59fec..67655667 100644 --- a/packages/base/armel/kernels/kernel-3.2-deb7-arm-iproc-all/builds/Makefile +++ b/packages/base/armel/kernels/kernel-3.2-deb7-arm-iproc-all/builds/Makefile @@ -12,6 +12,8 @@ THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) include $(ONL)/make/config.mk +export MODSYNCLIST_EXTRA := arch/arm/plat-iproc/include + kernel: $(MAKE) -C $(ONL)/packages/base/any/kernels/3.2.71-1+deb7/configs/arm-iproc-all K_TARGET_DIR=$(THIS_DIR) $(ONL_MAKE_PARALLEL) From b0c01e19bb7da384d47df925da36f3ca00f8ba60 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 29 Jun 2016 22:27:43 +0000 Subject: [PATCH 58/87] Latest --- sm/bigcode | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/bigcode b/sm/bigcode index fdc0f796..44249760 160000 --- a/sm/bigcode +++ b/sm/bigcode @@ -1 +1 @@ -Subproject commit fdc0f7964694f3b2c4c6d57f974af2bd7a877386 +Subproject commit 442497608648ff26996716432e67c2196ec9b613 From 7366c0427fbc1ab80a411b466a44f8f84c22f654 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 29 Jun 2016 16:09:53 -0700 Subject: [PATCH 59/87] Spelling. --- tools/autobuild/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/autobuild/install.sh b/tools/autobuild/install.sh index dddc2bfa..9f904a76 100755 --- a/tools/autobuild/install.sh +++ b/tools/autobuild/install.sh @@ -48,7 +48,7 @@ done if [ -z "$REMOTE_SERVER" ]; then - echo "Remote instlallation requires a server (-s)" + echo "Remote installation requires a server (-s)" exit 1 fi From 2d8f93201ee5c969a880e1e8f8cbba259dd36968 Mon Sep 17 00:00:00 2001 From: Steven Noble Date: Fri, 1 Jul 2016 17:37:33 -0700 Subject: [PATCH 60/87] update 5512 to use 3.18 kernel and add Wedge 100 to HCL (#91) --- docs/SupportedHardware.md | 1 + .../platform-config/r0/src/lib/x86-64-accton-as5512-54x-r0.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/SupportedHardware.md b/docs/SupportedHardware.md index fba20e1b..d8fa0b41 100644 --- a/docs/SupportedHardware.md +++ b/docs/SupportedHardware.md @@ -40,6 +40,7 @@ Accton/Edge-Core Accton AS7712-32X 32x100G Intel Rangeley C2538 x86 Broadcom BCM56960 (Tomahawk) Yes Yes Yes Yes*** Yes*** No Accton AS7716-32X 32x100G Intel Xeon D-1518 x86 Broadcom BCM56960 (Tomahawk) Yes Yes No Yes*** Yes*** No Accton Wedge-16X 16x40G Intel Rangeley C2550 x86 Broadcom BCM56864 (Trident2+) Work In Progress** Yes No No Yes No + Accton (FB) Wedge 100 32x100G Intel Bay Trail E3845 x86 Broadcom BCM56960 (Tomahawk) Work In Progress** Yes No No Yes No DNI/Agema diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/lib/x86-64-accton-as5512-54x-r0.yml b/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/lib/x86-64-accton-as5512-54x-r0.yml index 2c31c65a..218d540c 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/lib/x86-64-accton-as5512-54x-r0.yml +++ b/packages/platforms/accton/x86-64/x86-64-accton-as5512-54x/platform-config/r0/src/lib/x86-64-accton-as5512-54x-r0.yml @@ -18,7 +18,7 @@ x86-64-accton-as5512-54x-r0: --stop=1 kernel: - <<: *kernel-3-2 + <<: *kernel-3-18 args: >- nopat From 4918fee87beb87b3d1f594817d33a9735a99103b Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 5 Jul 2016 22:46:06 +0000 Subject: [PATCH 61/87] If any rc.boot scripts are present in mounted partitions they will be executed at boot time. --- packages/base/all/boot.d/src/52.rc.boot | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 packages/base/all/boot.d/src/52.rc.boot diff --git a/packages/base/all/boot.d/src/52.rc.boot b/packages/base/all/boot.d/src/52.rc.boot new file mode 100755 index 00000000..ffb8dc89 --- /dev/null +++ b/packages/base/all/boot.d/src/52.rc.boot @@ -0,0 +1,15 @@ +#!/bin/sh +# +############################################################ +# +# If any rc.boot scripts are present in any mounted +# partition they will be executed at boot time. +# +############################################################ +for dir in boot config images data; do + script=/mnt/onl/$dir/rc.boot + if [ -x "$script" ]; then + echo "Executing $script..." + $script + fi +done From 3d21d491e024cda848aa57841e7e01d53e1937ab Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 7 Jul 2016 17:20:02 +0000 Subject: [PATCH 62/87] The submodule post-update hooks are now specified via environment variables. --- setup.env | 3 +++ tools/scripts/submodule-updated.sh | 2 +- tools/submodules.py | 15 +++++++-------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/setup.env b/setup.env index 56d0ad37..7e6f7f33 100755 --- a/setup.env +++ b/setup.env @@ -44,3 +44,6 @@ export ONL_DEBIAN_SUITE=$(lsb_release -c -s) if [ ! -f $ONL/.git/hooks/post-merge ] && [ -d $ONL/.git ]; then cp $ONL/tools/scripts/post-merge.hook $ONL/.git/hooks/post-merge fi + +# submodule post update scripts. +export ONL_SUBMODULE_UPDATED_SCRIPTS="$ONL/tools/scripts/submodule-updated.sh" \ No newline at end of file diff --git a/tools/scripts/submodule-updated.sh b/tools/scripts/submodule-updated.sh index f1e166ce..c3ff4608 100755 --- a/tools/scripts/submodule-updated.sh +++ b/tools/scripts/submodule-updated.sh @@ -13,7 +13,7 @@ ############################################################ # Removing the manifest causes it to be regenerated. -rm -rf $ONL/.manifest.mk +rm -rf $ONL/make/module-manifest.mk # Rebuild pkg cache onlpm.py --rebuild-pkg-cache diff --git a/tools/submodules.py b/tools/submodules.py index 991178c4..9e8deba4 100755 --- a/tools/submodules.py +++ b/tools/submodules.py @@ -101,14 +101,13 @@ class OnlSubmoduleManager(object): # # Run any repository-specific post-submodule-init scripts. # - script = os.path.join(self.root, 'tools', 'scripts', 'submodule-updated.sh') - if os.path.exists(script): - try: - check_call([script, path], cwd=self.root) - except subprocess.CalledProcessError: - # Target doesn't exists - raise OnlSubmoduleError("The repository post-init script %s failed." % script) - + for script in os.getenv("ONL_SUBMODULE_UPDATED_SCRIPTS", "").split(':'): + if os.path.exists(script): + try: + print "Calling %s..." % script + check_call([script, path], cwd=self.root) + except subprocess.CalledProcessError: + raise OnlSubmoduleError("The repository post-init script %s failed." % script) def require(self, path, depth=None, recursive=False): self.get_status() From 0d42121939e69ebdeaee8d5e36e28a968b26de38 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 8 Jul 2016 19:17:29 +0000 Subject: [PATCH 63/87] Fix name. --- builds/any/installer/installer.sh.in | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/builds/any/installer/installer.sh.in b/builds/any/installer/installer.sh.in index 7982c5a1..e2dbd86e 100644 --- a/builds/any/installer/installer.sh.in +++ b/builds/any/installer/installer.sh.in @@ -9,16 +9,7 @@ # ############################################################ # -# SwitchLight Installation Script for PPC. -# -# The purpose of this script is to automatically install SwitchLight -# on the target system. -# -# This script is ONIE-compatible. -# -# This script is can be run under a manual boot of the SwitchLight -# Loader as the execution environment for platforms that do not -# support ONIE. +# Open Network Linux Installation Script # ############################################################ @@ -160,7 +151,7 @@ visit_proc_mounts() { local ifs line dummy fn rest sts fn=$1; shift rest="$@" - + ifs=$IFS; IFS=$CR for line in $(cat /proc/mounts); do IFS=$ifs From 418bdf3a5a0c7374d9ce9a760fb7c259134e13a4 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 11 Jul 2016 19:41:09 +0000 Subject: [PATCH 64/87] The initrd is not longer a part of the platform configuration. This is an integration setting. --- .../lib/platform-config-defaults-x86-64.yml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml index c3f416bf..fb897b59 100644 --- a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml +++ b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml @@ -19,17 +19,10 @@ default: # this is mostly to *reject* invalid disk labels, # since we will never create our own - initrd-amd64: &initrd-amd64 - =: onl-loader-initrd-amd64.cpio.gz - package: onl-loader-initrd:amd64 - - initrd: - <<: *initrd-amd64 - kernel-3.2: &kernel-3-2 =: kernel-3.2-deb7-x86_64-all package: onl-kernel-3.2-deb7-x86-64-all:amd64 - + kernel-3.9.6: &kernel-3-9-6 =: kernel-3.9.6-x86-64-all package: onl-kernel-3.9.6-x86-64-all:amd64 @@ -39,7 +32,7 @@ default: package: onl-kernel-3.18-x86-64-all:amd64 # pick one of the above kernels - kernel: + kernel: <<: *kernel-3-2 # GRUB command line arguments for 'serial' declaration @@ -70,10 +63,10 @@ default: ##args: >- ## nopat ## console=ttyS0,115200n8 - + ##device: /dev/vda ### install to a specific block device - + device: ONIE-BOOT # install to the device that contains the ONIE-BOOT partition # (query using parted and/or blkid) @@ -103,7 +96,7 @@ default: ##- ONL-CONFIG: 128MiB ##- ONL-IMAGES: 384MiB ##- ONL-DATA: 100% - + network: # remap interface names on boot (loader only) @@ -114,7 +107,7 @@ default: # this should work for most systems ma1: name: eth0 - + # for other wierd corner cases ##ma1: ## name: ~ From 997565c6bd18a68a12f0b620e7770352982a0d94 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 11 Jul 2016 19:42:00 +0000 Subject: [PATCH 65/87] Add default installer strings. --- .../src/etc/onl/sysconfig/00-defaults.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml b/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml index 6597f9c3..a4fe5b85 100644 --- a/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml +++ b/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml @@ -5,6 +5,10 @@ # These provide the base default values for all sysconfig keys. # ############################################################ +installer: + menu_name: "\"Open Network Linux\"" + os_name: Open Network Linux + upgrade: onie: auto: advisory @@ -33,7 +37,3 @@ pki: organizationalUnitName: Open Network Linux emailAddress: support@bigswitch.com cdays: 3600 - - - - From b044cf78a0e2d5c7cc061b9abfb0951e1b2bbf15 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 11 Jul 2016 19:42:21 +0000 Subject: [PATCH 66/87] - Use the sysconfig interface for customization. - Assume the existance of the initrd [This needs to be fixed later]. --- .../src/python/onl/install/BaseInstall.py | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py b/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py index d09af9d9..f18cd649 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py @@ -19,6 +19,7 @@ from InstallUtils import MountContext, BlkidParser, PartedParser from InstallUtils import ProcMountsParser import onl.YamlUtils +from onl.sysconfig import sysconfig class Base: @@ -363,9 +364,9 @@ terminal_input serial terminal_output serial set timeout=5 -menuentry OpenNetworkLinux { +menuentry %(boot_menu_entry)s { search --no-floppy --label --set=root ONL-BOOT - echo 'Loading Open Network Linux ...' + echo 'Loading %(boot_loading_name)s ...' insmod gzio insmod part_msdos linux /%(kernel)s %(args)s onl_platform=%(platform)s @@ -476,22 +477,26 @@ class GrubInstaller(SubprocessMixin, Base): kernel = self.im.platformConf['grub']['kernel'] ctx['kernel'] = kernel['='] if type(kernel) == dict else kernel - - initrd = self.im.platformConf['grub']['initrd'] - ctx['initrd'] = initrd['='] if type(initrd) == dict else initrd - ctx['args'] = self.im.platformConf['grub']['args'] ctx['platform'] = self.im.installerConf.installer_platform ctx['serial'] = self.im.platformConf['grub']['serial'] + ctx['boot_menu_entry'] = sysconfig.installer.menu_name + ctx['boot_loading_name'] = sysconfig.installer.os_name + + files = [] + for f in set(os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()): + if 'initrd' in f and 'cpio' in f: + ctx['initrd'] = f + files.append(f) + if 'kernel' in f: + files.append(f) + cf = GRUB_TPL % ctx self.log.info("Installing kernel") dev = self.blkidParts['ONL-BOOT'] - files = set(os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()) - files = [b for b in files if b.startswith('kernel-') or b.startswith('onl-loader-initrd-')] - with MountContext(dev.device, log=self.log) as ctx: def _cp(b): dst = os.path.join(ctx.dir, b) From 898b1a1531eb4b4f811a248f47c8b782c3b62168 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 11 Jul 2016 19:43:10 +0000 Subject: [PATCH 67/87] Fix key. --- .../r0/src/lib/x86-64-accton-as7512-32x-r0.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/lib/x86-64-accton-as7512-32x-r0.yml b/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/lib/x86-64-accton-as7512-32x-r0.yml index 4f4c51ce..77b890a5 100644 --- a/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/lib/x86-64-accton-as7512-32x-r0.yml +++ b/packages/platforms/accton/x86-64/x86-64-accton-as7512-32x/platform-config/r0/src/lib/x86-64-accton-as7512-32x-r0.yml @@ -6,7 +6,7 @@ # ###################################################################### -x86-64-accton-as5712-32x-r0: +x86-64-accton-as7512-32x-r0: grub: @@ -17,7 +17,7 @@ x86-64-accton-as5712-32x-r0: --parity=no --stop=1 - kernel: + kernel: <<: *kernel-3-2 args: >- From 9a98e40c09c7307e0a005a172b0de2aa4e47f9d7 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 11 Jul 2016 21:54:31 +0000 Subject: [PATCH 68/87] Use the new mkinstaller script. --- builds/any/installer/grub/builds/Makefile | 84 +---------------- builds/any/installer/uboot/builds/Makefile | 103 +-------------------- 2 files changed, 5 insertions(+), 182 deletions(-) diff --git a/builds/any/installer/grub/builds/Makefile b/builds/any/installer/grub/builds/Makefile index 2d1e55a6..068161b9 100644 --- a/builds/any/installer/grub/builds/Makefile +++ b/builds/any/installer/grub/builds/Makefile @@ -2,92 +2,12 @@ ifndef ARCH $(error $$ARCH not set) endif -ONLPLATFORM = python $(ONL)/tools/onlplatform.py -PLATFORMS := $(shell $(ONLPM) --platform-manifest onl-loader-initrd:$(ARCH)) - -MKSHAR = $(ONL)/tools/mkshar -MKSHAR_OPTS = --lazy --unzip-pad --fixup-perms autoperms.sh -MKSHAR_PERMS = autoperms.sh - # Hardcoded to match ONL File naming conventions. include $(ONL)/make/versions/version-onl.mk INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_INSTALLER -ifeq ($(ARCH), amd64) -INSTALLER_ARCH = x86_64 -else -INSTALLER_ARCH = $(ARCH) -endif - -__installer: __installer_platform_files __installer_swi_files - $(ONL_V_at)rm -rf *INSTALLER* *.md5sum - $(ONL_V_at)cp /dev/null installer.sh - $(ONL_V_at): ;\ - set -e ;\ - if $(ONL_V_P); then set -x; fi ;\ - set dummy *.cpio.gz; initrd="$$2" ;\ - sed \ - -e 's^@ONLVERSION@^$(VERSION_STRING)^g' \ - -e "s^@INITRD_ARCHIVE@^$$initrd^g" \ - -e 's^@INITRD_OFFSET@^^g' \ - -e 's^@INITRD_SIZE@^^g' \ - -e 's^@ARCH@^$(INSTALLER_ARCH)^g' \ - $(ONL)/builds/any/installer/installer.sh.in \ - >> installer.sh - $(ONL_V_at)echo "PAYLOAD_FOLLOWS" >> installer.sh - $(ONL_V_at)cp /dev/null $(MKSHAR_PERMS) - $(ONL_V_at)cp $(ONL)/make/versions/version-onl.sh . - $(ONL_V_at)echo "#!/bin/sh" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -e" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -x" >> $(MKSHAR_PERMS) - $(MKSHAR) $(MKSHAR_OPTS) "$(INSTALLER_NAME)" $(ONL)/tools/scripts/sfx.sh.in installer.sh kernel-* onl-loader-initrd-* *.swi version-onl.sh boot-config - $(ONL_V_at)rm -rf installer.sh kernel-* onl-loader-initrd-* $(ZTN_MANIFEST) *.swi version-onl.sh autoperms.sh +__installer: + $(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --initrd onl-loader-initrd:$(ARCH) onl-loader-initrd-$(ARCH).cpio.gz --out $(INSTALLER_NAME) md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum" -__installer_platform_files: - $(ONL_V_GEN): ;\ - set -e ;\ - if $(ONL_V_P); then set -x; fi ;\ - l="$(PLATFORMS)"; for p in $$l; do \ - src=$$($(ONLPLATFORM) $$p $(ARCH) kernel 2>/dev/null) || : ;\ - if test "$$src"; then \ - dst=$${src##*/} ;\ - if test "$dst" -ot Makefile; then \ - : ;\ - else \ - echo "Staging $$dst for $$p" ;\ - cp "$$src" "$$dst" ;\ - fi ;\ - fi ;\ - src=$$($(ONLPLATFORM) $$p $(ARCH) initrd 2>/dev/null) || : ;\ - if test "$$src"; then \ - dst=$${src##*/} ;\ - if test "$dst" -ot Makefile; then \ - : ;\ - else \ - echo "Staging $$dst for $$p" ;\ - cp "$$src" "$$dst" ;\ - fi ;\ - fi ;\ - done ;\ - : -ifndef NO_SWI -__installer_swi_files: - $(ONL_V_GEN): ;\ - set -e ;\ - if $(ONL_V_P); then set -x; fi ;\ - swidir=$$(mktemp -d $(PWD)/swi-d-XXXXXX) ;\ - $(ONLPM) --extract-dir onl-swi:$(ARCH) $$swidir ;\ - mv $$swidir/usr/share/onl/packages/$(ARCH)/onl-swi/*.swi . ;\ - rm -fr $$swidir ;\ - : -else -__installer_swi_files: - $(ONL_V_GEN): -endif - -shar installer: installer - -clean: - rm -f *.swi *.installer $(notdir $(KERNELS)) *initrd*.cpio.gz diff --git a/builds/any/installer/uboot/builds/Makefile b/builds/any/installer/uboot/builds/Makefile index eae9c217..79e73561 100644 --- a/builds/any/installer/uboot/builds/Makefile +++ b/builds/any/installer/uboot/builds/Makefile @@ -2,109 +2,12 @@ ifndef ARCH $(error $$ARCH not set) endif -ONLPLATFORM = python $(ONL)/tools/onlplatform.py -PLATFORMS := $(shell $(ONLPM) --platform-manifest onl-loader-initrd:$(ARCH)) - -MKSHAR = $(ONL)/tools/mkshar -MKSHAR_OPTS = --lazy --unzip-pad --fixup-perms autoperms.sh -MKSHAR_PERMS = autoperms.sh - -VONLDIR = $(ONL)/packages/base/all/vendor-config-onl -PYFIT = $(VONLDIR)/src/bin/pyfit -PYFIT_ENVIRONMENT = PYTHONPATH=$(VONLDIR)/src/python - # Hardcoded to match ONL File naming conventions. include $(ONL)/make/versions/version-onl.mk INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_INSTALLER -# default fit image can be used as the canonical location for the initrd -FIT_IMAGE_ALL := $(shell $(ONLPM) --find-file onl-loader-fit:$(ARCH) onl-loader-fit.itb) -INITRD := $(shell $(ONLPM) --find-file onl-loader-initrd:$(ARCH) onl-loader-initrd-$(ARCH).cpio.gz) -INITRD_BOUNDS := $(shell $(PYFIT_ENVIRONMENT) $(PYFIT) -v offset $(FIT_IMAGE_ALL) --initrd) +__installer: + $(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --fit onl-loader-fit:$(ARCH) onl-loader-fit.itb --out $(INSTALLER_NAME) + md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum" -__installer: installer.sh __installer_fit_files __installer_platform_files __installer_swi_files - $(ONL_V_at)rm -rf *INSTALLER* *.md5sum - $(ONL_V_at)cp /dev/null $(MKSHAR_PERMS) - $(ONL_V_at)cp $(ONL)/make/versions/version-onl.sh . - $(ONL_V_at)echo "#!/bin/sh" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -e" >> $(MKSHAR_PERMS) - $(ONL_V_at)echo "set -x" >> $(MKSHAR_PERMS) - $(MKSHAR) $(MKSHAR_OPTS) "$(INSTALLER_NAME)" $(ONL)/tools/scripts/sfx.sh.in installer.sh *.swi *.itb version-onl.sh boot-config - $(ONL_V_at)rm -rf installer.sh *.itb *.swi version-onl.sh autoperms.sh - $(ONL_V_at)md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum" -installer.sh: Makefile $(ONL)/builds/any/installer/installer.sh.in - $(ONL_V_GEN)cp /dev/null $@ - $(ONL_V_at): ;\ - set -e ;\ - if $(ONL_V_P); then set -x; fi ;\ - if test "$(INITRD_BOUNDS)"; then \ - a="$(FIT_IMAGE_ALL)"; a=$${a##*/} ;\ - else \ - a="$(INITRD)"; i=$${a##*/} ;\ - fi ;\ - set dummy $(INITRD_BOUNDS); start=$$2; end=$$3; sz=$$(($$end - $$start + 1)) ;\ - sed \ - -e 's^@ONLVERSION@^$(VERSION_STRING)^g' \ - -e "s^@INITRD_ARCHIVE@^$${a}^g" \ - -e "s^@INITRD_OFFSET@^$$start^g" \ - -e "s^@INITRD_SIZE@^$$sz^g" \ - -e 's^@ARCH@^$(ARCH)^g' \ - $(ONL)/builds/any/installer/installer.sh.in \ - >> $@ - $(ONL_V_at)echo "PAYLOAD_FOLLOWS" >> $@ - -__installer_fit_files: - $(ONL_V_GEN): ;\ - set -e ;\ - if $(ONL_V_P); then set -x; fi ;\ - src=$(FIT_IMAGE_ALL) ;\ - dst=$${src##*/} ;\ - if test "$$dst" -nt Makefile; then \ - : ;\ - else \ - echo "Staging $$dst" ;\ - cp $$src $$dst ;\ - fi ;\ - : - -############################## -# -# optionally include custom itb files for each platform -# -############################## - -__installer_platform_files: - $(ONL_V_GEN): ;\ - set -e ;\ - if $(ONL_V_P); then set -x; fi ;\ - l="$(PLATFORMS)"; for p in $$l; do \ - echo "Looking for an ITB specific to $$p, ignore errors..." ;\ - src=$$($(ONLPLATFORM) $$p $(ARCH) itb) 2>/dev/null || : ;\ - if test "$$src"; then :; else continue; fi ;\ - dst=$${src##*/} ;\ - echo "Found $$dst" ;\ - if test "$$dst" -nt Makefile; then continue; fi ;\ - echo "Staging $$dst for $$p" ;\ - cp "$$src" "$$dst" ;\ - done ;\ - : - -__installer_swi_files: -ifndef NO_SWI - $(ONL_V_GEN): ;\ - set -e ;\ - if $(ONL_V_P); then set -x; fi ;\ - swidir=$$(mktemp -d $(PWD)/swi-d-XXXXXX) ;\ - $(ONLPM) --extract-dir onl-swi:$(ARCH) $$swidir ;\ - mv $$swidir/usr/share/onl/packages/$(ARCH)/onl-swi/*.swi . ;\ - rm -fr $$swidir ;\ - : -else - $(ONL_V_GEN): -endif - -shar installer: installer - -clean: - rm -f *.swi *.installer *.cpio.gz From 14dd72b0eda668bfaa3f5e5592fdf142404e5864 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 11 Jul 2016 21:54:50 +0000 Subject: [PATCH 69/87] mkinstaller New script to automate the installer generation and inputs for different build configurations. --- tools/mkinstaller.py | 193 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100755 tools/mkinstaller.py diff --git a/tools/mkinstaller.py b/tools/mkinstaller.py new file mode 100755 index 00000000..8b63dcb5 --- /dev/null +++ b/tools/mkinstaller.py @@ -0,0 +1,193 @@ +#!/usr/bin/python +############################################################ +# +# Build an ONL Installer +# +############################################################ +import os +import sys +import argparse +import logging +import tempfile +import shutil +import subprocess + +NAME="mkinstaller" +logging.basicConfig() +logger = logging.getLogger(NAME) +logger.setLevel(logging.DEBUG) + +ONL = os.getenv('ONL') +if ONL is None: + logger.error("$ONL is not set.") + sys.exit(1) + +class InstallerShar(object): + def __init__(self, arch, template=None, work_dir=None): + self.ONL = ONL + + if template is None: + template = os.path.join(self.ONL, 'builds', 'any', 'installer', 'installer.sh.in') + if not os.path.exists(template): + self.abort("Template file '%s' is missing." % template) + + with open(template) as f: + self.template = f.read() + + if work_dir: + self.work_dir = work_dir + self.remove_work_dir = False + if os.path.exists(self.work_dir): + logger.info("Removing existing work tree @ %s" % self.work_dir) + shutil.rmtree(self.work_dir) + + else: + self.work_dir = tempfile.mkdtemp() + self.remove_work_dir = True + + if not os.path.isdir(self.work_dir): + os.makedirs(self.work_dir) + + self.files = [] + self.platforms = [] + self.arch = arch + + logger.info("Work Directory is %s" % self.work_dir) + + if self.arch == 'amd64': + self.setvar("ARCH", 'x86_64') + else: + self.setvar("ARCH", self.arch) + + def abort(self, msg): + logger.error(msg) + sys.exit(1) + + def find_file(self, package, filename): + return subprocess.check_output("onlpm --find-file %s %s" % (package, filename), shell=True).strip() + + def setvar(self, name, value): + self.template = self.template.replace("@%s@" % name, value) + + def add_initrd(self, package, filename, add_platforms=True): + self.initrd = self.find_file(package, filename) + self.add_file(self.initrd) + if add_platforms: + for platform in subprocess.check_output("onlpm --platform-manifest %s" % (package), shell=True).split(): + logger.info("Adding platform %s..." % platform) + kernel = subprocess.check_output([os.path.join(self.ONL, 'tools', 'onlplatform.py'), + platform, + self.arch, + 'kernel']).strip() + + logger.info("Platform %s using kernel %s..." % (platform, os.path.basename(kernel))) + self.add_file(kernel) + + self.setvar('INITRD_ARCHIVE', os.path.basename(self.initrd)) + self.setvar('INITRD_OFFSET', '') + self.setvar('INITRD_SIZE', '') + + + def add_fit(self, package, filename, add_platforms=True): + self.fit = self.find_file(package, filename) + VONL=os.path.join(self.ONL, "packages", "base", "all", "vendor-config-onl") + offsets = subprocess.check_output("PYTHONPATH=%s/src/python %s/src/bin/pyfit -v offset %s --initrd" % (VONL, VONL, self.fit), shell=True).split() + self.setvar('INITRD_ARCHIVE', os.path.basename(self.fit)) + self.setvar('INITRD_OFFSET', offsets[0]) + self.setvar('INITRD_SIZE', str(int(offsets[1]) - int(offsets[0]))) + self.add_file(self.fit) + + def add_file(self, filename): + if not os.path.exists(filename): + self.abort("File %s does not exist." % filename) + + logger.info("Adding file %s..." % os.path.basename(filename)) + self.files.append(filename) + self.files = list(set(self.files)) + + def add_swi(self, package): + edir = os.path.join(self.work_dir, "swidir") + subprocess.check_output('onlpm --extract-dir %s %s' % (package, edir), shell=True) + for (root, dirs, files) in os.walk(edir): + for f in files: + if f.endswith(".swi"): + self.add_file(os.path.join(root, f)) + + + def build(self, name): + + for f in self.files: + shutil.copy(f, self.work_dir) + + with open(os.path.join(self.work_dir, 'installer.sh'), "w") as f: + f.write(self.template) + f.write("PAYLOAD_FOLLOWS\n") + + with open(os.path.join(self.work_dir, "autoperms.sh"), "w") as f: + f.write("#!/bin/sh\n") + f.write("set -e\n") + f.write("set -x\n") + + + cwd = os.getcwd() + os.chdir(self.work_dir) + + mkshar = [ os.path.join(self.ONL, 'tools', 'mkshar'), + '--lazy', + '--unzip-pad', + '--fixup-perms', 'autoperms.sh', + name, + os.path.join(self.ONL, 'tools', 'scripts', 'sfx.sh.in'), + 'installer.sh', + ] + [ os.path.basename(f) for f in self.files ] + + subprocess.check_call(mkshar) + os.chdir(cwd) + + + + +if __name__ == '__main__': + + ap = argparse.ArgumentParser(NAME) + ap.add_argument("--arch", help="Installer Architecture.", required=True, + choices = ['amd64', 'powerpc', 'armel' ]) + ap.add_argument("--initrd", nargs=2, help="The system initrd.") + ap.add_argument("--fit", nargs=2, help="The system FIT image.") + ap.add_argument("--boot-config", help="The boot-config source.", required=True) + ap.add_argument("--swi", help="Include the given SWI in the installer.") + ap.add_argument("--work-dir", help="Set work directory and keep intermediates for debugging.") + ap.add_argument("--verbose", '-v', help="Verbose output.", action='store_true') + ap.add_argument("--out", help="Destination Filename") + + ops = ap.parse_args() + installer = InstallerShar(ops.arch, ops.work_dir) + + if ops.arch == 'amd64': + if ops.initrd is None: + logger.error("--initrd must be used with architecture %s" % ops.arch) + sys.exit(1) + if ops.fit: + logger.error("--fit cannot be used with architecture %s" % ops.arch) + sys.exit(1) + else: + if ops.fit is None: + logger.error("--fit must be used with architecture %s" % ops.arch) + sys.exit(1) + if ops.initrd: + logger.error("--initrd cannot be used with architecture %s" % ops.arch) + sys.exit(1) + + if ops.initrd: + installer.add_initrd(*ops.initrd) + if ops.fit: + installer.add_fit(*ops.fit) + + installer.add_file(ops.boot_config) + + if ops.swi: + installer.add_swi(ops.swi) + + iname = os.path.abspath(ops.out) + installer.build(iname) + logger.info("installer: %s" % iname) From 2a509d76082806b406240c1da380ce35023bd452 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 13 Jul 2016 18:14:43 +0000 Subject: [PATCH 70/87] Use ordered build. --- Makefile | 13 +++---------- builds/amd64/Makefile | 3 ++- builds/armel/Makefile | 3 ++- builds/powerpc/Makefile | 3 ++- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 96dab5a6..9a546102 100644 --- a/Makefile +++ b/Makefile @@ -21,9 +21,7 @@ onl-amd64 onl-x86 x86 x86_64 amd64: packages_base_all $(MAKE) -C packages/base/amd64/onlp $(MAKE) -C packages/base/amd64/onlp-snmpd $(MAKE) -C packages/base/amd64/faultd - $(MAKE) -C builds/amd64/rootfs - $(MAKE) -C builds/amd64/swi - $(MAKE) -C builds/amd64/installer + $(MAKE) -C builds/amd64 onl-ppc ppc: packages_base_all $(MAKE) -C packages/base/powerpc/kernels @@ -32,10 +30,7 @@ onl-ppc ppc: packages_base_all $(MAKE) -C packages/base/powerpc/onlp-snmpd $(MAKE) -C packages/base/powerpc/faultd $(MAKE) -C packages/base/powerpc/fit - $(MAKE) -C builds/powerpc/rootfs - $(MAKE) -C builds/powerpc/swi - $(MAKE) -C builds/powerpc/installer - + $(MAKE) -C builds/powerpc ifdef ONL_DEBIAN_SUITE_jessie @@ -49,9 +44,7 @@ onl-arm arm: arm_toolchain_check packages_base_all $(MAKE) -C packages/base/armel/onlp-snmpd $(MAKE) -C packages/base/armel/faultd $(MAKE) -C packages/base/armel/fit - $(MAKE) -C builds/armel/rootfs - $(MAKE) -C builds/armel/swi - $(MAKE) -C builds/armel/installer + $(MAKE) -C builds/armel else onl-arm arm: diff --git a/builds/amd64/Makefile b/builds/amd64/Makefile index 003238cf..92917844 100644 --- a/builds/amd64/Makefile +++ b/builds/amd64/Makefile @@ -1 +1,2 @@ -include $(ONL)/make/pkg.mk \ No newline at end of file +DIRECTORIES := rootfs swi installer +include $(ONL)/make/subdirs.mk diff --git a/builds/armel/Makefile b/builds/armel/Makefile index 003238cf..92917844 100644 --- a/builds/armel/Makefile +++ b/builds/armel/Makefile @@ -1 +1,2 @@ -include $(ONL)/make/pkg.mk \ No newline at end of file +DIRECTORIES := rootfs swi installer +include $(ONL)/make/subdirs.mk diff --git a/builds/powerpc/Makefile b/builds/powerpc/Makefile index 003238cf..92917844 100644 --- a/builds/powerpc/Makefile +++ b/builds/powerpc/Makefile @@ -1 +1,2 @@ -include $(ONL)/make/pkg.mk \ No newline at end of file +DIRECTORIES := rootfs swi installer +include $(ONL)/make/subdirs.mk From 137158ca1c6771391a449514a1b81167611ef683 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 13 Jul 2016 18:16:51 +0000 Subject: [PATCH 71/87] Add missing SWI option. --- builds/any/installer/grub/builds/Makefile | 2 +- builds/any/installer/uboot/builds/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builds/any/installer/grub/builds/Makefile b/builds/any/installer/grub/builds/Makefile index 068161b9..6caef35d 100644 --- a/builds/any/installer/grub/builds/Makefile +++ b/builds/any/installer/grub/builds/Makefile @@ -7,7 +7,7 @@ include $(ONL)/make/versions/version-onl.mk INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_INSTALLER __installer: - $(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --initrd onl-loader-initrd:$(ARCH) onl-loader-initrd-$(ARCH).cpio.gz --out $(INSTALLER_NAME) + $(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --initrd onl-loader-initrd:$(ARCH) onl-loader-initrd-$(ARCH).cpio.gz --swi onl-swi:$(ARCH) --out $(INSTALLER_NAME) md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum" diff --git a/builds/any/installer/uboot/builds/Makefile b/builds/any/installer/uboot/builds/Makefile index 79e73561..d6d8f84f 100644 --- a/builds/any/installer/uboot/builds/Makefile +++ b/builds/any/installer/uboot/builds/Makefile @@ -7,7 +7,7 @@ include $(ONL)/make/versions/version-onl.mk INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_INSTALLER __installer: - $(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --fit onl-loader-fit:$(ARCH) onl-loader-fit.itb --out $(INSTALLER_NAME) + $(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --fit onl-loader-fit:$(ARCH) onl-loader-fit.itb --swi onl-swi:$(ARCH) --out $(INSTALLER_NAME) md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum" From 3eea17f7a9d0d9fc2f4dcea482ac493f13946376 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 13 Jul 2016 22:58:00 +0000 Subject: [PATCH 72/87] Add new versions class interface. --- .../src/python/onl/versions/__init__.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 packages/base/all/vendor-config-onl/src/python/onl/versions/__init__.py diff --git a/packages/base/all/vendor-config-onl/src/python/onl/versions/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/versions/__init__.py new file mode 100644 index 00000000..08faa806 --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/python/onl/versions/__init__.py @@ -0,0 +1,37 @@ +import json + +class OnlVersionManifest(object): + def __init__(self, manifest): + self.version = json.load(open(manifest)) + + if 'version' in self.version: + self.version = self.version['version'] + + def __getattr__(self, name): + if name in self.version: + return self.version[name] + else: + raise AttributeError("version key '%s' does not exist." % name) + +class OnlVersionBase(OnlVersionManifest): + def __init__(self): + OnlVersionManifest.__init__(self, self.MANIFEST) + +class OnlRootfsVersion(OnlVersionBase): + MANIFEST='/etc/onl/rootfs/manifest.json' + +class OnlLoaderVersion(OnlVersionBase): + MANIFEST='/etc/onl/loader/manifest.json' + +# +# Expected usage: +# +# import onl.versions +# +# print onl.versions.rootfs.BUILD_TIMESTAMP +# + +rootfs = OnlRootfsVersion() +loader = OnlLoaderVersion() + + From 6ef54b1986684daf8c561a51c61f5d63e8eb0feb Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 14 Jul 2016 17:18:47 +0000 Subject: [PATCH 73/87] Improve context management. --- .../src/python/onl/pki/__init__.py | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py index f5c27b73..eec0f7fc 100755 --- a/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/pki/__init__.py @@ -17,25 +17,44 @@ from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContext from onl.sysconfig import sysconfig from onl.util import * + + +class OnlPkiContextReadWrite(OnlMountContextReadWrite): + def __init__(self, logger): + OnlMountContextReadWrite.__init__(self, "ONL-CONFIG", logger) + +class OnlPkiContextReadOnly(OnlMountContextReadOnly): + def __init__(self, logger): + OnlMountContextReadOnly.__init__(self, "ONL-CONFIG", logger) + + class OnlPki(OnlServiceMixin): """Initialize the ONL-CONFIG::PKI credentials.""" CONFIG_PKI_DIR="/mnt/onl/config/pki" - def __init__(self, logger): + def __init__(self, logger=None): self.logger = logger + + if self.logger is None: + self.logger = logging.getLogger("ONL:PKI") + self.kpath = os.path.join(self.CONFIG_PKI_DIR, sysconfig.pki.key.name) self.cpath = os.path.join(self.CONFIG_PKI_DIR, sysconfig.pki.cert.name) + def init(self, force=False): + self.init_key(force=force) + self.init_cert(force=force) + def init_key(self, force=False): - with OnlMountContextReadOnly("ONL-CONFIG", self.logger): + with OnlPkiContextReadOnly(self.logger): if not os.path.exists(self.kpath) or force: self.logger.info("Generating private key...") cmd = "openssl genrsa -out %s %s" % (self.kpath, sysconfig.pki.key.len) - with OnlMountContextReadWrite("ONL-CONFIG", self.logger): + with OnlPkiContextReadWrite(self.logger): if not os.path.isdir(self.CONFIG_PKI_DIR): os.makedirs(self.CONFIG_PKI_DIR) self._execute(cmd) @@ -44,7 +63,7 @@ class OnlPki(OnlServiceMixin): self.logger.info("Using existing private key.") def init_cert(self, force=False): - with OnlMountContextReadOnly("ONL-CONFIG", self.logger): + with OnlPkiContextReadOnly(self.logger): if not os.path.exists(self.cpath) or force: self.logger.info("Generating self-signed certificate...") csr = tempfile.NamedTemporaryFile(prefix="pki-", suffix=".csr", delete=False) @@ -53,7 +72,7 @@ class OnlPki(OnlServiceMixin): subject = "/" + "/".join(fields) self.logger.debug("Subject: '%s'", subject) self.logger.debug("CSR: %s", csr.name) - with OnlMountContextReadWrite("ONL-CONFIG", self.logger): + with OnlPkiContextReadWrite(self.logger): if not os.path.isdir(self.CONFIG_PKI_DIR): os.makedirs(self.CONFIG_PKI_DIR) self._execute("""openssl req -new -batch -subj "%s" -key %s -out %s""" % ( @@ -65,9 +84,6 @@ class OnlPki(OnlServiceMixin): else: self.logger.info("Using existing certificate.") - - - @staticmethod def main(): ap = argparse.ArgumentParser(description="ONL PKI Management") From a3b8906db393b92600193a83e8ec88e8806c77e3 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 14 Jul 2016 17:19:06 +0000 Subject: [PATCH 74/87] Clarify platform OID methods. --- .../src/python/onl/platform/base.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 fca8e0c5..1d9d5721 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 @@ -192,26 +192,26 @@ class OnlPlatformBase(object): # ONL Platform Information Tree - def platform_information_tree(self): + def platform_info_oid(self): return "1.3.6.1.4.1.42623.1.1" # ONL Platform Information General Tree - def opitg_oid(self): - return self.opit_oid() + ".1" + def platform_info_general_oid(self): + return self.platform_info_oid() + ".1" # ONL Platform Information General Sys Tree - def opitg_sys_oid(self): - return self.opitg_oid() + ".1" + def platform_info_general_sys_oid(self): + return self.platform_info_general_oid() + ".1" # ONL Platform Information Vendor Tree - def opitv_oid(self): - return self.opit_oid() + ".2" + def platform_info_vendor_oid(self): + return self.platform_info_oid() + ".2" def sys_oid_platform(self): raise Exception("sys_oid_platform() is not set.") def sys_object_id(self): - return "%s.%s%s" % (self.opitv_oid(), self.PRIVATE_ENTERPRISE_NUMBER, self.SYS_OBJECT_ID) + return "%s.%s%s" % (self.platform_info_vendor_oid(), self.PRIVATE_ENTERPRISE_NUMBER, self.SYS_OBJECT_ID) def onie_version(self): return self.onie_info.ONIE_VERSION From c575a267dc240ad1d1fcb1f7a9c819fe17c46268 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 14 Jul 2016 17:20:38 +0000 Subject: [PATCH 75/87] Make the upgrade status accessible. --- .../src/python/onl/upgrade/ubase.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 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 b9653815..52b39708 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 @@ -157,7 +157,7 @@ class BaseUpgrade(object): return default - UPGRADE_STATUS_JSON = "/lib/platform-config/current/upgrade.json" + UPGRADE_STATUS_JSON = "/lib/platform-config/current/onl/upgrade.json" def update_upgrade_status(self, key, value): data = {} @@ -168,7 +168,6 @@ class BaseUpgrade(object): 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() @@ -409,3 +408,13 @@ class BaseOnieUpgrade(BaseUpgrade): if os.path.exists(self.ONIE_UPDATER_PATH): self.logger.info("Removing previous onie-updater.") os.remove(self.ONIE_UPDATER_PATH) + + + +def upgrade_status(): + data = {} + if os.path.exists(BaseUpgrade.UPGRADE_STATUS_JSON): + with open(BaseUpgrade.UPGRADE_STATUS_JSON) as f: + data = json.load(f) + return data + From 1d878e046dd4d9b94c73a60cdc38bfd7e98405c8 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 14 Jul 2016 17:38:43 +0000 Subject: [PATCH 76/87] Return current environmental data in JSON --- .../all/vendor-config-onl/src/python/onl/platform/base.py | 6 ++++++ 1 file changed, 6 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 1d9d5721..39f50683 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 @@ -15,6 +15,7 @@ import os import re import yaml import onl.YamlUtils +import subprocess class OnlInfoObject(object): DEFAULT_INDENT=" " @@ -256,6 +257,11 @@ class OnlPlatformBase(object): # is ma1 and lo return 2 + def environment(self): + yamlstr = subprocess.check_output(['/bin/onlpd', '-r', '-y']) + data = yaml.load(yamlstr); + return json.dumps(data, indent=4) + def __str__(self): s = """Model: %s Manufacturer: %s From 80822e7f661f2e0d1aa41f873c0404ff73d6eeb7 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 14 Jul 2016 17:40:29 +0000 Subject: [PATCH 77/87] Return the current environmental data. --- .../base/all/vendor-config-onl/src/python/onl/platform/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 39f50683..1457f23c 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 @@ -260,7 +260,7 @@ class OnlPlatformBase(object): def environment(self): yamlstr = subprocess.check_output(['/bin/onlpd', '-r', '-y']) data = yaml.load(yamlstr); - return json.dumps(data, indent=4) + return data def __str__(self): s = """Model: %s From 147e638f7da867ffe22f0586f71f3a7ca690b21e Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 15 Jul 2016 08:02:04 -0700 Subject: [PATCH 78/87] Fix filesystem clean option. --- tools/onlrfs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/onlrfs.py b/tools/onlrfs.py index 8dedc172..00ab39d1 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -388,8 +388,8 @@ rm -f /usr/sbin/policy-rc.d logger.info("Cleaning Filesystem...") onlu.execute('sudo chroot %s /usr/bin/apt-get clean' % dir_) onlu.execute('sudo chroot %s /usr/sbin/localepurge' % dir_ ) - onlu.execute('sudo chroot %s find /usr/share/doc -type f | xargs rm -rf' % dir_) - onlu.execute('sudo chroot %s find /usr/share/man -type f | xargs rm -rf' % dir_) + onlu.execute('sudo chroot %s find /usr/share/doc -type f -delete' % dir_) + onlu.execute('sudo chroot %s find /usr/share/man -type f -delete' % dir_) if not options.get('securetty', True): From f095740c31fcb9a8f2f7c2f02968d3537ba286db Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 15 Jul 2016 15:50:38 +0000 Subject: [PATCH 79/87] Vendor configuration package for AlphaNetworks. --- packages/platforms/alphanetworks/vendor-config/Makefile | 1 + packages/platforms/alphanetworks/vendor-config/PKG.yml | 1 + .../vendor-config/src/python/alphanetworks/__init__.py | 7 +++++++ 3 files changed, 9 insertions(+) create mode 100644 packages/platforms/alphanetworks/vendor-config/Makefile create mode 100644 packages/platforms/alphanetworks/vendor-config/PKG.yml create mode 100644 packages/platforms/alphanetworks/vendor-config/src/python/alphanetworks/__init__.py diff --git a/packages/platforms/alphanetworks/vendor-config/Makefile b/packages/platforms/alphanetworks/vendor-config/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/alphanetworks/vendor-config/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/alphanetworks/vendor-config/PKG.yml b/packages/platforms/alphanetworks/vendor-config/PKG.yml new file mode 100644 index 00000000..a34897ad --- /dev/null +++ b/packages/platforms/alphanetworks/vendor-config/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/platform-config-vendor.yml VENDOR=alphanetworks Vendor=AlphaNetworks diff --git a/packages/platforms/alphanetworks/vendor-config/src/python/alphanetworks/__init__.py b/packages/platforms/alphanetworks/vendor-config/src/python/alphanetworks/__init__.py new file mode 100644 index 00000000..0aa964c8 --- /dev/null +++ b/packages/platforms/alphanetworks/vendor-config/src/python/alphanetworks/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/python + +from onl.platform.base import * + +class OnlPlatformAlphaNetworks(OnlPlatformBase): + MANUFACTURER='AlphaNetworks' + PRIVATE_ENTERPRISE_NUMBER=31874 From 03d7d9fad99e38ede25828b7f51366c2969bc224 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Fri, 15 Jul 2016 15:51:12 +0000 Subject: [PATCH 80/87] Initial packages for the SNX60A0-486F. --- .../.gitignore | 2 + .../Makefile | 1 + .../onlp/Makefile | 1 + .../onlp/PKG.yml | 1 + .../onlp/builds/Makefile | 2 + .../onlp/builds/lib/Makefile | 45 +++++++ ...bonlp-x86-64-alphanetworks-snx60a0-486f.mk | 10 ++ .../lib/x86_64_alphanetworks_snx60a0_486f.mk | 10 ++ .../onlp/builds/onlpdump/Makefile | 46 +++++++ .../x86_64_alphanetworks_snx60a0_486f/.module | 1 + .../Makefile | 9 ++ .../x86_64_alphanetworks_snx60a0_486f/README | 6 + .../module/auto/make.mk | 9 ++ .../x86_64_alphanetworks_snx60a0_486f.yml | 47 +++++++ .../x86_64_alphanetworks_snx60a0_486f.x | 14 ++ ...x86_64_alphanetworks_snx60a0_486f_config.h | 127 ++++++++++++++++++ .../x86_64_alphanetworks_snx60a0_486f_dox.h | 26 ++++ ...86_64_alphanetworks_snx60a0_486f_porting.h | 107 +++++++++++++++ .../module/make.mk | 10 ++ .../module/src/Makefile | 9 ++ .../module/src/make.mk | 9 ++ ...x86_64_alphanetworks_snx60a0_486f_config.c | 76 +++++++++++ .../x86_64_alphanetworks_snx60a0_486f_enums.c | 10 ++ .../x86_64_alphanetworks_snx60a0_486f_int.h | 12 ++ .../x86_64_alphanetworks_snx60a0_486f_log.c | 18 +++ .../x86_64_alphanetworks_snx60a0_486f_log.h | 12 ++ ...x86_64_alphanetworks_snx60a0_486f_module.c | 24 ++++ .../x86_64_alphanetworks_snx60a0_486f_ucli.c | 50 +++++++ .../utest/_make.mk | 8 ++ .../utest/main.c | 19 +++ .../x86_64_alphanetworks_snx60a0_486f.doxy | 0 .../x86_64_alphanetworks_snx60a0_486f.mk | 14 ++ .../platform-config/Makefile | 1 + .../platform-config/r0/Makefile | 1 + .../platform-config/r0/PKG.yml | 3 + .../x86-64-alphanetworks-snx60a0-486f-r0.yml | 25 ++++ .../__init__.py | 9 ++ 37 files changed, 774 insertions(+) create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/.gitignore create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/PKG.yml create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/libonlp-x86-64-alphanetworks-snx60a0-486f.mk create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/x86_64_alphanetworks_snx60a0_486f.mk create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/onlpdump/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/.module create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/README create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/make.mk create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/x86_64_alphanetworks_snx60a0_486f.yml create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.x create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_config.h create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_dox.h create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_porting.h create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/make.mk create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/make.mk create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_config.c create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_enums.c create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_int.h create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.c create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.h create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_module.c create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_ucli.c create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/_make.mk create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/main.c create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.doxy create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.mk create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/Makefile create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/PKG.yml create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/lib/x86-64-alphanetworks-snx60a0-486f-r0.yml create mode 100644 packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/python/x86_64_alphanetworks_snx60a0_486f_r0/__init__.py diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/.gitignore b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/.gitignore new file mode 100644 index 00000000..4d978b36 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/.gitignore @@ -0,0 +1,2 @@ +*x86*64*cel*redstone*xp*.mk +onlpdump.mk diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/PKG.yml b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/PKG.yml new file mode 100644 index 00000000..9233aee8 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/PKG.yml @@ -0,0 +1 @@ +!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-alphanetworks-snx60a0-486f ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/Makefile new file mode 100644 index 00000000..e7437cb2 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/Makefile @@ -0,0 +1,2 @@ +FILTER=src +include $(ONL)/make/subdirs.mk diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/Makefile new file mode 100644 index 00000000..87ec8e0d --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/Makefile @@ -0,0 +1,45 @@ +############################################################ +# +# +# Copyright 2014 BigSwitch Networks, Inc. +# +# Licensed under the Eclipse Public License, Version 1.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.eclipse.org/legal/epl-v10.html +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the +# License. +# +# +############################################################ +# +# +############################################################ +include $(ONL)/make/config.amd64.mk + +MODULE := libonlp-x86-64-alphanetworks-snx60a0-486f +include $(BUILDER)/standardinit.mk + +DEPENDMODULES := AIM IOF x86_64_alphanetworks_snx60a0_486f onlplib +DEPENDMODULE_HEADERS := sff + +include $(BUILDER)/dependmodules.mk + +SHAREDLIB := libonlp-x86-64-alphanetworks-snx60a0-486f.so +$(SHAREDLIB)_TARGETS := $(ALL_TARGETS) +include $(BUILDER)/so.mk +.DEFAULT_GOAL := $(SHAREDLIB) + +GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1 +GLOBAL_CFLAGS += -fPIC +GLOBAL_LINK_LIBS += -lpthread + +include $(BUILDER)/targets.mk + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/libonlp-x86-64-alphanetworks-snx60a0-486f.mk b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/libonlp-x86-64-alphanetworks-snx60a0-486f.mk new file mode 100644 index 00000000..f1efdbb6 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/libonlp-x86-64-alphanetworks-snx60a0-486f.mk @@ -0,0 +1,10 @@ + +############################################################################### +# +# Inclusive Makefile for the libonlp-x86-64-alphanetworks-snx60a0-486f module. +# +# Autogenerated 2016-07-15 15:27:29.712643 +# +############################################################################### +libonlp-x86-64-alphanetworks-snx60a0-486f_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/x86_64_alphanetworks_snx60a0_486f.mk b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/x86_64_alphanetworks_snx60a0_486f.mk new file mode 100644 index 00000000..bebc6e98 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/lib/x86_64_alphanetworks_snx60a0_486f.mk @@ -0,0 +1,10 @@ + +############################################################################### +# +# Inclusive Makefile for the x86_64_alphanetworks_snx60a0_486f module. +# +# Autogenerated 2016-07-15 15:27:29.728794 +# +############################################################################### +x86_64_alphanetworks_snx60a0_486f_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/onlpdump/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/onlpdump/Makefile new file mode 100644 index 00000000..7035ea16 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/onlpdump/Makefile @@ -0,0 +1,46 @@ +############################################################ +# +# +# Copyright 2014 BigSwitch Networks, Inc. +# +# Licensed under the Eclipse Public License, Version 1.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.eclipse.org/legal/epl-v10.html +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the +# License. +# +# +############################################################ +# +# +# +############################################################ +include $(ONL)/make/config.amd64.mk + +.DEFAULT_GOAL := onlpdump + +MODULE := onlpdump +include $(BUILDER)/standardinit.mk + +DEPENDMODULES := AIM IOF onlp x86_64_alphanetworks_snx60a0_486f onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS + +include $(BUILDER)/dependmodules.mk + +BINARY := onlpdump +$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS) +include $(BUILDER)/bin.mk + +GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1 +GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1 +GLOBAL_LINK_LIBS += -lpthread -lm + +include $(BUILDER)/targets.mk + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/.module b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/.module new file mode 100644 index 00000000..a41d2cfe --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/.module @@ -0,0 +1 @@ +name: x86_64_alphanetworks_snx60a0_486f diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/Makefile new file mode 100644 index 00000000..6ae7adde --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/Makefile @@ -0,0 +1,9 @@ +############################################################################### +# +# +# +############################################################################### +include $(ONL)/make/config.mk +MODULE := x86_64_alphanetworks_snx60a0_486f +AUTOMODULE := x86_64_alphanetworks_snx60a0_486f +include $(BUILDER)/definemodule.mk diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/README b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/README new file mode 100644 index 00000000..3f2b66d3 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/README @@ -0,0 +1,6 @@ +############################################################################### +# +# x86_64_alphanetworks_snx60a0_486f README +# +############################################################################### + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/make.mk b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/make.mk new file mode 100644 index 00000000..a6481dea --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/make.mk @@ -0,0 +1,9 @@ +############################################################################### +# +# x86_64_alphanetworks_snx60a0_486f Autogeneration +# +############################################################################### +x86_64_alphanetworks_snx60a0_486f_AUTO_DEFS := module/auto/x86_64_alphanetworks_snx60a0_486f.yml +x86_64_alphanetworks_snx60a0_486f_AUTO_DIRS := module/inc/x86_64_alphanetworks_snx60a0_486f module/src +include $(BUILDER)/auto.mk + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/x86_64_alphanetworks_snx60a0_486f.yml b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/x86_64_alphanetworks_snx60a0_486f.yml new file mode 100644 index 00000000..5a43e702 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/auto/x86_64_alphanetworks_snx60a0_486f.yml @@ -0,0 +1,47 @@ +############################################################################### +# +# x86_64_alphanetworks_snx60a0_486f Autogeneration Definitions. +# +############################################################################### + +cdefs: &cdefs +- X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING: + doc: "Include or exclude logging." + default: 1 +- X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT: + doc: "Default enabled log options." + default: AIM_LOG_OPTIONS_DEFAULT +- X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT: + doc: "Default enabled log bits." + default: AIM_LOG_BITS_DEFAULT +- X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT: + doc: "Default enabled custom log bits." + default: 0 +- X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB: + doc: "Default all porting macros to use the C standard libraries." + default: 1 +- X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS: + doc: "Include standard library headers for stdlib porting macros." + default: X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB +- X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI: + doc: "Include generic uCli support." + default: 0 + + +definitions: + cdefs: + X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_HEADER: + defs: *cdefs + basename: x86_64_alphanetworks_snx60a0_486f_config + + portingmacro: + X86_64_ALPHANETWORKS_SNX60A0_486F: + macros: + - malloc + - free + - memset + - memcpy + - strncpy + - vsnprintf + - snprintf + - strlen diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.x b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.x new file mode 100644 index 00000000..9c9a5a00 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.x @@ -0,0 +1,14 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* <--auto.start.xmacro(ALL).define> */ +/* */ + +/* <--auto.start.xenum(ALL).define> */ +/* */ + + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_config.h b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_config.h new file mode 100644 index 00000000..4e958ac0 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_config.h @@ -0,0 +1,127 @@ +/**************************************************************************//** + * + * @file + * @brief x86_64_alphanetworks_snx60a0_486f Configuration Header + * + * @addtogroup x86_64_alphanetworks_snx60a0_486f-config + * @{ + * + *****************************************************************************/ +#ifndef __X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_H__ +#define __X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_H__ + +#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG +#include +#endif +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_INCLUDE_CUSTOM_CONFIG +#include +#endif + +/* */ +#include +/** + * X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING + * + * Include or exclude logging. */ + + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING +#define X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING 1 +#endif + +/** + * X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT + * + * Default enabled log options. */ + + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT +#define X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT +#endif + +/** + * X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT + * + * Default enabled log bits. */ + + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT +#define X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT +#endif + +/** + * X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT + * + * Default enabled custom log bits. */ + + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT +#define X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT 0 +#endif + +/** + * X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB + * + * Default all porting macros to use the C standard libraries. */ + + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB +#define X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB 1 +#endif + +/** + * X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS + * + * Include standard library headers for stdlib porting macros. */ + + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS +#define X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB +#endif + +/** + * X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI + * + * Include generic uCli support. */ + + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI +#define X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI 0 +#endif + + + +/** + * All compile time options can be queried or displayed + */ + +/** Configuration settings structure. */ +typedef struct x86_64_alphanetworks_snx60a0_486f_config_settings_s { + /** name */ + const char* name; + /** value */ + const char* value; +} x86_64_alphanetworks_snx60a0_486f_config_settings_t; + +/** Configuration settings table. */ +/** x86_64_alphanetworks_snx60a0_486f_config_settings table. */ +extern x86_64_alphanetworks_snx60a0_486f_config_settings_t x86_64_alphanetworks_snx60a0_486f_config_settings[]; + +/** + * @brief Lookup a configuration setting. + * @param setting The name of the configuration option to lookup. + */ +const char* x86_64_alphanetworks_snx60a0_486f_config_lookup(const char* setting); + +/** + * @brief Show the compile-time configuration. + * @param pvs The output stream. + */ +int x86_64_alphanetworks_snx60a0_486f_config_show(struct aim_pvs_s* pvs); + +/* */ + +#include "x86_64_alphanetworks_snx60a0_486f_porting.h" + +#endif /* __X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_H__ */ +/* @} */ diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_dox.h b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_dox.h new file mode 100644 index 00000000..e4665cc6 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_dox.h @@ -0,0 +1,26 @@ +/**************************************************************************//** + * + * x86_64_alphanetworks_snx60a0_486f Doxygen Header + * + *****************************************************************************/ +#ifndef __X86_64_ALPHANETWORKS_SNX60A0_486F_DOX_H__ +#define __X86_64_ALPHANETWORKS_SNX60A0_486F_DOX_H__ + +/** + * @defgroup x86_64_alphanetworks_snx60a0_486f x86_64_alphanetworks_snx60a0_486f - x86_64_alphanetworks_snx60a0_486f Description + * + +The documentation overview for this module should go here. + + * + * @{ + * + * @defgroup x86_64_alphanetworks_snx60a0_486f-x86_64_alphanetworks_snx60a0_486f Public Interface + * @defgroup x86_64_alphanetworks_snx60a0_486f-config Compile Time Configuration + * @defgroup x86_64_alphanetworks_snx60a0_486f-porting Porting Macros + * + * @} + * + */ + +#endif /* __X86_64_ALPHANETWORKS_SNX60A0_486F_DOX_H__ */ diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_porting.h b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_porting.h new file mode 100644 index 00000000..b54775c1 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/inc/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f_porting.h @@ -0,0 +1,107 @@ +/**************************************************************************//** + * + * @file + * @brief x86_64_alphanetworks_snx60a0_486f Porting Macros. + * + * @addtogroup x86_64_alphanetworks_snx60a0_486f-porting + * @{ + * + *****************************************************************************/ +#ifndef __X86_64_ALPHANETWORKS_SNX60A0_486F_PORTING_H__ +#define __X86_64_ALPHANETWORKS_SNX60A0_486F_PORTING_H__ + + +/* */ +#if X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1 +#include +#include +#include +#include +#include +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_MALLOC + #if defined(GLOBAL_MALLOC) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_MALLOC GLOBAL_MALLOC + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_MALLOC malloc + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_MALLOC is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_FREE + #if defined(GLOBAL_FREE) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_FREE GLOBAL_FREE + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_FREE free + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_FREE is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_MEMSET + #if defined(GLOBAL_MEMSET) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_MEMSET GLOBAL_MEMSET + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_MEMSET memset + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_MEMSET is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_MEMCPY + #if defined(GLOBAL_MEMCPY) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_MEMCPY GLOBAL_MEMCPY + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_MEMCPY memcpy + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_MEMCPY is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_STRNCPY + #if defined(GLOBAL_STRNCPY) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_STRNCPY GLOBAL_STRNCPY + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_STRNCPY strncpy + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_STRNCPY is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_VSNPRINTF + #if defined(GLOBAL_VSNPRINTF) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_VSNPRINTF GLOBAL_VSNPRINTF + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_VSNPRINTF vsnprintf + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_VSNPRINTF is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_SNPRINTF + #if defined(GLOBAL_SNPRINTF) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_SNPRINTF GLOBAL_SNPRINTF + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_SNPRINTF snprintf + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_SNPRINTF is required but cannot be defined. + #endif +#endif + +#ifndef X86_64_ALPHANETWORKS_SNX60A0_486F_STRLEN + #if defined(GLOBAL_STRLEN) + #define X86_64_ALPHANETWORKS_SNX60A0_486F_STRLEN GLOBAL_STRLEN + #elif X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB == 1 + #define X86_64_ALPHANETWORKS_SNX60A0_486F_STRLEN strlen + #else + #error The macro X86_64_ALPHANETWORKS_SNX60A0_486F_STRLEN is required but cannot be defined. + #endif +#endif + +/* */ + + +#endif /* __X86_64_ALPHANETWORKS_SNX60A0_486F_PORTING_H__ */ +/* @} */ diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/make.mk b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/make.mk new file mode 100644 index 00000000..f4e72b01 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/make.mk @@ -0,0 +1,10 @@ +############################################################################### +# +# +# +############################################################################### +THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +x86_64_alphanetworks_snx60a0_486f_INCLUDES := -I $(THIS_DIR)inc +x86_64_alphanetworks_snx60a0_486f_INTERNAL_INCLUDES := -I $(THIS_DIR)src +x86_64_alphanetworks_snx60a0_486f_DEPENDMODULE_ENTRIES := init:x86_64_alphanetworks_snx60a0_486f ucli:x86_64_alphanetworks_snx60a0_486f + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/Makefile new file mode 100644 index 00000000..c1b65e94 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/Makefile @@ -0,0 +1,9 @@ +############################################################################### +# +# Local source generation targets. +# +############################################################################### + +ucli: + @../../../../tools/uclihandlers.py x86_64_alphanetworks_snx60a0_486f_ucli.c + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/make.mk b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/make.mk new file mode 100644 index 00000000..6f98ef96 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/make.mk @@ -0,0 +1,9 @@ +############################################################################### +# +# +# +############################################################################### + +LIBRARY := x86_64_alphanetworks_snx60a0_486f +$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(BUILDER)/lib.mk diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_config.c b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_config.c new file mode 100644 index 00000000..9f172282 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_config.c @@ -0,0 +1,76 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* */ +#define __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(_x) #_x +#define __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(_x) __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(_x) +x86_64_alphanetworks_snx60a0_486f_config_settings_t x86_64_alphanetworks_snx60a0_486f_config_settings[] = +{ +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING + { __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING), __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING) }, +#else +{ X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_LOGGING(__x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT + { __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT), __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT) }, +#else +{ X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT(__x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT + { __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT), __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT) }, +#else +{ X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT(__x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT + { __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT), __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT) }, +#else +{ X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT(__x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB + { __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB), __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB) }, +#else +{ X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_STDLIB(__x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS + { __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS), __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS) }, +#else +{ X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS(__x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME), "__undefined__" }, +#endif +#ifdef X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI + { __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI), __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE(X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI) }, +#else +{ X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI(__x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME), "__undefined__" }, +#endif + { NULL, NULL } +}; +#undef __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_VALUE +#undef __x86_64_alphanetworks_snx60a0_486f_config_STRINGIFY_NAME + +const char* +x86_64_alphanetworks_snx60a0_486f_config_lookup(const char* setting) +{ + int i; + for(i = 0; x86_64_alphanetworks_snx60a0_486f_config_settings[i].name; i++) { + if(strcmp(x86_64_alphanetworks_snx60a0_486f_config_settings[i].name, setting)) { + return x86_64_alphanetworks_snx60a0_486f_config_settings[i].value; + } + } + return NULL; +} + +int +x86_64_alphanetworks_snx60a0_486f_config_show(struct aim_pvs_s* pvs) +{ + int i; + for(i = 0; x86_64_alphanetworks_snx60a0_486f_config_settings[i].name; i++) { + aim_printf(pvs, "%s = %s\n", x86_64_alphanetworks_snx60a0_486f_config_settings[i].name, x86_64_alphanetworks_snx60a0_486f_config_settings[i].value); + } + return i; +} + +/* */ + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_enums.c b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_enums.c new file mode 100644 index 00000000..db93b1c3 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_enums.c @@ -0,0 +1,10 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +/* <--auto.start.enum(ALL).source> */ +/* */ + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_int.h b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_int.h new file mode 100644 index 00000000..6d28d252 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_int.h @@ -0,0 +1,12 @@ +/**************************************************************************//** + * + * x86_64_alphanetworks_snx60a0_486f Internal Header + * + *****************************************************************************/ +#ifndef __X86_64_ALPHANETWORKS_SNX60A0_486F_INT_H__ +#define __X86_64_ALPHANETWORKS_SNX60A0_486F_INT_H__ + +#include + + +#endif /* __X86_64_ALPHANETWORKS_SNX60A0_486F_INT_H__ */ diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.c b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.c new file mode 100644 index 00000000..433dcf4a --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.c @@ -0,0 +1,18 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#include "x86_64_alphanetworks_snx60a0_486f_log.h" +/* + * x86_64_alphanetworks_snx60a0_486f log struct. + */ +AIM_LOG_STRUCT_DEFINE( + X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_OPTIONS_DEFAULT, + X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_BITS_DEFAULT, + NULL, /* Custom log map */ + X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_LOG_CUSTOM_BITS_DEFAULT + ); + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.h b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.h new file mode 100644 index 00000000..fff31fe5 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_log.h @@ -0,0 +1,12 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#ifndef __X86_64_ALPHANETWORKS_SNX60A0_486F_LOG_H__ +#define __X86_64_ALPHANETWORKS_SNX60A0_486F_LOG_H__ + +#define AIM_LOG_MODULE_NAME x86_64_alphanetworks_snx60a0_486f +#include + +#endif /* __X86_64_ALPHANETWORKS_SNX60A0_486F_LOG_H__ */ diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_module.c b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_module.c new file mode 100644 index 00000000..aa08d3cc --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_module.c @@ -0,0 +1,24 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#include "x86_64_alphanetworks_snx60a0_486f_log.h" + +static int +datatypes_init__(void) +{ +#define X86_64_ALPHANETWORKS_SNX60A0_486F_ENUMERATION_ENTRY(_enum_name, _desc) AIM_DATATYPE_MAP_REGISTER(_enum_name, _enum_name##_map, _desc, AIM_LOG_INTERNAL); +#include + return 0; +} + +void __x86_64_alphanetworks_snx60a0_486f_module_init__(void) +{ + AIM_LOG_STRUCT_REGISTER(); + datatypes_init__(); +} + +int __onlp_platform_version__ = 1; diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_ucli.c b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_ucli.c new file mode 100644 index 00000000..a2327e08 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/module/src/x86_64_alphanetworks_snx60a0_486f_ucli.c @@ -0,0 +1,50 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#if X86_64_ALPHANETWORKS_SNX60A0_486F_CONFIG_INCLUDE_UCLI == 1 + +#include +#include +#include + +static ucli_status_t +x86_64_alphanetworks_snx60a0_486f_ucli_ucli__config__(ucli_context_t* uc) +{ + UCLI_HANDLER_MACRO_MODULE_CONFIG(x86_64_alphanetworks_snx60a0_486f) +} + +/* */ +/* */ + +static ucli_module_t +x86_64_alphanetworks_snx60a0_486f_ucli_module__ = + { + "x86_64_alphanetworks_snx60a0_486f_ucli", + NULL, + x86_64_alphanetworks_snx60a0_486f_ucli_ucli_handlers__, + NULL, + NULL, + }; + +ucli_node_t* +x86_64_alphanetworks_snx60a0_486f_ucli_node_create(void) +{ + ucli_node_t* n; + ucli_module_init(&x86_64_alphanetworks_snx60a0_486f_ucli_module__); + n = ucli_node_create("x86_64_alphanetworks_snx60a0_486f", NULL, &x86_64_alphanetworks_snx60a0_486f_ucli_module__); + ucli_node_subnode_add(n, ucli_module_log_node_create("x86_64_alphanetworks_snx60a0_486f")); + return n; +} + +#else +void* +x86_64_alphanetworks_snx60a0_486f_ucli_node_create(void) +{ + return NULL; +} +#endif + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/_make.mk b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/_make.mk new file mode 100644 index 00000000..1f9b2561 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/_make.mk @@ -0,0 +1,8 @@ +############################################################################### +# +# x86_64_alphanetworks_snx60a0_486f Unit Test Makefile. +# +############################################################################### +UMODULE := x86_64_alphanetworks_snx60a0_486f +UMODULE_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(BUILDER)/utest.mk diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/main.c b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/main.c new file mode 100644 index 00000000..e9fa4844 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/utest/main.c @@ -0,0 +1,19 @@ +/**************************************************************************//** + * + * + * + *****************************************************************************/ +#include + +#include +#include +#include +#include + +int aim_main(int argc, char* argv[]) +{ + printf("x86_64_alphanetworks_snx60a0_486f Utest Is Empty\n"); + x86_64_alphanetworks_snx60a0_486f_config_show(&aim_pvs_stdout); + return 0; +} + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.doxy b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.doxy new file mode 100644 index 00000000..e69de29b diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.mk b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.mk new file mode 100644 index 00000000..5652d605 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/onlp/builds/src/x86_64_alphanetworks_snx60a0_486f/x86_64_alphanetworks_snx60a0_486f.mk @@ -0,0 +1,14 @@ + +############################################################################### +# +# Inclusive Makefile for the x86_64_alphanetworks_snx60a0_486f module. +# +# Autogenerated 2016-07-15 15:47:05.304474 +# +############################################################################### +x86_64_alphanetworks_snx60a0_486f_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +include $(x86_64_alphanetworks_snx60a0_486f_BASEDIR)module/make.mk +include $(x86_64_alphanetworks_snx60a0_486f_BASEDIR)module/auto/make.mk +include $(x86_64_alphanetworks_snx60a0_486f_BASEDIR)module/src/make.mk +include $(x86_64_alphanetworks_snx60a0_486f_BASEDIR)utest/_make.mk + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/Makefile b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/PKG.yml b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/PKG.yml new file mode 100644 index 00000000..d3edd871 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/PKG.yml @@ -0,0 +1,3 @@ +!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=alphanetworks PLATFORM=x86-64-alphanetworks-snx60a0-486f-r0 + + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/lib/x86-64-alphanetworks-snx60a0-486f-r0.yml b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/lib/x86-64-alphanetworks-snx60a0-486f-r0.yml new file mode 100644 index 00000000..d55b1cc0 --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/lib/x86-64-alphanetworks-snx60a0-486f-r0.yml @@ -0,0 +1,25 @@ +--- + +###################################################################### +# +# platform-config for SNX60A0-486F +# +###################################################################### +x86-64-alphanetworks-snx60a0-486f-r0: + + grub: + + serial: >- + --port=0x3f8 + --speed=115200 + --word=8 + --parity=no + --stop=1 + + kernel: + <<: *kernel-3-2 + + args: >- + nopat + console=ttyS0,115200n8 + diff --git a/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/python/x86_64_alphanetworks_snx60a0_486f_r0/__init__.py b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/python/x86_64_alphanetworks_snx60a0_486f_r0/__init__.py new file mode 100644 index 00000000..f86ea0ce --- /dev/null +++ b/packages/platforms/alphanetworks/x86-64-alphanetworks-snx60a0-486f/platform-config/r0/src/python/x86_64_alphanetworks_snx60a0_486f_r0/__init__.py @@ -0,0 +1,9 @@ +from onl.platform.base import * +from onl.platform.alphanetworks import * + +class OnlPlatform_x86_64_alphanetworks_snx60a0_486f_r0(OnlPlatformAlphaNetworks, + OnlPlatformPortConfig_48x10_6x40): + PLATFORM='x86-64-alphanetworks-snx60a0-486f-r0' + MODEL="SNX-60A0-486F" + SYS_OBJECT_ID=".6000.486.1" + From 77c17d1c7c149833376bd46096e06578657bd0a2 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Mon, 18 Jul 2016 18:15:26 +0000 Subject: [PATCH 81/87] Fix i2c error detection. --- packages/base/any/onlp/src/onlplib/module/src/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/base/any/onlp/src/onlplib/module/src/i2c.c b/packages/base/any/onlp/src/onlplib/module/src/i2c.c index 3890a072..4340a6ea 100644 --- a/packages/base/any/onlp/src/onlplib/module/src/i2c.c +++ b/packages/base/any/onlp/src/onlplib/module/src/i2c.c @@ -142,7 +142,7 @@ onlp_i2c_read(int bus, uint8_t addr, uint8_t offset, int size, } for(i = 0; i < size; i++) { - uint32_t rv = i2c_smbus_read_byte_data(fd, offset+i); + int rv = i2c_smbus_read_byte_data(fd, offset+i); if(rv < 0) { AIM_LOG_ERROR("i2c-%d: reading address 0x%x, offset %d failed: %{errno}", bus, addr, offset+i, errno); @@ -175,7 +175,7 @@ onlp_i2c_write(int bus, uint8_t addr, uint8_t offset, int size, } for(i = 0; i < size; i++) { - uint32_t rv = i2c_smbus_write_byte_data(fd, offset+i, data[i]); + int rv = i2c_smbus_write_byte_data(fd, offset+i, data[i]); if(rv < 0) { AIM_LOG_ERROR("i2c-%d: writing address 0x%x, offset %d failed: %{errno}", bus, addr, offset+i, errno); From 705fd2f3cdcd978242772f1be19afb1cede1efb6 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 19 Jul 2016 14:35:03 +0000 Subject: [PATCH 82/87] Set default logger. --- .../all/vendor-config-onl/src/python/onl/mounts/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py index 67e166e7..f2b6f283 100755 --- a/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/mounts/__init__.py @@ -15,6 +15,8 @@ class MountManager(object): def __init__(self, logger): self.read_proc_mounts() self.logger = logger + if self.logger is None: + self.logger = logging.getLogger('onl:mounts') def read_proc_mounts(self): self.mounts = {} From b19ec2022773eebaf7cc7f41607ef553835174a0 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 19 Jul 2016 14:35:32 +0000 Subject: [PATCH 83/87] Boot-time package installation option. Packages present and listed in /mnt/onl/data/install-debs/list will be installed. This faciliates development and boot-patching of existing systems. --- packages/base/all/boot.d/src/53.install-debs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 packages/base/all/boot.d/src/53.install-debs diff --git a/packages/base/all/boot.d/src/53.install-debs b/packages/base/all/boot.d/src/53.install-debs new file mode 100755 index 00000000..e31d382d --- /dev/null +++ b/packages/base/all/boot.d/src/53.install-debs @@ -0,0 +1,16 @@ +#!/bin/sh +############################################################ +PACKAGE_DIR=/mnt/onl/data/install-debs +PACKAGE_LIST="$PACKAGE_DIR/list" + +if [ -e "$PACKAGE_LIST" ]; then + for package in $(cat $PACKAGE_LIST); do + echo "Installing packages $package..." + if ! dpkg -i "$PACKAGE_DIR/$package"; then + echo "Failed." + exit 1 + fi + done +fi + + From e87e30a31e0c18093b4cd06ce4baf52eb31b431e Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 19 Jul 2016 14:38:12 +0000 Subject: [PATCH 84/87] Fix user uid and gid generation. --- tools/onlrfs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/onlrfs.py b/tools/onlrfs.py index 00ab39d1..11251413 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -88,8 +88,10 @@ class OnlRfsSystemAdmin(object): def useradd(self, username, uid=None, gid=None, password=None, shell='/bin/bash', home=None, groups=None, sudo=False, deleteFirst=True): args = [ 'useradd', '--create-home' ] - if uid: + if uid is not None: args = args + [ '--non-unique', '--uid', str(uid) ] + if gid is not None: + args = args + [ '--gid', str(gid) ] if password: epassword=crypt.crypt(password, '$1$%s$' % self.gen_salt()); From be32b3baa728e177ac0720b0b49579199cfa9453 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Tue, 19 Jul 2016 15:33:34 +0000 Subject: [PATCH 85/87] Add gdb. --- builds/any/rootfs/jessie/common/all-base-packages.yml | 1 + builds/any/rootfs/wheezy/common/all-base-packages.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/builds/any/rootfs/jessie/common/all-base-packages.yml b/builds/any/rootfs/jessie/common/all-base-packages.yml index d41477b4..a43d1da1 100644 --- a/builds/any/rootfs/jessie/common/all-base-packages.yml +++ b/builds/any/rootfs/jessie/common/all-base-packages.yml @@ -75,3 +75,4 @@ - unzip - onl-mibs - openssl +- gdb diff --git a/builds/any/rootfs/wheezy/common/all-base-packages.yml b/builds/any/rootfs/wheezy/common/all-base-packages.yml index eb365075..fa007eec 100644 --- a/builds/any/rootfs/wheezy/common/all-base-packages.yml +++ b/builds/any/rootfs/wheezy/common/all-base-packages.yml @@ -74,3 +74,4 @@ - unzip - onl-mibs - openssl +- gdb From e67083e5b19b8aee376ddbb93ae745d27dc4cfa3 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 20 Jul 2016 15:48:41 -0700 Subject: [PATCH 86/87] Add image history for builder7:1.2 and builder8:1.3 --- docker/images/builder7/1.2/README | 2 ++ docker/images/builder7/1.2/history | 19 +++++++++++++++++++ docker/images/builder8/1.3/README | 2 ++ docker/images/builder8/1.3/history | 29 +++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 docker/images/builder7/1.2/README create mode 100644 docker/images/builder7/1.2/history create mode 100644 docker/images/builder8/1.3/README create mode 100644 docker/images/builder8/1.3/history diff --git a/docker/images/builder7/1.2/README b/docker/images/builder7/1.2/README new file mode 100644 index 00000000..cd082728 --- /dev/null +++ b/docker/images/builder7/1.2/README @@ -0,0 +1,2 @@ +The dockerfile for this image was lost. +The image history is present. diff --git a/docker/images/builder7/1.2/history b/docker/images/builder7/1.2/history new file mode 100644 index 00000000..43520a39 --- /dev/null +++ b/docker/images/builder7/1.2/history @@ -0,0 +1,19 @@ +IMAGE CREATED CREATED BY SIZE +30af21fbfb6f33404c14ffca74f5c4b6c2ea499afc3c6575ed8f8c4b250e9eb8 7 weeks ago /bin/sh -c #(nop) COPY file:85997e087b4d5e00e0a04bc193670e88f3c679ec6566c2578232f8771d2fa460 in /bin/container-id 245 B +f98ca0bcc821f3c29e55e3b04ac59f9d070884394a5bde7d08da2ea1f677dd42 7 weeks ago /bin/sh -c #(nop) COPY file:740656dd6897213f5de86c1bcab56a5cfb1bcef3b78fcfd9205997f03892c9cf in /bin/docker_shell 5.516 kB +c66fd0d67ccbe7adb1872e42fc001fc1e685d9d3f6906ad6c55a74e357fba5fe 7 weeks ago /bin/sh -c wget http://www.opennetlinux.org/tarballs/wheezy-usr-buildroot-toolchains-x86_64.tgz && tar -C / -xvzf wheezy-usr-buildroot-toolchains-x86_64.tgz && rm wheezy-usr-buildroot-toolchains-x86_64.tgz 232.5 MB +ef9ba8bae44eda8b581f3bf250c8d234b49ac9786861ee832dda20d360c1ef3b 7 weeks ago /bin/sh -c wget http://www.opennetlinux.org/tarballs/wheezy-usr-buildroot-toolchains-powerpc.tgz && tar -C / -xvzf wheezy-usr-buildroot-toolchains-powerpc.tgz && rm wheezy-usr-buildroot-toolchains-powerpc.tgz 206.4 MB +eade002eb617afb5e9f5973fe44cc7b0b6895a0f6ec994a6b4e59f181fbff541 7 weeks ago /bin/sh -c #(nop) MAINTAINER Jeffrey Townsend 0 B +f3f8c756d44cae02a081e8fa25fe699b62839367f84f3ed0c8cdac0d0cb61c71 5 months ago /bin/sh -c #(nop) COPY file:da995763fa1e4587d7dc435522b7b86c3f915fab6fc820983e694e9aa13996a9 in /bin/container-id 245 B +d3e2d8d3e6d0dfd2a2777bd4b5e4d4e7869c3795df33e718f25d1628d464a9d0 5 months ago /bin/sh -c #(nop) COPY file:102693745a139d309880bf2d29cbc9a19c08da85eab1df85b7bf9f6c8df6e51f in /bin/docker_shell 5.516 kB +758afffd3cf70037eba181d24c6bc80766c903951d80f1330994f348f342b2ff 5 months ago /bin/sh -c apt-get update && apt-get install -y libpcap-dev telnet gdb 167.8 MB +0cfd9081af7ec27350c53ee7b6a620bf430cbe773dd27d1f67b877c869edfb21 5 months ago /bin/sh -c #(nop) MAINTAINER Rob Sherwood 0 B +faaf7e26ce801e59638274f4fd1e6142cec53cfab98b523724c5e4b5e36d66ee 8 months ago /bin/sh -c #(nop) COPY file:9a22523afe2cf74d3d155f6c0abcc5e60eb02fbf3a8c0caf3bc31646e67b4a44 in /bin/container-id 245 B +9cc7bb19af34cc4782649727bd2f266ac58ac24b41e33ec44baffd58a6e7cae7 8 months ago /bin/sh -c #(nop) COPY file:2e453fbe7ebda297f827a3d6bd4803e5ea310b9531d6faeb9d5932016b152065 in /bin/docker_shell 5.075 kB +04a9de616cb5e1c1426736b1efb5d7e7c204230713cf6a85499586e601ee6b93 8 months ago /bin/sh -c ln -s /usr/bin/ar /usr/bin/x86_64-linux-gnu-ar && ln -s /usr/bin/ld /usr/bin/x86_64-linux-gnu-ld && ln -s /usr/bin/objcopy /usr/bin/x86_64-linux-gnu-objcopy 38 B +a520f12148816eb7d4cabd139dea1075ec20e6e9ab8c0271ec31d6f9c3d12d32 8 months ago /bin/sh -c cp /usr/include/linux/i2c-dev.h /usr/include/linux/i2c-devices.h && cp /usr/include/linux/i2c-dev.h /usr/powerpc-linux-gnu/include/linux/i2c-devices.h 21.16 kB +da6496888f80287d340259ae0e22b8e7de8325aaa0dfbcce033569e7ecc7ff10 8 months ago /bin/sh -c echo 'APT::Get::AllowUnauthenticated "true";\nAPT::Get::Assume-Yes "true";' | tee /etc/apt/apt.conf.d/99opennetworklinux && echo "deb http://apt.opennetlinux.org/debian/ unstable main" | tee /etc/apt/sources.list.d/opennetlinux.list && dpkg --add-architecture powerpc && apt-get update && apt-get install -y binutils-powerpc-linux-gnu=2.22-7.1 gcc-4.7-powerpc-linux-gnu libc6-dev-powerpc-cross libgomp1-powerpc-cross=4.7.2-4 && xapt -a powerpc libedit-dev ncurses-dev libsensors4-dev libwrap0-dev libssl-dev libsnmp-dev libevent-dev libpam-dev && update-alternatives --install /usr/bin/powerpc-linux-gnu-gcc powerpc-linux-gnu-gcc /usr/bin/powerpc-linux-gnu-gcc-4.7 10 && rm /etc/apt/apt.conf.d/docker-* && wget "https://launchpad.net/ubuntu/+source/qemu/1.4.0+dfsg-1expubuntu3/+build/4336762/+files/qemu-user-static_1.4.0%2Bdfsg-1expubuntu3_amd64.deb" && dpkg -i qemu-user-static_1.4.0+dfsg-1expubuntu3_amd64.deb && apt-get install python-pyroute2 274.2 MB +0c9fb97f33634b850ee1ed630cfc0eed2b0993377c7d3b19f60914a2f66f7c6e 8 months ago /bin/sh -c apt-get update && apt-get install -y apt apt-cacher-ng apt-file apt-utils autoconf automake1.9 autotools-dev bash-completion bc bind9-host binfmt-support binfmt-support bison bsdmainutils build-essential ccache cdbs cpio debhelper debhelper debhelper device-tree-compiler devscripts devscripts dialog dosfstools dpkg-sig emacs file flex gcc genisoimage ifupdown iproute iputils-ping kmod less libc6-dev libedit-dev libevent-dev libi2c-dev libpam-dev libsnmp-dev libtool locales lsof make mingetty mtd-utils mtools multistrap nano ncurses-dev netbase net-tools nfs-common openssh-server pkg-config pkg-config procps psmisc python python-dnspython python-yaml qemu qemu-user-static realpath realpath rsyslog rubygems screen squashfs-tools sshpass sudo syslinux texinfo=4.13a.dfsg.1-10 traceroute uboot-mkimage vim-tiny wget xapt zile zip && gem install --version 1.3.3 fpm 956.9 MB +8e0c035bb531a1311ab2e24f5b798edf89f20cd878ad4e1b8cf297b9b5afd410 9 months ago /bin/sh -c #(nop) MAINTAINER Rob Sherwood 0 B +bbe78c1a5a535fac669e3225d5c3bb4396b6b2f9decb560ffb6351396da8c345 11 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B +9d3ceacde91b4c7d6c1275032adb558d668afd5489c007f3512b39793ddf992d 11 months ago /bin/sh -c #(nop) ADD file:f7eb3ddd8c7f33332cd94564ec171306ffa490836953449b9b9c506085ec8745 in / 84.97 MB diff --git a/docker/images/builder8/1.3/README b/docker/images/builder8/1.3/README new file mode 100644 index 00000000..cd082728 --- /dev/null +++ b/docker/images/builder8/1.3/README @@ -0,0 +1,2 @@ +The dockerfile for this image was lost. +The image history is present. diff --git a/docker/images/builder8/1.3/history b/docker/images/builder8/1.3/history new file mode 100644 index 00000000..657c5ba5 --- /dev/null +++ b/docker/images/builder8/1.3/history @@ -0,0 +1,29 @@ +IMAGE CREATED CREATED BY SIZE +32155706d5a8ea8c642edaff8cf6ca93756c43f06b0df4ba6358fbd9b7241748 7 weeks ago /bin/sh -c #(nop) COPY file:64fe2c9e1b5e36e5a5dccdaf3f46ba7ca2894e6437f6d6c42efe0eb3ced9ab69 in /bin/container-id 245 B +da02890b2ba05440f2c7c1790ec9606c67ef946c1be1079652003ff47abc0683 7 weeks ago /bin/sh -c #(nop) COPY file:bbb3d40c93cd76b97c89e7bb34769a865d9ede5ce8311ad573125ae39a87f144 in /bin/docker_shell 5.516 kB +2a270cef9f88c6789cef1fc734edf02ea8fd7fc407a61a496d47d66fb776e3e1 7 weeks ago /bin/sh -c wget http://www.opennetlinux.org/tarballs/jessie-usr-buildroot-toolchains-arm.tgz && tar -C / -xvzf jessie-usr-buildroot-toolchains-arm.tgz && rm jessie-usr-buildroot-toolchains-arm.tgz 197.4 MB +f6bd6aa6112ff8e5f2f90392bb776e70f975a7c38ffa42363ad625e91d96ec87 7 weeks ago /bin/sh -c wget http://www.opennetlinux.org/tarballs/jessie-usr-buildroot-toolchains-x86_64.tgz && tar -C / -xvzf jessie-usr-buildroot-toolchains-x86_64.tgz && rm jessie-usr-buildroot-toolchains-x86_64.tgz 231.9 MB +460d6894f02cf961cb0ef04c37286eef20e302dda25caaeb9e8f31aca087cc05 7 weeks ago /bin/sh -c wget http://www.opennetlinux.org/tarballs/jessie-usr-buildroot-toolchains-powerpc.tgz && tar -C / -xvzf jessie-usr-buildroot-toolchains-powerpc.tgz && rm jessie-usr-buildroot-toolchains-powerpc.tgz 206.1 MB +2f1497573f9992b50dc67a588c64a4b142c60c19dc71476b29ed356cec23f657 3 months ago /bin/sh -c #(nop) MAINTAINER Jeffrey Townsend 0 B +dd52538e115b7afacd317aa629ae589640b563259c4dd3b0205141570b9e4fc0 3 months ago /bin/sh -c #(nop) COPY file:3ba8c73d2c1c05687b3a9ed061ce0ba68b3b3bcd3cc38d3b7872460ab20ef914 in /bin/container-id 245 B +1007bbaff6641c6f94b31bf8004d176a533fed98e02b1889d8546e2466de7685 3 months ago /bin/sh -c #(nop) COPY file:903a436a017d07edc14f3ad4155896e29fd20610cc268b25ef9dc566a2f67b67 in /bin/docker_shell 5.516 kB +2549711b6dfbd5c675cd06d04a0f90d77e4681cd0f15236aded81dad9becacf7 3 months ago /bin/sh -c xapt -a armel libedit-dev ncurses-dev libsensors4-dev libwrap0-dev libssl-dev libsnmp-dev 37.56 MB +d7b8911f99c278cce14adefb8739999022d588412cb5a48649dad01859f74d56 3 months ago /bin/sh -c apt-get update && apt-get install -y crossbuild-essential-armel gcc-arm-linux-gnueabi 450.9 MB +9d20ee8ab8a191f032def4397108e496f3d8c4823364b57296d115ad4183f27e 3 months ago /bin/sh -c dpkg --add-architecture armel 20 B +ffd59e478462bacdf142af97a881d5e23453e02d5d64c9b5cf8144f89e02d353 3 months ago /bin/sh -c #(nop) MAINTAINER Jeffrey Townsend 0 B +ad29f01f615f9477ed907ce7ff7dc4a55e0386e82614fcd134e0f6aca5b27c49 5 months ago /bin/sh -c #(nop) COPY file:841e3ae1b2e756363b64ba137881521b0e5e7dbe353fb76d62c967df8168092e in /bin/container-id 245 B +798fb45e3298c2a7fc374a17f4cd58148a6fb86f60e08a3e2ae0c227bc5c273e 5 months ago /bin/sh -c #(nop) COPY file:4c9660a24f51d28840aff28a6c89d7db3c6225c4bedbb9eebdf28a19e88551cd in /bin/docker_shell 5.516 kB +36b95e0bcd35619fdaab0de30fab19918347e53316657387d9c4ec8de4bc6cfd 5 months ago /bin/sh -c apt-get update && apt-get install -y libpcap-dev telnet gdb 263.9 MB +d1496c23e0ad410c13b466930f75ef98d5e23905791405da907f92808439831d 5 months ago /bin/sh -c #(nop) MAINTAINER Rob Sherwood 0 B +95d70986f9d6276424d3080d0d34f16a048bb0371580e3298d630b17dbe4609a 7 months ago /bin/sh -c apt-get install libboost-all-dev cmake 354.9 MB +ddb8d8aeac58a06f066bef825e6a27b0c72ff76835b0f571ad18a7c89bd93d40 7 months ago /bin/sh -c apt-get install -y libstdc++6=4.9.2-10 --force-yes 69.68 MB +09c7586cd496e865e594be70edfc83184f6e0552cb3ca9230c2f615331a93d68 7 months ago /bin/sh -c #(nop) COPY file:7cdbf54404b60a9d04a792bc0e9dcad6f49e612f48f8c6c402ee2dcf5688da69 in /bin/container-id 245 B +172f3bf0f3c43c34bd3303e6eb23359cc419831b8e6eac8ab90dd4b5aa600985 7 months ago /bin/sh -c #(nop) COPY file:77ace793edabe2a1c51ae29ff2eb52f6d6f46a86af4cf14cb2c413c0ff49d06e in /bin/docker_shell 5.075 kB +3c36ab092f6b85d75ffb756fad930b987fc8fbc8aa900dc22f01fedf7d202edc 7 months ago /bin/sh -c rm /etc/apt/apt.conf.d/docker-* && wget "https://launchpad.net/ubuntu/+source/qemu/1.4.0+dfsg-1expubuntu3/+build/4336762/+files/qemu-user-static_1.4.0%2Bdfsg-1expubuntu3_amd64.deb" && dpkg -i qemu-user-static_1.4.0+dfsg-1expubuntu3_amd64.deb 94.05 MB +cdb182045934be9bb9275ec8e9dcc7613594b8a91ab5e60a04b62d11e1c157be 7 months ago /bin/sh -c cp /usr/include/linux/i2c-dev.h /usr/include/linux/i2c-devices.h && cp /usr/include/linux/i2c-dev.h /usr/powerpc-linux-gnu/include/linux/i2c-devices.h 20.83 kB +9158d08b1793b1fc8a1d8e15bf19f23dc0fa13a1347a6c238225cb09f5e9e1d3 7 months ago /bin/sh -c echo 'APT::Get::AllowUnauthenticated "true";\nAPT::Get::Assume-Yes "true";' | tee /etc/apt/apt.conf.d/99opennetworklinux && echo "deb http://apt.opennetlinux.org/debian/ unstable main" | tee /etc/apt/sources.list.d/opennetlinux.list && curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | sudo apt-key add - && echo "deb http://emdebian.org/tools/debian/ jessie main" | tee /etc/apt/sources.list.d/embedian-jessie.list && dpkg --add-architecture powerpc && apt-get update && apt-get install -y binutils-powerpc-linux-gnu libc6-dev-powerpc-cross crossbuild-essential-powerpc cross-gcc-dev folly fbthrift wangle libgomp1-powerpc-cross && wget "http://ftp.us.debian.org/debian/pool/main/t/texinfo/texinfo_4.13a.dfsg.1-10_amd64.deb" && dpkg -i texinfo_4.13a.dfsg.1-10_amd64.deb && wget "http://ftp.us.debian.org/debian/pool/main/e/emdebian-crush/xapt_2.2.19_all.deb" && dpkg -i xapt_2.2.19_all.deb && xapt -a powerpc libedit-dev ncurses-dev libsensors4-dev libwrap0-dev libssl-dev libsnmp-dev 406 MB +49e279dabd91678fba86bd6687e6261a7b611f6e219648fff0a66bb933dc3c1d 7 months ago /bin/sh -c gem install --version 1.3.3 fpm 21.03 MB +49791c55ca44c73bf01888322bd5f020347b761c1c7f809c38301877a79d67af 7 months ago /bin/sh -c apt-get update && apt-get install -y apt apt-cacher-ng apt-file apt-utils autoconf automake autotools-dev bash-completion bc bind9-host binfmt-support binfmt-support bison bsdmainutils build-essential ccache cdbs cpio debhelper debhelper debhelper device-tree-compiler devscripts devscripts dialog dosfstools dpkg-sig emacs file flex gcc genisoimage git ifupdown iproute iputils-ping isolinux kmod less libc6-dev libcurl4-nss-dev libdouble-conversion-dev libedit-dev libevent-dev libgoogle-glog-dev libi2c-dev libkrb5-dev libnuma-dev libsasl2-dev libsnappy-dev libpam-dev libsnmp-dev libssl-dev libstdc++6=4.9.2-10 libtool locales lsof make mingetty mtd-utils mtools multistrap nano ncurses-dev netbase net-tools nfs-common openssh-server pkg-config pkg-config procps psmisc python python-debian python-dnspython python-yaml qemu qemu-user-static realpath realpath rsyslog ruby ruby-dev rubygems screen squashfs-tools sshpass sudo syslinux-utils traceroute u-boot-tools vim-tiny wget zile zip 1.213 GB +f6fd2198e086ea420c1b995d62c73f3626b25163b58c36fff23b1d33cba65476 9 months ago /bin/sh -c #(nop) MAINTAINER Rob Sherwood 0 B +58016a5acc80ae6bbee80c4c0ebf82fa0b17ad83a7c332b43420a5ac4daf1c78 9 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B +e2a4fb18da48c71baa73583c05c06ecf1a27486ea0ec08ca3458ddd4647a1894 9 months ago /bin/sh -c #(nop) ADD file:fd73312d29edb04f9cf107eb2488342984471d1798ea66ba6067f91d13f76fdf in / 125.2 MB From 06d5f3c1a46c2d4b3e56eafab10ff2ec077ef565 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Thu, 21 Jul 2016 09:39:39 -0700 Subject: [PATCH 87/87] Image 1.4: Update with ONIE build dependencies. --- docker/images/builder8/1.4/Dockerfile | 22 ++++++++++++++++++++++ docker/images/builder8/1.4/Makefile | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 docker/images/builder8/1.4/Dockerfile create mode 100644 docker/images/builder8/1.4/Makefile diff --git a/docker/images/builder8/1.4/Dockerfile b/docker/images/builder8/1.4/Dockerfile new file mode 100644 index 00000000..27550d56 --- /dev/null +++ b/docker/images/builder8/1.4/Dockerfile @@ -0,0 +1,22 @@ +############################################################ +# +# Update with ONIE build dependencies. +# +############################################################ +FROM opennetworklinux/builder8:1.3 +MAINTAINER Jeffrey Townsend + +RUN apt-get update && apt-get install -y \ + stgit \ + gperf \ + gawk \ + automake \ + libexpat1-dev \ + libtool-bin \ + xorriso + +# +# Docker shell and other container tools. +# +COPY docker_shell /bin/docker_shell +COPY container-id /bin/container-id diff --git a/docker/images/builder8/1.4/Makefile b/docker/images/builder8/1.4/Makefile new file mode 100644 index 00000000..994063cf --- /dev/null +++ b/docker/images/builder8/1.4/Makefile @@ -0,0 +1,19 @@ +VERSION=1.4 +USER=opennetworklinux +REPO=builder8 + +TOOLS=../../../tools/docker_shell ../../../tools/container-id + +build: check_version + cp $(TOOLS) . + docker build -t $(USER)/$(REPO):$(VERSION) . + rm -rf $(notdir $(TOOLS)) + +# +# Todo: Query remote repository to see if the request version already exists to avoid accidental overwrites +# when a new image is built but the VERSION variable is not updated. +# +check_version: + +push: + docker push $(USER)/$(REPO):$(VERSION)