Blob Blame History Raw
#!/bin/bash

URL="https://apibugzilla.suse.com/xmlrpc.cgi"
COMPONENT="Kernel"
COMMENT="This is an automated report for a proactive fix, documented below."

handle_one_patch() {
    FILE="$1"
    SUBJ=$(formail -x Subject < "${FILE}")
    BODY="$(formail -I "" < "${FILE}" | awk '/^---/ { exit; }; { print; } ')"

    # Use the last available version
    ${BUGZILLA} info -v "${PRODUCT}" > ${tmpdir}/version

    if [ $? -ne 0 ]; then
        echo "Could not get versions for ${PRODUCT}." >&2
        echo "This sometimes produces weird connection aborted errors." >&2
        cat ${tmpdir}/version >&2
        exit 1
    fi

    VERSION=$(grep -v unspecified ${tmpdir}/version | tail -1)

    ${BUGZILLA} new -p "${PRODUCT}" -c "${COMPONENT}" -a "${EMAIL}" \
        ${QA_EMAIL} -t "${SUBJ}" -v "${VERSION}" \
        --comment "${COMMENT}" -s "CONFIRMED" \
	--keywords Proactive-Upstream-Fix \
	--no-refresh --ids > ${tmpdir}/bugid

    if [ $? -ne 0 ]; then
        echo "Bug creation failed for "${FILE}"." >&2
	cat ${tmpdir}/bugid >&2
        exit 1
    fi

    read BUGID < ${tmpdir}/bugid

    # If we didn't get just a bug number, we got an error
    if [ -z "${BUGID}" -o "${BUGID}" != "${BUGID%[^0-9]}" ]; then
        echo "Bug creation failed for ${FILE}; Errors follow." >&2
        cat ${tmpdir}/bugid >&2
        exit 1
    fi

    OLDREFS=$(grep "^References:" "${FILE}"|sed -e 's#References: *##')
    if [ -n "${OLDREFS}" ]; then
        OLDREFS="${OLDREFS} "
    fi

    REFERENCE="References: ${OLDREFS}bsc#${BUGID}"
    if [ -n "${MORE_REFERENCES}" ]; then
        REFERENCE="${REFERENCE} ${MORE_REFERENCES}"
    fi

    # Update the references header before uploading
    FILENAME="$(basename "${FILE}")"
    grep -v "^References:" "${FILE}" | formail -f -I "${REFERENCE}" \
        > "${tmpdir}/${FILENAME}"
    if [ $? -eq 0 ]; then
        mv "${tmpdir}/${FILENAME}" "${FILE}"
    fi

    if [ "${SUBJ}" = "${SUBJ/\[PATCH}" ]; then
            SUBJ="[PATCH] ${SUBJ}"
    fi

    ${BUGZILLA} attach --file="${FILE}" -d "${SUBJ}" -t "text/x-patch" \
          --comment "${BODY}" ${BUGID}

    echo "Filed report ${BUGID} for ${FILE}"
}

usage () {
cat <<END
usage: $(basename $0) [options...] PATCH [PATCH ...]
Options:
    -e | --email <address>
        * Email address to which this report will be assigned
    -p | --product <product>
        * Bugzilla product to fail this report against
    -d | --debug
        * Enable debugging output (also assigns QA contact as you)
    -r | --reference
        * Any additional references to assign to this report,
          e.g. FATE#123456
    -h | --help
    	* Print this message

Notes:
  * If no email address specified, the username component of git-config
    user.email will be used with @suse.com appended.
  * If no product is specified, the \$BUGZILLA_PRODUCT variable in
    rpm/config.sh will be used, if present.
  * If the patch already contains references, they will be preserved with
    the bugzilla ID created and any additional references specified with
    --reference appended.  Otherwise, a new References tag will be created.
  * The patch will be updated with new references prior to upload.
  * Use of this script requires a ~/.bugzillarc with the following contents:
    [apibugzilla.suse.com]
    user = <bugzilla username>
    password = <bugzilla password>
    authtype = basic
END
    exit $1
}

# Defaults
EMAIL="$(git config user.email)"
if [ "${EMAIL}" != "${EMAIL%%*@suse.com}" ]; then
    EMAIL="${EMAIL%%@*}@suse.com"
fi

. $(dirname $0)/../rpm/config.sh
PRODUCT="${BUGZILLA_PRODUCT}"

OPTS="$(getopt -o e:p:dr:h --long email:,product:,debug,reference: -n 'bugzilla-upload' -- "$@")"

if [ $? -ne 0 ]; then
    echo "" >&2
    usage 1
fi

eval set -- "${OPTS}"

while true; do
    case "$1" in
    -e | --email)
        EMAIL="$2" ; shift 2 ;;
    -p | --product)
        PRODUCT="$2" ; shift 2 ;;
    -d | --debug)
        DEBUG=true; shift ;;
    -r | --reference)
        MORE_REFERENCES="${MORE_REFERENCES} $2" ; shift 2 ;;
    -h | --help)
        usage 0 ;;
    --)
        shift ; break ;;
    *)
        break ;;
    esac
done

if [ "$#" -eq 0 ]; then
	echo "" >&2
	usage 1
fi

DEBUG=true

if [ -z "${PRODUCT}" ]; then
    cat <<-END >&2
	ERROR: No product specified.

	Product may be specified via -p or rpm/config.sh:\$BUGZILLA_PRODUCT
	END
    exit 1
fi

if [ -z "${EMAIL}" ]; then
    cat <<-END >&2
	ERROR: No assignee email address specified.

	Email may be specified via -e or git-config user.email
	END
fi

# Don't spam QA while testing
if [ -n "${DEBUG}" ]; then
    QA_EMAIL="-q ${EMAIL}"
fi

DIR="$(realpath "$(dirname "$0")")"
if [ ! -e "${DIR}/bugzilla-cli" ]; then
    echo "Missing ${DIR}/bugzilla-cli" >&2
    exit 1
fi

BUGZILLA="${DIR}/bugzilla-cli --bugzilla ${URL} --ensure-logged-in"

cleanup () {
    rm -rf ${tmpdir}
}

trap cleanup EXIT
tmpdir=$(mktemp -d /tmp/bugzilla.XXXXXX)

for patch in "$@"; do
    handle_one_patch "${patch}"
done