Python3 Migration: make with PY_VERSION to handle Python 2&3 switching

Let make handle Python 2&3 switching with the PY_VERSION flag of which
the default value is set to python2.

BUG=b:169724328
TEST=Conduct the following tests
python3 -m compileall -q .
python2 -m compileall -q .
python3 -m py_compile *.py
python2 -m py_compile *.py
Bluetooth AVL tests

Change-Id: Iefa8f8ab6c9d3d979d55fef29015ba69b88e6e59
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/chameleon/+/2497730
Reviewed-by: Yu-Hsuan Hsu <yuhsuan@chromium.org>
Tested-by: Shyh-In Hwang <josephsih@chromium.org>
Commit-Queue: Shyh-In Hwang <josephsih@chromium.org>
diff --git a/Makefile b/Makefile
index 822138b..cd6dadc 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,10 @@
 IDENTITY_FILE := ~/trunk/src/scripts/mod_for_test_scripts/ssh_keys/testing_rsa
 COMMIT_FILE := $(DISTDIR)/commit
 
+# Set python3 as default after all teams using chameleon finish switching
+# to python3.
+PY_VERSION := python2
+
 TARGETS = check_git_tree_clean directories chameleond
 
 COMMIT = $(shell git log HEAD^..HEAD --pretty=format:"%h")
@@ -63,7 +67,16 @@
 .PHONY: chameleond
 chameleond: binaries
 	@echo $(COMMIT) > $(COMMIT_FILE)
+
+ifeq ($(PY_VERSION), python3)
+	@echo PY_VERSION: $(PY_VERSION)
+	@echo python3 setup.py sdist
+	@python3 setup.py sdist
+else
+	@echo PY_VERSION: $(PY_VERSION)
+	@echo python2 setup.py sdist
 	@python setup.py sdist
+endif
 
 $(BINDIR)/%.o: $(SRCDIR)/%.c
 	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
@@ -95,12 +108,20 @@
 	@cp -f $(BINARIES) "$(DESTDIR)"
 ifeq ($(REMOTE_INSTALL), TRUE)
 	@echo sync time with host...
-	@NOW="$(HOST_NOW)" sh deploy/deploy_pip
+	@NOW="$(HOST_NOW)" PY_VERSION="$(PY_VERSION)" sh deploy/deploy_pip
 else
 	@echo sync time with the chameleon mirror server...
-	@NOW="`chameleond/utils/server_time`" sh deploy/deploy_pip
+	@NOW="`chameleond/utils/server_time`" PY_VERSION="$(PY_VERSION)" \
+		sh deploy/deploy_pip
 endif
+
+ifeq ($(PY_VERSION), python3)
+	@echo python3 setup.py install -f
+	@python3 setup.py install -f
+else
+	@echo python2 setup.py install -f
 	@python setup.py install -f
+endif
 
 ifeq ($(PLATFORM), Chrome OS)
 	@cp -f $(INITDIR)/$(CONFFILES) $(CONFDIR)
@@ -108,7 +129,7 @@
 	@echo Please do \"\$ start chameleond\" or \"\$ restart chameleond\".
 else
 	@BUNDLE_VERSION=$(BUNDLE_VERSION) CHAMELEON_BOARD=$(CHAMELEON_BOARD) \
-	deploy/deploy $(PLATFORM)
+	deploy/deploy $(PLATFORM) $(PY_VERSION)
 	@echo Installing chameleon package on $(PLATFORM) platform is completed.
 endif
 
@@ -140,7 +161,8 @@
 	        "REMOTE_INSTALL=TRUE" \
 	        "HOST_NOW=\"$(HOST_NOW)\"" \
 	        "BUNDLE_VERSION=$(BUNDLE_VERSION) " \
-	        "CHAMELEON_BOARD=$(CHAMELEON_BOARD)"
+	        "CHAMELEON_BOARD=$(CHAMELEON_BOARD)"\
+	        "PY_VERSION=$(PY_VERSION)"
 else
 	$(error CHAMELEON_HOST is undefined)
 endif
