[AETHER-544][AETHER-523] Improve versioning of `tost` docker image and simplify build workflow

VERSION file is used for the release/tag process of `tost`.

Makefile.vars file defines the stable versions of each component
to be used during the build process.

Dockerfile.tost defines a docker label for each component
and uses the *_VERSION vars to set the docker labels.

Moves build logic inside app-build.sh. Build process is stopped if there are pending
changes in the repositories

Adds check-scripts target for shellcheck verify

Add fetch targets to update the repos

Deprecates the use of git-review for git fetch ref/changes/

Updates README to explain the new build process

Change-Id: I9a3f4b1b67064cd55c755330deaf6efef19ced22
diff --git a/Dockerfile.tost b/Dockerfile.tost
index c4ecc44..5345b6e 100644
--- a/Dockerfile.tost
+++ b/Dockerfile.tost
@@ -63,7 +63,13 @@
 ARG org_label_schema_vcs_url=unknown
 ARG org_label_schema_vcs_ref=unknown
 ARG org_label_schema_build_date=unknown
-ARG org_onosproject_vcs_commit_date=unknown
+ARG org_onosproject_onos_version=unknown
+ARG org_onosproject_trellis_control_version=unknown
+ARG org_onosproject_trellis_t3_version=unknown
+ARG org_opencord_fabric_tofino_version=unknown
+ARG org_omecproject_up4_version=unknown
+ARG org_opencord_kafka_onos_version=unknown
+ARG org_stratumproject_fabric_tna_version=unknown
 
 LABEL org.label-schema.schema-version=1.0 \
       org.label-schema.name=tost \
@@ -71,4 +77,10 @@
       org.label-schema.vcs-url=$org_label_schema_vcs_url \
       org.label-schema.vcs-ref=$org_label_schema_vcs_ref \
       org.label-schema.build-date=$org_label_schema_build_date \
-      org.onosproject.vcs-commit-date=$org_onosproject_vcs_commit_date
+      org.onosproject.onos.version=$org_onosproject_onos_version \
+      org.onosproject.trellis-control.version=$org_onosproject_trellis_control_version \
+      org.onosproject.trellis-t3.version=$org_onosproject_trellis_t3_version \
+      org.opencord.fabric-tofino.version=$org_opencord_fabric_tofino_version \
+      org.omecproject.up4.version=$org_omecproject_up4_version \
+      org.opencord.kafka-onos.version=$org_opencord_kafka_onos_version \
+      org.stratumproject.fabric-tna.version=$org_stratumproject_fabric_tna_version
diff --git a/Makefile b/Makefile
index 7b22c13..b08f826 100644
--- a/Makefile
+++ b/Makefile
@@ -15,30 +15,22 @@
 #
 
 # set default shell
-SHELL                    := /bin/bash -e -o pipefail
+SHELL                        := /bin/bash -e -o pipefail
 
-# Variables
-VERSION                  ?= $(shell cat ./VERSION)
-CURRENT_UID              := $(shell id -u)
-CURRENT_GID              := $(shell id -g)
-MKFILE_PATH              := $(abspath $(lastword $(MAKEFILE_LIST)))
-CURRENT_DIR              := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
-LOCAL_APPS               := local-apps
-# Do not attach stdin if running in an environment without it (e.g., Jenkins)
-IT                       := $(shell test -t 0 && echo "-it" || echo "-t")
+# General variables
+VERSION                      ?= $(shell cat ./VERSION)
+THIS_MAKE                    := $(lastword $(MAKEFILE_LIST))
 
 # Docker related
-DOCKER_REGISTRY          ?=
-DOCKER_REPOSITORY        ?=
-DOCKER_BUILD_ARGS        ?=
-DOCKER_TAG               ?= ${VERSION}
-DOCKER_MVN_TAG           := 3.6.3-openjdk-11-slim
-DOCKER_MVN_IMAGE         := maven:${DOCKER_MVN_TAG}
+DOCKER_REGISTRY              ?=
+DOCKER_REPOSITORY            ?=
+DOCKER_BUILD_ARGS            ?=
+DOCKER_TAG                   ?= ${VERSION}
 
 # Docker labels. Only set ref and commit date if committed
-DOCKER_LABEL_VCS_URL     ?= $(shell git remote get-url $(shell git remote))
-DOCKER_LABEL_BUILD_DATE  ?= $(shell date -u "+%Y-%m-%dT%H:%M:%SZ")
-DOCKER_LABEL_COMMIT_DATE  = $(shell git show -s --format=%cd --date=iso-strict HEAD)
+DOCKER_LABEL_VCS_URL         ?= $(shell git remote get-url $(shell git remote))
+DOCKER_LABEL_BUILD_DATE      ?= $(shell date -u "+%Y-%m-%dT%H:%M:%SZ")
+DOCKER_LABEL_COMMIT_DATE      = $(shell git show -s --format=%cd --date=iso-strict HEAD)
 
 ifeq ($(shell git ls-files --others --modified --exclude-standard 2>/dev/null | wc -l | sed -e 's/ //g'),0)
   DOCKER_LABEL_VCS_REF = $(shell git rev-parse HEAD)
@@ -46,86 +38,58 @@
   DOCKER_LABEL_VCS_REF = $(shell git rev-parse HEAD)+dirty
 endif
 
+# Includes the default ("working") versions of each component
+include ./Makefile.vars
+
+# Shellcheck related
+SHELLCHECK_TAG=v0.7.1
+SHELLCHECK_IMAGE=koalaman/shellcheck:${SHELLCHECK_TAG}
+
 # ONOS related
 ONOS_IMAGENAME               := tost-onos
-ONOS_BRANCH                  ?=
-ONOS_REVIEW                  ?=
 export ONOS_ROOT             := $(shell pwd)/onos
+ONOS_REPO                    := https://gerrit.onosproject.org/onos
 ONOS_PROFILE                 := "tost"
 KARAF_VERSION                := 4.2.9
 
 # TOST related
 TOST_IMAGENAME               := ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}tost:${DOCKER_TAG}
+export LOCAL_APPS            := local-apps
 
 # Trellis-Control related
-TRELLIS_CONTROL_BRANCH       ?=
-TRELLIS_CONTROL_REVIEW       ?=
-TRELLIS_CONTROL_MVN          ?=
-TRELLIS_CONTROL_ROOT         := $(shell pwd)/trellis-control
-TRELLIS_CONTROL_GROUPID      := org.onosproject
-TRELLIS_CONTROL_ARTIFACTID   := segmentrouting-oar
-TRELLIS_CONTROL_ARTIFACT     := ${TRELLIS_CONTROL_GROUPID}:${TRELLIS_CONTROL_ARTIFACTID}
-TRELLIS_CONTROL_VERSION      := 3.0.0-SNAPSHOT
+export TRELLIS_CONTROL_ROOT  := $(shell pwd)/trellis-control
+export TRELLIS_CONTROL_REPO  := https://gerrit.onosproject.org/trellis-control
 
 # Trellis-T3 related
