Skip to content

Commit

Permalink
Factor out the Jenkins install dir override hack
Browse files Browse the repository at this point in the history
This allows testing it and should make it easier to fix the regression.
  • Loading branch information
arichardson committed Aug 11, 2023
1 parent 779cdff commit e4278e8
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 39 deletions.
43 changes: 4 additions & 39 deletions pycheribuild/jenkins.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#
import argparse
import contextlib
import inspect
import os
import pprint
import shutil
Expand All @@ -40,7 +39,8 @@
from typing import Optional

from .config.jenkinsconfig import JenkinsAction, JenkinsConfig
from .config.loader import CommandLineConfigLoader, CommandLineConfigOption
from .config.loader import CommandLineConfigLoader
from .jenkins_utils import jenkins_override_install_dirs_hack
from .processutils import get_program_version, run_and_kill_children_on_exit, run_command

# make sure all projects are loaded so that target_manager gets populated
Expand All @@ -51,7 +51,7 @@
from .projects.cross import * # noqa: F401, F403, RUF100
from .projects.project import Project
from .projects.simple_project import SimpleProject
from .targets import MultiArchTargetAlias, SimpleTargetAlias, Target, target_manager
from .targets import Target, target_manager
from .utils import OSInfo, ThreadJoiner, fatal_error, init_global_config, status_update, warning_message

EXTRACT_SDK_TARGET: str = "extract-sdk"
Expand Down Expand Up @@ -243,42 +243,7 @@ def _jenkins_main() -> None:
fatal_error("More than one target is not supported yet.", pretend=False)
sys.exit()

expected_install_path = Path(f"{cheri_config.output_root}{cheri_config.installation_prefix}")
# Ugly workaround to override all install dirs to go to the tarball
for tgt in target_manager.targets(cheri_config):
if isinstance(tgt, SimpleTargetAlias):
continue
cls = tgt.project_class
if issubclass(cls, Project) and not isinstance(tgt, MultiArchTargetAlias):
cls._default_install_dir_fn = Path(expected_install_path)
i = inspect.getattr_static(cls, "_install_dir")
assert isinstance(i, CommandLineConfigOption)
# But don't change it if it was specified on the command line. Note: This also does the config
# inheritance: i.e. setting --cheribsd/install-dir will also affect cheribsd-cheri/cheribsd-mips
# noinspection PyTypeChecker
from_cmdline = i.load_option(cheri_config, cls, cls, return_none_if_default=True)
if from_cmdline is not None:
status_update("Install directory for", cls.target, "was specified on commandline:", from_cmdline)
else:
cls._install_dir = cheri_config.output_root
cls._check_install_dir_conflict = False

Target.instantiating_targets_should_warn = False
# Override the installation directory for all enabled targets
for name in cheri_config.targets:
target = target_manager.get_target_raw(name)
# noinspection PyProtectedMember
project = target._get_or_create_project_no_setup(None, cheri_config, caller=None)
if isinstance(project, Project):
# Using "/" as the install prefix results inconsistently prefixing some paths with '/usr/'.
# To avoid this, just use the full install path as the prefix.
if cheri_config.installation_prefix == Path("/"):
project._install_prefix = expected_install_path
project.destdir = Path("/")
else:
project._install_prefix = cheri_config.installation_prefix
project.destdir = cheri_config.output_root
assert project.real_install_root_dir == expected_install_path
jenkins_override_install_dirs_hack(cheri_config, cheri_config.installation_prefix)

if JenkinsAction.BUILD in cheri_config.action or JenkinsAction.TEST in cheri_config.action:
for tgt in cheri_config.targets:
Expand Down
76 changes: 76 additions & 0 deletions pycheribuild/jenkins_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#
# Copyright (c) 2023 Alex Richardson
# All rights reserved.
#
# This software was developed by SRI International and the University of
# Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
# ("CTSRD"), as part of the DARPA CRASH research programme.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
import inspect
from pathlib import Path

from .config.chericonfig import CheriConfig
from .config.loader import CommandLineConfigOption
from .projects.project import Project
from .targets import MultiArchTargetAlias, SimpleTargetAlias, Target, target_manager
from .utils import status_update


def jenkins_override_install_dirs_hack(cheri_config: CheriConfig, install_prefix: Path):
expected_install_path = Path(f"{cheri_config.output_root}{install_prefix}")
# Ugly workaround to override all install dirs to go to the tarball
for tgt in target_manager.targets(cheri_config):
if isinstance(tgt, SimpleTargetAlias):
continue
cls = tgt.project_class
if issubclass(cls, Project) and not isinstance(tgt, MultiArchTargetAlias):
cls._default_install_dir_fn = Path(expected_install_path)
i = inspect.getattr_static(cls, "_install_dir")
assert isinstance(i, CommandLineConfigOption)
# But don't change it if it was specified on the command line. Note: This also does the config
# inheritance: i.e. setting --cheribsd/install-dir will also affect cheribsd-cheri/cheribsd-mips
# noinspection PyTypeChecker
from_cmdline = i.load_option(cheri_config, cls, cls, return_none_if_default=True)
if from_cmdline is not None:
status_update("Install directory for", cls.target, "was specified on commandline:", from_cmdline)
else:
cls._install_dir = cheri_config.output_root
cls._check_install_dir_conflict = False

Target.instantiating_targets_should_warn = False
# Override the installation directory for all enabled targets
for name in cheri_config.targets:
target = target_manager.get_target_raw(name)
# noinspection PyProtectedMember
project = target._get_or_create_project_no_setup(None, cheri_config, caller=None)
if isinstance(project, Project):
# Using "/" as the install prefix results inconsistently prefixing some paths with '/usr/'.
# To avoid this, just use the full install path as the prefix.
if install_prefix == Path("/"):
project._install_prefix = expected_install_path
project.destdir = Path("/")
else:
project._install_prefix = install_prefix
project.destdir = cheri_config.output_root
assert project.real_install_root_dir == expected_install_path
21 changes: 21 additions & 0 deletions tests/test_argument_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from pycheribuild.config.compilation_targets import CompilationTargets, FreeBSDTargetInfo
from pycheribuild.config.defaultconfig import DefaultCheriConfig
from pycheribuild.config.loader import ConfigLoaderBase, ConfigOptionBase, JsonAndCommandLineConfigOption
from pycheribuild.jenkins_utils import jenkins_override_install_dirs_hack

# noinspection PyUnresolvedReferences
from pycheribuild.projects import * # noqa: F401, F403, RUF100
Expand Down Expand Up @@ -1379,3 +1380,23 @@ def _check_install_dirs(args, expected_install_dir):
["--source-root=/default/prefix", f"--{target}/install-directory=/custom/override"],
Path("/custom/override"),
)


@pytest.mark.xfail(reason="Bug after refactoring")
def test_jenkins_hack_disk_image():
# Regression test for the refactoring of the Jenkins installation directories hack:
# After refactoring the disk image target was trying to look for files in tarball/ instead of using
# the expected tarball/rootfs directory.
args = [
"--output-root=/tmp/tarball",
"--cheribsd/default-kernel-abi=hybrid",
"--cheribsd/build-bench-kernels",
]
config = _parse_arguments(args)
jenkins_override_install_dirs_hack(config, Path("/rootfs"))
disk_image = _get_target_instance(
"disk-image-aarch64", config, BuildCheriBSDDiskImage,
)
assert disk_image.disk_image_path == Path("/tmp/tarball/cheribsd-aarch64.img")
# FIXME: this is failing
assert disk_image.rootfs_dir == Path("/tmp/tarball/rootfs")

0 comments on commit e4278e8

Please sign in to comment.