Skip to content

Commit

Permalink
fix(service): Copy the libzypp caches and credentials to the installe…
Browse files Browse the repository at this point in the history
…d system (#1357)

## Problem

- The libzypp caches and credentials are not copied to the installed
system
- Installing any package or even simple `zypper refresh` triggers full
repository reload

## Solution

- Just copy the files from the Live ISO zypp repository to the installed
system

## Testing

- Added a new unit test
- Tested manually, after installation all caches are copied and `zypper
refresh` does nothing
  • Loading branch information
lslezak authored Jun 19, 2024
1 parent e15aa34 commit 3a77a14
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 4 deletions.
46 changes: 42 additions & 4 deletions service/lib/agama/software/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,8 @@ def finish
progress.step(_("Writing repositories to the target system")) do
Yast::Pkg.SourceSaveAll
Yast::Pkg.TargetFinish
# FIXME: Pkg.SourceCacheCopyTo works correctly only from the inst-sys
# (original target "/"), it does not work correctly when using
# "chroot" /run/agama/zypp, it needs to be reimplemented :-(
# Yast::Pkg.SourceCacheCopyTo(Yast::Installation.destdir)
# copy the libzypp caches to the target
copy_zypp_to_target
registration.finish
end
end
Expand Down Expand Up @@ -503,6 +501,46 @@ def pattern_exist?(pattern_name)
!Y2Packager::Resolvable.find(kind: :pattern, name: pattern_name).empty?
end

# this reimplements the Pkg.SourceCacheCopyTo call which works correctly
# only from the inst-sys (it copies the data from "/" where is actually
# the Live system package manager)
# @see https://github.com/yast/yast-pkg-bindings/blob/3d314480b70070299f90da4c6e87a5574e9c890c/src/Source_Installation.cc#L213-L267
def copy_zypp_to_target
# copy the zypp "raw" cache
cache = File.join(TARGET_DIR, "/var/cache/zypp/raw")
if Dir.exist?(cache)
target_cache = File.join(Yast::Installation.destdir, "/var/cache/zypp")
FileUtils.mkdir_p(target_cache)
FileUtils.cp_r(cache, target_cache)
end

# copy the "solv" cache but skip the "@System" directory because it
# contains empty installed packages (there were no installed packages
# before moving the target to "/mnt")
solv_cache = File.join(TARGET_DIR, "/var/cache/zypp/solv")
target_solv = File.join(Yast::Installation.destdir, "/var/cache/zypp/solv")
solvs = Dir.entries(solv_cache) - [".", "..", "@System"]
solvs.each do |s|
FileUtils.cp_r(File.join(solv_cache, s), target_solv)
end

# copy the zypp credentials if present
credentials = File.join(TARGET_DIR, "/etc/zypp/credentials.d")
if Dir.exist?(credentials)
target_credentials = File.join(Yast::Installation.destdir, "/etc/zypp")
FileUtils.mkdir_p(target_credentials)
FileUtils.cp_r(credentials, target_credentials)
end

# copy the global credentials if present
glob_credentials = File.join(TARGET_DIR, "/etc/zypp/credentials.cat")
return unless File.exist?(glob_credentials)

target_dir = File.join(Yast::Installation.destdir, "/etc/zypp")
FileUtils.mkdir_p(target_dir)
FileUtils.copy(glob_credentials, target_dir)
end

# update the zypp repositories for the new product, either delete them
# or keep them untouched
# @param new_product [Agama::Software::Product] the new selected product
Expand Down
8 changes: 8 additions & 0 deletions service/package/rubygem-agama-yast.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
-------------------------------------------------------------------
Wed Jun 19 06:04:46 UTC 2024 - Ladislav Slezák <[email protected]>

- Use a different libzypp target for Agama, do not use the Live
system package management (gh#openSUSE/agama#1329)
- Properly delete the libzypp cache when changing the products
(gh#openSUSE/agama#1349)

-------------------------------------------------------------------
Thu Jun 13 10:53:27 UTC 2024 - Imobach Gonzalez Sosa <[email protected]>

Expand Down
59 changes: 59 additions & 0 deletions service/test/agama/software/manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@
allow(Agama::Software::RepositoriesManager).to receive(:new).and_return(repositories)
allow(Agama::Software::Proposal).to receive(:new).and_return(proposal)
allow(Agama::ProductReader).to receive(:new).and_call_original
allow(FileUtils).to receive(:mkdir_p)
allow(FileUtils).to receive(:rm_rf)
allow(FileUtils).to receive(:cp_r)
allow(File).to receive(:exist?).and_call_original
end

after do
Expand Down Expand Up @@ -359,11 +363,66 @@

describe "#finish" do
it "releases the packaging system" do
allow(subject).to receive(:copy_zypp_to_target)
expect(Yast::Pkg).to receive(:SourceSaveAll)
expect(Yast::Pkg).to receive(:TargetFinish)

subject.finish
end

it "copies the libzypp cache and credentials to the target system" do
allow(Dir).to receive(:exist?).and_call_original
allow(Dir).to receive(:entries).and_call_original

# copying the raw cache
expect(Dir).to receive(:exist?).with(
File.join(target_dir, "/var/cache/zypp/raw")
).and_return(true)
expect(FileUtils).to receive(:mkdir_p).with(
File.join(Yast::Installation.destdir, "/var/cache/zypp")
)
expect(FileUtils).to receive(:cp_r).with(
File.join(target_dir, "/var/cache/zypp/raw"),
File.join(Yast::Installation.destdir, "/var/cache/zypp")
)

# copy the solv cache
repo_alias = "https-download.opensuse.org-94cc89aa"
expect(Dir).to receive(:entries)
.with(File.join(target_dir, "/var/cache/zypp/solv"))
.and_return([".", "..", "@System", repo_alias])
expect(FileUtils).to receive(:cp_r).with(
File.join(target_dir, "/var/cache/zypp/solv/", repo_alias),
File.join(Yast::Installation.destdir, "/var/cache/zypp/solv")
)
# ensure the @System cache is not copied
expect(FileUtils).to_not receive(:cp_r).with(
File.join(target_dir, "/var/cache/zypp/solv/@System"),
File.join(Yast::Installation.destdir, "/var/cache/zypp/solv")
)

# copying the credentials.d directory
expect(Dir).to receive(:exist?)
.with(File.join(target_dir, "/etc/zypp/credentials.d"))
.and_return(true)
expect(FileUtils).to receive(:mkdir_p)
.with(File.join(Yast::Installation.destdir, "/etc/zypp"))
expect(FileUtils).to receive(:cp_r).with(
File.join(target_dir, "/etc/zypp/credentials.d"),
File.join(Yast::Installation.destdir, "/etc/zypp")
)

# copying the global credentials file
expect(File).to receive(:exist?)
.with(File.join(target_dir, "/etc/zypp/credentials.cat"))
.and_return(true)
expect(FileUtils).to receive(:copy).with(
File.join(target_dir, "/etc/zypp/credentials.cat"),
File.join(Yast::Installation.destdir, "/etc/zypp")
)

subject.finish
end
end

describe "#package_installed?" do
Expand Down

0 comments on commit 3a77a14

Please sign in to comment.