commit yast2-rmt for openSUSE:Factory
Hello community, here is the log from the commit of package yast2-rmt for openSUSE:Factory checked in at 2018-04-27 16:09:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-rmt (Old) and /work/SRC/openSUSE:Factory/.yast2-rmt.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "yast2-rmt" Fri Apr 27 16:09:16 2018 rev:4 rq:601631 version:0.0.4 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-rmt/yast2-rmt.changes 2018-04-06 17:52:22.661347465 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-rmt.new/yast2-rmt.changes 2018-04-27 16:09:17.846345544 +0200 @@ -1,0 +2,7 @@ +Wed Apr 18 12:06:01 UTC 2018 - ikapelyukhin@suse.com + +- version 0.0.4 +- Allow a preexisting SSL CA: + https://github.com/SUSE/yast2-rmt/pull/11 + +------------------------------------------------------------------- Old: ---- yast2-rmt-0.0.3.tar.bz2 New: ---- yast2-rmt-0.0.4.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-rmt.spec ++++++ --- /var/tmp/diff_new_pack.NHG308/_old 2018-04-27 16:09:18.474322512 +0200 +++ /var/tmp/diff_new_pack.NHG308/_new 2018-04-27 16:09:18.478322365 +0200 @@ -17,14 +17,14 @@ Name: yast2-rmt -Version: 0.0.3 +Version: 0.0.4 Release: 0 BuildArch: noarch BuildRoot: %{_tmppath}/%{name}-%{version}-build Source0: %{name}-%{version}.tar.bz2 -Requires: rmt-server +Requires: rmt-server >= 0.0.5 Requires: yast2 Requires: yast2-ruby-bindings @@ -58,6 +58,7 @@ %defattr(-,root,root) %{yast_dir}/clients/*.rb %{yast_dir}/lib/rmt +%{yast_desktopdir}/rmt.desktop %{yast_dir}/data/rmt %doc COPYING ++++++ yast2-rmt-0.0.3.tar.bz2 -> yast2-rmt-0.0.4.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/Gemfile.lock new/yast2-rmt-0.0.4/Gemfile.lock --- old/yast2-rmt-0.0.3/Gemfile.lock 2018-02-26 17:24:52.157255046 +0100 +++ new/yast2-rmt-0.0.4/Gemfile.lock 2018-04-18 11:54:50.758844151 +0200 @@ -9,7 +9,7 @@ ast (~> 2.4.0) powerpack (0.1.1) rainbow (3.0.0) - rake (12.3.0) + rake (12.3.1) rubocop (0.52.1) parallel (~> 1.10) parser (>= 2.4.0.2, < 3.0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/README.md new/yast2-rmt-0.0.4/README.md --- old/yast2-rmt-0.0.3/README.md 2018-03-12 17:02:15.344583881 +0100 +++ new/yast2-rmt-0.0.4/README.md 2018-04-16 15:10:34.945032546 +0200 @@ -30,6 +30,48 @@ docker run -it yast-rmt-image rspec ``` -### Package +### Package -The package gets built for SLE15 here: https://build.opensuse.org/package/show/systemsmanagement:SCC:RMT/yast2-rmt +The package gets built for SLE 15 and openSUSE Leap 15 here: +https://build.opensuse.org/package/show/systemsmanagement:SCC:RMT/yast2-rmt + +You can use: + +```bash +rake osc:commit +``` + +to commit the current version to OBS. + + +#### Submit Requests to openSUSE Factory and SLES + +To get a maintenance request accepted, each changelog entry needs to reference a bug or feature +request with `bsc#123` or `fate#123`. + +##### Factory First + +To submit a request to openSUSE Factory, issue this commands in the console: + +```bash +osc sr systemsmanagement:SCC:RMT yast2-rmt openSUSE:Factory --no-cleanup +``` + + +##### Internal Build Service + +To make the initial submit for a new SLES version: + +```bash +osc -A https://api.suse.de sr Devel:SCC:RMT yast2-rmt SUSE:SLE-15:GA --no-cleanup +``` + +To submit the updated package as a maintenance update to released SLES versions: + +```bash +osc -A https://api.suse.de mr Devel:SCC:RMT yast2-rmt SUSE:SLE-15:GA:Update --no-cleanup +``` + +You can check the status of your requests [here](https://build.opensuse.org/package/requests/systemsmanagement:SCC:RMT/yast2-...) and [here](https://build.suse.de/package/requests/Devel:SCC:RMT/yast2-rmt). + +After your requests got accepted, they still have to pass maintenance testing before they get released to customers. You can check their progress at [maintenance.suse.de](https://maintenance.suse.de/search/?q=yast2-rmt). If you still need help, the maintenance team can be reached at [maint-coord@suse.de](maint-coord@suse.de) or #maintenance on irc.suse.de. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/Rakefile new/yast2-rmt-0.0.4/Rakefile --- old/yast2-rmt-0.0.3/Rakefile 2018-03-27 15:09:30.067122856 +0200 +++ new/yast2-rmt-0.0.4/Rakefile 2018-04-18 11:54:50.758844151 +0200 @@ -23,7 +23,7 @@ conf.obs_project = 'systemsmanagement:SCC:RMT' # Default target for osc:build conf.obs_target = 'openSUSE_Factory' - conf.skip_license_check = [ %r{^Gemfile\.lock$}, %r{rmt.*\.cnf\.erb$} ] + conf.skip_license_check = [ %r{^Gemfile\.lock$}, %r{rmt\.desktop} , %r{rmt.*\.cnf\.erb$} ] end # This is required, because `yast-travis-ruby` binary calls `rake test:unit` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/package/yast2-rmt.changes new/yast2-rmt-0.0.4/package/yast2-rmt.changes --- old/yast2-rmt-0.0.3/package/yast2-rmt.changes 2018-04-03 10:17:50.038563438 +0200 +++ new/yast2-rmt-0.0.4/package/yast2-rmt.changes 2018-04-24 11:54:43.422604842 +0200 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Wed Apr 18 12:06:01 UTC 2018 - ikapelyukhin@suse.com + +- version 0.0.4 +- Allow a preexisting SSL CA: + https://github.com/SUSE/yast2-rmt/pull/11 + +------------------------------------------------------------------- Tue Apr 3 08:16:37 UTC 2018 - ikapelyukhin@suse.com - version 0.0.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/package/yast2-rmt.spec new/yast2-rmt-0.0.4/package/yast2-rmt.spec --- old/yast2-rmt-0.0.3/package/yast2-rmt.spec 2018-04-03 10:16:23.106209620 +0200 +++ new/yast2-rmt-0.0.4/package/yast2-rmt.spec 2018-04-24 11:54:43.422604842 +0200 @@ -17,14 +17,14 @@ Name: yast2-rmt -Version: 0.0.3 +Version: 0.0.4 Release: 0 BuildArch: noarch BuildRoot: %{_tmppath}/%{name}-%{version}-build Source0: %{name}-%{version}.tar.bz2 -Requires: rmt-server +Requires: rmt-server >= 0.0.5 Requires: yast2 Requires: yast2-ruby-bindings @@ -58,6 +58,7 @@ %defattr(-,root,root) %{yast_dir}/clients/*.rb %{yast_dir}/lib/rmt +%{yast_desktopdir}/rmt.desktop %{yast_dir}/data/rmt %doc COPYING diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/spec/rmt/ssl/certificate_generator_spec.rb new/yast2-rmt-0.0.4/spec/rmt/ssl/certificate_generator_spec.rb --- old/yast2-rmt-0.0.3/spec/rmt/ssl/certificate_generator_spec.rb 2018-04-04 15:18:52.421068902 +0200 +++ new/yast2-rmt-0.0.4/spec/rmt/ssl/certificate_generator_spec.rb 2018-04-24 11:54:43.422604842 +0200 @@ -27,10 +27,12 @@ described_class::OPENSSL_FILES.map { |id, filename| [id, File.join(described_class::RMT_SSL_DIR, filename)] }.to_h end - let(:crt_and_key_files) { %i[ca_private_key ca_certificate server_private_key server_certificate] } + let(:ca_files) { %i[ca_private_key ca_certificate] } + let(:server_cert_files) { %i[server_private_key server_certificate] } + let(:crt_and_key_files) { ca_files + server_cert_files } - describe '#check_certs_presence' do - subject(:result) { generator.check_certs_presence } + describe '#ca_present?' do + subject(:result) { generator.ca_present? } before do # Yast reads locale data at startup for i18n @@ -38,14 +40,14 @@ end it 'returns false when none of the files exist' do - crt_and_key_files.each do |file| + ca_files.each do |file| expect(File).to receive(:exist?).with(ssl_files[file]).and_return(false) end expect(result).to eq(false) end it 'returns false when all of the files are empty' do - crt_and_key_files.each do |file| + ca_files.each do |file| expect(File).to receive(:exist?).with(ssl_files[file]).and_return(true) expect(File).to receive(:zero?).with(ssl_files[file]).and_return(true) end @@ -53,7 +55,39 @@ end it 'returns true when one the files exist and is not empty' do - file = crt_and_key_files.shift + file = ca_files.shift + expect(File).to receive(:exist?).with(ssl_files[file]).and_return(true) + expect(File).to receive(:zero?).with(ssl_files[file]).and_return(false) + + expect(result).to eq(true) + end + end + + describe '#server_cert_present??' do + subject(:result) { generator.server_cert_present? } + + before do + # Yast reads locale data at startup for i18n + expect(File).to receive(:exist?).with('/usr/share/YaST2/locale').and_return(false) + end + + it 'returns false when none of the files exist' do + server_cert_files.each do |file| + expect(File).to receive(:exist?).with(ssl_files[file]).and_return(false) + end + expect(result).to eq(false) + end + + it 'returns false when all of the files are empty' do + server_cert_files.each do |file| + expect(File).to receive(:exist?).with(ssl_files[file]).and_return(true) + expect(File).to receive(:zero?).with(ssl_files[file]).and_return(true) + end + expect(result).to eq(false) + end + + it 'returns true when one the files exist and is not empty' do + file = server_cert_files.shift expect(File).to receive(:exist?).with(ssl_files[file]).and_return(true) expect(File).to receive(:zero?).with(ssl_files[file]).and_return(false) @@ -71,65 +105,107 @@ let(:common_name) { 'example.org' } let(:alt_names) { ['foo.example.org', 'bar.example.org'] } - it 'generates the certificate' do - expect(RMT::SSL::ConfigGenerator).to receive(:new).and_return(config_generator_double) - expect(config_generator_double).to receive(:make_ca_config) { ca_config } - expect(config_generator_double).to receive(:make_server_config) { server_config } - - expect(generator).to receive(:create_files) - - expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:ca_serial_file], '01') - expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:ca_config], ca_config) - expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:server_config], server_config) - - expect(RMT::Execute).to receive(:on_target!).with( - 'openssl', 'genrsa', '-out', - ssl_files[:ca_private_key], described_class::OPENSSL_KEY_BITS - ) - - expect(RMT::Execute).to receive(:on_target!).with( - 'openssl', 'genrsa', '-out', - ssl_files[:server_private_key], described_class::OPENSSL_KEY_BITS - ) - - expect(RMT::Execute).to receive(:on_target!).with( - 'openssl', 'req', '-x509', '-new', '-nodes', - '-key', ssl_files[:ca_private_key], '-sha256', '-days', described_class::OPENSSL_CA_VALIDITY_DAYS, - '-out', ssl_files[:ca_certificate], '-config', ssl_files[:ca_config] - ) - - expect(RMT::Execute).to receive(:on_target!).with( - 'openssl', 'req', '-new', '-key', ssl_files[:server_private_key], - '-out', ssl_files[:server_csr], '-config', ssl_files[:server_config] - ) - - expect(RMT::Execute).to receive(:on_target!).with( - 'openssl', 'x509', '-req', '-in', ssl_files[:server_csr], - '-out', ssl_files[:server_certificate], '-CA', ssl_files[:ca_certificate], - '-CAkey', ssl_files[:ca_private_key], '-days', described_class::OPENSSL_SERVER_CERT_VALIDITY_DAYS, - '-sha256', '-CAcreateserial', '-extensions', 'v3_server_sign', - '-extfile', ssl_files[:server_config] - ) - - expect(Yast::SCR).to receive(:Read).with(scr_path, ssl_files[:server_certificate]).and_return(server_cert) - expect(Yast::SCR).to receive(:Read).with(scr_path, ssl_files[:ca_certificate]).and_return(ca_cert) - expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:server_certificate], server_cert + ca_cert) + context 'when CA is not yet generated' do + it 'generates the CA and server certificates' do + expect(RMT::SSL::ConfigGenerator).to receive(:new).and_return(config_generator_double) + expect(generator).to receive(:ca_present?).and_return(false).exactly(2).times + expect(config_generator_double).to receive(:make_ca_config).and_return(ca_config) + expect(config_generator_double).to receive(:make_server_config).and_return(server_config) + + expect(generator).to receive(:create_files) + + expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:ca_serial_file], '01') + expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:ca_config], ca_config) + expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:server_config], server_config) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'genrsa', '-out', + ssl_files[:ca_private_key], described_class::OPENSSL_KEY_BITS + ) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'genrsa', '-out', + ssl_files[:server_private_key], described_class::OPENSSL_KEY_BITS + ) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'req', '-x509', '-new', '-nodes', + '-key', ssl_files[:ca_private_key], '-sha256', '-days', described_class::OPENSSL_CA_VALIDITY_DAYS, + '-out', ssl_files[:ca_certificate], '-config', ssl_files[:ca_config] + ) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'req', '-new', '-key', ssl_files[:server_private_key], + '-out', ssl_files[:server_csr], '-config', ssl_files[:server_config] + ) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'x509', '-req', '-in', ssl_files[:server_csr], + '-out', ssl_files[:server_certificate], '-CA', ssl_files[:ca_certificate], + '-CAkey', ssl_files[:ca_private_key], '-days', described_class::OPENSSL_SERVER_CERT_VALIDITY_DAYS, + '-sha256', '-CAcreateserial', '-extensions', 'v3_server_sign', + '-extfile', ssl_files[:server_config] + ) + + expect(Yast::SCR).to receive(:Read).with(scr_path, ssl_files[:server_certificate]).and_return(server_cert) + expect(Yast::SCR).to receive(:Read).with(scr_path, ssl_files[:ca_certificate]).and_return(ca_cert) + expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:server_certificate], server_cert + ca_cert) - expect(RMT::Execute).to receive(:on_target!).with('chown', 'root:nginx', ssl_files[:ca_certificate]) - expect(RMT::Execute).to receive(:on_target!).with('chmod', '0640', ssl_files[:ca_certificate]) + expect(RMT::Execute).to receive(:on_target!).with('chown', 'root:nginx', ssl_files[:ca_certificate]) + expect(RMT::Execute).to receive(:on_target!).with('chmod', '0640', ssl_files[:ca_certificate]) - generator.generate(common_name, alt_names) + generator.generate(common_name, alt_names) + end + end + + context 'when CA is already present' do + it 'generates only the server certificate' do + expect(RMT::SSL::ConfigGenerator).to receive(:new).and_return(config_generator_double) + expect(generator).to receive(:ca_present?).and_return(true).exactly(2).times + expect(config_generator_double).to receive(:make_server_config).and_return(server_config) + + expect(generator).to receive(:create_files) + + expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:server_config], server_config) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'genrsa', '-out', + ssl_files[:server_private_key], described_class::OPENSSL_KEY_BITS + ) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'req', '-new', '-key', ssl_files[:server_private_key], + '-out', ssl_files[:server_csr], '-config', ssl_files[:server_config] + ) + + expect(RMT::Execute).to receive(:on_target!).with( + 'openssl', 'x509', '-req', '-in', ssl_files[:server_csr], + '-out', ssl_files[:server_certificate], '-CA', ssl_files[:ca_certificate], + '-CAkey', ssl_files[:ca_private_key], '-days', described_class::OPENSSL_SERVER_CERT_VALIDITY_DAYS, + '-sha256', '-CAcreateserial', '-extensions', 'v3_server_sign', + '-extfile', ssl_files[:server_config] + ) + + expect(Yast::SCR).to receive(:Read).with(scr_path, ssl_files[:server_certificate]).and_return(server_cert) + expect(Yast::SCR).to receive(:Read).with(scr_path, ssl_files[:ca_certificate]).and_return(ca_cert) + expect(Yast::SCR).to receive(:Write).with(scr_path, ssl_files[:server_certificate], server_cert + ca_cert) + + expect(RMT::Execute).to receive(:on_target!).with('chown', 'root:nginx', ssl_files[:ca_certificate]) + expect(RMT::Execute).to receive(:on_target!).with('chmod', '0640', ssl_files[:ca_certificate]) + + generator.generate(common_name, alt_names) + end end it 'handles Cheetah::ExecutionFailed exceptions' do expect(RMT::SSL::ConfigGenerator).to receive(:new).and_raise(Cheetah::ExecutionFailed.new('cmd', 1, '', 'Dummy error')) - expect(Yast::Report).to receive(:Error).with("An error ocurred during SSL certificate generation:\nDummy error\n") + expect(Yast::Report).to receive(:Error).with("An error occurred during SSL certificate generation:\nDummy error\n") generator.generate(common_name, alt_names) end it 'handles RMT::SSL::Exception exceptions' do expect(RMT::SSL::ConfigGenerator).to receive(:new).and_raise(RMT::SSL::Exception.new('Dummy error')) - expect(Yast::Report).to receive(:Error).with("An error ocurred during SSL certificate generation:\nDummy error\n") + expect(Yast::Report).to receive(:Error).with("An error occurred during SSL certificate generation:\nDummy error\n") generator.generate(common_name, alt_names) end end @@ -140,7 +216,7 @@ expect(generator).to receive(:write_file).with(file, '') expect(RMT::Execute).to receive(:on_target!).with('chmod', '0600', file) end - generator.send(:create_files) + generator.send(:create_files, ssl_files) end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/spec/rmt/ssl/config_generator_spec.rb new/yast2-rmt-0.0.4/spec/rmt/ssl/config_generator_spec.rb --- old/yast2-rmt-0.0.3/spec/rmt/ssl/config_generator_spec.rb 2018-04-04 13:29:22.681899544 +0200 +++ new/yast2-rmt-0.0.4/spec/rmt/ssl/config_generator_spec.rb 2018-04-24 11:54:43.422604842 +0200 @@ -25,6 +25,8 @@ let(:dns_names) { ['foo.example.org', 'bar.example.org'] } let(:ip_addresses) { ['1.1.1.1', '1111:2222:3333:4444:5555:6666:7777:8888'] } let(:alt_names) { dns_names + ip_addresses } + let(:template_system_location) { File.join(File.expand_path('./../../../src/data/rmt', __dir__), template_filename) } + let(:template) { File.read(File.join('src/data/rmt', template_filename)) } describe '#new' do it 'matches DNS names' do @@ -37,25 +39,38 @@ end describe '#make_ca_config' do + let(:template_filename) { 'rmt-ca.cnf.erb' } + it 'contains correct common name' do + expect(File).to receive(:read).with(template_system_location).and_return(template) expect(generator.make_ca_config).to match(/CN\s*=\s*RMT Certificate Authority \(#{common_name}\)/) end + + it 'writes to correct file' do + expect(File).to receive(:read).with(template_system_location).and_return(template) + generator.make_ca_config + end end describe '#make_server_config' do subject(:config) { generator.make_server_config } + let(:template_filename) { 'rmt-server-cert.cnf.erb' } + it 'contains correct common name' do + expect(File).to receive(:read).with(template_system_location).and_return(template) expect(config).to match(/CN\s*=\s*#{common_name}/) end it 'contains DNS alternative common names' do + expect(File).to receive(:read).with(template_system_location).and_return(template) dns_names.each do |alt_name| expect(config).to match(/DNS\.\d+\s*=\s*#{alt_name}/) end end it 'contains IP alternative common names' do + expect(File).to receive(:read).with(template_system_location).and_return(template) ip_addresses.each do |alt_name| expect(config).to match(/IP\.\d+\s*=\s*#{alt_name}/) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/spec/rmt/wizard_final_page_spec.rb new/yast2-rmt-0.0.4/spec/rmt/wizard_final_page_spec.rb --- old/yast2-rmt-0.0.3/spec/rmt/wizard_final_page_spec.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-rmt-0.0.4/spec/rmt/wizard_final_page_spec.rb 2018-04-16 15:10:34.949032563 +0200 @@ -0,0 +1,78 @@ +# Copyright (c) 2018 SUSE LLC. +# All Rights Reserved. + +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 or 3 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 about this file by physical or electronic mail, +# you may find current contact information at www.suse.com + +require 'rmt/wizard_final_page' + +Yast.import 'Wizard' + +describe RMT::WizardFinalPage do + subject(:final_page) { described_class.new(config) } + + let(:config) { {} } + + describe '#next_handler' do + it 'finishes when next button is pressed' do + expect(final_page).to receive(:finish_dialog).with(:next) + final_page.next_handler + end + end + + describe '#abort_handler' do + it 'finishes when abort button is pressed' do + expect(final_page).to receive(:finish_dialog).with(:abort) + final_page.abort_handler + end + end + + describe '#back_handler' do + it 'finishes when back button is pressed' do + expect(final_page).to receive(:finish_dialog).with(:back) + final_page.back_handler + end + end + + describe '#render_content' do + it 'renders UI elements' do + expect(Yast::Wizard).to receive(:SetContents) + final_page.render_content + end + end + + describe '#run' do + context 'when restarting the service succeeds' do + it 'renders content and enters the event loop' do + expect(Yast::Service).to receive(:Enable).with('rmt').and_return(true) + expect(Yast::Service).to receive(:Restart).with('rmt').and_return(true) + expect(final_page).to receive(:render_content) + expect(final_page).to receive(:event_loop) + final_page.run + end + end + + context 'when restarting the service fails' do + it 'displays the error, renders content and enters the event loop' do + expect(Yast::Service).to receive(:Enable).with('rmt').and_return(true) + expect(Yast::Service).to receive(:Restart).with('rmt').and_return(false) + expect(Yast::Report).to receive(:Error).with("Failed to enable and restart service 'rmt'") + expect(final_page).to receive(:render_content) + expect(final_page).to receive(:event_loop) + final_page.run + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/spec/rmt/wizard_maria_db_page_spec.rb new/yast2-rmt-0.0.4/spec/rmt/wizard_maria_db_page_spec.rb --- old/yast2-rmt-0.0.3/spec/rmt/wizard_maria_db_page_spec.rb 2018-04-04 15:27:00.475284854 +0200 +++ new/yast2-rmt-0.0.4/spec/rmt/wizard_maria_db_page_spec.rb 2018-04-16 15:10:34.949032563 +0200 @@ -25,7 +25,16 @@ describe RMT::WizardMariaDBPage do subject(:mariadb_page) { described_class.new(config) } - let(:config) { { 'database' => { 'username' => 'user_mcuserface', 'password' => 'test' } } } + let(:config) do + { + 'database' => { + 'username' => 'user_mcuserface', + 'password' => 'test', + 'hostname' => 'localhost', + 'database' => 'rmt' + } + } + end describe '#render_content' do it 'renders UI elements' do @@ -40,11 +49,19 @@ end describe '#run' do - it 'renders content and runs the event loop' do + it 'renders content and runs the event loop when the DB is not set up' do + expect(mariadb_page).to receive(:check_db_credentials).and_return(false) expect(mariadb_page).to receive(:render_content) expect(mariadb_page).to receive(:event_loop) mariadb_page.run end + + it 'skips DB creation when DB is already set up' do + expect(mariadb_page).to receive(:check_db_credentials).and_return(true) + expect(Yast::Popup).to receive(:Message).with('Database has already been configured, skipping database setup.') + expect(mariadb_page).to receive(:finish_dialog).with(:next) + mariadb_page.run + end end describe '#abort_handler' do @@ -187,4 +204,38 @@ expect(mariadb_page.create_database_and_user).to be(true) end end + + describe '#check_db_credentials' do + context 'when the required configuration keys are missing in the DB section' do + let(:config) { { 'database' => {} } } + + it('returns false') { expect(mariadb_page.check_db_credentials).to be(false) } + end + + context 'when the required configuration keys are present and are invalid' do + it 'returns false' do + expect(RMT::Execute).to receive(:on_target!).with( + ['echo', 'select 1;'], + [ + 'mysql', '-u', config['database']['username'], "-p#{config['database']['password']}", + '-D', config['database']['database'], '-h', config['database']['hostname'] + ] + ).and_raise(Cheetah::ExecutionFailed.new('command', 255, '', 'Something went wrong')) + expect(mariadb_page.check_db_credentials).to be(false) + end + end + + context 'when the required configuration keys are present and are valid' do + it 'returns false' do + expect(RMT::Execute).to receive(:on_target!).with( + ['echo', 'select 1;'], + [ + 'mysql', '-u', config['database']['username'], "-p#{config['database']['password']}", + '-D', config['database']['database'], '-h', config['database']['hostname'] + ] + ) + expect(mariadb_page.check_db_credentials).to be(true) + end + end + end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/spec/rmt/wizard_spec.rb new/yast2-rmt-0.0.4/spec/rmt/wizard_spec.rb --- old/yast2-rmt-0.0.3/spec/rmt/wizard_spec.rb 2018-03-27 15:39:21.355318371 +0200 +++ new/yast2-rmt-0.0.4/spec/rmt/wizard_spec.rb 2018-04-16 15:10:34.949032563 +0200 @@ -29,6 +29,7 @@ let(:scc_page_double) { instance_double(RMT::WizardSCCPage) } let(:db_page_double) { instance_double(RMT::WizardMariaDBPage) } let(:ssl_page_double) { instance_double(RMT::WizardSSLPage) } + let(:final_page_double) { instance_double(RMT::WizardFinalPage) } it 'runs and goes through the sequence' do expect(Yast::Confirm).to receive(:MustBeRoot).and_return(true) @@ -46,6 +47,9 @@ expect(RMT::WizardSSLPage).to receive(:new).and_return(ssl_page_double) expect(ssl_page_double).to receive(:run).and_return(:next) + expect(RMT::WizardFinalPage).to receive(:new).and_return(final_page_double) + expect(final_page_double).to receive(:run).and_return(:next) + expect(Yast::UI).to receive(:CloseDialog) wizard.run end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/spec/rmt/wizard_ssl_page_spec.rb new/yast2-rmt-0.0.4/spec/rmt/wizard_ssl_page_spec.rb --- old/yast2-rmt-0.0.3/spec/rmt/wizard_ssl_page_spec.rb 2018-04-04 15:27:08.159320139 +0200 +++ new/yast2-rmt-0.0.4/spec/rmt/wizard_ssl_page_spec.rb 2018-04-24 11:54:43.422604842 +0200 @@ -36,7 +36,6 @@ describe '#render_content' do it 'renders UI elements' do - expect(Yast::Wizard).to receive(:SetNextButton).with(:next, Yast::Label.FinishButton) expect(Yast::Wizard).to receive(:SetContents) expect(ssl_page).to receive(:query_common_name) @@ -118,7 +117,7 @@ describe '#run' do context 'when certificates are already present' do it 'shows a message and finishes' do - expect(generator_double).to receive(:check_certs_presence).and_return(true) + expect(generator_double).to receive(:server_cert_present?).and_return(true) expect(Yast::Popup).to receive(:Message).with('SSL certificates already present, skipping generation.') expect(ssl_page).to receive(:finish_dialog).with(:next) ssl_page.run @@ -127,7 +126,7 @@ context 'when certificates are not present' do it 'renders content and enters the event loop' do - expect(generator_double).to receive(:check_certs_presence).and_return(false) + expect(generator_double).to receive(:server_cert_present?).and_return(false) expect(ssl_page).to receive(:render_content) expect(ssl_page).to receive(:event_loop) ssl_page.run @@ -140,6 +139,13 @@ expect(RMT::Execute).to receive(:on_target!).with('hostname', '--long', stdout: :capture).and_return("\n\n\nexample.org\n\n") expect(ssl_page.send(:query_common_name)).to eq('example.org') end + + it 'handles exceptions and sets the default common name' do + expect(RMT::Execute).to receive(:on_target!).with('hostname', '--long', stdout: :capture).and_raise( + Cheetah::ExecutionFailed.new('command', 255, '', 'Something went wrong') + ) + expect(ssl_page.send(:query_common_name)).to eq('rmt.server') + end end describe '#query_alt_names' do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/src/desktop/rmt.desktop new/yast2-rmt-0.0.4/src/desktop/rmt.desktop --- old/yast2-rmt-0.0.3/src/desktop/rmt.desktop 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-rmt-0.0.4/src/desktop/rmt.desktop 2018-04-18 11:54:50.762844172 +0200 @@ -0,0 +1,16 @@ +[Desktop Entry] +Type=Application +Categories=Settings;System;Qt;X-SuSE-YaST;X-SuSE-YaST-Support; + +X-SuSE-YaST-Call=rmt +X-SuSE-YaST-RootOnly=true +X-SuSE-YaST-Group=Net_advanced +X-SuSE-YaST-AutoInst= +X-SuSE-YaST-AutoInstResource=rmt + +Icon=yast-rmt +Exec=/sbin/yast2 rmt + +Name=RMT Configuration +GenericName=RMT Configuration +StartupNotify=true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/src/lib/rmt/ssl/certificate_generator.rb new/yast2-rmt-0.0.4/src/lib/rmt/ssl/certificate_generator.rb --- old/yast2-rmt-0.0.3/src/lib/rmt/ssl/certificate_generator.rb 2018-04-04 15:17:14.972628767 +0200 +++ new/yast2-rmt-0.0.4/src/lib/rmt/ssl/certificate_generator.rb 2018-04-24 11:54:43.426604857 +0200 @@ -51,32 +51,43 @@ @ssl_paths = OPENSSL_FILES.map { |id, filename| [id, File.join(RMT_SSL_DIR, filename)] }.to_h end - def check_certs_presence - %i[ca_private_key ca_certificate server_private_key server_certificate].each do |file_type| + def ca_present? + %i[ca_private_key ca_certificate].each do |file_type| return true if File.exist?(@ssl_paths[file_type]) && !File.zero?(@ssl_paths[file_type]) end + false + end + def server_cert_present? + %i[server_private_key server_certificate].each do |file_type| + return true if File.exist?(@ssl_paths[file_type]) && !File.zero?(@ssl_paths[file_type]) + end false end def generate(common_name, alt_names) config_generator = RMT::SSL::ConfigGenerator.new(common_name, alt_names) - create_files + files = @ssl_paths.dup + %i[ca_certificate ca_private_key ca_serial_file ca_config].each { |file| files.delete(file) } if ca_present? - Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:ca_serial_file], '01') - Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:ca_config], config_generator.make_ca_config) - Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:server_config], config_generator.make_server_config) + create_files(files) - RMT::Execute.on_target!('openssl', 'genrsa', '-out', @ssl_paths[:ca_private_key], OPENSSL_KEY_BITS) - RMT::Execute.on_target!('openssl', 'genrsa', '-out', @ssl_paths[:server_private_key], OPENSSL_KEY_BITS) + Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:server_config], config_generator.make_server_config) - RMT::Execute.on_target!( - 'openssl', 'req', '-x509', '-new', '-nodes', '-key', @ssl_paths[:ca_private_key], - '-sha256', '-days', OPENSSL_CA_VALIDITY_DAYS, '-out', @ssl_paths[:ca_certificate], - '-config', @ssl_paths[:ca_config] - ) + unless ca_present? + Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:ca_serial_file], '01') + Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:ca_config], config_generator.make_ca_config) + + RMT::Execute.on_target!('openssl', 'genrsa', '-out', @ssl_paths[:ca_private_key], OPENSSL_KEY_BITS) + RMT::Execute.on_target!( + 'openssl', 'req', '-x509', '-new', '-nodes', '-key', @ssl_paths[:ca_private_key], + '-sha256', '-days', OPENSSL_CA_VALIDITY_DAYS, '-out', @ssl_paths[:ca_certificate], + '-config', @ssl_paths[:ca_config] + ) + end + RMT::Execute.on_target!('openssl', 'genrsa', '-out', @ssl_paths[:server_private_key], OPENSSL_KEY_BITS) RMT::Execute.on_target!( 'openssl', 'req', '-new', '-key', @ssl_paths[:server_private_key], '-out', @ssl_paths[:server_csr], '-config', @ssl_paths[:server_config] @@ -101,7 +112,7 @@ rescue Cheetah::ExecutionFailed, RMT::SSL::Exception => e Yast.import 'Report' Yast::Report.Error( - _("An error ocurred during SSL certificate generation:\n%<error>s\n") % { + _("An error occurred during SSL certificate generation:\n%<error>s\n") % { error: (e.class == Cheetah::ExecutionFailed) ? e.stderr : e.to_s } ) @@ -110,8 +121,8 @@ protected # Creates empty files and sets 600 permissions - def create_files - @ssl_paths.each_value do |file| + def create_files(files) + files.each_value do |file| write_file(file, '') RMT::Execute.on_target!('chmod', '0600', file) end @@ -119,6 +130,6 @@ def write_file(filename, content) result = Yast::SCR.Write(Yast.path('.target.string'), filename, content) - raise RMT::SSL::Exception, "Failed to write file #{filename}" unless result + raise RMT::SSL::Exception, _('Failed to write file %<filename>s' % { filename: filename }) unless result end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/src/lib/rmt/wizard.rb new/yast2-rmt-0.0.4/src/lib/rmt/wizard.rb --- old/yast2-rmt-0.0.3/src/lib/rmt/wizard.rb 2018-04-04 15:21:33.149795816 +0200 +++ new/yast2-rmt-0.0.4/src/lib/rmt/wizard.rb 2018-04-16 15:10:34.949032563 +0200 @@ -20,6 +20,7 @@ require 'rmt/wizard_scc_page' require 'rmt/wizard_maria_db_page' require 'rmt/wizard_ssl_page' +require 'rmt/wizard_final_page' module RMT end @@ -47,14 +48,16 @@ aliases = { 'step1' => -> { RMT::WizardSCCPage.new(@config).run }, 'step2' => -> { RMT::WizardMariaDBPage.new(@config).run }, - 'step3' => -> { RMT::WizardSSLPage.new(@config).run } + 'step3' => -> { RMT::WizardSSLPage.new(@config).run }, + 'finish' => -> { RMT::WizardFinalPage.new(@config).run } } sequence = { 'ws_start' => 'step1', 'step1' => { abort: :abort, next: 'step2' }, 'step2' => { abort: :abort, next: 'step3' }, - 'step3' => { abort: :abort, next: :next } + 'step3' => { abort: :abort, next: 'finish' }, + 'finish' => { abort: :abort, next: :next } } Wizard.CreateDialog() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/src/lib/rmt/wizard_final_page.rb new/yast2-rmt-0.0.4/src/lib/rmt/wizard_final_page.rb --- old/yast2-rmt-0.0.3/src/lib/rmt/wizard_final_page.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-rmt-0.0.4/src/lib/rmt/wizard_final_page.rb 2018-04-16 15:10:34.949032563 +0200 @@ -0,0 +1,74 @@ +# Copyright (c) 2018 SUSE LLC. +# All Rights Reserved. + +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 or 3 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 about this file by physical or electronic mail, +# you may find current contact information at www.suse.com + +require 'ui/event_dispatcher' + +module RMT; end + +class RMT::WizardFinalPage < Yast::Client + include ::UI::EventDispatcher + + Yast.import 'Report' + Yast.import 'Service' + + def initialize(config) + textdomain 'rmt' + @config = config + end + + def render_content + Wizard.SetNextButton(:next, Label.FinishButton) + + contents = + HBox( + HSpacing(1), + VBox( + VSpacing(1), + Label(_('RMT setup is now complete.')), + VSpacing(1) + ), + HSpacing(1) + ) + + Wizard.SetContents( + _('RMT configuration'), + contents, + _('<p>RMT setup is now complete.</p>'), + true, + true + ) + end + + def next_handler + finish_dialog(:next) + end + + def abort_handler + finish_dialog(:abort) + end + + def back_handler + finish_dialog(:back) + end + + def run + Yast::Report.Error(_("Failed to enable and restart service 'rmt'")) unless (Yast::Service.Enable('rmt') && Yast::Service.Restart('rmt')) + render_content + event_loop + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/src/lib/rmt/wizard_maria_db_page.rb new/yast2-rmt-0.0.4/src/lib/rmt/wizard_maria_db_page.rb --- old/yast2-rmt-0.0.3/src/lib/rmt/wizard_maria_db_page.rb 2018-04-04 15:26:06.627037592 +0200 +++ new/yast2-rmt-0.0.4/src/lib/rmt/wizard_maria_db_page.rb 2018-04-16 15:10:34.949032563 +0200 @@ -18,6 +18,7 @@ require 'rmt/maria_db/current_root_password_dialog' require 'rmt/maria_db/new_root_password_dialog' +require 'rmt/execute' require 'ui/event_dispatcher' module RMT; end @@ -53,7 +54,7 @@ Wizard.SetContents( _('RMT configuration step 2/3'), contents, - '<p>This step of the wizard performs the necessary database setup.</p>', + _('<p>This step of the wizard performs the necessary database setup.</p>'), true, true ) @@ -81,7 +82,7 @@ new_root_password = dialog.run if !new_root_password || new_root_password.empty? || !dialog.set_root_password(new_root_password, @config['database']['hostname']) - Report.Error('Setting new root password failed') + Report.Error(_('Setting new root password failed')) return end @@ -94,7 +95,7 @@ if @root_password create_database_and_user else - Report.Error('Root password not provided, skipping database setup.') + Report.Error(_('Root password not provided, skipping database setup.')) end RMT::Utils.write_config_file(@config) @@ -102,10 +103,31 @@ end def run + if check_db_credentials + Yast::Popup.Message(_('Database has already been configured, skipping database setup.')) + return finish_dialog(:next) + end render_content event_loop end + def check_db_credentials + %w[username password database hostname].each do |key| + return false if (!@config['database'][key] || @config['database'][key].empty?) + end + + RMT::Execute.on_target!( + ['echo', 'select 1;'], + [ + 'mysql', '-u', @config['database']['username'], "-p#{@config['database']['password']}", + '-D', @config['database']['database'], '-h', @config['database']['hostname'] + ] + ) + true + rescue Cheetah::ExecutionFailed + false + end + def root_password_empty? RMT::Utils.run_command( "echo 'show databases;' | mysql -u root -h %1 2>/dev/null", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/src/lib/rmt/wizard_scc_page.rb new/yast2-rmt-0.0.4/src/lib/rmt/wizard_scc_page.rb --- old/yast2-rmt-0.0.3/src/lib/rmt/wizard_scc_page.rb 2018-04-04 15:26:11.315059118 +0200 +++ new/yast2-rmt-0.0.4/src/lib/rmt/wizard_scc_page.rb 2018-04-16 15:10:34.949032563 +0200 @@ -56,7 +56,7 @@ Wizard.SetContents( _('RMT configuration step 1/3'), contents, - "<p>Organization credentials can be found on Organization page at <a href='https://scc.suse.com/'>SUSE Customer Center</a>.</p>", + _("<p>Organization credentials can be found on Organization page at <a href='https://scc.suse.com/'>SUSE Customer Center</a>.</p>"), true, true ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-rmt-0.0.3/src/lib/rmt/wizard_ssl_page.rb new/yast2-rmt-0.0.4/src/lib/rmt/wizard_ssl_page.rb --- old/yast2-rmt-0.0.3/src/lib/rmt/wizard_ssl_page.rb 2018-04-04 15:24:17.146538672 +0200 +++ new/yast2-rmt-0.0.4/src/lib/rmt/wizard_ssl_page.rb 2018-04-24 11:54:43.450604946 +0200 @@ -65,11 +65,10 @@ ) ) - Wizard.SetNextButton(:next, Label.FinishButton) Wizard.SetContents( _('RMT configuration step 3/3'), contents, - '<p>This step of the wizard generates the required SSL certificates.</p>', + _('<p>This step of the wizard generates the required SSL certificates.</p>'), true, true ) @@ -117,8 +116,8 @@ end def run - if @cert_generator.check_certs_presence - Yast::Popup.Message('SSL certificates already present, skipping generation.') + if @cert_generator.server_cert_present? + Yast::Popup.Message(_('SSL certificates already present, skipping generation.')) return finish_dialog(:next) end render_content @@ -130,6 +129,8 @@ def query_common_name output = RMT::Execute.on_target!('hostname', '--long', stdout: :capture) output.strip + rescue Cheetah::ExecutionFailed + 'rmt.server' end def query_alt_names
participants (1)
-
root@hilbert.suse.de