[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH 03/10] Add new step repocollect for collectiong repo specificatons.



In this step preceeding repotasksel (repo UI) all non-UI repo requirements
should be collected (from method, ks, driverdisc, /etc/anaconda/repos.d
config).  This used to be done as part of reposetup - partly in configBaseURL
(for method), partly in doConfigSetup (for other repos), we need to move it
before repo UI. Another part of configBaseURL - mounting of nfs, nfsiso, media
was separated so that it can be done in reposetup step for each repo
(RepoSpec.mount() method).

A tricky part here is obtaining specifications of repos from
/etc/anaconda.repos.d for which temporary AnacondaYumBase object is created
in the repocollect step.
---
 pyanaconda/backend.py      |    3 +
 pyanaconda/dispatch.py     |    3 +-
 pyanaconda/installclass.py |    1 +
 pyanaconda/upgrade.py      |    1 +
 pyanaconda/yuminstall.py   |  450 ++++++++++++++++++++-----------------------
 5 files changed, 216 insertions(+), 242 deletions(-)

diff --git a/pyanaconda/backend.py b/pyanaconda/backend.py
index 747252d..f7c9078 100644
--- a/pyanaconda/backend.py
+++ b/pyanaconda/backend.py
@@ -264,6 +264,9 @@ class AnacondaBackend:
 
     def complete(self, anaconda):
         pass
+def doCollectRepos(anaconda):
+    if anaconda.backend.doCollectRepos(anaconda) == DISPATCH_BACK:
+        return DISPATCH_BACK
 
 def doBackendSetup(anaconda):
     if anaconda.backend.doBackendSetup(anaconda) == DISPATCH_BACK:
diff --git a/pyanaconda/dispatch.py b/pyanaconda/dispatch.py
index 94f70f2..ad7e7c4 100644
--- a/pyanaconda/dispatch.py
+++ b/pyanaconda/dispatch.py
@@ -42,7 +42,7 @@ from upgrade import findRootParts, queryUpgradeContinue
 from installmethod import doMethodComplete
 from kickstart import runPostScripts
 
-from backend import doPostSelection, doBackendSetup, doBasePackageSelect
+from backend import doPostSelection, doBackendSetup, doBasePackageSelect, doCollectRepos
 from backend import doPreInstall, doPostInstall, doInstall
 from backend import writeConfiguration
 
