You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by GitBox <gi...@apache.org> on 2018/03/15 10:55:31 UTC

[GitHub] DaanHoogland closed pull request #2433: CLOUDSTACK-10268: Fix and enhance package script

DaanHoogland closed pull request #2433: CLOUDSTACK-10268: Fix and enhance package script
URL: https://github.com/apache/cloudstack/pull/2433
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseIntegrityChecker.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseIntegrityChecker.java
index 6111fb16cf2..bb75aacf2b6 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseIntegrityChecker.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseIntegrityChecker.java
@@ -26,7 +26,8 @@
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
-import com.cloud.maint.Version;
+import org.apache.cloudstack.utils.CloudStackVersion;
+
 import com.cloud.upgrade.dao.VersionDao;
 import com.cloud.utils.component.AdapterBase;
 import com.cloud.utils.component.ComponentLifecycle;
@@ -210,7 +211,7 @@ private boolean checkMissedPremiumUpgradeFor228() {
                     return false;
                 }
 
-                if (Version.compare(Version.trimToPatch(dbVersion), Version.trimToPatch("2.2.8")) != 0) {
+                if (CloudStackVersion.compare(dbVersion, "2.2.8") != 0) {
                     txn.commit();
                     return true;
                 }
diff --git a/packaging/build-deb.sh b/packaging/build-deb.sh
index d8f2f8f09b0..52a168a95ba 100755
--- a/packaging/build-deb.sh
+++ b/packaging/build-deb.sh
@@ -40,18 +40,104 @@
 # docker run -ti -v /tmp:/src ubuntu:14.04 /bin/bash -c "apt-get update && apt-get install -y dpkg-dev python debhelper openjdk-8-jdk genisoimage python-mysql.connector maven lsb-release devscripts dh-systemd python-setuptools && /src/cloudstack/packaging/build-deb.sh"
 #
 
-cd `dirname $0`
-cd ..
+function usage() {
+    cat << USAGE
+Usage: ./build-deb.sh [OPTIONS]...
+Package CloudStack for Debian based distribution.
+
+If there's a "branding" string in the POM version (e.g. x.y.z.a-NAME[-SNAPSHOT]), the branding name will
+be used in the final generated pacakge like: cloudstack-management_x.y.z.a-NAME-SNAPSHOT~xenial_all.deb
+note that you can override/provide "branding" string with "-b, --brand" flag as well.
+
+Optional arguments:
+   -b, --brand string                      Set branding to be used in package name (it will override any branding string in POM version)
+   -T, --use-timestamp                     Use epoch timestamp instead of SNAPSHOT in the package name (if not provided, use "SNAPSHOT")
+
+Other arguments:
+   -h, --help                              Display this help message and exit
+
+Examples:
+   build-deb.sh --use-timestamp
+   build-deb.sh --brand foo
+
+USAGE
+    exit 0
+}
+
+BRANDING=""
+USE_TIMESTAMP="false"
+
+while [ -n "$1" ]; do
+    case "$1" in
+        -h | --help)
+            usage
+            ;;
+
+        -b | --brand)
+            if [ -n "$BRANDING" ]; then
+                echo "ERROR: you have already entered value for -b, --brand"
+                exit 1
+            else
+                BRANDING=$2
+                shift 2
+            fi
+            ;;
+
+        -T | --use-timestamp)
+            if [ "$USE_TIMESTAMP" == "true" ]; then
+                echo "ERROR: you have already entered value for -T, --use-timestamp"
+                exit 1
+            else
+                USE_TIMESTAMP="true"
+                shift 1
+            fi
+            ;;
+
+        -*|*)
+            echo "ERROR: no such option $1. -h or --help for help"
+            exit 1
+            ;;
+    esac
+done
 
 DCH=$(which dch)
 if [ -z "$DCH" ] ; then
     echo -e "dch not found, please install devscripts at first. \nDEB Build Failed"
-    exit
+    exit 1
 fi
 
+NOW="$(date +%s)"
+PWD=$(cd $(dirname "$0") && pwd -P)
+cd $PWD/../
+
 VERSION=$(head -n1 debian/changelog  |awk -F [\(\)] '{print $2}')
 DISTCODE=$(lsb_release -sc)
 
