2 # @License EPL-1.0 <http://spdx.org/licenses/EPL-1.0>
5 # - Add -r option for mock to choose the distribution
6 # - add option to pass in spec file name, maybe use spec.in template
7 # - add option to pass in version and release
23 dist="fedora-19-x86_64"
24 pkg_dist_suffix="fc19"
25 mock_cmd="/usr/bin/mock"
39 # Maven is not installed at the system wide level but at the Jenkins level
40 # We need to map our Maven call to the Jenkins installed version
41 mvn_cmd="$JENKINS_HOME/tools/hudson.tasks.Maven_MavenInstallation/Maven_3.0.4/bin/mvn"
43 # Define our push repositories here. We do it in code since we can't
44 # use a POM file for the RPM pushes (we're doing "one-off" file pushes)
46 # Repositories will be of the form baseRepositoryId-$dist{-testing}
47 # -testing if it's a snapshot build (not using -snapshot as the name as
48 # -testing is the more common testing repo suffix for yum)
49 baseURL="http://nexus.opendaylight.org/content/repositories/opendaylight-yum-"
50 baseRepositoryId="opendaylight-yum-"
54 readonly RCPARMSERROR=65
55 readonly RCRPMBUILDERROR=66
56 readonly RCRMOCKERROR=67
65 local level=$1; shift;
67 if [ $level -le $loglevel ]; then
76 if [ "$outstr" != "" ]; then
81 echo "Usage: `basename $0` [OPTION...]"
84 echo " --buildtype TYPE build type, either snapshot or release"
85 echo " --buildroot DIRECTORY build root path"
86 echo " --buildtag tag the tmpbuild directory, i.e. Jenkins build number"
87 echo " --cleanroot clean buildroot directory before building"
88 echo " --cleantmp clean tmpbuild directory before building"
89 echo " --dist DIST distribution"
90 echo " --distsuffix SUFFIX package distribution suffix"
91 echo " --getsource METHOD method for getting source clone|snapshot|buildroot"
94 echo " --release RELEASE release tag (not used yet)"
95 echo " --version VERSION version tag"
97 echo "Repo sync options:"
98 echo " --repourl REPOURL url of the repo, include http://"
99 echo " --repouser REPOUSER user for repo"
100 echo " --repopw REPOPW password for repo"
102 echo "Deployment options:"
103 echo " --pushrpms push the built rpms to a maven repository"
104 echo " --mvn_cmd fully qualified path to where the mvn command"
105 echo " (defaults to Jenkins installation of Maven 3.0.4)"
106 echo " --baseURL base deployment URL. \$dist will be added to the end of this"
107 echo " If this is a snapshot build then -testing be added at the end"
108 echo " --baseRepositoryId base repository name. \$dist will be added to the end of this"
109 echo " If this is a snapshot build then -testing be added at the end"
112 echo " --mockinit Run mock init"
113 echo " --mockmvn replace the maven command used within mock"
116 echo " -?, -h, --help Display this help and exit"
117 echo " --debug Enable bash debugging output"
118 echo " --mockdebug Enable mock debugging output"
121 echo " --shortcircuits INDEX Start build with project index"
122 echo " --shortcircuite INDEX End build with project index"
123 echo " --listprojects List the projects and indexes"
124 echo " --timesuffix TIME Set the time suffix to use for build output"
130 readonly PJ_INTEGRATION=0
131 readonly PJ_CONTROLLER=1
133 readonly PJ_OPENFLOWJAVA=3
134 readonly PJ_OPENFLOWPLUGIN=4
135 readonly PJ_DEPENDENCIES=5
136 readonly PJ_OPENDAYLIGHT=6
137 readonly PJ_OPENDOVE=8
138 readonly PJ_LISPFLOWMAPPING=7
141 projects[$PJ_INTEGRATION]="opendaylight-integration"
142 projects[$PJ_CONTROLLER]="opendaylight-controller"
143 projects[$PJ_OVSDB]="opendaylight-ovsdb"
144 projects[$PJ_OPENFLOWJAVA]="opendaylight-openflowjava"
145 projects[$PJ_OPENFLOWPLUGIN]="opendaylight-openflowplugin"
146 projects[$PJ_DEPENDENCIES]="opendaylight-controller-dependencies"
147 projects[$PJ_OPENDAYLIGHT]="opendaylight"
148 projects[$PJ_OPENDOVE]="opendaylight-opendove"
149 projects[$PJ_LISPFLOWMAPPING]="opendaylight-lispflowmapping"
151 versions[$PJ_INTEGRATION]=""
152 versions[$PJ_CONTROLLER]=""
153 versions[$PJ_OVSDB]=""
154 versions[$PJ_OPENFLOWJAVA]=""
155 versions[$PJ_OPENFLOWPLUGIN]=""
156 versions[$PJ_DEPENDENCIES]=""
157 versions[$PJ_OPENDAYLIGHT]=""
158 versions[$PJ_OPENDOVE]=""
159 versions[$PJ_LISPFLOWMAPPING]=""
161 suffix[$PJ_INTEGRATION]=""
162 suffix[$PJ_CONTROLLER]=""
164 suffix[$PJ_OPENFLOWJAVA]=""
165 suffix[$PJ_OPENFLOWPLUGIN]=""
166 suffix[$PJ_DEPENDENCIES]=""
167 suffix[$PJ_OPENDAYLIGHT]=""
168 suffix[$PJ_OPENDOVE]=""
169 suffix[$PJ_LISPFLOWMAPPING]=""
171 gitprojects="$PJ_INTEGRATION $PJ_CONTROLLER $PJ_OVSDB $PJ_OPENFLOWJAVA $PJ_OPENFLOWPLUGIN $PJ_OPENDOVE $PJ_LISPFLOWMAPPING"
173 # Clone the projects.
174 function clone_source {
175 for i in $gitprojects; do
176 # We only care about a shallow clone (no need to grab the entire project)
177 project=${projects[$i]:13}
178 log $LOGINFO "Cloning $project to $buildroot/${projects[$i]}"
179 git clone --depth 0 https://git.opendaylight.org/gerrit/p/$project.git $buildroot/${projects[$i]}
183 # Copy the projects from snapshots.
184 # shague: Fill in with the nexus info.
185 # Make mk_snapshot_archives that just sets up the version strings.
186 function snapshot_source {
187 log $LOGINFO "$FUNCNAME: Not implemented yet."
190 # Archive the projects to creates the SOURCES for rpmbuild:
191 # - xz the source for later use by rpmbuild.
192 # - get the version and git hashes to produce a versions and suffix for each project.
193 # - copy the archives to the SOURCES dir
194 # shague: need another archive method for snapshot getsource builds since
195 # the source did not come from a git repo.
196 # versionmajor=0.1.0.snap.20140201.191633.git.7c5788d
197 # versionsnapsuffix=snap.20140201.191633.git.7c5788d
199 function mk_git_archives {
202 for i in $gitprojects; do
203 if [ "$version" == "" ]; then
204 if [ "$buildtype" == "snapshot" ]; then
205 cd $buildroot/${projects[$i]}
206 suffix[$i]="snap.$timesuffix.git.$(git log -1 --pretty=format:%h)"
211 if [ "$buildtype" == "snapshot" ]; then
212 suffix[$i]="snap.$version"
218 cd $buildroot/${projects[$PJ_INTEGRATION]}/packaging/rpm
219 # Get the version from the spec and append the suffix.
220 # integration uses the controller.spec because there isn't an integration.spec to query.
221 if [ ${projects[$i]} == ${projects[$PJ_INTEGRATION]} ]; then
222 versions[$i]="$( rpm -q --queryformat="%{version}\n" --specfile ${projects[$PJ_CONTROLLER]}.spec | head -n 1 | awk '{print $1}').${suffix[$i]}"
224 versions[$i]="$( rpm -q --queryformat="%{version}\n" --specfile ${projects[$i]}.spec | head -n 1 | awk '{print $1}').${suffix[$i]}"
227 # User really wants to set the version.
228 if [ "$buildtype" == "release" ] && [ "$version" != "" ]; then
229 versions[$i]=$version
232 log $LOGINFO "Building archive: $tmpbuild/${projects[$i]}-${versions[$i]}.tar.xz"
233 cd $buildroot/${projects[$i]}
234 git archive --prefix=${projects[$i]}-${versions[$i]}/ HEAD | \
235 xz > $tmpbuild/${projects[$i]}-${versions[$i]}.tar.xz
239 # Use the controller versions because these projects don't have a repo.
240 for i in `seq $PJ_DEPENDENCIES $PJ_OPENDAYLIGHT`; do
241 suffix[$i]=${suffix[$PJ_CONTROLLER]}
242 versions[$i]=${versions[$PJ_CONTROLLER]}
245 # Don't forget any patches.
246 cp $buildroot/${projects[$PJ_INTEGRATION]}/packaging/rpm/opendaylight-integration-fix-paths.patch $tmpbuild
249 # Pushes rpms to the specified Nexus repository
250 # This only happens if pushrpms is true
252 if [ $pushrpms = 1 ]; then
253 allrpms=`find $tmpbuild/repo -iname '*.rpm'`
255 log $LOGINFO "RPMS found"
256 for i in $allrpms; do
261 log $LOGINFO "::::: pushing RPMs"
263 for i in $allrpms; do
264 rpmname=`rpm -qp --queryformat="%{name}" $i`
265 rpmversion=`rpm -qp --queryformat="%{version}" $i`
266 distro=`echo $dist | tr - .`
268 if [ `echo $i | grep 'src.rpm'` ]; then
269 rpmrelease=`rpm -qp --queryformat="%{release}.src" $i`
272 rpmrelease=`rpm -qp --queryformat="%{release}.%{arch}" $i`
277 if [ "$buildtype" == "snapshot" ]; then
278 repositoryId="${baseRepositoryId}${dist}-testing"
279 pushURL="${baseURL}${dist}-testing"
281 repositoryId="${baseRepositoryId}${dist}"
282 pushURL="${baseURL}${dist}"
285 # Note version is the full version+release+{arch|src}
286 # if it is not configured this way on pushes then a download
287 # of the artifact will result in just the name-version.rpm
288 # instead of name-version-release.{arch|src}.rpm
289 $mvn_cmd org.apache.maven.plugins:maven-deploy-plugin:2.8.1:deploy-file \
290 -Dfile=$i -DrepositoryId=$repositoryId \
291 -Durl=$pushURL -DgroupId=$groupId \
292 -Dversion=$rpmversion-$rpmrelease -DartifactId=$rpmname \
300 Building controller using:
302 suffix: $pkg_dist_suffix
303 buildtype: $buildtype
306 getsource: $getsource
307 buildroot: $buildroot
316 # Build a single project.
317 function build_project {
319 local versionmajor="$2"
320 local versionsnapsuffix="$3"
323 log $LOGINFO "::::: building $project.rpm"
326 cp -f $buildroot/${projects[$PJ_INTEGRATION]}/packaging/rpm/$project.spec $tmpbuild
329 if [ "$buildtype" == "release" ] && [ "$version" != "" ]; then
330 # Find lines starting with Version: and replace the whole line with the version requested
331 sed -r -i -e '/^Version:./c\Version: '"$versionmajor" $project.spec
333 # Find lines starting with Version: and replace the rest of the line with the versionsnapsuffix
334 sed -r -i -e '/^Version:/s/\s*$/'".$versionsnapsuffix/" $project.spec
337 # Set the write values in the spec files.
339 ${projects[$PJ_CONTROLLER]})
340 # Set the version for the integration source.
341 # Find lines with opendaylight-integration-%{version} and replace %{version} with the version.
342 sed -r -i -e '/opendaylight-integration-\%\{version\}/s/\%\{version\}/'"${versions[$PJ_INTEGRATION]}"'/g' \
346 ${projects[$PJ_DEPENDENCIES]})
347 # Set the version for ovsdb in the dependencies spec.
348 # Find lines with opendaylight-ovsdb-%{version} and replace %{version} with the version.
349 sed -r -i -e '/opendaylight-ovsdb-\%\{version\}/s/\%\{version\}/'"${versions[$PJ_OVSDB]}"'/g' \
351 # Find lines with opendaylight-ovsdb-dependencies-%{version} and replace %{version} with the version.
352 sed -r -i -e '/opendaylight-ovsdb-dependencies-\%\{version\}/s/\%\{version\}/'"${versions[$PJ_OVSDB]}"'/g' \
360 # Rewrite the mvn command in the rpmbuild if the user requests it.
361 if [ "$mockmvn" != "" ]; then
362 # Find lines starting with export MAVEN_OPTS= and replace the whole line with $mockmvn
363 sed -r -i -e '/^export MAVEN_OPTS=./c\ '"$mockmvn" $project.spec
366 # Build the source RPM for use by mock later.
367 #rm -f SRPMS/*.src.rpm
368 log $LOGINFO "::::: building $project.src.rpm with rpmbuild"
369 rpmbuild -bs --define '%_topdir '"`pwd`" --define '%_sourcedir %{_topdir}' \
370 --define "%dist .$pkg_dist_suffix" $project.spec
373 if [ $rc != 0 ]; then
374 log $LOGERROR "rpmbuild of $project.src.rpm failed (rc=$rc)."
375 exit $RCRPMBUILDERROR
378 log $LOGINFO "::::: building $project.rpm with mock"
380 if [ "$buildtype" == "release" ]; then
381 resultdir="repo/$project.$pkg_dist_suffix.noarch"
383 resultdir="repo/$project.$pkg_dist_suffix.noarch.snap"
386 # Build the rpm using mock.
387 # Keep the build because we will need the distribution zip file for later
388 # when building the controller-dependencies.rpm.
389 eval $mock_cmd $mockdebug -r $dist --no-clean --no-cleanup-after --resultdir \"$resultdir\" \
390 -D \"dist .$pkg_dist_suffix\" -D \"noclean 1\" \
391 SRPMS/$project-$versionmajor-*.src.rpm
394 if [ $rc != 0 ]; then
395 log $LOGERROR "mock of $project.rpm failed (rc=$rc)."
399 log $LOGINFO "::::: finished building $project.rpm in mock"
401 # Copy the distribution zip from the controller and ovsdb projects
402 # for use in the dependencies.rpm.
404 ${projects[$PJ_CONTROLLER]})
405 log $LOGINFO "::::: Copying $project distribution.zip."
406 eval $mock_cmd $mockdebug -r $dist --no-clean --no-cleanup-after --resultdir \"$resultdir\" \
407 -D \"dist .$pkg_dist_suffix\" -D \"noclean 1\" \
408 --copyout \"builddir/build/BUILD/$project-$versionmajor/opendaylight/distribution/opendaylight/target/distribution.opendaylight-osgipackage.zip\" \"$resultdir/$project-$versionmajor.zip\"
410 ln -sf $resultdir/$project-$versionmajor.zip $tmpbuild
412 if [ ! -e $tmpbuild/$project-$versionmajor.zip ]; then
413 log $LOGERROR "cannot find $project distribution zip file (rc=$rc1:$rc2)."
418 ${projects[$PJ_OVSDB]})
419 log $LOGINFO "::::: Copying $project distribution.zip."
420 # Grab the version from the pom.xml file.
421 # Get the lines between the parent tags, then get the line with the version tag and remove leading space and
422 # the tag itself, then remove the trailing tag to be left with the version.
423 pomversion=`sed -n -e '/<parent>/,/<\/parent>/p' "$buildroot/${projects[$PJ_OVSDB]}/pom.xml" | sed -n -e '/<version>/s/.*<version>//p' | sed -n -e 's/<\/version>//p'`
424 eval $mock_cmd $mockdebug -r $dist --no-clean --no-cleanup-after --resultdir \"$resultdir\" \
425 -D \"dist .$pkg_dist_suffix\" -D \"noclean 1\" \
426 --copyout \"builddir/build/BUILD/$project-$versionmajor/distribution/opendaylight/target/distribution.ovsdb-$pomversion-osgipackage.zip\" \"$resultdir/$project-$versionmajor.zip\"
428 ln -sf $resultdir/$project-$versionmajor.zip $tmpbuild
430 if [ ! -e $tmpbuild/$project-$versionmajor.zip ]; then
431 log $LOGERROR "cannot find $project distribution zip file (rc=$rc1:$rc2)."
441 # Main function that builds the rpm's for snapshot's.
442 function build_snapshot {
443 mk_git_archives $timesuffix
445 # Initialize our mock build location (we'll be using --no-clean later)
446 # If we don't do the first init we can't build since the environment
447 # doesn't get setup correctly!
448 if [ $mockinit -eq 1 ]; then
449 eval $mock_cmd $mockdebug -r $dist --init
454 end=$PJ_LISPFLOWMAPPING
456 if [ $shortcircuits -ne 0 ]; then
460 if [ $shortcircuite -ne 0 ]; then
464 echo "start:end = $start:$end"
466 for i in `seq $start $end`; do
467 build_project ${projects[$i]} ${versions[$i]} ${suffix[$i]}
471 log $LOGINFO "::::: All projects have been built"
477 # Main function that builds the rpm's for release's.
478 # shague: should be similar to snapshot but use a different version or tag.
479 # spec files should be updated with correct version. If so, do
480 function build_release {
481 log $LOGINFO "$FUNCNAME: Not implemented yet."
484 function parse_options {
492 mockdebug="-v"; shift;
496 shift; buildtype="$1"; shift;
497 if [ "$buildtype" != "snapshot" ] && [ "$buildtype" != "release" ]; then
498 usage $RCPARMSERROR "Invalid build type.";
503 shift; buildroot="$1"; shift;
504 if [ "$buildroot" == "" ]; then
505 usage $RCPARMSERROR "Missing build root.";
507 if [ ! -d "$buildroot" ]; then
508 usage $RCPARMSERROR "Invalid build root path."
513 shift; buildtag="$1"; shift;
514 if [ "$buildtag" == "" ]; then
515 usage $RCPARMSERROR "Missing build tag.";
528 shift; getsource="$1"; shift;
529 if [ "$getsource" != "clone" ] && [ "$getsource" != "snapshot" ] && \
530 [ "$getsource" != "buildroot" ]; then
531 usage $RCPARMSERROR "Invalid getsource method.";
536 shift; dist="$1"; shift;
537 if [ "$dist" == "" ]; then
538 $RCPARMSERROR "Missing distribution.";
543 shift; pkg_dist_suffix="$1"; shift;
544 if [ "$pkg_dist_suffix" == "" ]; then
545 $RCPARMSERROR "Missing package distribution suffix.";
550 shift; release="$1"; shift;
551 if [ "$release" == "" ]; then
552 $RCPARMSERROR "Missing release.";
557 shift; version="$1"; shift;
558 if [ "$version" == "" ]; then
559 $RCPARMSERROR "Missing version.";
564 shift; repourl="$1"; shift;
565 if [ "$repourl" == "" ]; then
566 $RCPARMSERROR "Missing repo url.";
571 shift; repouser="$1"; shift;
572 if [ "$repouser" == "" ]; then
573 $RCPARMSERROR "Missing repo user.";
578 shift; repopw="$1"; shift;
579 if [ "$repopw" == "" ]; then
580 $RCPARMSERROR "Missing repo pw.";
589 shift; timesuffix="$1"; shift;
590 if [ "$timesuffix" == "" ]; then
591 usage $RCPARMSERROR "Missing time suffix.";
596 shift; mvn_cmd="$1"; shift;
597 if [ "$mvn_cmd" == "" ]; then
598 $RCPARMSERROR "Missing mvn_cmd.";
607 shift; mockmvn="$1"; shift;
608 if [ "$mockmvn" == "" ]; then
609 $RCPARMSERROR "Missing mockmvn.";
614 shift; baseURL="$1"; shift;
615 if [ "$baseURL" == "" ]; then
616 $RCPARMSERROR "Missing baseURL.";
621 shift; baseRepositoryId="$1"; shift;
622 if [ "$baseRepositoryId" == "" ]; then
623 $RCPARMSERROR "Missing baseRepositoryId.";
628 shift; shortcircuits=$1; shift;
632 shift; shortcircuite=$1; shift;
636 listprojects=1; shift;
646 log $LOGINFO "Ignoring unknown option: $1"; shift;
652 #################### main ####################
654 if [ "$timesuffix" == "" ]; then
655 timesuffix="$(date +%F_%T | tr -d .:- | tr _ .)"
657 date_start=$(date +%s)
661 if [ $listprojects -eq 1 ]; then
662 for i in `seq $PJ_FIRST $PJ_LAST`; do
663 echo "$i ${projects[$i]}"
668 # Some more error checking...
669 if [ -z $buildroot ]; then
670 log $LOGERROR "Mising buildroot"
674 if [ $cleanroot -eq 1 ] && [ $getsource = "buildroot" ]; then
675 log $LOGERROR "Aborting. You probably do not want to clean the directory" \
676 "containing the source."
680 # Can change tmpbuild to be an index or other tag
681 if [ -n "$buildtag" ]; then
682 tmpbuild="$buildroot/bld_$buildtag"
684 tmpbuild="$buildroot/bld"
689 if [ $cleanroot -eq 1 ]; then
694 if [ $cleantmp -eq 1 ]; then
698 # Setup the temp build directory.
699 mkdir -p $tmpbuild/repo
715 # Check if all the projects dirs are really there.
716 for i in $gitprojects; do
717 if [ ! -d ${projects[$i]}; then
718 log $LOGERROR "Missing ${projects[$i]}"
725 if [ "$buildtype" = "snapshot" ]; then
726 log $LOGINFO "Building a snapshot build"
729 #log $LOGINFO "Release builds are not supported yet."
731 log $LOGINFO "Building a release build"
736 diff=$(($date_end - $date_start))
737 log $LOGINFO "Build took $(($diff / 3600 % 24)) hours $(($diff / 60 % 60)) minutes and $(($diff % 60)) seconds."