@@ -95,6 +95,7 @@ installSteps = [
     ("upgbootloader", ),
     ("bootloadersetup", bootloaderSetupChoices, ),
     ("bootloader", ),
+    ("repocollect", doCollectRepos, ),
     ("repotasksel", ),
     ("reposetup", doBackendSetup, ),
     ("basepkgsel", doBasePackageSelect, ),
diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
index 920c710..5344933 100644
--- a/pyanaconda/installclass.py
+++ b/pyanaconda/installclass.py
@@ -94,6 +94,7 @@ class BaseInstallClass(object):
 		 "network",
 		 "timezone",
 		 "accounts",
+                 "repocollect",
 		 "repotasksel",
                  "reposetup",
                  "basepkgsel",
diff --git a/pyanaconda/upgrade.py b/pyanaconda/upgrade.py
index 1978409..82c0737 100644
--- a/pyanaconda/upgrade.py
+++ b/pyanaconda/upgrade.py
@@ -332,6 +332,7 @@ def setSteps(anaconda):
                 "upgrademigratefs",
                 "enablefilesystems",
                 "upgradecontinue",
+                "repocollect",
                 "reposetup",
                 "upgbootloader",
                 "checkdeps",
diff --git a/pyanaconda/yuminstall.py b/pyanaconda/yuminstall.py
index a7e5385..1fcf7f8 100644
--- a/pyanaconda/yuminstall.py
+++ b/pyanaconda/yuminstall.py
@@ -236,6 +236,100 @@ class YumRepoSpec(RepoSpec):
         self.enabled = yumrepo.enabled
         self.mediaid = yumrepo.mediaid
 
+    def mount(self, ayum):
+        # TODORV: failure handling
+        if self.url.startswith("hd:"):
+            if self.url.count(":") == 2:
+                (device, path) = self.url[3:].split(":")
+            else:
+                (device, fstype, path) = self.url[3:].split(":")
+
+            ayum.isodir = "/mnt/isodir/%s" % path
+
+            # This takes care of mounting /mnt/isodir first.
+            ayum._switchImage(1)
+            ayum.mediagrabber = ayum.mediaHandler
+        elif self.url.startswith("http") or self.url.startswith("ftp:"):
+            self.baseurl = self.url
+        elif self.url.startswith("cdrom:"):
+            # When/if supported (KS, UI), parse device
+            if not self.media_device:
+                cdr = scanForMedia(ayum.tree, ayum.anaconda.storage)
+                if cdr:
+                    self.media_device = cdr
+                    log.info("found installation media on %s" % cdr)
+                else:
+                    ayum.anaconda.intf.messageWindow(_("No Media Found"),
+                                            _("No installation media was found. "
+                                              "Please insert a disc into your drive "
+                                              "and try again."))
+                    self.setup_fail_comment = _("No Media Found")
+                    self.setup = "failed"
+                    return False
+            ayum.anaconda.mediaDevice = self.media_device
+            ayum._switchCD(1)
+            ayum.mediagrabber = ayum.mediaHandler
+            self.baseurl = "file://%s" % ayum.tree
+        elif self.url.startswith("nfs:"):
+            if self.type == "method":
+                dest = ayum.tree
+            else:
+                dest = tempfile.mkdtemp("", self.name.replace(" ", ""), "/mnt")
+
+            (opts, server, path) = iutil.parseNfsUrl(self.url)
+            try:
+                isys.mount(server+":"+path, dest, "nfs", options=opts)
+            except Exception as e:
+                log.error("error mounting NFS repo %s: %s" % (self.name, e))
+                raise
+            self.baseurl = "file://%s" % dest
+
+            # This really should be fixed in loader instead but for now see
+            # if there's images and if so go with this being an NFSISO
+            # install instead.
+            if self.type == "method":
+                images = findIsoImages(ayum.tree, ayum.anaconda.intf.messageWindow)
+                if images != {}:
+                    isys.umount(ayum.tree, removeDir=False)
+                    self.url = "nfsiso:%s" % self.url[4:]
+                    # TODORV - fix properly? SPOT?
+                    # "nfsiso:" case pasted
+                    ayum.isodir = "/mnt/isodir"
+                    ayum._switchImage(1)
+                    ayum.mediagrabber = ayum.mediaHandler
+                    self.baseurl = "file://%s" % ayum.tree
+        elif self.url.startswith("nfsiso:"):
+            ayum.isodir = "/mnt/isodir"
+            ayum._switchImage(1)
+            ayum.mediagrabber = ayum.mediaHandler
+            self.baseurl = "file://%s" % ayum.tree
+        else:
+            log.info("repo %s has unsupported url: %s" % (self.name,
+                                                          self.url))
+        if self.isIsoRepo():
+            self.mediaid = getMediaId(ayum.tree)
+            log.info("set mediaid of repo %s to: %s" % (self.id, self.mediaid))
+
+        return True
+
+    def dirCleanup(self):
+        if not self.yumrepo:
+            return False
+        cachedir = self.yumrepo.getAttribute('cachedir')
+        if os.path.isdir(cachedir):
+            # Remove also cached metadata only for non-network repos
+            # or installation repos or repos that has not been used (enabled).
+            # TODORV: count also addon installation repos in when implemented
+            if (not (self.url.startswith("http") or self.url.startswith("ftp"))
+                or self.type == "method"
+                or not self.enabled):
+                shutil.rmtree(cachedir)
+            else:
+                if os.path.exists("%s/headers" % cachedir):
+                    shutil.rmtree("%s/headers" % cachedir)
+                if os.path.exists("%s/packages" % cachedir):
+                    shutil.rmtree("%s/packages" % cachedir)
+
 def isValidRepoURL(url):
     return (url.startswith("hd:") or
             url.startswith("nfsiso:") or
@@ -464,6 +558,8 @@ class AnacondaYum(YumSorter):
         self.anaconda = anaconda
         self._timestamp = None
 
+        self.readReposFromConfig = False
+
         self.repoIDcounter = itertools.count()
 
         # Only needed for hard drive and nfsiso installs.
@@ -586,117 +682,6 @@ class AnacondaYum(YumSorter):
                                       discImages=self._discImages)
         self.currentMedia = discnum
 
-    def configBaseURL(self):
-        # We only have a methodstr if method= or repo= was passed to
-        # anaconda.  No source for this base repo (the CD media, NFS,
-        # whatever) is mounted yet since loader only mounts the source
-        # for the stage2 image.  We need to set up the source mount
-        # now.
-        if flags.cmdline.has_key("preupgrade"):
-            path = "/var/cache/yum/preupgrade"
-            self.anaconda.methodstr = "hd::%s" % path 
-            self._baseRepoURL = "file:///mnt/sysimage/%s" % path
-        elif self.anaconda.methodstr:
-            m = self.anaconda.methodstr
-
-            if m.startswith("hd:"):
-                if m.count(":") == 2:
-                    (device, path) = m[3:].split(":")
-                else:
-                    (device, fstype, path) = m[3:].split(":")
-
-                self.isodir = "/mnt/isodir/%s" % path
-
-                # This takes care of mounting /mnt/isodir first.
-                self._switchImage(1)
-                self.mediagrabber = self.mediaHandler
-            elif m.startswith("nfsiso:"):
-                self.isodir = "/mnt/isodir"
-
-                # Calling _switchImage takes care of mounting /mnt/isodir first.
-                if not network.hasActiveNetDev():
-                    if not self.anaconda.intf.enableNetwork():
-                        self._baseRepoURL = None
-                        return
-
-                    urlgrabber.grabber.reset_curl_obj()
-
-                self._switchImage(1)
-                self.mediagrabber = self.mediaHandler
-            elif m.startswith("http") or m.startswith("ftp:"):
-                self._baseRepoURL = m
-            elif m.startswith("nfs:"):
-                if not network.hasActiveNetDev():
-                    if not self.anaconda.intf.enableNetwork():
-                        self._baseRepoURL = None
-
-                    urlgrabber.grabber.reset_curl_obj()
-
-                (opts, server, path) = iutil.parseNfsUrl(m)
-                isys.mount(server+":"+path, self.tree, "nfs", options=opts)
-
-                # This really should be fixed in loader instead but for now see
-                # if there's images and if so go with this being an NFSISO
-                # install instead.
-                images = findIsoImages(self.tree, self.anaconda.intf.messageWindow)
-                if images != {}:
-                    isys.umount(self.tree, removeDir=False)
-                    self.anaconda.methodstr = "nfsiso:%s" % m[4:]
-                    self.configBaseURL()
-                    return
-            elif m.startswith("cdrom:"):
-                self._switchCD(1)
-                self.mediagrabber = self.mediaHandler
-                self._baseRepoURL = "file://%s" % self.tree
-        else:
-            # No methodstr was given.  In order to find an installation source,
-            # we should first check to see if there's a CD/DVD with packages
-            # on it, and then default to the mirrorlist URL.  The user can
-            # always change the repo with the repo editor later.
-            cdr = scanForMedia(self.tree, self.anaconda.storage)
-            if cdr:
-                self.mediagrabber = self.mediaHandler
-                self.anaconda.mediaDevice = cdr
-                self.currentMedia = 1
-                log.info("found installation media on %s" % cdr)
-            else:
-                # No CD with media on it and no repo=/method= parameter, so
-                # default to using whatever's enabled in /etc/yum.repos.d/
-                self._baseRepoURL = None
-
-    def configBaseRepo(self, root='/'):
-        # Create the "base" repo object, assuming there is one.  Otherwise we
-        # just skip all this and use the defaults from /etc/yum.repos.d.
-        if not self._baseRepoURL:
-            return
-
-        # add default repos
-        anacondabaseurl = (self.anaconda.methodstr or
-                           "cdrom:%s" % (self.anaconda.mediaDevice))
-        anacondabasepaths = self.anaconda.instClass.getPackagePaths(anacondabaseurl)
-        for (name, uri) in self.anaconda.instClass.getPackagePaths(self._baseRepoURL).items():
-            rid = name.replace(" ", "")
-
-            repo = AnacondaYumRepo("anaconda-%s-%s" % (rid, productStamp))
-            repo.baseurl = uri
-            repo.anacondaBaseURLs = anacondabasepaths[name]
-
-            repo.name = name
-            repo.cost = 100
-
-            if self.anaconda.mediaDevice or self.isodir:
-                repo.mediaid = getMediaId(self.tree)
-                log.info("set mediaid of repo %s to: %s" % (rid, repo.mediaid))
-
-            if self.anaconda.proxy:
-                repo.setProxy(self.anaconda)
-
-            if flags.noverifyssl:
-                repo.sslverify = False
-
-            repo.enable()
-            self.repos.add(repo)
-
     def mediaHandler(self, *args, **kwargs):
         mediaid = kwargs["mediaid"]
         discnum = kwargs["discnum"]
@@ -719,8 +704,8 @@ class AnacondaYum(YumSorter):
                    text=kwargs["text"], range=kwargs["range"], copy_local=1)
         return kwargs["local"]
 