-TRELLIS_T3_BRANCH            ?=
-TRELLIS_T3_REVIEW            ?=
-TRELLIS_T3_MVN               ?=
-TRELLIS_T3_ROOT              := $(shell pwd)/trellis-t3
-TRELLIS_T3_GROUPID           := org.onosproject
-TRELLIS_T3_ARTIFACTID        := t3-app
-TRELLIS_T3_ARTIFACT          := ${TRELLIS_T3_GROUPID}:${TRELLIS_T3_ARTIFACTID}
-TRELLIS_T3_VERSION           := 3.0.0-SNAPSHOT
+export TRELLIS_T3_ROOT       := $(shell pwd)/trellis-t3
+export TRELLIS_T3_REPO       := https://gerrit.onosproject.org/trellis-t3
 
 # Fabric-Tofino related
-FABRIC_TOFINO_BRANCH         ?=
-FABRIC_TOFINO_REVIEW         ?=
-FABRIC_TOFINO_MVN            ?=
-FABRIC_TOFINO_ROOT           := $(shell pwd)/fabric-tofino
-FABRIC_TOFINO_GROUPID        := org.opencord
-FABRIC_TOFINO_ARTIFACTID     := fabric-tofino
-FABRIC_TOFINO_ARTIFACT       := ${FABRIC_TOFINO_GROUPID}:${FABRIC_TOFINO_ARTIFACTID}
-FABRIC_TOFINO_VERSION        := 1.1.1-SNAPSHOT
-FABRIC_TOFINO_TARGETS        := fabric-spgw
-FABRIC_TOFINO_SDE_DOCKER_IMG := opennetworking/bf-sde:9.0.0-p4c
-FABRIC_TOFINO_P4CFLAGS       := "-DS1U_SGW_PREFIX='(8w192++8w0++8w0++8w0)' -DS1U_SGW_PREFIX_LEN=8"
+export FABRIC_TOFINO_ROOT    := $(shell pwd)/fabric-tofino
+export FABRIC_TOFINO_REPO    := https://gerrit.opencord.org/fabric-tofino
 
 # Up4 related
-UP4_BRANCH                   ?=
 OMECPROJECT_API              ?=
-UP4_ROOT                     := $(shell pwd)/up4
-UP4_ARTIFACTID               := up4-app
-UP4_VERSION                  := 1.0.0-SNAPSHOT
-UP4_TARGETS                  := _prepare_app_build
+export UP4_ROOT              := $(shell pwd)/up4
+
 ifeq ($(OMECPROJECT_API),)
-  UP4_REPO = https://github.com/omec-project/up4.git
+  export UP4_REPO = https://github.com/omec-project/up4.git
 else
-  UP4_REPO = https://omecproject:${OMECPROJECT_API}@github.com/omec-project/up4.git
+  export UP4_REPO = https://omecproject:${OMECPROJECT_API}@github.com/omec-project/up4.git
 endif
 
 # Kafka-onos related
-KAFKA_ONOS_BRANCH            ?=
-KAKFA_ONOS_REVIEW            ?=
-KAFKA_ONOS_MVN               ?=
-KAFKA_ONOS_ROOT              := $(shell pwd)/kafka-onos
-KAFKA_ONOS_GROUPID           := org.opencord
-KAFKA_ONOS_ARTIFACTID        := kafka
-KAFKA_ONOS_ARTIFACT          := ${KAFKA_ONOS_GROUPID}:${KAFKA_ONOS_ARTIFACTID}
-KAFKA_ONOS_VERSION           := 2.4.0-SNAPSHOT
+export KAFKA_ONOS_ROOT       := $(shell pwd)/kafka-onos
+export KAFKA_ONOS_REPO       := https://gerrit.opencord.org/kafka-onos
 
 # Fabric-TNA related
-FABRIC_TNA_BRANCH            ?=
 ONOS_BUILDER_API             ?=
-FABRIC_TNA_ROOT              := $(shell pwd)/fabric-tna
-FABRIC_TNA_ARTIFACTID        := fabric-tna
-FABRIC_TNA_VERSION           := 1.0.0-SNAPSHOT
-FABRIC_TNA_TARGETS           := fabric fabric-spgw
-FABRIC_TNA_SDE_DOCKER_IMG    := opennetworking/bf-sde:9.2.0-p4c
+export FABRIC_TNA_ROOT       := $(shell pwd)/fabric-tna
 
 ifeq ($(ONOS_BUILDER_API),)
-  FABRIC_TNA_REPO = https://github.com/stratum/fabric-tna.git
+  export FABRIC_TNA_REPO = https://github.com/stratum/fabric-tna.git
 else
-  FABRIC_TNA_REPO = https://onos-builder:${ONOS_BUILDER_API}@github.com/stratum/fabric-tna.git
+  export FABRIC_TNA_REPO = https://onos-builder:${ONOS_BUILDER_API}@github.com/stratum/fabric-tna.git
 endif
 
 .PHONY: onos trellis-control trellis-t3 fabric-tofino up4 kafka-onos fabric-tna
@@ -137,51 +101,27 @@
 	@echo "Usage: make [<target>]"
 	@echo "where available targets are:"
 	@echo
-	@grep '^[[:alnum:]_-]*:.* ##' $(MAKEFILE_LIST) \
+	@grep '^[[:alnum:]_-]*:.* ##' $(THIS_MAKE) \
 	| sort | awk 'BEGIN {FS=":.* ## "}; {printf "%-25s %s\n", $$1, $$2};'
 	@echo
 	@echo "Environment variables:"
-	@echo "ONOS_BRANCH               : Define to use the following branch to build the image"
-	@echo "ONOS_REVIEW               : Define to use the following review to build the image"
-	@echo "TRELLIS_CONTROL_BRANCH    : Define to use the following branch to build the image"
-	@echo "TRELLIS_CONTROL_REVIEW    : Define to use the following review to build the image"
-	@echo "TRELLIS_CONTROL_MVN       : Define to download the app using mvn"
-	@echo "TRELLIS_T3_BRANCH         : Define to use the following branch to build the image"
-	@echo "TRELLIS_T3_REVIEW         : Define to use the following review to build the image"
-	@echo "TRELLIS_T3_MVN            : Define to download the app using mvn"
-	@echo "FABRIC_TOFINO_BRANCH      : Define to use the following branch to build the image"
-	@echo "FABRIC_TOFINO_REVIEW      : Define to use the following review to build the image"
-	@echo "FABRIC_TOFINO_MVN         : Define to download the app using mvn"
-	@echo "UP4_BRANCH                : Define to use the following branch to build the image"
-	@echo "KAFKA_ONOS_BRANCH         : Define to use the following branch to build the image"
-	@echo "KAFKA_ONOS_REVIEW         : Define to use the following review to build the image"
-	@echo "KAFKA_ONOS_MVN            : Define to download the app using mvn"
-	@echo "FABRIC_TNA_BRANCH         : Define to use the following branch to build the image"
+	@echo "ONOS_VERSION              : Override to use a specific branch/commit/tag/release to build the image"
+	@echo "TRELLIS_CONTROL_VERSION   : Override to use a specific branch/commit/tag/release to build the image"
+	@echo "TRELLIS_T3_VERSION        : Override to use a specific branch/commit/tag/release to build the image"
+	@echo "FABRIC_TOFINO_VERSION     : Override to use a specific branch/commit/tag/release to build the image"
+	@echo "UP4_VERSION               : Override to use a specific branch/commit/tag/release to build the image"
+	@echo "KAFKA_ONOS_VERSION        : Override to use a specific branch/commit/tag/release to build the image"
+	@echo "FABRIC_TNA_VERSION        : Override to use a specific branch/commit/tag/release to build the image"
 	@echo ""
