diff --git a/bin/is b/bin/is index de3e46fcbd00fa58a68b8039bc7b56b260a7804a..6c451dbdb804dc5eabfb7dd4ece7bc902e036f10 100755 --- a/bin/is +++ b/bin/is @@ -24,12 +24,12 @@ from installsystems.repository import RepositoryConfig from installsystems.image import PackageImage, SourceImage from installsystems.config import MainConfigFile, RepoConfigFile -def load_repositories(args, force_offline=False): +def load_repositories(args): ''' Load repositories on a repository manager ''' # remove cache is asked - if args.no_cache: + if hasattr(args, "no_cache") and args.no_cache: args.cache = None # init repo cache object repoman = RepositoryManager(args.cache, timeout=args.timeout, filter=args.repo_filter) @@ -37,10 +37,14 @@ def load_repositories(args, force_offline=False): # load repo configs from command line if args.repo_path is not None: repoman.register(RepositoryConfig(istools.smd5sum(args.repo_path)[:8], - path=args.repo_path), temp=True, offline=force_offline) + path=args.repo_path), temp=True, + nosync=hasattr(args, "no_sync") and args.no_sync, + offline=hasattr(args, "force_offline") and args.force_offline) # load repo configs from config for repoconf in RepoConfigFile(args.repo_config).repos: - repoman.register(repoconf, offline=force_offline) + repoman.register(repoconf, + nosync=hasattr(args, "no_sync") and args.no_sync, + offline=hasattr(args, "force_offline") and args.force_offline) return repoman def select_image(name, repoman, best=False): @@ -291,7 +295,7 @@ def c_repo(parser, args): ''' Get information about repositories ''' - repoman = load_repositories(args, force_offline=args.local) + repoman = load_repositories(args) for pattern in args.repository: repoman.show_repos(pattern, online=not args.offline, offline=not args.online, url=args.verbose, state=not args.no_state) @@ -503,6 +507,8 @@ p_list.add_argument("-u", "--url", action="store_true", default=False, help="display image url") p_list.add_argument("-D", "--description", action="store_true", default=False, help="display image description") +p_list.add_argument("--no-sync", action="store_true", default=False, + help="doesn't sync repository before listing") p_list.add_argument("image", nargs="*", default=['*'], help="image syntax is [repository/]image[:version]") p_list.set_defaults(func=c_list, subparser=p_list) @@ -533,10 +539,10 @@ p_repo.add_argument("-o", "--online", action="store_true", default=False, help="list only online repository") p_repo.add_argument("-O", "--offline", action="store_true", default=False, help="list only offline repository") -p_repo.add_argument("-l", "--local", action="store_true", default=False, - help="force repository to be offline. This just list repository name without connection") p_repo.add_argument("-S", "--no-state", action="store_true", default=False, help="doesn't display repository state (online/offline)") +p_repo.add_argument("--force-offline", action="store_true", default=False, + help="force repository to be offline") p_repo.add_argument("repository", nargs='*', default=["*"], help="repository pattern") p_repo.set_defaults(func=c_repo) diff --git a/completion/bash/is b/completion/bash/is index 41a80207b9d9bc10f6e5362e95b05f1dbc46e20a..d38d9afbc4de9347f97269cd2f684d70c6b8cdde 100644 --- a/completion/bash/is +++ b/completion/bash/is @@ -2,12 +2,12 @@ # list local repositories _repo() { - COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is --no-color repo -lS)" -- "$cur")) + COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is --no-color repo --no-state --force-offline)" -- "$cur")) } # list all images available in any online repositories _remote_image() { - COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is -q --no-color list)" -- "$cur")) + COMPREPLY=("${COMPREPLY[@]}" $(compgen -W "$(is -q --no-color list --no-sync)" -- "$cur")) } # list all local (files) images @@ -127,7 +127,7 @@ _is() { (( args > 2 )) && _filedir ;; list) - [[ "$cur" == -* ]] && _opt '-h --help -l --long -j --json -m --md5 -s --size -d --date -a --author -u --url -D --description' && return 0 + [[ "$cur" == -* ]] && _opt '-h --help -l --long -j --json -m --md5 -s --size -d --date -a --author -u --url -D --description --no-sync' && return 0 _remote_image ;; move) @@ -139,7 +139,7 @@ _is() { _filedir -d ;; repo) - [[ "$cur" == -* ]] && _opt '-h --help -v --verbose -o --online -O --offline -l --local -S --no-state' && return 0 + [[ "$cur" == -* ]] && _opt '-h --help -v --verbose -o --online -O --offline -S --no-state --force-offline' && return 0 _repo ;; search) diff --git a/installsystems/database.py b/installsystems/database.py index 14286ceee56df166f75f93eff9896faf18f75c1d..5b912774436c5c3a743033d82ba8baa5e5134625 100644 --- a/installsystems/database.py +++ b/installsystems/database.py @@ -19,8 +19,6 @@ class Database(object): It needs to be local cause of sqlite3 which need to open a file ''' - db_format = "1" - @classmethod def create(cls, path): arrow("Creating repository database") @@ -49,6 +47,11 @@ class Database(object): raise Exception("Database not exists") self.conn = sqlite3.connect(self.path, isolation_level=None) self.conn.execute("PRAGMA foreign_keys = ON") + # we make a query to be sure format is valid + try: + self.ask("SELECT * FROM image") + except: + raise Exception("Invalid database format") def begin(self): ''' diff --git a/installsystems/repository.py b/installsystems/repository.py index 9b03981baa59cd76e40aa2f7510a2376add9ba5d..e3ca49bdfacfb9ab92538594047520873ad83c45 100644 --- a/installsystems/repository.py +++ b/installsystems/repository.py @@ -489,10 +489,11 @@ class RepositoryManager(object): return True return False - def register(self, config, temp=False, offline=False): + def register(self, config, temp=False, nosync=False, offline=False): ''' Register a repository from its config temp: repository is stored in a temporary location + nosync: register repository as online, but no sync is done before offline: repository is marked offline ''' # check filter on name @@ -512,14 +513,18 @@ class RepositoryManager(object): # path is remote, we need to create a cache else: debug("Registering cached repository %s (%s)" % (config.path, config.name)) - self.repos.append(self._cachify(config, temp)) + self.repos.append(self._cachify(config, temp, nosync)) - - def _cachify(self, config, temp=False): + def _cachify(self, config, temp=False, nosync=False): ''' Return a config of a cached repository from an orignal config file + :param config: repository configuration + :param temp: repository db should be stored in a temporary location + :param nosync: if a cache exists, don't try to update it ''' try: + if temp and nosync: + raise IOError("unable to cache, sync is disabled") # Ensure destination file exists if temp is True or self.cache_path is None: # this is a forced temporary repository or without name repo @@ -531,34 +536,34 @@ class RepositoryManager(object): # create file if not exists if not os.path.exists(filedest): open(filedest, "wb") - # Open remote database - rdb = PipeFile(config.dbpath, timeout=self.timeout) - # get remote last modification - if rdb.mtime is None: - # We doesn't have modification time, we use the last file - try: - rlast = int(PipeFile(config.lastpath, mode='r', - timeout=self.timeout).read().strip()) - except IOError: - rlast = -1 - else: - rlast = rdb.mtime - # get local last value - llast = int(os.stat(filedest).st_mtime) - # if repo is out of date, download it - if rlast != llast: - arrow("Downloading %s" % config.dbpath) - - rdb.progressbar = True - ldb = open(filedest, "wb") - rdb.consume(ldb) - ldb.close() - rdb.close() - istools.chrights(filedest, - uid=config.uid, - gid=config.gid, - mode=config.fmod, - mtime=rlast) + if not nosync: + # Open remote database + rdb = PipeFile(config.dbpath, timeout=self.timeout) + # get remote last modification + if rdb.mtime is None: + # We doesn't have modification time, we use the last file + try: + rlast = int(PipeFile(config.lastpath, mode='r', + timeout=self.timeout).read().strip()) + except IOError: + rlast = -1 + else: + rlast = rdb.mtime + # get local last value + llast = int(os.stat(filedest).st_mtime) + # if repo is out of date, download it + if rlast != llast: + arrow("Downloading %s" % config.dbpath) + rdb.progressbar = True + ldb = open(filedest, "wb") + rdb.consume(ldb) + ldb.close() + rdb.close() + istools.chrights(filedest, + uid=config.uid, + gid=config.gid, + mode=config.fmod, + mtime=rlast) config.dbpath = filedest except IOError as e: # if something append bad during caching, we mark repo as offline