-    # XXX: This is straight out of yum, but we need to override it here in
-    # order to use our own repo class.
+    # We need to have more control (esp. in UI) over using repos from config
+    # At some point, after repo selection, we don't want to add them at all.
     def readRepoConfig(self, parser, section):
         '''Parse an INI file section for a repository.
 
@@ -728,41 +713,10 @@ class AnacondaYum(YumSorter):
         @param section: INI file section to read.
         @return: YumRepository instance.
         '''
-        repo = AnacondaYumRepo(section)
-        repo.populate(parser, section, self.conf)
-
-        # Ensure that the repo name is set
-        if not repo.name:
-            repo.name = section
-            self.logger.error(_('Repository %r is missing name in configuration, '
-                    'using id') % section)
-
-        # Set attributes not from the config file
-        repo.yumvar.update(self.conf.yumvar)
-        repo.cfg = parser
-
-        if "-source" in repo.id or "-debuginfo" in repo.id:
-            name = repo.name
-            del(repo)
-            raise RepoError, "Repo %s contains -source or -debuginfo, excluding" % name
-
-        # this is a little hard-coded, but it's effective
-        if not BETANAG and ("rawhide" in repo.id or "development" in repo.id):
-            name = repo.name
-            del(repo)
-            raise RepoError, "Excluding devel repo %s for non-devel anaconda" % name
-
-        if BETANAG and not repo.enabled:
-            name = repo.name
-            del(repo)
-            raise RepoError, "Excluding disabled repo %s for prerelease" % name
-
-        # If repo=/method= was passed in, we want to default these extra
-        # repos to off.
-        if self._baseRepoURL:
-            repo.enabled = False
-
-        return repo
+        if not self.readReposFromConfig:
+            raise RepoError, "Intentionally ignoring .repo configuration file"
+        else:
+            return super(AnacondaYum,self).readRepoConfig(parser, section)
 
     # We need to make sure $releasever gets set up before .repo files are
     # read.  Since there's no redhat-release package in /mnt/sysimage (and