-	@echo "'onos' clones onos if it does not exist in the workspace."
-	@echo "Uses current workspace unless above vars are defined."
-	@echo ""
-	@echo "'trellis-control' clones trellis-control if it does not exist in the workspace."
-	@echo "Uses current workspace unless above vars are defined."
-	@echo ""
-	@echo "'trellis-t3' clones trellis-t3 if it does not exist in the workspace."
-	@echo "Uses current workspace unless above vars are defined."
-	@echo ""
-	@echo "'fabric-tofino' clones fabric-tofino if it does not exist in the workspace."
-	@echo "Uses current workspace unless above vars are defined."
-	@echo ""
-	@echo "'up4' clones up4 if it does not exist in the workspace."
-	@echo "Uses current workspace unless above vars are defined."
-	@echo ""
-	@echo "'kafka-onos' clones kafka-onos if it does not exist in the workspace."
-	@echo "Uses current workspace unless above vars are defined."
-	@echo ""
-	@echo "'fabric-tna' clones fabric-tna if it does not exist in the workspace."
-	@echo "Uses current workspace unless above vars are defined."
+	@echo "'Makefile.vars' defines default values for '*_VERSION' variables".
 	@echo ""
 
 ## Make targets
 
+check-scripts: ## : Provides warnings and suggestions for bash/sh shell scripts
+	# Fail if any of these files have warnings, exclude sed replacement warnings
+	docker run --rm -v "${PWD}:/mnt" ${SHELLCHECK_IMAGE} *.sh -e SC2001
+
 mvn_settings.xml: mvn_settings.sh ## : Builds mvn_settings file for proxy
 	@./$<
 
@@ -191,201 +131,169 @@
 trellis-control: ## : Checkout trellis-control code
 	# Clones trellis-control if it does not exist
 	if [ ! -d "trellis-control" ]; then \
-		git clone https://gerrit.onosproject.org/trellis-control; \
+		git clone ${TRELLIS_CONTROL_REPO}; \
 	fi
-# Both are not supported
-ifdef TRELLIS_CONTROL_BRANCH
-ifdef TRELLIS_CONTROL_REVIEW
-	@echo "Too many parameters. You cannot specify branch and review."
-	exit 1
-else
-	cd ${TRELLIS_CONTROL_ROOT} && git checkout ${TRELLIS_CONTROL_BRANCH}
-endif
-else
-ifdef TRELLIS_CONTROL_REVIEW
-	cd ${TRELLIS_CONTROL_ROOT} && git review -d ${TRELLIS_CONTROL_REVIEW}
-endif
-endif
+
+	# Pending changes - do not proceed
+	@modified=$$(cd ${TRELLIS_CONTROL_ROOT} && git status --porcelain); \
+	if [ ! -z "$${modified}" ]; then \
+		echo "Unable to checkout, you have pending changes in trellis-control repository"; \
+		exit 1; \
+	fi
+
+	# Try the git checkout first otherwise git review
+	if ! (cd ${TRELLIS_CONTROL_ROOT} && git checkout ${TRELLIS_CONTROL_VERSION}); then \
+	if ! (cd ${TRELLIS_CONTROL_ROOT} && git fetch ${TRELLIS_CONTROL_REPO} ${TRELLIS_CONTROL_VERSION} && git checkout FETCH_HEAD); then \
+		echo "Unable to fetch the changes from the trellis-control repository"; \
+	fi \
+	fi
 
 trellis-control-build: mvn_settings.xml local-apps trellis-control  ## : Builds trellis-control using local app or mvn
-	# Settings are needed by both build processes - contains proxy settings and extra
-	cp mvn_settings.xml ${TRELLIS_CONTROL_ROOT}/
-ifdef TRELLIS_CONTROL_MVN
-	# Dependencies are needed only by the mvn copy - contains repo settings
-	cp dependencies.xml ${TRELLIS_CONTROL_ROOT}/
-	# Mounting the current dir allows to cache the .m2 folder that is persisted and leveraged by subsequent builds
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/trellis-control ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn dependency:copy -Dartifact=${TRELLIS_CONTROL_ARTIFACT}:${TRELLIS_CONTROL_VERSION}:oar \
-		-DoutputDirectory=oar/target -Dmdep.useBaseVersion=true \
-		-Dmdep.overWriteReleases=true -Dmdep.overWriteSnapshots=true -f dependencies.xml \
-		-s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-else
-	# Having the same mount file allows to reduce build time.
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/trellis-control ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn clean install -s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-endif
-	# Final step requires to move the oar to the folder used by the tost docker file
-	cp ${TRELLIS_CONTROL_ROOT}/oar/target/${TRELLIS_CONTROL_ARTIFACTID}-${TRELLIS_CONTROL_VERSION}.oar ${LOCAL_APPS}/
+	@./app-build.sh $@
+
+trellis-control-fetch: ## : downloads commits, files, and refs from remote trellis-control
+	cd ${TRELLIS_CONTROL_ROOT} && git fetch
 
 trellis-t3: ## : Checkout trellis-t3 code
 	if [ ! -d "trellis-t3" ]; then \
-		git clone https://gerrit.onosproject.org/trellis-t3; \
+		git clone ${TRELLIS_T3_REPO}; \
 	fi
-ifdef TRELLIS_T3_BRANCH
-ifdef TRELLIS_T3_REVIEW
-	@echo "Too many parameters. You cannot specify branch and review."
-	exit 1
-else
-	cd ${TRELLIS_T3_ROOT} && git checkout ${TRELLIS_T3_BRANCH}
-endif
-else
-ifdef TRELLIS_T3_REVIEW
-	cd ${TRELLIS_T3_ROOT} && git review -d ${TRELLIS_T3_REVIEW}
-endif
-endif
+
+	@modified=$$(cd ${TRELLIS_T3_ROOT} && git status --porcelain); \
+	if [ ! -z "$${modified}" ]; then \
+		echo "Unable to checkout, you have pending changes in trellis-t3 repository"; \
+		exit 1; \
+	fi
+
+	if ! (cd ${TRELLIS_T3_ROOT} && git checkout ${TRELLIS_T3_VERSION}); then \
+	if ! (cd ${TRELLIS_T3_ROOT} && git fetch ${TRELLIS_T3_REPO} ${TRELLIS_T3_VERSION} && git checkout FETCH_HEAD); then \
+		echo "Unable to fetch the changes from the trellis-t3 repository"; \
+	fi \
+	fi
 
 trellis-t3-build: mvn_settings.xml local-apps trellis-t3  ## : Builds trellis-t3 using local app or mvn
-	cp mvn_settings.xml ${TRELLIS_T3_ROOT}/
-ifdef TRELLIS_T3_MVN
-	cp dependencies.xml ${TRELLIS_T3_ROOT}/
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/trellis-t3 ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn dependency:copy -Dartifact=${TRELLIS_T3_ARTIFACT}:${TRELLIS_T3_VERSION}:oar \
-		-DoutputDirectory=app/target -Dmdep.useBaseVersion=true \
-		-Dmdep.overWriteReleases=true -Dmdep.overWriteSnapshots=true -f dependencies.xml \
-		-s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-else
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/trellis-t3 ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn clean install -s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-endif
-	cp ${TRELLIS_T3_ROOT}/app/target/${TRELLIS_T3_ARTIFACTID}-${TRELLIS_T3_VERSION}.oar ${LOCAL_APPS}/
+	@./app-build.sh $@
+
+trellis-t3-fetch: ## : downloads commits, files, and refs from remote trellis-t3
+	cd ${TRELLIS_T3_ROOT} && git fetch
 
 fabric-tofino: ## : Checkout fabric-tofino code
 	if [ ! -d "fabric-tofino" ]; then \