diff --git a/deploy/deploy b/deploy/deploy
index 33a9306..61c5bb7 100755
--- a/deploy/deploy
+++ b/deploy/deploy
@@ -27,15 +27,23 @@
 . "${CWD}/bundle_common"
 
 PLATFORM="$1"
+PY_VERSION="$2"
 
 if [ "${PLATFORM}" = "raspberrypi" ] || [ "${PLATFORM}" = "x86-generic" ]; then
     IS_BLUETOOTH_PEER=1
 fi
 
+[ "${PY_VERSION=}" = "python3" ] && pip_cmd=pip3 || pip_cmd=pip
+
 # We do not want lighttpd and chameleon-updater to run on startup.
 update-rc.d -f "${LIGHTTPD_NAME}" remove
 update-rc.d -f "${UPDATER_NAME}" remove
 
+die() {
+  [ -n "$1" ] && echo "ERROR: $1" >&2
+  exit 1
+}
+
 validate_package_installation() {
     PACKAGE_NAME=$1
 
@@ -57,11 +65,11 @@
 validate_python_package_installation() {
     PACKAGE_NAME=$1
 
-    if pip show "${PACKAGE_NAME}" > /dev/null; then
+    if eval "${pip_cmd} show "${PACKAGE_NAME}" > /dev/null"; then
         echo "Python package ${PACKAGE_NAME} already installed"
     else
         echo "Installing python package ${PACKAGE_NAME}..."
-        if pip install "${PACKAGE_NAME}" > /dev/null; then
+        if eval "${pip_cmd} install "${PACKAGE_NAME}" > /dev/null"; then
             echo "Python package ${PACKAGE_NAME} installed"
         else
             echo "Error: fail to install python package ${PACKAGE_NAME}"
@@ -69,6 +77,27 @@
     fi
 }
 
+use_python_version() {
+    target_python_version=$1
+
+    curr_python_version="$(readlink "$(which python)")"
+    if [ "${curr_python_version}" != "python2" ] && \
+         [ "${curr_python_version}" != "python3" ]; then
+        die "Python version should be python2 or python3."
+    fi
+
+    if [ "${curr_python_version}" = "${target_python_version}" ]; then
+        echo "Python version is already ${target_python_version}"
+    else
+        echo "Update Python version from ${curr_python_version}" \
+            "to ${target_python_version}"
+        ln -fs "${target_python_version}" /usr/bin/python || \
+                die update "${target_python_version}"
+        ln -fs "${target_python_version}-config" /usr/bin/python-config || \
+                die update "${target_python_version}-config"
+    fi
+}
+
 validate_socket_installation() {
     INSTALL_LOCATION="/tmp"
     PACKAGE_NAME="btsocket"
@@ -248,6 +277,10 @@
     # Install python packages for Raspberry Pi.
     validate_python_package_installation "pexpect"
     validate_python_package_installation "numpy"
+    validate_python_package_installation "pybluez"
+
+    echo deploy: PY_VERSION "${PY_VERSION}"
+    use_python_version "${PY_VERSION}"
 
     validate_socket_installation
 
diff --git a/deploy/deploy_pip b/deploy/deploy_pip
index 269c274..afb2096 100755
--- a/deploy/deploy_pip
+++ b/deploy/deploy_pip
@@ -7,9 +7,14 @@
 UPDATABLE_DIR="$(realpath $(dirname ${SCRIPT})/../updatable)"
 SRC_PYTHON_DIR="${UPDATABLE_DIR}/python2.7"
 PIP_DIR="${UPDATABLE_DIR}/pip"
-DST_PYTHON_DIR="/usr/lib/python2.7"
 PIP_BOOTSTRAP="get-pip.py"
 
+if [ "${PY_VERSION}" = python3 ]; then
+    DST_PYTHON_DIR="/usr/lib/python3"
+else
+    DST_PYTHON_DIR="/usr/lib/python2.7"
+fi
+
 set_time() {
     echo Current chameleon time: $(date --set="$NOW")
 }