def include(filename, hosts=False, when=True): ''' Executes a local python file within the ``pyinfra.pseudo_state.deploy_dir`` directory. Args: hosts (string, list): group name or list of hosts to limit this include to when (bool): indicate whether to trigger operations in this include ''' if not pyinfra.is_cli: raise PyinfraError('local.include is only available in CLI mode.') if not when: return if hosts is not False: hosts = ensure_host_list(hosts, inventory=pseudo_state.inventory) if pseudo_host not in hosts: return if pseudo_state.deploy_dir: filename = path.join(pseudo_state.deploy_dir, filename) frameinfo = get_caller_frameinfo() logger.debug('Including local file: {0}'.format(filename)) try: # Fixes a circular import because `pyinfra.local` is really a CLI # only thing (so should be `pyinfra_cli.local`). It is kept here # to maintain backwards compatability and the nicer public import # (ideally users never need to import from `pyinfra_cli`). from pyinfra_cli.config import extract_file_config from pyinfra_cli.util import exec_file # Load any config defined in the file and setup like a @deploy config_data = extract_file_config(filename) kwargs = { key.lower(): value for key, value in six.iteritems(config_data) if key in [ 'SUDO', 'SUDO_USER', 'SU_USER', 'PRESERVE_SUDO_ENV', 'IGNORE_ERRORS', ] } with pseudo_state.deploy( filename, kwargs, None, frameinfo.lineno, in_deploy=False, ): exec_file(filename) # One potential solution to the above is to add local as an actual # module, ie `pyinfra.modules.local`. except IOError as e: raise PyinfraError( 'Could not include local file: {0}\n{1}'.format(filename, e), )
def include(filename): ''' Executes a local python file within the ``pyinfra.pseudo_state.deploy_dir`` directory. ''' if not pyinfra.is_cli: raise PyinfraError('local.include is only available in CLI mode.') if filename.startswith('.'): filename = path.join(path.dirname(pseudo_state.current_exec_filename), filename) elif pseudo_state.deploy_dir: filename = path.join(pseudo_state.deploy_dir, filename) logger.debug('Including local file: {0}'.format(filename)) try: # Fixes a circular import because `pyinfra.local` is really a CLI # only thing (so should be `pyinfra_cli.local`). It is kept here # to maintain backwards compatibility and the nicer public import # (ideally users never need to import from `pyinfra_cli`). from pyinfra_cli.config import extract_file_config from pyinfra_cli.util import exec_file # Load any config defined in the file and setup like a @deploy config_data = extract_file_config(filename) kwargs = { key.lower(): value for key, value in six.iteritems(config_data) if key in [ 'SUDO', 'SUDO_USER', 'SU_USER', 'PRESERVE_SUDO_ENV', 'IGNORE_ERRORS', ] } with pseudo_state.deploy(path.normpath(filename), kwargs, None, in_deploy=False): exec_file(filename) # One potential solution to the above is to add local as an actual # module, ie `pyinfra.operations.local`. except Exception as e: raise PyinfraError( 'Could not include local file: {0}:\n{1}'.format(filename, e), )