diff --git a/service/lib/agama/helpers.rb b/service/lib/agama/helpers.rb index e8cd993b11..d60bbbd107 100644 --- a/service/lib/agama/helpers.rb +++ b/service/lib/agama/helpers.rb @@ -45,5 +45,24 @@ def on_target(&block) Yast::WFM.SCRClose(handle) end end + + # Run a block in the local system + # + # @param block [Proc] Block to run on the local system + def on_local(&block) + Yast.import "WFM" + old_handle = Yast::WFM.SCRGetDefault + handle = Yast::WFM.SCROpen("chroot=/:scr", false) + Yast::WFM.SCRSetDefault(handle) + + begin + block.call + rescue StandardError => e + logger.error "Error while running on target tasks: #{e.inspect}" + ensure + Yast::WFM.SCRSetDefault(old_handle) + Yast::WFM.SCRClose(handle) + end + end end end diff --git a/service/lib/agama/manager.rb b/service/lib/agama/manager.rb index 6eea3dba66..dfb2210de3 100644 --- a/service/lib/agama/manager.rb +++ b/service/lib/agama/manager.rb @@ -22,6 +22,7 @@ require "yast" require "agama/config" require "agama/network" +require "agama/proxy_setup" require "agama/with_progress" require "agama/installation_phase" require "agama/service_status_recorder" @@ -103,6 +104,7 @@ def install_phase progress.step("Partitioning") do storage.install + proxy.propose # propose software after /mnt is already separated, so it uses proper # target software.propose @@ -137,6 +139,13 @@ def software end end + # ProxySetup instance + # + # @return [ProxySetup] + def proxy + ProxySetup.instance + end + # Language manager # # @return [DBus::Clients::Locale] diff --git a/service/lib/agama/network.rb b/service/lib/agama/network.rb index c8c4435a72..23eef44e37 100644 --- a/service/lib/agama/network.rb +++ b/service/lib/agama/network.rb @@ -23,6 +23,7 @@ require "yast" require "yast2/systemd/service" require "y2network/proposal_settings" +require "agama/proxy_setup" Yast.import "Installation" @@ -41,6 +42,8 @@ def initialize(logger) def install copy_files enable_service + + ProxySetup.instance.install end private diff --git a/service/lib/agama/proxy_setup.rb b/service/lib/agama/proxy_setup.rb index 9852db68ca..00ae9e3f88 100644 --- a/service/lib/agama/proxy_setup.rb +++ b/service/lib/agama/proxy_setup.rb @@ -21,6 +21,8 @@ require "yast" require "uri" +require "fileutils" +require "agama/helpers" module Agama # This class is responsible of parsing the proxy url from the kernel cmdline or configured @@ -30,16 +32,26 @@ class ProxySetup include Singleton include Yast include Logger + include Helpers CMDLINE_PATH = "/proc/cmdline" CMDLINE_MENU_CONF = "/etc/cmdline-menu.conf" + PACKAGES = ["microos-tools"].freeze + CONFIG_PATH = "/etc/sysconfig/proxy" + PROPOSAL_ID = "network_proposal" # @return [URI::Generic] attr_accessor :proxy + alias_method :logger, :log + # Constructor def initialize Yast.import "Proxy" + Yast.import "Installation" + Yast.import "PackagesProposal" + + Proxy.Read end def run @@ -47,6 +59,17 @@ def run write end + def propose + add_packages if Proxy.enabled + end + + def install + return unless Proxy.enabled + + on_local { copy_files } + enable_services + end + private def read @@ -105,5 +128,26 @@ def write Proxy.Write end + + def add_packages + log.info "Selecting these packages for installation: #{PACKAGES}" + Yast::PackagesProposal.SetResolvables(PROPOSAL_ID, :package, PACKAGES) + end + + def copy_files + log.info "Copying proxy configuration to the target system" + ::FileUtils.cp(CONFIG_PATH, File.join(Yast::Installation.destdir, CONFIG_PATH)) + end + + def enable_services + service = Yast2::Systemd::Service.find("setup-systemd-proxy-env") + if service.nil? + log.error "setup-systemd-proxy-env service was not found" + return + end + + Yast::Execute.on_target!("systemctl", "enable", "setup-systemd-proxy-env.service") + Yast::Execute.on_target!("systemctl", "enable", "setup-systemd-proxy-env.path") + end end end diff --git a/service/package/rubygem-agama.changes b/service/package/rubygem-agama.changes index 292cb806d8..fd7da96943 100644 --- a/service/package/rubygem-agama.changes +++ b/service/package/rubygem-agama.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Mon Aug 28 07:59:26 UTC 2023 - Knut Anderssen + +- Copy the proxy configuration to the target system when needed + (bsc#1212677, gh#openSUSE/agama#711). + ------------------------------------------------------------------- Wed Aug 23 10:39:46 UTC 2023 - Imobach Gonzalez Sosa diff --git a/service/test/agama/manager_test.rb b/service/test/agama/manager_test.rb index cf57345473..b050600515 100644 --- a/service/test/agama/manager_test.rb +++ b/service/test/agama/manager_test.rb @@ -34,6 +34,9 @@ end let(:config) { Agama::Config.from_file(config_path) } let(:logger) { Logger.new($stdout, level: :warn) } + let(:proxy) do + instance_double(Agama::ProxySetup, propose: nil, install: nil) + end let(:software) do instance_double( @@ -61,6 +64,7 @@ before do allow(Agama::Network).to receive(:new).and_return(network) + allow(Agama::ProxySetup).to receive(:instance).and_return(proxy) allow(Agama::DBus::Clients::Locale).to receive(:new).and_return(locale) allow(Agama::DBus::Clients::Software).to receive(:new).and_return(software) allow(Agama::DBus::Clients::Storage).to receive(:new).and_return(storage) @@ -115,6 +119,12 @@ expect(subject.installation_phase.install?).to eq(true) end + it "calls #propose on proxy and software modules" do + expect(proxy).to receive(:propose) + expect(software).to receive(:propose) + subject.install_phase + end + it "calls #install (or #write) method of each module" do expect(network).to receive(:install) expect(software).to receive(:install) diff --git a/service/test/agama/proxy_setup_test.rb b/service/test/agama/proxy_setup_test.rb index 484541296a..c4246921dc 100644 --- a/service/test/agama/proxy_setup_test.rb +++ b/service/test/agama/proxy_setup_test.rb @@ -28,15 +28,15 @@ proxy.proxy = nil end + before do + allow(Yast::Proxy).to receive(:Read) + allow(Yast::Proxy).to receive(:Write) + end + describe "#run" do let(:file_content) { "proxy=#{proxy_url}" } let(:proxy_url) { "https://yast:1234@192.168.122.1:3128" } - before do - allow(Yast::Proxy).to receive(:Read) - allow(Yast::Proxy).to receive(:Write) - end - context "when some configuration is given through the kernel command line" do before do allow(proxy).to receive(:proxy_from_cmdline).and_return(URI(proxy_url)) @@ -75,4 +75,69 @@ end end end + + describe "#propose" do + let(:config) do + { + "enabled" => false + } + end + + before do + Yast::Proxy.Import(config) + allow(Yast::Installation).to receive(:destdir).and_return("/mnt") + end + + context "when the use of proxy is enabled" do + let(:config) do + { + "enabled" => true, + "http_proxy" => "http://192.168.122.1:3128" + } + end + + it "adds microos-tools package to the set of resolvables" do + expect(Yast::PackagesProposal).to receive(:SetResolvables) do |_, _, packages| + expect(packages).to contain_exactly("microos-tools") + end + + proxy.propose + end + end + end + + describe "#install" do + let(:config) do + { + "enabled" => false + } + end + + before do + Yast::Proxy.Import(config) + allow(Yast::Installation).to receive(:destdir).and_return("/mnt") + end + + context "when the use of proxy is disabled" do + it "does not copy the configuration to the target system" do + expect(FileUtils).to_not receive(:cp) + proxy.install + end + end + + context "when the use of proxy is enabled" do + let(:config) do + { + "enabled" => true, + "http_proxy" => "http://192.168.122.1:3128" + } + end + + it "copies the configuration to the target system" do + expect(FileUtils).to receive(:cp).with(described_class::CONFIG_PATH, + File.join("/mnt", described_class::CONFIG_PATH)) + proxy.install + end + end + end end