-		git clone https://gerrit.opencord.org/fabric-tofino; \
+		git clone ${FABRIC_TOFINO_REPO}; \
 	fi
-ifdef FABRIC_TOFINO_BRANCH
-ifdef FABRIC_TOFINO_REVIEW
-	@echo "Too many parameters. You cannot specify branch and review."
-	exit 1
-else
-	cd ${FABRIC_TOFINO_ROOT} && git checkout ${FABRIC_TOFINO_BRANCH}
-endif
-else
-ifdef FABRIC_TOFINO_REVIEW
-	cd ${FABRIC_TOFINO_ROOT} && git review -d ${FABRIC_TOFINO_REVIEW}
-endif
-endif
+
+	@modified=$$(cd ${FABRIC_TOFINO_ROOT} && git status --porcelain); \
+	if [ ! -z "$${modified}" ]; then \
+		echo "Unable to checkout, you have pending changes in fabric-tofino repository"; \
+		exit 1; \
+	fi
+
+	if ! (cd ${FABRIC_TOFINO_ROOT} && git checkout ${FABRIC_TOFINO_VERSION}); then \
+	if ! (cd ${FABRIC_TOFINO_ROOT} && git fetch ${FABRIC_TOFINO_REPO} ${FABRIC_TOFINO_VERSION} && git checkout FETCH_HEAD); then \
+		echo "Unable to fetch the changes from the fabric-tofino repository"; \
+		exit 1; \
+	fi \
+	fi
 
 fabric-tofino-build: mvn_settings.xml local-apps fabric-tofino  ## : Builds fabric-tofino using local app or mvn
-	cp mvn_settings.xml ${FABRIC_TOFINO_ROOT}/
-ifdef FABRIC_TOFINO_MVN
-	cp dependencies.xml ${FABRIC_TOFINO_ROOT}/
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/fabric-tofino ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn dependency:copy -Dartifact=${FABRIC_TOFINO_ARTIFACT}:${FABRIC_TOFINO_VERSION}:oar \
-		-DoutputDirectory=target -Dmdep.useBaseVersion=true \
-		-Dmdep.overWriteReleases=true -Dmdep.overWriteSnapshots=true -f dependencies.xml \
-		-s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-else
-	# This workaround is temporary - typically we need to build only the pipeconf
-	cd ${FABRIC_TOFINO_ROOT} && make ${FABRIC_TOFINO_TARGETS} SDE_DOCKER_IMG=${FABRIC_TOFINO_SDE_DOCKER_IMG} \
-		P4CFLAGS=${FABRIC_TOFINO_P4CFLAGS}
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/fabric-tofino ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn clean install -s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-endif
-	cp ${FABRIC_TOFINO_ROOT}/target/${FABRIC_TOFINO_ARTIFACTID}-${FABRIC_TOFINO_VERSION}.oar ${LOCAL_APPS}/
+	@./app-build.sh $@
+
+fabric-tofino-fetch: ## : downloads commits, files, and refs from remote fabric-tofino
+	cd ${FABRIC_TOFINO_ROOT} && git fetch
 
 up4: ## : Checkout up4 code
 	if [ ! -d "up4" ]; then \
 		git clone ${UP4_REPO}; \
 	fi
-ifdef UP4_BRANCH
-	cd ${UP4_ROOT} && git checkout ${UP4_BRANCH}
-endif
+
+	@modified=$$(cd ${UP4_ROOT} && git status --porcelain); \
+	if [ ! -z "$${modified}" ]; then \
+		echo "Unable to checkout, you have pending changes in up4 repository"; \
+		exit 1; \
+	fi
+
+	if ! (cd ${UP4_ROOT} && git checkout ${UP4_VERSION}); then \
+	if ! (cd ${UP4_ROOT} && git fetch ${UP4_REPO} ${UP4_VERSION} && git checkout FETCH_HEAD); then \
+		echo "Unable to fetch the changes from the up4 repository"; \
+		exit 1; \
+	fi \
+	fi
 
 up4-build: mvn_settings.xml local-apps up4  ## : Builds up4 using local app
-	cp mvn_settings.xml ${UP4_ROOT}/app
-	# Copy the p4 reources inside the app before the actual build
-	cd ${UP4_ROOT} && make ${UP4_TARGETS}
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/up4/app ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn clean install -s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-	cp ${UP4_ROOT}/app/app/target/${UP4_ARTIFACTID}-${UP4_VERSION}.oar ${LOCAL_APPS}/
+	@./app-build.sh $@
+
+up4-fetch: ## : downloads commits, files, and refs from remote up4
+	cd ${UP4_ROOT} && git fetch
 
 kafka-onos: ## : Checkout kafka-onos code
 	if [ ! -d "kafka-onos" ]; then \
-		git clone https://gerrit.opencord.org/kafka-onos; \
+		git clone ${KAFKA_ONOS_REPO}; \
 	fi
-ifdef KAFKA_ONOS_BRANCH
-ifdef KAFKA_ONOS_REVIEW
-	@echo "Too many parameters. You cannot specify branch and review."
-	exit 1
-else
-	cd ${KAFKA_ONOS_ROOT} && git checkout ${KAFKA_ONOS_BRANCH}
-endif
-else
-ifdef KAFKA_ONOS_REVIEW
-	cd ${KAFKA_ONOS_ROOT} && git review -d ${KAFKA_ONOS_REVIEW}
-endif
-endif
+
+	@modified=$$(cd ${KAFKA_ONOS_ROOT} && git status --porcelain); \
+	if [ ! -z "$${modified}" ]; then \
+		echo "Unable to checkout, you have pending changes in kafka-onos repository"; \
+		exit 1; \
+	fi
+
+	if ! (cd ${KAFKA_ONOS_ROOT} && git checkout ${KAFKA_ONOS_VERSION}); then \
+	if ! (cd ${KAFKA_ONOS_ROOT} && git fetch ${KAFKA_ONOS_REPO} ${KAFKA_ONOS_VERSION} && git checkout FETCH_HEAD); then \
+		echo "Unable to fetch the changes from the kafka-onos repository"; \
+	fi \
+	fi
 
 kafka-onos-build: mvn_settings.xml local-apps kafka-onos  ## : Builds kafka-onos using local app or mvn
