Loading bin/is +59 −23 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ from installsystems.repository import RepositoryConfig from installsystems.image import PackageImage, SourceImage from installsystems.config import MainConfigFile, RepoConfigFile ################################################################################ # Common functions ################################################################################ def load_repositories(args): ''' Load repositories on a repository manager Loading @@ -31,6 +35,10 @@ def load_repositories(args): # remove cache is asked if hasattr(args, "no_cache") and args.no_cache: args.cache = None # split filter in list if args.repo_filter is not None: args.repo_filter = [f for f in re.split("[ ,\n\t\v]+", args.repo_filter) if f != ""] # init repo cache object repoman = RepositoryManager(args.cache, timeout=args.timeout, filter=args.repo_filter) # register repositories (order matter) Loading @@ -56,19 +64,37 @@ def select_image(name, repoman, best=False): Return the repository as second argument ''' # image is a local file if istools.isfile(name) and os.path.isfile(name): return PackageImage(name), None # we need to find image in a repository else: x = re.match("^(([-_\w]+)/)?([-_\w]+)(:v?(\d+))?$", name) if x is None: raise Exception("%s is not a valid image" % name) (repo, image, version) = x.group(2,3,5) debug("Selected image is %s v%s in %s" % (image, version, repo)) if len(repoman.onlines) == 0: raise Exception('No online repository') (repo, image, version) = istools.split_image_path(name) debug("Requested image: %s v%s in %s" % (image, version, repo)) # repo is not specified, we need to crawl in path if repo is None: return repoman.get(image, version, best) # split search path as a list if args.repo_search is not None: args.repo_search = [s for s in re.split("[ ,\n\t\v]+", args.repo_search) if s in repoman.onlines] else: args.repo_search = [] # if we have only one repo, search in it if len(args.repo_search) == 0 and len(repoman.onlines) == 1: args.repo_search = repoman.onlines elif len(args.repo_search) == 0 and len(repoman.onlines) > 1: raise Exception('You must use a full image path or set a valid search path') return repoman.get(image, version, search=args.repo_search, best=best) # we can ask directly repository about image else: return repoman[repo].get(image, version), repoman[repo] ################################################################################ # Commands functions ################################################################################ def c_add(parser, args): ''' Add an image package into a repository Loading Loading @@ -328,6 +354,10 @@ def c_version(parser, args): ''' out(installsystems.version) ################################################################################ # Parser definition ################################################################################ # Top level argument parsing p_main = argparse.ArgumentParser() p_main.add_argument("-V", "--version", action="version", Loading @@ -340,22 +370,24 @@ ex_group.add_argument("-d", "--debug", action="store_true", default=None, ex_group.add_argument("-q", "--quiet", action="store_true", default=None, help="active quiet mode") # common options p_main.add_argument("-c", "--config", default="installsystems", p_main.add_argument("-c", "--config", default="installsystems", metavar="PATH", help="config file path") p_main.add_argument("-R", "--repo-config", default="repository", p_main.add_argument("-R", "--repo-config", default="repository", metavar="REPO", help="repository config file path") p_main.add_argument("-f", "--repo-filter", default=None, help="select repository by name in config files") p_main.add_argument("-r", "--repo-path", default=None, help="repository path") p_main.add_argument("-C", "--cache", default=None, p_main.add_argument("-s", "--repo-search", metavar="REPO,REPO,...", help="search for images inside those repositories") p_main.add_argument("-f", "--repo-filter", metavar="REPO,REPO,...", help="filter repositories by name") p_main.add_argument("-r", "--repo-path", metavar="PATH", help="define a temporary repository") p_main.add_argument("-C", "--cache", metavar="PATH", help="path of the repository cache") p_main.add_argument("--no-cache", action="store_true", default=None, help="not use persistent db caching") p_main.add_argument("--no-color", action="store_true", default=None, help="dot not display colored output") p_main.add_argument("-t", "--timeout", dest="timeout", type=int, default=None, help="download timeout (default 3)") metavar="SECONDS", help="download timeout (default 3)") # create a subparsers for each command subparsers = p_main.add_subparsers() Loading @@ -382,7 +414,7 @@ p_build.set_defaults(func=c_build) # cat command parser p_cat = subparsers.add_parser("cat", help=c_cat.__doc__.lower()) p_cat.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_cat.add_argument("image", help="<path|[repository/]image[:version]>") p_cat.add_argument("file", nargs="+", help="file inside image to cat (globbing allowed)") Loading @@ -391,7 +423,7 @@ p_cat.set_defaults(func=c_cat) # changelog command parser p_changelog = subparsers.add_parser("changelog", help=c_changelog.__doc__.lower()) p_changelog.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_changelog.add_argument("-v", "--all-version", action="store_true", default=False, help="display changelog for all versions") p_changelog.add_argument("image", help="<path|[repository/]image[:version]>") Loading Loading @@ -419,7 +451,7 @@ p_clean.set_defaults(func=c_clean) # copy command parser p_copy = subparsers.add_parser("copy", help=c_copy.__doc__.lower()) p_copy.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_copy.add_argument("image", nargs="+", help="image syntax is <path|[repository/]image[:version]>") p_copy.add_argument("repository", help="destination repository") Loading @@ -430,7 +462,7 @@ p_del = subparsers.add_parser("del", help=c_del.__doc__.lower()) p_del.add_argument("image", nargs="+", help="image syntax is <path|[repository/]image[:version]>") p_del.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_del.add_argument("-f", "--force", action="store_true", default=False, help="delete image without confirmation") p_del.add_argument("-p", "--preserve", action="store_true", default=False, Loading @@ -442,13 +474,13 @@ p_diff = subparsers.add_parser("diff", help=c_diff.__doc__.lower()) p_diff.add_argument("object", nargs=2, help="object syntax is <path|repository|[repository/]image[:version]>") p_diff.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_diff.set_defaults(func=c_diff) # extract command parser p_extract = subparsers.add_parser("extract", help=c_extract.__doc__.lower()) p_extract.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_extract.add_argument("-f", "--force", action="store_true", default=False, help="overwrite existing destinations") p_extract.add_argument("-g", "--gen-description", action="store_true", default=False, Loading @@ -463,7 +495,7 @@ p_extract.set_defaults(func=c_extract) # get command parser p_get = subparsers.add_parser("get", help=c_get.__doc__.lower()) p_get.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_get.add_argument("-f", "--force", action="store_true", default=False, help="overwrite existing destinations") p_get.add_argument("-I", "--no-image", action="store_true", default=False, Loading @@ -482,7 +514,7 @@ p_help.set_defaults(func=c_help, subparser=subparsers) # info command parser p_info = subparsers.add_parser("info", help=c_info.__doc__.lower()) p_info.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_info.add_argument("-c", "--changelog", action="store_true", default=False, help="display image changelog") p_info.add_argument("-v", "--verbose", action="store_true", default=False, Loading Loading @@ -535,7 +567,7 @@ p_list.set_defaults(func=c_list) # move command parser p_move = subparsers.add_parser("move", help=c_move.__doc__.lower()) p_move.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_move.add_argument("-f", "--force", action="store_true", default=False, help="move image without confirmation") p_move.add_argument("image", nargs="+", Loading Loading @@ -594,6 +626,10 @@ p_unprepare_chroot.set_defaults(func=c_unprepare_chroot) p_version = subparsers.add_parser("version", help=c_version.__doc__.lower()) p_version.set_defaults(func=c_version) ################################################################################ # Main ################################################################################ try: # first (partial) parsing args = p_main.parse_known_args()[0] Loading installsystems/config.py +13 −4 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ class MainConfigFile(ConfigFile): Program configuration file ''' valid_options = ("debug", "quiet", "no_cache", "no_color", "timeout", "cache", "repo_search", "repo_filter", "repo_config") def __init__(self, filename, prefix=os.path.basename(sys.argv[0])): self.prefix = prefix ConfigFile.__init__(self, filename) Loading Loading @@ -81,8 +83,14 @@ class MainConfigFile(ConfigFile): Merge current loaded option with a namespace from argparse ''' for option, value in self._config.items(): # check option is valid if option not in self.valid_options: warn("Invalid option %s in %s, skipped" % (option, self.path)) continue # no option is specified in command line, set it if not hasattr(namespace, option): setattr(namespace, option, value) # handle by default none options elif getattr(namespace, option) == None: # we need to handle boolean differently if option in ("debug", "quiet", "no_cache", "no_color"): Loading @@ -94,11 +102,12 @@ class MainConfigFile(ConfigFile): except ValueError: raise Exception("Invalid %s: Not a number" % option) setattr(namespace, option, n) # we can handle string more carefuly elif option in ("cache", "repo_filter", "repo_config"): # handle strings elif option in ("cache", "repo_search", "repo_filter"): setattr(namespace, option, value) # repo_config is a special parameter, default value is repository elif option == "repo_config" and option.repo_config == "repository": setattr(namespace, option, value) else: warn("Invalid option %s in %s, skipped" % (option, self.path)) def _cache_paths(self): ''' Loading installsystems/repository.py +20 −17 Original line number Diff line number Diff line Loading @@ -391,7 +391,8 @@ class Repository(object): r = self.db.ask("select md5 from image where name = ? and version = ? limit 1", (name, version)).fetchone() if r is None: raise Exception("Unable to find image %s v%s" % (name, version)) raise Exception("Unable to find image %s v%s in %s" % (name, version, self.config.name)) path = os.path.join(self.config.path, r[0]) # getting the file arrow("Loading image %s v%s from repository %s" % (name, Loading Loading @@ -436,7 +437,7 @@ class RepositoryManager(object): self.timeout = 3 if timeout is None else timeout self.repos = [] self.tempfiles = [] self.filter = filter self.filter = [] if filter is None else filter if cache_path is None: self.cache_path = None debug("No repository cache") Loading Loading @@ -500,8 +501,9 @@ class RepositoryManager(object): offline: repository is marked offline ''' # check filter on name if self.filter is not None: if not fnmatch.fnmatch(config.name, self.filter): if len(self.filter) > 0: if config.name not in self.filter: debug("Filtering repository %s" % config.name) return # repository is offline if config.offline or offline: Loading Loading @@ -622,19 +624,20 @@ class RepositoryManager(object): del images["%s/%s:%s" % (repo, img, rmv)] return images def get(self, name, version=None, best=False): def get(self, name, version=None, search=None, best=False): ''' Crawl repositories to get an image Crawl searchable repositories to get an image best mode search the most recent version accross all repo else it search the first match ''' if search is None: search = [] # search last version if needed if version is None: version = -1 for repo in self.repos: if repo.config.offline: continue current = repo.last(name) for repo in search: current = self[repo].last(name) # if not best mode, we found our version if not best and current > 0: version = current Loading @@ -642,13 +645,14 @@ class RepositoryManager(object): version = max(version, current) # if version < 0, il n'y a pas d'image if version < 0: raise Exception("Unable to find image %s" % name) raise Exception("Unable to find image %s in %s" % ( name, search)) # search image in repos for repo in self.repos: if repo.config.offline: continue if repo.has(name, version): return repo.get(name, version), repo raise Exception("Unable to find image %s v%s" % (name, version)) for repo in search: if self[repo].has(name, version): return self[repo].get(name, version), repo raise Exception("No image %s v%s in %s" % ( name, version, search)) def show_repos(self, pattern, local=None, online=None, url=False, state=True): ''' Loading Loading @@ -722,8 +726,7 @@ class RepositoryManager(object): ''' Search pattern accross all registered repositories ''' for repo in self.repos: if repo.config.offline: continue for repo in self.onlines: arrow(repo.config.name) repo.search(pattern) Loading installsystems/tools.py +10 −0 Original line number Diff line number Diff line Loading @@ -493,3 +493,13 @@ def compare_versions(v1, v2): fv1 = get_ver(v1) fv2 = get_ver(v2) return fv1 - fv2 def split_image_path(path): ''' Split an image path (repo/image:version) in a tuple (repo, image, version) ''' x = re.match(u"^(?:([-_\w]+)/)?([-_\w]+)(?::v?(\d+))?$", path) if x is None: raise Exception("invalid image path: %s" % path) return x.group(1,2,3) samples/installsystems.conf +5 −2 Original line number Diff line number Diff line Loading @@ -23,8 +23,11 @@ # define connection timeout #timeout = 30 # default repository name #repo_filter = local # search images inside repositories #repo_search = stable testing # filter repository list #repo_filter = stable testing # custom repository config file #repo_config = Loading
bin/is +59 −23 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ from installsystems.repository import RepositoryConfig from installsystems.image import PackageImage, SourceImage from installsystems.config import MainConfigFile, RepoConfigFile ################################################################################ # Common functions ################################################################################ def load_repositories(args): ''' Load repositories on a repository manager Loading @@ -31,6 +35,10 @@ def load_repositories(args): # remove cache is asked if hasattr(args, "no_cache") and args.no_cache: args.cache = None # split filter in list if args.repo_filter is not None: args.repo_filter = [f for f in re.split("[ ,\n\t\v]+", args.repo_filter) if f != ""] # init repo cache object repoman = RepositoryManager(args.cache, timeout=args.timeout, filter=args.repo_filter) # register repositories (order matter) Loading @@ -56,19 +64,37 @@ def select_image(name, repoman, best=False): Return the repository as second argument ''' # image is a local file if istools.isfile(name) and os.path.isfile(name): return PackageImage(name), None # we need to find image in a repository else: x = re.match("^(([-_\w]+)/)?([-_\w]+)(:v?(\d+))?$", name) if x is None: raise Exception("%s is not a valid image" % name) (repo, image, version) = x.group(2,3,5) debug("Selected image is %s v%s in %s" % (image, version, repo)) if len(repoman.onlines) == 0: raise Exception('No online repository') (repo, image, version) = istools.split_image_path(name) debug("Requested image: %s v%s in %s" % (image, version, repo)) # repo is not specified, we need to crawl in path if repo is None: return repoman.get(image, version, best) # split search path as a list if args.repo_search is not None: args.repo_search = [s for s in re.split("[ ,\n\t\v]+", args.repo_search) if s in repoman.onlines] else: args.repo_search = [] # if we have only one repo, search in it if len(args.repo_search) == 0 and len(repoman.onlines) == 1: args.repo_search = repoman.onlines elif len(args.repo_search) == 0 and len(repoman.onlines) > 1: raise Exception('You must use a full image path or set a valid search path') return repoman.get(image, version, search=args.repo_search, best=best) # we can ask directly repository about image else: return repoman[repo].get(image, version), repoman[repo] ################################################################################ # Commands functions ################################################################################ def c_add(parser, args): ''' Add an image package into a repository Loading Loading @@ -328,6 +354,10 @@ def c_version(parser, args): ''' out(installsystems.version) ################################################################################ # Parser definition ################################################################################ # Top level argument parsing p_main = argparse.ArgumentParser() p_main.add_argument("-V", "--version", action="version", Loading @@ -340,22 +370,24 @@ ex_group.add_argument("-d", "--debug", action="store_true", default=None, ex_group.add_argument("-q", "--quiet", action="store_true", default=None, help="active quiet mode") # common options p_main.add_argument("-c", "--config", default="installsystems", p_main.add_argument("-c", "--config", default="installsystems", metavar="PATH", help="config file path") p_main.add_argument("-R", "--repo-config", default="repository", p_main.add_argument("-R", "--repo-config", default="repository", metavar="REPO", help="repository config file path") p_main.add_argument("-f", "--repo-filter", default=None, help="select repository by name in config files") p_main.add_argument("-r", "--repo-path", default=None, help="repository path") p_main.add_argument("-C", "--cache", default=None, p_main.add_argument("-s", "--repo-search", metavar="REPO,REPO,...", help="search for images inside those repositories") p_main.add_argument("-f", "--repo-filter", metavar="REPO,REPO,...", help="filter repositories by name") p_main.add_argument("-r", "--repo-path", metavar="PATH", help="define a temporary repository") p_main.add_argument("-C", "--cache", metavar="PATH", help="path of the repository cache") p_main.add_argument("--no-cache", action="store_true", default=None, help="not use persistent db caching") p_main.add_argument("--no-color", action="store_true", default=None, help="dot not display colored output") p_main.add_argument("-t", "--timeout", dest="timeout", type=int, default=None, help="download timeout (default 3)") metavar="SECONDS", help="download timeout (default 3)") # create a subparsers for each command subparsers = p_main.add_subparsers() Loading @@ -382,7 +414,7 @@ p_build.set_defaults(func=c_build) # cat command parser p_cat = subparsers.add_parser("cat", help=c_cat.__doc__.lower()) p_cat.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_cat.add_argument("image", help="<path|[repository/]image[:version]>") p_cat.add_argument("file", nargs="+", help="file inside image to cat (globbing allowed)") Loading @@ -391,7 +423,7 @@ p_cat.set_defaults(func=c_cat) # changelog command parser p_changelog = subparsers.add_parser("changelog", help=c_changelog.__doc__.lower()) p_changelog.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_changelog.add_argument("-v", "--all-version", action="store_true", default=False, help="display changelog for all versions") p_changelog.add_argument("image", help="<path|[repository/]image[:version]>") Loading Loading @@ -419,7 +451,7 @@ p_clean.set_defaults(func=c_clean) # copy command parser p_copy = subparsers.add_parser("copy", help=c_copy.__doc__.lower()) p_copy.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_copy.add_argument("image", nargs="+", help="image syntax is <path|[repository/]image[:version]>") p_copy.add_argument("repository", help="destination repository") Loading @@ -430,7 +462,7 @@ p_del = subparsers.add_parser("del", help=c_del.__doc__.lower()) p_del.add_argument("image", nargs="+", help="image syntax is <path|[repository/]image[:version]>") p_del.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_del.add_argument("-f", "--force", action="store_true", default=False, help="delete image without confirmation") p_del.add_argument("-p", "--preserve", action="store_true", default=False, Loading @@ -442,13 +474,13 @@ p_diff = subparsers.add_parser("diff", help=c_diff.__doc__.lower()) p_diff.add_argument("object", nargs=2, help="object syntax is <path|repository|[repository/]image[:version]>") p_diff.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_diff.set_defaults(func=c_diff) # extract command parser p_extract = subparsers.add_parser("extract", help=c_extract.__doc__.lower()) p_extract.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_extract.add_argument("-f", "--force", action="store_true", default=False, help="overwrite existing destinations") p_extract.add_argument("-g", "--gen-description", action="store_true", default=False, Loading @@ -463,7 +495,7 @@ p_extract.set_defaults(func=c_extract) # get command parser p_get = subparsers.add_parser("get", help=c_get.__doc__.lower()) p_get.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_get.add_argument("-f", "--force", action="store_true", default=False, help="overwrite existing destinations") p_get.add_argument("-I", "--no-image", action="store_true", default=False, Loading @@ -482,7 +514,7 @@ p_help.set_defaults(func=c_help, subparser=subparsers) # info command parser p_info = subparsers.add_parser("info", help=c_info.__doc__.lower()) p_info.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_info.add_argument("-c", "--changelog", action="store_true", default=False, help="display image changelog") p_info.add_argument("-v", "--verbose", action="store_true", default=False, Loading Loading @@ -535,7 +567,7 @@ p_list.set_defaults(func=c_list) # move command parser p_move = subparsers.add_parser("move", help=c_move.__doc__.lower()) p_move.add_argument("-b", "--best", action="store_true", default=False, help="in best mode, image is the most recent in all repositories") help="take the most recent image in all searchable repositories") p_move.add_argument("-f", "--force", action="store_true", default=False, help="move image without confirmation") p_move.add_argument("image", nargs="+", Loading Loading @@ -594,6 +626,10 @@ p_unprepare_chroot.set_defaults(func=c_unprepare_chroot) p_version = subparsers.add_parser("version", help=c_version.__doc__.lower()) p_version.set_defaults(func=c_version) ################################################################################ # Main ################################################################################ try: # first (partial) parsing args = p_main.parse_known_args()[0] Loading
installsystems/config.py +13 −4 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ class MainConfigFile(ConfigFile): Program configuration file ''' valid_options = ("debug", "quiet", "no_cache", "no_color", "timeout", "cache", "repo_search", "repo_filter", "repo_config") def __init__(self, filename, prefix=os.path.basename(sys.argv[0])): self.prefix = prefix ConfigFile.__init__(self, filename) Loading Loading @@ -81,8 +83,14 @@ class MainConfigFile(ConfigFile): Merge current loaded option with a namespace from argparse ''' for option, value in self._config.items(): # check option is valid if option not in self.valid_options: warn("Invalid option %s in %s, skipped" % (option, self.path)) continue # no option is specified in command line, set it if not hasattr(namespace, option): setattr(namespace, option, value) # handle by default none options elif getattr(namespace, option) == None: # we need to handle boolean differently if option in ("debug", "quiet", "no_cache", "no_color"): Loading @@ -94,11 +102,12 @@ class MainConfigFile(ConfigFile): except ValueError: raise Exception("Invalid %s: Not a number" % option) setattr(namespace, option, n) # we can handle string more carefuly elif option in ("cache", "repo_filter", "repo_config"): # handle strings elif option in ("cache", "repo_search", "repo_filter"): setattr(namespace, option, value) # repo_config is a special parameter, default value is repository elif option == "repo_config" and option.repo_config == "repository": setattr(namespace, option, value) else: warn("Invalid option %s in %s, skipped" % (option, self.path)) def _cache_paths(self): ''' Loading
installsystems/repository.py +20 −17 Original line number Diff line number Diff line Loading @@ -391,7 +391,8 @@ class Repository(object): r = self.db.ask("select md5 from image where name = ? and version = ? limit 1", (name, version)).fetchone() if r is None: raise Exception("Unable to find image %s v%s" % (name, version)) raise Exception("Unable to find image %s v%s in %s" % (name, version, self.config.name)) path = os.path.join(self.config.path, r[0]) # getting the file arrow("Loading image %s v%s from repository %s" % (name, Loading Loading @@ -436,7 +437,7 @@ class RepositoryManager(object): self.timeout = 3 if timeout is None else timeout self.repos = [] self.tempfiles = [] self.filter = filter self.filter = [] if filter is None else filter if cache_path is None: self.cache_path = None debug("No repository cache") Loading Loading @@ -500,8 +501,9 @@ class RepositoryManager(object): offline: repository is marked offline ''' # check filter on name if self.filter is not None: if not fnmatch.fnmatch(config.name, self.filter): if len(self.filter) > 0: if config.name not in self.filter: debug("Filtering repository %s" % config.name) return # repository is offline if config.offline or offline: Loading Loading @@ -622,19 +624,20 @@ class RepositoryManager(object): del images["%s/%s:%s" % (repo, img, rmv)] return images def get(self, name, version=None, best=False): def get(self, name, version=None, search=None, best=False): ''' Crawl repositories to get an image Crawl searchable repositories to get an image best mode search the most recent version accross all repo else it search the first match ''' if search is None: search = [] # search last version if needed if version is None: version = -1 for repo in self.repos: if repo.config.offline: continue current = repo.last(name) for repo in search: current = self[repo].last(name) # if not best mode, we found our version if not best and current > 0: version = current Loading @@ -642,13 +645,14 @@ class RepositoryManager(object): version = max(version, current) # if version < 0, il n'y a pas d'image if version < 0: raise Exception("Unable to find image %s" % name) raise Exception("Unable to find image %s in %s" % ( name, search)) # search image in repos for repo in self.repos: if repo.config.offline: continue if repo.has(name, version): return repo.get(name, version), repo raise Exception("Unable to find image %s v%s" % (name, version)) for repo in search: if self[repo].has(name, version): return self[repo].get(name, version), repo raise Exception("No image %s v%s in %s" % ( name, version, search)) def show_repos(self, pattern, local=None, online=None, url=False, state=True): ''' Loading Loading @@ -722,8 +726,7 @@ class RepositoryManager(object): ''' Search pattern accross all registered repositories ''' for repo in self.repos: if repo.config.offline: continue for repo in self.onlines: arrow(repo.config.name) repo.search(pattern) Loading
installsystems/tools.py +10 −0 Original line number Diff line number Diff line Loading @@ -493,3 +493,13 @@ def compare_versions(v1, v2): fv1 = get_ver(v1) fv2 = get_ver(v2) return fv1 - fv2 def split_image_path(path): ''' Split an image path (repo/image:version) in a tuple (repo, image, version) ''' x = re.match(u"^(?:([-_\w]+)/)?([-_\w]+)(?::v?(\d+))?$", path) if x is None: raise Exception("invalid image path: %s" % path) return x.group(1,2,3)
samples/installsystems.conf +5 −2 Original line number Diff line number Diff line Loading @@ -23,8 +23,11 @@ # define connection timeout #timeout = 30 # default repository name #repo_filter = local # search images inside repositories #repo_search = stable testing # filter repository list #repo_filter = stable testing # custom repository config file #repo_config =