import existing scripts to init project
authorLin Yang <lin.a.yang@intel.com>
Tue, 26 Jun 2012 08:48:30 +0000 (16:48 +0800)
committerLin Yang <lin.a.yang@intel.com>
Tue, 26 Jun 2012 08:48:30 +0000 (16:48 +0800)
DeleteTag.sh [new file with mode: 0755]
PolicyCheck.sh [new file with mode: 0755]
SubmitToOBS.sh [new file with mode: 0755]

diff --git a/DeleteTag.sh b/DeleteTag.sh
new file mode 100755 (executable)
index 0000000..ae94d8f
--- /dev/null
@@ -0,0 +1,88 @@
+#!/bin/bash
+#This script will delete all tags on abandoned commit
+
+set -x
+#Update one git project
+update-git-project()
+{
+    pushd .
+    PRJ_PATH=$1
+    PRJ_FULL_NAME=$2
+    PRJ_NAME=$(basename ${PRJ_FULL_NAME})
+
+    if [ ! -d ${PRJ_PATH} ]; then
+        mkdir ${PRJ_PATH} -p
+    fi
+    cd ${PRJ_PATH}
+    retry_num=3
+    while [ $retry_num -ne 0 ]
+    do
+        #try pull the change from git, if failed, delete local code and re-clone
+        if [ -d ${PRJ_NAME} ]; then
+            cd ${PRJ_NAME}
+            git pull 2>&1
+            if [ $? -ne 0 ]; then
+                cd ${PRJ_PATH}
+                rm -rf ${PRJ_PATH}/${PRJ_NAME}
+                git clone ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${PRJ_FULL_NAME}
+            else
+                popd
+                return 0
+            fi
+        else
+            git clone ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${PRJ_FULL_NAME}
+        fi
+        if [ $? -eq 0 -a -d ${PRJ_NAME} ]; then
+            popd
+            return 0
+        else
+            let "retry_num=retry_num-1"
+            if [ $retry_num -eq 0 ]; then
+                popd
+                return 1
+            fi
+            rm ${PRJ_PATH}/${PRJ_NAME} -rf
+        fi
+    done
+}
+
+#Prepare necessary variable
+export http_proxy=""
+LANG=c
+unset LC_ALL
+PROJECT=$(basename ${GERRIT_PROJECT})
+GERRIT_PATH=$(echo ${GERRIT_PROJECT} | sed "s/^\(.*\)${PROJECT}$/\1/g")
+JENKINS_HOME=$(cd ${WORKSPACE}/../../..; pwd)
+
+#Update gerrit project from remote
+update-git-project ${WORKSPACE} ${GERRIT_PROJECT}
+if [ $? -ne 0 ]; then
+    exit 1
+fi
+cd ${WORKSPACE}/${PROJECT}
+
+#Get all patchset ID of this change
+ssh -p ${GERRIT_SSHPORT} ${GERRIT_USERNAME}@${GERRIT_HOSTNAME} gerrit query "change:${GERRIT_CHANGE_NUMBER}" --patch-sets | egrep "    revision:" > ${WORKSPACE}/patchsetid
+
+#Delete all tags on all patchsets
+index=1
+num=$(echo "0"${GERRIT_CHANGE_NUMBER} | sed "s/^.*\(..\)$/\1/g")
+cat ${WORKSPACE}/patchsetid | while IFS= ; read line
+do
+    commitid=$(echo ${line} | sed "s/^[[:space:]]*revision:[[:space:]]*\([0-9a-z]*\)$/\1/g")
+    git fetch ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${GERRIT_PROJECT} refs/changes/${num}/${GERRIT_CHANGE_NUMBER}/${index}
+    git checkout FETCH_HEAD
+    while [ true ]
+    do
+        tag=$(git describe --tags --exact-match ${commitid})
+        if [ $? -ne 0 ]; then
+            break
+        fi
+        git push origin :refs/tags/${tag} -f
+        git tag -d ${tag}
+    done
+    let index=$index+1
+done
+
+rm ${WORKSPACE}/* -rf
+exit 0
diff --git a/PolicyCheck.sh b/PolicyCheck.sh
new file mode 100755 (executable)
index 0000000..34f861d
--- /dev/null
@@ -0,0 +1,256 @@
+#!/bin/bash
+#Do policy check when a change is created in gerrit
+
+set -x
+#osc wrapper to handle osc random failure
+OSCCMD=/${WORKSPACE}/wrapped_osc
+cat > $OSCCMD << DATA
+#!/usr/bin/python
+import sys, locale
+# this is a hack to make osc work as expected with utf-8 characters,
+# no matter how site.py is set...
+reload(sys)
+loc = locale.getdefaultlocale()[1]
+if not loc:
+    loc = sys.getdefaultencoding()
+sys.setdefaultencoding(loc)
+del sys.setdefaultencoding
+from osc import core, oscerr
+# Injection code for osc.core to fix the empty XML bug
+def solid_get_files_meta(self, revision='latest', skip_service=True):
+    from time import sleep
+    retry_count = 3
+    while retry_count > 0:
+        fm = core.show_files_meta(self.apiurl, self.prjname, self.name,
+                                  revision=revision, meta=self.meta)
+        try:
+            root = core.ET.fromstring(fm)
+            break
+        except:
+            print 'corrupted or empty obs server response ,retrying ...'
+            sleep(1)
+            retry_count -= 1
+    if not retry_count:
+        # all the re-try failed, abort
+        raise oscerr.OscIOError(None, 'cannet fetch files meta xml from server')
+    # look for "too large" files according to size limit and mark them
+    for e in root.findall('entry'):
+        size = e.get('size')
+        if size and self.size_limit and int(size) > self.size_limit \
+            or skip_service and (e.get('name').startswith('_service:') or e.get('name').startswith('_service_')):
+            e.set('skipped', 'true')
+    return core.ET.tostring(root)
+core.Package.get_files_meta = solid_get_files_meta
+# run
+from osc import commandline, babysitter
+sys.exit(babysitter.run(commandline.Osc()))
+DATA
+chmod +x $OSCCMD
+
+#Update one git project
+update-git-project()
+{
+    pushd .
+    PRJ_PATH=$1
+    PRJ_FULL_NAME=$2
+    PRJ_NAME=$(basename ${PRJ_FULL_NAME})
+
+    if [ ! -d ${PRJ_PATH} ]; then
+        mkdir ${PRJ_PATH} -p
+    fi
+    cd ${PRJ_PATH}
+    retry_num=3
+    while [ $retry_num -ne 0 ]
+    do
+        #try pull the change from git, if failed, delete local code and re-clone
+        if [ -d ${PRJ_NAME} ]; then
+            cd ${PRJ_NAME}
+            git pull 2>&1
+            if [ $? -ne 0 ]; then
+                cd ${PRJ_PATH}
+                rm -rf ${PRJ_PATH}/${PRJ_NAME}
+                git clone ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${PRJ_FULL_NAME}
+            else
+                popd
+                return 0                
+            fi
+        else
+            git clone ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${PRJ_FULL_NAME}
+        fi
+        if [ $? -eq 0 -a -d ${PRJ_NAME} ]; then
+            popd
+            return 0
+        else
+            let "retry_num=retry_num-1"
+            if [ $retry_num -eq 0 ]; then
+                popd
+                return 1
+            fi
+            rm ${PRJ_PATH}/${PRJ_NAME} -rf
+        fi
+    done
+}
+
+#Check spec file
+checkspec()
+{
+    spec_check_msg="Auto Policy Check Result:"
+
+    if [ ! ${SPECFILE} ]; then
+        if [ -d packaging ]; then
+            if [ $(find ./packaging -name "*\.spec" | wc -l) -eq 1 ]; then
+                SPECFILE=$(find ./packaging -name "*\.spec" | sed "s/.*packaging\/\(.*\)\.spec/\1/g")
+            fi
+        fi
+        if [ ! ${SPECFILE} ]; then
+            SPECFILE=${PROJECT}
+        fi
+    fi
+    #Check whether exist spec file under packaging directory
+    if [ -f packaging/${SPECFILE}.spec ]; then
+        #Abstract version from spec file
+        cp packaging/${SPECFILE}.spec template.spec
+        egrep "^%prep" template.spec
+        if [ $? -ne 0 ]; then
+            echo "%prep" >> template.spec
+        fi
+        sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{version}\nexit\n/' template.spec > tmp.spec
+        VERSION=$(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3)
+        if [ ! ${VERSION} ]; then
+            VERSION=$(egrep "Version:[ \t]*" tmp.spec | sed "s/.*Version:[ \t]*\(.*\)$/\1/g")
+        fi
+        #Abstract project name from spec file
+        sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{name}\nexit\n/' template.spec > tmp.spec
+        NAME=$(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3)
+        if [ ! ${NAME} ]; then
+            NAME=$(egrep "Name:[ \t]*" tmp.spec | sed "s/.*Name:[ \t]*\(.*\)$/\1/g")
+        fi
+        #Abstract source0 tarball name from spec file
+        sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{SOURCE0}\nexit\n/' template.spec > tmp.spec
+        TARBALL=$(basename $(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3))
+        if [ ! ${TARBALL} ]; then
+            sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{SOURCE}\nexit\n/' template.spec > tmp.spec
+            TARBALL=$(basename $(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3))
+        fi
+        rm tmp.spec template.spec
+
+        if [ "x${direct_submit}" = "xtrue" -o "x${needSR}" = "xtrue" ]; then
+            message="[IMPORTANT NOTICE]:"
+            $OSCCMD -A ${OBS_API_URL} -c ${OBS_OSCRC_PATH} ls ${OBS_DEST_PROJECT} | egrep "^${NAME}$"
+            if [ $? -ne 0 ]; then
+                message=${message}" [NEW package \"${NAME}\"]"
+            fi
+            message=${message}" This change will be submitted to OBS ${OBS_DEST_PROJECT} project !!!"
+        fi
+
+        if [ ! "${NAME}" ]; then
+            lack_field="%{name}"
+        fi
+        if [ ! "${VERSION}" ]; then
+            lack_field=${lack_field}" %{version}"
+        fi
+        if [ "${lack_field}" ]; then
+            spec_check_msg=${spec_check_msg}" Warning: ${SPECFILE}.spec do not contain ${lack_field} variable."
+            return
+        fi
+        else
+        spec_check_msg=${spec_check_msg}" Error: NOT Contain spec file under packaging directory!"
+        return      
+    fi
+    spec_check_msg=${spec_check_msg}" Passed."
+    return
+}
+
+PROJECT=$(basename ${GERRIT_PROJECT})
+GERRIT_PATH=$(echo ${GERRIT_PROJECT} | sed "s/^\(.*\)${PROJECT}$/\1/g")
+JENKINS_HOME=$(cd ${WORKSPACE}/../../..; pwd)
+
+#Update git-obs-mapping configuration if don't exist
+if [ ! -f ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml ]; then
+    update-git-project ${JENKINS_HOME}/git/scm scm/git-obs-mapping
+    if [ $? -ne 0 ]; then
+        exit 1
+    fi
+fi
+
+#Update gerrit project from remote
+update-git-project ${JENKINS_HOME}/git/${GERRIT_PATH} ${GERRIT_PROJECT}
+if [ $? -eq 0 ]; then
+    cp ${JENKINS_HOME}/git/${GERRIT_PROJECT} ${WORKSPACE} -rf
+fi
+update-git-project ${WORKSPACE} ${GERRIT_PROJECT}
+if [ $? -ne 0 ]; then
+    exit 1
+fi
+cd ${WORKSPACE}/${PROJECT}
+
+#Fetch the patch from Gerrit
+git fetch ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${GERRIT_PROJECT} ${GERRIT_REFSPEC} -t
+git checkout FETCH_HEAD
+
+#Parse OBS target project from git-obs-mapping configuration. Result "@OBS_project#@#@OBS_staging_project#@#@OBS_package" will be recoreded in ${WORKSPACE}/mapping.txt
+xml sel -t -m "/mapping/project[@name='${GERRIT_PROJECT}' and @submission='N'] | /mapping/project[@name='/${GERRIT_PROJECT}' and @submission='N'] | /mapping/project[@name='${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}' and @submission='N'] | /mapping/project[@name='/${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}' and @submission='N']" -v "@name" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml
+if [ $? -ne 0 ]; then
+    xml sel -t -m "/mapping/project[@name='${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}'] | /mapping/project[@name='/${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}']" -v "concat(@OBS_project,'#@#',@OBS_staging_project,'#@#',@OBS_package)" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml > ${WORKSPACE}/mapping.txt
+    if [ $? -ne 0 -o ! -f ${WORKSPACE}/mapping.txt -o ! -s ${WORKSPACE}/mapping.txt ]; then
+        PATH_NAME="/"${GERRIT_PROJECT}
+        while [ true ];
+        do
+            PATH_NAME=$(echo ${PATH_NAME} | sed "s/^\(.*\)\/[^\/]*$/\1/g")
+            xml sel -t -m "/mapping/default/path[@name='${PATH_NAME}' and @submission='N'] | /mapping/default/path[@name='${PATH_NAME}/' and @submission='N'] | /mapping/default/path[@name='${PATH_NAME}']/branch[@name='${GERRIT_BRANCH}' and @submission='N'] | /mapping/default/path[@name='${PATH_NAME}/']/branch[@name='${GERRIT_BRANCH}' and @submission='N']" -v "@name" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml
+            if [ $? -eq 0 ]; then
+                break
+            fi
+            xml sel -t -m "/mapping/default/path[@name='${PATH_NAME}']/branch[@name='${GERRIT_BRANCH}'] | /mapping/default/path[@name='${PATH_NAME}/']/branch[@name='${GERRIT_BRANCH}']" -v "concat(@OBS_project,'#@#',@OBS_staging_project,'#@#',@OBS_package)" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml > ${WORKSPACE}/mapping.txt
+            if [ $? -eq 0 -a -f ${WORKSPACE}/mapping.txt -a -s ${WORKSPACE}/mapping.txt ]; then
+                break
+            elif [ ! ${PATH_NAME} ]; then
+                break
+            fi
+        done
+    fi
+fi
+
+if [ -f ${WORKSPACE}/mapping.txt -a -s ${WORKSPACE}/mapping.txt ]; then
+    line=$(head -1 ${WORKSPACE}/mapping.txt)
+    if [ ! ${line} ]; then
+        continue
+    fi
+    OBS_DEST_PROJECT=$(echo ${line} | awk -F '#@#' '{print $1}')
+    OBS_STAGING_PROJECT=$(echo ${line} | awk -F '#@#' '{print $2}')
+    SPECFILE=$(echo ${line} | awk -F '#@#' '{print $3}')
+    if [ ! ${OBS_DEST_PROJECT} ]; then
+        exit 0
+    fi
+    if [ ! "${OBS_STAGING_PROJECT}" ]; then
+        direct_submit=true
+        OBS_STAGING_PROJECT=${OBS_DEST_PROJECT}
+    fi
+    git show --pretty="format:" --name-only ${GERRIT_PATCHSET_REVISION} | egrep "packaging/.*\.changes"
+    if [ $? -eq 0 ]; then
+        git describe --tags --exact-match ${GERRIT_PATCHSET_REVISION}
+        if [ $? -eq 0 ]; then
+            needSR=true
+        fi
+    fi
+
+    #Do policy check for specfile
+    checkspec
+else
+    message="[IMPORTANT NOTICE]: The project will not be submitted to OBS according configuration in gerrit \"scm/git-obs-mapping\" project. If needed, please modify scm/git-obs-mapping to enable submission to OBS."
+fi
+
+#Post comment back to gerrit
+if [ "${message}" ]; then
+    message="- "${message}"\n"
+else
+    message="- "
+fi
+if [ "${spec_check_msg}" ]; then
+    message=${message}${spec_check_msg}
+fi
+ssh -p ${GERRIT_SSHPORT} ${GERRIT_USERNAME}@${GERRIT_HOSTNAME} gerrit review ${GERRIT_CHANGE_NUMBER},${GERRIT_PATCHSET_NUMBER} --message \'"$(echo -e ${message})"\' 
+
+#Cleanup and exit
+rm -rf ${WORKSPACE}/* -rf
+exit 0
diff --git a/SubmitToOBS.sh b/SubmitToOBS.sh
new file mode 100755 (executable)
index 0000000..5687688
--- /dev/null
@@ -0,0 +1,324 @@
+#!/bin/bash
+#This script will submit a merged change to corresponding OBS staging project. If necessary, create SR to request merge to target OBS project.
+
+set -x
+#Cleanup workspace and record execute resutl in mysql DB when script done
+end()
+{
+    rm -rf ${WORKSPACE}/* -rf
+    if [ $1 = success ]; then
+        mysql -h${MYSQL_HOSTNAME} -P${MYSQL_PORT} -u${MYSQL_USERNAME} -p${MYSQL_PASSWORD} -D${MYSQL_DB_NAME} -e "UPDATE ChangeMerged_Event SET state='TRIGGER_SUCCESS' WHERE changeNum='${GERRIT_CHANGE_NUMBER}' and patchsetNum='${GERRIT_PATCHSET_NUMBER}'"
+        exit 0
+    elif [ $1 = retry ]; then
+        mysql -h${MYSQL_HOSTNAME} -P${MYSQL_PORT} -u${MYSQL_USERNAME} -p${MYSQL_PASSWORD} -D${MYSQL_DB_NAME} -e "UPDATE ChangeMerged_Event SET state='TRIGGER_RETRY' WHERE changeNum='${GERRIT_CHANGE_NUMBER}' and patchsetNum='${GERRIT_PATCHSET_NUMBER}'"
+        exit 1
+    else
+        mysql -h${MYSQL_HOSTNAME} -P${MYSQL_PORT} -u${MYSQL_USERNAME} -p${MYSQL_PASSWORD} -D${MYSQL_DB_NAME} -e "UPDATE ChangeMerged_Event SET state='TRIGGER_FAILURE' WHERE changeNum='${GERRIT_CHANGE_NUMBER}' and patchsetNum='${GERRIT_PATCHSET_NUMBER}'"
+        exit 0
+    fi
+}
+
+#Update one git project
+update-git-project()
+{
+    pushd .
+    PRJ_PATH=$1
+    PRJ_FULL_NAME=$2
+    PRJ_NAME=$(basename ${PRJ_FULL_NAME})
+
+    if [ ! -d ${PRJ_PATH} ]; then
+        mkdir ${PRJ_PATH} -p
+    fi
+    cd ${PRJ_PATH}
+    retry_num=3
+    while [ $retry_num -ne 0 ]
+    do
+        #try pull the change from git, if failed, delete local code and re-clone
+        if [ -d ${PRJ_NAME} ]; then
+            cd ${PRJ_NAME}
+            git pull 2>&1
+            if [ $? -ne 0 ]; then
+                cd ${PRJ_PATH}
+                rm -rf ${PRJ_PATH}/${PRJ_NAME}
+                git clone ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${PRJ_FULL_NAME}
+            else
+                popd
+                return 0               
+            fi
+        else
+            git clone ssh://${GERRIT_USERNAME}@${GERRIT_HOSTNAME}:${GERRIT_SSHPORT}/${PRJ_FULL_NAME}
+        fi
+        if [ $? -eq 0 -a -d ${PRJ_NAME} ]; then
+            popd
+            return 0
+        else
+            let "retry_num=retry_num-1"
+            if [ $retry_num -eq 0 ]; then
+                popd
+                return 1
+            fi
+            rm ${PRJ_PATH}/${PRJ_NAME} -rf
+        fi
+    done
+}
+
+#Checkout OBS package to local
+obs_checkout()
+{
+    OBS_PROJECT=$1
+    OBS_PACKAGE=$2
+    retry_num=3
+    while [ $retry_num -ne 0 ]
+    do
+        $OSCCMD ls ${OBS_PROJECT} | egrep "^${OBS_PACKAGE}$"
+        if [ $? -eq 0 ]; then
+            #If OBS staging project already contains package, checkout it directly
+            $OSCCMD co ${OBS_PROJECT} ${OBS_PACKAGE}
+        else
+            #Create a new package in OBS staging project
+            dummy=$($OSCCMD ls ${OBS_PROJECT} | head -1)
+            $OSCCMD ls ${OBS_PROJECT} ${dummy}
+            $OSCCMD co ${OBS_PROJECT} ${dummy}
+            (cd ${OBS_PROJECT} && $OSCCMD mkpac ${OBS_PACKAGE})
+            (cd ${OBS_PROJECT}/${OBS_PACKAGE} && $OSCCMD ci --skip-validation --force -m "init package")
+        fi
+        if [ $? -eq 0 -a -d ${OBS_PROJECT}/${OBS_PACKAGE} ]; then
+            if [ "x${direct_submit}" != "xtrue" ]; then
+                $OSCCMD ls ${OBS_PROJECT} | egrep "^tmp$"
+                if [ $? -ne 0 ]; then
+                    (cd ${OBS_PROJECT} && $OSCCMD mkpac tmp)
+                    (cd ${OBS_PROJECT}/tmp && $OSCCMD ci --skip-validation --force -m "Leave an empty package in here to prevent OBS delete TIZEN:Staging project automatically when all request from here to TIZEN:Main are accepted.")
+                fi
+            fi
+            return 0
+        else
+            let "retry_num=retry_num-1"
+            if [ $retry_num -eq 0 ]; then
+                return 1
+            fi
+            rm ${OBS_PROJECT} -rf
+        fi
+    done
+}
+
+#osc wrapper to handle osc random failure
+OSCCMD=${WORKSPACE}/wrapped_osc
+cat > $OSCCMD << DATA
+#!/usr/bin/python
+import sys, locale
+# this is a hack to make osc work as expected with utf-8 characters,
+# no matter how site.py is set...
+reload(sys)
+loc = locale.getdefaultlocale()[1]
+if not loc:
+    loc = sys.getdefaultencoding()
+sys.setdefaultencoding(loc)
+del sys.setdefaultencoding
+from osc import core, oscerr
+# Injection code for osc.core to fix the empty XML bug
+def solid_get_files_meta(self, revision='latest', skip_service=True):
+    from time import sleep
+    retry_count = 3
+    while retry_count > 0:
+        fm = core.show_files_meta(self.apiurl, self.prjname, self.name,
+                                  revision=revision, meta=self.meta)
+        try:
+            root = core.ET.fromstring(fm)
+            break
+        except:
+            print 'corrupted or empty obs server response ,retrying ...'
+            sleep(1)
+            retry_count -= 1
+    if not retry_count:
+        # all the re-try failed, abort
+        raise oscerr.OscIOError(None, 'cannet fetch files meta xml from server')
+    # look for "too large" files according to size limit and mark them
+    for e in root.findall('entry'):
+        size = e.get('size')
+        if size and self.size_limit and int(size) > self.size_limit \
+            or skip_service and (e.get('name').startswith('_service:') or e.get('name').startswith('_service_')):
+            e.set('skipped', 'true')
+    return core.ET.tostring(root)
+core.Package.get_files_meta = solid_get_files_meta
+# run
+from osc import commandline, babysitter
+sys.exit(babysitter.run(commandline.Osc()))
+DATA
+chmod +x $OSCCMD
+OSCCMD="${WORKSPACE}/wrapped_osc -A ${OBS_API_URL} -c ${OBS_OSCRC_PATH}"
+
+#Prepare necessary variable
+export http_proxy=""
+LANG=c
+unset LC_ALL
+PROJECT=$(basename ${GERRIT_PROJECT})
+GERRIT_PATH=$(echo ${GERRIT_PROJECT} | sed "s/^\(.*\)${PROJECT}$/\1/g")
+JENKINS_HOME=$(cd ${WORKSPACE}/../../..; pwd)
+
+#Update git-obs-mapping configuration if don't exist
+if [ x${GERRIT_PROJECT} = "xscm/git-obs-mapping" -o ! -f ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml ]; then
+    update-git-project ${JENKINS_HOME}/git/scm scm/git-obs-mapping
+    if [ $? -ne 0 ]; then
+        end retry
+    fi
+    if [ x${GERRIT_PROJECT} = "xscm/git-obs-mapping" ]; then
+        end success
+    fi
+fi
+
+#Parse OBS target project from git-obs-mapping configuration. Result "@OBS_project#@#@OBS_staging_project#@#@OBS_package" will be recoreded in ${WORKSPACE}/mapping.txt
+#Check whether submission of this project is blocked
+xml sel -t -m "/mapping/project[@name='${GERRIT_PROJECT}' and @submission='N'] | /mapping/project[@name='/${GERRIT_PROJECT}' and @submission='N'] | /mapping/project[@name='${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}' and @submission='N'] | /mapping/project[@name='/${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}' and @submission='N']" -v "@name" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml > ${WORKSPACE}/mapping.txt
+if [ $? -eq 0 -a -f ${WORKSPACE}/mapping.txt -a -s ${WORKSPACE}/mapping.txt ]; then
+    end success
+fi
+#Check whether this project map to a specific OBS project
+xml sel -t -m "/mapping/project[@name='${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}'] | /mapping/project[@name='/${GERRIT_PROJECT}']/branch[@name='${GERRIT_BRANCH}']" -v "concat(@OBS_project,'#@#',@OBS_staging_project,'#@#',@OBS_package)" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml > ${WORKSPACE}/mapping.txt
+if [ $? -ne 0 -o ! -f ${WORKSPACE}/mapping.txt -o ! -s ${WORKSPACE}/mapping.txt ]; then
+    #Search default section in git-obs-mapping configuration
+    PATH_NAME="/"${GERRIT_PROJECT}
+    while [ true ];
+    do
+        PATH_NAME=$(echo ${PATH_NAME} | sed "s/^\(.*\)\/[^\/]*$/\1/g")
+        #Check whether submission under this directory is blocked
+        xml sel -t -m "/mapping/default/path[@name='${PATH_NAME}' and @submission='N'] | /mapping/default/path[@name='${PATH_NAME}/' and @submission='N'] | /mapping/default/path[@name='${PATH_NAME}']/branch[@name='${GERRIT_BRANCH}' and @submission='N'] | /mapping/default/path[@name='${PATH_NAME}/']/branch[@name='${GERRIT_BRANCH}' and @submission='N']" -v "@name" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml > ${WORKSPACE}/mapping.txt
+        if [ $? -eq 0 -a -f ${WORKSPACE}/mapping.txt -a -s ${WORKSPACE}/mapping.txt ]; then
+            end success
+        fi
+        xml sel -t -m "/mapping/default/path[@name='${PATH_NAME}']/branch[@name='${GERRIT_BRANCH}'] | /mapping/default/path[@name='${PATH_NAME}/']/branch[@name='${GERRIT_BRANCH}']" -v "concat(@OBS_project,'#@#',@OBS_staging_project,'#@#',@OBS_package)" -n ${JENKINS_HOME}/git/scm/git-obs-mapping/git-obs-mapping.xml > ${WORKSPACE}/mapping.txt
+        if [ $? -eq 0 -a -f ${WORKSPACE}/mapping.txt -a -s ${WORKSPACE}/mapping.txt ]; then
+            break
+        elif [ ! ${PATH_NAME} ]; then
+            end success
+        fi
+    done
+fi
+
+#Update gerrit project from remote
+update-git-project ${JENKINS_HOME}/git/${GERRIT_PATH} ${GERRIT_PROJECT}
+if [ $? -eq 0 ]; then
+    cp ${JENKINS_HOME}/git/${GERRIT_PROJECT} ${WORKSPACE} -rf
+fi
+update-git-project ${WORKSPACE} ${GERRIT_PROJECT}
+if [ $? -ne 0 ]; then
+    end retry
+fi
+
+cd ${WORKSPACE}/${PROJECT}
+git checkout origin/${GERRIT_BRANCH}
+COMMITLOG=$(git log -1 --format="%h : %s" ${GERRIT_PATCHSET_REVISION})
+
+line=$(head -1 ${WORKSPACE}/mapping.txt)
+if [ ! ${line} ]; then
+    continue
+fi
+cd ${WORKSPACE}/${PROJECT}
+OBS_DEST_PROJECT=$(echo ${line} | awk -F '#@#' '{print $1}')
+OBS_STAGING_PROJECT=$(echo ${line} | awk -F '#@#' '{print $2}')
+SPECFILE=$(echo ${line} | awk -F '#@#' '{print $3}')
+if [ ! "${OBS_DEST_PROJECT}" ]; then
+    end failure
+fi
+if [ ! "${OBS_STAGING_PROJECT}" ]; then
+    direct_submit=true
+    OBS_STAGING_PROJECT=${OBS_DEST_PROJECT}
+fi
+if [ "x${direct_submit}" != "xtrue" ]; then
+    git show --pretty="format:" --name-only ${GERRIT_PATCHSET_REVISION} | egrep "packaging/.*\.changes"
+    if [ $? -ne 0 ]; then
+        end success
+    else
+        git describe --tags --exact-match ${GERRIT_PATCHSET_REVISION}
+        if [ $? -ne 0 ]; then
+            end success
+        fi
+    fi
+fi
+
+#If git-obs-mapping don't indicate use which specfile, use the only one specfile by default
+if [ ! ${SPECFILE} ]; then
+    if [ -d packaging ]; then
+        if [ $(find ./packaging -name "*\.spec" | wc -l) -eq 1 ]; then
+            SPECFILE=$(find ./packaging -name "*\.spec" | sed "s/.*packaging\/\(.*\)\.spec/\1/g")
+        fi
+    fi
+    if [ ! ${SPECFILE} ]; then
+        SPECFILE=${PROJECT}
+    fi
+fi
+#Abstract related info from spec file
+if [ -f packaging/${SPECFILE}.spec ]; then
+    cp packaging/${SPECFILE}.spec template.spec
+    egrep "^%prep" template.spec
+    if [ $? -ne 0 ]; then
+        echo "%prep" >> template.spec
+    fi
+    sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{version}\nexit\n/' template.spec > tmp.spec
+    VERSION=$(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3)
+    if [ ! ${VERSION} ]; then
+        VERSION=$(egrep "Version:[ \t]*" tmp.spec | sed "s/.*Version:[ \t]*\(.*\)$/\1/g")
+    fi
+    sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{name}\nexit\n/' template.spec > tmp.spec
+    NAME=$(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3)
+    if [ ! ${NAME} ]; then
+        NAME=$(egrep "Name:[ \t]*" tmp.spec | sed "s/.*Name:[ \t]*\(.*\)$/\1/g")
+    fi
+    sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{SOURCE0}\nexit\n/' template.spec > tmp.spec
+    TARBALL=$(basename $(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3))
+    if [ ! ${TARBALL} ]; then
+        sed -e 's/BuildArch:.*//g' -e 's/ExclusiveArch:.*//g' -e 's/^%prep/%prep\necho %{SOURCE}\nexit\n/' template.spec > tmp.spec
+        TARBALL=$(basename $(rpmbuild -bp --nodeps --force tmp.spec --define '_topdir .' --define '_builddir .' --define '_sourcedir .' --define '_rpmdir .' --define '_specdir .' --define '_srcrpmdir .' 2>&1 | grep 'echo' | cut -d ' ' -f 3))
+    fi
+    rm tmp.spec template.spec
+    if [ ! ${NAME} -o ! ${VERSION} ]; then
+        end failure
+    fi
+else
+    end failure
+fi
+#Use gbs to generate tarball
+gbs export --spec=packaging/${SPECFILE}.spec 
+
+cd ${WORKSPACE}
+OBS_PACKAGE=${NAME}
+#Checkout OBS package to local
+obs_checkout ${OBS_STAGING_PROJECT} ${OBS_PACKAGE}
+if [ $? -ne 0 ]; then
+    end retry
+fi
+
+#Update files in local OBS package directory    
+cd ${WORKSPACE}/${OBS_STAGING_PROJECT}/${OBS_PACKAGE}
+rm ${WORKSPACE}/${OBS_STAGING_PROJECT}/${OBS_PACKAGE}/* -rf
+cp ${WORKSPACE}/${PROJECT}/packaging/* . -rf
+echo -e "Commit: ${COMMITLOG}\nOwner: ${GERRIT_PATCHSET_UPLOADER_NAME} <${GERRIT_PATCHSET_UPLOADER_EMAIL}>\nGerrit URL: ${GERRIT_CHANGE_URL}\nSubmit Time: $(date +"%x %H:%M:%S")" > ${WORKSPACE}/message.txt
+#Submit code to OBS staging project and create a request to merger to Trunk
+retry_num=3
+while [ $retry_num -ne 0 ]
+do
+    $OSCCMD addremove &&
+    $OSCCMD ci --skip-validation --force -F ${WORKSPACE}/message.txt &&
+    if [ "x${direct_submit}" != "xtrue" ]; then
+        $OSCCMD request list -U ${OBS_USERNAME} ${OBS_DEST_PROJECT} ${OBS_PACKAGE} > ${WORKSPACE}/request.txt &&
+        {
+            REQUEST_ID=$(head -1 ${WORKSPACE}/request.txt | awk '{print $1}')
+            if [ ${REQUEST_ID} ]; then
+                echo -e "" >> ${WORKSPACE}/message.txt
+                $OSCCMD request show ${REQUEST_ID} > ${WORKSPACE}/request.txt &&
+                awk -v key="Message:" '$0==key{p=1;next}/\State:/{p=0}p' ${WORKSPACE}/request.txt >> ${WORKSPACE}/message.txt &&
+                echo "y" | $OSCCMD sr ${OBS_DEST_PROJECT} ${OBS_PACKAGE} -m "$(cat ${WORKSPACE}/message.txt)" --cleanup &&
+                break
+            else
+                $OSCCMD sr ${OBS_DEST_PROJECT} ${OBS_PACKAGE} -m "$(cat ${WORKSPACE}/message.txt)" --cleanup &&
+                break
+            fi
+        }
+    else
+        break
+    fi
+    let "retry_num=retry_num-1"
+    if [ $retry_num -eq 0 ]; then
+        end retry
+    fi
+done
+end success