@@ -827,99 +781,6 @@ class AnacondaYum(YumSorter):
         else:
             YumSorter._getConfig(self, fn=fn, root=root,
                                  enabled_plugins=["whiteout", "blacklist"])
-        self.configBaseRepo(root=root)
-
-        extraRepos = []
-
-        ddArch = os.uname()[4]
-
-        #Add the Driver disc repos to Yum
-        for d in glob.glob(DD_RPMS):
-            dirname = os.path.basename(d)
-            rid = "anaconda-%s" % dirname
-
-            repo = AnacondaYumRepo(rid)
-            repo.baseurl = [ "file://%s" % d ]
-            repo.name = "Driver Disk %s" % dirname.split("-")[1]
-            repo.enable()
-            extraRepos.append(repo)
-
-        if self.anaconda.ksdata:
-            for ksrepo in self.anaconda.ksdata.repo.repoList:
-                anacondaBaseURLs = [ksrepo.baseurl]
-
-                # yum doesn't understand nfs:// and doesn't want to.  We need
-                # to first do the mount, then translate it into a file:// that
-                # yum does understand.
-                # "nfs:" and "nfs://" prefixes are accepted in ks repo --baseurl
-                if ksrepo.baseurl and ksrepo.baseurl.startswith("nfs:"):
-                    if not network.hasActiveNetDev() and not self.anaconda.intf.enableNetwork():
-                        self.anaconda.intf.messageWindow(_("No Network Available"),
-                            _("Some of your software repositories require "
-                              "networking, but there was an error enabling the "
-                              "network on your system."),
-                            type="custom", custom_icon="error",
-                            custom_buttons=[_("_Exit installer")])
-                        sys.exit(1)
-
-                    urlgrabber.grabber.reset_curl_obj()
-
-                    dest = tempfile.mkdtemp("", ksrepo.name.replace(" ", ""), "/mnt")
-
-                    # handle "nfs://" prefix
-                    if ksrepo.baseurl[4:6] == '//':
-                        ksrepo.baseurl = ksrepo.baseurl.replace('//', '', 1)
-                        anacondaBaseURLs = [ksrepo.baseurl]
-                    try:
-                        isys.mount(ksrepo.baseurl[4:], dest, "nfs")
-                    except Exception as e:
-                        log.error("error mounting NFS repo: %s" % e)
-
-                    ksrepo.baseurl = "file://%s" % dest
-
-                repo = AnacondaYumRepo(ksrepo.name)
-                repo.mirrorlist = ksrepo.mirrorlist
-                repo.name = ksrepo.name
-
-                if not ksrepo.baseurl:
-                    repo.baseurl = []
-                else:
-                    repo.baseurl = [ ksrepo.baseurl ]
-                repo.anacondaBaseURLs = anacondaBaseURLs
-
-                if ksrepo.cost:
-                    repo.cost = ksrepo.cost
-
-                if ksrepo.excludepkgs:
-                    repo.exclude = ksrepo.excludepkgs
-
-                if ksrepo.includepkgs:
-                    repo.includepkgs = ksrepo.includepkgs
-
-                if ksrepo.noverifyssl:
-                    repo.sslverify = False
-
-                if ksrepo.proxy:
-                    repo.setProxy(ksrepo)
-
-                repo.enable()
-                extraRepos.append(repo)
-
-        for repo in extraRepos:
-            try:
-                self.repos.add(repo)
-                log.info("added repository %s with URL %s" % (repo.name, repo.mirrorlist or repo.baseurl))
-            except:
-                log.warning("ignoring duplicate repository %s with URL %s" % (repo.name, repo.mirrorlist or repo.baseurl))
-
-        self.repos.setCacheDir(self.conf.cachedir)
-
-        if os.path.exists("%s/boot/upgrade/install.img" % self.anaconda.rootPath):
-            log.info("REMOVING stage2 image from %s /boot/upgrade" % self.anaconda.rootPath )
-            try:
-                os.unlink("%s/boot/upgrade/install.img" % self.anaconda.rootPath)
-            except:
-                log.warning("failed to clean /boot/upgrade")
 
     def downloadHeader(self, po):
         while True:
