anaconda/anaconda-40.22.3.13/pyanaconda/core/kickstart/addon.py
2024-11-14 21:39:56 -08:00

183 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