Commit fe2df895 authored by Aurélien Dunand's avatar Aurélien Dunand Committed by Sébastien Luttringer
Browse files

Add a command to upgrade old repositories to the current version



The command 'upgrade_db' create a dummy repository (to the current version) and
add each images/payloads from the repository to upgrade. Symlinks are used to
avoid copy. Old database is still available in repository as db.bak.

Signed-off-by: default avatarSébastien Luttringer <sebastien.luttringer@smartjog.com>
parent 857d967c
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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)
+7 −1
Original line number Diff line number Diff line
@@ -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
      ;;
+5 −0
Original line number Diff line number Diff line
@@ -308,6 +308,11 @@ _is() {
                        '1:path:_files -/'
                        )
                        ;;
                     (upgrade_db)
                        args+=(
                        '1:repo:_installsystems_local_repo'
                        )
                        ;;
                esac
                _arguments -s -w "$args[@]" && ret=0
            else
+4 −0
Original line number Diff line number Diff line
@@ -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.

+53 −2
Original line number Diff line number Diff line
@@ -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):