Exemple #1
0
def test_set_unknown(client: Client, package_ahriman: Package,
                     mocker: MockerFixture) -> None:
    """
    must add new package with unknown status
    """
    add_mock = mocker.patch("ahriman.core.status.client.Client.add")
    client.set_unknown(package_ahriman)

    add_mock.assert_called_with(package_ahriman, BuildStatusEnum.Unknown)
Exemple #2
0
def test_set_success(client: Client, package_ahriman: Package,
                     mocker: MockerFixture) -> None:
    """
    must set success status to the package
    """
    add_mock = mocker.patch("ahriman.core.status.client.Client.add")
    client.set_success(package_ahriman)

    add_mock.assert_called_with(package_ahriman, BuildStatusEnum.Success)
Exemple #3
0
def test_set_failed(client: Client, package_ahriman: Package,
                    mocker: MockerFixture) -> None:
    """
    must set failed status to the package
    """
    update_mock = mocker.patch("ahriman.core.status.client.Client.update")
    client.set_failed(package_ahriman.base)

    update_mock.assert_called_with(package_ahriman.base,
                                   BuildStatusEnum.Failed)
Exemple #4
0
def test_load_full_client(configuration: Configuration) -> None:
    """
    must load full client if no settings set
    """
    configuration.set("web", "host", "localhost")
    configuration.set("web", "port", "8080")
    assert isinstance(Client.load(configuration), WebClient)
Exemple #5
0
    def __init__(self, args: argparse.Namespace, architecture: str,
                 configuration: Configuration) -> None:
        """
        default constructor
        :param args: command line args
        :param architecture: repository architecture
        :param configuration: configuration instance
        """
        self.path = Path(
            f"{args.lock}_{architecture}") if args.lock is not None else None
        self.force = args.force
        self.unsafe = args.unsafe

        self.root = Path(configuration.get("repository", "root"))
        self.reporter = Client() if args.no_report else Client.load(
            configuration)
Exemple #6
0
    def __init__(self, architecture: str,
                 configuration: Configuration) -> None:
        self.logger = logging.getLogger("builder")
        self.architecture = architecture
        self.configuration = configuration

        self.aur_url = configuration.get("alpm", "aur_url")
        self.name = configuration.get("repository", "name")

        self.paths = RepositoryPaths(
            configuration.getpath("repository", "root"), architecture)
        self.paths.create_tree()

        self.ignore_list = configuration.getlist("build", "ignore_packages")
        self.pacman = Pacman(configuration)
        self.sign = GPG(architecture, configuration)
        self.repo = Repo(self.name, self.paths, self.sign.repository_sign_args)
        self.reporter = Client.load(configuration)
Exemple #7
0
def client() -> Client:
    return Client()
Exemple #8
0
def test_update_self(client: Client) -> None:
    """
    must update self status without errors
    """
    client.update_self(BuildStatusEnum.Unknown)
Exemple #9
0
def test_update(client: Client, package_ahriman: Package) -> None:
    """
    must update package status without errors
    """
    client.update(package_ahriman.base, BuildStatusEnum.Unknown)
Exemple #10
0
def test_remove(client: Client, package_ahriman: Package) -> None:
    """
    must process remove without errors
    """
    client.remove(package_ahriman.base)
Exemple #11
0
def test_get_self(client: Client) -> None:
    """
    must return unknown status for service
    """
    assert client.get_self().status == BuildStatusEnum.Unknown
Exemple #12
0
def test_get_internal(client: Client) -> None:
    """
    must return dummy status for web service
    """
    assert client.get_internal() == InternalStatus()
Exemple #13
0
def test_get(client: Client, package_ahriman: Package) -> None:
    """
    must return empty package list
    """
    assert client.get(package_ahriman.base) == []
    assert client.get(None) == []
Exemple #14
0
def test_add(client: Client, package_ahriman: Package) -> None:
    """
    must process package addition without errors
    """
    client.add(package_ahriman, BuildStatusEnum.Unknown)
Exemple #15
0
def test_load_dummy_client(configuration: Configuration) -> None:
    """
    must load dummy client if no settings set
    """
    assert isinstance(Client.load(configuration), Client)
Exemple #16
0
class Lock:
    """
    wrapper for application lock file
    :ivar force: remove lock file on start if any
    :ivar path: path to lock file if any
    :ivar reporter: build status reporter instance
    :ivar root: repository root (i.e. ahriman home)
    :ivar unsafe: skip user check
    """
    def __init__(self, args: argparse.Namespace, architecture: str,
                 configuration: Configuration) -> None:
        """
        default constructor
        :param args: command line args
        :param architecture: repository architecture
        :param configuration: configuration instance
        """
        self.path = Path(
            f"{args.lock}_{architecture}") if args.lock is not None else None
        self.force = args.force
        self.unsafe = args.unsafe

        self.root = Path(configuration.get("repository", "root"))
        self.reporter = Client() if args.no_report else Client.load(
            configuration)

    def __enter__(self) -> Lock:
        """
        default workflow is the following:

            check user UID
            check if there is lock file
            check web status watcher status
            create lock file
            report to web if enabled
        """
        self.check_user()
        self.check_version()
        self.create()
        self.reporter.update_self(BuildStatusEnum.Building)
        return self

    def __exit__(self, exc_type: Optional[Type[Exception]],
                 exc_val: Optional[Exception],
                 exc_tb: TracebackType) -> Literal[False]:
        """
        remove lock file when done
        :param exc_type: exception type name if any
        :param exc_val: exception raised if any
        :param exc_tb: exception traceback if any
        :return: always False (do not suppress any exception)
        """
        self.clear()
        status = BuildStatusEnum.Success if exc_val is None else BuildStatusEnum.Failed
        self.reporter.update_self(status)
        return False

    def check_version(self) -> None:
        """
        check web server version
        """
        status = self.reporter.get_internal()
        if status.version is not None and status.version != version.__version__:
            logging.getLogger("root").warning(
                f"status watcher version mismatch, "
                f"our {version.__version__}, their {status.version}")

    def check_user(self) -> None:
        """
        check if current user is actually owner of ahriman root
        """
        if self.unsafe:
            return
        current_uid = os.getuid()
        root_uid = self.root.stat().st_uid
        if current_uid != root_uid:
            raise UnsafeRun(current_uid, root_uid)

    def clear(self) -> None:
        """
        remove lock file
        """
        if self.path is None:
            return
        self.path.unlink(missing_ok=True)

    def create(self) -> None:
        """
        create lock file
        """
        if self.path is None:
            return
        try:
            self.path.touch(exist_ok=self.force)
        except FileExistsError:
            raise DuplicateRun()