# -*- coding: utf-8 -*-
#
# This tool helps you rebase your package to the latest version
# Copyright (C) 2013-2019 Red Hat, Inc.
#
# 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Authors: Petr Hráček <phracek@redhat.com>
# Tomáš Hozza <thozza@redhat.com>
# Nikola Forró <nforro@redhat.com>
# František Nečas <fifinecas@seznam.cz>
import logging
import os
import shutil
from typing import cast
import pam # type: ignore
from rebasehelper.helpers.path_helper import PathHelper
from rebasehelper.logger import CustomLogger
from rebasehelper.temporary_environment import TemporaryEnvironment
logger: CustomLogger = cast(CustomLogger, logging.getLogger(__name__))
[docs]
def get_mock_logfile_path(ret, results_dir, tmp_path=None):
"""
Get path to logfile containing the error message
:param ret: return code from mock
:param results_dir: directory where logs will be stored
:param tmp_path: temporary directory where logs are during build
:return:
"""
tmp_build_log_path = os.path.join(results_dir, 'build.log')
tmp_mock_log_path = os.path.join(results_dir, 'mock_output.log')
if tmp_path:
# The logs are still located in the temporary build directory
tmp_build_log_path = os.path.join(tmp_path, 'build.log')
tmp_mock_log_path = os.path.join(tmp_path, 'mock_output.log')
build_log_path = os.path.join(results_dir, 'build.log')
mock_log_path = os.path.join(results_dir, 'mock_output.log')
root_log_path = os.path.join(results_dir, 'root.log')
# Mock return code classification based on https://pagure.io/koji/blob/c496bf9/f/builder/kojid#_481
if ret == 1:
if not os.path.exists(tmp_build_log_path) and os.path.exists(tmp_mock_log_path):
logfile = mock_log_path
else:
logfile = build_log_path
elif ret < 0:
# koji error
logfile = None
else:
logfile = root_log_path
return logfile
[docs]
def check_mock_privileges() -> bool:
# try to authenticate as superuser using mock PAM service
return pam.pam().authenticate('root', '', service='mock')
[docs]
class BuildTemporaryEnvironment(TemporaryEnvironment):
"""Class representing temporary environment."""
TEMPDIR_SOURCES: str = TemporaryEnvironment.TEMPDIR + '_SOURCES'
TEMPDIR_SPEC: str = TemporaryEnvironment.TEMPDIR + '_SPEC'
TEMPDIR_SPECS: str = TemporaryEnvironment.TEMPDIR + '_SPECS'
TEMPDIR_RESULTS: str = TemporaryEnvironment.TEMPDIR + '_RESULTS'
def __init__(self, sources, patches, spec, results_dir):
super().__init__(self._build_env_exit_callback)
self._env['results_dir'] = results_dir
self.sources = sources
self.patches = patches
self.spec = spec
def __enter__(self):
obj = super().__enter__()
log_message = "Copying '%s' to '%s'"
# create the directory structure
self._create_directory_structure()
# copy sources
for source in self.sources:
logger.debug(log_message, source, self._env[self.TEMPDIR_SOURCES])
shutil.copy(source, self._env[self.TEMPDIR_SOURCES])
# copy patches
for patch in self.patches:
logger.debug(log_message, patch, self._env[self.TEMPDIR_SOURCES])
shutil.copy(patch, self._env[self.TEMPDIR_SOURCES])
# copy SPEC file
spec_name = os.path.basename(self.spec)
self._env[self.TEMPDIR_SPEC] = os.path.join(self._env[self.TEMPDIR_SPECS], spec_name)
shutil.copy(self.spec, self._env[self.TEMPDIR_SPEC])
logger.debug(log_message, self.spec, self._env[self.TEMPDIR_SPEC])
return obj
def _create_directory_structure(self):
"""Function creating the directory structure in the TemporaryEnvironment."""
raise NotImplementedError('The create directory function has to be implemented in child class!')
def _build_env_exit_callback(self, results_dir, **kwargs):
"""
The function that is called just before the destruction of the TemporaryEnvironment.
It copies packages and logs into the results directory.
:param results_dir: absolute path to results directory
:return:
"""
log_message = "Copying '%s' '%s' to '%s'"
# copy logs
for log in PathHelper.find_all_files(kwargs[self.TEMPDIR_RESULTS], '*.log'):
logger.debug(log_message, 'log', log, results_dir)
shutil.copy(log, results_dir)
# copy packages
for package in PathHelper.find_all_files(kwargs[self.TEMPDIR], '*.rpm'):
logger.debug(log_message, 'package', package, results_dir)
shutil.copy(package, results_dir)
[docs]
class RpmbuildTemporaryEnvironment(BuildTemporaryEnvironment):
"""Class representing temporary environment for RpmbuildBuildTool."""
TEMPDIR_RPMBUILD: str = TemporaryEnvironment.TEMPDIR + '_RPMBUILD'
TEMPDIR_BUILD: str = TemporaryEnvironment.TEMPDIR + '_BUILD'
TEMPDIR_BUILDROOT: str = TemporaryEnvironment.TEMPDIR + '_BUILDROOT'
TEMPDIR_RPMS: str = TemporaryEnvironment.TEMPDIR + '_RPMS'
TEMPDIR_SRPMS: str = TemporaryEnvironment.TEMPDIR + '_SRPMS'
def _create_directory_structure(self):
# create rpmbuild directory structure
for dir_name in ['RESULTS', 'rpmbuild']:
self._env[self.TEMPDIR + '_' + dir_name.upper()] = os.path.join(
self._env[self.TEMPDIR], dir_name)
logger.debug("Creating '%s'",
self._env[self.TEMPDIR + '_' + dir_name.upper()])
os.makedirs(self._env[self.TEMPDIR + '_' + dir_name.upper()])
for dir_name in ['BUILD', 'BUILDROOT', 'RPMS', 'SOURCES', 'SPECS',
'SRPMS']:
self._env[self.TEMPDIR + '_' + dir_name] = os.path.join(
self._env[self.TEMPDIR_RPMBUILD],
dir_name)
logger.debug("Creating '%s'",
self._env[self.TEMPDIR + '_' + dir_name])
os.makedirs(self._env[self.TEMPDIR + '_' + dir_name])
[docs]
class MockTemporaryEnvironment(BuildTemporaryEnvironment):
"""Class representing temporary environment for MockBuildTool."""
def _create_directory_structure(self):
# create directory structure
for dir_name in ['SOURCES', 'SPECS', 'RESULTS']:
self._env[self.TEMPDIR + '_' + dir_name] = os.path.join(
self._env[self.TEMPDIR], dir_name)
logger.debug("Creating '%s'",
self._env[self.TEMPDIR + '_' + dir_name])
os.makedirs(self._env[self.TEMPDIR + '_' + dir_name])