factory: toolkit: explicitly execute python script in install_factory_toolkit.run

BUG=b:138982809
TEST=install_factory_toolkit.run successfully run when /tmp is noexec

Change-Id: I06b73534e28f24802c7e5b2e3e7c10d2e198a99f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1741774
Reviewed-by: Wei-Han Chen <stimim@chromium.org>
Tested-by: Meng-Huan Yu <menghuan@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Commit-Queue: Meng-Huan Yu <menghuan@chromium.org>
diff --git a/py/toolkit/installer.py b/py/toolkit/installer.py
index fd77a99..77c4c33 100755
--- a/py/toolkit/installer.py
+++ b/py/toolkit/installer.py
@@ -350,8 +350,14 @@
     help_header.flush()
     cmd = [os.path.join(src_root, 'makeself.sh'), '--bzip2', '--nox11',
            '--help-header', help_header.name,
-           src_root, output_path, initial_version + modified_msg,
-           INSTALLER_PATH, '--in-exe']
+           src_root, # archive_dir
+           output_path, # file_name
+           initial_version + modified_msg, # label
+           # startup script and args
+           # We have to explicitly execute python instead of directly execute
+           # INSTALLER_PATH because files under INSTALLER_PATH may not be
+           # executable.
+           'env', 'python', INSTALLER_PATH, '--in-exe']
     Spawn(cmd, check_call=True, log=True)
   with file_utils.TempDirectory() as tmp_dir:
     version_path = os.path.join(tmp_dir, VERSION_PATH)