def test(self): tmpdir = tempfile.mkdtemp(prefix='laymantmp_') makeconf = os.path.join(tmpdir, 'make.conf') reposconf = os.path.join(tmpdir, 'repos.conf') make_txt =\ 'PORTDIR_OVERLAY="\n'\ '$PORTDIR_OVERLAY"' # Create the .conf files so layman doesn't # complain. with fileopen(makeconf, 'w') as f: f.write(make_txt) with fileopen(reposconf, 'w') as f: f.write('') my_opts = { 'installed': HERE + '/testfiles/global-overlays.xml', 'make_conf': makeconf, 'nocheck': 'yes', 'storage': tmpdir, 'repos_conf': reposconf, 'conf_type': ['make.conf', 'repos.conf'], } config = OptionConfig(my_opts) config.set_option('quietness', 3) a = DB(config) config['output'].set_colorize(False) conf = RepoConfManager(config, a.overlays) # Set up our success tracker. success = [] # Add all the overlays in global_overlays.xml. for overlay in a.overlays.keys(): conf_success = conf.add(a.overlays[overlay]) if conf_success == False: success.append(False) else: success.append(True) # Disable one overlay. self.assertTrue(conf.disable(a.overlays['wrobel'])) # Enable disabled overlay. self.assertTrue(conf.enable(a.overlays['wrobel'])) # Delete all the overlays in global_overlays.xml. for overlay in a.overlays.keys(): self.assertTrue(conf.delete(a.overlays[overlay])) # Clean up. os.unlink(makeconf) os.unlink(reposconf) shutil.rmtree(tmpdir)
def set_db_type(self, migrate_type, installed): config_path = self.config['config']\ % {'configdir': self.config['configdir']} db_type_found = False installed_found = False new_conf = os.path.dirname(config_path) + '/' + '._cfg0000_' +\ os.path.basename(config_path) new_lines = [] try: shutil.copy(config_path, new_conf) except IOError as err: msg = ' set_db_type() error; failed to copy "%(old)s" to '\ '"%(new)s\n Error was: %(err)s"' % {'old': config_path, 'new': new_conf, 'err': err} self.output.error(msg) raise err if not os.path.isfile(new_conf): msg = 'set_db_type() error; failed to read config at "%(path)s".'\ % {'path': new_conf} self.output.error(' ' + msg) raise Exception(msg) try: with fileopen(new_conf, 'r') as laymanconf: lines = laymanconf.readlines() except Exception as err: msg = ' set_db_type() error; failed to read config at "%(path)s".'\ '\n Error was: "%(err)s"' % {'path': new_conf, 'err': err} self.output.error(msg) raise err for line in lines: if re.search('^#*\s*db_type\s*:', line): db_type_found = True line = 'db_type : ' + migrate_type + '\n' if re.search('^#*\s*installed\s*:', line): installed_found = True line = 'installed : %(storage)s/' + installed + '\n' new_lines.append(line) if not db_type_found: new_lines.append('db_type : ' + migrate_type + '\n') if not installed_found: new_lines.append('installed : %(storage)s/' + installed + '\n') with fileopen(new_conf, 'w') as laymanconf: for line in new_lines: laymanconf.write(line)
def test(self): tmpdir = tempfile.mkdtemp(prefix='laymantmp_') cache = os.path.join(tmpdir, 'cache') my_opts = { 'overlays': ['file://' + HERE + '/testfiles/global-overlays.xml'], 'cache': cache, 'nocheck': 'yes', 'proxy': None } config = OptionConfig(my_opts) db = RemoteDB(config) self.assertEqual(db.cache(), (True, True)) db_xml = fileopen(db.filepath(config['overlays']) + '.xml') test_line = ' A collection of ebuilds from Gunnar Wrobel '\ '[[email protected]].\n' self.assertEqual(db_xml.readlines()[19], test_line) for line in db_xml.readlines(): print(line, end='') db_xml.close() keys = sorted(db.overlays) self.assertEqual(keys, ['wrobel', 'wrobel-stable']) shutil.rmtree(tmpdir)
def write(self, delete=None): ''' Writes changes from ConfigParser to /etc/portage/repos.conf/layman.conf. @params delete: overlay name to be delete from the config. @return boolean: represents a successful write. ''' try: with fileopen(self.path, 'w') as laymanconf: # If the repos.conf is empty check to see if we can write # all the overlays to the file. if self.rebuild: # start over with a fresh instance self.repo_conf = ConfigParser.ConfigParser() if not self.repo_conf.sections(): if ('disable' in self.config.keys() and not self.config['disable'][0].lower() == 'all'): for i in sorted(self.overlays): if not i == delete: self.add(self.overlays[i], no_write=True) self.repo_conf.write(laymanconf) self.rebuild = False return True except IOError as error: self.output.error('ReposConf: ConfigHandler.write(); Failed to write "'\ '%(path)s".\nError was:\n%(error)s'\ % ({'path': self.path, 'error': str(error)}))
def write(self, delete=None): ''' Writes changes from ConfigParser to /etc/portage/repos.conf/layman.conf. @params delete: overlay name to be delete from the config. @return boolean: represents a successful write. ''' try: with fileopen(self.path, 'w') as laymanconf: # If the repos.conf is empty check to see if we can write # all the overlays to the file. if self.rebuild: # start over with a fresh instance self.repo_conf = ConfigParser.ConfigParser() for i in sorted(self.overlays): self.add(self.overlays[i], no_write=True) if not self.repo_conf.sections() and not self.rebuild: if ('disable' in self.config.keys() and not self.config['disable'][0].lower() == 'all'): for i in sorted(self.overlays): if not i == delete: self.add(self.overlays[i], no_write=True) self.repo_conf.write(laymanconf) return True except IOError as error: self.output.error('ReposConf: ConfigHandler.write(); Failed to write "'\ '%(path)s".\nError was:\n%(error)s'\ % ({'path': self.path, 'error': str(error)}))
def write_cache(olist, mpath, tpath=None, timestamp=None): has_updates = False try: with fileopen(mpath, 'w') as out_file: out_file.write(olist) if timestamp is not None and tpath is not None: with fileopen(tpath, 'w') as out_file: out_file.write(str(timestamp)) has_updates = True except Exception as error: raise IOError('Failed to temporarily cache overlays list in' ' ' + mpath + '\nError was:\n' + str(error)) return has_updates
def write(self, path): ''' Write the list of overlays to a file. >>> import tempfile >>> tmpdir = tempfile.mkdtemp(prefix="laymantmp_") >>> write = os.path.join(tmpdir, 'test.xml') >>> here = os.path.dirname(os.path.realpath(__file__)) >>> from layman.config import BareConfig >>> config = BareConfig() >>> a = DbBase(config, [here + '/tests/testfiles/global-overlays.xml', ]) >>> from layman.output import Message >>> b = DbBase({"output": Message() }, [write,]) >>> b.overlays['wrobel-stable'] = a.overlays['wrobel-stable'] >>> b.write(write) >>> c = DbBase({"output": Message() }, [write,]) >>> c.overlays.keys() ['wrobel-stable'] >>> os.unlink(write) >>> os.rmdir(tmpdir) ''' tree = ET.Element('repositories', version="1.0", encoding=_UNICODE) tree[:] = [e.to_xml() for e in self.overlays.values()] indent(tree) tree = ET.ElementTree(tree) try: with fileopen(path, 'w') as f: tree.write(f, encoding=_UNICODE) except Exception as error: raise Exception('Failed to write to local overlays file: ' + path + '\nError was:\n' + str(error))
def write(self, delete=None, disable=None): ''' Writes changes from ConfigParser to /etc/portage/repos.conf/layman.conf. @params disable: overlay name to be disabled. @return boolean: represents a successful write. ''' try: with fileopen(self.path, 'w') as laymanconf: # If the repos.conf is empty check to see if we can write # all the overlays to the file. if not self.repo_conf.sections(): for i in self.overlays: if not i == delete: self.add(self.overlays[i]) self.repo_conf.write(laymanconf) if disable: # comments out section header of the overlay. subprocess.call(['sed', '-i', 's/^\[%(ovl)s\]/#[%(ovl)s]/'\ % {'ovl': disable}, self.path]) return True except IOError as error: self.output.error('ReposConf: ConfigHandler.write(); Failed to write "'\ '%(path)s".\nError was:\n%(error)s'\ % ({'path': self.path, 'error': str(error)}))
def test(self): tmpdir = tempfile.mkdtemp(prefix='laymantmp_') cache = os.path.join(tmpdir, 'cache') my_opts = { 'overlays' : ['file://' + HERE + '/testfiles/global-overlays.xml'], 'cache' : cache, 'nocheck' : 'yes', 'proxy' : None } config = OptionConfig(my_opts) db = RemoteDB(config) self.assertEquals(db.cache(), (True, True)) db_xml = fileopen(db.filepath(config['overlays']) + '.xml') test_line = ' A collection of ebuilds from Gunnar Wrobel '\ '[[email protected]].\n' self.assertEqual(db_xml.readlines()[19], test_line) for line in db_xml.readlines(): print(line, end='') db_xml.close() keys = sorted(db.overlays) self.assertEqual(keys, ['wrobel', 'wrobel-stable']) shutil.rmtree(tmpdir)
def _fetch_file(self, url, mpath, tpath=None): self.output.debug('RemoteDB._fetch_file() url = %s' % url, 2) # check when the cache was last updated # and don't re-fetch it unless it has changed filepath = url.replace('file://','') url_timestamp = None timestamp = '' if tpath and os.path.exists(tpath): with fileopen(tpath,'r') as previous: timestamp = previous.read() if not self.check_path([mpath]): return (False, '', '') try: url_timestamp = os.stat(filepath).st_mtime if url_timestamp != timestamp: self.output.debug('RemoteDB._fetch_file() opening file', 2) # Fetch the remote list with fileopen(filepath) as connection: olist = connection.read() else: self.output.info('Remote list already up to date: %s' % url, 4) self.output.info('Last-modified: %s' % timestamp, 4) except IOError as error: self.output.error('RemoteDB._fetch_file(); Failed to update the ' 'overlay list from: %s\nIOError was:%s\n' % (url, str(error))) return (False, '', '') else: quieter = 1 self.output.info('Fetching new list... %s' % url, 4 + quieter) if url_timestamp is not None: self.output.info('Last-modified: %s' % url_timestamp, 4 + quieter) self.output.debug('RemoteDB._fetch_url(), olist type = %s' % str(type(olist)),2) return (True, olist, url_timestamp)
def test(self): tmpdir = tempfile.mkdtemp(prefix='laymantmp_') cache = os.path.join(tmpdir, 'cache') my_opts = { 'overlays': ['file://'\ + HERE + '/testfiles/global-overlays.xml'], 'cache': cache, 'nocheck': 'yes', 'proxy': None, 'quietness': 3 } config = OptionConfig(my_opts) api = LaymanAPI(config) self.assertTrue(api.fetch_remote_list()) filename = api._get_remote_db().filepath(config['overlays']) + '.xml' with fileopen(filename, 'r') as b: self.assertEqual(b.readlines()[19], ' A collection of ebuilds from Gunnar Wrobel [[email protected]].\n') for line in b.readlines(): print(line, end='') # Check if we get available overlays. available = api.get_available() self.assertEqual(available, ['wrobel', 'wrobel-stable']) # Test the info of an overlay. all_info = api.get_all_info('wrobel') test_info = {'status': 'official', 'owner_name': None, 'description': ['Test'], 'src_uris': ['https://overlays.gentoo.org/svn/dev/wrobel'], 'owner_email': '*****@*****.**', 'sources': [('https://overlays.gentoo.org/svn/dev/wrobel', 'Subversion', None)], 'quality': 'experimental', 'name': 'wrobel', 'supported': True, 'src_types': ['Subversion'], 'official': True, 'priority': 10, 'feeds': [], 'irc': None, 'homepage': None} info = all_info['wrobel'] info['src_uris'] = [e for e in info['src_uris']] info['src_types'] = [e for e in info['src_types']] self.assertEqual(info, test_info) self.assertEqual(info['status'], 'official') self.assertEqual(info['description'], ['Test']) sources = [('https://overlays.gentoo.org/svn/dev/wrobel', 'Subversion', None)] self.assertEqual(info['sources'], sources) os.unlink(filename) shutil.rmtree(tmpdir)
def _fetch_file(self, url, mpath, tpath=None): self.output.debug('RemoteDB._fetch_file() url = %s' % url, 2) # check when the cache was last updated # and don't re-fetch it unless it has changed filepath = url.replace('file://', '') url_timestamp = None timestamp = '' if tpath and os.path.exists(tpath): with fileopen(tpath, 'r') as previous: timestamp = previous.read() if not self.check_path([mpath]): return (False, '', '') try: url_timestamp = os.stat(filepath).st_mtime if url_timestamp != timestamp: self.output.debug('RemoteDB._fetch_file() opening file', 2) # Fetch the remote list with fileopen(filepath) as connection: olist = connection.read() else: self.output.info('Remote list already up to date: %s' % url, 4) self.output.info('Last-modified: %s' % timestamp, 4) except IOError as error: self.output.error('RemoteDB._fetch_file(); Failed to update the ' 'overlay list from: %s\nIOError was:%s\n' % (url, str(error))) return (False, '', '') else: quieter = 1 self.output.info('Fetching new list... %s' % url, 4 + quieter) if url_timestamp is not None: self.output.info('Last-modified: %s' % url_timestamp, 4 + quieter) self.output.debug( 'RemoteDB._fetch_url(), olist type = %s' % str(type(olist)), 2) return (True, olist, url_timestamp)
def content(self): ''' Returns the content of the /var/lib/layman/make.conf file. ''' try: with fileopen(self.path, 'r') as make_conf: self.data = make_conf.read() except Exception as error: self.output.error('ConfigHandler: content(); Failed to read "'\ '%(path)s".\nError was:\n%(error)s' % ({'path': self.path, 'error': str(error)})) raise error
def read_file(self, path): '''Read the overlay definition file.''' try: df = fileopen(path, 'r') document = df.read() except Exception, error: if not self.ignore_init_read_errors: self.output.error('Failed to read the overlay list at ("' + path + '")') raise error
def get_file(self, path, mode='r'): '''Obtains file object for given path''' if mode not in ('r', 'w+'): raise LockingException('Invalid mode %(mode)s' % {'mode': mode}) if (path not in self.files or self.files[path].closed or self.files[path].mode != mode): self.files[path] = fileopen(path, mode) f = self.files[path] f.seek(0) return f
def write(self, path): ''' Write the list of overlays to a file. ''' try: repo = {'@encoding': 'unicode', '@version': '1.0', 'repo': []} repo['repo'] = [self.overlays[key].to_json() for key in self.overlays] with fileopen(path, 'w') as df: df.write(json.dumps(repo, sort_keys=True, indent=2)) except Exception as err: msg = 'Failed to write to local overlays file: %(path)s\nError was'\ ': %(err)s' % {'path': path, 'err': err} self.output.error(msg) raise err
def content(self): """ Returns the content of the /var/lib/layman/make.conf file. """ try: with fileopen(self.path, "r") as make_conf: self.data = make_conf.read() except Exception as error: self.output.error( 'ConfigHandler: content(); Failed to read "' '%(path)s".\nError was:\n%(error)s' % ({"path": self.path, "error": str(error)}) ) raise error
def write(self): ''' Writes changes from ConfigParser to /etc/portage/repos.conf/layman.conf. @return boolean: represents a successful write. ''' try: with fileopen(self.path, 'w') as laymanconf: self.repo_conf.write(laymanconf) return True except IOError as error: self.output.error('ReposConf: ConfigHandler.write(); Failed to write "'\ '%(path)s".\nError was:\n%(error)s'\ % ({'path': self.path, 'error': str(error)}))
def write(self, path, remove=False): ''' Write the list of overlays to a file. ''' try: repo = {'@encoding': 'unicode', '@version': '1.0', 'repo': []} repo['repo'] = [ self.overlays[key].to_json() for key in self.overlays ] with fileopen(path, 'w') as df: df.write(json.dumps(repo, sort_keys=True, indent=2)) except Exception as err: msg = 'Failed to write to local overlays file: %(path)s\nError was'\ ': %(err)s' % {'path': path, 'err': err} self.output.error(msg) raise err
def write(self, path): ''' Write the list of overlays to a file. ''' tree = ET.Element('repositories', version="1.0", encoding=_UNICODE) tree[:] = [e.to_xml() for e in self.overlays.values()] indent(tree) tree = ET.ElementTree(tree) try: with fileopen(path, 'w') as f: tree.write(f, encoding=_UNICODE) except Exception as error: raise Exception('Failed to write to local overlays file: ' + path + '\nError was:\n' + str(error))
def write(self, path, remove=False): ''' Write the list of overlays to a file. ''' tree = ET.Element('repositories', version="1.0", encoding=_UNICODE) tree[:] = [e.to_xml() for e in self.overlays.values()] indent(tree) tree = ET.ElementTree(tree) try: with fileopen(path, 'w') as f: tree.write(f, encoding=_UNICODE) except Exception as err: msg = 'Failed to write to local overlays file: %(path)s\nError was'\ ':\n%(err)s' % {'path': path, 'err': err} raise Exception(msg)
def write(self, path): ''' Write the list of overlays to a file. ''' tree = ET.Element('repositories', version="1.0", encoding=_UNICODE) tree[:] = [e.to_xml() for e in self.overlays.values()] indent(tree) tree = ET.ElementTree(tree) try: with fileopen(path, 'w') as f: tree.write(f, encoding=_UNICODE) except Exception as err: msg = 'Failed to write to local overlays file: %(path)s\nError was'\ ':\n%(err)s' % {'path': path, 'err': err} raise Exception(msg)
def _fetch(self, base, archive_url, dest_dir): ''' Fetches overlay source archive. @params base: string of directory base for installed overlays. @params archive_url: string of URL where archive is located. @params dest_dir: string of destination of extracted archive. @rtype tuple (str of package location, bool to clean_archive) ''' ext = self.get_extension() if 'file://' not in archive_url: # set up ssl-fetch output map connector_output = { 'info': self.output.debug, 'error': self.output.error, 'kwargs-info': { 'level': 5 }, 'kwargs-debug': { 'level': 2 }, 'kwargs-error': { 'level': None }, } fetcher = Connector(connector_output, self.proxies, USERAGENT) success, archive, timestamp = fetcher.fetch_content(archive_url) pkg = path([base, self.parent.name + ext]) try: with fileopen(pkg, 'w+b') as out_file: out_file.write(archive) except Exception as error: raise Exception('Failed to store archive package in '\ '%(pkg)s\nError was: %(error)s'\ % ({'pkg': pkg, 'error': error})) else: self.clean_archive = False pkg = archive_url.replace('file://', '') return pkg
def test(self): tmpdir = tempfile.mkdtemp(prefix='laymantmp_') cache = os.path.join(tmpdir, 'cache') my_opts = { 'overlays': ['file://'\ + HERE + '/testfiles/global-overlays.xml'], 'db_type': 'xml', 'cache': cache, 'nocheck': 'yes', 'proxy': None, 'quietness': 3 } config = OptionConfig(my_opts) api = LaymanAPI(config) self.assertTrue(api.fetch_remote_list()) filename = api._get_remote_db().filepath(config['overlays']) + '.xml' with fileopen(filename, 'r') as b: description = b.readlines()[19] self.assertEqual(description, ' A collection of ebuilds from '\ 'Gunnar Wrobel [[email protected]].\n') for line in b.readlines(): print(line, end='') # Check if we get available overlays. available = api.get_available() self.assertEqual(available, ['wrobel', 'wrobel-stable']) # Test the info of an overlay. info = api.get_info_str(['wrobel'], verbose=True, local=False) test_info = 'wrobel\n~~~~~~\nSource : https://overlays.gentoo.org'\ '/svn/dev/wrobel\nContact : [email protected]\nType '\ ': Subversion; Priority: 10\nQuality : experimental\n\n'\ 'Description:\n Test\n' info = info['wrobel'][0].decode('utf-8') self.assertEqual(info, test_info) os.unlink(filename) shutil.rmtree(tmpdir)
def read_db(self, path, text=None): ''' Read the overlay definition file. ''' document = text if not document: try: with fileopen(path, 'r') as df: document = df.read() except Exception as error: if not self.ignore_init_read_errors: msg = 'JSON DBHandler - Failed to read the overlay list at'\ '("%(path)s")' % {'path': path} self.output.error(msg) raise error self.add_new(document, origin=path)
def read_db(self, path, text=None): ''' Read the overlay definition file. ''' document = text if not document: try: with fileopen(path, 'r') as df: document = df.read() except Exception as error: if not self.ignore_init_read_errors: msg = 'XML DBHandler - Failed to read the overlay list at '\ '"%(path)s"' % {'path': path} self.output.error(msg) return False success = self.read(document, origin=path) return success
def _extract(self, base, tar_url, dest_dir): ext = '.tar.noidea' clean_tar = self.config['clean_tar'] for i in [('tar.%s' % e) for e in ('bz2', 'gz', 'lzma', 'xz', 'Z')] \ + ['tgz', 'tbz', 'taz', 'tlz', 'txz']: candidate_ext = '.%s' % i if self.src.endswith(candidate_ext): ext = candidate_ext break if 'file://' not in tar_url: # setup the ssl-fetch output map connector_output = { 'info': self.output.debug, 'error': self.output.error, 'kwargs-info': {'level': 2}, 'kwargs-error':{'level': None}, } fetcher = Connector(connector_output, self.proxies, USERAGENT) success, tar, timestamp = fetcher.fetch_content(tar_url) pkg = path([base, self.parent.name + ext]) try: with fileopen(pkg, 'w+b') as out_file: out_file.write(tar) except Exception as error: raise Exception('Failed to store tar package in ' + pkg + '\nError was:' + str(error)) else: clean_tar = False pkg = tar_url.replace('file://', '') # tar -v -x -f SOURCE -C TARGET args = ['-v', '-x', '-f', pkg, '-C', dest_dir] result = self.run_command(self.command(), args, cmd=self.type) if clean_tar: os.unlink(pkg) return result
def write(self, destination): ''' Writes overlay file to desired location. @params destination: path & file to write xml to. @rtype bool: reflects success or failure to write xml. ''' if not destination: filepath = self.config.get_option('overlay_defs') if self.sudo: filepath = get_input('Desired file destination dir: ') filename = get_input('Desired overlay file name: ') if not filename.endswith('.xml'): filename += ".xml" if not filepath.endswith(os.path.sep): filepath += os.path.sep destination = filepath + filename self.tree = ET.Element('repositories', version='1.1', encoding=_UNICODE) if os.path.isfile(destination): self.read(destination) self._sort_to_tree() indent(self.tree) self.tree = ET.ElementTree(self.tree) try: with fileopen(destination, 'w') as xml: self.tree.write(xml, encoding=_UNICODE) msg = 'Successfully wrote repo(s) to: %(path)s'\ % ({'path': destination}) self.output.info(msg) return True except IOError as e: raise Exception("Writing XML failed: %(error)s" % ({'error': e}))
def _fetch(self, base, archive_url, dest_dir): ''' Fetches overlay source archive. @params base: string of directory base for installed overlays. @params archive_url: string of URL where archive is located. @params dest_dir: string of destination of extracted archive. @rtype tuple (str of package location, bool to clean_archive) ''' ext = self.get_extension() if 'file://' not in archive_url: # set up ssl-fetch output map connector_output = { 'info': self.output.debug, 'error': self.output.error, 'kwargs-info': {'level': 5}, 'kwargs-debug': {'level': 2}, 'kwargs-error': {'level': None}, } fetcher = Connector(connector_output, self.proxies, USERAGENT) success, archive, timestamp = fetcher.fetch_content(archive_url) pkg = path([base, self.parent.name + ext]) try: with fileopen(pkg, 'w+b') as out_file: out_file.write(archive) except Exception as error: raise Exception('Failed to store archive package in '\ '%(pkg)s\nError was: %(error)s'\ % ({'pkg': pkg, 'error': error})) else: self.clean_archive = False pkg = archive_url.replace('file://', '') return pkg
def test(self): temp_dir_path = tempfile.mkdtemp() my_opts = { 'overlays': ['file://'\ + HERE + '/testfiles/global-overlays.xml'], 'nocheck': 'yes', 'proxy': None, 'quietness': 3, } config = OptionConfig(my_opts) ovl_dict = { 'name': 'wrobel', 'description': ['Test'], 'owner': [{ 'name': 'nobody', 'email': '*****@*****.**' }], 'status': 'official', 'source': [['https://overlays.gentoo.org/svn/dev/wrobel', 'svn', '']], 'priority': '10', } a = Overlay(config=config, ovl_dict=ovl_dict, ignore=config['ignore']) ovl = (ovl_dict['name'], a) path = temp_dir_path + '/overlay.xml' create_overlay_xml = Interactive(config=config) create_overlay_xml(overlay_package=ovl, path=path) self.assertTrue(os.path.exists(path)) with fileopen(path, 'r') as xml: test_line = ' <source type="svn">'\ 'https://overlays.gentoo.org/svn/dev/wrobel</source>\n' self.assertTrue(test_line in xml.readlines()) for line in xml.readlines(): print(line, end='') shutil.rmtree(temp_dir_path)
def write(self, destination): """ Writes overlay file to desired location. @params destination: path & file to write xml to. @rtype bool: reflects success or failure to write xml. """ if not destination: filepath = self.config.get_option("overlay_defs") if self.sudo: filepath = get_input("Desired file destination dir: ") filename = get_input("Desired overlay file name: ") if not filename.endswith(".xml"): filename += ".xml" if not filepath.endswith(os.path.sep): filepath += os.path.sep destination = filepath + filename self.tree = ET.Element("repositories", version="1.1", encoding=_UNICODE) if os.path.isfile(destination): self.read(destination) self._sort_to_tree() indent(self.tree) self.tree = ET.ElementTree(self.tree) try: with fileopen(destination, "w") as xml: self.tree.write(xml, encoding=_UNICODE) msg = "Successfully wrote repo(s) to: %(path)s" % ({"path": destination}) self.output.info(msg) return True except IOError as e: raise Exception("Writing XML failed: %(error)s" % ({"error": e}))
def test(self): temp_dir_path = tempfile.mkdtemp() my_opts = { 'overlays': ['file://'\ + HERE + '/testfiles/global-overlays.xml'], 'nocheck': 'yes', 'proxy': None, 'quietness': 3, } config = OptionConfig(my_opts) ovl_dict = { 'name': 'wrobel', 'descriptions': ['Test'], 'owner_name': 'nobody', 'owner_email': '*****@*****.**', 'status': 'official', 'sources': [['https://overlays.gentoo.org/svn/dev/wrobel', 'svn', '']], 'priority': '10', } a = Overlay(config=config, ovl_dict=ovl_dict, ignore=config['ignore']) ovl = (ovl_dict['name'], a) path = temp_dir_path + '/overlay.xml' create_overlay_xml = Interactive(config=config) create_overlay_xml(overlay_package=ovl, path=path) self.assertTrue(os.path.exists(path)) with fileopen(path, 'r') as xml: test_line = ' <source type="svn">'\ 'https://overlays.gentoo.org/svn/dev/wrobel</source>\n' self.assertEqual(xml.readlines()[9], test_line) for line in xml.readlines(): print(line, end='') shutil.rmtree(temp_dir_path)
def read_db(self, path, text=None): ''' Read the overlay definition file. ''' document = text if not document: try: with fileopen(path, 'r') as df: document = df.read() except ValueError as error: msg = 'JSON DBHanlder - ValueError: %(err)s' % {'err': error} self.output.error(msg) return False except Exception as error: if not self.ignore_init_read_errors: msg = 'JSON DBHandler - Failed to read the overlay list at'\ '("%(path)s")' % {'path': path} self.output.error(msg) raise error success = self.add_new(document, origin=path) return success
def write(self, disable=None, enable=None): """ Write the list of registered overlays to /var/layman/make.conf. >>> import tempfile >>> tmpdir = tempfile.mkdtemp(prefix="laymantmp_") >>> os.path.join(tmpdir, 'make.conf') >>> here = os.path.dirname(os.path.realpath(__file__)) >>> config = {'installed' : ... here + '/tests/testfiles/global-overlays.xml', ... 'make_conf' : here + '/tests/testfiles/make.conf', ... 'nocheck' : True, ... 'storage' : '/var/lib/layman', ... 'quietness':3} >>> c = DB(config) >>> a = ConfigHandler(config, c.overlays) >>> a.path = write >>> a.write() >>> config['make_conf'] = write >>> b = ConfigHandler(config, c.overlays) >>> [i.name for i in b.overlays] ['wrobel-stable'] >>> b.extra ['/usr/local/portage/ebuilds/testing', '/usr/local/portage/ebuilds/stable', '/usr/local/portage/kolab2', '/usr/local/portage/gentoo-webapps-overlay/experimental', '/usr/local/portage/gentoo-webapps-overlay/production-ready'] >>> os.unlink(write) >>> import shutil >>> shutil.rmtree(tmpdir) """ def prio_sort(a, b): """Sort by priority.""" if a.priority < b.priority: return -1 elif a.priority > b.priority: return 1 return 0 self.overlays.sort(key=cmp_to_key(prio_sort)) enabled = [] for i in self.overlays: ovl = path([self.storage, i.name]) # We want to enable this overlay: if i.name == enable: if ovl in self.disabled: self.disabled.remove(ovl) enabled.append(ovl) else: msg = 'Overlay "%(repo)s" is already enabled!' % ({"repo": i.name}) self.output.error(msg) return False # We want to disable this overlay: elif i.name == disable: if ovl not in self.disabled: self.disabled.append(ovl) else: msg = 'Overlay "%(repo)s" is already disabled!' % ({"repo": i.name}) self.output.error(msg) # We want to keep it as-is: else: if ovl not in self.disabled: enabled.append(ovl) self.disabled.sort() enabled_overlays = 'ENABLED="\n' enabled_overlays += "\n".join(enabled) + "\n" if enabled else "" enabled_overlays += '"' disabled_overlays = 'DISABLED="\n' disabled_overlays += "\n".join(self.disabled) + "\n" if self.disabled else "" disabled_overlays += '"' overlays = 'PORTDIR_OVERLAY="\n' overlays += "$ENABLED\n" overlays += "$PORTDIR_OVERLAY\n" overlays += "\n".join(self.extra) overlays += '"' if not re.search("ENABLED=", self.data): self.data = "\n".join((enabled_overlays, disabled_overlays, overlays)) enabled_content = self.my_enabled_re.sub(enabled_overlays, self.data) disabled_content = self.my_disabled_re.sub(disabled_overlays, enabled_content) content = self.my_portdir_re.sub(overlays, disabled_content) if not self.my_portdir_re.search(content): self.output.error( "MakeConf: ConfigHandler.write(); Oops, failed to set a " "proper PORTDIR_OVERLAY entry in file " "%(path)s! Did not overwrite the file." % ({"path": self.path}) ) return False try: with fileopen(self.path, "w") as make_conf: make_conf.write(content) except Exception as error: self.output.error( 'MakeConf: ConfigHandler.write(); Failed to write "' '%(path)s".\nError was:\n%(error)s' % ({"path": self.path, "error": str(error)}) ) return False return True
def write(self, disable=None, enable=None): ''' Write the list of registered overlays to /var/layman/make.conf. >>> import tempfile >>> tmpdir = tempfile.mkdtemp(prefix="laymantmp_") >>> os.path.join(tmpdir, 'make.conf') >>> here = os.path.dirname(os.path.realpath(__file__)) >>> config = {'installed' : ... here + '/tests/testfiles/global-overlays.xml', ... 'make_conf' : here + '/tests/testfiles/make.conf', ... 'nocheck' : True, ... 'storage' : '/var/lib/layman', ... 'quietness':3} >>> c = DB(config) >>> a = ConfigHandler(config, c.overlays) >>> a.path = write >>> a.write() >>> config['make_conf'] = write >>> b = ConfigHandler(config, c.overlays) >>> [i.name for i in b.overlays] ['wrobel-stable'] >>> b.extra ['/usr/local/portage/ebuilds/testing', '/usr/local/portage/ebuilds/stable', '/usr/local/portage/kolab2', '/usr/local/portage/gentoo-webapps-overlay/experimental', '/usr/local/portage/gentoo-webapps-overlay/production-ready'] >>> os.unlink(write) >>> import shutil >>> shutil.rmtree(tmpdir) ''' def prio_sort(a, b): '''Sort by priority.''' if a.priority < b.priority: return -1 elif a.priority > b.priority: return 1 return 0 self.overlays.sort(key=cmp_to_key(prio_sort)) enabled = [] for i in self.overlays: ovl = path([self.storage, i.name]) # We want to enable this overlay: if i.name == enable: if ovl in self.disabled: self.disabled.remove(ovl) enabled.append(ovl) else: msg = 'Overlay "%(repo)s" is already enabled!'\ % ({'repo': i.name}) self.output.error(msg) return False # We want to disable this overlay: elif i.name == disable: if ovl not in self.disabled: self.disabled.append(ovl) else: msg = 'Overlay "%(repo)s" is already disabled!'\ % ({'repo': i.name}) self.output.error(msg) # We want to keep it as-is: else: if ovl not in self.disabled: enabled.append(ovl) self.disabled.sort() enabled_overlays = 'ENABLED="\n' enabled_overlays += '\n'.join(enabled) + '\n' if enabled else '' enabled_overlays += '"' disabled_overlays = 'DISABLED="\n' disabled_overlays += '\n'.join( self.disabled) + '\n' if self.disabled else '' disabled_overlays += '"' overlays = 'PORTDIR_OVERLAY="\n' overlays += '$ENABLED\n' overlays += '$PORTDIR_OVERLAY\n' overlays += '\n'.join(self.extra) overlays += '"' if not re.search('ENABLED=', self.data): self.data = '\n'.join( (enabled_overlays, disabled_overlays, overlays)) enabled_content = self.my_enabled_re.sub(enabled_overlays, self.data) disabled_content = self.my_disabled_re.sub(disabled_overlays, enabled_content) content = self.my_portdir_re.sub(overlays, disabled_content) if not self.my_portdir_re.search(content): self.output.error('MakeConf: ConfigHandler.write(); Oops, failed to set a '\ 'proper PORTDIR_OVERLAY entry in file '\ '%(path)s! Did not overwrite the file.' % ({'path': self.path})) return False try: with fileopen(self.path, 'w') as make_conf: make_conf.write(content) except Exception as error: self.output.error('MakeConf: ConfigHandler.write(); Failed to write "'\ '%(path)s".\nError was:\n%(error)s' % ({'path': self.path, 'error': str(error)})) return False return True
def test(self): repo_name = 'tar_test_overlay' temp_dir_path = tempfile.mkdtemp(prefix='laymantmp_') db_file = os.path.join(temp_dir_path, 'installed.xml') make_conf = os.path.join(temp_dir_path, 'make.conf') repo_conf = os.path.join(temp_dir_path, 'repos.conf') tar_source_path = os.path.join(HERE, 'testfiles', 'layman-test.tar.bz2') (_, temp_tarball_path) = tempfile.mkstemp() shutil.copyfile(tar_source_path, temp_tarball_path) # Write overlay collection XML xml_text = '''\ <?xml version="1.0" encoding="UTF-8"?> <repositories xmlns="" version="1.0"> <repo quality="experimental" status="unofficial"> <name>%(repo_name)s</name> <description>XXXXXXXXXXX</description> <owner> <email>[email protected]</email> </owner> <source type="tar">file://%(temp_tarball_url)s</source> </repo> </repositories> '''\ % { 'temp_tarball_url': urllib.pathname2url(temp_tarball_path), 'repo_name': repo_name } (fd, temp_xml_path) = tempfile.mkstemp() my_opts = {'installed' : temp_xml_path, 'conf_type' : ['make.conf', 'repos.conf'], 'db_type' : 'xml', 'nocheck' : 'yes', 'make_conf' : make_conf, 'repos_conf' : repo_conf, 'storage' : temp_dir_path, 'check_official': False} with os.fdopen(fd, 'w') as f: f.write(xml_text) with fileopen(make_conf, 'w') as f: f.write('PORTDIR_OVERLAY="$PORTDIR_OVERLAY"\n') with fileopen(repo_conf, 'w') as f: f.write('') config = OptionConfig(options=my_opts) config.set_option('quietness', 3) a = DB(config) config.set_option('installed', db_file) # Add an overlay to a fresh DB file. b = DB(config) b.add(a.select(repo_name)) # Make sure it's actually installed. specific_overlay_path = os.path.join(temp_dir_path, repo_name) self.assertTrue(os.path.exists(specific_overlay_path)) # Check the DbBase to ensure that it's reading the installed.xml. c = DbBase(config, paths=[db_file,]) self.assertEqual(list(c.overlays), ['tar_test_overlay']) # Make sure the configs have been written to correctly. conf = RepoConfManager(config, b.overlays) self.assertEqual(list(conf.overlays), ['tar_test_overlay']) # Delete the overlay from the second DB. b.delete(b.select(repo_name)) self.assertEqual(b.overlays, {}) # Ensure the installed.xml has been cleaned properly. c = DbBase(config, paths=[db_file,]) self.assertEqual(c.overlays, {}) conf = RepoConfManager(config, b.overlays) self.assertEqual(conf.overlays, {}) # Clean up. os.unlink(temp_xml_path) os.unlink(temp_tarball_path) shutil.rmtree(temp_dir_path)
def write(self): ''' Write the list of registered overlays to /var/layman/make.conf. >>> import tempfile >>> tmpdir = tempfile.mkdtemp(prefix="laymantmp_") >>> os.path.join(tmpdir, 'make.conf') >>> here = os.path.dirname(os.path.realpath(__file__)) >>> config = {'installed' : ... here + '/tests/testfiles/global-overlays.xml', ... 'make_conf' : here + '/tests/testfiles/make.conf', ... 'nocheck' : True, ... 'storage' : '/var/lib/layman', ... 'quietness':3} >>> c = DB(config) >>> a = ConfigHandler(config, c.overlays) >>> a.path = write >>> a.write() >>> config['make_conf'] = write >>> b = ConfigHandler(config, c.overlays) >>> [i.name for i in b.overlays] ['wrobel-stable'] >>> b.extra ['/usr/local/portage/ebuilds/testing', '/usr/local/portage/ebuilds/stable', '/usr/local/portage/kolab2', '/usr/local/portage/gentoo-webapps-overlay/experimental', '/usr/local/portage/gentoo-webapps-overlay/production-ready'] >>> os.unlink(write) >>> import shutil >>> shutil.rmtree(tmpdir) ''' def prio_sort(a, b): '''Sort by priority.''' if a.priority < b.priority: return -1 elif a.priority > b.priority: return 1 return 0 self.overlays.sort(key=cmp_to_key(prio_sort)) paths = [] for i in self.overlays: paths.append(path((self.storage, i.name, ))) overlays = 'PORTDIR_OVERLAY="\n' overlays += '\n'.join(paths) + '\n' overlays += '$PORTDIR_OVERLAY\n' overlays += '\n'.join(self.extra) overlays += '"' content = self.my_re.sub(overlays, self.data) if not self.my_re.search(content): self.output.error('MakeConf: ConfigHandler.write(); Oops, failed to set a '\ 'proper PORTDIR_OVERLAY entry in file '\ '%(path)s! Did not overwrite the file.' % ({'path': self.path})) return False try: with fileopen(self.path, 'w') as make_conf: make_conf.write(content) except Exception as error: self.output.error('MakeConf: ConfigHandler.write(); Failed to write "'\ '%(path)s".\nError was:\n%(error)s' % ({'path': self.path, 'error': str(error)})) return False return True
def test(self): tmpdir = tempfile.mkdtemp(prefix='laymantmp_') makeconf = os.path.join(tmpdir, 'make.conf') reposconf = os.path.join(tmpdir, 'repos.conf') make_txt =\ 'PORTDIR_OVERLAY="\n'\ '$PORTDIR_OVERLAY"' # Create the .conf files so layman doesn't # complain. with fileopen(makeconf, 'w') as f: f.write(make_txt) with fileopen(reposconf, 'w') as f: f.write('') my_opts = { 'installed' : HERE + '/testfiles/global-overlays.xml', 'make_conf' : makeconf, 'nocheck' : 'yes', 'storage' : tmpdir, 'repos_conf' : reposconf, 'conf_type' : ['make.conf', 'repos.conf'], } config = OptionConfig(my_opts) config.set_option('quietness', 3) a = DB(config) config['output'].set_colorize(False) conf = RepoConfManager(config, a.overlays) # Set up our success tracker. success = [] # Add all the overlays in global_overlays.xml. for overlay in a.overlays.keys(): conf_success = conf.add(a.overlays[overlay]) if False in conf_success: success.append(False) else: success.append(True) # Disable one overlay. conf_success = conf.disable(a.overlays['wrobel']) if False in conf_success: success.append(False) else: success.append(True) # Enable disabled overlay. conf_success = conf.enable(a.overlays['wrobel']) if False in conf_success: success.append(False) else: success.append(True) # Delete all the overlays in global_overlays.xml. for overlay in a.overlays.keys(): conf_success = conf.delete(a.overlays[overlay]) if False in conf_success: success.append(False) else: success.append(True) # Clean up. os.unlink(makeconf) os.unlink(reposconf) shutil.rmtree(tmpdir) if False in success: success = False else: success = True self.assertTrue(success)
def test(self): repo_name = 'tar_test_overlay' temp_dir_path = tempfile.mkdtemp(prefix='laymantmp_') db_file = os.path.join(temp_dir_path, 'installed.xml') make_conf = os.path.join(temp_dir_path, 'make.conf') repo_conf = os.path.join(temp_dir_path, 'repos.conf') tar_source_path = os.path.join(HERE, 'testfiles', 'layman-test.tar.bz2') (_, temp_tarball_path) = tempfile.mkstemp() shutil.copyfile(tar_source_path, temp_tarball_path) # Write overlay collection XML xml_text = '''\ <?xml version="1.0" encoding="UTF-8"?> <repositories xmlns="" version="1.0"> <repo quality="experimental" status="unofficial"> <name>%(repo_name)s</name> <description>XXXXXXXXXXX</description> <owner> <email>[email protected]</email> </owner> <source type="tar">file://%(temp_tarball_url)s</source> </repo> </repositories> '''\ % { 'temp_tarball_url': urllib.pathname2url(temp_tarball_path), 'repo_name': repo_name } (fd, temp_xml_path) = tempfile.mkstemp() my_opts = { 'installed': temp_xml_path, 'conf_type': ['make.conf', 'repos.conf'], 'db_type': 'xml', 'nocheck': 'yes', 'make_conf': make_conf, 'repos_conf': repo_conf, 'storage': temp_dir_path, 'check_official': False } with os.fdopen(fd, 'w') as f: f.write(xml_text) with fileopen(make_conf, 'w') as f: f.write('PORTDIR_OVERLAY="$PORTDIR_OVERLAY"\n') with fileopen(repo_conf, 'w') as f: f.write('') config = OptionConfig(options=my_opts) config.set_option('quietness', 3) a = DB(config) config.set_option('installed', db_file) # Add an overlay to a fresh DB file. b = DB(config) b.add(a.select(repo_name)) # Make sure it's actually installed. specific_overlay_path = os.path.join(temp_dir_path, repo_name) self.assertTrue(os.path.exists(specific_overlay_path)) # Check the DbBase to ensure that it's reading the installed.xml. c = DbBase(config, paths=[ db_file, ]) self.assertEqual(list(c.overlays), ['tar_test_overlay']) # Make sure the configs have been written to correctly. conf = RepoConfManager(config, b.overlays) self.assertEqual(list(conf.overlays), ['tar_test_overlay']) # Delete the overlay from the second DB. b.delete(b.select(repo_name)) self.assertEqual(b.overlays, {}) # Ensure the installed.xml has been cleaned properly. c = DbBase(config, paths=[ db_file, ]) self.assertEqual(c.overlays, {}) conf = RepoConfManager(config, b.overlays) self.assertEqual(conf.overlays, {}) # Clean up. os.unlink(temp_xml_path) os.unlink(temp_tarball_path) shutil.rmtree(temp_dir_path)