Validation of parameter skip_phases
It checks config file value 'skip_phases' for valid phases names. Also checks command-line attribute 'skip-phase' of 'bin/pungi-koji'. JIRA: COMPOSE-2493 Signed-off-by: Ondrej Nosek <onosek@redhat.com>
This commit is contained in:
parent
ab2faa85b3
commit
b2190c1c3f
@ -3,24 +3,26 @@
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
|
||||||
import locale
|
|
||||||
import datetime
|
import datetime
|
||||||
import getpass
|
import getpass
|
||||||
|
import json
|
||||||
|
import locale
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
import socket
|
import socket
|
||||||
import signal
|
import signal
|
||||||
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from six.moves import shlex_quote
|
from six.moves import shlex_quote
|
||||||
import json
|
|
||||||
|
|
||||||
here = sys.path[0]
|
here = sys.path[0]
|
||||||
if here != '/usr/bin':
|
if here != '/usr/bin':
|
||||||
# Git checkout
|
# Git checkout
|
||||||
sys.path[0] = os.path.dirname(here)
|
sys.path[0] = os.path.dirname(here)
|
||||||
|
|
||||||
|
from pungi.phases import PHASES_NAMES
|
||||||
from pungi import get_full_version
|
from pungi import get_full_version
|
||||||
|
|
||||||
|
|
||||||
@ -84,6 +86,7 @@ def main():
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--skip-phase",
|
"--skip-phase",
|
||||||
metavar="PHASE",
|
metavar="PHASE",
|
||||||
|
choices=PHASES_NAMES,
|
||||||
action="append",
|
action="append",
|
||||||
default=[],
|
default=[],
|
||||||
help="skip a compose phase",
|
help="skip a compose phase",
|
||||||
@ -91,6 +94,7 @@ def main():
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--just-phase",
|
"--just-phase",
|
||||||
metavar="PHASE",
|
metavar="PHASE",
|
||||||
|
choices=PHASES_NAMES,
|
||||||
action="append",
|
action="append",
|
||||||
default=[],
|
default=[],
|
||||||
help="run only a specified compose phase",
|
help="run only a specified compose phase",
|
||||||
|
@ -37,15 +37,17 @@ When a new config option is added, the schema must be updated (see the
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import multiprocessing
|
||||||
import os.path
|
import os.path
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import jsonschema
|
import jsonschema
|
||||||
import six
|
import six
|
||||||
from kobo.shortcuts import force_list
|
from kobo.shortcuts import force_list
|
||||||
|
from pungi.phases import PHASES_NAMES
|
||||||
from productmd.common import RELEASE_TYPES
|
from productmd.common import RELEASE_TYPES
|
||||||
from productmd.composeinfo import COMPOSE_TYPES
|
from productmd.composeinfo import COMPOSE_TYPES
|
||||||
import multiprocessing
|
|
||||||
|
|
||||||
from . import util
|
from . import util
|
||||||
|
|
||||||
@ -760,7 +762,11 @@ def make_schema():
|
|||||||
|
|
||||||
"paths_module": {"type": "string"},
|
"paths_module": {"type": "string"},
|
||||||
"skip_phases": {
|
"skip_phases": {
|
||||||
"$ref": "#/definitions/list_of_strings",
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": PHASES_NAMES,
|
||||||
|
},
|
||||||
"default": [],
|
"default": [],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, see <https://gnu.org/licenses/>.
|
# along with this program; if not, see <https://gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
# phases in runtime order
|
# phases in runtime order
|
||||||
from .init import InitPhase # noqa
|
from .init import InitPhase # noqa
|
||||||
@ -32,3 +33,8 @@ from .livemedia_phase import LiveMediaPhase # noqa
|
|||||||
from .ostree import OSTreePhase # noqa
|
from .ostree import OSTreePhase # noqa
|
||||||
from .ostree_installer import OstreeInstallerPhase # noqa
|
from .ostree_installer import OstreeInstallerPhase # noqa
|
||||||
from .osbs import OSBSPhase # noqa
|
from .osbs import OSBSPhase # noqa
|
||||||
|
from .phases_metadata import gather_phases_metadata # noqa
|
||||||
|
|
||||||
|
|
||||||
|
this_module = sys.modules[__name__]
|
||||||
|
PHASES_NAMES = gather_phases_metadata(this_module)
|
||||||
|
31
pungi/phases/phases_metadata.py
Normal file
31
pungi/phases/phases_metadata.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
from inspect import isclass
|
||||||
|
|
||||||
|
from pungi.phases.base import PhaseBase
|
||||||
|
|
||||||
|
|
||||||
|
def gather_phases_metadata(source_object):
|
||||||
|
"""
|
||||||
|
Code gathers metadata from Phase classes.
|
||||||
|
Metadata are 'name' attributes of the corresponding classes.
|
||||||
|
Metadata are gathered without creating instances of Phase classes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not source_object:
|
||||||
|
raise ValueError("PhasesMetadata can not load any data - it got empty parameter")
|
||||||
|
|
||||||
|
phases = []
|
||||||
|
for item in dir(source_object):
|
||||||
|
cls = getattr(source_object, item) # get all objects references
|
||||||
|
if not isclass(cls): # filter out non-classes
|
||||||
|
continue
|
||||||
|
if issubclass(cls, PhaseBase):
|
||||||
|
try:
|
||||||
|
name_attr = getattr(cls, 'name')
|
||||||
|
phases.append(name_attr)
|
||||||
|
except AttributeError:
|
||||||
|
raise AttributeError("Bad phase-class format: '%s' is missing attribute 'name'" % item)
|
||||||
|
|
||||||
|
return phases
|
@ -428,5 +428,37 @@ class VariantAsLookasideTestCase(ConfigTestCase):
|
|||||||
self.assertValidation(cfg)
|
self.assertValidation(cfg)
|
||||||
|
|
||||||
|
|
||||||
|
class SkipPhasesTestCase(ConfigTestCase):
|
||||||
|
def test_empty(self):
|
||||||
|
skip_phases = []
|
||||||
|
cfg = load_config(
|
||||||
|
PKGSET_REPOS,
|
||||||
|
skip_phases=skip_phases,
|
||||||
|
)
|
||||||
|
self.assertValidation(cfg)
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
skip_phases = [
|
||||||
|
"buildinstall",
|
||||||
|
"gather",
|
||||||
|
]
|
||||||
|
cfg = load_config(
|
||||||
|
PKGSET_REPOS,
|
||||||
|
skip_phases=skip_phases,
|
||||||
|
)
|
||||||
|
self.assertValidation(cfg)
|
||||||
|
|
||||||
|
def test_bad_phase_name(self):
|
||||||
|
skip_phases = [
|
||||||
|
"gather",
|
||||||
|
"non-existing-phase_name",
|
||||||
|
]
|
||||||
|
cfg = load_config(
|
||||||
|
PKGSET_REPOS,
|
||||||
|
skip_phases=skip_phases,
|
||||||
|
)
|
||||||
|
self.assertNotEqual(checks.validate(cfg), ([], []))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user