Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not cleanup the libzypp cache (bsc#1179415) #919

Merged
merged 1 commit into from Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions package/yast2-installation.changes
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Wed Feb 24 16:59:53 UTC 2021 - Ladislav Slezák <lslezak@suse.cz>

- Do not cleanup the libzypp cache when the system has low memory,
incomplete cache confuses libzypp later (bsc#1179415)
- 4.1.52

-------------------------------------------------------------------
Mon Dec 21 10:44:22 UTC 2020 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-installation.spec
Expand Up @@ -16,7 +16,7 @@
#

Name: yast2-installation
Version: 4.1.51
Version: 4.1.52
Release: 0

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand Down
61 changes: 1 addition & 60 deletions src/lib/installation/instsys_cleaner.rb
Expand Up @@ -29,42 +29,11 @@ class InstsysCleaner

Yast.import "Mode"
Yast.import "Stage"
Yast.import "UI"

# memory limit for removing the kernel modules from inst-sys (1GB)
KERNEL_MODULES_WATERLINE = 1 << 30
KERNEL_MODULES_MOUNT_POINT = "/parts/mp_0000".freeze

# memory limit for removing the libzypp metadata cache (<640MB in text mode, <1GB in GUI)
LIBZYPP_WATERLINE_TUI = 640 << 20
LIBZYPP_WATERLINE_GUI = 1 << 30
# the cache in inst-sys, the target system cache is at /mnt/...,
# in upgrade mode the target cache is kept
LIBZYPP_CACHE_PATH = "/var/cache/zypp/raw".freeze

# files which can be removed from the libzypp "raw" cache in inst-sys (globs),
# not needed for package installation
LIBZYPP_CLEANUP_PATTERNS = [
# repository meta data already included in the "solv" cache,
"*-deltainfo.xml.gz",
"*-primary.xml.gz",
"*-susedata.xml.gz",
"*-susedata.*.xml.gz",
"*-susedinfo.xml.gz",
"*-updateinfo.xml.gz",
# product licenses (already confirmed)
"*-license-*.tar.gz",
# application meta data
"*-appdata.xml.gz",
"*-appdata-icons.tar.gz",
"appdata-ignore.xml.gz",
"appdata-screenshots.tar"
].freeze

def self.libzypp_waterline
Yast::UI.TextMode ? LIBZYPP_WATERLINE_TUI : LIBZYPP_WATERLINE_GUI
end

# Remove some files in inst-sys to have more free space if the system
# has too low memory. If the system has enough memory keep everything in place.
# This method might remove the kernel modules from the system, make sure
Expand All @@ -81,38 +50,10 @@ def self.make_clean

# run the cleaning actions depending on the available memory
unmount_kernel_modules if memory < KERNEL_MODULES_WATERLINE
cleanup_zypp_cache if memory < libzypp_waterline
end

########################## Internal methods ################################

# Remove the libzypp downloaded repository metadata.
# Libzypp has "raw" and "solv" caches, the "solv" is built from "raw"
# but it cannot be removed because libzypp keeps the files open.
# The "raw" files will be later downloaded automatically again when loading
# the repositories. But libzypp still need some files during package
# installation, we can only remove the known files, @see LIBZYPP_CLEANUP_PATTERNS
def self.cleanup_zypp_cache
log.info("Cleaning unused files in the libzypp cache (#{LIBZYPP_CACHE_PATH})")
saved_space = 0

LIBZYPP_CLEANUP_PATTERNS.each do |p|
files = Dir[File.join(LIBZYPP_CACHE_PATH, "**", p)]
next if files.empty?

files.each do |f|
log.debug("Removing cache file #{f}")
saved_space += File.size(f)
# make sure we do not collide with Yast::FileUtils...
::FileUtils.rm(f)
end
end

# convert to kiB
saved_space /= 1024
log.info("Libzypp cache cleanup saved #{saved_space}kiB (#{saved_space / 1024}MiB)")
end

# Remove the kernel modules squashfs image.
# It assumes that all needed kernel drivers are already loaded and active
# so we can remove the files to save some space.
Expand Down Expand Up @@ -183,6 +124,6 @@ def self.losetup_backing_file(device)
end

private_class_method :log_space_usage, :unmount_kernel_modules,
:cleanup_zypp_cache, :find_device, :losetup_backing_file
:find_device, :losetup_backing_file
end
end
44 changes: 1 addition & 43 deletions test/instsys_cleaner_test.rb
Expand Up @@ -16,10 +16,9 @@
allow(Yast::Execute).to receive(:locally).with("free", "-m")
allow(File).to receive(:size).and_return(0)
allow(Dir).to receive(:[]).and_return([])
allow(Yast::UI).to receive(:TextMode).and_return(true)
end

context "a bit less than 640MB memory in text mode" do
context "a bit less than 640MB memory" do
before do
# 512MB - 1B
expect(Yast2::HwDetection).to receive(:memory).and_return((512 << 20) - 1)
Expand All @@ -30,50 +29,11 @@
expect(FileUtils).to_not receive(:rm)
described_class.make_clean
end

it "removes the known files from the libzypp cache" do
file = "/var/cache/zypp/raw/SLES15-15-0/repodata/1234567890abcdef-appdata.xml.gz"
expect(Dir).to receive(:[]).with("/var/cache/zypp/raw/**/*-appdata.xml.gz")
.and_return([file])
expect(FileUtils).to receive(:rm).with(file)
described_class.make_clean
end
end

context "a bit less than 1GB memory in graphical mode" do
before do
# 1GB - 1B
expect(Yast2::HwDetection).to receive(:memory).and_return((1 << 30) - 1)
allow(described_class).to receive(:unmount_kernel_modules)
allow(Yast::UI).to receive(:TextMode).and_return(false)
end

it "removes the known files from the libzypp cache" do
file = "/var/cache/zypp/raw/SLES15-15-0/repodata/1234567890abcdef-appdata.xml.gz"
expect(Dir).to receive(:[]).with("/var/cache/zypp/raw/**/*-appdata.xml.gz")
.and_return([file])
expect(FileUtils).to receive(:rm).with(file)
described_class.make_clean
end
end

context "a bit less than 1GB memory in text mode" do
before do
# 1GB - 1B
expect(Yast2::HwDetection).to receive(:memory).and_return((1 << 30) - 1)
allow(described_class).to receive(:unmount_kernel_modules)
end

fit "does not remove the libzypp cache" do
expect(described_class).to_not receive(:cleanup_zypp_cache)
described_class.make_clean
end
end

it "removes the kernel modules if the memory is less than 1GB" do
# 1GB - 1B
expect(Yast2::HwDetection).to receive(:memory).and_return((1 << 30) - 1)
allow(described_class).to receive(:cleanup_zypp_cache)

# the order of the executed commands is important, check it explicitly
expect(File).to receive(:exist?).with("/parts/mp_0000/lib/modules").and_return(true).ordered
Expand All @@ -91,7 +51,6 @@
# 2GB RAM
expect(Yast2::HwDetection).to receive(:memory).and_return(2 << 30)

expect(described_class).to_not receive(:cleanup_zypp_cache)
expect(described_class).to_not receive(:unmount_kernel_modules)

described_class.make_clean
Expand All @@ -104,7 +63,6 @@
end

it "does not do anything" do
expect(described_class).to_not receive(:cleanup_zypp_cache)
expect(described_class).to_not receive(:unmount_kernel_modules)

described_class.make_clean
Expand Down