-	cp mvn_settings.xml ${KAFKA_ONOS_ROOT}/
-ifdef KAFKA_ONOS_MVN
-	cp dependencies.xml ${KAFKA_ONOS_ROOT}/
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/kafka-onos ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn dependency:copy -Dartifact=${KAFKA_ONOS_ARTIFACT}:${KAFKA_ONOS_VERSION}:oar \
-		-DoutputDirectory=target -Dmdep.useBaseVersion=true \
-		-Dmdep.overWriteReleases=true -Dmdep.overWriteSnapshots=true -f dependencies.xml \
-		-s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-else
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/kafka-onos ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn clean install -s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-endif
-	cp ${KAFKA_ONOS_ROOT}/target/${KAFKA_ONOS_ARTIFACTID}-${KAFKA_ONOS_VERSION}.oar ${LOCAL_APPS}/
+	@./app-build.sh $@
+
+kafka-onos-fetch: ## : downloads commits, files, and refs from remote kafka-onos
+	cd ${KAFKA_ONOS_ROOT} && git fetch
 
 fabric-tna: ## : Checkout fabric-tna code
 	if [ ! -d "fabric-tna" ]; then \
 		git clone ${FABRIC_TNA_REPO}; \
 	fi
-ifdef FABRIC_TNA_BRANCH
-	cd ${FABRIC_TNA_ROOT} && git checkout ${FABRIC_TNA_BRANCH}
-endif
+
+	@modified=$$(cd ${FABRIC_TNA_ROOT} && git status --porcelain); \
+	if [ ! -z "$${modified}" ]; then \
+		echo "Unable to checkout, you have pending changes in fabric-tna repository"; \
+		exit 1; \
+	fi
+
+	if ! (cd ${FABRIC_TNA_ROOT} && git checkout ${FABRIC_TNA_VERSION}); then \
+	if ! (cd ${FABRIC_TNA_ROOT} && git fetch ${FABRIC_TNA_REPO} ${FABRIC_TNA_VERSION} && git checkout FETCH_HEAD); then \
+		echo "Unable to fetch the changes from the fabric-tna repository"; \
+		exit 1; \
+	fi \
+	fi
 
 fabric-tna-build: mvn_settings.xml local-apps fabric-tna  ## : Builds fabric-tna using local app
-	cp mvn_settings.xml ${FABRIC_TNA_ROOT}/
-	# Rebuilds the artifact and the pipeconf
-	cd ${FABRIC_TNA_ROOT} && make ${FABRIC_TNA_TARGETS} SDE_DOCKER_IMG=${FABRIC_TNA_SDE_DOCKER_IMG}
-	docker run ${IT} --rm -v ${CURRENT_DIR}:/root -w /root/fabric-tna ${DOCKER_MVN_IMAGE} \
-		bash -c "mvn clean install -s mvn_settings.xml; \
-		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
-	cp ${FABRIC_TNA_ROOT}/target/${FABRIC_TNA_ARTIFACTID}-${FABRIC_TNA_VERSION}.oar ${LOCAL_APPS}/
+	@./app-build.sh $@
+
+fabric-tna-fetch: ## : downloads commits, files, and refs from remote fabric-tna
+	cd ${FABRIC_TNA_ROOT} && git fetch
+
+apps-fetch: trellis-control-fetch trellis-t3-fetch fabric-tofino-fetch up4-fetch kafka-onos-fetch fabric-tna-fetch ## : downloads commits, files, and refs from remotes
+
+apps-build: trellis-control-build trellis-t3-build fabric-tofino-build up4-build kafka-onos-build fabric-tna-build ## : Build the onos apps
 
 onos: ## : Checkout onos code
 	if [ ! -d "onos" ]; then \
 		git clone https://gerrit.onosproject.org/onos; \
 	fi
-ifdef ONOS_BRANCH
-ifdef ONOS_REVIEW
-	@echo "Too many parameters. You cannot specify branch and review."
-	exit 1
-else
-	cd ${ONOS_ROOT} && git checkout ${ONOS_BRANCH}
-endif
-else
-ifdef ONOS_REVIEW
-	cd ${ONOS_ROOT} && git review -d ${ONOS_REVIEW}
-endif
-endif
 
-apps-build: trellis-control-build trellis-t3-build fabric-tofino-build up4-build kafka-onos-build fabric-tna-build ## : Build the onos apps
+	@modified=$$(cd ${ONOS_ROOT} && git status --porcelain); \
+	if [ ! -z "$${modified}" ]; then \
+		echo "Unable to checkout, you have pending changes in onos repository"; \
+		exit 1; \
+	fi
+
+	# In case of failure, we do not proceed because we cannot build with mvn
+	if ! (cd ${ONOS_ROOT} && git checkout ${ONOS_VERSION}); then \
+	if ! (cd ${ONOS_ROOT} && git fetch ${ONOS_REPO} ${ONOS_VERSION} && git checkout FETCH_HEAD); then \
+		echo "Unable to fetch the changes from the onos repository"; \
+		exit 1; \
+	fi \
+	fi
 
 onos-build: onos ## : Builds the tost-onos docker image
 	# Set some env variables
@@ -403,7 +311,13 @@
     --build-arg org_label_schema_vcs_url="${DOCKER_LABEL_VCS_URL}" \
     --build-arg org_label_schema_vcs_ref="${DOCKER_LABEL_VCS_REF}" \
     --build-arg org_label_schema_build_date="${DOCKER_LABEL_BUILD_DATE}" \
-    --build-arg org_onosproject_vcs_commit_date="${DOCKER_LABEL_COMMIT_DATE}" \
+    --build-arg org_onosproject_onos_version="${ONOS_VERSION}"\
+    --build-arg org_onosproject_trellis_control_version="${TRELLIS_CONTROL_VERSION}"\
+    --build-arg org_onosproject_trellis_t3_version="${TRELLIS_T3_VERSION}"\
+    --build-arg org_opencord_fabric_tofino_version="${FABRIC_TOFINO_VERSION}"\
+    --build-arg org_omecproject_up4_version="${UP4_VERSION}"\
+    --build-arg org_opencord_kafka_onos_version="${KAFKA_ONOS_VERSION}"\
+    --build-arg org_stratumproject_fabric_tna_version="${FABRIC_TNA_VERSION}"\
     -f Dockerfile.tost .
 
 onos-push: ## : Pushes the tost-onos docker image to an external repository
@@ -413,7 +327,7 @@
 	docker push ${TOST_IMAGENAME}
 
 # Used for CI job
-docker-build: onos-build apps-build tost-build ## : Builds the tost image
+docker-build: check-scripts onos-build apps-build tost-build ## : Builds the tost image
 
 # User for CD job
 docker-push: tost-push ## : Pushes the tost image
diff --git a/Makefile.vars b/Makefile.vars
new file mode 100644
index 0000000..eebe099
--- /dev/null
+++ b/Makefile.vars
@@ -0,0 +1,35 @@
+#
+# Copyright 2020-present Open Networking Foundation
+#
+# Licensed 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.
+#
+
+# Released tags, commits hash, branches and reviews / pull requests.
+
+# The APPNAME targets defined in the Makefile will download the repo and will try to checkout
+# the APPNAME_VERSION defined here, using the following methods in order:
+# (1) Checkout local source code (local branch not yet pushed);
+# (2) Fetch from Gerrit/Github (pending review in the form of refs/changes/... or pending pull request);
+#
+# The APPNAME-build targets will try to build with the given version, using the following sources in order:
+# (1) Download from Maven central (for released versions or snapshots);
+# (2) Checkout Local source code (local branch not yet pushed);
+# (3) Fetch from Gerrit/Github (pending review in the form of refs/changes/... or pending pull request);
+
+export ONOS_VERSION            ?= 2.2.4
+export TRELLIS_CONTROL_VERSION ?= 3.0.0-SNAPSHOT
+export TRELLIS_T3_VERSION      ?= 3.0.0-SNAPSHOT
+export FABRIC_TOFINO_VERSION   ?= e1cf4551b4ab74bb82a7cecf19d197698ffbc1cb
+export UP4_VERSION             ?= cac4b02ef342a0588bc3e1fcfb8d29fef1c0dfd8
+export KAFKA_ONOS_VERSION      ?= 2.4.0-SNAPSHOT
+export FABRIC_TNA_VERSION      ?= da091c3445f81fc69a67acf5d1e37be715f5c052
diff --git a/README.md b/README.md
index 32f40df..2d4304a 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,8 @@
 
 We provide multiple build targets for the Makefile
 
