mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-28 02:34:59 +00:00
Merge branch 'master' of github.com:opencomputeproject/OpenNetworkLinux
This commit is contained in:
@@ -1,2 +1 @@
|
||||
DIRECTORIES := rootfs swi installer
|
||||
include $(ONL)/make/subdirs.mk
|
||||
include $(ONL)/make/arch-build.mk
|
||||
|
||||
@@ -10,6 +10,7 @@ common:
|
||||
version: 0.$FNAME_RELEASE_ID
|
||||
copyright: Copyright 2016 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-installer-$BOOTMODE
|
||||
|
||||
@@ -10,8 +10,20 @@ endif
|
||||
include $(ONL)/make/versions/version-onl.mk
|
||||
INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_$(BOOTMODE)_INSTALLER
|
||||
|
||||
MKINSTALLER_OPTS = \
|
||||
--arch $(ARCH) \
|
||||
--boot-config boot-config \
|
||||
--add-dir config \
|
||||
--initrd onl-loader-initrd:$(ARCH) onl-loader-initrd-$(ARCH).cpio.gz \
|
||||
--swi onl-swi:$(ARCH) \
|
||||
--preinstall-script $(ONL)/builds/any/installer/sample-preinstall.sh \
|
||||
--postinstall-script $(ONL)/builds/any/installer/sample-postinstall.sh \
|
||||
--plugin $(ONL)/builds/any/installer/sample-preinstall.py \
|
||||
--plugin $(ONL)/builds/any/installer/sample-postinstall.py \
|
||||
# THIS LINE INTENTIONALLY LEFT BLANK
|
||||
|
||||
__installer:
|
||||
$(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --add-dir config --initrd onl-loader-initrd:$(ARCH) onl-loader-initrd-$(ARCH).cpio.gz --swi onl-swi:$(ARCH) --out $(INSTALLER_NAME)
|
||||
$(ONL)/tools/mkinstaller.py $(MKINSTALLER_OPTS) --out $(INSTALLER_NAME)
|
||||
md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum"
|
||||
|
||||
|
||||
|
||||
@@ -361,16 +361,44 @@ else
|
||||
installer_list=$initrd_archive
|
||||
fi
|
||||
|
||||
installer_unzip() {
|
||||
local zip tmp dummy
|
||||
zip=$1; shift
|
||||
|
||||
installer_say "Extracting from $zip: $@ ..."
|
||||
|
||||
tmp=$(mktemp -d -t "unzip-XXXXXX")
|
||||
if test "$SFX_PAD"; then
|
||||
# ha ha, busybox cannot exclude multiple files
|
||||
unzip -o $zip "$@" -x $SFX_PAD -d $tmp
|
||||
elif test "$SFX_UNZIP"; then
|
||||
unzip -o $zip "$@" -x $installer_script -d $tmp
|
||||
else
|
||||
dd if=$zip bs=$SFX_BLOCKSIZE skip=$SFX_BLOCKS \
|
||||
| unzip -o - "$@" -x $installer_script -d $tmp
|
||||
fi
|
||||
|
||||
rm -f $tmp/$installer_script
|
||||
if test "$SFX_PAD"; then
|
||||
rm -f $tmp/$SFX_PAD
|
||||
fi
|
||||
|
||||
set dummy $tmp/*
|
||||
if test -e "$2"; then
|
||||
shift
|
||||
while test $# -gt 0; do
|
||||
mv "$1" .
|
||||
shift
|
||||
done
|
||||
else
|
||||
installer_say "Extracting from $zip: no files extracted"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
installer_say "Unpacking ONL installer files..."
|
||||
if test "$SFX_PAD"; then
|
||||
# ha ha, busybox cannot exclude multiple files
|
||||
unzip -o $installer_zip $installer_list -x $SFX_PAD
|
||||
elif test "$SFX_UNZIP"; then
|
||||
unzip -o $installer_zip $installer_list -x $installer_script
|
||||
else
|
||||
dd if=$installer_zip bs=$SFX_BLOCKSIZE skip=$SFX_BLOCKS \
|
||||
| unzip -o - $installer_list -x $installer_script
|
||||
fi
|
||||
installer_unzip $installer_zip $installer_list
|
||||
|
||||
# Developer debugging
|
||||
if has_boot_env onl_installer_unpack_only; then installer_unpack_only=1; fi
|
||||
@@ -513,6 +541,13 @@ else
|
||||
installer_say "*** watch out for lingering mount-points"
|
||||
fi
|
||||
|
||||
installer_unzip $installer_zip preinstall.sh || :
|
||||
if test -f preinstall.sh; then
|
||||
installer_say "Invoking pre-install actions"
|
||||
chmod +x preinstall.sh
|
||||
./preinstall.sh $rootdir
|
||||
fi
|
||||
|
||||
chroot "${rootdir}" $installer_shell
|
||||
|
||||
if test -f "$postinst"; then
|
||||
@@ -522,6 +557,12 @@ if test -f "$postinst"; then
|
||||
set +x
|
||||
fi
|
||||
|
||||
installer_unzip $installer_zip postinstall.sh || :
|
||||
if test -f preinstall.sh; then
|
||||
chmod +x postinstall.sh
|
||||
./postinstall.sh $rootdir
|
||||
fi
|
||||
|
||||
trap - 0 1
|
||||
installer_umount
|
||||
|
||||
|
||||
71
builds/any/installer/sample-postinstall.py
Normal file
71
builds/any/installer/sample-postinstall.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""sample-postinstall.py
|
||||
|
||||
Example Python script for post-install hooks.
|
||||
|
||||
Add this as a postinstall hook to your installer via
|
||||
the 'mkinstaller.py' command line:
|
||||
|
||||
$ mkinstaller.py ... --plugin sample-postinstall.py ...
|
||||
|
||||
At install time, this script will
|
||||
|
||||
1. be extracted into a temporary working directory
|
||||
2. be imported as a module, in the same process as the installer
|
||||
script
|
||||
|
||||
Importing the module should not trigger any side-effects.
|
||||
|
||||
At the appropriate time during the install (a chrooted invocation
|
||||
of the installer Python script) will
|
||||
|
||||
1. scrape the top-level plugin's namespace for subclasses of
|
||||
onl.install.Plugin.Plugin.
|
||||
Implementors should declare classes here
|
||||
(inheriting from onl.install.Plugin.Plugin) to embed the plugin
|
||||
functionality.
|
||||
2. instantiate an instance of each class, with the installer
|
||||
object initialized as the 'installer' attribute
|
||||
3. invoke the 'run' method (which must be overridden by implementors)
|
||||
For a post-install plugin, the 'mode' argument is set to
|
||||
PLUGIN_POSTINSTALL.
|
||||
4. invoke the 'shutdown' method (by default, a no-op)
|
||||
|
||||
The 'run' method should return zero on success. In any other case, the
|
||||
installer terminates.
|
||||
|
||||
The post-install plugins are invoked after the installer is complete
|
||||
and after the boot loader is updated.
|
||||
|
||||
An exception to this is for proxy GRUB configurations. In that case, the
|
||||
post-install plugins are invoked after the install is finished, but before
|
||||
the boot loader has been updated.
|
||||
|
||||
At the time the post-install plugin is invoked, none of the
|
||||
filesystems are mounted. If the implementor needs to manipulate the
|
||||
disk, the filesystems should be re-mounted temporarily with
|
||||
e.g. MountContext. The OnlMountContextReadWrite object and their
|
||||
siblings won't work here because the mtab.yml file is not populated
|
||||
within the loader environment.
|
||||
|
||||
A post-install plugin should execute any post-install actions when
|
||||
'mode' is set to PLUGIN_POSTINSTALL. If 'mode' is set to any other
|
||||
value, the plugin should ignore it and return zero. The plugin run()
|
||||
method is invoked multiple times during the installer with different
|
||||
values of 'mode'. The 'shutdown()' method is called only once.
|
||||
|
||||
When using MountContxt, the system state in the installer object can help
|
||||
(self.installer.blkidParts in particular).
|
||||
|
||||
"""
|
||||
|
||||
import onl.install.Plugin
|
||||
|
||||
class Plugin(onl.install.Plugin.Plugin):
|
||||
|
||||
def run(self, mode):
|
||||
|
||||
if mode == self.PLUGIN_POSTINSTALL:
|
||||
self.log.info("hello from postinstall plugin")
|
||||
return 0
|
||||
|
||||
return 0
|
||||
42
builds/any/installer/sample-postinstall.sh
Normal file
42
builds/any/installer/sample-postinstall.sh
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
######################################################################
|
||||
#
|
||||
# sample-postinstall.sh
|
||||
#
|
||||
# Example script for post-install hooks.
|
||||
#
|
||||
# Add this as a postinstall hook to your installer via
|
||||
# the 'mkinstaller.py' command line:
|
||||
#
|
||||
# $ mkinstaller.py ... --postinstall-script sample-postinstall.sh ...
|
||||
#
|
||||
# At install time, this script will
|
||||
#
|
||||
# 1. be extracted into the working directory with the other installer
|
||||
# collateral
|
||||
# 2. have the execute bit set
|
||||
# 3. run in-place with the installer chroot directory passed
|
||||
# as the first command line parameter
|
||||
#
|
||||
# If the script fails (returns a non-zero exit code) then
|
||||
# the install is aborted.
|
||||
#
|
||||
# This script is executed using the ONIE runtime (outside the chroot),
|
||||
# after the actual installer (chrooted Python script) has finished.
|
||||
#
|
||||
# This script is run after the postinstall actions (e.g. proxy GRUB
|
||||
# commands)
|
||||
#
|
||||
# At the time the script is run, the installer environment (chroot)
|
||||
# is fully prepared, including filesystem mount-points.
|
||||
# That is, the chroot mount points have not been unmounted yet.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
rootdir=$1; shift
|
||||
|
||||
echo "Hello from postinstall"
|
||||
echo "Chroot is $rootdir"
|
||||
|
||||
exit 0
|
||||
61
builds/any/installer/sample-preinstall.py
Normal file
61
builds/any/installer/sample-preinstall.py
Normal file
@@ -0,0 +1,61 @@
|
||||
"""sample-preinstall.py
|
||||
|
||||
Example Python script for pre-install hooks.
|
||||
|
||||
Add this as a preinstall hook to your installer via
|
||||
the 'mkinstaller.py' command line:
|
||||
|
||||
$ mkinstaller.py ... --plugin sample-preinstall.py ...
|
||||
|
||||
At install time, this script will
|
||||
|
||||
1. be extracted into a temporary working directory
|
||||
2. be imported as a module, in the same process as the installer
|
||||
script
|
||||
|
||||
Importing the module should not trigger any side-effects.
|
||||
|
||||
At the appropriate time during the install (a chrooted invocation
|
||||
of the installer Python script) will
|
||||
|
||||
1. scrape the top-level plugin's namespace for subclasses of
|
||||
onl.install.Plugin.Plugin.
|
||||
Implementors should declare classes here
|
||||
(inheriting from onl.install.Plugin.Plugin) to embed the plugin
|
||||
functionality.
|
||||
2. instantiate an instance of each class, with the installer
|
||||
object initialized as the 'installer' attribute
|
||||
3. invoke the 'run' method (which must be overridden by implementors)
|
||||
For a pre-install plugin, the 'mode' argument is set to
|
||||
PLUGIN_PREINSTALL.
|
||||
4. invoke the 'shutdown' method (by default, a no-op)
|
||||
|
||||
The 'run' method should return zero on success. In any other case, the
|
||||
installer terminates.
|
||||
|
||||
The 'installer' object has a handle onto the installer ZIP archive
|
||||
(self.installer.zf) but otherwise the install has not been
|
||||
started. That is, the install disk has not been
|
||||
prepped/initialized/scanned yet. As per the ONL installer API, the
|
||||
installer starts with *no* filesystems mounted, not even the ones from
|
||||
a prior install.
|
||||
|
||||
A pre-install plugin should execute any pre-install actions when
|
||||
'mode' is set to PLUGIN_PREINSTALL. If 'mode' is set to any other
|
||||
value, the plugin should ignore it and return zero. The plugin run()
|
||||
method is invoked multiple times during the installer with different
|
||||
values of 'mode'. The 'shutdown()' method is called only once.
|
||||
|
||||
"""
|
||||
|
||||
import onl.install.Plugin
|
||||
|
||||
class Plugin(onl.install.Plugin.Plugin):
|
||||
|
||||
def run(self, mode):
|
||||
|
||||
if mode == self.PLUGIN_PREINSTALL:
|
||||
self.log.info("hello from preinstall plugin")
|
||||
return 0
|
||||
|
||||
return 0
|
||||
38
builds/any/installer/sample-preinstall.sh
Normal file
38
builds/any/installer/sample-preinstall.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
######################################################################
|
||||
#
|
||||
# sample-preinstall.sh
|
||||
#
|
||||
# Example script for pre-install hooks.
|
||||
#
|
||||
# Add this as a preinstall hook to your installer via
|
||||
# the 'mkinstaller.py' command line:
|
||||
#
|
||||
# $ mkinstaller.py ... --preinstall-script sample-preinstall.sh ...
|
||||
#
|
||||
# At install time, this script will
|
||||
#
|
||||
# 1. be extracted into the working directory with the other installer
|
||||
# collateral
|
||||
# 2. have the execute bit set
|
||||
# 3. run in-place with the installer chroot directory passed
|
||||
# as the first command line parameter
|
||||
#
|
||||
# If the script fails (returns a non-zero exit code) then
|
||||
# the install is aborted.
|
||||
#
|
||||
# This script is executed using the ONIE runtime (outside the chroot),
|
||||
# before the actual installer (chrooted Python script)
|
||||
#
|
||||
# At the time the script is run, the installer environment (chroot)
|
||||
# has been fully prepared, including filesystem mount-points.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
rootdir=$1; shift
|
||||
|
||||
echo "Hello from preinstall"
|
||||
echo "Chroot is $rootdir"
|
||||
|
||||
exit 0
|
||||
@@ -10,8 +10,20 @@ endif
|
||||
include $(ONL)/make/versions/version-onl.mk
|
||||
INSTALLER_NAME=$(FNAME_PRODUCT_VERSION)_ONL-OS_$(FNAME_BUILD_ID)_$(UARCH)_$(BOOTMODE)_INSTALLER
|
||||
|
||||
MKINSTALLER_OPTS = \
|
||||
--arch $(ARCH) \
|
||||
--boot-config boot-config \
|
||||
--add-dir config \
|
||||
--fit onl-loader-fit:$(ARCH) onl-loader-fit.itb \
|
||||
--swi onl-swi:$(ARCH) \
|
||||
--preinstall-script $(ONL)/builds/any/installer/sample-preinstall.sh \
|
||||
--postinstall-script $(ONL)/builds/any/installer/sample-postinstall.sh \
|
||||
--plugin $(ONL)/builds/any/installer/sample-preinstall.py \
|
||||
--plugin $(ONL)/builds/any/installer/sample-postinstall.py \
|
||||
# THIS LINE INTENTIONALLY LEFT BLANK
|
||||
|
||||
__installer:
|
||||
$(ONL)/tools/mkinstaller.py --arch $(ARCH) --boot-config boot-config --add-dir config --fit onl-loader-fit:$(ARCH) onl-loader-fit.itb --swi onl-swi:$(ARCH) --out $(INSTALLER_NAME)
|
||||
$(ONL)/tools/mkinstaller.py $(MKINSTALLER_OPTS) --out $(INSTALLER_NAME)
|
||||
md5sum "$(INSTALLER_NAME)" | awk '{ print $$1 }' > "$(INSTALLER_NAME).md5sum"
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ common:
|
||||
version: 0.$FNAME_RELEASE_ID
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-rootfs
|
||||
|
||||
@@ -77,3 +77,4 @@
|
||||
- gdb
|
||||
- tcpdump
|
||||
- strace
|
||||
- sysstat
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
- smartmontools
|
||||
- grub2
|
||||
- onl-upgrade
|
||||
- kexec-tools
|
||||
|
||||
|
||||
|
||||
|
||||
- hw-management
|
||||
- sx-kernel
|
||||
- onl-kernel-3.16-lts-x86-64-all-modules
|
||||
- onl-kernel-3.2-deb7-x86-64-all-modules
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
- u-boot-tools
|
||||
- kexec-tools
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#
|
||||
############################################################
|
||||
- u-boot-tools
|
||||
- kexec-tools
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
- pciutils
|
||||
- usbutils
|
||||
- mtd-utils
|
||||
- kexec-tools
|
||||
- i2c-tools
|
||||
- module-init-tools
|
||||
- isc-dhcp-client
|
||||
@@ -77,3 +76,4 @@
|
||||
- gdb
|
||||
- tcpdump
|
||||
- strace
|
||||
- sysstat
|
||||
|
||||
@@ -69,8 +69,6 @@ Configure:
|
||||
- 'nfs-common remove'
|
||||
- 'rpcbind remove'
|
||||
- 'motd remove'
|
||||
- 'kexec remove'
|
||||
- 'kexec-load remove'
|
||||
- 'mountall-bootclean.sh remove'
|
||||
- 'mountall.sh remove'
|
||||
- 'checkfs.sh remove'
|
||||
|
||||
@@ -10,6 +10,7 @@ common:
|
||||
version: 0.$FNAME_RELEASE_ID
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-swi
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
DIRECTORIES := rootfs swi installer
|
||||
include $(ONL)/make/subdirs.mk
|
||||
include $(ONL)/make/arch-build.mk
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
DIRECTORIES := rootfs swi installer
|
||||
include $(ONL)/make/subdirs.mk
|
||||
include $(ONL)/make/arch-build.mk
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
DIRECTORIES := rootfs swi installer
|
||||
include $(ONL)/make/subdirs.mk
|
||||
include $(ONL)/make/arch-build.mk
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
common:
|
||||
arch: all
|
||||
version: 1.1.0
|
||||
version: 1.3.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-docker-tools
|
||||
|
||||
@@ -20,7 +20,7 @@ g_timestamp = datetime.datetime.now().strftime("%Y-%m-%d.%H%M%S")
|
||||
g_builder7_image_name="opennetworklinux/builder7:1.2"
|
||||
g_builder8_image_name="opennetworklinux/builder8:1.5"
|
||||
|
||||
g_default_image_name=g_builder7_image_name
|
||||
g_default_image_name=g_builder8_image_name
|
||||
g_default_container_name = "%s_%s" % (g_current_user, g_timestamp)
|
||||
g_default_user="%s:%s" % (g_current_user, g_current_uid)
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ Quanta
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="info">
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> ORC <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
</thead>
|
||||
<tr> <td> QuantaMesh T1048-LB9 <td> 48x1G + 4x10G <td> FreeScale P2020 <td> Broadcom BCM56534 (Firebolt3) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> QuantaMesh T3048-LY2 <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56846 (Trident+) <td> Yes <td> Yes <td> Yes <td> Yes <td> No <td> No </tr>
|
||||
<tr> <td> QuantaMesh T3048-LY8 <td> 48x10G + 6x40G <td> Intel Rangeley C2758 x86 <td> Broadcom BCM56854 (Trident2) <td> Yes* <td> No <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> QuantaMesh T5032-LY6 <td> 32x40G <td> Intel Rangeley C2758 x86 <td> Broadcom BCM56850 (Trident2) <td> Yes* <td> No <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> QuantaMesh T1048-LB9 <td> 48x1G + 4x10G <td> FreeScale P2020 <td> Broadcom BCM56534 (Firebolt3) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> QuantaMesh T3048-LY2 <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56846 (Trident+) <td> Yes <td> Yes <td> Yes <td> No <td> No </tr>
|
||||
<tr> <td> QuantaMesh T3048-LY8 <td> 48x10G + 6x40G <td> Intel Rangeley C2758 x86 <td> Broadcom BCM56854 (Trident2) <td> Yes* <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> QuantaMesh T5032-LY6 <td> 32x40G <td> Intel Rangeley C2758 x86 <td> Broadcom BCM56850 (Trident2) <td> Yes* <td> No <td> No <td> No <td> No </tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -23,24 +23,24 @@ Accton/Edge-Core
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="info">
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> ORC <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
</thead>
|
||||
<tr> <td> Accton AS4600-54T <td> 48x1G + 4x10G <td> FreeScale P2020 <td> Broadcom BCM56540 (Apollo2) <td> Yes <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS4610-54P <td> 48x1G + 4x10G + 2x20G <td> Dual-core ARM Cortex A9 1GHz <td> Broadcom BCM56340 (Helix4) <td> Yes <td> Yes <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5600-52X <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56846 (Trident+) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5610-52X <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56846 (Trident+) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5710-54X <td> 48x10G + 6x40G <td> FreeScale P2041 <td> Broadcom BCM56854 (Trident2) <td> Yes <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS6700-32X <td> 32x40G <td> FreeScale P2041 <td> Broadcom BCM56850 (Trident2) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5512-54X <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> MediaTek/Nephos MT3258 <td> No <td> No <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5712-54X <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56854 (Trident2) <td> Yes <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS6712-32X <td> 32x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56850 (Trident2) <td> Yes <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS5812-54T <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56864 (Trident2+) <td> Yes <td> Yes <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5812-54X <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56864 (Trident2+) <td> Yes <td> Yes <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS6812-32X <td> 32x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56864 (Trident2+) <td> Yes <td> Yes <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS7712-32X <td> 32x100G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56960 (Tomahawk) <td> Yes <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS7716-32X <td> 32x100G <td> Intel Xeon D-1518 x86 <td> Broadcom BCM56960 (Tomahawk) <td> Yes <td> Yes <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton Wedge-16X <td> 16x40G <td> Intel Rangeley C2550 x86 <td> Broadcom BCM56864 (Trident2+) <td> Work In Progress** <td> Yes <td> No <td> No <td> Yes <td> No </tr>
|
||||
<tr> <td> Accton (FB) Wedge 100 <td> 32x100G <td> Intel Bay Trail E3845 x86 <td> Broadcom BCM56960 (Tomahawk) <td> Work In Progress** <td> Yes <td> No <td> No <td> Yes <td> No </tr>
|
||||
<tr> <td> Accton AS4600-54T <td> 48x1G + 4x10G <td> FreeScale P2020 <td> Broadcom BCM56540 (Apollo2) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS4610-54P <td> 48x1G + 4x10G + 2x20G <td> Dual-core ARM Cortex A9 1GHz <td> Broadcom BCM56340 (Helix4) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5600-52X <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56846 (Trident+) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5610-52X <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56846 (Trident+) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5710-54X <td> 48x10G + 6x40G <td> FreeScale P2041 <td> Broadcom BCM56854 (Trident2) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS6700-32X <td> 32x40G <td> FreeScale P2041 <td> Broadcom BCM56850 (Trident2) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5512-54X <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> MediaTek/Nephos MT3258 <td> No <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5712-54X <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56854 (Trident2) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS6712-32X <td> 32x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56850 (Trident2) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS5812-54T <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56864 (Trident2+) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Accton AS5812-54X <td> 48x10G + 6x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56864 (Trident2+) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS6812-32X <td> 32x40G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56864 (Trident2+) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS7712-32X <td> 32x100G <td> Intel Rangeley C2538 x86 <td> Broadcom BCM56960 (Tomahawk) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton AS7716-32X <td> 32x100G <td> Intel Xeon D-1518 x86 <td> Broadcom BCM56960 (Tomahawk) <td> Yes <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Accton Wedge-16X <td> 16x40G <td> Intel Rangeley C2550 x86 <td> Broadcom BCM56864 (Trident2+) <td> Work In Progress** <td> Yes <td> No <td> Yes <td> No </tr>
|
||||
<tr> <td> Accton (FB) Wedge 100 <td> 32x100G <td> Intel Bay Trail E3845 x86 <td> Broadcom BCM56960 (Tomahawk) <td> Work In Progress** <td> Yes <td> No <td> Yes <td> No </tr>
|
||||
</table>
|
||||
|
||||
DNI/Agema
|
||||
@@ -48,9 +48,9 @@ DNI/Agema
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="info">
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> ORC <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
</thead>
|
||||
<tr> <td> AG-7448CU <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56845 (Trident) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> AG-7448CU <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56845 (Trident) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
</table>
|
||||
|
||||
Dell
|
||||
@@ -58,12 +58,12 @@ Dell
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="info">
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> ORC <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
</thead>
|
||||
<tr> <td> S4810-ON <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56845 (Trident) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> S4048-ON <td> 48x10G + 6x40G <td> Intel Atom C2338 <td> Broadcom BCM56854 (Trident2) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> S6000-ON <td> 32x40G <td> Intel Atom S1220 <td> Broadcom BCM56850 (Trident2) <td> Yes <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Z9100-ON <td> 32x100G <td> Intel Atom C2538 <td> Broadcom BCM56960 (Tomahawk) <td> Yes <td> Yes <td> No <td> No <td> No <td> No </tr>
|
||||
<tr> <td> S4810-ON <td> 48x10G + 4x40G <td> FreeScale P2020 <td> Broadcom BCM56845 (Trident) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> S4048-ON <td> 48x10G + 6x40G <td> Intel Atom C2338 <td> Broadcom BCM56854 (Trident2) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> S6000-ON <td> 32x40G <td> Intel Atom S1220 <td> Broadcom BCM56850 (Trident2) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
<tr> <td> Z9100-ON <td> 32x100G <td> Intel Atom C2538 <td> Broadcom BCM56960 (Tomahawk) <td> Yes <td> Yes <td> No <td> No <td> No </tr>
|
||||
</table>
|
||||
|
||||
Interface Masters Technologies, Inc.
|
||||
@@ -71,13 +71,28 @@ Interface Masters Technologies, Inc.
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="info">
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> ORC <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> OF-DPA <th> OpenNSL <th> SAI </tr>
|
||||
</thead>
|
||||
<tr> <td> Niagara 2948X12XLm <td> 48x10G + 12x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2960X6XLm <td> 60x10G + 6x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2972Xm <td> 72x10G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> Yes <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2932XL <td> 32x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2948X6XL <td> 48x10G + 6x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> No <td> Yes*** <td> Yes <td> No </tr>
|
||||
<tr> <td> Niagara 2948X12XLm <td> 48x10G + 12x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2960X6XLm <td> 60x10G + 6x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2972Xm <td> 72x10G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> Yes <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2932XL <td> 32x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> Yes*** <td> Yes*** <td> No </tr>
|
||||
<tr> <td> Niagara 2948X6XL <td> 48x10G + 6x40G <td> Intel/AMD x86 <td> Broadcom BCM56850 (Trident2) <td> Work In Progress** <td> No <td> Yes*** <td> Yes <td> No </tr>
|
||||
</table>
|
||||
|
||||
Mellanox
|
||||
---
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="info">
|
||||
<th> Device <th> Ports <th> CPU <th> Forwarding <th> ONL Certified <th> In Lab <th> SAI </tr>
|
||||
</thead>
|
||||
<tr> <td> SN2100 <td> 16x100G <td> Intel Rangeley C2558 <td> Mellanox Spectrum <td> Yes <td> Yes <td> Yes </tr>
|
||||
<tr> <td> SN2100B <td> 16x40G <td> Intel Rangeley C2558 <td> Mellanox Spectrum <td> Yes <td> No <td> Yes </tr>
|
||||
<tr> <td> SN2410 <td> 48x25G + 8x100G <td> Intel Ivybridge 1047UE <td> Mellanox Spectrum <td> Yes <td> Yes <td> Yes </tr>
|
||||
<tr> <td> SN2410B <td> 48x10G + 8x100G <td> Intel Ivybridge 1047UE <td> Mellanox Spectrum <td> Yes <td> No <td> Yes </tr>
|
||||
<tr> <td> SN2700 <td> 32x100G <td> Intel Ivybridge 1047UE <td> Mellanox Spectrum <td> Yes <td> Yes <td> Yes </tr>
|
||||
<tr> <td> SN2700B <td> 32x40G <td> Intel Ivybridge 1047UE <td> Mellanox Spectrum <td> Yes <td> No <td> Yes </tr>
|
||||
</table>
|
||||
|
||||
Notes:
|
||||
|
||||
48
docs/mibs/OCP-ONL-RESOURCE-MIB.txt
Normal file
48
docs/mibs/OCP-ONL-RESOURCE-MIB.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Open Network Linux Resource MIB
|
||||
-- ----------------------------------------------------------------------
|
||||
|
||||
OCP-ONL-RESOURCE-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS
|
||||
OBJECT-TYPE, MODULE-IDENTITY, Integer32, enterprises, Gauge32 FROM SNMPv2-SMI
|
||||
DisplayString FROM SNMPv2-TC
|
||||
ocp FROM OCP-MIB
|
||||
OpenNetworkLinux FROM OCP-ONL-MIB;
|
||||
|
||||
onlResource MODULE-IDENTITY
|
||||
LAST-UPDATED "201612120000Z"
|
||||
ORGANIZATION "Open Compute Project"
|
||||
CONTACT-INFO "http://www.opencompute.org"
|
||||
DESCRIPTION
|
||||
"This MIB describes objects for host resources used in Open Network Linux."
|
||||
REVISION "201612120000Z"
|
||||
DESCRIPTION "Initial revision"
|
||||
::= { OpenNetworkLinux 3 }
|
||||
|
||||
|
||||
--
|
||||
-- Basic Resource Objects
|
||||
--
|
||||
-- These are simplified and useful version of common resource measurements.
|
||||
--
|
||||
|
||||
Basic OBJECT IDENTIFIER ::= { onlResource 1 }
|
||||
|
||||
CpuAllPercentUtilization OBJECT-TYPE
|
||||
SYNTAX Gauge32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The average CPU utilization in percent, multiplied by 100 and rounded to the nearest integer. Provided by mpstat."
|
||||
::= { Basic 1 }
|
||||
|
||||
CpuAllPercentIdle OBJECT-TYPE
|
||||
SYNTAX Gauge32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The average CPU idle time in percent, multiplied by 100 and rounded to the nearest integer. Provided by mpstat."
|
||||
::= { Basic 2 }
|
||||
|
||||
END
|
||||
3
make/.gitignore
vendored
3
make/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
versions/
|
||||
module-manifest.mk
|
||||
modules/module*
|
||||
|
||||
|
||||
|
||||
9
make/arch-build.mk
Normal file
9
make/arch-build.mk
Normal file
@@ -0,0 +1,9 @@
|
||||
DIRECTORIES := rootfs swi installer
|
||||
include $(ONL)/make/subdirs.mk
|
||||
|
||||
.PHONY: swi
|
||||
|
||||
swi:
|
||||
$(MAKE) -C rootfs
|
||||
$(MAKE) -C swi
|
||||
|
||||
@@ -26,8 +26,11 @@ 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 $(ONL)/make/mmg.yml $(ONL) --only-if-missing)
|
||||
|
||||
# Use the new module database tool to resolve dependencies dynamically.
|
||||
export BUILDER_MODULE_DATABASE := $(ONL)/make/modules/modules.json
|
||||
# Regenerate the module manifest if necessary.
|
||||
export MODULEMANIFEST := $(shell $(BUILDER)/tools/modtool.py --db $(BUILDER_MODULE_DATABASE) --dbroot $(ONL) --make-manifest $(ONL)/make/modules/modules.mk)
|
||||
|
||||
# Generate versions if necessary.
|
||||
$(shell $(ONL)/tools/make-versions.py --import-file=$(ONL)/tools/onlvi --class-name=OnlVersionImplementation --output-dir $(ONL)/make/versions)
|
||||
|
||||
19
make/kmodule.mk
Normal file
19
make/kmodule.mk
Normal file
@@ -0,0 +1,19 @@
|
||||
ifndef KERNELS
|
||||
$(error $$KERNELS must be set)
|
||||
endif
|
||||
|
||||
ifndef KMODULES
|
||||
$(error $$KMODULES must be set)
|
||||
endif
|
||||
|
||||
ifndef PLATFORM
|
||||
$(error $$PLATFORM must be set)
|
||||
endif
|
||||
|
||||
ifndef ARCH
|
||||
$(error $$ARCH must be set)
|
||||
endif
|
||||
|
||||
|
||||
modules:
|
||||
ARCH=$(ARCH) $(ONL)/tools/scripts/kmodbuild.sh "$(KERNELS)" "$(KMODULES)" $(PLATFORM)
|
||||
@@ -1,9 +0,0 @@
|
||||
directories:
|
||||
- .
|
||||
|
||||
manifest: make/module-manifest.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1
make/modules/README
Normal file
1
make/modules/README
Normal file
@@ -0,0 +1 @@
|
||||
This directory contains the module database files generated at build time.
|
||||
@@ -3,6 +3,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-bootd
|
||||
|
||||
@@ -3,6 +3,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-loader-initrd-files
|
||||
|
||||
@@ -284,7 +284,7 @@ class Runner(onl.install.InstallUtils.SubprocessMixin):
|
||||
l = [x for x in os.listdir(d) if x.endswith('.swi')]
|
||||
l = [os.path.join(d, x) for x in l]
|
||||
l.sort(key=swiSortKey)
|
||||
return l[-1]
|
||||
return l[-1] if l else None
|
||||
|
||||
pm = ProcMountsParser()
|
||||
parts = [x for x in pm.mounts if x.device == dev]
|
||||
@@ -294,6 +294,9 @@ class Runner(onl.install.InstallUtils.SubprocessMixin):
|
||||
self.log.info("found 'latest' swi %s", dst)
|
||||
else:
|
||||
dst = os.path.join(parts[0].dir, src)
|
||||
if dst is None:
|
||||
self.log.error("missing SWI")
|
||||
return None
|
||||
if not os.path.exists(dst):
|
||||
self.log.error("missing SWI: %s", dst)
|
||||
return None
|
||||
|
||||
@@ -90,6 +90,7 @@ if [ ! -f /etc/onl/abort ]; then
|
||||
elif [ -f /etc/onl/boot-config-default ]; then
|
||||
# Use default boot-config.
|
||||
cp /etc/onl/boot-config-default /etc/onl/boot-config
|
||||
cp /etc/onl/boot-config-default /mnt/onl/boot/boot-config
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-mibs
|
||||
|
||||
@@ -3,11 +3,12 @@ prerequisites:
|
||||
|
||||
packages:
|
||||
- name: onl-vendor-config-onl
|
||||
depends: [ python-yaml, onl-bootd ]
|
||||
depends: [ python-yaml, onl-bootd, python-dmidecode ]
|
||||
version: 1.0.0
|
||||
arch: all
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
summary: ONL Base Configuration Package
|
||||
|
||||
files:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Run native ONIE tools
|
||||
"""Run native (on-disk) loader tools
|
||||
"""
|
||||
|
||||
import onl.install.ShellApp
|
||||
|
||||
4
packages/base/all/vendor-config-onl/src/bin/onl-boot-config
Executable file
4
packages/base/all/vendor-config-onl/src/bin/onl-boot-config
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
############################################################
|
||||
from onl.bootconfig import OnlBootConfigNet
|
||||
OnlBootConfigNet().main("onl-boot-config")
|
||||
34
packages/base/all/vendor-config-onl/src/bin/onl-onie-boot-mode
Executable file
34
packages/base/all/vendor-config-onl/src/bin/onl-onie-boot-mode
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/python
|
||||
############################################################
|
||||
import sys
|
||||
import platform
|
||||
import argparse
|
||||
import onl.grub
|
||||
|
||||
if platform.machine() != 'x86_64':
|
||||
sys.stderr.write("This command can only be used on GRUB-based X86_64 architectures.")
|
||||
sys.exit(1)
|
||||
|
||||
ap = argparse.ArgumentParser("onl-onie-boot-mode")
|
||||
|
||||
ap.add_argument("mode", choices=onl.grub.ONIE_BOOT_MODES)
|
||||
ap.add_argument("--onie-only", action='store_true', help="Do not set ONIE boot menu option.")
|
||||
|
||||
ops = ap.parse_args()
|
||||
|
||||
onl.grub.onie_boot_mode_set(ops.mode)
|
||||
|
||||
if not ops.onie_only:
|
||||
onl.grub.boot_onie()
|
||||
print "The system will boot into ONIE %s mode at the next restart." % ops.mode
|
||||
else:
|
||||
print "Mode %s will be selected the next time the system boots into ONIE." % ops.mode
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3
packages/base/all/vendor-config-onl/src/bin/onlfs
Executable file
3
packages/base/all/vendor-config-onl/src/bin/onlfs
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/python
|
||||
from onl.mounts import OnlMountManager
|
||||
OnlMountManager.main('onlfs')
|
||||
11
packages/base/all/vendor-config-onl/src/bin/onlkernel
Executable file
11
packages/base/all/vendor-config-onl/src/bin/onlkernel
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
############################################################
|
||||
if [ -z "$1" ]; then
|
||||
echo "usage: $0 <kernel url>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dir=`mktemp -d`
|
||||
(cd $dir && wget $1)
|
||||
onlfs rw boot mv $dir/* /mnt/onl/boot
|
||||
rmdir $dir
|
||||
5
packages/base/all/vendor-config-onl/src/bin/onlswi
Executable file
5
packages/base/all/vendor-config-onl/src/bin/onlswi
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
############################################################
|
||||
onlfs mount images --rw
|
||||
(cd /mnt/onl/images && rm -f *.swi && wget $1)
|
||||
onlfs mount images
|
||||
7
packages/base/all/vendor-config-onl/src/bin/pylegacy
Executable file
7
packages/base/all/vendor-config-onl/src/bin/pylegacy
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Swiss-army-knife legacy U-Boot image decoder
|
||||
"""
|
||||
|
||||
import onl.install.Legacy
|
||||
onl.install.Legacy.App.main()
|
||||
7
packages/base/all/vendor-config-onl/src/bin/upgrade-shell
Executable file
7
packages/base/all/vendor-config-onl/src/bin/upgrade-shell
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Run the upgrade image
|
||||
"""
|
||||
|
||||
import onl.install.ShellApp
|
||||
onl.install.ShellApp.Upgrader.main()
|
||||
1
packages/base/all/vendor-config-onl/src/boot.d/10.upgrade-system
Executable file
1
packages/base/all/vendor-config-onl/src/boot.d/10.upgrade-system
Executable file
@@ -0,0 +1 @@
|
||||
/sbin/onl-upgrade-system
|
||||
@@ -22,13 +22,16 @@ upgrade:
|
||||
package:
|
||||
dir: /lib/platform-config/current/onl/upgrade/onie
|
||||
|
||||
system:
|
||||
auto: force
|
||||
|
||||
firmware:
|
||||
auto: advisory
|
||||
package:
|
||||
dir: /lib/platform-config/current/onl/upgrade/firmware
|
||||
|
||||
loader:
|
||||
auto: advisory
|
||||
auto: force
|
||||
versions: /etc/onl/loader/versions.json
|
||||
package:
|
||||
dir: /etc/onl/upgrade/$PARCH
|
||||
|
||||
@@ -62,17 +62,26 @@ installer_mkchroot() {
|
||||
local rootdir
|
||||
rootdir=$1
|
||||
|
||||
local hasDevTmpfs
|
||||
if grep -q devtmpfs /proc/filesystems; then
|
||||
hasDevTmpfs=1
|
||||
fi
|
||||
|
||||
# special handling for /dev, which usually already has nested mounts
|
||||
installer_say "Setting up /dev"
|
||||
rm -fr "${rootdir}/dev"/*
|
||||
for dev in /dev/*; do
|
||||
if test -d "$dev"; then
|
||||
mkdir "${rootdir}${dev}"
|
||||
else
|
||||
cp -a "$dev" "${rootdir}${dev}"
|
||||
fi
|
||||
done
|
||||
mkdir -p "${rootdir}/dev/pts"
|
||||
if test "$hasDevTmpfs"; then
|
||||
:
|
||||
else
|
||||
for dev in /dev/*; do
|
||||
if test -d "$dev"; then
|
||||
mkdir "${rootdir}${dev}"
|
||||
else
|
||||
cp -a "$dev" "${rootdir}${dev}"
|
||||
fi
|
||||
done
|
||||
mkdir -p "${rootdir}/dev/pts"
|
||||
fi
|
||||
|
||||
installer_say "Setting up /run"
|
||||
rm -fr "${rootdir}/run"/*
|
||||
@@ -99,6 +108,10 @@ installer_mkchroot() {
|
||||
installer_say "Setting up mounts"
|
||||
mount -t proc proc "${rootdir}/proc"
|
||||
mount -t sysfs sysfs "${rootdir}/sys"
|
||||
if test "$hasDevTmpfs"; then
|
||||
mount -t devtmpfs devtmpfs "${rootdir}/dev"
|
||||
mkdir -p ${rootdir}/dev/pts
|
||||
fi
|
||||
mount -t devpts devpts "${rootdir}/dev/pts"
|
||||
|
||||
if test ${TMPDIR+set}; then
|
||||
|
||||
@@ -32,8 +32,8 @@ default:
|
||||
package: onl-kernel-3.18-x86-64-all:amd64
|
||||
|
||||
kernel-3.16: &kernel-3-16
|
||||
=: kernel-3.16+deb8-x86_64-all
|
||||
package: onl-kernel-3.16+deb8-x86-64-all:amd64
|
||||
=: kernel-3.16-lts-x86_64-all
|
||||
package: onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
|
||||
# pick one of the above kernels
|
||||
kernel:
|
||||
|
||||
224
packages/base/all/vendor-config-onl/src/python/onl/bootconfig/__init__.py
Executable file
224
packages/base/all/vendor-config-onl/src/python/onl/bootconfig/__init__.py
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/python
|
||||
############################################################
|
||||
import os
|
||||
import sys
|
||||
import netaddr
|
||||
|
||||
class OnlBootConfig(object):
|
||||
BOOT_CONFIG_DEFAULT='/mnt/onl/boot/boot-config'
|
||||
|
||||
def __init__(self):
|
||||
self.keys = {}
|
||||
self.__classmethod("init")
|
||||
|
||||
def _readf(self, fname):
|
||||
with open(fname) as f:
|
||||
for line in f.readlines():
|
||||
(k,d,v) = line.partition('=')
|
||||
if d == '=':
|
||||
self.keys[k] = v.strip()
|
||||
self._original = self.keys.copy()
|
||||
|
||||
def read(self, bc=None):
|
||||
if bc:
|
||||
self._readf(bc)
|
||||
else:
|
||||
from onl.mounts import OnlMountContextReadOnly
|
||||
with OnlMountContextReadOnly("ONL-BOOT", logger=None):
|
||||
self._readf(self.BOOT_CONFIG_DEFAULT)
|
||||
|
||||
def set(self, k, v):
|
||||
self.keys[k] = v
|
||||
|
||||
def get(self, k, d=None):
|
||||
return self.keys.get(k, d)
|
||||
|
||||
def delete(self, k):
|
||||
self.keys.pop(k, None)
|
||||
|
||||
def _writeh(self, handle):
|
||||
for (k, v) in self.keys.iteritems():
|
||||
handle.write("%s=%s\n" % (k, v))
|
||||
|
||||
def _writef(self, f):
|
||||
with open(f, "w") as f:
|
||||
self._writeh(f)
|
||||
|
||||
def write(self, dst=None, force_overwrite=True):
|
||||
self.validate()
|
||||
if dst:
|
||||
self._writef(dst)
|
||||
return True
|
||||
else:
|
||||
from onl.mounts import OnlMountContextReadWrite
|
||||
with OnlMountContextReadWrite("ONL-BOOT", logger=None):
|
||||
if not os.path.exists(self.BOOT_CONFIG_DEFAULT) or force_overwrite:
|
||||
self._writef(self.BOOT_CONFIG_DEFAULT)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def __classmethod(self, name, *args):
|
||||
for attr in dir(self):
|
||||
if attr.endswith("__%s" % name):
|
||||
getattr(self, attr)(*args)
|
||||
|
||||
def validate(self):
|
||||
return self.__classmethod("validate")
|
||||
|
||||
def argparse_init(self, ap):
|
||||
ap.add_argument("--read", help="Read the given file instead of the default [ %s ]." % OnlBootConfig.BOOT_CONFIG_DEFAULT)
|
||||
ap.add_argument("--write", help="Write the given file instead of the default [ %s ]." % OnlBootConfig.BOOT_CONFIG_DEFAULT)
|
||||
ap.add_argument("--show", help="Show the configuration.", action='store_true')
|
||||
self.__classmethod("argparse_init", ap)
|
||||
ap.add_argument("--dry", help='Show changes but do not update.', action='store_true')
|
||||
|
||||
def argparse_process(self, ops):
|
||||
self.read(ops.read)
|
||||
if(ops.show):
|
||||
self._writeh(sys.stdout)
|
||||
return self.__classmethod("argparse_process", ops)
|
||||
|
||||
def argparse_write(self, ops):
|
||||
try:
|
||||
if ops.dry:
|
||||
print self.keys
|
||||
self.validate()
|
||||
else:
|
||||
self.write(ops.write)
|
||||
if not ops.write and self.keys != self._original:
|
||||
print "You must reboot the switch before these changes will take affect."
|
||||
|
||||
except Exception, e:
|
||||
print e
|
||||
print "The boot configuration has not been changed."
|
||||
|
||||
|
||||
def main(self, name):
|
||||
import argparse
|
||||
ap = argparse.ArgumentParser("name")
|
||||
self.argparse_init(ap)
|
||||
ops = ap.parse_args()
|
||||
self.argparse_process(ops)
|
||||
self.argparse_write(ops)
|
||||
|
||||
|
||||
class OnlBootConfigNet(OnlBootConfig):
|
||||
|
||||
NET_REQUIRED = False
|
||||
|
||||
def netauto_set(self):
|
||||
self.delete('NETIP')
|
||||
self.delete('NETMASK')
|
||||
self.delete('NETGW')
|
||||
self.set('NETAUTO', 'dhcp')
|
||||
|
||||
def netip_set(self, addr):
|
||||
self.delete('NETAUTO')
|
||||
self.keys['NETIP'] = addr
|
||||
|
||||
def netmask_set(self, mask):
|
||||
self.delete('NETAUTO')
|
||||
self.keys['NETMASK'] = mask
|
||||
|
||||
def netgw_set(self, gw):
|
||||
self.delete('NETAUTO')
|
||||
self.keys['NETGW'] = gw
|
||||
|
||||
def __validate(self):
|
||||
if 'NETAUTO' not in self.keys:
|
||||
|
||||
netip = self.keys.get('NETIP', None)
|
||||
if netip:
|
||||
if not self.is_ip_address(netip):
|
||||
raise ValueError("NETIP=%s is not a valid ip-address" % (netup))
|
||||
elif self.NET_REQUIRED:
|
||||
raise ValueError("No IP configuration set for the management interface.")
|
||||
|
||||
netmask = self.keys.get('NETMASK', None)
|
||||
if netmask:
|
||||
if not self.is_netmask(netmask):
|
||||
raise ValueError("NETMASK=%s is not a valid netmask." % (netmask))
|
||||
elif self.NET_REQUIRED:
|
||||
raise ValueError("No Netmask configured for the management interface.")
|
||||
|
||||
netgw = self.keys.get('NETGW', None)
|
||||
if netgw:
|
||||
if not self.is_ip_address(netgw):
|
||||
raise ValueError("NETGW=%s is not a valid ip-address." % (netgw))
|
||||
elif self.NET_REQUIRED:
|
||||
raise ValueError("No gateway configured for the management interface.")
|
||||
|
||||
if netip and netmask and netgw:
|
||||
net = netaddr.IPNetwork("%s/%s" % (netip, netmask))
|
||||
if netaddr.IPAddress(netgw) not in net:
|
||||
raise ValueError("Gateway provided is not within the management network %s" % net)
|
||||
elif netip or netmask or netgw:
|
||||
raise ValueError("Incomplete static network configuration. NETIP, NETMASK, and NETGW must all be set.")
|
||||
|
||||
elif self.keys['NETAUTO'] not in ['dhcp', 'up']:
|
||||
raise ValueError("The NETAUTO value '%s' is invalid." % self.keys['NETAUTO'])
|
||||
elif self.keys['NETAUTO'] == 'up' and self.NET_REQUIRED:
|
||||
raise ValueError("NETAUTO is 'up' but non-local networking is required.")
|
||||
|
||||
if 'NETDEV' not in self.keys:
|
||||
self.keys['NETDEV'] = 'ma1'
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def is_ip_address(value):
|
||||
try:
|
||||
netaddr.IPAddress(value)
|
||||
return value
|
||||
except (netaddr.core.AddrFormatError, ValueError):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def is_netmask(value):
|
||||
try:
|
||||
if not netaddr.IPAddress(value).is_netmask():
|
||||
return False
|
||||
return value
|
||||
except (netaddr.core.AddrFormatError, ValueError):
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def argparse_type_is_ip_address(value):
|
||||
if not OnlBootConfigNet.is_ip_address(value):
|
||||
import argparse
|
||||
raise argparse.ArgumentTypeError("%s is not a valid address." % value)
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def argparse_type_is_netmask(value):
|
||||
if not OnlBootConfigNet.is_netmask(value):
|
||||
import argparse
|
||||
raise argparse.ArgumentTypeError("%s is not a valid netmask." % value)
|
||||
return value
|
||||
|
||||
def __argparse_init(self, ap):
|
||||
ap.add_argument("--dhcp", action='store_true', help="Use DHCP on the management interface.")
|
||||
ap.add_argument("--ip", help='Set static IP address for the management interface.', type=OnlBootConfigNet.argparse_type_is_ip_address)
|
||||
ap.add_argument("--netmask", help='Set the static netmask for the management interface.', type=OnlBootConfigNet.argparse_type_is_netmask)
|
||||
ap.add_argument("--gateway", help='Set the gateway address.', type=OnlBootConfigNet.argparse_type_is_ip_address)
|
||||
|
||||
|
||||
def __argparse_process(self, ops):
|
||||
if ops.dhcp:
|
||||
self.netauto_set()
|
||||
|
||||
if ops.ip:
|
||||
self.netip_set(ops.ip)
|
||||
|
||||
if ops.netmask:
|
||||
self.netmask_set(ops.netmask)
|
||||
|
||||
if ops.gateway:
|
||||
self.netgw_set(ops.gateway)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
bc = OnlBootConfigNet()
|
||||
bc.main("onl-boot-config")
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
from onl.mounts import OnlOnieBootContext, OnlMountContextReadWrite
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
ONIE_BOOT_MODES = [ 'install',
|
||||
'rescue',
|
||||
'uninstall',
|
||||
'update',
|
||||
'embed',
|
||||
'diag',
|
||||
'none'
|
||||
]
|
||||
|
||||
def onie_boot_mode_set(mode):
|
||||
if mode not in ONIE_BOOT_MODES:
|
||||
raise ValueError("%s is not a valid onie boot mode." % mode)
|
||||
|
||||
with OnlOnieBootContext() as ob:
|
||||
subprocess.check_call("%s/onie/tools/bin/onie-boot-mode -o %s" % (ob.directory, mode), shell=True)
|
||||
|
||||
def _makedirs(d):
|
||||
if not os.path.exists(d):
|
||||
os.makedirs(d)
|
||||
|
||||
def onie_fwpkg(arguments):
|
||||
with OnlOnieBootContext() as ob:
|
||||
# This is necessary if we've upgraded ONIE but haven't booted into it yet...
|
||||
_makedirs("%s/onie/update/pending" % ob.directory)
|
||||
_makedirs("%s/onie/update/attempts" % ob.directory)
|
||||
subprocess.check_call("%s/onie/tools/bin/onie-fwpkg %s" % (ob.directory, arguments), shell=True)
|
||||
|
||||
def boot_entry_set(index):
|
||||
with OnlMountContextReadWrite("ONL-BOOT", logger=None) as ob:
|
||||
subprocess.check_call("/usr/sbin/grub-set-default --boot-directory=%s %d" % (ob.directory, index), shell=True)
|
||||
|
||||
def boot_onie():
|
||||
return boot_entry_set(1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@ import time
|
||||
from InstallUtils import InitrdContext
|
||||
from InstallUtils import SubprocessMixin
|
||||
from InstallUtils import ProcMountsParser
|
||||
from ShellApp import OnieBootContext
|
||||
import ConfUtils, BaseInstall
|
||||
|
||||
class App(SubprocessMixin):
|
||||
class App(SubprocessMixin, object):
|
||||
|
||||
def __init__(self, url=None,
|
||||
debug=False, force=False,
|
||||
@@ -43,6 +44,8 @@ class App(SubprocessMixin):
|
||||
|
||||
self.nextUpdate = None
|
||||
|
||||
self.octx = None
|
||||
|
||||
def run(self):
|
||||
|
||||
if self.url is not None:
|
||||
@@ -123,45 +126,14 @@ class App(SubprocessMixin):
|
||||
self.log.info("please reboot this system now.")
|
||||
return 0
|
||||
|
||||
def runLocal(self):
|
||||
def runLocalOrChroot(self):
|
||||
|
||||
self.log.info("getting installer configuration")
|
||||
if os.path.exists(ConfUtils.MachineConf.PATH):
|
||||
self.machineConf = ConfUtils.MachineConf()
|
||||
else:
|
||||
self.log.warn("missing /etc/machine.conf from ONIE runtime")
|
||||
self.machineConf = ConfUtils.MachineConf(path='/dev/null')
|
||||
self.installerConf = ConfUtils.InstallerConf()
|
||||
|
||||
##self.log.info("using native GRUB")
|
||||
##self.grubEnv = ConfUtils.GrubEnv(log=self.log.getChild("grub"))
|
||||
|
||||
pat = "/mnt/onie-boot/onie/initrd.img*"
|
||||
l = glob.glob(pat)
|
||||
if l:
|
||||
initrd = l[0]
|
||||
self.log.info("using native ONIE initrd+chroot GRUB (%s)", initrd)
|
||||
initrdDir = InitrdContext.mkChroot(initrd, log=self.log)
|
||||
self.grubEnv = ConfUtils.ChrootGrubEnv(initrdDir,
|
||||
bootDir="/mnt/onie-boot",
|
||||
path="/grub/grubenv",
|
||||
log=self.log.getChild("grub"))
|
||||
# direct access using ONIE initrd as a chroot
|
||||
# (will need to fix up bootDir and bootPart later)
|
||||
else:
|
||||
self.log.info("using proxy GRUB")
|
||||
self.grubEnv = ConfUtils.ProxyGrubEnv(self.installerConf,
|
||||
bootDir="/mnt/onie-boot",
|
||||
path="/grub/grubenv",
|
||||
chroot=False,
|
||||
log=self.log.getChild("grub"))
|
||||
# indirect access through chroot host
|
||||
# (will need to fix up bootDir and bootPart later)
|
||||
|
||||
if os.path.exists(ConfUtils.UbootEnv.SETENV):
|
||||
self.ubootEnv = ConfUtils.UbootEnv(log=self.log.getChild("u-boot"))
|
||||
else:
|
||||
self.ubootEnv = None
|
||||
if self.machineConf is None:
|
||||
self.log.error("missing machine.conf")
|
||||
return 1
|
||||
if self.installerConf is None:
|
||||
self.log.error("missing installer.conf")
|
||||
return 1
|
||||
|
||||
self.log.info("ONL Installer %s", self.installerConf.onl_version)
|
||||
|
||||
@@ -189,6 +161,45 @@ class App(SubprocessMixin):
|
||||
self.log.error("cannot detect installer type")
|
||||
return 1
|
||||
|
||||
self.grubEnv = None
|
||||
|
||||
if 'grub' in self.onlPlatform.platform_config:
|
||||
##self.log.info("using native GRUB")
|
||||
##self.grubEnv = ConfUtils.GrubEnv(log=self.log.getChild("grub"))
|
||||
|
||||
with OnieBootContext(log=self.log) as self.octx:
|
||||
|
||||
self.octx.ictx.attach()
|
||||
self.octx.ictx.unmount()
|
||||
self.octx.ictx.detach()
|
||||
# XXX roth -- here, detach the initrd mounts
|
||||
|
||||
self.octx.detach()
|
||||
|
||||
if self.octx.onieDir is not None:
|
||||
self.log.info("using native ONIE initrd+chroot GRUB (%s)", self.octx.onieDir)
|
||||
self.grubEnv = ConfUtils.ChrootGrubEnv(self.octx.initrdDir,
|
||||
bootDir=self.octx.onieDir,
|
||||
path="/grub/grubenv",
|
||||
log=self.log.getChild("grub"))
|
||||
# direct access using ONIE initrd as a chroot
|
||||
# (will need to fix up bootDir and bootPart later)
|
||||
|
||||
if self.grubEnv is None:
|
||||
self.log.info("using proxy GRUB")
|
||||
self.grubEnv = ConfUtils.ProxyGrubEnv(self.installerConf,
|
||||
bootDir="/mnt/onie-boot",
|
||||
path="/grub/grubenv",
|
||||
chroot=False,
|
||||
log=self.log.getChild("grub"))
|
||||
# indirect access through chroot host
|
||||
# (will need to fix up bootDir and bootPart later)
|
||||
|
||||
if os.path.exists(ConfUtils.UbootEnv.SETENV):
|
||||
self.ubootEnv = ConfUtils.UbootEnv(log=self.log.getChild("u-boot"))
|
||||
else:
|
||||
self.ubootEnv = None
|
||||
|
||||
# run the platform-specific installer
|
||||
self.installer = iklass(machineConf=self.machineConf,
|
||||
installerConf=self.installerConf,
|
||||
@@ -216,6 +227,19 @@ class App(SubprocessMixin):
|
||||
self.log.info("Install finished.")
|
||||
return 0
|
||||
|
||||
def runLocal(self):
|
||||
|
||||
self.log.info("getting installer configuration")
|
||||
if os.path.exists(ConfUtils.MachineConf.PATH):
|
||||
self.machineConf = ConfUtils.MachineConf()
|
||||
else:
|
||||
self.log.warn("missing /etc/machine.conf from ONIE runtime")
|
||||
self.machineConf = ConfUtils.MachineConf(path='/dev/null')
|
||||
|
||||
self.installerConf = ConfUtils.InstallerConf()
|
||||
|
||||
return self.runLocalOrChroot()
|
||||
|
||||
def findPlatform(self):
|
||||
|
||||
plat = arch = None
|
||||
@@ -302,6 +326,11 @@ class App(SubprocessMixin):
|
||||
if installer is not None:
|
||||
installer.shutdown()
|
||||
|
||||
ctx, self.octx = self.octx, None
|
||||
if ctx:
|
||||
ctx.attach()
|
||||
ctx.shutdown()
|
||||
|
||||
def post_mortem(self):
|
||||
self.log.info("re-attaching to tty")
|
||||
fdno = os.open("/dev/console", os.O_RDWR)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Base classes for installers.
|
||||
"""
|
||||
|
||||
import os, stat
|
||||
import os, sys, stat
|
||||
import subprocess
|
||||
import re
|
||||
import tempfile
|
||||
@@ -13,14 +13,25 @@ import parted
|
||||
import yaml
|
||||
import zipfile
|
||||
import shutil
|
||||
import imp
|
||||
import fnmatch, glob
|
||||
|
||||
from InstallUtils import SubprocessMixin
|
||||
from InstallUtils import MountContext, BlkidParser, PartedParser
|
||||
from InstallUtils import ProcMountsParser
|
||||
from Plugin import Plugin
|
||||
|
||||
import onl.YamlUtils
|
||||
from onl.sysconfig import sysconfig
|
||||
|
||||
try:
|
||||
PartedException = parted._ped.PartedException
|
||||
DiskException = parted._ped.DiskException
|
||||
except AttributeError:
|
||||
import _ped
|
||||
PartedException = _ped.PartedException
|
||||
DiskException = _ped.DiskException
|
||||
|
||||
class Base:
|
||||
|
||||
class installmeta:
|
||||
@@ -80,11 +91,23 @@ class Base:
|
||||
self.zf = None
|
||||
# zipfile handle to installer archive
|
||||
|
||||
self.plugins = []
|
||||
# dynamically-detected plugins
|
||||
|
||||
def run(self):
|
||||
self.log.error("not implemented")
|
||||
return 1
|
||||
|
||||
def upgradeBootLoader(self):
|
||||
self.log.error("not implemented")
|
||||
return 1
|
||||
|
||||
def shutdown(self):
|
||||
|
||||
plugins, self.plugins = self.plugins, []
|
||||
for plugin in plugins:
|
||||
plugin.shutdown()
|
||||
|
||||
zf, self.zf = self.zf, None
|
||||
if zf: zf.close()
|
||||
|
||||
@@ -94,7 +117,7 @@ class Base:
|
||||
src = os.path.join(self.im.installerConf.installer_dir, basename)
|
||||
if os.path.exists(src):
|
||||
self.copy2(src, dst)
|
||||
return
|
||||
return True
|
||||
|
||||
if basename in self.zf.namelist():
|
||||
self.log.debug("+ unzip -p %s %s > %s",
|
||||
@@ -102,11 +125,13 @@ class Base:
|
||||
with self.zf.open(basename, "r") as rfd:
|
||||
with open(dst, "wb") as wfd:
|
||||
shutil.copyfileobj(rfd, wfd)
|
||||
return
|
||||
return True
|
||||
|
||||
if not optional:
|
||||
raise ValueError("missing installer file %s" % basename)
|
||||
|
||||
return False
|
||||
|
||||
def installerDd(self, basename, device):
|
||||
|
||||
p = os.path.join(self.im.installerConf.installer_dir, basename)
|
||||
@@ -346,7 +371,10 @@ class Base:
|
||||
basename = 'boot-config'
|
||||
with MountContext(dev.device, log=self.log) as ctx:
|
||||
dst = os.path.join(ctx.dir, basename)
|
||||
self.installerCopy(basename, dst)
|
||||
|
||||
if not self.installerCopy(basename, dst, True):
|
||||
return
|
||||
|
||||
with open(dst) as fd:
|
||||
buf = fd.read()
|
||||
|
||||
@@ -382,7 +410,7 @@ class Base:
|
||||
for m in pm.mounts:
|
||||
if m.device.startswith(self.device):
|
||||
if not self.force:
|
||||
self.log.error("mount %s on %s will be erased by install",
|
||||
self.log.error("mount %s on %s will be erased by install (try --force)",
|
||||
m.dir, m.device)
|
||||
return 1
|
||||
else:
|
||||
@@ -396,14 +424,84 @@ class Base:
|
||||
|
||||
return 0
|
||||
|
||||
def loadPluginsFromFile(self, pyPath):
|
||||
self.log.info("loading plugins from %s", pyPath)
|
||||
with open(pyPath) as fd:
|
||||
sfx = ('.py', 'U', imp.PY_SOURCE,)
|
||||
moduleName = os.path.splitext(os.path.basename(pyPath))[0]
|
||||
mod = imp.load_module("onl_install_plugin_%s" % moduleName, fd, pyPath, sfx)
|
||||
for attr in dir(mod):
|
||||
klass = getattr(mod, attr)
|
||||
if isinstance(klass, type) and issubclass(klass, Plugin):
|
||||
self.log.info("%s: found plugin %s", pyPath, attr)
|
||||
plugin = klass(self)
|
||||
self.plugins.append(plugin)
|
||||
|
||||
def loadPlugins(self):
|
||||
|
||||
# scrape any plugins from the installer working directory
|
||||
pat = os.path.join(self.im.installerConf.installer_dir, "plugins", "*.py")
|
||||
for src in glob.glob(pat):
|
||||
self.loadPluginsFromFile(src)
|
||||
|
||||
# scrape any plugins from the installer archive
|
||||
pat = "plugins/*.py"
|
||||
for basename in self.zf.namelist():
|
||||
if not fnmatch.fnmatch(basename, pat): continue
|
||||
try:
|
||||
src = None
|
||||
with self.zf.open(basename, "r") as rfd:
|
||||
wfno, src = tempfile.mkstemp(prefix="plugin-",
|
||||
suffix=".py")
|
||||
with os.fdopen(wfno, "w") as wfd:
|
||||
shutil.copyfileobj(rfd, wfd)
|
||||
self.loadPluginsFromFile(src)
|
||||
finally:
|
||||
if src and os.path.exists(src):
|
||||
os.unlink(src)
|
||||
|
||||
# scrape plugins from the loader runtime
|
||||
# (any plugins dropped into $pydir/onl/install/plugins/*.py)
|
||||
try:
|
||||
import onl.install.plugins
|
||||
plugindir = os.path.dirname(onl.install.plugins.__file__)
|
||||
except ImportError:
|
||||
plugindir = None
|
||||
if plugindir:
|
||||
pat = os.path.join(plugindir, "*.py")
|
||||
for src in glob.glob(pat):
|
||||
self.loadPluginsFromFile(src)
|
||||
|
||||
return 0
|
||||
|
||||
def runPlugins(self, mode):
|
||||
self.log.info("running plugins: %s", mode)
|
||||
for plugin in self.plugins:
|
||||
try:
|
||||
code = plugin.run(mode)
|
||||
except:
|
||||
self.log.exception("plugin failed")
|
||||
code = 1
|
||||
if code: return code
|
||||
return 0
|
||||
|
||||
GRUB_TPL = """\
|
||||
serial %(serial)s
|
||||
terminal_input serial
|
||||
terminal_output serial
|
||||
set timeout=5
|
||||
|
||||
# Always boot the saved_entry value
|
||||
load_env
|
||||
if [ "${saved_entry}" ] ; then
|
||||
set default="${saved_entry}"
|
||||
fi
|
||||
|
||||
menuentry %(boot_menu_entry)s {
|
||||
search --no-floppy --label --set=root ONL-BOOT
|
||||
# Always return to this entry by default.
|
||||
set saved_entry="0"
|
||||
save_env saved_entry
|
||||
echo 'Loading %(boot_loading_name)s ...'
|
||||
insmod gzio
|
||||
insmod part_msdos
|
||||
@@ -414,6 +512,9 @@ menuentry %(boot_menu_entry)s {
|
||||
# Menu entry to chainload ONIE
|
||||
menuentry ONIE {
|
||||
search --no-floppy --label --set=root ONIE-BOOT
|
||||
# Always return to entry 0 by default.
|
||||
set saved_entry="0"
|
||||
save_env saved_entry
|
||||
echo 'Loading ONIE ...'
|
||||
chainloader +1
|
||||
}
|
||||
@@ -511,19 +612,7 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
|
||||
def installLoader(self):
|
||||
|
||||
ctx = {}
|
||||
|
||||
kernel = self.im.platformConf['grub']['kernel']
|
||||
ctx['kernel'] = kernel['='] if type(kernel) == dict else kernel
|
||||
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
|
||||
|
||||
kernels = []
|
||||
|
||||
for f in set(os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()):
|
||||
if 'kernel' in f:
|
||||
kernels.append(f)
|
||||
@@ -535,11 +624,10 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
initrd = i
|
||||
break
|
||||
|
||||
cf = GRUB_TPL % ctx
|
||||
|
||||
self.log.info("Installing kernel")
|
||||
dev = self.blkidParts['ONL-BOOT']
|
||||
|
||||
self.log.info("Installing kernel to %s", dev.device)
|
||||
|
||||
with MountContext(dev.device, log=self.log) as ctx:
|
||||
def _cp(b, dstname=None):
|
||||
if dstname is None:
|
||||
@@ -548,8 +636,32 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
self.installerCopy(b, dst, optional=True)
|
||||
[_cp(e) for e in kernels]
|
||||
_cp(initrd, "%s.cpio.gz" % self.im.installerConf.installer_platform)
|
||||
|
||||
return 0
|
||||
|
||||
def installGrubCfg(self):
|
||||
|
||||
dev = self.blkidParts['ONL-BOOT']
|
||||
|
||||
self.log.info("Installing grub.cfg to %s", dev.device)
|
||||
|
||||
ctx = {}
|
||||
|
||||
kernel = self.im.platformConf['grub']['kernel']
|
||||
ctx['kernel'] = kernel['='] if type(kernel) == dict else kernel
|
||||
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
|
||||
|
||||
cf = GRUB_TPL % ctx
|
||||
|
||||
with MountContext(dev.device, log=self.log) as ctx:
|
||||
d = os.path.join(ctx.dir, "grub")
|
||||
self.makedirs(d)
|
||||
if not os.path.exists(d):
|
||||
self.makedirs(d)
|
||||
dst = os.path.join(ctx.dir, 'grub/grub.cfg')
|
||||
with open(dst, "w") as fd:
|
||||
fd.write(cf)
|
||||
@@ -563,6 +675,17 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
|
||||
def installGpt(self):
|
||||
|
||||
# get a handle to the installer zip
|
||||
p = os.path.join(self.im.installerConf.installer_dir,
|
||||
self.im.installerConf.installer_zip)
|
||||
self.zf = zipfile.ZipFile(p)
|
||||
|
||||
code = self.loadPlugins()
|
||||
if code: return code
|
||||
|
||||
code = self.runPlugins(Plugin.PLUGIN_PREINSTALL)
|
||||
if code: return code
|
||||
|
||||
code = self.findGpt()
|
||||
if code: return code
|
||||
|
||||
@@ -600,17 +723,15 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
self.im.grubEnv.__dict__['bootPart'] = dev.device
|
||||
self.im.grubEnv.__dict__['bootDir'] = None
|
||||
|
||||
# get a handle to the installer zip
|
||||
p = os.path.join(self.im.installerConf.installer_dir,
|
||||
self.im.installerConf.installer_zip)
|
||||
self.zf = zipfile.ZipFile(p)
|
||||
|
||||
code = self.installSwi()
|
||||
if code: return code
|
||||
|
||||
code = self.installLoader()
|
||||
if code: return code
|
||||
|
||||
code = self.installGrubCfg()
|
||||
if code: return code
|
||||
|
||||
code = self.installBootConfig()
|
||||
if code: return code
|
||||
|
||||
@@ -620,6 +741,9 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
code = self.installGrub()
|
||||
if code: return code
|
||||
|
||||
code = self.runPlugins(Plugin.PLUGIN_POSTINSTALL)
|
||||
if code: return code
|
||||
|
||||
self.log.info("ONL loader install successful.")
|
||||
self.log.info("GRUB installation is required next.")
|
||||
|
||||
@@ -635,6 +759,16 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
return 1
|
||||
return self.installGpt()
|
||||
|
||||
def upgradeBootLoader(self):
|
||||
"""Upgrade the boot loader settings."""
|
||||
|
||||
self.blkidParts = BlkidParser(log=self.log.getChild("blkid"))
|
||||
|
||||
code = self.installGrubCfg()
|
||||
if code: return code
|
||||
|
||||
return 0
|
||||
|
||||
def shutdown(self):
|
||||
Base.shutdown(self)
|
||||
|
||||
@@ -668,9 +802,6 @@ class UbootInstaller(SubprocessMixin, Base):
|
||||
|
||||
self.device = self.im.getDevice()
|
||||
|
||||
code = self.assertUnmounted()
|
||||
if code: return code
|
||||
|
||||
self.rawLoaderDevice = None
|
||||
# set to a partition device for raw loader install,
|
||||
# default to None for FS-based install
|
||||
@@ -686,11 +817,17 @@ class UbootInstaller(SubprocessMixin, Base):
|
||||
return 0
|
||||
self.log.warn("disk %s has wrong label %s",
|
||||
self.device, self.partedDisk.type)
|
||||
except Exception as ex:
|
||||
except (DiskException, PartedException) as ex:
|
||||
self.log.error("cannot get partition table from %s: %s",
|
||||
self.device, str(ex))
|
||||
except Exception:
|
||||
self.log.exception("cannot get partition table from %s",
|
||||
self.device)
|
||||
|
||||
self.log.info("creating msdos label on %s")
|
||||
self.log.info("clobbering disk label on %s", self.device)
|
||||
self.partedDevice.clobber()
|
||||
|
||||
self.log.info("creating msdos label on %s", self.device)
|
||||
self.partedDisk = parted.freshDisk(self.partedDevice, 'msdos')
|
||||
|
||||
return 0
|
||||
@@ -783,6 +920,20 @@ class UbootInstaller(SubprocessMixin, Base):
|
||||
self.log.error("not a block device: %s", self.device)
|
||||
return 1
|
||||
|
||||
# get a handle to the installer zip
|
||||
p = os.path.join(self.im.installerConf.installer_dir,
|
||||
self.im.installerConf.installer_zip)
|
||||
self.zf = zipfile.ZipFile(p)
|
||||
|
||||
code = self.loadPlugins()
|
||||
if code: return code
|
||||
|
||||
code = self.runPlugins(Plugin.PLUGIN_PREINSTALL)
|
||||
if code: return code
|
||||
|
||||
code = self.assertUnmounted()
|
||||
if code: return code
|
||||
|
||||
code = self.maybeCreateLabel()
|
||||
if code: return code
|
||||
|
||||
@@ -825,11 +976,6 @@ class UbootInstaller(SubprocessMixin, Base):
|
||||
self.rawLoaderDevice = self.device + str(partIdx+1)
|
||||
break
|
||||
|
||||
# get a handle to the installer zip
|
||||
p = os.path.join(self.im.installerConf.installer_dir,
|
||||
self.im.installerConf.installer_zip)
|
||||
self.zf = zipfile.ZipFile(p)
|
||||
|
||||
code = self.installSwi()
|
||||
if code: return code
|
||||
|
||||
@@ -854,6 +1000,9 @@ class UbootInstaller(SubprocessMixin, Base):
|
||||
code = self.installUbootEnv()
|
||||
if code: return code
|
||||
|
||||
code = self.runPlugins(Plugin.PLUGIN_POSTINSTALL)
|
||||
if code: return code
|
||||
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
@@ -864,5 +1013,17 @@ class UbootInstaller(SubprocessMixin, Base):
|
||||
|
||||
return self.installUboot()
|
||||
|
||||
def upgradeBootLoader(self):
|
||||
"""Upgrade the boot loader settings as part of a loader upgrade."""
|
||||
|
||||
self.blkidParts = BlkidParser(log=self.log.getChild("blkid"))
|
||||
|
||||
# XXX boot-config (and saved boot-config) should be unchanged during loader upgrade
|
||||
|
||||
code = self.installUbootEnv()
|
||||
if code: return code
|
||||
|
||||
return 0
|
||||
|
||||
def shutdown(self):
|
||||
Base.shutdown(self)
|
||||
|
||||
@@ -7,6 +7,7 @@ import os
|
||||
import logging
|
||||
import subprocess
|
||||
from InstallUtils import SubprocessMixin, ChrootSubprocessMixin, MountContext
|
||||
from cStringIO import StringIO
|
||||
|
||||
class ConfBase:
|
||||
|
||||
@@ -45,6 +46,14 @@ class ConfBase:
|
||||
def __setattr__(self, attr, val):
|
||||
self.__dict__['_data'][attr] = val
|
||||
|
||||
def dumps(self):
|
||||
"""Generate a serialized representation."""
|
||||
buf = StringIO()
|
||||
data = self.__dict__.get('_data', {})
|
||||
for key, val in data.iteritems():
|
||||
buf.write("%s=\"%s\"\n" % (key, val,))
|
||||
return buf.getvalue()
|
||||
|
||||
class ConfFileBase(ConfBase):
|
||||
|
||||
PATH = None
|
||||
|
||||
@@ -38,6 +38,21 @@ class Parser:
|
||||
self.rootNodes = {}
|
||||
self._parse()
|
||||
|
||||
@classmethod
|
||||
def isFit(cls, path=None, stream=None):
|
||||
if stream is not None:
|
||||
try:
|
||||
pos = stream.tell()
|
||||
buf = stream.read(4)
|
||||
finally:
|
||||
stream.seek(pos, 0)
|
||||
else:
|
||||
with open(path) as fd:
|
||||
buf = fd.read(4)
|
||||
if len(buf) != 4: return False
|
||||
magic = struct.unpack(">I", buf)[0]
|
||||
return magic == cls.FDT_MAGIC
|
||||
|
||||
def _parse(self):
|
||||
if self.stream is not None:
|
||||
try:
|
||||
@@ -58,7 +73,7 @@ class Parser:
|
||||
hdr = list(struct.unpack(">10I", buf))
|
||||
magic = hdr.pop(0)
|
||||
if magic != self.FDT_MAGIC:
|
||||
raise ValueError("missing magic")
|
||||
raise ValueError("missing or invalid magic")
|
||||
self.fdtSize = hdr.pop(0)
|
||||
self.structPos = hdr.pop(0)
|
||||
self.stringPos = hdr.pop(0)
|
||||
|
||||
@@ -10,6 +10,8 @@ import tempfile
|
||||
import string
|
||||
import shutil
|
||||
|
||||
import Fit, Legacy
|
||||
|
||||
class SubprocessMixin:
|
||||
|
||||
V1 = "V1"
|
||||
@@ -177,6 +179,25 @@ class SubprocessMixin:
|
||||
# don't believe it
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
|
||||
def cpR(self, srcRoot, dstRoot):
|
||||
srcRoot = os.path.abspath(srcRoot)
|
||||
dstRoot = os.path.abspath(dstRoot)
|
||||
dstRoot = os.path.join(dstRoot, os.path.split(srcRoot)[1])
|
||||
for r, dl, fl in os.walk(srcRoot):
|
||||
|
||||
for de in dl:
|
||||
src = os.path.join(r, de)
|
||||
subdir = src[len(srcRoot)+1:]
|
||||
dst = os.path.join(dstRoot, subdir)
|
||||
if not os.path.exists(dst):
|
||||
self.makedirs(dst)
|
||||
|
||||
for fe in fl:
|
||||
src = os.path.join(r, fe)
|
||||
subdir = src[len(srcRoot)+1:]
|
||||
dst = os.path.join(dstRoot, subdir)
|
||||
self.copy2(src, dst)
|
||||
|
||||
class TempdirContext(SubprocessMixin):
|
||||
|
||||
def __init__(self, prefix=None, suffix=None, chroot=None, log=None):
|
||||
@@ -210,8 +231,8 @@ class MountContext(SubprocessMixin):
|
||||
self.label = label
|
||||
self.fsType = fsType
|
||||
self.dir = None
|
||||
self.hostDir = None
|
||||
self.mounted = False
|
||||
self.hostDir = self.__hostDir = None
|
||||
self.mounted = self.__mounted = False
|
||||
self.log = log or logging.getLogger("mount")
|
||||
|
||||
if self.device and self.label:
|
||||
@@ -245,7 +266,7 @@ class MountContext(SubprocessMixin):
|
||||
self.mounted = True
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, tb):
|
||||
def shutdown(self):
|
||||
|
||||
mounted = False
|
||||
if self.mounted:
|
||||
@@ -263,8 +284,18 @@ class MountContext(SubprocessMixin):
|
||||
if self.hostDir is not None:
|
||||
self.rmdir(self.hostDir)
|
||||
|
||||
def __exit__(self, type, value, tb):
|
||||
self.shutdown()
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.__mounted, self.mounted = self.mounted, False
|
||||
self.__hostDir, self.hostDir = self.hostDir, None
|
||||
|
||||
def attach(self):
|
||||
self.mounted = self.__mounted
|
||||
self.hostDir = self.__hostDir
|
||||
|
||||
class BlkidEntry:
|
||||
|
||||
def __init__(self, device, **kwargs):
|
||||
@@ -665,6 +696,10 @@ class InitrdContext(SubprocessMixin):
|
||||
self.ilog.setLevel(logging.INFO)
|
||||
self.log = self.hlog
|
||||
|
||||
self.__initrd = None
|
||||
self.__dir = None
|
||||
self._hasDevTmpfs = False
|
||||
|
||||
def _unpack(self):
|
||||
self.dir = self.mkdtemp(prefix="chroot-",
|
||||
suffix=".d")
|
||||
@@ -724,27 +759,28 @@ class InitrdContext(SubprocessMixin):
|
||||
else:
|
||||
self.unlink(dst)
|
||||
|
||||
for e in os.listdir("/dev"):
|
||||
src = os.path.join("/dev", e)
|
||||
dst = os.path.join(dev2, e)
|
||||
if os.path.islink(src):
|
||||
self.symlink(os.readlink(src), dst)
|
||||
elif os.path.isdir(src):
|
||||
self.mkdir(dst)
|
||||
elif os.path.isfile(src):
|
||||
self.copy2(src, dst)
|
||||
else:
|
||||
st = os.stat(src)
|
||||
if stat.S_ISBLK(st.st_mode):
|
||||
maj, min = os.major(st.st_rdev), os.minor(st.st_rdev)
|
||||
self.log.debug("+ mknod %s b %d %d", dst, maj, min)
|
||||
os.mknod(dst, st.st_mode, st.st_rdev)
|
||||
elif stat.S_ISCHR(st.st_mode):
|
||||
maj, min = os.major(st.st_rdev), os.minor(st.st_rdev)
|
||||
self.log.debug("+ mknod %s c %d %d", dst, maj, min)
|
||||
os.mknod(dst, st.st_mode, st.st_rdev)
|
||||
if not self._hasDevTmpfs:
|
||||
for e in os.listdir("/dev"):
|
||||
src = os.path.join("/dev", e)
|
||||
dst = os.path.join(dev2, e)
|
||||
if os.path.islink(src):
|
||||
self.symlink(os.readlink(src), dst)
|
||||
elif os.path.isdir(src):
|
||||
self.mkdir(dst)
|
||||
elif os.path.isfile(src):
|
||||
self.copy2(src, dst)
|
||||
else:
|
||||
self.log.debug("skipping device %s", src)
|
||||
st = os.stat(src)
|
||||
if stat.S_ISBLK(st.st_mode):
|
||||
maj, min = os.major(st.st_rdev), os.minor(st.st_rdev)
|
||||
self.log.debug("+ mknod %s b %d %d", dst, maj, min)
|
||||
os.mknod(dst, st.st_mode, st.st_rdev)
|
||||
elif stat.S_ISCHR(st.st_mode):
|
||||
maj, min = os.major(st.st_rdev), os.minor(st.st_rdev)
|
||||
self.log.debug("+ mknod %s c %d %d", dst, maj, min)
|
||||
os.mknod(dst, st.st_mode, st.st_rdev)
|
||||
else:
|
||||
self.log.debug("skipping device %s", src)
|
||||
|
||||
dst = os.path.join(self.dir, "dev/pts")
|
||||
if not os.path.exists(dst):
|
||||
@@ -757,6 +793,11 @@ class InitrdContext(SubprocessMixin):
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
with open("/proc/filesystems") as fd:
|
||||
buf = fd.read()
|
||||
if "devtmpfs" in buf:
|
||||
self._hasDevTmpfs = True
|
||||
|
||||
if self.initrd is not None:
|
||||
|
||||
self.log.debug("extracting initrd %s", self.initrd)
|
||||
@@ -777,43 +818,156 @@ class InitrdContext(SubprocessMixin):
|
||||
cmd = ('mount', '-t', 'sysfs', 'sysfs', dst,)
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
|
||||
# maybe mount devtmpfs
|
||||
if self._hasDevTmpfs:
|
||||
dst = os.path.join(self.dir, "dev")
|
||||
cmd = ('mount', '-t', 'devtmpfs', 'devtmpfs', dst,)
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
|
||||
dst = os.path.join(self.dir, "dev/pts")
|
||||
if not os.path.exists(dst):
|
||||
self.mkdir(dst)
|
||||
|
||||
dst = os.path.join(self.dir, "dev/pts")
|
||||
cmd = ('mount', '-t', 'devpts', 'devpts', dst,)
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, tb):
|
||||
def unmount(self):
|
||||
|
||||
p = ProcMountsParser()
|
||||
dirs = [e.dir for e in p.mounts if e.dir.startswith(self.dir)]
|
||||
if self.dir is not None:
|
||||
dirs = [e.dir for e in p.mounts if e.dir.startswith(self.dir)]
|
||||
else:
|
||||
dirs = []
|
||||
|
||||
# XXX probabaly also kill files here
|
||||
|
||||
# umount any nested mounts
|
||||
self.log.debug("un-mounting mounts points in chroot %s", self.dir)
|
||||
dirs.sort(reverse=True)
|
||||
for p in dirs:
|
||||
cmd = ('umount', p,)
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
if dirs:
|
||||
self.log.debug("un-mounting mounts points in chroot %s", self.dir)
|
||||
dirs.sort(reverse=True)
|
||||
for p in dirs:
|
||||
cmd = ('umount', p,)
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
|
||||
if self.initrd is not None:
|
||||
def shutdown(self):
|
||||
|
||||
self.unmount()
|
||||
|
||||
if self.initrd and self.dir:
|
||||
self.log.debug("cleaning up chroot in %s", self.dir)
|
||||
self.rmtree(self.dir)
|
||||
else:
|
||||
elif self.dir:
|
||||
self.log.debug("saving chroot in %s", self.dir)
|
||||
|
||||
def __exit__(self, type, value, tb):
|
||||
self.shutdown()
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.__initrd, self.initrd = self.initrd, None
|
||||
self.__dir, self.dir = self.dir, None
|
||||
|
||||
def attach(self):
|
||||
self.initrd = self.__initrd
|
||||
self.dir = self.__dir
|
||||
|
||||
@classmethod
|
||||
def mkChroot(self, initrd, log=None):
|
||||
with InitrdContext(initrd=initrd, log=log) as ctx:
|
||||
def mkChroot(cls, initrd, log=None):
|
||||
with cls(initrd=initrd, log=log) as ctx:
|
||||
initrdDir = ctx.dir
|
||||
ctx.initrd = None
|
||||
ctx.detach()
|
||||
# save the unpacked directory, do not clean it up
|
||||
# (it's inside this chroot anyway)
|
||||
return initrdDir
|
||||
|
||||
class UbootInitrdContext(SubprocessMixin):
|
||||
|
||||
def __init__(self, path, log=None):
|
||||
self.path = path
|
||||
self.log = log or logging.getLogger(self.__class__.__name__)
|
||||
self.initrd = self.__initrd = None
|
||||
|
||||
def _extractFit(self):
|
||||
self.log.debug("parsing FIT image in %s", self.path)
|
||||
p = Fit.Parser(path=self.path, log=self.log)
|
||||
node = p.getInitrdNode()
|
||||
if node is None:
|
||||
raise ValueError("cannot find initrd node in FDT")
|
||||
prop = node.properties.get('data', None)
|
||||
if prop is None:
|
||||
raise ValueError("cannot find initrd data property in FDT")
|
||||
|
||||
with open(self.path) as fd:
|
||||
self.log.debug("reading initrd at [%x:%x]",
|
||||
prop.offset, prop.offset+prop.sz)
|
||||
fd.seek(prop.offset, 0)
|
||||
buf = fd.read(prop.sz)
|
||||
|
||||
fno, self.initrd = tempfile.mkstemp(prefix="initrd-",
|
||||
suffix=".img")
|
||||
self.log.debug("+ cat > %s", self.initrd)
|
||||
with os.fdopen(fno, "w") as fd:
|
||||
fd.write(buf)
|
||||
|
||||
def _extractLegacy(self):
|
||||
self.log.debug("parsing legacy U-Boot image in %s", self.path)
|
||||
p = Legacy.Parser(path=self.path, log=self.log)
|
||||
|
||||
if p.ih_type != Legacy.Parser.IH_TYPE_MULTI:
|
||||
raise ValueError("not a multi-file image")
|
||||
|
||||
if p.ih_os != Legacy.Parser.IH_OS_LINUX:
|
||||
raise ValueError("invalid OS code")
|
||||
|
||||
sz, off = p.images[1]
|
||||
# assume the initrd is the second of three images
|
||||
|
||||
with open(self.path) as fd:
|
||||
self.log.debug("reading initrd at [%x:%x]",
|
||||
off, off+sz)
|
||||
fd.seek(off, 0)
|
||||
buf = fd.read(sz)
|
||||
|
||||
fno, self.initrd = tempfile.mkstemp(prefix="initrd-",
|
||||
suffix=".img")
|
||||
self.log.debug("+ cat > %s", self.initrd)
|
||||
with os.fdopen(fno, "w") as fd:
|
||||
fd.write(buf)
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
with open(self.path) as fd:
|
||||
isFit = Fit.Parser.isFit(stream=fd)
|
||||
isLegacy = Legacy.Parser.isLegacy(stream=fd)
|
||||
|
||||
if isFit:
|
||||
self._extractFit()
|
||||
return self
|
||||
|
||||
if isLegacy:
|
||||
self._extractLegacy()
|
||||
return self
|
||||
|
||||
raise ValueError("invalid U-Boot image %s" % self.path)
|
||||
|
||||
def shutdown(self):
|
||||
initrd, self.initrd = self.initrd, None
|
||||
if initrd and os.path.exists(initrd):
|
||||
self.unlink(initrd)
|
||||
|
||||
def __exit__(self, eType, eValue, eTrace):
|
||||
self.shutdown()
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.__initrd, self.initrd = self.initrd, None
|
||||
|
||||
def attach(self):
|
||||
self.initrd = self.__initrd
|
||||
|
||||
class ChrootSubprocessMixin:
|
||||
|
||||
chrootDir = None
|
||||
|
||||
@@ -0,0 +1,378 @@
|
||||
"""Legacy.py
|
||||
|
||||
See
|
||||
http://www.isysop.com/unpacking-and-repacking-u-boot-uimage-files/
|
||||
https://github.com/lentinj/u-boot/blob/master/include/image.h
|
||||
|
||||
"""
|
||||
|
||||
import os, sys
|
||||
import logging
|
||||
import struct
|
||||
import argparse
|
||||
import time
|
||||
|
||||
class Parser:
|
||||
|
||||
MAGIC = 0x27051956
|
||||
|
||||
# codes for ih_os
|
||||
IH_OS_INVALID = 0
|
||||
IH_OS_OPENBSD = 1
|
||||
IH_OS_NETBSD = 2
|
||||
IH_OS_FREEBSD = 3
|
||||
IH_OS_4_4BSD = 4
|
||||
IH_OS_LINUX = 5
|
||||
IH_OS_SVR4 = 6
|
||||
IH_OS_ESIX = 7
|
||||
IH_OS_SOLARIS = 8
|
||||
IH_OS_IRIX = 9
|
||||
IH_OS_SCO = 10
|
||||
IH_OS_DELL = 11
|
||||
IH_OS_NCR = 12
|
||||
IH_OS_LYNXOS = 13
|
||||
IH_OS_VXWORKS = 14
|
||||
IH_OS_PSOS = 15
|
||||
IH_OS_QNX = 16
|
||||
IH_OS_U_BOOT = 17
|
||||
IH_OS_RTEMS = 18
|
||||
IH_OS_ARTOS = 19
|
||||
IH_OS_UNITY = 20
|
||||
IH_OS_INTEGRITY = 21
|
||||
IH_OS_OSE = 22
|
||||
_IH_OS_END = 23
|
||||
|
||||
# codes for ih_arch
|
||||
IH_ARCH_INVALID = 0
|
||||
IH_ARCH_ALPHA = 1
|
||||
IH_ARCH_ARM = 2
|
||||
IH_ARCH_I386 = 3
|
||||
IH_ARCH_IA64 = 4
|
||||
IH_ARCH_MIPS = 5
|
||||
IH_ARCH_MIPS64 = 6
|
||||
IH_ARCH_PPC = 7
|
||||
IH_ARCH_S390 = 8
|
||||
IH_ARCH_SH = 9
|
||||
IH_ARCH_SPARC = 10
|
||||
IH_ARCH_SPARC64 = 11
|
||||
IH_ARCH_M68K = 12
|
||||
IH_ARCH_MICROBLAZE = 14
|
||||
IH_ARCH_NIOS2 = 15
|
||||
IH_ARCH_BLACKFIN = 16
|
||||
IH_ARCH_AVR32 = 17
|
||||
IH_ARCH_ST200 = 18
|
||||
IH_ARCH_SANDBOX = 19
|
||||
IH_ARCH_NDS32 = 20
|
||||
IH_ARCH_OPENRISC = 21
|
||||
_IH_ARCH_END = 22
|
||||
|
||||
# codes for ih_type
|
||||
IH_TYPE_INVALID = 0
|
||||
IH_TYPE_STANDALONE = 1
|
||||
IH_TYPE_KERNEL = 2
|
||||
IH_TYPE_RAMDISK = 3
|
||||
IH_TYPE_MULTI = 4
|
||||
IH_TYPE_FIRMWARE = 5
|
||||
IH_TYPE_SCRIPT = 6
|
||||
IH_TYPE_FILESYSTEM = 7
|
||||
IH_TYPE_FLATDT = 8
|
||||
IH_TYPE_KWBIMAGE = 9
|
||||
IH_TYPE_IMXIMAGE = 10
|
||||
IH_TYPE_UBLIMAGE = 11
|
||||
IH_TYPE_OMAPIMAGE = 12
|
||||
IH_TYPE_AISIMAGE =13
|
||||
IH_TYPE_KERNEL_NOLOAD = 14
|
||||
_IH_TYPE_END = 15
|
||||
|
||||
# codes for ih_comp
|
||||
IH_COMP_NONE = 0
|
||||
IH_COMP_GZIP = 1
|
||||
IH_COMP_BZIP2 = 2
|
||||
IH_COMP_LZMA = 3
|
||||
IH_COMP_LZO = 4
|
||||
_IH_COMP_END = 5
|
||||
|
||||
@classmethod
|
||||
def registerConstants(cls):
|
||||
|
||||
cls.IH_OS = [None] * cls._IH_OS_END
|
||||
for k, v in cls.__dict__.iteritems():
|
||||
if k.startswith('IH_OS_'):
|
||||
cls.IH_OS[v] = k[6:]
|
||||
|
||||
cls.IH_ARCH = [None] * cls._IH_ARCH_END
|
||||
for k, v in cls.__dict__.iteritems():
|
||||
if k.startswith('IH_ARCH_'):
|
||||
cls.IH_ARCH[v] = k[8:]
|
||||
|
||||
cls.IH_TYPE = [None] * cls._IH_TYPE_END
|
||||
for k, v in cls.__dict__.iteritems():
|
||||
if k.startswith('IH_TYPE_'):
|
||||
cls.IH_TYPE[v] = k[8:]
|
||||
|
||||
cls.IH_COMP = [None] * cls._IH_COMP_END
|
||||
for k, v in cls.__dict__.iteritems():
|
||||
if k.startswith('IH_COMP_'):
|
||||
cls.IH_COMP[v] = k[8:]
|
||||
|
||||
def __init__(self, path=None, stream=None, log=None):
|
||||
|
||||
self.log = log or logging.getLogger(self.__class__.__name__)
|
||||
self.path = path
|
||||
self.stream = stream
|
||||
|
||||
self.images = []
|
||||
self._parse()
|
||||
|
||||
@classmethod
|
||||
def isLegacy(cls, path=None, stream=None):
|
||||
if stream is not None:
|
||||
try:
|
||||
pos = stream.tell()
|
||||
buf = stream.read(4)
|
||||
finally:
|
||||
stream.seek(pos, 0)
|
||||
else:
|
||||
with open(path) as fd:
|
||||
buf = fd.read(4)
|
||||
if len(buf) != 4: return False
|
||||
magic = struct.unpack(">I", buf)[0]
|
||||
return magic == cls.MAGIC
|
||||
|
||||
def _parse(self):
|
||||
if self.stream is not None:
|
||||
try:
|
||||
pos = self.stream.tell()
|
||||
self._parseStream(self.stream)
|
||||
finally:
|
||||
self.stream.seek(pos, 0)
|
||||
elif self.path is not None:
|
||||
with open(self.path) as fd:
|
||||
self._parseStream(fd)
|
||||
else:
|
||||
raise ValueError("missing file or stream")
|
||||
|
||||
def _parseStream(self, fd):
|
||||
|
||||
buf = fd.read(64)
|
||||
hdr = list(struct.unpack(">7IBBBB32s", buf))
|
||||
|
||||
self.ih_magic = hdr.pop(0)
|
||||
if self.ih_magic != self.MAGIC:
|
||||
raise ValueError("missing or invalid magic")
|
||||
|
||||
self.ih_hcrc = hdr.pop(0)
|
||||
|
||||
self.ih_time = hdr.pop(0)
|
||||
self.log.debug("image created %s",
|
||||
time.ctime(self.ih_time))
|
||||
|
||||
self.ih_size = hdr.pop(0)
|
||||
self.log.debug("total image size %s bytes",
|
||||
self.ih_size)
|
||||
|
||||
self.ih_load = hdr.pop(0)
|
||||
self.ih_ep = hdr.pop(0)
|
||||
self.ih_dcrc = hdr.pop(0)
|
||||
|
||||
self.ih_os = hdr.pop(0)
|
||||
self.ih_arch = hdr.pop(0)
|
||||
|
||||
self.ih_type = hdr.pop(0)
|
||||
|
||||
self.ih_comp = hdr.pop(0)
|
||||
# compression is ignored here, since it applies to the first
|
||||
# image (the kernel)
|
||||
|
||||
self.ih_name = hdr.pop(0).rstrip('\0')
|
||||
|
||||
if self.ih_type == self.IH_TYPE_MULTI:
|
||||
self.images = []
|
||||
while True:
|
||||
buf = fd.read(4)
|
||||
sz = struct.unpack(">I", buf)[0]
|
||||
if sz == 0: break
|
||||
self.log.debug("found image header %d bytes", sz)
|
||||
self.images.append([sz, None])
|
||||
|
||||
# compute absolute image offsets
|
||||
pos = fd.tell()
|
||||
for idx, rec in enumerate(self.images):
|
||||
rec[1] = pos
|
||||
pos += rec[0]
|
||||
|
||||
# images are aligned at 4-byte boundaries
|
||||
pos += 3
|
||||
pos &= ~0x3
|
||||
|
||||
return
|
||||
|
||||
Parser.registerConstants()
|
||||
|
||||
class DumpRunner:
|
||||
|
||||
def __init__(self, stream, log=None):
|
||||
self.log = log or logging.getLogger(self.__class__.__name__)
|
||||
self.stream = stream
|
||||
|
||||
def run(self):
|
||||
p = Parser(stream=self.stream, log=self.log)
|
||||
|
||||
sys.stdout.write("Legacy U-Boot Image \"%s\":\n" % p.ih_name)
|
||||
sys.stdout.write("created %s, %d bytes\n"
|
||||
% (time.ctime(p.ih_time), p.ih_size,))
|
||||
sys.stdout.write("load @0x%04x, execute @0x%04x\n"
|
||||
% (p.ih_load, p.ih_ep,))
|
||||
sys.stdout.write("OS is %s\n" % p.IH_OS[p.ih_os])
|
||||
sys.stdout.write("architecture is %s\n" % p.IH_ARCH[p.ih_arch])
|
||||
sys.stdout.write("image type is %s\n" % p.IH_TYPE[p.ih_type])
|
||||
sys.stdout.write("compression type is %s\n" % p.IH_COMP[p.ih_comp])
|
||||
|
||||
if p.ih_type == p.IH_TYPE_MULTI:
|
||||
sys.stdout.write("%d images total:\n" % len(p.images))
|
||||
for i, rec in enumerate(p.images):
|
||||
sys.stdout.write("image %d, %d bytes (offset %d)\n"
|
||||
% (i, rec[0], rec[1],))
|
||||
|
||||
return 0
|
||||
|
||||
def shutdown(self):
|
||||
strm, self.stream = self.stream, None
|
||||
if strm is not None: strm.close()
|
||||
|
||||
class ExtractRunner:
|
||||
"""Extract a specific image.
|
||||
|
||||
NOTE that image zero may be compressed.
|
||||
"""
|
||||
|
||||
def __init__(self, stream, index=None, outStream=None, log=None):
|
||||
self.log = log or logging.getLogger(self.__class__.__name__)
|
||||
self.stream = stream
|
||||
self.index = index
|
||||
self.outStream = outStream
|
||||
|
||||
def run(self):
|
||||
p = Parser(stream=self.stream, log=self.log)
|
||||
|
||||
if p.ih_type != p.IH_TYPE_MULTI:
|
||||
if self.index is not None:
|
||||
self.log.error("not a multi-file image, image index not allowed")
|
||||
return 1
|
||||
self.stream.seek(64, 0)
|
||||
buf = self.stream.read(p.ih_size)
|
||||
else:
|
||||
if self.index is None:
|
||||
self.log.error("multi-file image, image index required")
|
||||
return 1
|
||||
sz, off = p.images[self.index]
|
||||
self.stream.seek(off, 0)
|
||||
buf = self.stream.read(sz)
|
||||
|
||||
strm = self.outStream or sys.stdout
|
||||
strm.write(buf)
|
||||
|
||||
return 0
|
||||
|
||||
def shutdown(self):
|
||||
strm, self.stream = self.stream, None
|
||||
if strm is not None: strm.close()
|
||||
strm, self.outStream = self.outStream, None
|
||||
if strm is not None: strm.close()
|
||||
|
||||
USAGE = """\
|
||||
pylegacy [OPTIONS] ...
|
||||
"""
|
||||
|
||||
DUMP_USAGE = """\
|
||||
pylegacy [OPTIONS] dump IMAGE-FILE
|
||||
"""
|
||||
|
||||
EXTRACT_USAGE = """\
|
||||
pylegacy [OPTIONS] extract [OPTIONS] IMAGE-FILE [IMAGE-INDEX]
|
||||
"""
|
||||
|
||||
class App:
|
||||
|
||||
def __init__(self, log=None):
|
||||
self.log = log or logging.getLogger("pyfit")
|
||||
|
||||
def run(self):
|
||||
|
||||
ap = argparse.ArgumentParser(usage=USAGE)
|
||||
ap.add_argument('-q', '--quiet', action='store_true',
|
||||
help="Suppress log messages")
|
||||
ap.add_argument('-v', '--verbose', action='store_true',
|
||||
help="Add more logging")
|
||||
|
||||
sp = ap.add_subparsers()
|
||||
|
||||
apd = sp.add_parser('dump',
|
||||
help="Dump image structure",
|
||||
usage=DUMP_USAGE)
|
||||
apd.set_defaults(mode='dump')
|
||||
apd.add_argument('image-file', type=open,
|
||||
help="U-Boot Legacy Image")
|
||||
|
||||
apx = sp.add_parser('extract',
|
||||
help="Extract items",
|
||||
usage=EXTRACT_USAGE)
|
||||
apx.set_defaults(mode='extract')
|
||||
apx.add_argument('image-file', type=open,
|
||||
help="U-Boot Legacy Image")
|
||||
|
||||
apx.add_argument('-o', '--output',
|
||||
type=argparse.FileType('wb', 0),
|
||||
help="File destination")
|
||||
apx.add_argument('index', type=int, nargs='?',
|
||||
help="Image index (zero-based)")
|
||||
|
||||
try:
|
||||
args = ap.parse_args()
|
||||
except SystemExit, what:
|
||||
return what.code
|
||||
|
||||
if args.quiet:
|
||||
self.log.setLevel(logging.ERROR)
|
||||
if args.verbose:
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
if args.mode == 'dump':
|
||||
strm = getattr(args, 'image-file')
|
||||
r = DumpRunner(strm, log=self.log)
|
||||
elif args.mode == 'extract':
|
||||
strm = getattr(args, 'image-file')
|
||||
r = ExtractRunner(strm,
|
||||
index=args.index,
|
||||
outStream=args.output,
|
||||
log=self.log)
|
||||
|
||||
try:
|
||||
code = r.run()
|
||||
except:
|
||||
self.log.exception("runner failed")
|
||||
code = 1
|
||||
r.shutdown()
|
||||
return code
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def main(cls):
|
||||
logging.basicConfig()
|
||||
logger = logging.getLogger("pylegacy")
|
||||
logger.setLevel(logging.INFO)
|
||||
app = cls(log=logger)
|
||||
try:
|
||||
code = app.run()
|
||||
except:
|
||||
logger.exception("app failed")
|
||||
code = 1
|
||||
app.shutdown()
|
||||
sys.exit(code)
|
||||
|
||||
main = App.main
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Plugin.py
|
||||
|
||||
Base class for installer plugins.
|
||||
"""
|
||||
|
||||
class Plugin(object):
|
||||
|
||||
PLUGIN_PREINSTALL = "preinstall"
|
||||
PLUGIN_POSTINSTALL = "postinstall"
|
||||
|
||||
def __init__(self, installer):
|
||||
self.installer = installer
|
||||
self.log = self.installer.log.getChild("plugin")
|
||||
|
||||
def run(self, mode):
|
||||
|
||||
if hasattr(self, mode):
|
||||
return getattr(self, mode)()
|
||||
|
||||
if mode == self.PLUGIN_PREINSTALL:
|
||||
self.log.warn("pre-install plugin not implemented")
|
||||
return 0
|
||||
|
||||
if mode == self.PLUGIN_POSTINSTALL:
|
||||
self.log.warn("post-install plugin not implemented")
|
||||
return 0
|
||||
|
||||
self.log.warn("invalid plugin mode %s", repr(mode))
|
||||
return 1
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
@@ -13,11 +13,12 @@ from InstallUtils import InitrdContext, MountContext
|
||||
from InstallUtils import SubprocessMixin
|
||||
from InstallUtils import ProcMountsParser, ProcMtdParser
|
||||
from InstallUtils import BlkidParser
|
||||
import Fit
|
||||
from InstallUtils import UbootInitrdContext
|
||||
|
||||
import onl.platform.current
|
||||
from onl.sysconfig import sysconfig
|
||||
|
||||
class AppBase(SubprocessMixin):
|
||||
class AppBase(SubprocessMixin, object):
|
||||
|
||||
@property
|
||||
def PROG(self):
|
||||
@@ -46,30 +47,8 @@ class AppBase(SubprocessMixin):
|
||||
return 0
|
||||
|
||||
def _runFitShell(self, device):
|
||||
self.log.debug("parsing FIT image in %s", device)
|
||||
p = Fit.Parser(path=device, log=self.log)
|
||||
node = p.getInitrdNode()
|
||||
if node is None:
|
||||
self.log.error("cannot find initrd node in FDT")
|
||||
return 1
|
||||
prop = node.properties.get('data', None)
|
||||
if prop is None:
|
||||
self.log.error("cannot find initrd data property in FDT")
|
||||
return 1
|
||||
with open(device) as fd:
|
||||
self.log.debug("reading initrd at [%x:%x]",
|
||||
prop.offset, prop.offset+prop.sz)
|
||||
fd.seek(prop.offset, 0)
|
||||
buf = fd.read(prop.sz)
|
||||
try:
|
||||
fno, initrd = tempfile.mkstemp(prefix="initrd-",
|
||||
suffix=".img")
|
||||
self.log.debug("+ cat > %s", initrd)
|
||||
with os.fdopen(fno, "w") as fd:
|
||||
fd.write(buf)
|
||||
return self._runInitrdShell(initrd)
|
||||
finally:
|
||||
self.unlink(initrd)
|
||||
with UbootInitrdContext(path=device, log=self.log) as ctx:
|
||||
return self._runInitrdShell(ctx.initrd)
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
@@ -108,11 +87,22 @@ class AppBase(SubprocessMixin):
|
||||
app.shutdown()
|
||||
sys.exit(code)
|
||||
|
||||
class Onie(AppBase):
|
||||
class OnieBootContext:
|
||||
"""Find the ONIE initrd and umpack/mount it."""
|
||||
|
||||
PROG = "onie-shell"
|
||||
def __init__(self, log=None):
|
||||
self.log = log or logging.getLogger(self.__class__.__name__)
|
||||
|
||||
def run(self):
|
||||
self.initrd = None
|
||||
|
||||
self.pm = self.blkid = self.mtd = None
|
||||
self.ictx = self.dctx = self.fctx = None
|
||||
self.onieDir = None
|
||||
self.initrdDir = None
|
||||
|
||||
self.__ictx = self.__dctx = self.__fctx = None
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
self.pm = ProcMountsParser()
|
||||
self.blkid = BlkidParser(log=self.log.getChild("blkid"))
|
||||
@@ -134,25 +124,32 @@ class Onie(AppBase):
|
||||
|
||||
parts = [p for p in self.pm.mounts if p.device == dev]
|
||||
if parts:
|
||||
onieDir = parts[0]
|
||||
self.log.debug("found ONIE boot mounted at %s", onieDir)
|
||||
initrd = _g(onieDir)
|
||||
self.log.debug("found ONIE boot mounted at %s", parts[0].dir)
|
||||
initrd = _g(parts[0].dir)
|
||||
if initrd is None:
|
||||
self.log.warn("cannot find ONIE initrd on %s", onieDir)
|
||||
else:
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
return _runInitrdShell(initrd)
|
||||
raise ValueError("cannot find ONIE initrd on %s" % parts[0].dir)
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
with InitrdContext(initrd=initrd, log=self.log) as self.ictx:
|
||||
self.initrd = initrd
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
with MountContext(dev, log=self.log) as ctx:
|
||||
initrd = _g(ctx.dir)
|
||||
# else, try to mount the directory containing the initrd
|
||||
with MountContext(dev, log=self.log) as self.dctx:
|
||||
initrd = _g(self.dctx.dir)
|
||||
if initrd is None:
|
||||
self.log.warn("cannot find ONIE initrd on %s", dev)
|
||||
else:
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
return self._runInitrdShell(initrd)
|
||||
raise ValueError("cannot find ONIE initrd on %s" % dev)
|
||||
self.onieDir = self.dctx.dir
|
||||
self.dctx.detach()
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
with InitrdContext(initrd=initrd, log=self.log) as self.ictx:
|
||||
self.initrd = initrd
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
self.log.warn("cannot find an ONIE initrd")
|
||||
return 1
|
||||
raise ValueError("cannot find an ONIE initrd")
|
||||
|
||||
# try to find onie initrd on a mounted fs (GRUB);
|
||||
# for ONIE images this is usually /mnt/onie-boot
|
||||
@@ -163,8 +160,13 @@ class Onie(AppBase):
|
||||
self.log.debug("cannot find ONIE initrd on %s (%s)",
|
||||
part.device, part.dir)
|
||||
else:
|
||||
self.onieDir = part.dir
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
return self._runInitrdShell(initrd)
|
||||
with InitrdContext(initrd=initrd, log=self.log) as self.ictx:
|
||||
self.initrd = initrd
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
# grovel through MTD devices (u-boot)
|
||||
parts = [p for p in self.mtd.parts if p.label == "onie"]
|
||||
@@ -172,15 +174,61 @@ class Onie(AppBase):
|
||||
part = parts[0]
|
||||
self.log.debug("found ONIE MTD device %s",
|
||||
part.charDevice or part.blockDevice)
|
||||
return self._runFitShell(part.blockDevice)
|
||||
elif self.mtd.mounts:
|
||||
self.log.error("cannot find ONIE MTD device")
|
||||
return 1
|
||||
with UbootInitrdContext(part.blockDevice, log=self.log) as self.fctx:
|
||||
with InitrdContext(initrd=self.fctx.initrd, log=self.log) as self.ictx:
|
||||
self.initrd = self.fctx.initrd
|
||||
self.fctx.detach()
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
self.log.error("cannot find ONIE initrd")
|
||||
return 1
|
||||
if self.mtd.mounts:
|
||||
raise ValueError("cannot find ONIE MTD device")
|
||||
|
||||
raise ValueError("cannot find ONIE initrd")
|
||||
|
||||
def shutdown(self):
|
||||
ctx, self.fctx = self.fctx, None
|
||||
if ctx is not None:
|
||||
ctx.shutdown()
|
||||
ctx.attach()
|
||||
ctx.shutdown()
|
||||
ctx, self.ictx = self.ictx, None
|
||||
if ctx is not None:
|
||||
ctx.shutdown()
|
||||
ctx.attach()
|
||||
ctx.shutdown()
|
||||
ctx, self.dctx = self.dctx, None
|
||||
if ctx is not None:
|
||||
ctx.shutdown()
|
||||
ctx.attach()
|
||||
ctx.shutdown()
|
||||
|
||||
def __exit__(self, eType, eValue, eTrace):
|
||||
self.shutdown()
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.__fctx, self.fctx = self.fctx, None
|
||||
self.__ictx, self.ictx = self.ictx, None
|
||||
self.__dctx, self.dctx = self.dctx, None
|
||||
|
||||
def attach(self):
|
||||
self.fctx = self.__fctx
|
||||
self.ictx = self.__ictx
|
||||
self.dctx = self.__dctx
|
||||
|
||||
class Onie(AppBase):
|
||||
"""XXX roth -- refactor in from loader.py code."""
|
||||
|
||||
PROG = "onie-shell"
|
||||
|
||||
def run(self):
|
||||
with OnieBootContext(log=self.log) as ctx:
|
||||
return self._runInitrdShell(ctx.initrd)
|
||||
|
||||
class Loader(AppBase):
|
||||
"""Application shell that uses the (installed) loader runtime."""
|
||||
|
||||
PROG = "loader-shell"
|
||||
|
||||
@@ -263,7 +311,7 @@ class Loader(AppBase):
|
||||
# run from a file in a mounted filesystem
|
||||
parts = [p for p in self.pm.mounts if p.device == bootDevice]
|
||||
if parts:
|
||||
loaderDir = parts[0]
|
||||
loaderDir = parts[0].dir
|
||||
self.log.debug("found loader device mounted at %s", loaderDir)
|
||||
for e in l:
|
||||
p = os.path.join(loaderDir, e)
|
||||
@@ -297,6 +345,49 @@ class Loader(AppBase):
|
||||
self.log.error("invalid platform-config")
|
||||
return 1
|
||||
|
||||
class Upgrader(AppBase):
|
||||
"""Application shell that uses on-disk upgrade loader runtime."""
|
||||
|
||||
PROG = "upgrade-shell"
|
||||
|
||||
def runGrub(self):
|
||||
|
||||
d = sysconfig.upgrade.loader.package.dir
|
||||
for b in sysconfig.upgrade.loader.package.grub:
|
||||
p = os.path.join(d, b)
|
||||
if os.path.exists(p):
|
||||
self.log.debug("found upgrade initrd at %s", p)
|
||||
return self._runInitrdShell(p)
|
||||
|
||||
self.log.error("cannot find upgrade initrd")
|
||||
return 1
|
||||
|
||||
def runUboot(self):
|
||||
|
||||
d = sysconfig.upgrade.loader.package.dir
|
||||
for b in sysconfig.upgrade.loader.package.fit:
|
||||
p = os.path.join(d, b)
|
||||
if os.path.exists(p):
|
||||
self.log.debug("found upgrade FIT image %s", p)
|
||||
return self._runFitShell(p)
|
||||
|
||||
self.log.error("cannot find FIT image")
|
||||
return 1
|
||||
|
||||
def run(self):
|
||||
|
||||
self.platform = onl.platform.current.OnlPlatform()
|
||||
self.pc = self.platform.platform_config
|
||||
|
||||
if 'grub' in self.pc:
|
||||
return self.runGrub()
|
||||
|
||||
if 'flat_image_tree' in self.pc:
|
||||
return self.runUboot()
|
||||
|
||||
self.log.error("invalid platform-config")
|
||||
return 1
|
||||
|
||||
main = Onie.main
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
"""App.py
|
||||
|
||||
Application code for onl-install.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os, sys
|
||||
import json
|
||||
import tempfile
|
||||
import zipfile
|
||||
import shutil
|
||||
import argparse
|
||||
import fnmatch
|
||||
import subprocess
|
||||
|
||||
from onl.install.InstallUtils import InitrdContext
|
||||
from onl.install.InstallUtils import ProcMountsParser
|
||||
from onl.install.ConfUtils import MachineConf, InstallerConf
|
||||
from onl.install.ShellApp import OnieBootContext, Upgrader
|
||||
from onl.install.InstallUtils import SubprocessMixin
|
||||
import onl.install.App
|
||||
|
||||
from onl.sysconfig import sysconfig
|
||||
|
||||
from onl.mounts import OnlMountContextReadWrite
|
||||
|
||||
class UpgradeHelper(Upgrader):
|
||||
|
||||
def __init__(self, callback=None, log=None):
|
||||
super(UpgradeHelper, self).__init__(log=log)
|
||||
self.callback = callback
|
||||
|
||||
def _runInitrdShell(self, p):
|
||||
if self.callback is not None:
|
||||
return self.callback(self, p)
|
||||
return 0
|
||||
|
||||
class App(SubprocessMixin):
|
||||
|
||||
def __init__(self, force=False, log=None):
|
||||
|
||||
if log is not None:
|
||||
self.log = log
|
||||
else:
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
self.force = force
|
||||
|
||||
def _runInitrd(self, helper, path):
|
||||
with InitrdContext(initrd=path, log=self.log) as ctx:
|
||||
|
||||
tdir = os.path.join(ctx.dir, "tmp")
|
||||
abs_idir = tempfile.mkdtemp(dir=tdir,
|
||||
prefix="installer-", suffix=".d")
|
||||
chroot_idir = abs_idir[len(ctx.dir):]
|
||||
|
||||
with OnieBootContext(log=self.log) as octx:
|
||||
self.log.info("onie directory is %s", octx.onieDir)
|
||||
self.log.info("initrd directory is %s", octx.initrdDir)
|
||||
|
||||
src = os.path.join(octx.initrdDir, "etc/machine.conf")
|
||||
dst = os.path.join(ctx.dir, "etc/machine.conf")
|
||||
self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
src = "/etc/fw_env.config"
|
||||
if os.path.exists(src):
|
||||
dst = os.path.join(ctx.dir, "etc/fw_env.config")
|
||||
self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
srcRoot = "/etc/onl"
|
||||
dstRoot = os.path.join(ctx.dir, "etc")
|
||||
self.cpR(srcRoot, dstRoot)
|
||||
|
||||
# constitute an /etc/onl/installer.conf in place
|
||||
installerConf = InstallerConf(path="/dev/null")
|
||||
|
||||
vj = "/etc/onl/loader/versions.json"
|
||||
if os.path.exists(vj):
|
||||
with open(vj) as fd:
|
||||
data = json.load(fd)
|
||||
installerConf.onl_version = data['VERSION_ID']
|
||||
else:
|
||||
installerConf.onl_version = "unknown"
|
||||
|
||||
installerConf.installer_dir = chroot_idir
|
||||
|
||||
abs_postinst = tempfile.mktemp(dir=abs_idir,
|
||||
prefix="postinst-", suffix=".sh")
|
||||
chroot_postinst = abs_postinst[len(ctx.dir):]
|
||||
installerConf.installer_postinst = chroot_postinst
|
||||
|
||||
# make an empty(ish) zip file (local path in installer_dir) for collateral
|
||||
zipPath = tempfile.mktemp(dir=abs_idir,
|
||||
prefix="install-", suffix=".zip")
|
||||
with zipfile.ZipFile(zipPath, "w") as zf:
|
||||
pass
|
||||
installerConf.installer_zip = os.path.split(zipPath)[1]
|
||||
|
||||
# finalize the local installer.conf
|
||||
dst = os.path.join(ctx.dir, "etc/onl/installer.conf")
|
||||
with open(dst, "w") as fd:
|
||||
fd.write(installerConf.dumps())
|
||||
|
||||
# populate installer_dir with the contents of the loader upgrade
|
||||
# See also Loader_Upgrade_x86_64.do_upgrade
|
||||
# Here the initrd filename is as per the installer.zip;
|
||||
# it is renamed on install to the grub directory
|
||||
sdir = sysconfig.upgrade.loader.package.dir
|
||||
|
||||
# get kernels for grub installs:
|
||||
pats = ["kernel-*",]
|
||||
for f in os.listdir(sdir):
|
||||
for pat in pats:
|
||||
if fnmatch.fnmatch(f, pat):
|
||||
src = os.path.join(sdir, f)
|
||||
dst = os.path.join(abs_idir, f)
|
||||
self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
try:
|
||||
l = sysconfig.upgrade.loader.package.grub
|
||||
except AttributeError:
|
||||
l = []
|
||||
for f in l:
|
||||
src = os.path.join(sdir, f)
|
||||
if os.path.exists(src):
|
||||
dst = os.path.join(abs_idir, f)
|
||||
self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
# get FIT files from powerpc installs:
|
||||
try:
|
||||
l = sysconfig.upgrade.loader.package.fit
|
||||
except AttributeError:
|
||||
l = []
|
||||
for f in l:
|
||||
src = os.path.join(sdir, f)
|
||||
if os.path.exists(src):
|
||||
dst = os.path.join(abs_idir, f)
|
||||
self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
#
|
||||
# Disable until a system for boot-config upgrade is implemented.
|
||||
# with OnlMountContextReadWrite('ONL-BOOT', logger=self.log) as octx:
|
||||
# src = os.path.join(octx.directory, "boot-config")
|
||||
# dst = os.path.join(abs_idir, "boot-config")
|
||||
# self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
# shutil.copy2(src, dst)
|
||||
#
|
||||
|
||||
# chroot to the onl-install script
|
||||
##cmd = ('chroot', ctx.dir,
|
||||
## '/bin/sh', '-i')
|
||||
if self.log.level < logging.INFO:
|
||||
cmd = ('chroot', ctx.dir, "/usr/bin/onl-install", "--verbose", "--force",)
|
||||
else:
|
||||
cmd = ('chroot', ctx.dir, "/usr/bin/onl-install", "--force",)
|
||||
try:
|
||||
self.check_call(cmd)
|
||||
except subprocess.CalledProcessError, what:
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
"""XXX roth -- migrate this to onl.install.App.App
|
||||
|
||||
XXX roth -- assume TMPDIR=/tmp.
|
||||
"""
|
||||
|
||||
pm = ProcMountsParser()
|
||||
|
||||
# resize /tmp to be large enough for the initrd, see tmpfs
|
||||
# nonsense in installer.sh.in
|
||||
tflags = None
|
||||
tdev = os.stat('/tmp').st_dev
|
||||
pdir = None
|
||||
for m in pm.mounts:
|
||||
if m.fsType in ('ramfs', 'tmpfs',):
|
||||
dev = os.stat(m.dir).st_dev
|
||||
if dev == tdev:
|
||||
self.log.info("found tmpfs/ramfs %s (%s)", dev, m.flags)
|
||||
pdir = m.dir
|
||||
tflags = m.flags
|
||||
|
||||
# XXX glean this from install.sh.in (installer_tmpfs_kmin)
|
||||
if pdir is None:
|
||||
self.check_call(('mount',
|
||||
'-o', 'size=1048576k',
|
||||
'-t', 'tmpfs',
|
||||
'tmpfs', '/tmp',))
|
||||
else:
|
||||
self.check_call(('mount',
|
||||
'-o', 'remount,size=1048576k',
|
||||
pdir,))
|
||||
|
||||
for m in pm.mounts:
|
||||
if m.dir.startswith('/mnt/onl'):
|
||||
if not self.force:
|
||||
self.log.error("directory %s is still mounted (try --force)", m.dir)
|
||||
return 1
|
||||
self.log.warn("unmounting %s (--force)", m.dir)
|
||||
self.check_call(('umount', m.dir,))
|
||||
|
||||
upgrader = UpgradeHelper(callback=self._runInitrd, log=self.log)
|
||||
try:
|
||||
code = upgrader.run()
|
||||
except:
|
||||
self.log.exception("upgrader failed")
|
||||
code = 1
|
||||
upgrader.shutdown()
|
||||
return code
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def main(cls):
|
||||
|
||||
logging.basicConfig()
|
||||
logger = logging.getLogger("onl-install")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
# send to ONIE log
|
||||
hnd = logging.FileHandler("/dev/console")
|
||||
logger.addHandler(hnd)
|
||||
logger.propagate = False
|
||||
|
||||
onie_verbose = 'onie_verbose' in os.environ
|
||||
installer_debug = 'installer_debug' in os.environ
|
||||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('-v', '--verbose', action='store_true',
|
||||
default=onie_verbose,
|
||||
help="Enable verbose logging")
|
||||
ap.add_argument('-D', '--debug', action='store_true',
|
||||
default=installer_debug,
|
||||
help="Enable python debugging")
|
||||
ap.add_argument('-F', '--force', action='store_true',
|
||||
help="Unmount filesystems before install")
|
||||
ops = ap.parse_args()
|
||||
|
||||
if ops.verbose:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
app = cls(force=ops.force,
|
||||
log=logger)
|
||||
try:
|
||||
code = app.run()
|
||||
except:
|
||||
logger.exception("runner failed")
|
||||
code = 1
|
||||
if ops.debug:
|
||||
app.post_mortem()
|
||||
|
||||
app.shutdown()
|
||||
sys.exit(code)
|
||||
|
||||
main = App.main
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,7 @@
|
||||
"""__init__.py
|
||||
|
||||
Module init for installer plugins.
|
||||
|
||||
DO NOT auto-load modules from here.
|
||||
Rather, drop files here so they will be processed by the installer.
|
||||
"""
|
||||
@@ -137,25 +137,27 @@ class OnlMountManager(object):
|
||||
self.missing = None
|
||||
|
||||
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:
|
||||
t = timeout
|
||||
while t >= 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
|
||||
t -= 1
|
||||
|
||||
if 'device' not in v:
|
||||
self.logger.error("Timeout waiting for block label %s after %d seconds." % (k, timeout))
|
||||
self.missing = k
|
||||
return False
|
||||
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.
|
||||
@@ -273,6 +275,17 @@ class OnlMountManager(object):
|
||||
o.init()
|
||||
o.mount(args.labels, mode=mode)
|
||||
|
||||
@staticmethod
|
||||
def cmdRw(args, register=False):
|
||||
if register:
|
||||
p = args.add_parser('rw')
|
||||
p.add_argument("label")
|
||||
p.add_argument("cmd", nargs='+')
|
||||
p.set_defaults(func=OnlMountManager.cmdRw)
|
||||
else:
|
||||
with OnlMountContextReadWrite(args.label, logger=None):
|
||||
rc = subprocess.call(" ".join(args.cmd), shell=True)
|
||||
sys.exit(rc)
|
||||
|
||||
@staticmethod
|
||||
def cmdFsck(args, register=False):
|
||||
@@ -355,3 +368,14 @@ class OnlMountContextReadWrite(OnlMountContext):
|
||||
def __init__(self, label, logger):
|
||||
OnlMountContext.__init__(self, label, "rw", logger)
|
||||
|
||||
|
||||
class OnlOnieBootContext(MountContext):
|
||||
def __init__(self, mdir="/mnt/onie-boot", mode="rw", label="ONIE-BOOT", logger=None):
|
||||
try:
|
||||
device = subprocess.check_output("blkid -L %s" % label, shell=True).strip()
|
||||
except subprocess.CalledProcessError:
|
||||
self.logger.debug("Block label %s does not yet exist..." % label)
|
||||
raise
|
||||
if not os.path.exists(mdir):
|
||||
os.makedirs(mdir)
|
||||
MountContext.__init__(self, device, mdir, mode, logger)
|
||||
|
||||
@@ -16,6 +16,7 @@ import re
|
||||
import yaml
|
||||
import onl.YamlUtils
|
||||
import subprocess
|
||||
import platform
|
||||
|
||||
class OnlInfoObject(object):
|
||||
DEFAULT_INDENT=" "
|
||||
@@ -43,6 +44,9 @@ class OnlInfoObject(object):
|
||||
"""String representation of the information container."""
|
||||
return OnlInfoObject.string(self._data, indent)
|
||||
|
||||
def update(self, d):
|
||||
self._data.update(d)
|
||||
|
||||
@staticmethod
|
||||
def string(d, indent=DEFAULT_INDENT):
|
||||
return "\n".join( sorted("%s%s: %s" % (indent,k,v) for k,v in d.iteritems() if not k.startswith('_') and d[k] is not None and k != 'CRC'))
|
||||
@@ -114,6 +118,11 @@ class OnlPlatformBase(object):
|
||||
self.add_info_json("platform_info", "%s/platform-info.json" % self.basedir_onl(), PlatformInfo,
|
||||
required=False)
|
||||
|
||||
if hasattr(self, "platform_info"):
|
||||
self.platform_info.update(self.dmi_versions())
|
||||
else:
|
||||
self.add_info_dict("platform_info", self.dmi_versions())
|
||||
|
||||
# Find the base platform config
|
||||
if self.platform().startswith('x86-64'):
|
||||
y1 = self.CONFIG_DEFAULT_GRUB
|
||||
@@ -149,8 +158,12 @@ class OnlPlatformBase(object):
|
||||
|
||||
def add_info_json(self, name, f, klass=None, required=True):
|
||||
if os.path.exists(f):
|
||||
d = json.load(file(f))
|
||||
self.add_info_dict(name, d, klass)
|
||||
try:
|
||||
d = json.load(file(f))
|
||||
self.add_info_dict(name, d, klass)
|
||||
except ValueError, e:
|
||||
if required:
|
||||
raise e
|
||||
elif required:
|
||||
raise RuntimeError("A required system file (%s) is missing." % f)
|
||||
|
||||
@@ -177,6 +190,97 @@ class OnlPlatformBase(object):
|
||||
def baseconfig(self):
|
||||
return True
|
||||
|
||||
def insmod(self, module, required=True):
|
||||
kv = os.uname()[2]
|
||||
searched = []
|
||||
|
||||
# Search paths in this order:
|
||||
locations = [ self.PLATFORM,
|
||||
'-'.join(self.PLATFORM.split('-')[:-1]),
|
||||
'onl',
|
||||
".",
|
||||
]
|
||||
for l in locations:
|
||||
for e in [ ".ko", "" ]:
|
||||
path = "/lib/modules/%s/%s/%s%s" % (kv, l, module, e)
|
||||
searched.append(path)
|
||||
if os.path.exists(path):
|
||||
subprocess.check_call("insmod %s" % path, shell=True)
|
||||
return True
|
||||
|
||||
if required:
|
||||
raise RuntimeError("kernel module %s could not be found. Searched: %s" % (module, searched))
|
||||
else:
|
||||
return False
|
||||
|
||||
def insmod_platform(self):
|
||||
kv = os.uname()[2]
|
||||
# Insert all modules in the platform module directories
|
||||
directories = [ self.PLATFORM,
|
||||
'-'.join(self.PLATFORM.split('-')[:-1]) ]
|
||||
|
||||
for subdir in directories:
|
||||
d = "/lib/modules/%s/%s" % (kv, subdir)
|
||||
if os.path.isdir(d):
|
||||
for f in os.listdir(d):
|
||||
if f.endswith(".ko"):
|
||||
self.insmod(f)
|
||||
|
||||
def onie_machine_get(self):
|
||||
mc = self.basedir_onl("etc/onie/machine.json")
|
||||
if not os.path.exists(mc):
|
||||
data = {}
|
||||
mcconf = subprocess.check_output("""onie-shell -c "cat /etc/machine.conf" """, shell=True)
|
||||
for entry in mcconf.split():
|
||||
(k,e,v) = entry.partition('=')
|
||||
if e:
|
||||
data[k] = v
|
||||
|
||||
if not os.path.exists(os.path.dirname(mc)):
|
||||
os.makedirs(os.path.dirname(mc))
|
||||
|
||||
with open(mc, "w") as f:
|
||||
f.write(json.dumps(data, indent=2))
|
||||
else:
|
||||
data = json.load(open(mc))
|
||||
|
||||
return data
|
||||
|
||||
ONIE_EEPROM_JSON='etc/onie/eeprom.json'
|
||||
|
||||
def onie_syseeprom_get(self):
|
||||
se = self.basedir_onl(self.ONIE_EEPROM_JSON)
|
||||
if not os.path.exists(se):
|
||||
data = {}
|
||||
extensions = []
|
||||
syseeprom = subprocess.check_output("""onie-shell -c onie-syseeprom""", shell=True)
|
||||
e = re.compile(r'(.*?) (0x[0-9a-fA-F][0-9a-fA-F])[ ]+(\d+) (.*)')
|
||||
for line in syseeprom.split('\n'):
|
||||
m = e.match(line)
|
||||
if m:
|
||||
value = m.groups(0)[3]
|
||||
code = m.groups(0)[1].lower()
|
||||
if code == '0xfd':
|
||||
extensions.append(value)
|
||||
else:
|
||||
data[code] = value
|
||||
if len(extensions):
|
||||
data['0xfd'] = extensions
|
||||
|
||||
self.onie_syseeprom_set(data)
|
||||
else:
|
||||
data = json.load(open(se))
|
||||
return data
|
||||
|
||||
def onie_syseeprom_set(self, data):
|
||||
se = self.basedir_onl(self.ONIE_EEPROM_JSON)
|
||||
if not os.path.exists(os.path.dirname(se)):
|
||||
os.makedirs(os.path.dirname(se))
|
||||
|
||||
with open(se, "w") as f:
|
||||
f.write(json.dumps(data, indent=2))
|
||||
|
||||
|
||||
def platform(self):
|
||||
return self.PLATFORM
|
||||
|
||||
@@ -224,6 +328,39 @@ class OnlPlatformBase(object):
|
||||
def firmware_version(self):
|
||||
return self.platform_info.CPLD_VERSIONS
|
||||
|
||||
def dmi_versions(self):
|
||||
# Note - the dmidecode module returns empty lists for powerpc systems.
|
||||
if platform.machine() != "x86_64":
|
||||
return {}
|
||||
|
||||
try:
|
||||
import dmidecode
|
||||
except ImportError:
|
||||
return {}
|
||||
|
||||
fields = [
|
||||
{
|
||||
'name': 'DMI BIOS Version',
|
||||
'subsystem': dmidecode.bios,
|
||||
'dmi_type' : 0,
|
||||
'key' : 'Version',
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'DMI System Version',
|
||||
'subsystem': dmidecode.system,
|
||||
'dmi_type' : 1,
|
||||
'key' : 'Version',
|
||||
},
|
||||
]
|
||||
rv = {}
|
||||
for field in fields:
|
||||
for v in field['subsystem']().values():
|
||||
if type(v) is dict and v['dmi_type'] == field['dmi_type']:
|
||||
rv[field['name']] = v['data'][field['key']]
|
||||
|
||||
return rv
|
||||
|
||||
def upgrade_manifest(self, type_, override_dir=None):
|
||||
if override_dir:
|
||||
m = os.path.join(override_dir, "manifest.json")
|
||||
|
||||
@@ -16,6 +16,9 @@ class FirmwareUpgrade(ubase.BaseOnieUpgrade):
|
||||
current_version_key="Current Firmware Version"
|
||||
next_version_key="Next Firmware Version"
|
||||
|
||||
def auto_upgrade_default(self):
|
||||
return sysconfig.upgrade.firmware.auto
|
||||
|
||||
def init_versions(self):
|
||||
|
||||
# Get the current platform firmware version
|
||||
@@ -25,8 +28,12 @@ class FirmwareUpgrade(ubase.BaseOnieUpgrade):
|
||||
self.load_manifest(os.path.join(sysconfig.upgrade.firmware.package.dir, "manifest.json"))
|
||||
|
||||
def do_upgrade(self, forced=False):
|
||||
self.install_onie_updater(sysconfig.upgrade.firmware.package.dir,
|
||||
self.manifest['updater'])
|
||||
if self.manifest.get('fwpkg', False):
|
||||
self.onie_fwpkg_add(os.path.join(sysconfig.upgrade.firmware.package.dir,
|
||||
self.manifest['updater']))
|
||||
else:
|
||||
self.install_onie_updater(sysconfig.upgrade.firmware.package.dir,
|
||||
self.manifest['updater'])
|
||||
self.initiate_onie_update()
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ import fnmatch
|
||||
from onl.upgrade import ubase
|
||||
from onl.sysconfig import sysconfig
|
||||
from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite
|
||||
from onl.install import BaseInstall, ConfUtils, InstallUtils
|
||||
from onl.install.ShellApp import OnieBootContext
|
||||
import onl.platform.current
|
||||
import onl.versions
|
||||
|
||||
class LoaderUpgradeBase(ubase.BaseUpgrade):
|
||||
name="loader"
|
||||
@@ -57,9 +61,10 @@ class LoaderUpgradeBase(ubase.BaseUpgrade):
|
||||
* A single reboot will be required to complete this upgrade.
|
||||
"""
|
||||
|
||||
|
||||
class LoaderUpgrade_Fit(LoaderUpgradeBase):
|
||||
|
||||
installer_klass = BaseInstall.UbootInstaller
|
||||
|
||||
def do_upgrade(self, forced=False):
|
||||
|
||||
fit_image = None
|
||||
@@ -75,10 +80,49 @@ class LoaderUpgrade_Fit(LoaderUpgradeBase):
|
||||
with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d:
|
||||
self.copyfile(fit_image, os.path.join(d.directory, "%s.itb" % (self.platform.platform())))
|
||||
|
||||
onlPlatform = onl.platform.current.OnlPlatform()
|
||||
|
||||
with OnieBootContext(log=self.logger) as octx:
|
||||
path = os.path.join(octx.initrdDir, "etc/machine.conf")
|
||||
machineConf = ConfUtils.MachineConf(path=path)
|
||||
|
||||
installerConf = ConfUtils.InstallerConf(path="/dev/null")
|
||||
# start with an empty installerConf, fill it in piece by piece
|
||||
|
||||
installerConf.installer_platform = onlPlatform.platform()
|
||||
installerConf.installer_arch = machineConf.onie_arch
|
||||
installerConf.installer_platform_dir = os.path.join("/lib/platform-config",
|
||||
onlPlatform.platform())
|
||||
|
||||
mfPath = os.path.join(sysconfig.upgrade.loader.package.dir, "manifest.json")
|
||||
mf = onl.versions.OnlVersionManifest(mfPath)
|
||||
installerConf.onl_version = mf.RELEASE_ID
|
||||
|
||||
grubEnv = ConfUtils.ProxyGrubEnv(installerConf,
|
||||
bootDir="/mnt/onie-boot",
|
||||
path="/grub/grubenv",
|
||||
chroot=False,
|
||||
log=self.logger.getChild("grub"))
|
||||
|
||||
ubootEnv = ConfUtils.UbootEnv(log=self.logger.getChild("u-boot"))
|
||||
|
||||
installer = self.installer_klass(machineConf=machineConf,
|
||||
installerConf=installerConf,
|
||||
platformConf=onlPlatform.platform_config,
|
||||
grubEnv=grubEnv,
|
||||
ubootEnv=ubootEnv,
|
||||
force=True,
|
||||
log=self.logger)
|
||||
|
||||
installer.upgradeBootLoader()
|
||||
installer.shutdown()
|
||||
|
||||
self.reboot()
|
||||
|
||||
|
||||
class LoaderUpgrade_x86_64(LoaderUpgradeBase):
|
||||
class LoaderUpgrade_x86_64(LoaderUpgradeBase, InstallUtils.SubprocessMixin):
|
||||
|
||||
installer_klass = BaseInstall.GrubInstaller
|
||||
|
||||
def do_upgrade(self, forced=False):
|
||||
|
||||
@@ -110,6 +154,55 @@ class LoaderUpgrade_x86_64(LoaderUpgradeBase):
|
||||
#if os.path.exists(src):
|
||||
# self.copyfile(src, dst)
|
||||
|
||||
# installer assumes that partitions are unmounted
|
||||
|
||||
self.log = self.logger
|
||||
# ha ha, SubprocessMixin api is different
|
||||
|
||||
pm = InstallUtils.ProcMountsParser()
|
||||
for m in pm.mounts:
|
||||
if m.dir.startswith('/mnt/onl'):
|
||||
self.logger.warn("unmounting %s (--force)", m.dir)
|
||||
self.check_call(('umount', m.dir,))
|
||||
|
||||
onlPlatform = onl.platform.current.OnlPlatform()
|
||||
|
||||
with OnieBootContext(log=self.logger) as octx:
|
||||
path = os.path.join(octx.initrdDir, "etc/machine.conf")
|
||||
machineConf = ConfUtils.MachineConf(path=path)
|
||||
|
||||
# hold on to the ONIE boot context for grub access
|
||||
|
||||
installerConf = ConfUtils.InstallerConf(path="/dev/null")
|
||||
|
||||
# XXX fill in installerConf fields
|
||||
installerConf.installer_platform = onlPlatform.platform()
|
||||
installerConf.installer_arch = machineConf.onie_arch
|
||||
installerConf.installer_platform_dir = os.path.join("/lib/platform-config",
|
||||
onlPlatform.platform())
|
||||
|
||||
mfPath = os.path.join(sysconfig.upgrade.loader.package.dir, "manifest.json")
|
||||
mf = onl.versions.OnlVersionManifest(mfPath)
|
||||
installerConf.onl_version = mf.RELEASE_ID
|
||||
|
||||
grubEnv = ConfUtils.ChrootGrubEnv(octx.initrdDir,
|
||||
bootDir=octx.onieDir,
|
||||
path="/grub/grubenv",
|
||||
log=self.logger.getChild("grub"))
|
||||
|
||||
ubootEnv = None
|
||||
|
||||
installer = self.installer_klass(machineConf=machineConf,
|
||||
installerConf=installerConf,
|
||||
platformConf=onlPlatform.platform_config,
|
||||
grubEnv=grubEnv,
|
||||
ubootEnv=ubootEnv,
|
||||
force=True,
|
||||
log=self.logger)
|
||||
|
||||
installer.upgradeBootLoader()
|
||||
installer.shutdown()
|
||||
|
||||
self.reboot()
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ class OnieUpgrade(ubase.BaseOnieUpgrade):
|
||||
current_version_key="Current ONIE Version"
|
||||
next_version_key="Next ONIE Version"
|
||||
|
||||
def auto_upgrade_default(self):
|
||||
return sysconfig.upgrade.onie.auto
|
||||
|
||||
def init_versions(self):
|
||||
# Get the current platform ONIE version
|
||||
self.current_version = self.platform.onie_version()
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/python
|
||||
############################################################
|
||||
#
|
||||
# ONL System Upgrade
|
||||
#
|
||||
############################################################
|
||||
import os
|
||||
import sys
|
||||
import fnmatch
|
||||
from onl.upgrade import ubase
|
||||
from onl.sysconfig import sysconfig
|
||||
from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite
|
||||
|
||||
from onl.install.SystemInstall import App
|
||||
|
||||
class SystemUpgrade(ubase.BaseUpgrade):
|
||||
name="system"
|
||||
Name="System"
|
||||
title="System Compatibility Version Check"
|
||||
atype="A Compatible System"
|
||||
|
||||
current_version_key="Current System Compatibility Version"
|
||||
next_version_key="Next System Compatibility Version"
|
||||
|
||||
def auto_upgrade_default(self):
|
||||
return sysconfig.upgrade.system.auto
|
||||
|
||||
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 = sysconfig.upgrade.loader.versions
|
||||
|
||||
# Upgrade Loader Version file.
|
||||
NEXT_LOADER_VERSIONS_JSON = os.path.join(sysconfig.upgrade.loader.package.dir, "manifest.json")
|
||||
|
||||
VKEY = "SYSTEM_COMPATIBILITY_VERSION"
|
||||
|
||||
self.current_version = self.load_json(ETC_LOADER_VERSIONS_JSON, VKEY, None)
|
||||
|
||||
self.next_version = self.load_json(NEXT_LOADER_VERSIONS_JSON,
|
||||
"version", {}).get(VKEY, None)
|
||||
|
||||
def prepare_upgrade(self):
|
||||
pass
|
||||
|
||||
def summarize(self):
|
||||
self.logger.info("Current System Compatibility Version: %s",
|
||||
self.current_version)
|
||||
self.logger.info(" Next System Compatibility Version: %s",
|
||||
self.next_version)
|
||||
self.logger.info("")
|
||||
|
||||
|
||||
def upgrade_notes(self):
|
||||
return """
|
||||
* One or more reboots will be required to complete this upgrade.
|
||||
"""
|
||||
|
||||
def do_upgrade(self, forced=False):
|
||||
app = App(force=True, log=self.logger)
|
||||
try:
|
||||
code = app.run()
|
||||
except:
|
||||
self.logger.exception("upgrade failed")
|
||||
code = 1
|
||||
app.shutdown()
|
||||
if code:
|
||||
self.abort("System upgrade failed.")
|
||||
else:
|
||||
self.logger.info("Upgrade succeeded, rebooting")
|
||||
self.reboot()
|
||||
|
||||
if __name__ == '__main__':
|
||||
klass = SystemUpgrade
|
||||
klass().main()
|
||||
@@ -176,8 +176,9 @@ class BaseUpgrade(object):
|
||||
def update_upgrade_status(self, key, value):
|
||||
data = self.upgrade_status_get()
|
||||
data[key] = value
|
||||
with open(self.UPGRADE_STATUS_JSON, "w") as f:
|
||||
json.dump(data, f)
|
||||
if os.path.exists(os.path.dirname(BaseUpgrade.UPGRADE_STATUS_JSON)):
|
||||
with open(self.UPGRADE_STATUS_JSON, "w") as f:
|
||||
json.dump(data, f)
|
||||
|
||||
#
|
||||
# Initialize self.current_version, self.next_Version
|
||||
@@ -390,24 +391,23 @@ class BaseOnieUpgrade(BaseUpgrade):
|
||||
dst = os.path.join(self.ONIE_UPDATER_PATH, f)
|
||||
self.copyfile(src, dst)
|
||||
|
||||
def onie_fwpkg_add(self, pkg):
|
||||
import onl.grub
|
||||
onl.grub.onie_fwpkg("add %s" % pkg)
|
||||
onl.grub.onie_fwpkg("show")
|
||||
|
||||
def initiate_onie_update(self):
|
||||
self.logger.info("Initiating %s Update." % self.Name)
|
||||
|
||||
if self.arch == 'ppc':
|
||||
# Initiate update
|
||||
self.fw_setenv('onie_boot_reason', 'update')
|
||||
self.reboot()
|
||||
|
||||
elif self.arch == 'x86_64':
|
||||
OB = "/mnt/onie-boot"
|
||||
self.mount(OB, label="ONIE-BOOT")
|
||||
if os.system("/mnt/onie-boot/onie/tools/bin/onie-boot-mode -o update") != 0:
|
||||
self.abort("Could not set ONIE Boot Mode to Update. Upgrade cannot continue.")
|
||||
self.umount(OB)
|
||||
|
||||
with OnlMountContextReadWrite("ONL-BOOT", logger=None):
|
||||
with open("/mnt/onl/boot/grub/grub.cfg", "a") as f:
|
||||
f.write("set default=ONIE\n")
|
||||
import onl.grub
|
||||
onl.grub.onie_boot_mode_set("update")
|
||||
onl.grub.boot_onie()
|
||||
self.reboot()
|
||||
|
||||
else:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
import json
|
||||
|
||||
class OnlVersionManifest(object):
|
||||
@@ -30,8 +31,8 @@ class OnlLoaderVersion(OnlVersionBase):
|
||||
#
|
||||
# print onl.versions.rootfs.BUILD_TIMESTAMP
|
||||
#
|
||||
|
||||
rootfs = OnlRootfsVersion()
|
||||
loader = OnlLoaderVersion()
|
||||
rootfs = OnlRootfsVersion() if os.path.exists(OnlRootfsVersion.MANIFEST) else None
|
||||
loader = OnlLoaderVersion() if os.path.exists(OnlLoaderVersion.MANIFEST) else None
|
||||
|
||||
|
||||
|
||||
|
||||
7
packages/base/all/vendor-config-onl/src/sbin/onl-install-system
Executable file
7
packages/base/all/vendor-config-onl/src/sbin/onl-install-system
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Re-install ONL using the ONL installer infrastructure.
|
||||
"""
|
||||
|
||||
import onl.install.SystemInstall
|
||||
onl.install.SystemInstall.main()
|
||||
3
packages/base/all/vendor-config-onl/src/sbin/onl-upgrade-system
Executable file
3
packages/base/all/vendor-config-onl/src/sbin/onl-upgrade-system
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/python
|
||||
from onl.upgrade.system import SystemUpgrade
|
||||
SystemUpgrade().main()
|
||||
@@ -3,26 +3,25 @@ set -e
|
||||
|
||||
uninstall_x86_64()
|
||||
{
|
||||
#
|
||||
# Set ONIE boot selection to uninstall
|
||||
#
|
||||
mkdir -p /mnt/onie-boot
|
||||
mount -L ONIE-BOOT /mnt/onie-boot > /dev/null 2>&1
|
||||
if [ "$1" = "manual" ]; then
|
||||
# Clear any ONIE boot selection settings and default to Install
|
||||
mkdir -p /mnt/onie-boot
|
||||
mount `blkid -L ONIE-BOOT` /mnt/onie-boot
|
||||
rm -rf /mnt/onie-boot/grubenv
|
||||
umount /mnt/onie-boot
|
||||
|
||||
# Force ONIE boot selection
|
||||
onlfs mount boot --rw
|
||||
echo "default=1" >> /mnt/onl/boot/grub/grub.cfg
|
||||
|
||||
if [ "$1" = "factory" ]; then
|
||||
/mnt/onie-boot/onie/tools/bin/onie-boot-mode -o uninstall
|
||||
else
|
||||
/mnt/onie-boot/onie/tools/bin/onie-boot-mode -o install
|
||||
if [ "$1" = "factory" ]; then
|
||||
mode=uninstall
|
||||
else
|
||||
mode=install
|
||||
fi
|
||||
onl-onie-boot-mode $mode
|
||||
fi
|
||||
|
||||
umount /mnt/onie-boot
|
||||
|
||||
#
|
||||
# Select ONIE as the boot default
|
||||
#
|
||||
onl-mounts mount boot --rw
|
||||
echo "set default=ONIE" >> /mnt/onl/boot/grub/grub.cfg
|
||||
onl-mounts mount boot
|
||||
}
|
||||
|
||||
uninstall_uboot()
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
common:
|
||||
arch: amd64
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
|
||||
packages:
|
||||
- name: onl-kernel-3.16+deb8-x86-64-all
|
||||
version: 1.0.0
|
||||
summary: Open Network Linux Kernel 3.16-deb8 for X86_64 Platforms.
|
||||
|
||||
files:
|
||||
builds/kernel-3.16+deb8-x86_64-all : $$PKG_INSTALL/
|
||||
builds/linux-3.16.7-ckt25-mbuild : $$PKG_INSTALL/mbuilds
|
||||
|
||||
changelog: Change changes changes.,
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
variables:
|
||||
basename: onl-kernel-3.16-lts-x86-64-all
|
||||
|
||||
common:
|
||||
arch: amd64
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: $basename
|
||||
version: 1.0.0
|
||||
summary: Open Network Linux 3.16 LTS Kernel for X86_64 Platforms.
|
||||
|
||||
files:
|
||||
builds/kernel-3.16* : $$PKG_INSTALL/
|
||||
builds/linux-*mbuild : $$PKG_INSTALL/mbuilds
|
||||
|
||||
changelog: Change changes changes.,
|
||||
|
||||
- name: $basename-modules
|
||||
version: 1.0.0
|
||||
summary: Open Network Linux 3.16 LTS Kernel Modules for X86_64 Platforms
|
||||
|
||||
files:
|
||||
builds/lib: /lib
|
||||
|
||||
changelog: Change changes changes.,
|
||||
@@ -1,2 +1,3 @@
|
||||
linux-*
|
||||
kernel-*
|
||||
lib
|
||||
@@ -13,7 +13,8 @@ THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
include $(ONL)/make/config.mk
|
||||
|
||||
kernel:
|
||||
$(MAKE) -C $(ONL)/packages/base/any/kernels/3.16+deb8/configs/x86_64-all K_TARGET_DIR=$(THIS_DIR) $(ONL_MAKE_PARALLEL)
|
||||
$(MAKE) -C $(ONL)/packages/base/any/kernels/3.16-lts/configs/x86_64-all K_TARGET_DIR=$(THIS_DIR) $(ONL_MAKE_PARALLEL)
|
||||
ARCH=x86_64 $(ONL)/tools/scripts/kmodbuild.sh linux-3.16.39-mbuild "$(wildcard $(ONL)/packages/base/any/kernels/modules/*)" onl
|
||||
|
||||
clean:
|
||||
rm -rf linux-3.16* kernel-3.16*
|
||||
@@ -4,6 +4,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-kernel-3.18-x86-64-all
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
variables:
|
||||
basename: onl-kernel-3.2-deb7-x86-64-all
|
||||
|
||||
common:
|
||||
arch: amd64
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-kernel-3.2-deb7-x86-64-all
|
||||
- name: $basename
|
||||
version: 1.0.0
|
||||
summary: Open Network Linux Kernel 3.2-deb7 for X86_64 Platforms.
|
||||
|
||||
@@ -16,6 +19,11 @@ packages:
|
||||
|
||||
changelog: Change changes changes.,
|
||||
|
||||
- name: $basename-modules
|
||||
version: 1.0.0
|
||||
summary: Open Network Linux 3.2 Kernel Modules for X86_64 Platforms
|
||||
|
||||
files:
|
||||
builds/lib: /lib
|
||||
|
||||
|
||||
changelog: Change changes changes.,
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
linux-3.2.65-1+deb7u2*
|
||||
kernel-3.2-deb7-x86_64-all
|
||||
kernel-3.2-deb7-x86_64-all
|
||||
lib
|
||||
|
||||
@@ -14,6 +14,6 @@ include $(ONL)/make/config.mk
|
||||
|
||||
kernel:
|
||||
$(MAKE) -C $(ONL)/packages/base/any/kernels/3.2.65-1+deb7u2/configs/x86_64-all K_TARGET_DIR=$(THIS_DIR) $(ONL_MAKE_PARALLEL)
|
||||
|
||||
ARCH=x86_64 $(ONL)/tools/scripts/kmodbuild.sh linux-3.2.65-1+deb7u2-mbuild "$(wildcard $(ONL)/packages/base/any/kernels/modules/*)" onl
|
||||
clean:
|
||||
rm -rf linux-3.2.65-1+deb7u2 linux-3.2.65-1+deb7u2-mbuild
|
||||
|
||||
@@ -7,6 +7,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-kernel-3.9.6-x86-64-all
|
||||
|
||||
@@ -3,7 +3,7 @@ prerequisites:
|
||||
- onl-kernel-3.9.6-x86-64-all:amd64
|
||||
- onl-kernel-3.2-deb7-x86-64-all:amd64
|
||||
- onl-kernel-3.18-x86-64-all:amd64
|
||||
- onl-kernel-3.16+deb8-x86-64-all:amd64
|
||||
- onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
- onl-loader-initrd:amd64
|
||||
|
||||
common:
|
||||
@@ -11,6 +11,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-upgrade
|
||||
|
||||
@@ -4,7 +4,7 @@ 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) \
|
||||
$(shell $(ONLPM) --find-file onl-kernel-3.16+deb8-x86-64-all:amd64 kernel-3.16+deb8-x86_64-all) \
|
||||
$(shell $(ONLPM) --find-file onl-kernel-3.16-lts-x86-64-all:amd64 kernel-3.16-lts-x86_64-all) \
|
||||
|
||||
|
||||
# Loader initrd
|
||||
@@ -16,5 +16,3 @@ all:
|
||||
cp $(KERNELS) files
|
||||
cp $(INITRD) files
|
||||
cp $(MANIFEST) files
|
||||
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
|
||||
support: opennetworklinux@googlegroups.com
|
||||
depends: base-files
|
||||
packages:
|
||||
- name: onl-faultd
|
||||
version: 1.0.0
|
||||
summary: Fault Reporting Daemon
|
||||
provides: [ faultd ]
|
||||
|
||||
files:
|
||||
builds/$BUILD_DIR/${TOOLCHAIN}/bin/faultd.bin : /usr/bin/faultd
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-buildroot-fit
|
||||
|
||||
@@ -7,6 +7,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-loader-fit
|
||||
|
||||
@@ -14,6 +14,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-buildroot-initrd
|
||||
|
||||
@@ -13,6 +13,7 @@ common:
|
||||
version: 1.0.0
|
||||
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
|
||||
maintainer: support@bigswitch.com
|
||||
support: opennetworklinux@googlegroups.com
|
||||
|
||||
packages:
|
||||
- name: onl-loader-initrd
|
||||
|
||||
@@ -1,280 +0,0 @@
|
||||
+ 0x75diff -urpN a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c 2016-03-02 10:31:21.000000000 +0000
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c 2016-09-15 19:55:02.680725611 +0000
|
||||
@@ -179,8 +179,11 @@ static s32 igb_init_phy_params_82575(str
|
||||
ctrl_ext = rd32(E1000_CTRL_EXT);
|
||||
|
||||
if (igb_sgmii_active_82575(hw)) {
|
||||
- phy->ops.reset = igb_phy_hw_reset_sgmii_82575;
|
||||
- ctrl_ext |= E1000_CTRL_I2C_ENA;
|
||||
+ if(phy->type == e1000_phy_bcm5461s)
|
||||
+ phy->ops.reset = igb_phy_hw_reset;
|
||||
+ else
|
||||
+ phy->ops.reset = igb_phy_hw_reset_sgmii_82575;
|
||||
+ ctrl_ext |= E1000_CTRL_I2C_ENA;
|
||||
} else {
|
||||
phy->ops.reset = igb_phy_hw_reset;
|
||||
ctrl_ext &= ~E1000_CTRL_I2C_ENA;
|
||||
@@ -286,6 +289,19 @@ static s32 igb_init_phy_params_82575(str
|
||||
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 BCM5461S_PHY_ID:
|
||||
+ phy->type = e1000_phy_bcm5461s;
|
||||
+ phy->ops.check_polarity = NULL;
|
||||
+ phy->ops.get_phy_info = igb_get_phy_info_5461s;
|
||||
+ phy->ops.get_cable_length = NULL;
|
||||
+ phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580;
|
||||
+ break;
|
||||
+
|
||||
+ case BCM54616_E_PHY_ID:
|
||||
+ phy->type = e1000_phy_bcm54616;
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
goto out;
|
||||
@@ -827,9 +843,9 @@ static s32 igb_get_phy_id_82575(struct e
|
||||
break;
|
||||
case e1000_82580:
|
||||
case e1000_i350:
|
||||
- case e1000_i354:
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
+ case e1000_i354:
|
||||
mdic = rd32(E1000_MDICNFG);
|
||||
mdic &= E1000_MDICNFG_PHY_MASK;
|
||||
phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
|
||||
@@ -840,6 +856,17 @@ static s32 igb_get_phy_id_82575(struct e
|
||||
break;
|
||||
}
|
||||
ret_val = igb_get_phy_id(hw);
|
||||
+
|
||||
+ if (ret_val && hw->mac.type == e1000_i354) {
|
||||
+ /* we do a special check for bcm5461s phy by setting
|
||||
+ * the phy->addr to 5 and doing the phy check again. This
|
||||
+ * call will succeed and retrieve a valid phy id if we have
|
||||
+ * the bcm5461s phy
|
||||
+ */
|
||||
+ phy->addr = 5;
|
||||
+ phy->type = e1000_phy_bcm5461s;
|
||||
+ ret_val = igb_get_phy_id(hw);
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1220,6 +1247,9 @@ static s32 igb_get_cfg_done_82575(struct
|
||||
(hw->phy.type == e1000_phy_igp_3))
|
||||
igb_phy_init_script_igp3(hw);
|
||||
|
||||
+ if (hw->phy.type == e1000_phy_bcm5461s)
|
||||
+ igb_phy_init_script_5461s(hw);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1552,6 +1582,7 @@ static s32 igb_setup_copper_link_82575(s
|
||||
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);
|
||||
@@ -1595,6 +1626,10 @@ static s32 igb_setup_copper_link_82575(s
|
||||
case e1000_phy_82580:
|
||||
ret_val = igb_copper_link_setup_82580(hw);
|
||||
break;
|
||||
+ case e1000_phy_bcm54616:
|
||||
+ break;
|
||||
+ case e1000_phy_bcm5461s:
|
||||
+ break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
break;
|
||||
diff -urpN a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h 2016-03-02 10:31:21.000000000 +0000
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h 2016-09-15 19:55:27.068726140 +0000
|
||||
@@ -860,6 +860,8 @@
|
||||
#define M88_VENDOR 0x0141
|
||||
#define I210_I_PHY_ID 0x01410C00
|
||||
#define M88E1543_E_PHY_ID 0x01410EA0
|
||||
+#define BCM54616_E_PHY_ID 0x3625D10
|
||||
+#define BCM5461S_PHY_ID 0x002060C0
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
diff -urpN a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h 2016-03-02 10:31:21.000000000 +0000
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h 2016-09-15 19:55:44.584726520 +0000
|
||||
@@ -128,6 +128,8 @@ enum e1000_phy_type {
|
||||
e1000_phy_ife,
|
||||
e1000_phy_82580,
|
||||
e1000_phy_i210,
|
||||
+ e1000_phy_bcm54616,
|
||||
+ e1000_phy_bcm5461s,
|
||||
};
|
||||
|
||||
enum e1000_bus_type {
|
||||
diff -urpN a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c 2016-03-02 10:31:21.000000000 +0000
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c 2016-09-15 20:07:34.964741935 +0000
|
||||
@@ -148,6 +148,14 @@ s32 igb_read_phy_reg_mdic(struct e1000_h
|
||||
* Control register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
+
|
||||
+ if (phy->type == e1000_phy_bcm5461s) {
|
||||
+ mdic = rd32(E1000_MDICNFG);
|
||||
+ mdic &= ~E1000_MDICNFG_PHY_MASK;
|
||||
+ mdic |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
|
||||
+ wr32(E1000_MDICNFG, mdic);
|
||||
+ }
|
||||
+
|
||||
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
|
||||
(phy->addr << E1000_MDIC_PHY_SHIFT) |
|
||||
(E1000_MDIC_OP_READ));
|
||||
@@ -204,6 +212,14 @@ s32 igb_write_phy_reg_mdic(struct e1000_
|
||||
* Control register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
+
|
||||
+ if (phy->type == e1000_phy_bcm5461s) {
|
||||
+ mdic = rd32(E1000_MDICNFG);
|
||||
+ mdic &= ~E1000_MDICNFG_PHY_MASK;
|
||||
+ mdic |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
|
||||
+ wr32(E1000_MDICNFG, mdic);
|
||||
+ }
|
||||
+
|
||||
mdic = (((u32)data) |
|
||||
(offset << E1000_MDIC_REG_SHIFT) |
|
||||
(phy->addr << E1000_MDIC_PHY_SHIFT) |
|
||||
@@ -1115,11 +1131,13 @@ s32 igb_setup_copper_link(struct e1000_h
|
||||
* depending on user settings.
|
||||
*/
|
||||
hw_dbg("Forcing Speed and Duplex\n");
|
||||
- ret_val = hw->phy.ops.force_speed_duplex(hw);
|
||||
- if (ret_val) {
|
||||
+ if(hw->phy.ops.force_speed_duplex) {
|
||||
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
|
||||
+ if (ret_val) {
|
||||
hw_dbg("Error Forcing Speed and Duplex\n");
|
||||
goto out;
|
||||
- }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Check link status. Wait up to 100 microseconds for link to become
|
||||
@@ -2509,3 +2527,67 @@ static s32 igb_set_master_slave_mode(str
|
||||
|
||||
return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data);
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * igb_phy_init_script_5461s - Inits the BCM5461S PHY
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * Initializes a Broadcom Gigabit PHY.
|
||||
+ **/
|
||||
+s32 igb_phy_init_script_5461s(struct e1000_hw *hw)
|
||||
+{
|
||||
+ u16 mii_reg_led = 0;
|
||||
+
|
||||
+ /* 1. Speed LED (Set the Link LED mode), Shadow 00010, 0x1C.bit2=1 */
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, 0x0800);
|
||||
+ hw->phy.ops.read_reg(hw, 0x1C, &mii_reg_led);
|
||||
+ mii_reg_led |= 0x0004;
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, mii_reg_led | 0x8000);
|
||||
+
|
||||
+ /* 2. Active LED (Set the Link LED mode), Shadow 01001, 0x1C.bit4=1, 0x10.bit5=0 */
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, 0x2400);
|
||||
+ hw->phy.ops.read_reg(hw, 0x1C, &mii_reg_led);
|
||||
+ mii_reg_led |= 0x0010;
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, mii_reg_led | 0x8000);
|
||||
+ hw->phy.ops.read_reg(hw, 0x10, &mii_reg_led);
|
||||
+ mii_reg_led &= 0xffdf;
|
||||
+ hw->phy.ops.write_reg(hw, 0x10, mii_reg_led);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * igb_get_phy_info_5461s - Retrieve 5461s PHY information
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * Read PHY status to determine if link is up. If link is up, then
|
||||
+ * set/determine 10base-T extended distance and polarity correction. Read
|
||||
+ * PHY port status to determine MDI/MDIx and speed. Based on the speed,
|
||||
+ * determine on the cable length, local and remote receiver.
|
||||
+ **/
|
||||
+s32 igb_get_phy_info_5461s(struct e1000_hw *hw)
|
||||
+{
|
||||
+ struct e1000_phy_info *phy = &hw->phy;
|
||||
+ s32 ret_val;
|
||||
+ bool link;
|
||||
+
|
||||
+ ret_val = igb_phy_has_link(hw, 1, 0, &link);
|
||||
+ if (ret_val)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!link) {
|
||||
+ ret_val = -E1000_ERR_CONFIG;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ phy->polarity_correction = true;
|
||||
+
|
||||
+ phy->is_mdix = true;
|
||||
+ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
|
||||
+ phy->local_rx = e1000_1000t_rx_status_ok;
|
||||
+ phy->remote_rx = e1000_1000t_rx_status_ok;
|
||||
+
|
||||
+out:
|
||||
+ return ret_val;
|
||||
+}
|
||||
diff -urpN a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_phy.h 2016-03-02 10:31:21.000000000 +0000
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h 2016-09-15 19:41:43.584708271 +0000
|
||||
@@ -61,6 +61,8 @@ s32 igb_phy_has_link(struct e1000_hw *h
|
||||
void igb_power_up_phy_copper(struct e1000_hw *hw);
|
||||
void igb_power_down_phy_copper(struct e1000_hw *hw);
|
||||
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
|
||||
+s32 igb_phy_init_script_5461s(struct e1000_hw *hw);
|
||||
+s32 igb_get_phy_info_5461s(struct e1000_hw *hw);
|
||||
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
diff -urpN a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
|
||||
--- a/drivers/net/ethernet/intel/igb/igb_main.c 2016-03-02 10:31:21.000000000 +0000
|
||||
+++ b/drivers/net/ethernet/intel/igb/igb_main.c 2016-09-15 19:56:53.276728011 +0000
|
||||
@@ -108,6 +108,7 @@ static const struct pci_device_id igb_pc
|
||||
{ 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, }
|
||||
};
|
||||
@@ -7198,11 +7199,19 @@ static int igb_mii_ioctl(struct net_devi
|
||||
data->phy_id = adapter->hw.phy.addr;
|
||||
break;
|
||||
case SIOCGMIIREG:
|
||||
+ adapter->hw.phy.addr = data->phy_id;
|
||||
if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
|
||||
&data->val_out))
|
||||
return -EIO;
|
||||
break;
|
||||
case SIOCSMIIREG:
|
||||
+ if (!capable(CAP_NET_ADMIN))
|
||||
+ return -EPERM;
|
||||
+ adapter->hw.phy.addr = data->phy_id;
|
||||
+ if (igb_write_phy_reg(&adapter->hw, data->reg_num & 0x1F,
|
||||
+ data->val_in))
|
||||
+ return -EIO;
|
||||
+ break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -18,10 +18,6 @@
|
||||
#
|
||||
# </bsn.cl>
|
||||
############################################################
|
||||
#
|
||||
# Default 3.18.25 configuration for x86_64 platforms.
|
||||
#
|
||||
############################################################
|
||||
THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
include $(ONL)/make/config.mk
|
||||
|
||||
@@ -35,8 +31,7 @@ K_CONFIG := x86_64-all.config
|
||||
K_BUILD_TARGET := bzImage
|
||||
K_COPY_SRC := arch/x86/boot/bzImage
|
||||
ifndef K_COPY_DST
|
||||
K_COPY_DST := kernel-3.16+deb8-x86_64-all
|
||||
K_COPY_DST := kernel-3.16-lts-x86_64-all
|
||||
endif
|
||||
|
||||
include $(ONL)/make/kbuild.mk
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/x86_64 3.16.7-ckt25 Kernel Configuration
|
||||
# Linux/x86_64 3.16.39 Kernel Configuration
|
||||
#
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_X86_64=y
|
||||
@@ -151,7 +151,6 @@ CONFIG_PROC_PID_CPUSET=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_MEMCG=y
|
||||
# CONFIG_MEMCG_DISABLED is not set
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_MEMCG_SWAP_ENABLED=y
|
||||
CONFIG_MEMCG_KMEM=y
|
||||
@@ -1462,7 +1461,34 @@ CONFIG_PATA_RZ1000=y
|
||||
# CONFIG_PATA_ACPI is not set
|
||||
CONFIG_ATA_GENERIC=y
|
||||
# CONFIG_PATA_LEGACY is not set
|
||||
# CONFIG_MD is not set
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=y
|
||||
# CONFIG_MD_AUTODETECT is not set
|
||||
# CONFIG_MD_LINEAR is not set
|
||||
# CONFIG_MD_RAID0 is not set
|
||||
# CONFIG_MD_RAID1 is not set
|
||||
# CONFIG_MD_RAID10 is not set
|
||||
# CONFIG_MD_RAID456 is not set
|
||||
# CONFIG_MD_MULTIPATH is not set
|
||||
# CONFIG_MD_FAULTY is not set
|
||||
# CONFIG_BCACHE is not set
|
||||
CONFIG_BLK_DEV_DM_BUILTIN=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
# CONFIG_DM_DEBUG is not set
|
||||
CONFIG_DM_CRYPT=y
|
||||
# CONFIG_DM_SNAPSHOT is not set
|
||||
# CONFIG_DM_THIN_PROVISIONING is not set
|
||||
# CONFIG_DM_CACHE is not set
|
||||
# CONFIG_DM_ERA is not set
|
||||
# CONFIG_DM_MIRROR is not set
|
||||
# CONFIG_DM_RAID is not set
|
||||
# CONFIG_DM_ZERO is not set
|
||||
# CONFIG_DM_MULTIPATH is not set
|
||||
# CONFIG_DM_DELAY is not set
|
||||
# CONFIG_DM_UEVENT is not set
|
||||
# CONFIG_DM_FLAKEY is not set
|
||||
# CONFIG_DM_VERITY is not set
|
||||
# CONFIG_DM_SWITCH is not set
|
||||
# CONFIG_TARGET_CORE is not set
|
||||
# CONFIG_FUSION is not set
|
||||
|
||||
@@ -1515,7 +1541,6 @@ CONFIG_MDIO=y
|
||||
# CONFIG_NET_VENDOR_ALTEON is not set
|
||||
# CONFIG_ALTERA_TSE is not set
|
||||
# CONFIG_NET_VENDOR_AMD is not set
|
||||
# CONFIG_NET_XGENE is not set
|
||||
CONFIG_NET_VENDOR_ARC=y
|
||||
# CONFIG_NET_VENDOR_ATHEROS is not set
|
||||
CONFIG_NET_VENDOR_BROADCOM=y
|
||||
@@ -2436,7 +2461,6 @@ CONFIG_USB_DEFAULT_PERSIST=y
|
||||
#
|
||||
# CONFIG_USB_C67X00_HCD is not set
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
# CONFIG_USB_XHCI_PLATFORM is not set
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||
CONFIG_USB_EHCI_TT_NEWSCHED=y
|
||||
@@ -2811,6 +2835,7 @@ CONFIG_X86_PLATFORM_DEVICES=y
|
||||
# CONFIG_INTEL_RST is not set
|
||||
# CONFIG_INTEL_SMARTCONNECT is not set
|
||||
# CONFIG_PVPANIC is not set
|
||||
CONFIG_DELL_S6000_S1220=y
|
||||
# CONFIG_CHROME_PLATFORMS is not set
|
||||
|
||||
#
|
||||
@@ -2860,7 +2885,6 @@ CONFIG_GENERIC_PHY=y
|
||||
# CONFIG_PHY_SAMSUNG_USB2 is not set
|
||||
# CONFIG_POWERCAP is not set
|
||||
# CONFIG_MCB is not set
|
||||
# CONFIG_THUNDERBOLT is not set
|
||||
|
||||
#
|
||||
# Firmware Drivers
|
||||
@@ -3008,20 +3032,6 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
|
||||
# CONFIG_UFS_FS is not set
|
||||
# CONFIG_EXOFS_FS is not set
|
||||
# CONFIG_F2FS_FS is not set
|
||||
CONFIG_AUFS_FS=y
|
||||
CONFIG_AUFS_BRANCH_MAX_127=y
|
||||
# CONFIG_AUFS_BRANCH_MAX_511 is not set
|
||||
# CONFIG_AUFS_BRANCH_MAX_1023 is not set
|
||||
# CONFIG_AUFS_BRANCH_MAX_32767 is not set
|
||||
CONFIG_AUFS_SBILIST=y
|
||||
# CONFIG_AUFS_HNOTIFY is not set
|
||||
# CONFIG_AUFS_EXPORT is not set
|
||||
# CONFIG_AUFS_FHSM is not set
|
||||
# CONFIG_AUFS_RDU is not set
|
||||
# CONFIG_AUFS_SHWH is not set
|
||||
# CONFIG_AUFS_BR_RAMFS is not set
|
||||
CONFIG_AUFS_BDEV_LOOP=y
|
||||
# CONFIG_AUFS_DEBUG is not set
|
||||
CONFIG_ORE=y
|
||||
CONFIG_NETWORK_FILESYSTEMS=y
|
||||
CONFIG_NFS_FS=y
|
||||
@@ -3033,6 +3043,7 @@ CONFIG_NFS_V4=y
|
||||
CONFIG_NFS_V4_1=y
|
||||
# CONFIG_NFS_V4_2 is not set
|
||||
CONFIG_PNFS_FILE_LAYOUT=y
|
||||
CONFIG_PNFS_BLOCK=y
|
||||
CONFIG_PNFS_OBJLAYOUT=y
|
||||
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
|
||||
# CONFIG_NFS_V4_1_MIGRATION is not set
|
||||
@@ -25,9 +25,6 @@
|
||||
THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
K_MAJOR_VERSION := 3
|
||||
K_PATCH_LEVEL := 16
|
||||
K_SUB_LEVEL := 7
|
||||
K_SUB_LEVEL := 39
|
||||
K_SUFFIX :=
|
||||
K_PATCH_DIR := $(THIS_DIR)/patches
|
||||
K_ARCHIVE_NAME := linux-3.16.7-ckt25.tgz
|
||||
K_NAME := linux-3.16.7-ckt25
|
||||
K_ARCHIVE_URL := http://opennetlinux.org/tarballs/linux-3.16.7-ckt25.tgz
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user