2N/A#! /usr/bin/python2.6
2N/A#
2N/A# CDDL HEADER START
2N/A#
2N/A# The contents of this file are subject to the terms of the
2N/A# Common Development and Distribution License (the "License").
2N/A# You may not use this file except in compliance with the License.
2N/A#
2N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A# or http://www.opensolaris.org/os/licensing.
2N/A# See the License for the specific language governing permissions
2N/A# and limitations under the License.
2N/A#
2N/A# When distributing Covered Code, include this CDDL HEADER in each
2N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A# If applicable, add the following below this CDDL HEADER, with the
2N/A# fields enclosed by brackets "[]" replaced with your own identifying
2N/A# information: Portions Copyright [yyyy] [name of copyright owner]
2N/A#
2N/A# CDDL HEADER END
2N/A#
2N/A# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
2N/A#
2N/A
2N/A"""
2N/AVarious bootloader interfaces for pybootmgmt
2N/A"""
2N/A
2N/Aimport sys
2N/Afrom bootmgmt import BootmgmtError, BootmgmtInvalidBootloaderError
2N/Afrom bootmgmt.bootutil import LoggerMixin
2N/Afrom bootmgmt.bootloader import BootLoader, ProxyBootLoader
2N/A
2N/ABOOT_LOADER_BACKENDS = ['grub2', 'legacygrub', 'sbb']
2N/A
2N/A
2N/Aclass BackendBootLoaderFactory(LoggerMixin):
2N/A """Factory that returns BootLoader instances.
2N/A """
2N/A
2N/A @classmethod
2N/A def get(cls, **kwargs):
2N/A """Returns an instance of bootloader.BootLoader appropriate for the
2N/A system identified by the keyword arguments passed in. Invokes a
2N/A probe function for each boot loader backend, and returns the loader
2N/A whose probe function returned the highest rank value. If multiple
2N/A boot loaders' probe functions succeed, a ProxyBootLoader instance is
2N/A returned that will manage access to both BootLoader instances.
2N/A """
2N/A loaderlist = []
2N/A loader_instance = None
2N/A
2N/A for loader in BOOT_LOADER_BACKENDS:
2N/A blmod = __name__ + '.' + loader
2N/A __import__(blmod, level=0)
2N/A namespc = sys.modules[blmod]
2N/A for loaderclass in namespc.bootloader_classes():
2N/A try:
2N/A loaderinst = loaderclass.probe(**kwargs)
2N/A if not loaderinst is None:
2N/A cls._debug('[PROBE SUCCEEDED] class %s',
2N/A loaderinst.__class__.__name__)
2N/A loaderlist.append(loaderinst)
2N/A except BootmgmtError as bmerr:
2N/A cls._debug('Exception during probe: %s', bmerr)
2N/A
2N/A loaderclass = kwargs.get('loaderclass')
2N/A if loaderclass:
2N/A loaders = [x for x in loaderlist if isinstance(x, loaderclass)]
2N/A if len(loaders) == 0:
2N/A raise BootmgmtInvalidBootloaderError('Could not find an '
2N/A 'instance of BootLoader class %s' % loaderclass.__name__)
2N/A cls._debug('OVERRIDDEN [class=%s] loaderlist => %s',
2N/A (loaderclass.__name__, loaders))
2N/A return loaders[0]
2N/A
2N/A # Sort the loader list by decreasing rank:
2N/A loaderlist.sort(cmp=\
2N/A ProxyBootLoader.bootloader_cmp_by_artifacts_and_weight,
2N/A reverse=True)
2N/A
2N/A cls._debug('loaderlist => %s', loaderlist)
2N/A
2N/A if len(loaderlist) > 1:
2N/A bcfg = kwargs.get('bootconfig')
2N/A if bcfg and getattr(bcfg, 'EXCLUSIVE_LOADER', False):
2N/A cls._debug('boot config with exclusive loader requirement '
2N/A 'detected')
2N/A loader_instance = loaderlist[0]
2N/A else:
2N/A cls._debug('Creating ProxyBootLoader with primary=%s, '
2N/A 'secondary=%s', (repr(loaderlist[0]), repr(loaderlist[1])))
2N/A loader_instance = ProxyBootLoader(loaderlist[0], loaderlist[1])
2N/A elif len(loaderlist) > 0:
2N/A loader_instance = loaderlist[0]
2N/A
2N/A return loader_instance
2N/A