+if [ "$USE_TIMESTAMP" == "true" ]; then
+    # use timestamp instead of SNAPSHOT
+    if echo "$VERSION" | grep -q SNAPSHOT ; then
+        # apply/override branding, if provided
+        if [ "$BRANDING" != "" ]; then
+            VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+            VERSION="$VERSION-$BRANDING-$NOW"
+        else
+            VERSION=`echo $VERSION | sed 's/-SNAPSHOT/-'$NOW'/g'`
+        fi
+
+        branch=$(cd $PWD; git rev-parse --abbrev-ref HEAD)
+        (cd $PWD; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+    fi
+else
+    # apply/override branding, if provided
+    if [ "$BRANDING" != "" ]; then
+        VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+        VERSION="$VERSION-$BRANDING"
+
+        branch=$(cd $PWD; git rev-parse --abbrev-ref HEAD)
+        (cd $PWD; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+    fi
+fi
+
 /bin/cp debian/changelog /tmp/changelog.orig
 
 dch -b -v "${VERSION}~${DISTCODE}" -u low -m "Apache CloudStack Release ${VERSION}"
@@ -61,3 +147,5 @@ dpkg-checkbuilddeps
 dpkg-buildpackage -uc -us -b
 
 /bin/mv /tmp/changelog.orig debian/changelog
+
+(cd $PWD; git reset --hard)
diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec
index ba1798e7dac..c26143ede83 100644
--- a/packaging/centos63/cloud.spec
+++ b/packaging/centos63/cloud.spec
@@ -24,13 +24,8 @@
 Name:      cloudstack
 Summary:   CloudStack IaaS Platform
 #http://fedoraproject.org/wiki/PackageNamingGuidelines#Pre-Release_packages
-%if "%{?_prerelease}" != ""
-%define _maventag %{_ver}-SNAPSHOT
+%define _maventag %{_fullver}
 Release:   %{_rel}%{dist}
-%else
-%define _maventag %{_ver}
-Release:   %{_rel}%{dist}
-%endif
 
 %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 
diff --git a/packaging/centos7/cloud.spec b/packaging/centos7/cloud.spec
index 481c86c3baf..23d386696cc 100644
--- a/packaging/centos7/cloud.spec
+++ b/packaging/centos7/cloud.spec
@@ -24,13 +24,8 @@
 Name:      cloudstack
 Summary:   CloudStack IaaS Platform
 #http://fedoraproject.org/wiki/PackageNamingGuidelines#Pre-Release_packages
-%if "%{?_prerelease}" != ""
-%define _maventag %{_ver}-SNAPSHOT
+%define _maventag %{_fullver}
 Release:   %{_rel}%{dist}
-%else
-%define _maventag %{_ver}
-Release:   %{_rel}%{dist}
-%endif
 
 %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 
diff --git a/packaging/package.sh b/packaging/package.sh
index 8a876615123..a823afadff2 100755
--- a/packaging/package.sh
+++ b/packaging/package.sh
@@ -17,48 +17,68 @@
 # under the License.
 
 function usage() {
-    echo ""
-    echo "usage: ./package.sh [-h|--help] -d|--distribution <name> [-r|--release <version>] [-p|--pack oss|OSS|noredist|NOREDIST] [-s|--simulator default|DEFAULT|simulator|SIMULATOR]"
-    echo ""
-    echo "The supported arguments are:"
-    echo "  To package with only redistributable libraries (default)"
-    echo "    -p|--pack oss|OSS"
-    echo "  To package with non-redistributable libraries"
-    echo "    -p|--pack noredist|NOREDIST"
-    echo "  To build a package for a distribution (mandatory)"
-    echo "    -d|--distribution centos7|centos63|fedora20|fedora21"
-    echo "  To set the package release version (optional)"
-    echo "  (default is 1 for normal and prereleases, empty for SNAPSHOT)"
-    echo "    -r|--release version(integer)"
-    echo "  To build for Simulator (optional)"
-    echo "    -s|--simulator default|DEFAULT|simulator|SIMULATOR"
-    echo "  To display this information"
-    echo "    -h|--help"
-    echo ""
-    echo "Examples: ./package.sh --pack oss"
-    echo "          ./package.sh --pack noredist"
-    echo "          ./package.sh --pack oss --distribution centos7 --release 42"
-    echo "          ./package.sh --distribution centos7 --release 42"
-    echo "          ./package.sh --distribution centos7"
+    cat << USAGE
+Usage: ./package.sh -d DISTRO [OPTIONS]...
+Package CloudStack for specific distribution and provided options.
+
+If there's a "branding" string in the POM version (e.g. x.y.z.a-NAME[-SNAPSHOT]), the branding name will
+be used in the final generated pacakge like: cloudstack-management-x.y.z.a-NAME.NUMBER.el7.centos.x86_64
+note that you can override/provide "branding" string with "-b, --brand" flag as well.
+
+Mandatory arguments:
+   -d, --distribution string               Build package for specified distribution ("centos7"|"centos63")
+
+Optional arguments:
+   -p, --pack string                       Define which type of libraries to package ("oss"|"OSS"|"noredist"|"NOREDIST") (default "oss")
+                                             - oss|OSS to package with only redistributable libraries
+                                             - noredist|NOREDIST to package with non-redistributable libraries
+   -r, --release integer                   Set the package release version (default is 1 for normal and prereleases, empty for SNAPSHOT)
+   -s, --simulator string                  Build package for Simulator ("default"|"DEFAULT"|"simulator"|"SIMULATOR") (default "default")
+   -b, --brand string                      Set branding to be used in package name (it will override any branding string in POM version)
+   -T, --use-timestamp                     Use epoch timestamp instead of SNAPSHOT in the package name (if not provided, use "SNAPSHOT")
+
+Other arguments:
+   -h, --help                              Display this help message and exit
+
+Examples:
+   package.sh --distribution centos7
+   package.sh --distribution centos7 --pack oss
+   package.sh --distribution centos7 --pack noredist
+   package.sh --distribution centos7 --release 42
+   package.sh --distribution centos7 --pack noredist --release 42
+
+USAGE
+    exit 0
 }
 
+PWD=$(cd $(dirname "$0") && pwd -P)
+NOW="$(date +%s)"
+
 # packaging
 #   $1 redist flag
 #   $2 simulator flag
 #   $3 distribution name
 #   $4 package release version
+#   $5 brand string to apply/override
+#   $6 use timestamp flag
 function packaging() {
-    CWD=$(pwd)
-    RPMDIR=$CWD/../dist/rpmbuild
+    RPMDIR=$PWD/../dist/rpmbuild
     PACK_PROJECT=cloudstack
+
     if [ -n "$1" ] ; then
         DEFOSSNOSS="-D_ossnoss $1"
     fi
     if [ -n "$2" ] ; then
         DEFSIM="-D_sim $2"
     fi
+    if [ "$6" == "true" ]; then
+        INDICATOR="$NOW"
+    else
+        INDICATOR="SNAPSHOT"
+    fi
 
     DISTRO=$3
+
     MVN=$(which mvn)
     if [ -z "$MVN" ] ; then
         MVN=$(locate bin/mvn | grep -e mvn$ | tail -1)
@@ -67,24 +87,63 @@ function packaging() {
             exit 2
         fi
     fi
-    VERSION=$(cd ../; $MVN org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep --color=none '^[0-9]\.')
+
+    VERSION=$(cd $PWD/../; $MVN org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep --color=none '^[0-9]\.')
+    REALVER=$(echo "$VERSION" | cut -d '-' -f 1)
+
+    if [ -n "$5" ]; then
+        BRAND="${5}."
+    else
+        BASEVER=$(echo "$VERSION" | sed 's/-SNAPSHOT//g')
+        BRAND=$(echo "$BASEVER" | cut -d '-' -f 2)
+
+        if [ "$REALVER" != "$BRAND" ]; then
+            BRAND="${BRAND}."
+        else
+            BRAND=""
+        fi
+    fi
+
     if echo "$VERSION" | grep -q SNAPSHOT ; then
-        REALVER=$(echo "$VERSION" | cut -d '-' -f 1)
         if [ -n "$4" ] ; then
-            DEFPRE="-D_prerelease $4"
-            DEFREL="-D_rel SNAPSHOT$4"
+            DEFREL="-D_rel ${BRAND}${INDICATOR0}.$4"
         else
-            DEFPRE="-D_prerelease 1"
-            DEFREL="-D_rel SNAPSHOT"
+            DEFREL="-D_rel ${BRAND}${INDICATOR}"
         fi
     else
-        REALVER="$VERSION"
         if [ -n "$4" ] ; then
-            DEFREL="-D_rel $4"
+            DEFREL="-D_rel ${BRAND}$4"
         else
-            DEFREL="-D_rel 1"
+            DEFREL="-D_rel ${BRAND}1"
         fi
     fi
+
+    if [ "$USE_TIMESTAMP" == "true" ]; then
+        # use timestamp instead of SNAPSHOT
+        if echo "$VERSION" | grep -q SNAPSHOT ; then
+            # apply/override branding, if provided
+            if [ "$BRANDING" != "" ]; then
+                VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+                VERSION="$VERSION-$BRANDING-$NOW"
+            else
+                VERSION=`echo $VERSION | sed 's/-SNAPSHOT/-'$NOW'/g'`
+            fi
+
+            branch=$(cd $PWD/../; git rev-parse --abbrev-ref HEAD)
+            (cd $PWD/../; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+        fi
+    else
+        # apply/override branding, if provided
+        if [ "$BRANDING" != "" ]; then
+            VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+            VERSION="$VERSION-$BRANDING"
+
+            branch=$(cd $PWD/../; git rev-parse --abbrev-ref HEAD)
+            (cd $PWD/../; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+        fi
+    fi
+
+    DEFFULLVER="-D_fullver $VERSION"
     DEFVER="-D_ver $REALVER"
 
     echo "Preparing to package Apache CloudStack $VERSION"
@@ -96,13 +155,14 @@ function packaging() {
     mkdir -p "$RPMDIR/SOURCES/$PACK_PROJECT-$VERSION"
 
     echo ". preparing source tarball"
-    (cd ../; tar -c --exclude .git --exclude dist . | tar -C "$RPMDIR/SOURCES/$PACK_PROJECT-$VERSION" -x )
+    (cd $PWD/../; tar -c --exclude .git --exclude dist . | tar -C "$RPMDIR/SOURCES/$PACK_PROJECT-$VERSION" -x )
     (cd "$RPMDIR/SOURCES/"; tar -czf "$PACK_PROJECT-$VERSION.tgz" "$PACK_PROJECT-$VERSION")
 
     echo ". executing rpmbuild"
-    cp "$DISTRO/cloud.spec" "$RPMDIR/SPECS"
+    cp "$PWD/$DISTRO/cloud.spec" "$RPMDIR/SPECS"
 
-    (cd "$RPMDIR"; rpmbuild --define "_topdir ${RPMDIR}" "${DEFVER}" "${DEFREL}" ${DEFPRE+"$DEFPRE"} ${DEFOSSNOSS+"$DEFOSSNOSS"} ${DEFSIM+"$DEFSIM"} -bb SPECS/cloud.spec)
+    (cd "$RPMDIR"; rpmbuild --define "_topdir ${RPMDIR}" "${DEFVER}" "${DEFFULLVER}" "${DEFREL}" ${DEFPRE+"$DEFPRE"} ${DEFOSSNOSS+"$DEFOSSNOSS"} ${DEFSIM+"$DEFSIM"} -bb SPECS/cloud.spec)
+    (cd $PWD/../; git reset --hard)
     if [ $? -ne 0 ]; then
         echo "RPM Build Failed "
         exit 3
@@ -116,22 +176,20 @@ TARGETDISTRO=""
 SIM=""
 PACKAGEVAL=""
 RELEASE=""
+BRANDING=""
+USE_TIMESTAMP="false"
 
-SHORTOPTS="hp:s:d:r:"
-LONGOPTS="help,pack:simulator:distribution:release:"
-ARGS=$(getopt -s bash -u -a --options "$SHORTOPTS"  --longoptions "$LONGOPTS" --name "$0" -- "$@")
-eval set -- "$ARGS"
-echo "$ARGS"
-while [ $# -gt 0 ] ; do
+unrecognized_flags=""
+
+while [ -n "$1" ]; do
     case "$1" in
         -h | --help)
             usage
             exit 0
             ;;
+
         -p | --pack)
-            echo "Packaging CloudStack..."
             PACKAGEVAL=$2
-            echo "$PACKAGEVAL"
             if [ "$PACKAGEVAL" == "oss" -o "$PACKAGEVAL" == "OSS" ] ; then
                 PACKAGEVAL=""
             elif [ "$PACKAGEVAL" == "noredist" -o "$PACKAGEVAL" == "NOREDIST" ] ; then
@@ -141,11 +199,11 @@ while [ $# -gt 0 ] ; do
                 usage
                 exit 1
             fi
-            shift
+            shift 2
             ;;
+
         -s | --simulator)
             SIM=$2
-            echo "$SIM"
             if [ "$SIM" == "default" -o "$SIM" == "DEFAULT" ] ; then
                 SIM="false"
             elif [ "$SIM" == "simulator" -o "$SIM" == "SIMULATOR" ] ; then
@@ -155,8 +213,9 @@ while [ $# -gt 0 ] ; do
                 usage
                 exit 1
             fi
-            shift
+            shift 2
             ;;
+
         -d | --distribution)
             TARGETDISTRO=$2
             if [ -z "$TARGETDISTRO" ] ; then
@@ -164,22 +223,41 @@ while [ $# -gt 0 ] ; do
                 usage
                 exit 1
             fi
-            shift
+            shift 2
             ;;
+
         -r | --release)
             RELEASE=$2
-            shift
+            shift 2
             ;;
-        -)
-            echo "Error: Unrecognized option"
-            usage
-            exit 1
+
+        -b | --brand)
+            BRANDING=$2
+            shift 2
             ;;
+
+        -T | --use-timestamp)
+            USE_TIMESTAMP="true"
+            shift 1
+            ;;
+
+        -*)
+            unrecognized_flags="${unrecognized_flags}$1 "
+            shift 1
+            ;;
+
         *)
-            shift
+            shift 1
             ;;
     esac
 done
 
-packaging "$PACKAGEVAL" "$SIM" "$TARGETDISTRO" "$RELEASE"
+if [ -n "$unrecognized_flags" ]; then
+    echo "Warning: Unrecognized option(s) found \" ${unrecognized_flags}\""
+    echo "         You're advised to fix your build job scripts and prevent using these"
+    echo "         flags, as in the future release(s) they will break packaging script."
+    echo ""
+fi
 
+echo "Packaging CloudStack..."
+packaging "$PACKAGEVAL" "$SIM" "$TARGETDISTRO" "$RELEASE" "$BRANDING" "$USE_TIMESTAMP"
diff --git a/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java
index e3d1e30d348..729ef2b6c79 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java
@@ -21,16 +21,17 @@
 
 import javax.inject.Inject;
 
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
 import org.apache.cloudstack.api.response.DomainRouterResponse;
 import org.apache.cloudstack.api.response.NicResponse;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
+import org.apache.cloudstack.utils.CloudStackVersion;
 
 import com.cloud.api.ApiResponseHelper;
 import com.cloud.api.query.vo.DomainRouterJoinVO;
-import com.cloud.maint.Version;
 import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.router.VirtualRouter.Role;
@@ -78,9 +79,9 @@ public DomainRouterResponse newDomainRouterResponse(DomainRouterJoinVO router, A
         routerResponse.setIsRedundantRouter(router.isRedundantRouter());
         routerResponse.setRedundantState(router.getRedundantState().toString());
         if (router.getTemplateVersion() != null) {
-            String routerVersion = Version.trimRouterVersion(router.getTemplateVersion());
+            String routerVersion = CloudStackVersion.trimRouterVersion(router.getTemplateVersion());
             routerResponse.setVersion(routerVersion);
-            routerResponse.setRequiresUpgrade((Version.compare(routerVersion, NetworkOrchestrationService.MinVRVersion.valueIn(router.getDataCenterId())) < 0));
+            routerResponse.setRequiresUpgrade((CloudStackVersion.compare(routerVersion, NetworkOrchestrationService.MinVRVersion.valueIn(router.getDataCenterId())) < 0));
         } else {
             routerResponse.setVersion("UNKNOWN");
             routerResponse.setRequiresUpgrade(true);
diff --git a/server/src/main/java/com/cloud/network/router/NetworkHelperImpl.java b/server/src/main/java/com/cloud/network/router/NetworkHelperImpl.java
index fa17e7bc315..5c84527317a 100644
--- a/server/src/main/java/com/cloud/network/router/NetworkHelperImpl.java
+++ b/server/src/main/java/com/cloud/network/router/NetworkHelperImpl.java
@@ -27,12 +27,14 @@
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
+import org.apache.log4j.Logger;
+import org.cloud.network.router.deployment.RouterDeploymentDefinition;
+
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-import org.cloud.network.router.deployment.RouterDeploymentDefinition;
+import org.apache.cloudstack.utils.CloudStackVersion;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
@@ -61,7 +63,6 @@
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.maint.Version;
 import com.cloud.network.IpAddressManager;
 import com.cloud.network.Network;
 import com.cloud.network.NetworkModel;
@@ -265,8 +266,8 @@ public boolean checkRouterVersion(final VirtualRouter router) {
             return false;
         }
         final long dcid = router.getDataCenterId();
-        final String trimmedVersion = Version.trimRouterVersion(router.getTemplateVersion());
-        return Version.compare(trimmedVersion, NetworkOrchestrationService.MinVRVersion.valueIn(dcid)) >= 0;
+        String routerVersion = CloudStackVersion.trimRouterVersion(router.getTemplateVersion());
+        return CloudStackVersion.compare(routerVersion, NetworkOrchestrationService.MinVRVersion.valueIn(dcid)) >= 0;
     }
 
     protected DomainRouterVO start(DomainRouterVO router, final User user, final Account caller, final Map<Param, Object> params, final DeploymentPlan planToDeploy)
diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh
index 8b1032ecc8b..893404da531 100755
--- a/tools/appliance/build.sh
+++ b/tools/appliance/build.sh
@@ -34,8 +34,12 @@ Usage:
 END
   exit 0
 }
-echo $@ | grep help >/dev/null && usage
-echo $@ | grep '\-h' >/dev/null && usage
+
+for i in $@; do
+    if [ "$i" == "-h" -o "$i" == "--help" -o "$i" == "help" ]; then
+        usage
+    fi
+done
 
 # requires 32-bit vhd-util and faketime binaries to be available (even for 64 bit builds)
 # Something like (on centos 6.5)...
@@ -194,8 +198,10 @@ function create_definition() {
     cp -r "${appliance}" "${appliance_build_name}"
     set +e
     if [ ! -z "${version}" ]; then
-    sed ${sed_regex_option} -i -e "s/^CLOUDSTACK_RELEASE=.+/CLOUDSTACK_RELEASE=${version}/" \
-        "${appliance_build_name}/configure_systemvm_services.sh"
+    if [ -f "${appliance_build_name}/scripts/configure_systemvm_services.sh" ]; then
+        sed ${sed_regex_option} -i -e "s/^CLOUDSTACK_RELEASE=.+/CLOUDSTACK_RELEASE=${version}/" \
+            "${appliance_build_name}/scripts/configure_systemvm_services.sh"
+        fi
     fi
     set -e
     add_on_exit rm -rf "${appliance_build_name}"
@@ -215,7 +221,7 @@ function packer_build() {
   cd ${appliance_build_name} && packer build template.json && cd ..
 }
 
-function stage_vmx (){
+function stage_vmx() {
   cat << VMXFILE > "${1}.vmx"
 .encoding = "UTF-8"
 displayname = "${1}"
diff --git a/tools/build/setnextversion.sh b/tools/build/setnextversion.sh
index 2387b8926bc..b4bf9145d65 100755
--- a/tools/build/setnextversion.sh
+++ b/tools/build/setnextversion.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -16,60 +16,125 @@
 # specific language governing permissions and limitations
 # under the License.
 
-version='TESTBUILD'
-sourcedir=~/cloudstack/
-branch='master'
+set -e
 
-usage(){
-    echo "usage: $0 -v version [-b branch] [-s source dir] [-h]"
-    echo "  -v sets the version"
-    echo "  -b sets the branch (defaults to 'master')"
-    echo "  -s sets the source directory (defaults to $sourcedir)"
-    echo "  -h"
+usage() {
+    cat << USAGE
+Usage: setnextversion.sh --version string [OPTIONS]...
+Set the next version of CloudStack in the POMs.
+
+Mandatory arguments:
+   -v, --version string                    Set the next version to be applied
+
+Optional arguments:
+   -b, --branch string                     Set the branch to update the version into (default "master")
+   -s, --sourcedir string                  Set the source directory to clone repo into (default "$sourcedir")
+   -n, --no-commit                         Apply only the version change and don't git commit them (default "false")
+
+Other arguments:
+   -h, --help                              Display this help message and exit
+
+Examples:
+   setnextversion.sh --version x.y.z.a-SNAPSHOT
+   setnextversion.sh --version x.y.z.a-SNAPSHOT --branch foo-feature
+   setnextversion.sh --version x.y.z.a-SNAPSHOT --sourcedir /path/to/cloudstack/repo
+   setnextversion.sh --version x.y.z.a-SNAPSHOT --no-commit
+
+USAGE
+    exit 0
 }
 
-while getopts v:s:b:h opt
-do
-    case "$opt" in
-      v)  version="$OPTARG";;
-      s)  sourcedir="$OPTARG";;
-      b)  branch="$OPTARG";;
-      h)  usage
-          exit 0;;
-      /?)       # unknown flag
-          usage
-          exit 1;;
+while [ -n "$1" ]; do
+    case "$1" in
+        -h | --help)
+            usage
+            ;;
+
+        -v | --version)
+            if [ -n "$version" ]; then
+                echo "ERROR: you have already entered value for -v, --version"
+                exit 1
+            else
+                version=$2
+                shift 2
+            fi
+            ;;
+
+        -b | --branch)
+            if [ -n "$branch" ]; then
+                echo "ERROR: you have already entered value for -b, --branch"
+                exit 1
+            else
+                branch=$2
+                shift 2
+            fi
+            ;;
+
+        -s | --sourcedir)
+            if [ -n "$sourcedir" ]; then
+                echo "ERROR: you have already entered value for -s, --sourcedir"
+                exit 1
+            else
+                sourcedir=$2
+                shift 2
+            fi
+            ;;
+
+        -n | --no-commit)
+            if [ "$nocommit" == "true" ]; then
+                echo "ERROR: you have already entered value for -n, --no-commit"
+                exit 1
+            else
+                nocommit="true"
+                shift 1
+            fi
+            ;;
+
+        -*|*)
+            echo "ERROR: no such option $1. -h or --help for help"
+            exit 1
+            ;;
     esac
 done
