184 lines
5.2 KiB
Python
184 lines
5.2 KiB
Python
|
#
|
||
|
# Support for %addon sections.
|
||
|
#
|
||
|
# Copyright (C) 2019 Red Hat, Inc. All rights reserved.
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation; either version 2 of the License, or
|
||
|
# (at your option) any later version.
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU General Public License
|
||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
#
|
||
|
from abc import ABCMeta, abstractmethod
|
||
|
from types import SimpleNamespace
|
||
|
|
||
|
from pykickstart.errors import KickstartParseError
|
||
|
from pykickstart.ko import KickstartObject
|
||
|
from pykickstart.sections import Section
|
||
|
|
||
|
from pyanaconda.anaconda_loggers import get_module_logger
|
||
|
from pyanaconda.core.i18n import _
|
||
|
|
||
|
log = get_module_logger(__name__)
|
||
|
|
||
|
__all__ = ["AddonData", "AddonSection", "AddonRegistry"]
|
||
|
|
||
|
|
||
|
class AddonData(KickstartObject, metaclass=ABCMeta):
|
||
|
"""Kickstart data for addon.
|
||
|
|
||
|
This is a common parent class for loading and storing 3rd
|
||
|
party data to kickstart. It is instantiated by kickstart
|
||
|
parser and stored as ksdata.addons.<name> to be used in
|
||
|
the user interfaces.
|
||
|
|
||
|
The following methods have to be implemented:
|
||
|
|
||
|
* handle_header handles arguments of the section
|
||
|
* handle_line is called for every line of the section
|
||
|
* __str__ returns a kickstart representation of the section
|
||
|
|
||
|
"""
|
||
|
|
||
|
@abstractmethod
|
||
|
def handle_header(self, args, line_number=None):
|
||
|
"""Handle the arguments of the %addon line.
|
||
|
|
||
|
This function receives any arguments on the %addon line
|
||
|
after the name. For example, for the line:
|
||
|
|
||
|
%addon com_example_foo --argument='example'
|
||
|
|
||
|
This function would be called with:
|
||
|
|
||
|
args=["--argument='example'"].
|
||
|
|
||
|
:param args: a list of additional arguments
|
||
|
:param line_number: a line number
|
||
|
:raise: KickstartParseError for invalid arguments
|
||
|
"""
|
||
|
pass
|
||
|
|
||
|
@abstractmethod
|
||
|
def handle_line(self, line, line_number=None):
|
||
|
"""Handle one line of the section.
|
||
|
|
||
|
:param line: a line to parse
|
||
|
:param line_number: a line number
|
||
|
:raise: KickstartParseError for invalid lines
|
||
|
"""
|
||
|
pass
|
||
|
|
||
|
def handle_end(self):
|
||
|
"""Handle the end of the section.."""
|
||
|
pass
|
||
|
|
||
|
@abstractmethod
|
||
|
def __str__(self):
|
||
|
"""Generate the kickstart representation.
|
||
|
|
||
|
Generate the %addon section for your addon.
|
||
|
|
||
|
For example:
|
||
|
|
||
|
%addon com_example_foo --argument='example'
|
||
|
My lines.
|
||
|
%end
|
||
|
|
||
|
:return: a string
|
||
|
"""
|
||
|
return ""
|
||
|
|
||
|
|
||
|
class AddonSection(Section):
|
||
|
"""Parser of the %addon sections.
|
||
|
|
||
|
Parses the name of the current %addon section and propagates
|
||
|
all arguments and lines of this section to the addon with the
|
||
|
specified name.
|
||
|
"""
|
||
|
sectionOpen = "%addon"
|
||
|
|
||
|
def __init__(self, handler, **kwargs):
|
||
|
super().__init__(handler, **kwargs)
|
||
|
self.data = None
|
||
|
self.line_number = None
|
||
|
|
||
|
def handleHeader(self, lineno, args):
|
||
|
"""Handle a header of the current %addon section.
|
||
|
|
||
|
This method is called when the opening tag for a section is
|
||
|
seen. Not all sections will need this method, though all
|
||
|
provided with kickstart include one.
|
||
|
|
||
|
:param lineno: a number of the current line
|
||
|
:param args: a list of strings passed as arguments
|
||
|
"""
|
||
|
super().handleHeader(lineno, args)
|
||
|
|
||
|
if not args:
|
||
|
raise KickstartParseError(
|
||
|
_("Missing name of the %addon section."),
|
||
|
lineno=lineno
|
||
|
)
|
||
|
|
||
|
name = args[1]
|
||
|
arguments = args[2:]
|
||
|
data = getattr(self.handler.addons, name, None)
|
||
|
|
||
|
if not data:
|
||
|
raise KickstartParseError(
|
||
|
_("Unknown name of the %addon section."),
|
||
|
lineno=lineno
|
||
|
)
|
||
|
|
||
|
self.data = data
|
||
|
self.line_number = lineno
|
||
|
self.data.handle_header(arguments, self.line_number)
|
||
|
|
||
|
def handleLine(self, line):
|
||
|
"""Handle one line of the current %addon section.
|
||
|
|
||
|
This method is called for every line of a section. Take
|
||
|
whatever action is appropriate. While this method is not
|
||
|
required to be provided, not providing it does not make
|
||
|
a whole lot of sense.
|
||
|
|
||
|
:param line: a complete line, with any trailing newline
|
||
|
"""
|
||
|
if not self.handler:
|
||
|
return
|
||
|
|
||
|
self.line_number += 1
|
||
|
self.data.handle_line(line, self.line_number)
|
||
|
|
||
|
def finalize(self):
|
||
|
"""Handle the end of the current %addon section.
|
||
|
|
||
|
This method is called when the %end tag for a section is
|
||
|
seen.
|
||
|
"""
|
||
|
super().finalize()
|
||
|
self.data.handle_end()
|
||
|
self.data = None
|
||
|
|
||
|
|
||
|
class AddonRegistry(SimpleNamespace):
|
||
|
"""Data holder of the %addon sections.
|
||
|
|
||
|
Provides access to instances of AddonData from the handler.
|
||
|
|
||
|
For example:
|
||
|
|
||
|
handler.addons.com_example_foo
|
||
|
|
||
|
"""
|
||
|
pass
|