diff --git a/service/lib/agama/software/manager.rb b/service/lib/agama/software/manager.rb index 9de17bdf1b..ddb08989fd 100644 --- a/service/lib/agama/software/manager.rb +++ b/service/lib/agama/software/manager.rb @@ -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 @@ -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 diff --git a/service/package/rubygem-agama-yast.changes b/service/package/rubygem-agama-yast.changes index dfd5b661c7..89fa95ad10 100644 --- a/service/package/rubygem-agama-yast.changes +++ b/service/package/rubygem-agama-yast.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Wed Jun 19 06:04:46 UTC 2024 - Ladislav Slezák + +- 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 diff --git a/service/test/agama/software/manager_test.rb b/service/test/agama/software/manager_test.rb index f5b7470829..ad2770c4ec 100644 --- a/service/test/agama/software/manager_test.rb +++ b/service/test/agama/software/manager_test.rb @@ -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 @@ -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