-shift `expr $OPTIND - 1`
 
-if [ $version == 'TESTBUILD' ]; then
-    echo >&2 "A version must be specified with the -v option: $0 -v 4.0.0.RC1"
+if [ -z "$version" ]; then
+    echo >&2 "A version must be specified with the -v, --version option: $0 -v 4.0.0.RC1"
     exit 1
 fi
 
-echo "Using version: $version"
-echo "Using source directory: $sourcedir"
-echo "Using branch: $branch"
+if [ -z "$branch" ]; then
+    branch="master"
+fi
+
+if [ -z "$sourcedir" ]; then
+    sourcedir="~/cloudstack/"
+fi
+
+if [ -z "$nocommit" ]; then
+    nocommit="false"
+fi
+
+echo "Using version          : $version"
+echo "Using source directory : $sourcedir"
+echo "Using branch           : $branch"
 
 cd $sourcedir
 
-echo 'checking out correct branch'
+echo "checking out correct branch"
 git checkout $branch
 
-echo 'determining current mvn version'
+echo "determining current POM version"
 export currentversion=`mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['`
 echo "found $currentversion"
 
-echo 'setting version numbers'
-mvn versions:set -DnewVersion=$version -P vmware -P developer -P systemvm -P simulator -P baremetal -P ucs -Dnoredist
-mv deps/XenServerJava/pom.xml.versionsBackup deps/XenServerJava/pom.xml
-perl -pi -e "s/$currentversion/$version/" deps/XenServerJava/pom.xml
+echo "setting new version numbers"
+mvn versions:set -DnewVersion=$version -P vmware -P developer -P systemvm -P simulator -Dnoredist versions:commit
+
 perl -pi -e "s/$currentversion/$version/" tools/apidoc/pom.xml
 perl -pi -e "s/$currentversion/$version/" debian/changelog
 perl -pi -e "s/$currentversion/$version/" tools/marvin/setup.py
 perl -pi -e "s/$currentversion/$version/" services/iam/plugin/pom.xml
