diff --git a/bin/is b/bin/is index 10d0237a295800ad0f644b97df95b17c0b656f75..6c1dba0e194116f231edc8cd6c750b9e967b6a05 100755 --- a/bin/is +++ b/bin/is @@ -418,6 +418,13 @@ def c_unprepare_chroot(args): ''' istools.unprepare_chroot(args.path, mount=not args.no_umount) +def c_upgrade_db(args): + ''' + Upgrade repository's database to the current database version + ''' + repoman = load_repositories(args) + repoman[args.repository].upgrade_db() + def c_version(args): ''' Display installsystems version @@ -683,6 +690,11 @@ def arg_parser_init(): help="disable unmounting of /{proc,dev,sys}") p.add_argument("path") p.set_defaults(func=c_unprepare_chroot) + # upgrade_db command parser + p = subparser.add_parser("upgrade_db", + help=c_upgrade_db.__doc__.lower()) + p.add_argument("repository", help="repository to upgrade") + p.set_defaults(func=c_upgrade_db) # version command parser p = subparser.add_parser("version", help=c_version.__doc__.lower()) p.set_defaults(func=c_version) diff --git a/completion/bash/is b/completion/bash/is index b96ff4e1696a5995c3065f569428815410bf090f..4d6ad76c4a27252f54200d83a2db909c4e2e3df1 100644 --- a/completion/bash/is +++ b/completion/bash/is @@ -53,7 +53,8 @@ _is() { _get_first_arg cmds=('add' 'build' 'cat' 'changelog' 'check' 'chroot' 'clean' 'copy' 'del' 'extract' 'get' 'help' 'info' 'init' 'install' 'list' 'move' 'new' 'repo' - 'search' 'version' 'diff' 'payload' 'prepare_chroot' 'unprepare_chroot') + 'search' 'version' 'diff' 'payload' 'prepare_chroot' 'unprepare_chroot', + 'upgrade_db') opts=('-h' '--help' '-V' '--version' '-v' '--verbosity' @@ -183,6 +184,11 @@ _is() { [[ "$cur" == -* ]] && _opt '-h --help -m --no-mount' && return 0 _filedir -d ;; + upgrade_db) + [[ "$cur" == -* ]] && _opt '-h --help' && return 0 + _count_args + (( args == 2 )) && _local_repo + ;; version) [[ "$cur" == -* ]] && _opt '-h --help' && return 0 ;; diff --git a/completion/zsh/_installsystems b/completion/zsh/_installsystems index 40a1cb753c666af2d99d78494e470d92f9a5de8b..6792bfcb8d81f2438eac15ac649677c50b1d6758 100644 --- a/completion/zsh/_installsystems +++ b/completion/zsh/_installsystems @@ -308,6 +308,11 @@ _is() { '1:path:_files -/' ) ;; + (upgrade_db) + args+=( + '1:repo:_installsystems_local_repo' + ) + ;; esac _arguments -s -w "$args[@]" && ret=0 else diff --git a/doc/is.1.rst b/doc/is.1.rst index df4468f2737cd48140012bd7e4833ce338dbe705..eb487ad8a57b769c0c83fa27b3f1a0df87461ffa 100644 --- a/doc/is.1.rst +++ b/doc/is.1.rst @@ -325,6 +325,10 @@ unprepare_chroot [-h] [-m] *path* disable unmouting of /{proc,dev,sys} +upgrade_db [-h] *repository* + Upgrade repository's database to the current database version + + version [-h] Print InstallSystems version. diff --git a/installsystems/repository.py b/installsystems/repository.py index 47c9df2a97ca86547d86e6cec5e519699a6676fb..dc815a7e90c723dbec9e472621e4f37868ffa8aa 100644 --- a/installsystems/repository.py +++ b/installsystems/repository.py @@ -155,8 +155,8 @@ class Repository(object): because repository is not initialized ''' config = object.__getattribute__(self, "config") - # config, init, local are always accessible - if name in ("init", "config", "local"): + # config, init, local and upgrade_db are always accessible + if name in ("init", "config", "local", "upgrade_db"): return object.__getattribute__(self, name) # if no db (not init or not accessible) raise error if config.offline: @@ -534,6 +534,57 @@ class Repository(object): (a[0],)).fetchall() return [ a[0] ] + [ x[0] for x in b ] + def upgrade_db(self): + if self.version == Database.version: + info("Database already up-to-date (%s)" % self.version) + return + else: + arrow("Start repository upgrade") + arrowlevel(1) + # Create dummy repository + tmpdir = tempfile.mkdtemp() + try: + repoconf = RepositoryConfig("tmp_migrate_repo", path=tmpdir) + dstrepo = Repository(repoconf) + # Symlink content from repository into dummy repo + for file in os.listdir(self.config.path): + os.symlink(os.path.join(self.config.path, file), + os.path.join(tmpdir, file)) + os.unlink(repoconf.dbpath) + os.unlink(repoconf.lastpath) + old_verbosity = installsystems.verbosity + arrow("Initialize new database") + # Disable unwanted message during upgrade + installsystems.verbosity = 0 + dstrepo.init() + # Restore verbosity + installsystems.verbosity = old_verbosity + md5s = self.db.ask("SELECT md5 FROM image").fetchall() + # Copy images to dummy repository (fill new database) + arrow("Fill database with images") + arrowlevel(1) + installsystems.verbosity = 0 + for img in [PackageImage(os.path.join(self.config.path, md5[0]), + md5name=True) for md5 in md5s]: + installsystems.verbosity = old_verbosity + arrow("%s v%s" % (img.name, img.version)) + installsystems.verbosity = 0 + dstrepo.add(img) + installsystems.verbosity = old_verbosity + arrowlevel(-1) + arrow("Backup old database") + shutil.move(self.config.dbpath, + os.path.join("%s.bak" % self.config.dbpath)) + # Replace old db with the new from dummy repository + shutil.move(repoconf.dbpath, self.config.dbpath) + self.update_last() + arrowlevel(-1) + arrow("Repository upgrade complete") + finally: + # Remove dummy repository + shutil.rmtree(tmpdir) + + class Repository_v1(Repository): def _add(self, image):