[PATCH 3/3] DNFPayload: pick the right FS as package download target.
Ales Kozumplik
akozumpl at redhat.com
Wed Feb 12 12:28:45 UTC 2014
From: Ales Kozumplik <ales at redhat.com>
---
anaconda.spec.in | 2 +-
pyanaconda/packaging/dnfpayload.py | 68 +++++++++++++++++++++++++++++++++++++-
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/anaconda.spec.in b/anaconda.spec.in
index 2d41c5d..7215e32 100755
--- a/anaconda.spec.in
+++ b/anaconda.spec.in
@@ -23,7 +23,7 @@ Source0: %{name}-%{version}.tar.bz2
%define intltoolver 0.31.2-3
%define pykickstartver 1.99.46
%define yumver 3.4.3-91
-%define dnfver 0.4.8
+%define dnfver 0.4.14
%define partedver 1.8.1
%define pypartedver 2.5-2
%define pythonpyblockver 0.45
diff --git a/pyanaconda/packaging/dnfpayload.py b/pyanaconda/packaging/dnfpayload.py
index 5bcb596..f92478e 100644
--- a/pyanaconda/packaging/dnfpayload.py
+++ b/pyanaconda/packaging/dnfpayload.py
@@ -30,6 +30,7 @@ import logging
import multiprocessing
import pyanaconda.constants as constants
import pyanaconda.errors as errors
+import pyanaconda.iutil
import pyanaconda.packaging as packaging
import sys
import time
@@ -49,6 +50,7 @@ except ImportError as e:
DEFAULT_REPOS = [constants.productName.lower(), "rawhide"]
DNF_CACHE_DIR = '/tmp/dnf.cache'
+DNF_PACKAGE_CACHE_DIR_SUFFIX = 'dnf.package.cache'
REPO_DIRS = ['/etc/yum.repos.d',
'/etc/anaconda.repos.d',
'/tmp/updates/anaconda.repos.d',
@@ -59,6 +61,46 @@ def _failure_limbo():
while True:
time.sleep(10000)
+def _df_map():
+ """Return (mountpoint -> size available) mapping."""
+ output = pyanaconda.iutil.execWithCapture('df', ['--output=target,avail'])
+ output = output.rstrip()
+ lines = output.split('\n')
+ structured = {}
+ for line in lines:
+ items = line.split()
+ key = items[0]
+ val = items[1]
+ if not key.startswith('/'):
+ continue
+ structured[key] = Size(bytes=int(val)*1024)
+ return structured
+
+def _pick_mpoint(df, requested):
+ def reasonable_mpoint(mpoint):
+ return mpoint in ['/tmp',
+ '/',
+ '/mnt/sysimage',
+ '/mnt/sysimage/home',
+ '/mnt/sysimage/tmp',
+ '/mnt/sysimage/var',
+ ]
+
+ # reserve extra
+ requested = requested + Size(en_spec="150 MB")
+ sufficients = {key : val for (key,val) in df.items() if val > requested
+ and reasonable_mpoint(key)}
+ log.info('Sufficient mountpoints found: %s' % sufficients)
+
+ # prefer /tmp:
+ if '/tmp' in sufficients:
+ return '/tmp'
+ if not len(sufficients):
+ return None
+ # default to the biggest one:
+ return sorted(sufficients.iteritems(), key=operator.itemgetter(1),
+ reverse=True)[0][0]
+
class PayloadRPMDisplay(dnf.output.LoggingTransactionDisplay):
def __init__(self, queue):
super(PayloadRPMDisplay, self).__init__()
@@ -163,6 +205,15 @@ class DNFPayload(packaging.PackagePayload):
conf.reposdir = REPO_DIRS
+ @property
+ def _download_space(self):
+ transaction = self._base.transaction
+ if transaction is None:
+ return Size(0)
+
+ size = sum(tsi.installed.downloadsize for tsi in transaction)
+ return Size(size)
+
def _install_package(self, pkg_name):
try:
return self._base.install(pkg_name)
@@ -182,6 +233,20 @@ class DNFPayload(packaging.PackagePayload):
progressQ.send_quit(1)
sys.exit(1)
+ def _pick_download_location(self):
+ required = self._download_space
+ df_map = _df_map()
+ mpoint = _pick_mpoint(df_map, required)
+ log.info("Download space required: %s, use filesystem at: %s", required,
+ mpoint)
+ if mpoint is None:
+ msg = "Not enough disk space to download the packages."
+ raise packaging.PayloadError(msg)
+
+ pkgdir = '%s/%s' % (mpoint, DNF_PACKAGE_CACHE_DIR_SUFFIX)
+ for repo in self._base.repos.iter_enabled():
+ repo.pkgdir = pkgdir
+
def _select_group(self, group_id, default=True, optional=False):
grp = self._base.comps.group_by_pattern(group_id)
if grp is None:
@@ -345,7 +410,8 @@ class DNFPayload(packaging.PackagePayload):
self._setupMedia(self.install_device)
try:
self.checkSoftwareSelection()
- except packaging.DependencyError as e:
+ self._pick_download_location()
+ except packaging.PayloadError as e:
if errors.errorHandler.cb(e) == errors.ERROR_RAISE:
_failure_limbo()
--
1.8.5.3
More information about the anaconda-patches
mailing list