From 6d544cf41630fe8d095641be91192a465131e65e Mon Sep 17 00:00:00 2001 From: Ondrej Nosek Date: Dec 14 2022 03:55:40 +0000 Subject: WIP: Checking availability of sources in lookaside with a git hook This check should prevent unwanted pushing of incorrect configuration. When a 'git push' command is executed, the git hook script is activated. Checks available: 1. Is tarball added in the 'sources' file? 2. Is tarball uploaded to the lookaside cache? JIRA: RHELCMP-10415 Fixes: https://pagure.io/fedpkg/issue/491 Relates: https://pagure.io/releng/issue/9955 Signed-off-by: Ondrej Nosek --- diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py index 1595344..ab3367a 100644 --- a/pyrpkg/__init__.py +++ b/pyrpkg/__init__.py @@ -1626,6 +1626,7 @@ class Commands(object): if not bare_dir: self._add_git_excludes(os.path.join(path, git_dir)) + self._add_git_pre_push_hook(os.path.join(path, git_dir)) return @@ -1711,6 +1712,7 @@ class Commands(object): # Add excludes self._add_git_excludes(branch_path) + self._add_git_pre_push_hook(branch_path) except (git.GitCommandError, OSError) as e: raise rpkgError('Could not locally clone %s from %s: %s' % (branch, repo_path, e)) @@ -1773,6 +1775,72 @@ class Commands(object): git_excludes.write() self.log.debug('Git-excludes patterns were added into %s' % git_excludes_path) + def _add_git_pre_push_hook(self, conf_dir): + """ + TODO: make the description + """ + # TODO: dedent? + hook_content = """#!/bin/bash + +remote="$1" # NOTE: is it needed? +url="$2" + +IFS=' ' + +while read local_ref local_sha remote_ref remote_sha # NOTE: are these useful? +do + # TODO: it is not very reliable way of specifying .spec so far. + REPO=$(basename `pwd`) # can I rely on 'pwd'? + echo "Repo:" $REPO # NOTE: debug + MAIN_SPECFILE=$(ls *.spec | grep $REPO.spec) + if [[ -z "$MAIN_SPECFILE" ]]; then + MAIN_SPECFILE=$(ls *.spec | head -n 1) + fi + echo "Specfile:" $MAIN_SPECFILE # NOTE: debug + SOURCE=$(spectool -lS $MAIN_SPECFILE) + TARBALL=$(basename $(echo $SOURCE | cut -d: -f2-)) # TODO: is it always URL? + echo "Tarball:" $TARBALL # NOTE: debug + + # 1st test - Is tarball added in the 'sources' file? + grep -q $TARBALL sources + if [[ $? -ne 0 ]]; then + echo "Tarball is not added to the 'sources'. Push operation was canceled." + exit 1 + fi + + # 2nd test - Is tarball uploaded to the lookaside cache? + # TODO: more items/lines? + HASH_TYPE=$(grep $TARBALL sources | cut -d\ -f1 | tr '[:upper:]' '[:lower:]') + echo "Hash type:" $HASH_TYPE # NOTE: debug + # TODO: possible more types of 'sources' file formats + HASH=$(grep $TARBALL sources | cut -d= -f2 | xargs) # NOTE: xargs does trimming + echo "Hash:" $HASH # NOTE: debug + + # TODO: This should come from fedpkg's config. Move the functionality there? + FEDPKG_LOOKASIDE="https://src.fedoraproject.org/repo/pkgs" + NAMESPACE="rpms" + LOOKASIDE_URL=$FEDPKG_LOOKASIDE/$NAMESPACE/$REPO/$TARBALL/$HASH_TYPE/$HASH/$TARBALL + echo "Lookaside URL:" $LOOKASIDE_URL # NOTE: debug + if curl --head --silent --fail $LOOKASIDE_URL 1>/dev/null; then + echo "OK" # NOTE: debug + else + echo "Tarball wasn't uploaded to the lookaside cache. Push operation was cancelled." + exit 2 + fi +done + +exit 0 +""" # noqa + + git_pre_push_hook_path = os.path.join(conf_dir, '.git/hooks/pre-push') + if not os.path.exists(os.path.dirname(git_pre_push_hook_path)): + # prepare ".git/hooks" directory if is missing + os.makedirs(os.path.dirname(git_pre_push_hook_path)) + with open(git_pre_push_hook_path, "w") as hook_file: + hook_file.writelines(hook_content) + os.chmod(git_pre_push_hook_path, 0o775) # TODO: catch exceptions + self.log.debug('pre-push hook script was added into %s' % git_pre_push_hook_path) + def commit(self, message=None, file=None, files=[], signoff=False): """Commit changes to a repository (optionally found at path)