def __init__(self, *, dynamic_linker: str, root_path: str) -> None: """Create a Patcher instance. :param str dynamic_linker: the path to the dynamic linker to set the elf file to. :param str root_path: the base path for the snap to determine if use of $ORIGIN is possible. """ self._dynamic_linker = dynamic_linker self._root_path = root_path # If we are running from the snap we want to use the patchelf # bundled there as it would have the capability of working # anywhere given the fixed ld it would have. # If not found, resort to whatever is on the system brought # in by packaging dependencies. # The docker conditional will work if the docker image has the # snaps unpacked in the corresponding locations. if common.is_snap(): snap_dir = os.getenv('SNAP') self._patchelf_cmd = os.path.join(snap_dir, 'bin', 'patchelf') elif (common.is_docker_instance() and os.path.exists('/snap/snapcraft/current/bin/patchelf')): self._patchelf_cmd = '/snap/snapcraft/current/bin/patchelf' else: self._patchelf_cmd = 'patchelf'
def __init__(self, *, dynamic_linker: str, library_path_func=lambda x: x, base_rpaths: List[str] = None) -> None: """Create a Patcher instance. :param str dynamic_linker: the path to the dynamic linker to set the elf file to. :param library_path_func: function to determine the library path to a given dependency of ElfFile. :param list base_rpaths: library paths for the used base snap. """ self._dynamic_linker = dynamic_linker self._library_path_func = library_path_func if not base_rpaths: base_rpaths = [] self._base_rpaths = base_rpaths # If we are running from the snap we want to use the patchelf # bundled there as it would have the capability of working # anywhere given the fixed ld it would have. # If not found, resort to whatever is on the system brought # in by packaging dependencies. # The docker conditional will work if the docker image has the # snaps unpacked in the corresponding locations. if common.is_snap(): snap_dir = os.getenv('SNAP') self._patchelf_cmd = os.path.join(snap_dir, 'bin', 'patchelf') elif (common.is_docker_instance() and os.path.exists('/snap/snapcraft/current/bin/patchelf')): self._patchelf_cmd = '/snap/snapcraft/current/bin/patchelf' else: self._patchelf_cmd = 'patchelf'
def __init__(self, *, force_provider: str = None) -> None: """Instantiate a BuildEnvironmentConfig. :param str force_provider: ignore the hints from the environment and use the specified provider. """ if force_provider: build_provider = force_provider elif common.is_docker_instance(): build_provider = "host" else: build_provider = os.environ.get("SNAPCRAFT_BUILD_ENVIRONMENT", "multipass") valid_providers = ["host", "multipass", "managed-host", "lxd"] if build_provider not in valid_providers: raise errors.SnapcraftEnvironmentError( "The snapcraft build environment must be one of: {}.".format( humanize_list(items=valid_providers, conjunction="or") ) ) self.provider = build_provider self.is_host = build_provider == "host" self.is_multipass = build_provider == "multipass" self.is_multipass = build_provider == "lxd" self.is_managed_host = build_provider == "managed-host"
def get_tool_path(command_name: str) -> str: """Return the path to the given command Return a path to command_name, if Snapcraft is running out of the snap or out of Docker, it ensures it is using the one in the snap, not the host. If a path cannot be resolved, ToolMissingError is raised. : param str command_name: the name of the command to resolve a path for. :raises ToolMissingError: if command_name cannot be resolved to a path. :return: Path to command :rtype: str """ if common.is_snap(): command_path = _command_path_in_root(os.getenv("SNAP"), command_name) elif common.is_docker_instance(): command_path = _command_path_in_root( os.path.join(os.sep, "snap", "snapcraft", "current"), command_name) else: command_path = shutil.which(command_name) # shutil.which will return None if it cannot find command_name if command_path is None: raise ToolMissingError(command_name=command_name) return command_path
def _should_get_core(confinement: str) -> bool: is_env_var_set = os.environ.get("SNAPCRAFT_SETUP_CORE", False) is not False # This is a quirk so that docker users not using the Dockerfile # we distribute and create can automatically build classic is_docker_instance = common.is_docker_instance() # type: bool is_classic = confinement == "classic" # type: bool return is_classic and (is_env_var_set or is_docker_instance)
def _should_get_core(confinement: str) -> bool: is_env_var_set = os.environ.get("SNAPCRAFT_SETUP_CORE", False) is not False # This is a quirk so that docker users not using the Dockerfile # we distribute and create can automatically build classic is_docker_instance = common.is_docker_instance() # type: bool is_classic = confinement == "classic" # type: bool return is_classic and (is_env_var_set or is_docker_instance)
def __init__(self, project: project.Project) -> None: self.build_snaps = set() # type: Set[str] self.project = project # raw_snapcraft_yaml is read only, create a new copy snapcraft_yaml = apply_extensions(project.info.get_raw_snapcraft()) self.validator = Validator(snapcraft_yaml) self.validator.validate() snapcraft_yaml = self._expand_filesets(snapcraft_yaml) self.data = self._expand_env(snapcraft_yaml) self._ensure_no_duplicate_app_aliases() grammar_processor = grammar_processing.GlobalGrammarProcessor( properties=self.data, project=project) self.build_tools = grammar_processor.get_build_packages() self.build_tools |= set(project.additional_build_packages) # If version: git is used we want to add "git" to build-packages if self.data.get("version") == "git": self.build_tools.add("git") # Always add the base for building for non os and base snaps if project.info.base is not None and project.info.type not in ("base", "os"): # If the base is already installed by other means, skip its installation. # But, we should always add it when in a docker environment so # the creator of said docker image is aware that it is required. if common.is_docker_instance( ) or not repo.snaps.SnapPackage.is_snap_installed( project.info.base): self.build_snaps.add(project.info.base) elif project.info.type not in ("base", "os"): # This exception is here to help with porting issues with bases. In normal # executions, when no base is set, the legacy snapcraft will be executed. raise RuntimeError("A base is required for {!r} snaps.".format( project.info.type)) self.parts = PartsConfig( parts=self.data, project=project, validator=self.validator, build_snaps=self.build_snaps, build_tools=self.build_tools, ) self.data["architectures"] = _process_architectures( self.data.get("architectures"), project.deb_arch) conduct_environment_sanity_check(self.project, self.data, self.validator.schema)
def __init__(self, *, dynamic_linker: str, root_path: str, preferred_patchelf_path=None) -> None: """Create a Patcher instance. :param str dynamic_linker: the path to the dynamic linker to set the elf file to. :param str root_path: the base path for the snap to determine if use of $ORIGIN is possible. :param str preferred_patchelf_path: patch the necessary elf_files with this patchelf. """ self._dynamic_linker = dynamic_linker self._root_path = root_path # We will first fallback to the preferred_patchelf_path, # if that is not found we will look for the snap and finally, # if we are running from the snap we want to use the patchelf # bundled there as it would have the capability of working # anywhere given the fixed ld it would have. # If not found, resort to whatever is on the system brought # in by packaging dependencies. # The docker conditional will work if the docker image has the # snaps unpacked in the corresponding locations. if preferred_patchelf_path: self._patchelf_cmd = preferred_patchelf_path # We use the full path here as the path may not be set on # build systems where the path is recently created and added # to the environment elif os.path.exists('/snap/bin/patchelf'): self._patchelf_cmd = '/snap/bin/patchelf' elif common.is_snap(): snap_dir = os.getenv('SNAP') self._patchelf_cmd = os.path.join(snap_dir, 'bin', 'patchelf') elif (common.is_docker_instance() and os.path.exists('/snap/snapcraft/current/bin/patchelf')): self._patchelf_cmd = '/snap/snapcraft/current/bin/patchelf' else: self._patchelf_cmd = 'patchelf'
def get_tool_path(command_name): """Return the path to the given command By default this utilizes the PATH, but if Snapcraft is running out of the snap or out of Docker, it ensures it's using the one in the snap, not the host. :return: Path to command :rtype: str """ path = command_name if common.is_snap(): path = _command_path_in_root(os.getenv("SNAP"), command_name) elif common.is_docker_instance(): path = _command_path_in_root( os.path.join(os.sep, "snap", "snapcraft", "current"), command_name) if path: return path else: return command_name
def get_tool_path(command_name): """Return the path to the given command By default this utilizes the PATH, but if Snapcraft is running out of the snap or out of Docker, it ensures it's using the one in the snap, not the host. :return: Path to command :rtype: str """ path = command_name if common.is_snap(): path = _command_path_in_root(os.getenv("SNAP"), command_name) elif common.is_docker_instance(): path = _command_path_in_root( os.path.join(os.sep, "snap", "snapcraft", "current"), command_name ) if path: return path else: return command_name
def _requires_patchelf_snap(confinement: str) -> bool: is_snap = common.is_snap() is_docker_instance = common.is_docker_instance() is_classic = confinement == 'classic' return (is_classic and not is_snap and not is_docker_instance)