Commit 40ff45e2 by Łukasz Nowak

Allow to pass external environment during software build.

WIP. Idea needs some clarificatoin.
1 parent aaf2e015
......@@ -47,7 +47,7 @@ class Software(object):
"""This class is responsible of installing a software release"""
def __init__(self, url, software_root, console, buildout,
signature_private_key_file=None, upload_cache_url=None,
upload_dir_url=None):
upload_dir_url=None, software_environment=None):
"""Initialisation of class parameters
"""
self.url = url
......@@ -60,6 +60,7 @@ class Software(object):
self.signature_private_key_file = signature_private_key_file
self.upload_cache_url = upload_cache_url
self.upload_dir_url = upload_dir_url
self.software_environment = software_environment
def install(self):
""" Fetches buildout configuration from the server, run buildout with
......@@ -98,11 +99,12 @@ class Software(object):
buildout_parameter_list.extend(['-c', self.url])
utils.bootstrapBuildout(self.software_path, self.buildout,
additional_buildout_parametr_list=buildout_parameter_list,
console=self.console)
console=self.console, environment=self.software_environment)
utils.launchBuildout(self.software_path,
os.path.join(self.software_path, 'bin', 'buildout'),
additional_buildout_parametr_list=buildout_parameter_list,
console=self.console)
console=self.console,
environment=self.software_environment)
finally:
shutil.rmtree(extends_cache)
......
......@@ -110,6 +110,8 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple):
parser.add_argument("--promise-timeout",
type=int, default=3,
help="Promise timeout in seconds.")
parser.add_argument("--software-environment-file", type=argparse.FileType(),
help="File containing environment overrides for software runs.")
parser.add_argument("configuration_file", nargs=1, type=argparse.FileType(),
help="SlapOS configuration file.")
......@@ -178,12 +180,20 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple):
# slapgrid scripts without this parameter.
if signature_private_key_file:
mandatory_file_list.append(signature_private_key_file)
for f in mandatory_file_list:
if f is not None:
if not os.path.exists(f):
parser.error('File %r does not exists.' % f)
# process software environment overrides
software_environment = None
software_environment_file = option_dict.get('software_environment_file')
if software_environment_file is not None:
software_env_config = ConfigParser.SafeConfigParser()
software_env_config.optionxform = str
software_env_config.readfp(software_environment_file)
software_environment = dict(software_env_config.items('environment'))
certificate_repository_path = option_dict.get('certificate_repository_path')
if certificate_repository_path is not None:
if not os.path.isdir(certificate_repository_path):
......@@ -216,7 +226,8 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple):
upload_dir_url=option_dict.get('upload-dir-url', None),
console=option_dict['console'],
buildout=option_dict.get('buildout'),
promise_timeout=option_dict['promise_timeout']),
promise_timeout=option_dict['promise_timeout'],
software_environment=software_environment),
option_dict])
......@@ -289,7 +300,8 @@ class Slapgrid(object):
master_ca_file=None,
certificate_repository_path=None,
console=False,
promise_timeout=3):
promise_timeout=3,
software_environment=None):
"""Makes easy initialisation of class parameters"""
# Parses arguments
self.software_root = os.path.abspath(software_root)
......@@ -320,6 +332,7 @@ class Slapgrid(object):
self.console = console
self.buildout = buildout
self.promise_timeout = promise_timeout
self.software_environment = software_environment
def checkEnvironmentAndCreateStructure(self):
"""Checks for software_root and instance_root existence, then creates
......@@ -381,7 +394,8 @@ class Slapgrid(object):
console=self.console, buildout=self.buildout,
signature_private_key_file=self.signature_private_key_file,
upload_cache_url=self.upload_cache_url,
upload_dir_url=self.upload_dir_url).install()
upload_dir_url=self.upload_dir_url,
software_environment=self.software_environment).install()
except (SystemExit, KeyboardInterrupt):
exception = traceback.format_exc()
software_release.error(exception)
......
......@@ -100,7 +100,7 @@ def getSoftwareUrlHash(url):
return md5(url).hexdigest()
def getCleanEnvironment(home_path='/tmp'):
def getCleanEnvironment(home_path='/tmp', replace_environment=None):
logger = logging.getLogger('CleanEnvironment')
changed_env = {}
removed_env = []
......@@ -112,6 +112,10 @@ def getCleanEnvironment(home_path='/tmp'):
if old is not None:
removed_env.append(k)
changed_env['HOME'] = env['HOME'] = home_path
if replace_environment is not None:
for k, v in replace_environment.iteritems():
# Note: os.path.expandvars is used in order to simulate shell expansion
changed_env[k] = env[k] = os.path.expandvars(v)
for k in sorted(changed_env.iterkeys()):
logger.debug('Overriden %s = %r' % (k,changed_env[k]))
logger.debug('Removed from environement: %s' % ', '.join(sorted(removed_env)))
......@@ -218,7 +222,7 @@ def dropPrivileges(uid, gid):
def bootstrapBuildout(path, buildout=None,
additional_buildout_parametr_list=None, console=False):
additional_buildout_parametr_list=None, console=False, environment=None):
if additional_buildout_parametr_list is None:
additional_buildout_parametr_list = []
logger = logging.getLogger('BuildoutManager')
......@@ -259,7 +263,8 @@ def bootstrapBuildout(path, buildout=None,
kw.update(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
process_handler = SlapPopen(invocation_list,
preexec_fn=lambda: dropPrivileges(uid, gid),
cwd=path, env=getCleanEnvironment(pwd.getpwuid(uid).pw_dir),
cwd=path, env=getCleanEnvironment(pwd.getpwuid(uid).pw_dir,
environment),
**kw
)
result = process_handler.communicate()[0]
......@@ -279,7 +284,8 @@ def bootstrapBuildout(path, buildout=None,
def launchBuildout(path, buildout_binary,
additional_buildout_parametr_list=None, console=False):
additional_buildout_parametr_list=None, console=False,
environment=None):
""" Launches buildout."""
logger = logging.getLogger('BuildoutManager')
if additional_buildout_parametr_list is None:
......@@ -310,7 +316,8 @@ def launchBuildout(path, buildout_binary,
kw.update(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
process_handler = SlapPopen(invocation_list,
preexec_fn=lambda: dropPrivileges(uid, gid), cwd=path,
env=getCleanEnvironment(pwd.getpwuid(uid).pw_dir), **kw)
env=getCleanEnvironment(pwd.getpwuid(uid).pw_dir, environment),
**kw)
result = process_handler.communicate()[0]
if console:
result = 'Please consult messages above'
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!