-perl -pi -e "s/$currentversion/$version/" services/iam/pom.xm
+perl -pi -e "s/$currentversion/$version/" services/iam/pom.xml
 perl -pi -e "s/$currentversion/$version/" services/iam/server/pom.xml
 perl -pi -e "s/$currentversion/$version/" tools/checkstyle/pom.xml
 perl -pi -e "s/$currentversion/$version/" services/console-proxy/plugin/pom.xml
@@ -85,8 +150,10 @@ perl -pi -e "s/Marvin-(.*).tar.gz/Marvin-${version}.tar.gz/" tools/docker/Docker
 
 git clean -f
 
-echo 'commit changes'
-git commit -a -s -m "Updating pom.xml version numbers for release $version"
-export commitsh=`git show HEAD | head -n 1 | cut -d ' ' -f 2`
+if [ "$nocommit" == "false" ]; then
+    echo "commit changes"
+    git commit -a -s -m "Updating pom.xml version numbers for release $version"
+    export commitsh=`git show HEAD | head -n 1 | cut -d ' ' -f 2`
 
-echo "committed as $commitsh"
+    echo "committed as $commitsh"
+fi
diff --git a/utils/src/main/java/com/cloud/maint/Version.java b/utils/src/main/java/com/cloud/maint/Version.java
deleted file mode 100644
index 925806e3a05..00000000000
--- a/utils/src/main/java/com/cloud/maint/Version.java
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.maint;
-
-public class Version {
-    /**
-     * Compares two version strings and see which one is higher version.
-     * @param ver1
-     * @param ver2
-     * @return positive if ver1 is higher.  negative if ver1 is lower; zero if the same.
-     */
-    public static int compare(String ver1, String ver2) {
-        String[] tokens1 = ver1.split("[.]");
-        String[] tokens2 = ver2.split("[.]");
-//        assert(tokens1.length <= tokens2.length);
-
-        int compareLength = Math.min(tokens1.length, tokens2.length);
-        for (int i = 0; i < compareLength; i++) {
-            long version1 = Long.parseLong(tokens1[i]);
-            long version2 = Long.parseLong(tokens2[i]);
-            if (version1 != version2) {
-                return version1 < version2 ? -1 : 1;
-            }
-        }
-
-        if (tokens1.length > tokens2.length) {
-            return 1;
-        } else if (tokens1.length < tokens2.length) {
-            return -1;
-        }
-
-        return 0;
-    }
-
-    public static String trimToPatch(String version) {
-        int index = version.indexOf("-");
-
-        if (index > 0)
-            version = version.substring(0, index);
-
-        String[] tokens = version.split("[.]");
-
-        if (tokens.length < 3)
-            return "0";
-        return tokens[0] + "." + tokens[1] + "." + tokens[2];
-    }
-
-    public static String trimRouterVersion(String version) {
-        String[] tokens = version.split(" ");
-        if (tokens.length >= 3 && tokens[2].matches("[0-9]+(\\.[0-9]+)*")) {
-            return tokens[2];
-        }
-        return "0";
-    }
-
-    public static void main(String[] args) {
-        System.out.println("Result is " + compare(args[0], args[1]));
-    }
-
-}
diff --git a/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java b/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java
index 4dfd4e2b62a..9090de755a3 100755
--- a/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java
+++ b/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java
@@ -21,7 +21,7 @@
 
 import org.apache.log4j.Logger;
 