@@ -1281,6 +1142,113 @@ reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anacon
         # unhappy (#496961)
         iutil.resetRpmDb(anaconda.rootPath)
 
+    def doCollectRepos(self, anaconda):
+        """from methodstr, KS, /etc/yumrepos.d, addon (RHEL)"""
+        if anaconda.dir == DISPATCH_BACK:
+            return DISPATCH_BACK
+
+        anaconda.repos = []
+
+        # base install repo
+        rs = YumRepoSpec()
+
+        # special preupgrade case
+        if flags.cmdline.has_key("preupgrade"):
+            path = "/var/cache/yum/preupgrade"
+            rs.url = "hd::%s" % path
+            rs.baseurl = "file:///mnt/sysimage/%s" % path
+            rs.type = "preupgrade"
+            self.anaconda.repos.append(rs)
+            rs.name = "Preupgrade Repo"
+        else:
+            # method=/repo= - base installation repository
+            m = self.anaconda.methodstr
+            if not m:
+                cdr = scanForMedia(self.tree, self.anaconda.storage)
+                if cdr:
+                    log.info("found installation media on %s" % cdr)
+                    rs.media_device = cdr
+                    m = "cdrom://"
+                else:
+                    m = ""
+            if isValidRepoURL(m):
+                rs.url = m
+                rs.name = "Installation Repo"
+                rs.type = "method"
+                rs.cost = 100
+                rs.enabled = True
+                if self.anaconda.proxy:
+                    rs.setProxy(self.anaconda)
+                if flags.noverifyssl:
+                    rs.sslverify = False
+                self.anaconda.repos.append(rs)
+
+        # DD repos
+        for d in glob.glob(DD_RPMS):
+            rs = YumRepoSpec()
+            dirname = os.path.basename(d)
+            rs.url = "file://%s"
+            rs.name = "Driver Disk %s" % dirname.split("-")[1]
+            rs.type = "driverdisc"
+            rs.enabled = True
+            self.anaconda.repos.append(rs)
+
+        # ks repos
+        if self.anaconda.ksdata:
+            for ksrepo in self.anaconda.ksdata.repo.repoList:
+                rs = YumRepoSpec()
+                baseurl = ksrepo.baseurl or ksrepo.mirrorlist or ""
+                # change "nfs://" prefix to "nfs:"
+                if baseurl.startswith("nfs://"):
+                    baseurl = baseurl.replace('//', '', 1)
+                if isValidRepoURL(baseurl):
+                    rs.url = baseurl
+                    if ksrepo.mirrorlist:
+                        rs.mirrorlist = True
+                    rs.type = "kickstart"
+                    rs.name = ksrepo.name
+                    rs.enabled = True
+                    if ksrepo.excludepkgs:
+                        rs.excludepkgs = ksrepo.excludepkgs
+                    if ksrepo.includepkgs:
+                        rs.includepkgs = ksrepo.includepkgs
+                    if ksrepo.noverifyssl:
+                        rs.sslverify = False
+                    if ksrepo.proxy:
+                        rs.setProxy(ksrepo)
+                else:
+                    log.info("Kickstart repository with invalid url %s ignored"
+                             % baseurl)
+                self.anaconda.repos.append(rs)
+
+        # addon repos (rhel only?)
+
+        # config repos (.repo)
+        ayum = AnacondaYum(anaconda)
+        ayum.readReposFromConfig = True
+        ayum.doConfigSetup()
+        for repo in ayum.repos.repos.values():
+            if "-source" in repo.id or "-debuginfo" in repo.id:
+                log.info("Repo %s contains -source or -debuginfo, excluding" %
+                         repo.name)
+                continue
+            if not BETANAG and ("rawhide" in repo.id or "development" in repo.id):
+                log.info("Excluding devel repo %s for non-devel anaconda" %
+                         repo.name)
+                continue
+            if BETANAG and not repo.enabled:
+                log.info("Excluding disabled repo %s for prerelease" % repo.name)
+                continue
+
+            # If repo=/method= was passed in, we want to default these extra
+            # repos to off.
+            if [rs for rs in self.anaconda.repos if rs.type == "method"]:
+                repo.enabled = False
+            rs = YumRepoSpec(yumrepo=repo)
+            rs.type = "config"
+            self.anaconda.repos.append(rs)
+        ayum.readReposFromConfig = False
+
     def doBackendSetup(self, anaconda):
         if anaconda.dir == DISPATCH_BACK:
             return DISPATCH_BACK
-- 
1.7.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]