From 06a5c3b0c74d24e450ed2789ab9068c0f85c6543 Mon Sep 17 00:00:00 2001 From: Knut Anderssen Date: Mon, 14 Aug 2023 07:38:42 +0100 Subject: [PATCH] Moved to lib, added test and documentation --- doc/boot_arguments.md | 11 +++ service/bin/agama-proxy-setup | 109 +----------------------- service/lib/agama/proxy_setup.rb | 110 +++++++++++++++++++++++++ service/test/agama/proxy_setup_test.rb | 78 ++++++++++++++++++ 4 files changed, 201 insertions(+), 107 deletions(-) create mode 100644 service/lib/agama/proxy_setup.rb create mode 100644 service/test/agama/proxy_setup_test.rb diff --git a/doc/boot_arguments.md b/doc/boot_arguments.md index f31be92504..69e4a65fa6 100644 --- a/doc/boot_arguments.md +++ b/doc/boot_arguments.md @@ -26,3 +26,14 @@ agama.web.ssl=true agama.web.ssl_cert=http://192.168.122.1/mycert.pem agama.web. ``` Changing complex options (e.g., collections) is not supported yet. + +## Proxy Setup + +Agama supports proxy setup using the `proxy=` kernel command line option like +`proxy=http:192.168.122.1:3128`. + +When the installation system boots, the agama-proxy-setup service will read the proxy url to be +used from the kernel command line options or through the dracut ask prompt configuration file +writing it to the /etc/sysconfig/proxy. After that the microOS Tools setup-systemd-proxy-env +systemd service will make the proxy variables from that file available to all the systemd units +writing a systemd config file with all the variables as Enviroment ones. diff --git a/service/bin/agama-proxy-setup b/service/bin/agama-proxy-setup index ea99ebcdcf..8d16341175 100755 --- a/service/bin/agama-proxy-setup +++ b/service/bin/agama-proxy-setup @@ -1,111 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -# Copyright (c) [2023] SUSE LLC -# -# All Rights Reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of version 2 of the GNU General Public License as published -# by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, contact SUSE LLC. -# -# To contact SUSE LLC about this file by physical or electronic mail, you may -# find current contact information at www.suse.com. +require "agama/proxy_setup" -# Helper script to create a configuration file for a selected list of products. - -require "yast" -require "uri" - -# This class is responsible of parsing the proxy url from the kernel cmdline or configured -# during the boot proccess of the system -class SetupProxy - include Singleton - include Yast - include Logger - - CMDLINE_PATH = "/etc/cmdline" - CMDLINE_MENU_CONF = "/etc/cmdline-menu.conf" - - attr_accessor :proxy - - # Constructor - def initialize - Yast.import "Proxy" - end - - def run - read - write - end - -private - - def read - self.proxy = proxy_from_cmdline || proxy_from_dracut - end - - # TODO - def proxy_from_dracut - return unless File.exist?(CMDLINE_MENU_CONF) - - options = File.read(CMDLINE_MENU_CONF) - proxy_url_from(options) - end - - def proxy_url_from(options) - proxy_url = options.split.find { |o| o.start_with?(/proxy/i) } - return unless proxy_url - - URI(proxy_url.downcase.gsub("proxy=", "")) - end - - def proxy_from_cmdline - return unless File.exist?(CMDLINE_PATH) - - options = File.read(CMDLINE_PATH) - proxy_url_from(options) - end - - def proxy_import_settings - ex = Proxy.Export - proto = proxy.scheme - - # save user name and password separately - ex["proxy_user"] = proxy.user - proxy.user = nil - ex["proxy_password"] = proxy.password - proxy.password = nil - ex["#{proto}_proxy"] = proxy.to_s - # Use the proxy also for https and ftp - if proto == "http" - ex["https_proxy"] = proxy.to_s - ex["ftp_proxy"] = proxy.to_s - end - ex["enabled"] = true - ex - end - - def write - return unless proxy - - Proxy.Read - ex = proxy_import_settings - - log.info "Writing proxy settings: #{proxy.scheme}_proxy = '#{proxy}'" - log.debug "Writing proxy settings: #{ex}" - - Proxy.Import(ex) - Proxy.Write - end -end - -SetupProxy.instance.run +Agama::ProxySetup.instance.run diff --git a/service/lib/agama/proxy_setup.rb b/service/lib/agama/proxy_setup.rb new file mode 100644 index 0000000000..4bf8b27851 --- /dev/null +++ b/service/lib/agama/proxy_setup.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +# Copyright (c) [2023] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +# Helper script to create a configuration file for a selected list of products. + +require "yast" +require "uri" + +module Agama + # This class is responsible of parsing the proxy url from the kernel cmdline or configured + # during the boot proccess of the system writing the configuration to /etc/sysconfig/proxy + class ProxySetup + include Singleton + include Yast + include Logger + + CMDLINE_PATH = "/etc/cmdline" + CMDLINE_MENU_CONF = "/etc/cmdline-menu.conf" + + attr_accessor :proxy + + # Constructor + def initialize + Yast.import "Proxy" + end + + def run + read + write + end + + private + + def read + self.proxy = proxy_from_cmdline || proxy_from_dracut + end + + # TODO + def proxy_from_dracut + return unless File.exist?(CMDLINE_MENU_CONF) + + options = File.read(CMDLINE_MENU_CONF) + proxy_url_from(options) + end + + def proxy_url_from(options) + proxy_url = options.split.find { |o| o.start_with?(/proxy/i) } + return unless proxy_url + + URI(proxy_url.downcase.gsub("proxy=", "")) + end + + def proxy_from_cmdline + return unless File.exist?(CMDLINE_PATH) + + options = File.read(CMDLINE_PATH) + proxy_url_from(options) + end + + def proxy_import_settings + ex = Proxy.Export + proto = proxy.scheme + + # save user name and password separately + ex["proxy_user"] = proxy.user + proxy.user = nil + ex["proxy_password"] = proxy.password + proxy.password = nil + ex["#{proto}_proxy"] = proxy.to_s + # Use the proxy also for https and ftp + if proto == "http" + ex["https_proxy"] = proxy.to_s + ex["ftp_proxy"] = proxy.to_s + end + ex["enabled"] = true + ex + end + + def write + return unless proxy + + Proxy.Read + ex = proxy_import_settings + Proxy.Import(ex) + + log.info "Writing proxy settings: #{proxy.scheme}_proxy = '#{proxy}'" + log.debug "Writing proxy settings: #{ex}" + + Proxy.Write + end + end +end diff --git a/service/test/agama/proxy_setup_test.rb b/service/test/agama/proxy_setup_test.rb new file mode 100644 index 0000000000..484541296a --- /dev/null +++ b/service/test/agama/proxy_setup_test.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +# Copyright (c) [2023] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require_relative "../test_helper" +require "agama/proxy_setup" + +describe Agama::ProxySetup do + subject(:proxy) { described_class.instance } + before do + proxy.proxy = nil + 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)) + allow(proxy).to receive(:write) + end + + it "reads the given proxy configuraion" do + expect(proxy.proxy).to be_nil + proxy.run + expect(proxy.proxy).to be_a(URI) + end + + it "writes the proxy configuration to /etc/sysconfig/proxy" do + allow(proxy).to receive(:write).and_call_original + expect(Yast::Proxy).to receive(:Write) + proxy.run + config = Yast::Proxy.Export + expect(config).to include("https_proxy" => "https://192.168.122.1:3128", + "proxy_password" => "1234", + "proxy_user" => "yast", + "enabled" => true) + end + + context "when an http url is given" do + let(:proxy_url) { "http://192.168.122.1:3128" } + + it "sets also the https and ftp with the same url" do + allow(proxy).to receive(:write).and_call_original + proxy.run + config = Yast::Proxy.Export + expect(config).to include("http_proxy" => "http://192.168.122.1:3128", + "https_proxy" => "http://192.168.122.1:3128", + "ftp_proxy" => "http://192.168.122.1:3128", + "enabled" => true) + end + end + end + end +end