import logging
import os
import subprocess
+import sys
import virtualenv
import venv
import utils
import proto.CommandExecutor_pb2 as CommandExecutor_pb2
+REQUIREMENTS_TXT = "requirements.txt"
+
class CommandExecutorHandler():
self.installed = self.venv_home + '/.installed'
def is_installed(self):
- if os.path.exists(self.installed):
- return True
- else:
- return False
+ return os.path.exists(self.installed)
def prepare_env(self, request, results):
if not self.is_installed():
return True
def execute_command(self, request, results):
- # if not self.activate_venv():
- # return False
+ if not self.activate_venv():
+ return False
+
+ cmd = "cd " + self.venv_home
+
+ if "ansible-playbook" in request.command:
+ cmd = cmd + "; " + request.command + " -e 'ansible_python_interpreter=" + self.venv_home + "/bin/python'"
+ else:
+ cmd = cmd + "; " + request.command
+
+ self.logger.info("Command: {}".format(cmd))
try:
- results.append(os.popen(request.command).read())
+ with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ shell=True, bufsize=1, universal_newlines=True) as newProcess:
+ while True:
+ output = newProcess.stdout.readline()
+ if output == '' and newProcess.poll() is not None:
+ break
+ if output:
+ self.logger.info(output.strip())
+ results.append(output.strip())
+ rc = newProcess.poll()
except Exception as e:
self.logger.info("{} - Failed to execute command. Error: {}".format(self.blueprint_id, e))
results.append(e)
for package in request.packages:
if package.type == type:
f.write("Installed %s packages:\r\n" % CommandExecutor_pb2.PackageType.Name(type))
- for python_package in package.package:
- f.write(" %s\r\n" % python_package)
+ for p in package.package:
+ f.write(" %s\r\n" % p)
if package.type == CommandExecutor_pb2.pip:
- success = self.install_python_packages(python_package, results)
+ success = self.install_python_packages(p, results)
else:
- success = self.install_ansible_packages(python_package, results)
+ success = self.install_ansible_packages(p, results)
if not success:
f.close()
os.remove(self.installed)
def install_python_packages(self, package, results):
self.logger.info(
"{} - Install Python package({}) in Python Virtual Environment".format(self.blueprint_id, package))
- command = ["pip", "install", package]
+
+ if REQUIREMENTS_TXT == package:
+ command = ["pip", "install", "-r", self.venv_home + "/Environments/" + REQUIREMENTS_TXT]
+ else:
+ command = ["pip", "install", package]
env = dict(os.environ)
if "https_proxy" in os.environ:
def activate_venv(self):
self.logger.info("{} - Activate Python Virtual Environment".format(self.blueprint_id))
+ # Fix: The python generated activate_this.py script concatenates the env bin dir to PATH on every call
+ # eventually this process PATH variable was so big (128Kb) that no child process could be spawn
+ # This script will remove all duplicates; while keeping the order of the PATH folders
+ fixpathenvvar = "os.environ['PATH']=os.pathsep.join(list(dict.fromkeys(os.environ['PATH'].split(':'))))"
+
path = "%s/bin/activate_this.py" % self.venv_home
try:
exec (open(path).read(), {'__file__': path})
+ exec (fixpathenvvar)
+ self.logger.info("Running with PATH : {}".format(os.environ['PATH']))
return True
except Exception as err:
self.logger.info(