Anaconda must compute size for downloaded and installed packages when testing free space for installed root. Also use only 90% of disk capacity for required space compare.
*Resolves: rhbz#1224048*
Added label: f23-branch.
From: Jiri Konecny jkonecny@redhat.com
Anaconda must compute size for downloaded and installed packages when testing free space for installed root.
Resolves: rhbz#1224048 --- pyanaconda/packaging/dnfpayload.py | 44 ++++++++++++++++++++++++++++++-------- pyanaconda/ui/lib/space.py | 4 ++-- 2 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/pyanaconda/packaging/dnfpayload.py b/pyanaconda/packaging/dnfpayload.py index ed83d50..e645205 100644 --- a/pyanaconda/packaging/dnfpayload.py +++ b/pyanaconda/packaging/dnfpayload.py @@ -58,6 +58,7 @@ DNF_CACHE_DIR = '/tmp/dnf.cache' DNF_PLUGINCONF_DIR = '/tmp/dnf.pluginconf' DNF_PACKAGE_CACHE_DIR_SUFFIX = 'dnf.package.cache' +INSTALL_ROOT_MPOINT = '/mnt/sysimage' DOWNLOAD_MPOINTS = {'/tmp', '/', '/mnt/sysimage', @@ -104,14 +105,19 @@ def paced_fn(self, *args): return fn(self, *args) return paced_fn
-def _pick_mpoint(df, requested): +def _pick_mpoint(df, download_size, install_size): def reasonable_mpoint(mpoint): return mpoint in DOWNLOAD_MPOINTS
# reserve extra - requested = requested + Size("150 MB") - sufficients = {key : val for (key, val) in df.items() if val > requested - and reasonable_mpoint(key)} + requested = download_size + requested_root = requested + install_size + sufficients = {key : val for (key, val) in df.items() + # for root we need to take in count both download and install size + if ((key != INSTALL_ROOT_MPOINT and val > requested) + or val > requested_root) and reasonable_mpoint(key)} + log.debug('Estimated size: download %s & install %s - df: %s', requested, + (requested_root - requested), df) log.info('Sufficient mountpoints found: %s', sufficients)
if not len(sufficients): @@ -423,7 +429,7 @@ def _download_space(self): return Size(0)
size = sum(tsi.installed.downloadsize for tsi in transaction) - return Size(size) + return Size(size) + Size("150 MB")
def _install_package(self, pkg_name, required=False): try: @@ -446,11 +452,10 @@ def _miss(self, exn): sys.exit(1)
def _pick_download_location(self): - required = self._download_space + download_size = self._download_space + install_size = self._spaceRequired() df_map = _df_map() - mpoint = _pick_mpoint(df_map, required) - log.info("Download space required: %s, use filesystem at: %s", required, - mpoint) + mpoint = _pick_mpoint(df_map, download_size, install_size) if mpoint is None: msg = "Not enough disk space to download the packages." raise packaging.PayloadError(msg) @@ -538,6 +543,27 @@ def repos(self):
@property def spaceRequired(self): + size = self._spaceRequired() + download_size = self._download_space + valid_points = _df_map() + future_mpoints = dict() + for (key, val) in self.storage.mountpoints.items(): + new_key = key + if key.endswith('/'): + new_key = key[:-1] + # we can ignore swap + if key.startswith('/') and ((INSTALL_ROOT_MPOINT + new_key) not in valid_points): + valid_points[INSTALL_ROOT_MPOINT + new_key] = val.format.freeSpaceEstimate(val.size) + + m_points = _pick_mpoint(valid_points, download_size, size) + if not m_points or m_points == INSTALL_ROOT_MPOINT: + # download and install to the same mount point + size = size + download_size + log.debug("Instalation space required %s for mpoints %s", size, m_points) + return size + + + def _spaceRequired(self): transaction = self._base.transaction if transaction is None: return Size("3000 MB") diff --git a/pyanaconda/ui/lib/space.py b/pyanaconda/ui/lib/space.py index a133c8b..067e4d8 100644 --- a/pyanaconda/ui/lib/space.py +++ b/pyanaconda/ui/lib/space.py @@ -75,7 +75,7 @@ def check(self): free = Size(self.storage.fileSystemFreeSpace) needed = self.payload.spaceRequired log.info("fs space: %s needed: %s", free, needed) - self.success = (free >= needed) + self.success = (free > needed) if not self.success: self.deficit = needed - free self.error_message = _(self.error_template) % self.deficit @@ -106,7 +106,7 @@ def check(self): free = Size(stat.f_bsize * stat.f_bfree) needed = self.payload.spaceRequired log.info("fs space: %s needed: %s", free, needed) - self.success = (free >= needed) + self.success = (free > needed) if not self.success: self.deficit = needed - free self.error_message = _(self.error_template) % self.deficit
In reply to line 432 of pyanaconda/packaging/dnfpayload.py:
I think the ``# reserve extra`` comment should be moved right above this line.
Added label: master.
From: Jiri Konecny jkonecny@redhat.com
We need to reduce the disk capacity for space required comparison because fs takes some for metadata.
Related: rhbz#1224048 --- pyanaconda/ui/gui/spokes/storage.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py index 6f2b8ce..181e97c 100644 --- a/pyanaconda/ui/gui/spokes/storage.py +++ b/pyanaconda/ui/gui/spokes/storage.py @@ -824,9 +824,10 @@ def _check_space_and_get_dialog(self, disks): log.debug("disk free: %s fs free: %s sw needs: %s auto swap: %s", disk_free, fs_free, required_space, auto_swap)
- if disk_free >= required_space + auto_swap: + # compare only to 90% of disk space because fs takes some space for a metadata + if (disk_free * 0.9) >= required_space + auto_swap: dialog = None - elif disks_size >= required_space: + elif (disks_size * 0.9) >= required_space: dialog = NeedSpaceDialog(self.data, payload=self.payload) dialog.refresh(required_space, auto_swap, disk_free, fs_free) else:
Looks good to me otherwise.
Added label: ACK.
anaconda-patches@lists.fedorahosted.org