-import com.cloud.maint.Version;
+import org.apache.cloudstack.utils.CloudStackVersion;
 
 public class NiciraNvpApiVersion {
     private static final Logger s_logger = Logger.getLogger(NiciraNvpApiVersion.class);
@@ -33,8 +33,10 @@ public static synchronized void setNiciraApiVersion(String apiVersion){
     }
 
     public static synchronized boolean isApiVersionLowerThan(String apiVersion){
-        if (niciraApiVersion == null) return false;
-        int compare = Version.compare(niciraApiVersion, apiVersion);
+        if (niciraApiVersion == null) {
+            return false;
+        }
+        int compare = CloudStackVersion.compare(niciraApiVersion, apiVersion);
         return (compare < 0);
     }
 
diff --git a/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java b/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java
index 035f69e8938..8bd2b6f9bf2 100644
--- a/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java
+++ b/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java
@@ -39,16 +39,39 @@
  */
 public final class CloudStackVersion implements Comparable<CloudStackVersion> {
 
-    private final static Pattern VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+");
+    private final static Pattern NUMBER_VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+");
+    private final static Pattern FULL_VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+(-[a-zA-Z]+)?(-\\d+)?(-SNAPSHOT)?");
+
+    private final int majorRelease;
+    private final int minorRelease;
+    private final int patchRelease;
+    private final Integer securityRelease;
+
+    private CloudStackVersion(final int majorRelease, final int minorRelease, final int patchRelease, final Integer securityRelease) {
+
+        super();
+
+        checkArgument(majorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a majorRelease greater than 0.");
+        checkArgument(minorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a minorRelease greater than 0.");
+        checkArgument(patchRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a patchRelease greater than 0.");
+        checkArgument((securityRelease != null && securityRelease >= 0) || (securityRelease == null),
+                CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a null securityRelease or a non-null value greater than 0.");
+
+        this.majorRelease = majorRelease;
+        this.minorRelease = minorRelease;
+        this.patchRelease = patchRelease;
+        this.securityRelease = securityRelease;
+
+    }
 
     /**
      *
      * Parses a <code>String</code> representation of a version that conforms one of the following
      * formats into a <code>CloudStackVersion</code> instance:
      * <ul>
-     *     <li><code><major version>.<minor version>.<patch release></code></li>
-     *     <li><code><major version>.<minor version>.<patch release>.<security release></code></li>
-     *     <li><code><major version>.<minor version>.<patch release>.<security release>-<any string></code></li>
+     *     <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;</code></li>
+     *     <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;</code></li>
+     *     <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;-&lt;any string&gt;</code></li>
      * </ul>
      *
      * If the string contains a suffix that begins with a "-" character, then the "-" and all characters following it
@@ -67,7 +90,7 @@ public static CloudStackVersion parse(final String value) {
         final String trimmedValue = substringBefore(value, "-");
 
         checkArgument(isNotBlank(trimmedValue), CloudStackVersion.class.getName() + ".parse(String) requires a non-blank value");
-        checkArgument(VERSION_FORMAT.matcher(trimmedValue).matches(), CloudStackVersion.class.getName() + "parse(String) passed " +
+        checkArgument(NUMBER_VERSION_FORMAT.matcher(trimmedValue).matches(), CloudStackVersion.class.getName() + ".parse(String) passed " +
                 value + ", but requires a value in the format of int.int.int(.int)(-<legacy patch>)");
 
         final String[] components = trimmedValue.split("\\.");
@@ -84,39 +107,20 @@ public static CloudStackVersion parse(final String value) {
 
     }
 
-    private final int majorRelease;
-    private final int minorRelease;
-    private final int patchRelease;
-    private final Integer securityRelease;
-
-    private CloudStackVersion(final int majorRelease, final int minorRelease, final int patchRelease, final Integer securityRelease) {
-
-        super();
-
-        checkArgument(majorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a majorRelease greater than 0.");
-        checkArgument(minorRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a minorRelease greater than 0.");
-        checkArgument(patchRelease >= 0, CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a patchRelease greater than 0.");
-        checkArgument((securityRelease != null && securityRelease >= 0) || (securityRelease == null),
-                CloudStackVersion.class.getName() + "(int, int, int, Integer) requires a null securityRelease or a non-null value greater than 0.");
-
-        this.majorRelease = majorRelease;
-        this.minorRelease = minorRelease;
-        this.patchRelease = patchRelease;
-        this.securityRelease = securityRelease;
-
-    }
-
-    private static ImmutableList<Integer> normalizeVersionValues(final ImmutableList<Integer> values) {
-
-        checkArgument(values != null);
-        checkArgument(values.size() == 3 || values.size() == 4);
-
-        if (values.size() == 3) {
-            return ImmutableList.<Integer>builder().addAll(values).add(0).build();
-        }
-
-        return values;
-
+    /**
+     * Shortcut method to {@link #parse(String)} and {@link #compareTo(CloudStackVersion)} two versions
+     *
+     * @param version1 the first value to be parsed and compared
+     * @param version2 the second value to be parsed and compared
+     *
+     * @return A value less than zero (0) indicates <code>version1</code> is less than <code>version2</code>.  A value
+     *         equal to zero (0) indicates <code>version1</code> equals <code>version2</code>.  A value greater than zero (0)
+     *         indicates <code>version1</code> is greater than <code>version2</code>.
+     *
+     * @since 4.12.0.0
+     */
+    public static int compare(String version1, String version2) {
+        return parse(version1).compareTo(parse(version2));
     }
 
     /**
@@ -125,7 +129,7 @@ private CloudStackVersion(final int majorRelease, final int minorRelease, final
      * A couple of notes about the comparison rules for this method:
      * <ul>
      *     <li>Three position versions are normalized to four position versions with the security release being
-     *         defaulted to zero (0).  For example, for the purposes of comparision, <code>4.8.1</code> would be
+     *         defaulted to zero (0).  For example, for the purposes of comparison, <code>4.8.1</code> would be
      *         normalized to <code>4.8.1.0</code> for all comparison operations.</li>
      *     <li>A three position version with a null security release is considered equal to a four position
      *         version number where the major release, minor release, and patch release are the same and the security
@@ -166,6 +170,43 @@ public int compareTo(final CloudStackVersion thatVersion) {
 
     }
 
+    /**
+     * Trim full version from router version. Valid versions are:
+     *
+     * <ul>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]]</li>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]]-&lt;branding&gt;</li>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]][-&lt;branding&gt;]-SNAPSHOT</li>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]][-&lt;branding&gt;]-&lt;epoch timestamp&gt;</li>
+     * </ul>
+     *
+     * @param version to trim
+     *
+     * @return actual trimmed version
+     */
+    public static String trimRouterVersion(String version) {
+        final String[] tokens = version.split(" ");
+
+        if (tokens.length >= 3 && FULL_VERSION_FORMAT.matcher(tokens[2]).matches()) {
+            return tokens[2];
+        }
+
+        return "0";
+    }
+
+    private static ImmutableList<Integer> normalizeVersionValues(final ImmutableList<Integer> values) {
+
+        checkArgument(values != null);
+        checkArgument(values.size() == 3 || values.size() == 4);
+
+        if (values.size() == 3) {
+            return ImmutableList.<Integer>builder().addAll(values).add(0).build();
+        }
+
+        return values;
+
+    }
+
     /**
      *
      * @return The components of this version as an {@link ImmutableList} in order of major release, minor release,
@@ -187,6 +228,22 @@ public int compareTo(final CloudStackVersion thatVersion) {
 
     }
 
+    public int getMajorRelease() {
+        return majorRelease;
+    }
+
+    public int getMinorRelease() {
+        return minorRelease;
+    }
+
+    public int getPatchRelease() {
+        return patchRelease;
+    }
+
+    public Integer getSecurityRelease() {
+        return securityRelease;
+    }
+
     @Override
     public boolean equals(final Object thatObject) {
 
@@ -215,21 +272,4 @@ public int hashCode() {
     public String toString() {
         return Joiner.on(".").join(asList());
     }
-
-    public int getMajorRelease() {
-        return majorRelease;
-    }
-
-    public int getMinorRelease() {
-        return minorRelease;
-    }
-
-    public int getPatchRelease() {
-        return patchRelease;
-    }
-
-    public Integer getSecurityRelease() {
-        return securityRelease;
-    }
-
 }
diff --git a/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java b/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java
index ab576bba867..eb7a76a2c0f 100644
--- a/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java
+++ b/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java
@@ -31,7 +31,12 @@
 public final class CloudStackVersionTest {
 
     @Test
-    @DataProvider({ "1.2.3, 1.2.3", "1.2.3.4, 1.2.3.4", "1.2.3-12, 1.2.3", "1.2.3.4-14, 1.2.3.4" })
+    @DataProvider({
+        "1.2.3, 1.2.3",
+        "1.2.3.4, 1.2.3.4",
+        "1.2.3-12, 1.2.3",
+        "1.2.3.4-14, 1.2.3.4"
+    })
     public void testValidParse(final String inputValue, final String expectedVersion) {
         final CloudStackVersion version = CloudStackVersion.parse(inputValue);
         assertNotNull(version);
@@ -39,13 +44,26 @@ public void testValidParse(final String inputValue, final String expectedVersion
     }
 
     @Test(expected = IllegalArgumentException.class)
-    @DataProvider({ "1.2", "1", "1.2.3.4.5", "aaaa", "", "  ", "1.2.3.4.5"})
+    @DataProvider({
+        "1.2",
+        "1",
+        "1.2.3.4.5",
+        "aaaa",
+        "",
+        "  ",
+        "1.2.3.4.5"
+    })
     public void testInvalidParse(final String invalidValue) {
         CloudStackVersion.parse(invalidValue);
     }
 
     @Test
-    @DataProvider({ "1.0.0", "1.0.0.0", "1.2.3", "1.2.3.4" })
+    @DataProvider({
+        "1.0.0",
+        "1.0.0.0",
+        "1.2.3",
+        "1.2.3.4"
+    })
     public void testEquals(final String value) {
 
         final CloudStackVersion version = CloudStackVersion.parse(value);
@@ -62,16 +80,19 @@ public void testEquals(final String value) {
 
     @Test
     @DataProvider({
-            "1.0.0.0, 1.0.0.0",
-            "1.0.0, 1.0.0",
-            "1.0.0.0, 1.0.0",
-            "1.0.0-10, 1.0.0-10",
-            "1.0.0-10, 1.0.0",
-            "1.0.0.0, 1.0.0-10",
-            "1.0.0.0, 1.0.0.0-10",
-            "1.0.0-10, 1.0.0-11",
-            "1.0.0-10, 1.0.0.0-14",
-            "1.0.0.0-14, 1.0.0.0-15"
+        "1.0.0.0, 1.0.0.0",
+        "1.0.0, 1.0.0",
+        "1.0.0.0, 1.0.0",
+        "1.0.0-10, 1.0.0-10",
+        "1.0.0-10, 1.0.0",
+        "1.0.0.0, 1.0.0-10",
+        "1.0.0.0, 1.0.0.0-10",
+        "1.0.0-10, 1.0.0-11",
+        "1.0.0-10, 1.0.0.0-14",
+        "1.0.0.0-14, 1.0.0.0-15",
+        "1.0.0.0-SNAPSHOT, 1.0.0.0-SNAPSHOT",
+        "1.0.0.0-branding, 1.0.0.0-branding",
+        "1.0.0.0-1518453362, 1.0.0.0-1519453362"
     })
     public void testEqualCompareTo(final String value, final String thatValue) {
 
@@ -88,21 +109,44 @@ public void testEqualCompareTo(final String value, final String thatValue) {
 
     @Test
     @DataProvider({
-            "1.2.3.4, 1.2.3",
-            "1.2.3, 1.0.0.0",
-            "1.2.3.4, 1.0.0",
-            "2.0.0, 1.2.3",
-            "2.0.0, 1.2.3.4",
-            "2.0.0.0, 1.2.3",
-            "2.0.0.0, 1.2.3.4",
-            "2.0.0.0, 1.2.3",
-            "1.3.0, 1.2.3.4",
-            "1.3.0.0, 1.2.3.4",
-            "1.3.0.0, 1.2.3",
-            "1.2.3.4-10, 1.0.0.0-5",
-            "1.2.3-10, 1.0.0-5",
-            "1.2.3.4, 1.0.0.0-5",
-            "1.2.3.4-10, 1.0.0"
+        "1.0.0.0, 1.0.0.0",
+        "1.0.0, 1.0.0",
+        "1.0.0.0, 1.0.0",
+        "1.0.0-10, 1.0.0-10",
+        "1.0.0-10, 1.0.0",
+        "1.0.0.0, 1.0.0-10",
+        "1.0.0.0, 1.0.0.0-10",
+        "1.0.0-10, 1.0.0-11",
+        "1.0.0-10, 1.0.0.0-14",
+        "1.0.0.0-14, 1.0.0.0-15",
+        "1.0.0.0-SNAPSHOT, 1.0.0.0-SNAPSHOT",
+        "1.0.0.0-branding, 1.0.0.0-branding",
+        "1.0.0.0-1518453362, 1.0.0.0-1519453362"
+    })
+    public void testEqualCompareDirect(final String value, final String thatValue) {
+
+        assertEquals(0, CloudStackVersion.compare(value, thatValue));
+        assertEquals(0, CloudStackVersion.compare(thatValue, value));
+
+    }
+
+    @Test
+    @DataProvider({
+        "1.2.3.4, 1.2.3",
+        "1.2.3, 1.0.0.0",
+        "1.2.3.4, 1.0.0",
+        "2.0.0, 1.2.3",
+        "2.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "2.0.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "1.3.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3",
+        "1.2.3.4-10, 1.0.0.0-5",
+        "1.2.3-10, 1.0.0-5",
+        "1.2.3.4, 1.0.0.0-5",
+        "1.2.3.4-10, 1.0.0"
     })
     public void testGreaterThanAndLessThanCompareTo(final String value, final String thatValue) {
 
@@ -117,4 +161,47 @@ public void testGreaterThanAndLessThanCompareTo(final String value, final String
 
     }
 
+    @Test
+    @DataProvider({
+        "1.2.3.4, 1.2.3",
+        "1.2.3, 1.0.0.0",
+        "1.2.3.4, 1.0.0",
+        "2.0.0, 1.2.3",
+        "2.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "2.0.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "1.3.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3",
+        "1.2.3.4-10, 1.0.0.0-5",
+        "1.2.3-10, 1.0.0-5",
+        "1.2.3.4, 1.0.0.0-5",
+        "1.2.3.4-10, 1.0.0"
+    })
+    public void testGreaterThanAndLessThanCompareDirect(final String value, final String thatValue) {
+
+        assertEquals(1, CloudStackVersion.compare(value, thatValue));
+        assertEquals(-1, CloudStackVersion.compare(thatValue, value));
+
+    }
+
+    @Test
+    @DataProvider({
+        "Cloudstack Release 1.2.3 Mon Jan  1 10:10:10 UTC 2018, 1.2.3",
+        "Cloudstack Release 1.2.3.4 Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4",
+        "Cloudstack Release 1.2.3-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 1.2.3-SNAPSHOT",
+        "Cloudstack Release 1.2.3.4-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-SNAPSHOT",
+        "Cloudstack Release 1.2.3.4-1519453362 Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-1519453362",
+        "Cloudstack Release 1.2.3.4-brnading-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-brnading-SNAPSHOT",
+        "Cloudstack Release 1.2.3.4-brnading-1519453362 Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-brnading-1519453362",
+        "Cloudstack Release 1.2 Mon Jan  1 10:10:10 UTC 2018, 0",
+        "Cloudstack Release 1.2-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 0",
+        "Cloud stack Release 1.2.3.4 Mon Jan  1 10:10:10 UTC 2018, 0"
+    })
+    public void testTrimRouterVersion(final String value, final String expected) {
+
+        assertEquals(expected, CloudStackVersion.trimRouterVersion(value));
+
+    }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services