-`onos-build` is used to build a specialized **Docker** image of **ONOS** (`tost-onos`) that will contain only the apps needed by **TOST**. It depends on `onos` target, which is used to setup the `onos` workspace for the build. It is possible to build the image by using a specific branch (export `ONOS_BRANCH` variable) or by defining a specific review (export `ONOS_REVIEW` variable). It clones `onos` if it does not exist in the workspace and uses current workspace unless above vars are defined.
+`onos-build` is used to build a specialized **Docker** image of **ONOS** (`tost-onos`) that will contain only the apps needed by **TOST**. It depends on `onos` target, which is used to setup the `onos` workspace for the build. It clones `onos` if it does not exist in the workspace, it will try to checkout the **ONOS_VERSION** first and in case of failure will try to download the patchset from remote repository. **ONOS_VERSION** is defined in `Makefile.vars`, overriding the variable at run time it is possible to build a different version of **ONOS**.
+
 
 ```sh
 # Build a tost-onos image from the current workspace.
@@ -14,18 +15,19 @@
 ```
 
 ```sh
-# Build a tost-onos image from the onos-2.2 branch.
-make ONOS_BRANCH=onos-2.2 onos-build
+# Build a tost-onos image from the tip of the onos-2.2 branch.
+make ONOS_VERSION=onos-2.2 onos-build
 ```
 
 ```sh
 # Build a tost-onos image from the review 12345.
-make ONOS_REVIEW=12345 onos-build
+make ONOS_VERSION=ref/changes/72/12345/1 onos-build
 ```
 
 Makefile will build also the apps. These are the apps currently integrated in the script: **trellis-control**, **trellis-t3**, **fabric-tofino**, **up4**, **kafka-onos** and **fabric-tna**. For each one, there is a **build** target.
 
-`app-name-build` builds the oar from the source code. If **APPNAME_MVN** is specified, the script will download the oar from the maven repositories. As prerequisite, the script prepares `mvn_settings.xml` file, creates the `local-apps` folder and checks out the code if it is not present (relies on `app-name` target). `app-name` allows the developers to specify an **APPNAME_BRANCH** or an **APPNAME_REVIEW**.
+`appname-build` builds with the version specified in the `Makefile.vars`, using the following sources in order: (1) Maven central (for released versions or snapshots); (2) Local source code (for local branch not yet pushed); (3) Gerrit/Github (for pending review in the form of refs/changes/... or pending pull request). As a prerequisite, the script prepares `mvn_settings.xml` file, creates the `local-apps` folder and checks out the code if it is not present (relies on `appname` target). **APPNAME_VERSION**, defined in `Makefile.vars`, can be overridden at runtime.
+
 
 ```sh
 # Build trellis-control from the source code.
@@ -37,10 +39,15 @@
 make up4-build
 ```
 
+```sh
+# Build fabric-tofino app from the tag 1.1.0.
+make FABRIC_TOFINO_VERSION=1.1.0 fabric-tofino-build
+```
+
 `apps-build` is an additional target that automates the build process of the apps building one by one all the apps.
 
 ```sh
-# Build one by one all the apps
+# Build one by one all the apps.
 make apps-build
 ```
 
@@ -51,12 +58,26 @@
 make tost-build
 ```
 
-## Clean
+## Fetch
 
-Use target `clean` to remove the local artificats generated by the tool.
+Use `fetch` targets to downloads commits, files, and refs from remotes.
 
 ```sh
