def test_local_elf_interp_install(self): """ Makes sure that we link to the installed interp if there is one. """ # This is a slight hack, but lets pre-create seed the environment with # our symlink ld.so so that it is the link target interp_path = linux.readelf_interp(sys.executable) lib_dir = os.path.join(self.env_dir, 'lib') target_path = os.path.join(lib_dir, 'ld-2.99.so') util.ensure_dir(lib_dir) os.symlink(interp_path, target_path) # Create out environment self._make_empty_env() # Run the install self._xpkg_cmd(['install', 'basic', '--tree', self.tree_dir]) # Make sure it has the proper elf interp basic_bin = os.path.join(self.env_dir, 'bin', 'basic') interp_path = linux.readelf_interp(basic_bin) expected = os.path.join(self.env_dir, 'lib', 'ld-linux-xpkg.so') self.assertEquals(expected, interp_path) # Make sure it points to our special one linked_path = os.readlink(interp_path) self.assertEquals(target_path, linked_path)
def setUpClass(cls): """ Sets up a little test Xpkg environment and builds the test toolset packages. """ # Get all the basics setup TestBase.setUpClass() # Create a toolset repo directory cls.toolset_repo_dir = os.path.join(cls.storage_dir, 'toolset-repo') util.ensure_dir(cls.toolset_repo_dir) # Build our packages into it root_tree = os.path.join(root_dir, 'pkgs') for pkg_name in ['busybox', 'tcc', 'uclibc']: xpd_path = os.path.join(root_tree, pkg_name + '.xpd') args = ['build', xpd_path, '--dest', cls.toolset_repo_dir] cmd = [sys.executable, '-m', 'xpkg.main'] + args # Run build inside toolset dir so that the build logs don't pollute # Anything cwd = os.getcwd() with util.cd(cls.toolset_repo_dir): with util.save_env(): os.environ['PYTHONPATH'] = cwd output = util.shellcmd(cmd, shell=False, stream=False)
def create_test_repo(dest_dir): """ Creates a set of Xpkg package files and matches source tar balls from our test projects. """ # Create our target directories file_dir = os.path.join(dest_dir, 'files') tree_dir = os.path.join(dest_dir, 'tree') util.ensure_dir(file_dir) util.ensure_dir(tree_dir) # Unpack all the packages test_package_dir = os.path.join(root_dir, 'tests') for name in os.listdir(test_package_dir): full_path = os.path.join(test_package_dir, name) if os.path.isdir(full_path): # Do this for all the xpd files starting with name in the directory regex = re.compile('(%s\d*).xpd.pyt' % name) for file_name in os.listdir(full_path): match = regex.match(file_name) if match: xpd_name = match.group(1) setup_package(xpd_name, full_path, file_dir, tree_dir)
def test_multi_tree(self): """ Test that we can properly work with multiple package trees. """ # Paths to our two trees primary_tree = os.path.join(self.work_dir, 'primary-tree') secondary_tree = os.path.join(self.work_dir, 'secondary-tree') # Copy the contents of our main tree primary local tree shutil.copytree(self.tree_dir, primary_tree) # Move libgreet-2 and hello packages to the secondary tree util.ensure_dir(secondary_tree) for move_file in ['libgreet2.xpd', 'hello.xpd']: shutil.move(os.path.join(primary_tree, move_file), secondary_tree) # Set the tree environment variable to include both the primary and # the secondary tree os.environ[core.xpkg_tree_var] = '%s:%s' % (primary_tree, secondary_tree) # Make sure we can install hello package self._xpkg_cmd(['install', 'hello']) self.assertPathExists(self.hello_bin) # Install greeter2, and make sure we have libgreet installed self._xpkg_cmd(['install', 'greeter==2.0.0']) output = self._xpkg_cmd(['list']) self.assertRegexpMatches(output, '.*libgreet - 2.0.0.*')
def save_to_disk(self): """ Saves XPA info manifests to JSON cache file. """ cache_dir, _ = os.path.split(self._cache_path) util.ensure_dir(cache_dir) with open(self._cache_path, 'w') as f: json.dump(self._cache, f)
def setUp(self): """ Creates repo and environment directory. """ # Create temp dir self.work_dir = tempfile.mkdtemp(suffix = '-testing-xpkg') print self.work_dir # Create the user cache dir self.user_cache_dir = os.path.join(self.work_dir, 'user_cache') # Mock the user dir os.environ[core.xpkg_local_cache_var] = self.user_cache_dir # Create the env_dir self.env_dir = os.path.join(self.work_dir, 'env') # Create our binary package repository dir self.repo_dir = os.path.join(self.work_dir, 'repo') util.ensure_dir(self.repo_dir) # Save the environment self._envStorage = util.EnvStorage(store = True)
def setUp(self): """ Creates repo and environment directory. """ # Create temp dir self.work_dir = tempfile.mkdtemp(suffix='-testing-xpkg') print self.work_dir # Create the user cache dir self.user_cache_dir = os.path.join(self.work_dir, 'user_cache') # Mock the user dir os.environ[core.xpkg_local_cache_var] = self.user_cache_dir # Create the env_dir self.env_dir = os.path.join(self.work_dir, 'env') # Create our binary package repository dir self.repo_dir = os.path.join(self.work_dir, 'repo') util.ensure_dir(self.repo_dir) # Save the environment self._envStorage = util.EnvStorage(store=True)
def update_ld_so_symlink(root, target_dir=None): """ Maintains a symlink from <env_dir>/lib/ld-linux-xpkg.so to the Environment's local one or the system copy. root - the root directory of our environment target_dir - where to place the symlink (defaults to root) """ # Use the current Python interpreters ld-linux path as the system # version interp_path = readelf_interp(sys.executable) if interp_path is None: msg = 'Could not find ELF program interpreter for: ' + sys.executable raise Exception(msg) # Search for system copies (this is kind of hacky right now) search_dirs = [ 'lib', 'lib64', os.path.join('lib', 'x86_64-linux-gnu'), os.path.join('lib', 'i386-linux-gnu') ] search_paths = [os.path.join(root, d) for d in search_dirs] search_patterns = ['ld-2.[0-9]+.so', 'ld64-uClibc.so.0'] search_regex = [re.compile(p) for p in search_patterns] env_interp = None for search_dir in [p for p in search_paths if os.path.exists(p)]: for filename in os.listdir(search_dir): for regex in search_regex: match = regex.match(filename) if match and match.span()[1] == len(filename): env_interp = os.path.join(search_dir, filename) # Chose the environment interp the source one if env_interp: source_interp = env_interp else: source_interp = interp_path # Remove the existing symlink if present if target_dir is None: target_root = root else: target_root = target_dir link_target = paths.ld_linux_path(target_root) if os.path.lexists(link_target): os.remove(link_target) # Make sure the target directory is created link_dir, _ = os.path.split(link_target) util.ensure_dir(link_dir) # Place down our symlink os.symlink(source_interp, link_target) return link_target
def build(self, target_dir, environment = None, output_to_file=True): """ Right now this just executes instructions inside the XPD, but in the future we can make this a little smarter. It returns the info structure for the created package. See the XPA class for the structure of the data returned. """ # Create our temporary directory self._work_dir = tempfile.mkdtemp(suffix = '-xpkg-' + self._xpd.name) # TODO: LOG THIS print 'Working in:',self._work_dir # Create our output if output_to_file: # Form a hopefully unique name for the output file args = (self._xpd.name, self._xpd.version) output_file = '%s-%s_build.log' % args # Put the file in our environment if we have, or the current # directory if environment: # Find out log dir log_dir = environment.log_dir(environment.root) # Make sure it exists util.ensure_dir(log_dir) # Now finally commit to our path output_path = os.path.join(log_dir, output_file) else: output_path = os.path.abspath(os.path.join('.', output_file)) # TODO: LOG THIS print 'Log file:',output_path # Open our file for writing self._output = open(output_path, 'w') else: self._output = None # Store our target dir self._target_dir = target_dir util.ensure_dir(self._target_dir) # Determine our environment directory if environment: self._env_dir = environment._env_dir else: self._env_dir = '' # Setup the ld.so symlink in the target dir pointing to either # the system ld.so, or the current environments ld_target_dir = self._target_dir update_root = self._env_dir if len(self._env_dir) else self._target_dir linux.update_ld_so_symlink(update_root, ld_target_dir) try: # Store the current environment env_vars = util.EnvStorage(store = True) # If we have an environment apply it's variables so the build can # reference the libraries installed in it if environment: environment.apply_env_variables() # Fetches and unpacks all the required sources for the package self._get_sources() # Determine what directory we have to do the build in dirs = [d for d in os.listdir(self._work_dir) if os.path.isdir(os.path.join(self._work_dir, d))] if 'build-dir' in self._xpd._data: # If the user specifies a build directory use it rel_build_dir = self._xpd._data['build-dir'] build_dir = os.path.join(self._work_dir, rel_build_dir) # Make sure the directory exists util.ensure_dir(build_dir) elif len(dirs) == 1: build_dir = os.path.join(self._work_dir, dirs[0]) else: build_dir = self._work_dir with util.cd(build_dir): # Standard build configure install self._configure() self._build() new_paths = self._install() finally: # Put back our environment env_vars.restore() self._env_dir = '' # Close our output file if it exists if self._output: self._output.close() self._output = None # Make sure we cleanup after we are done shutil.rmtree(self._work_dir) return self._create_info(new_paths)
def __init__(self, env_dir=None, create=False, tree_path=None, repo_path=None, verbose=False): """ env_dir - path to the environment dir create - create the environment if it does exist tree_path - URL for a XPD tree repo_path - URL for a XPA package archive verbose - print all build commands to screen """ if env_dir is None: if xpkg_root_var in os.environ: self._env_dir = os.environ[xpkg_root_var] else: raise Exception("No XPKG_ROOT not defined, can't find environment") else: self._env_dir = env_dir self.root = self._env_dir self.verbose = verbose # Error out if we are not creating and environment and this one does # not exist if not self.env_exists(self._env_dir) and not create: raise Exception('No Xpkg environment found in "%s"' % self._env_dir) # Create environment if needed if not self.env_exists(self._env_dir) and create: self.init(self._env_dir, 'default', build.DefaultToolsetName) # If needed this will setup the empty environment self._pdb = InstallDatabase(self._env_dir) # Load the settings settings = Settings(self.env_settings_path(self._env_dir)) self.name = settings.name self.toolset = settings.toolset def get_paths(base_path, env_var): """ Parse class argument and environment variables to get path. """ # Get the raw path from our given value, or the environment variable raw_path = None if base_path: raw_path = base_path elif env_var in os.environ: raw_path = os.environ[env_var] else: raw_path = None # Turn that raw path into a list if raw_path: paths = raw_path.split(':') else: paths = [] return paths # Setup the package tree to either load from the given path or return # no packages self.tree_paths = get_paths(tree_path, xpkg_tree_var) if len(self.tree_paths) == 1: self._tree = FilePackageTree(self.tree_paths[0]) elif len(self.tree_paths) > 0: trees = [FilePackageTree(t) for t in self.tree_paths] self._tree = CombinePackageSource(trees) else: self._tree = EmptyPackageSource() # Setup the package repository so we can install pre-compiled packages self.repo_paths = get_paths(repo_path, xpkg_repo_var) if len(self.repo_paths) == 1: self._repo = FilePackageRepo(self.repo_paths[0]) elif len(self.repo_paths) > 0: repos = [FilePackageRepo(t) for t in self.repo_paths] self._repo = CombinePackageSource(repos) else: self._repo = EmptyPackageSource() # Make sure the package cache is created self._xpa_cache_dir = self.xpa_cache_dir(self._env_dir) util.ensure_dir(self._xpa_cache_dir)
def update_ld_so_symlink(root, target_dir = None): """ Maintains a symlink from <env_dir>/lib/ld-linux-xpkg.so to the Environment's local one or the system copy. root - the root directory of our environment target_dir - where to place the symlink (defaults to root) """ # Use the current Python interpreters ld-linux path as the system # version interp_path = readelf_interp(sys.executable) if interp_path is None: msg = 'Could not find ELF program interpreter for: ' + sys.executable raise Exception(msg) # Search for system copies (this is kind of hacky right now) search_dirs = [ 'lib', 'lib64', os.path.join('lib', 'x86_64-linux-gnu'), os.path.join('lib', 'i386-linux-gnu') ] search_paths = [os.path.join(root, d) for d in search_dirs] search_patterns = [ 'ld-2.[0-9]+.so', 'ld64-uClibc.so.0' ] search_regex = [re.compile(p) for p in search_patterns] env_interp = None for search_dir in [p for p in search_paths if os.path.exists(p)]: for filename in os.listdir(search_dir): for regex in search_regex: match = regex.match(filename) if match and match.span()[1] == len(filename): env_interp = os.path.join(search_dir, filename) # Chose the environment interp the source one if env_interp: source_interp = env_interp else: source_interp = interp_path # Remove the existing symlink if present if target_dir is None: target_root = root else: target_root = target_dir link_target = paths.ld_linux_path(target_root) if os.path.lexists(link_target): os.remove(link_target) # Make sure the target directory is created link_dir, _ = os.path.split(link_target) util.ensure_dir(link_dir) # Place down our symlink os.symlink(source_interp, link_target) return link_target
def __init__(self, env_dir=None, create=False, tree_path=None, repo_path=None, verbose=False): """ env_dir - path to the environment dir create - create the environment if it does exist tree_path - URL for a XPD tree repo_path - URL for a XPA package archive verbose - print all build commands to screen """ if env_dir is None: if xpkg_root_var in os.environ: self._env_dir = os.environ[xpkg_root_var] else: raise Exception( "No XPKG_ROOT not defined, can't find environment") else: self._env_dir = env_dir self.root = self._env_dir self.verbose = verbose # Error out if we are not creating and environment and this one does # not exist if not self.env_exists(self._env_dir) and not create: raise Exception('No Xpkg environment found in "%s"' % self._env_dir) # Create environment if needed if not self.env_exists(self._env_dir) and create: self.init(self._env_dir, 'default', build.DefaultToolsetName) # If needed this will setup the empty environment self._pdb = InstallDatabase(self._env_dir) # Load the settings settings = Settings(self.env_settings_path(self._env_dir)) self.name = settings.name self.toolset = settings.toolset def get_paths(base_path, env_var): """ Parse class argument and environment variables to get path. """ # Get the raw path from our given value, or the environment variable raw_path = None if base_path: raw_path = base_path elif env_var in os.environ: raw_path = os.environ[env_var] else: raw_path = None # Turn that raw path into a list if raw_path: paths = raw_path.split(':') else: paths = [] return paths # Setup the package tree to either load from the given path or return # no packages self.tree_paths = get_paths(tree_path, xpkg_tree_var) if len(self.tree_paths) == 1: self._tree = FilePackageTree(self.tree_paths[0]) elif len(self.tree_paths) > 0: trees = [FilePackageTree(t) for t in self.tree_paths] self._tree = CombinePackageSource(trees) else: self._tree = EmptyPackageSource() # Setup the package repository so we can install pre-compiled packages self.repo_paths = get_paths(repo_path, xpkg_repo_var) if len(self.repo_paths) == 1: self._repo = FilePackageRepo(self.repo_paths[0]) elif len(self.repo_paths) > 0: repos = [FilePackageRepo(t) for t in self.repo_paths] self._repo = CombinePackageSource(repos) else: self._repo = EmptyPackageSource() # Make sure the package cache is created self._xpa_cache_dir = self.xpa_cache_dir(self._env_dir) util.ensure_dir(self._xpa_cache_dir)