def setup(dn): tempfile.tempdir = app.config['tmp'] dn['sandbox'] = tempfile.mkdtemp() os.environ['TMPDIR'] = app.config['tmp'] app.config['sandboxes'] += [dn['sandbox']] dn['checkout'] = os.path.join(dn['sandbox'], dn['name'] + '.build') dn['install'] = os.path.join(dn['sandbox'], dn['name'] + '.inst') dn['baserockdir'] = os.path.join(dn['install'], 'baserock') dn['tmp'] = os.path.join(dn['sandbox'], 'tmp') for directory in ['checkout', 'install', 'tmp', 'baserockdir']: os.makedirs(dn[directory]) dn['log'] = os.path.join(app.config['artifacts'], dn['cache'] + '.build-log') if app.config.get('instances'): dn['log'] += '.' + str(app.config.get('fork', 0)) assembly_dir = dn['sandbox'] for directory in ['dev', 'tmp']: call(['mkdir', '-p', os.path.join(assembly_dir, directory)]) try: yield except app.RetryException as e: raise e except: import traceback app.log(dn, 'ERROR: surprise exception in sandbox', '') traceback.print_exc() app.log(dn, 'Sandbox debris is at', dn['sandbox'], exit=True) finally: pass app.log(dn, "Removing sandbox dir", dn['sandbox'], verbose=True) app.remove_dir(dn['sandbox'])
def setup(this): currentdir = os.getcwd() tempfile.tempdir = app.config['tmp'] this['sandbox'] = tempfile.mkdtemp() os.environ['TMPDIR'] = app.config['tmp'] app.config['sandboxes'] += [this['sandbox']] this['build'] = os.path.join(this['sandbox'], this['name'] + '.build') this['install'] = os.path.join(this['sandbox'], this['name'] + '.inst') this['baserockdir'] = os.path.join(this['install'], 'baserock') this['tmp'] = os.path.join(this['sandbox'], 'tmp') for directory in ['build', 'install', 'tmp', 'baserockdir']: os.makedirs(this[directory]) this['log'] = os.path.join(app.config['artifacts'], this['cache'] + '.build-log') if app.config.get('instances'): this['log'] += '.' + str(app.config.get('fork', 0)) assembly_dir = this['sandbox'] for directory in ['dev', 'tmp']: call(['mkdir', '-p', os.path.join(assembly_dir, directory)]) try: yield except app.RetryException as e: raise e except: import traceback app.log(this, 'ERROR: a surprise exception happened', '') traceback.print_exc() app.exit(this, 'ERROR: sandbox debris is at', this['sandbox']) finally: pass if app.config.get('log-verbose'): app.log(this, "Removing sandbox dir", this['sandbox']) app.remove_dir(this['sandbox'])
def assemble(defs, target): '''Assemble dependencies and contents recursively until target exists.''' component = defs.get(target) if cache_key(defs, component) is False: return False if get_cache(defs, component): return cache_key(defs, component) if app.config.get('kbas-url'): with claim(defs, component): if get_remote(defs, component): app.config['counter'].increment() return cache_key(defs, component) random.seed(datetime.datetime.now()) if component.get('arch') and component['arch'] != app.config['arch']: return None sandbox.setup(component) systems = component.get('systems', []) random.shuffle(systems) for system in systems: assemble(defs, system['path']) for subsystem in system.get('subsystems', []): assemble(defs, subsystem) dependencies = component.get('build-depends', []) for it in dependencies: preinstall(defs, component, it) contents = component.get('contents', []) random.shuffle(contents) for it in contents: subcomponent = defs.get(it) if subcomponent.get('build-mode', 'staging') != 'bootstrap': preinstall(defs, component, subcomponent) if 'systems' not in component and not get_cache(defs, component): if app.config.get('instances', 1) > 1: with claim(defs, component): # in here, exceptions get eaten do_build(defs, component) else: # in here, exceptions do not get eaten do_build(defs, component) app.remove_dir(component['sandbox']) return cache_key(defs, component)
def __init__(self, defs, component): if app.config['log-verbose'] and \ app.config.get('last-retry-component') != component: app.log(component, 'Already downloading/building, so wait/retry') if app.config.get('last-retry'): wait = datetime.datetime.now() - app.config.get('last-retry') if wait.seconds < 1: with open(lockfile(defs, component), 'r') as l: call(['flock', '--shared', '--timeout', app.config.get('timeout', '60'), str(l.fileno())]) app.config['last-retry'] = datetime.datetime.now() app.config['last-retry-component'] = component for dirname in app.config['sandboxes']: app.remove_dir(dirname) app.config['sandboxes'] = [] pass
def deploy_system(defs, system_spec, parent_location=''): '''Deploy a system and subsystems recursively. Takes a system spec (i.e. an entry in the "systems" list in a cluster definition), and optionally a path to a parent system tree. If `parent_location` is given then the `location` given in the cluster definition for the subsystem is appended to `parent_location`, with the result being used as the location for the deployment extensions. ''' system = defs.get(system_spec['path']) deploy_defaults = system_spec.get('deploy-defaults') sandbox.setup(system) app.log(system, 'Extracting system artifact into', system['sandbox']) with open(cache.get_cache(defs, system), 'r') as artifact: call(['tar', 'x', '--directory', system['sandbox']], stdin=artifact) for subsystem in system_spec.get('subsystems', []): if deploy_defaults: subsystem = dict(deploy_defaults.items() + subsystem.items()) deploy_system(defs, subsystem, parent_location=system['sandbox']) for name, deployment in system_spec.get('deploy', {}).iteritems(): method = deployment.get('type') or deployment.get('upgrade-type') method = os.path.basename(method) if deploy_defaults: deployment = dict(deploy_defaults.items() + deployment.items()) do_deployment_manifest(system, deployment) if parent_location: location = deployment.get('location') or \ deployment.get('upgrade-location') deployment['location'] = os.path.join(parent_location, location.lstrip('/')) try: sandbox.run_extension(system, deployment, 'check', method) except KeyError: app.log(system, "Couldn't find a check extension for", method) for ext in system.get('configuration-extensions', []): sandbox.run_extension(system, deployment, 'configure', os.path.basename(ext)) os.chmod(system['sandbox'], 0o755) sandbox.run_extension(system, deployment, 'write', method) app.remove_dir(system['sandbox'])
def __init__(self, defs, component): if app.config['log-verbose'] and \ app.config.get('last-retry-component') != component: app.log(component, 'Already downloading/building, so wait/retry') if app.config.get('last-retry'): wait = datetime.datetime.now() - app.config.get('last-retry') if wait.seconds < 1: with open(lockfile(defs, component), 'r') as l: call([ 'flock', '--shared', '--timeout', app.config.get('timeout', '60'), str(l.fileno()) ]) app.config['last-retry'] = datetime.datetime.now() app.config['last-retry-component'] = component for dirname in app.config['sandboxes']: app.remove_dir(dirname) app.config['sandboxes'] = [] pass
def clear(deleted, artifact_dir): artifacts = utils.sorted_ls(artifact_dir) for artifact in artifacts: stat = os.statvfs(artifact_dir) free = stat.f_frsize * stat.f_bavail / 1000000000 if free >= app.config.get('min-gigabytes', 10): app.log('SETUP', '%sGB is enough free space' % free) if deleted > 0: app.log('SETUP', 'Culled %s items in' % deleted, artifact_dir) return True path = os.path.join(artifact_dir, artifact) if os.path.exists(os.path.join(path, artifact + '.unpacked')): path = os.path.join(path, artifact + '.unpacked') if os.path.exists(path) and artifact not in app.config['keys']: tmpdir = tempfile.mkdtemp() shutil.move(path, os.path.join(tmpdir, 'to-delete')) app.remove_dir(tmpdir) deleted += 1 return False
def setup(this): currentdir = os.getcwd() tempfile.tempdir = app.config['tmp'] this['sandbox'] = tempfile.mkdtemp() app.config['sandboxes'] += [this['sandbox']] this['build'] = os.path.join(this['sandbox'], this['name'] + '.build') this['install'] = os.path.join(this['sandbox'], this['name'] + '.inst') this['baserockdir'] = os.path.join(this['install'], 'baserock') this['tmp'] = os.path.join(this['sandbox'], 'tmp') for directory in ['build', 'install', 'tmp', 'baserockdir']: os.makedirs(this[directory]) this['log'] = os.path.join(app.config['artifacts'], this['cache'] + '.build-log') if app.config.get('instances'): this['log'] += '.' + str(app.config.get('fork', 0)) assembly_dir = this['sandbox'] for directory in ['dev', 'tmp']: call(['mkdir', '-p', os.path.join(assembly_dir, directory)]) try: yield finally: app.remove_dir(this['sandbox'])