-# Cleans the workspace
+# Update up4 app.
+make up4-fetch
+```
+
+```sh
+# Update one by one all the apps.
+make apps-fetch
+```
+
+## Clean
+
+Use `clean` target to remove the local artificats generated by the tool.
+
+```sh
+# Cleans the workspace.
 make clean
 ```
 
@@ -78,4 +99,4 @@
 
 ## CI/CD targets
 
-There are two special targets used by the CI/CD jobs: `docker-build` and `docker-push`. The first target automates the build process of the `tost` image (`onos-build`, `apps-build` and `tost-build`). While the second one, it is just a `tost-push` called in a different way (temporary). Feel free to use them if you are ok with the prerequisites steps.
+There are two special targets used by the CI/CD jobs: `docker-build` and `docker-push`. The first target automates the build process of the `tost` image (`check-scripts`, `onos-build`, `apps-build` and `tost-build`). While the second one, it is just a `tost-push` called in a different way (temporary). Feel free to use them if you are ok with the prerequisites steps.
diff --git a/app-build.sh b/app-build.sh
new file mode 100755
index 0000000..3a91545
--- /dev/null
+++ b/app-build.sh
@@ -0,0 +1,225 @@
+#!/bin/bash
+
+# Copyright 2020-present Open Networking Foundation
+#
+# Licensed 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.
+
+# Build the apps
+
+# General purposes vars
+CURRENT_UID=$(id -u)
+CURRENT_GID=$(id -g)
+CURRENT_DIR=$(pwd)
+MVN=1
+PROJECT_VERSION=0
+
+# Docker related vars
+DOCKER_MVN_TAG=3.6.3-openjdk-11-slim
+DOCKER_MVN_IMAGE=maven:${DOCKER_MVN_TAG}
+
+# Do not attach stdin if running in an environment without it (e.g., Jenkins)
+IT=$(test -t 0 && echo "-it" || echo "-t")
+
+# Trellis-control related vars
+TRELLIS_CONTROL_GROUPID=org.onosproject
+TRELLIS_CONTROL_ARTIFACTID=segmentrouting-oar
+TRELLIS_CONTROL_ARTIFACT=${TRELLIS_CONTROL_GROUPID}:${TRELLIS_CONTROL_ARTIFACTID}
+TRELLIS_CONTROL_OAR=${TRELLIS_CONTROL_ROOT}/oar/target/${TRELLIS_CONTROL_ARTIFACTID}-${TRELLIS_CONTROL_VERSION}.oar
+
+# Trellis-t3 related vars
+TRELLIS_T3_GROUPID=org.onosproject
+TRELLIS_T3_ARTIFACTID=t3-app
+TRELLIS_T3_ARTIFACT=${TRELLIS_T3_GROUPID}:${TRELLIS_T3_ARTIFACTID}
+TRELLIS_T3_OAR=${TRELLIS_T3_ROOT}/app/target/${TRELLIS_T3_ARTIFACTID}-${TRELLIS_T3_VERSION}.oar
+
+# Fabric-tofino related vars
+FABRIC_TOFINO_GROUPID=org.opencord
+FABRIC_TOFINO_ARTIFACTID=fabric-tofino
+FABRIC_TOFINO_ARTIFACT=${FABRIC_TOFINO_GROUPID}:${FABRIC_TOFINO_ARTIFACTID}
+FABRIC_TOFINO_TARGETS=(fabric-spgw)
+FABRIC_TOFINO_SDE_DOCKER_IMG=opennetworking/bf-sde:9.0.0-p4c
+FABRIC_TOFINO_P4CFLAGS="-DS1U_SGW_PREFIX='(8w192++8w0++8w0++8w0)' -DS1U_SGW_PREFIX_LEN=8"
+FABRIC_TOFINO_OAR=${FABRIC_TOFINO_ROOT}/target/${FABRIC_TOFINO_ARTIFACTID}-${FABRIC_TOFINO_VERSION}.oar
+
+# UP4 related vars
+UP4_GROUPID=org.omecproject
+UP4_ARTIFACTID=up4-app
+UP4_ARTIFACT=${UP4_GROUPID}:${UP4_ARTIFACTID}
+UP4_TARGETS=_prepare_app_build
+UP4_OAR=${UP4_ROOT}/app/app/target/${UP4_ARTIFACTID}-${UP4_VERSION}.oar
+
+# Kafka-onos related vars
+KAFKA_ONOS_GROUPID=org.opencord
+KAFKA_ONOS_ARTIFACTID=kafka
+KAFKA_ONOS_ARTIFACT=${KAFKA_ONOS_GROUPID}:${KAFKA_ONOS_ARTIFACTID}
+KAFKA_ONOS_OAR=${KAFKA_ONOS_ROOT}/target/${KAFKA_ONOS_ARTIFACTID}-${KAFKA_ONOS_VERSION}.oar
+
+# Fabric-tna related vars
+FABRIC_TNA_GROUPID=org.stratumproject
+FABRIC_TNA_ARTIFACTID=fabric-tna
+FABRIC_TNA_ARTIFACT=${FABRIC_TNA_GROUPID}:${FABRIC_TNA_ARTIFACTID}
+FABRIC_TNA_TARGETS=(fabric fabric-spgw)
+FABRIC_TNA_SDE_DOCKER_IMG=opennetworking/bf-sde:9.2.0-p4c
+FABRIC_TNA_OAR=${FABRIC_TNA_ROOT}/target/${FABRIC_TNA_ARTIFACTID}-${FABRIC_TNA_VERSION}.oar
+
+set -eu -o pipefail
+
+function extract_version {
+	# Enter in the project folder
+	cd "$1" || exit 1
+	# Verify if the VERSION file exists
+	if [ -f "VERSION" ]; then
+		NEW_VERSION=$(head -n1 "VERSION")
+		# If this is a golang project, use funky v-prefixed versions
+		if [ -f "Gopkg.toml" ] || [ -f "go.mod" ]; then
+			PROJECT_VERSION=v${NEW_VERSION}
+		else
+			PROJECT_VERSION=${NEW_VERSION}
+		fi
+	# If this is a node.js project
+	elif [ -f "package.json" ]; then
+		NEW_VERSION=$(python -c 'import json,sys;obj=json.load(sys.stdin); print obj["version"]' < package.json)
+		PROJECT_VERSION=${NEW_VERSION}
+	# If this is a mvn project
+	elif [ -f "pom.xml" ]; then
+		NEW_VERSION=$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' pom.xml)
+		PROJECT_VERSION=${NEW_VERSION}
+	else
+		echo "ERROR: No versioning file found!"
+		exit 1
+	fi
+	cd ../
+}
+
+# Generic function to build an app
+function build_app {
+	# First step is to remove the oar dir
+	rm -rf "$1"
+	# Settings are needed by both build processes - contains proxy settings and extra
+	cp mvn_settings.xml "$2"
+	# Dependencies are needed only by the mvn copy - contains repo settings
+	cp dependencies.xml "$2"
+	# Mounting the current dir allows to cache the .m2 folder that is persisted and leveraged by subsequent builds
+	docker run "${IT}" --rm -v "${CURRENT_DIR}":/root -w /root/"$3" "${DOCKER_MVN_IMAGE}" \
+		bash -c "mvn dependency:copy -Dartifact=$4:$5:oar \
+		-DoutputDirectory=$6 -Dmdep.useBaseVersion=true \
+		-Dmdep.overWriteReleases=true -Dmdep.overWriteSnapshots=true -f dependencies.xml \
+		-s mvn_settings.xml; \
+		chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
+	# If the oar is not found - try to build using the source code
+	if [ ! -f "$7" ]; then
+		cd "$2" || exit 1
+		# Verify for the last time if the VERSION is a checkout object or a review
+		if ! (git checkout "$5"); then
+			if ! (git fetch "$8" "$5" && git checkout FETCH_HEAD); then
+				exit 1
+			fi
+		fi
+		cd ../
+		# Having the same mount file allows to reduce build time
+		docker run "${IT}" --rm -v "${CURRENT_DIR}":/root -w /root/"$3" "${DOCKER_MVN_IMAGE}" \
+			bash -c "mvn clean install -s mvn_settings.xml; \
+			chown -R ${CURRENT_UID}:${CURRENT_GID} /root"
+		# We need to override the version variable because it is not valid at this point
+		MVN=0
+	fi
+}
+
+function trellis-control-build {
+	# Build function
+	build_app "${TRELLIS_CONTROL_ROOT}"/oar/target \
+	"${TRELLIS_CONTROL_ROOT}"/ "trellis-control" \
+	"${TRELLIS_CONTROL_ARTIFACT}" "${TRELLIS_CONTROL_VERSION}" \
+	"oar/target" "${TRELLIS_CONTROL_OAR}" "${TRELLIS_CONTROL_REPO}"
+	# If MVN was not successful - built from sources
+	if [ "$MVN" -eq "0" ]; then
+		# Update VERSION
+		extract_version "${TRELLIS_CONTROL_ROOT}"
+		# Update OAR
+		TRELLIS_CONTROL_OAR="${TRELLIS_CONTROL_ROOT}"/oar/target/"${TRELLIS_CONTROL_ARTIFACTID}"-"${PROJECT_VERSION}".oar
+	fi
+	# Final step requires to move the oar to the folder used by the tost docker file. Moreover, it will help catch up errors
+	cp "${TRELLIS_CONTROL_OAR}" "${LOCAL_APPS}"/
+}
+
+function trellis-t3-build {
+	build_app "${TRELLIS_T3_ROOT}"/app/target \
+	"${TRELLIS_T3_ROOT}"/ "trellis-t3" \
+	"${TRELLIS_T3_ARTIFACT}" "${TRELLIS_T3_VERSION}" \
+	"app/target" "${TRELLIS_T3_OAR}" "${TRELLIS_T3_REPO}"
+	if [ "$MVN" -eq "0" ]; then
+		extract_version "${TRELLIS_T3_ROOT}"
+		TRELLIS_T3_OAR="${TRELLIS_T3_ROOT}"/app/target/"${TRELLIS_T3_ARTIFACTID}"-"${PROJECT_VERSION}".oar
+	fi
+	cp "${TRELLIS_T3_OAR}" "${LOCAL_APPS}"/
+}
+
+function fabric-tofino-build {
+	# This workaround is temporary - typically we need to build only the pipeconf
+	cd "${FABRIC_TOFINO_ROOT}" || exit 1 && make "${FABRIC_TOFINO_TARGETS[@]}" SDE_DOCKER_IMG="${FABRIC_TOFINO_SDE_DOCKER_IMG}" P4CFLAGS="${FABRIC_TOFINO_P4CFLAGS}"
+	cd ../
+	build_app "${FABRIC_TOFINO_ROOT}"/target \
+	"${FABRIC_TOFINO_ROOT}"/ "fabric-tofino" \
+	"${FABRIC_TOFINO_ARTIFACT}" "${FABRIC_TOFINO_VERSION}" \
+	"target" "${FABRIC_TOFINO_OAR}" "${FABRIC_TOFINO_REPO}"
+	if [ "$MVN" -eq "0" ]; then
+		extract_version "${FABRIC_TOFINO_ROOT}"
+		FABRIC_TOFINO_OAR="${FABRIC_TOFINO_ROOT}"/target/"${FABRIC_TOFINO_ARTIFACTID}"-"${PROJECT_VERSION}".oar
+	fi
+	cp "${FABRIC_TOFINO_OAR}" "${LOCAL_APPS}"/
+}
+
+function up4-build {
+	# Prepares app folder
+	cd "${UP4_ROOT}" || exit 1 && make "${UP4_TARGETS}"
+	cd ../
+	build_app "${UP4_ROOT}"/app/app/target \
+	"${UP4_ROOT}"/app "up4/app" \
+	"${UP4_ARTIFACT}" "${UP4_VERSION}" \
+	"app/app/target" "${UP4_OAR}" "${UP4_REPO}"
+	if [ "$MVN" -eq "0" ]; then
+		extract_version "${UP4_ROOT}"/app
+		cd ../
+		UP4_OAR="${UP4_ROOT}"/app/app/target/"${UP4_ARTIFACTID}"-"${PROJECT_VERSION}".oar
+	fi
+	cp "${UP4_OAR}" "${LOCAL_APPS}"/
+}
+
+function kafka-onos-build {
+	build_app "${KAFKA_ONOS_ROOT}"/target \
+	"${KAFKA_ONOS_ROOT}"/ "kafka-onos" \
+	"${KAFKA_ONOS_ARTIFACT}" "${KAFKA_ONOS_VERSION}" \
+	"target" "${KAFKA_ONOS_OAR}" "${KAFKA_ONOS_REPO}"
+	if [ "$MVN" -eq "0" ]; then
+		extract_version "${KAFKA_ONOS_ROOT}"
+		KAFKA_ONOS_OAR="${KAFKA_ONOS_ROOT}"/target/"${KAFKA_ONOS_ARTIFACTID}"-"${PROJECT_VERSION}".oar
+	fi
+	cp "${KAFKA_ONOS_OAR}" "${LOCAL_APPS}"/
+}
+
+function fabric-tna-build {
+	# This workaround is temporary - typically we need to build only the pipeconf
+	cd "${FABRIC_TNA_ROOT}" || exit 1 && make "${FABRIC_TNA_TARGETS[@]}" SDE_DOCKER_IMG="${FABRIC_TNA_SDE_DOCKER_IMG}"
+	cd ../
+	build_app "${FABRIC_TNA_ROOT}"/target \
+	"${FABRIC_TNA_ROOT}"/ "fabric-tna" \
+	"${FABRIC_TNA_ARTIFACT}" "${FABRIC_TNA_VERSION}" \
+	"target" "${FABRIC_TNA_OAR}" "${FABRIC_TNA_REPO}"
+	if [ "$MVN" -eq "0" ]; then
+		extract_version "${FABRIC_TNA_ROOT}"
+		FABRIC_TNA_OAR="${FABRIC_TNA_ROOT}"/target/"${FABRIC_TNA_ARTIFACTID}"-"${PROJECT_VERSION}".oar
+	fi
+	cp "${FABRIC_TNA_OAR}" "${LOCAL_APPS}"/
+}
+
+"$1"
diff --git a/app-install.sh b/app-install.sh
old mode 100644
new mode 100755
index 502f545..3eec063
--- a/app-install.sh
+++ b/app-install.sh
@@ -1,4 +1,5 @@
 #!/bin/bash
+
 #
 # Copyright 2020-present Open Networking Foundation
 #
@@ -16,20 +17,20 @@
 #
 
 HERE=$(pwd)
-OARS=$(find $DOWNLOAD_ROOT -name "*.oar")
+OARS=$(find "$DOWNLOAD_ROOT" -name "*.oar")
 for oar in $OARS; do
-    cd $HERE
+    cd "$HERE" || exit 1
     echo "Installing application '$oar'"
-    rm -rf $APP_INSTALL_ROOT
-    mkdir -p $APP_INSTALL_ROOT
-    cd $APP_INSTALL_ROOT
-    cp $oar $APP_INSTALL_ROOT
-    unzip -oq -d . $APP_INSTALL_ROOT/$(basename $oar)
-    name=$(grep "name=" $APP_INSTALL_ROOT/app.xml | sed 's/<app name="//g;s/".*//g')
-    mkdir -p $APPS_ROOT/$name
-    cp $APP_INSTALL_ROOT/app.xml $APPS_ROOT/$name/app.xml
-    [ -f $APP_INSTALL_ROOT/app.png ] && cp $APP_INSTALL_ROOT/app.png $APPS_ROOT/$name/app.png
-    cp $APP_INSTALL_ROOT/$(basename $oar) $APPS_ROOT/$name/$name.oar
-    cp -rf $APP_INSTALL_ROOT/m2/* $KARAF_M2
-    rm -rf $APP_INSTALL_ROOT
+    rm -rf "$APP_INSTALL_ROOT"
+    mkdir -p "$APP_INSTALL_ROOT"
+    cd "$APP_INSTALL_ROOT" || exit 1
+    cp "$oar" "$APP_INSTALL_ROOT"
+    unzip -oq -d . "$APP_INSTALL_ROOT"/"$(basename "$oar")"
+    name=$(grep "name=" "$APP_INSTALL_ROOT"/app.xml | sed 's/<app name="//g;s/".*//g')
+    mkdir -p "$APPS_ROOT"/"$name"
+    cp "$APP_INSTALL_ROOT"/app.xml "$APPS_ROOT"/"$name"/app.xml
+    [ -f "$APP_INSTALL_ROOT"/app.png ] && cp "$APP_INSTALL_ROOT"/app.png "$APPS_ROOT"/"$name"/app.png
+    cp "$APP_INSTALL_ROOT"/"$(basename "$oar")" "$APPS_ROOT"/"$name"/"$name".oar
+    cp -rf "$APP_INSTALL_ROOT"/m2/* "$KARAF_M2"
+    rm -rf "$APP_INSTALL_ROOT"
 done
diff --git a/mvn_settings.sh b/mvn_settings.sh
index 6e95aff..b2e72e0 100755
--- a/mvn_settings.sh
+++ b/mvn_settings.sh
@@ -1,4 +1,5 @@
 #!/bin/bash
+
 #
 # Copyright 2020-present Open Networking Foundation
 #
@@ -14,6 +15,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+
+http_proxy=${http_proxy:-}
+https_proxy=${https_proxy:-}
+no_proxy=${no_proxy:-}
+
 if [ -f mvn_settings.custom.xml ] ; then
   cp mvn_settings.custom.xml mvn_settings.xml
   exit 0