Hello community,
here is the log from the commit of package yast2-installation for
openSUSE:Factory checked in at 2016-05-19 12:04:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-installation (Old)
and /work/SRC/openSUSE:Factory/.yast2-installation.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-installation"
Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-installation/yast2-installation.changes
2016-05-10 09:26:39.000000000 +0200
+++
/work/SRC/openSUSE:Factory/.yast2-installation.new/yast2-installation.changes
2016-05-19 12:04:33.000000000 +0200
@@ -1,0 +2,32 @@
+Tue May 17 08:17:51 UTC 2016 - [email protected]
+
+- Visual improvement in the SSH keys importing proposal summary
+
+-------------------------------------------------------------------
+Mon May 16 16:39:34 UTC 2016 - [email protected]
+
+- The user is now informed about SSH keys to be reused (copied
+ from a previous system) during system installation.
+- The user can select a different partition (or none) to read the
+ keys from and whether to also copy config files.
+- SSH import functionality not longer depending from
+ "copy_to_system" feature.
+- Fate#319624
+- 3.1.187
+
+-------------------------------------------------------------------
+Mon May 16 08:29:25 UTC 2016 - [email protected]
+
+- SSH installation: handle closing the initial installation screen
+ by the window manager close button (bsc#979499)
+- 3.1.186
+
+-------------------------------------------------------------------
+Mon May 9 15:14:22 CEST 2016 - [email protected]
+
+- Do not copy licenses from inst-sys to target system.
+ Showing EULA location in the installed system.
+ (fate#219341)
+- 3.1.185
+
+-------------------------------------------------------------------
Old:
----
yast2-installation-3.1.184.tar.bz2
New:
----
yast2-installation-3.1.187.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast2-installation.spec ++++++
--- /var/tmp/diff_new_pack.OmButz/_old 2016-05-19 12:04:34.000000000 +0200
+++ /var/tmp/diff_new_pack.OmButz/_new 2016-05-19 12:04:34.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-installation
-Version: 3.1.184
+Version: 3.1.187
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
++++++ yast2-installation-3.1.184.tar.bz2 -> yast2-installation-3.1.187.tar.bz2
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/package/yast2-installation.changes
new/yast2-installation-3.1.187/package/yast2-installation.changes
--- old/yast2-installation-3.1.184/package/yast2-installation.changes
2016-05-09 14:24:55.000000000 +0200
+++ new/yast2-installation-3.1.187/package/yast2-installation.changes
2016-05-18 11:28:09.000000000 +0200
@@ -1,4 +1,36 @@
-------------------------------------------------------------------
+Tue May 17 08:17:51 UTC 2016 - [email protected]
+
+- Visual improvement in the SSH keys importing proposal summary
+
+-------------------------------------------------------------------
+Mon May 16 16:39:34 UTC 2016 - [email protected]
+
+- The user is now informed about SSH keys to be reused (copied
+ from a previous system) during system installation.
+- The user can select a different partition (or none) to read the
+ keys from and whether to also copy config files.
+- SSH import functionality not longer depending from
+ "copy_to_system" feature.
+- Fate#319624
+- 3.1.187
+
+-------------------------------------------------------------------
+Mon May 16 08:29:25 UTC 2016 - [email protected]
+
+- SSH installation: handle closing the initial installation screen
+ by the window manager close button (bsc#979499)
+- 3.1.186
+
+-------------------------------------------------------------------
+Mon May 9 15:14:22 CEST 2016 - [email protected]
+
+- Do not copy licenses from inst-sys to target system.
+ Showing EULA location in the installed system.
+ (fate#219341)
+- 3.1.185
+
+-------------------------------------------------------------------
Fri May 6 11:09:28 UTC 2016 - [email protected]
- get more texts for roles dialog from control file, allow
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/package/yast2-installation.spec
new/yast2-installation-3.1.187/package/yast2-installation.spec
--- old/yast2-installation-3.1.184/package/yast2-installation.spec
2016-05-09 14:24:55.000000000 +0200
+++ new/yast2-installation-3.1.187/package/yast2-installation.spec
2016-05-18 11:28:09.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-installation
-Version: 3.1.184
+Version: 3.1.187
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-installation-3.1.184/src/Makefile.am
new/yast2-installation-3.1.187/src/Makefile.am
--- old/yast2-installation-3.1.184/src/Makefile.am 2016-05-09
14:24:55.000000000 +0200
+++ new/yast2-installation-3.1.187/src/Makefile.am 2016-05-18
11:28:09.000000000 +0200
@@ -49,6 +49,7 @@
clients/inst_rpmcopy_secondstage.rb \
clients/inst_save_hardware_status.rb \
clients/inst_scenarios.rb \
+ clients/inst_ssh_import.rb \
clients/inst_system_analysis.rb \
clients/inst_system_role.rb \
clients/inst_upgrade_urls.rb \
@@ -66,6 +67,7 @@
clients/save_config_finish.rb \
clients/save_hw_status_finish.rb \
clients/snapshots_finish.rb \
+ clients/ssh_import_proposal.rb \
clients/ssh_settings_finish.rb \
clients/stroj-casu.rb \
clients/switch_scr_finish.rb \
@@ -116,7 +118,11 @@
lib/installation/select_system_role.rb \
lib/installation/snapshots_finish.rb \
lib/installation/updates_manager.rb \
- lib/installation/update_repository.rb
+ lib/installation/update_repository.rb \
+ lib/installation/ssh_config.rb \
+ lib/installation/ssh_key.rb \
+ lib/installation/ssh_config_file.rb \
+ lib/installation/ssh_importer.rb
ylibtransferdir = "${yast2dir}/lib/transfer"
ylibtransfer_DATA = \
@@ -174,6 +180,7 @@
lib/installation/clients/proxy_finish.rb \
lib/installation/clients/save_config_finish.rb \
lib/installation/clients/save_hw_status_finish.rb \
+ lib/installation/clients/ssh_import_proposal.rb \
lib/installation/clients/ssh_settings_finish.rb \
lib/installation/clients/stroj-casu.rb \
lib/installation/clients/switch_scr_finish.rb \
@@ -184,6 +191,10 @@
lib/installation/clients/x11_finish.rb \
lib/installation/clients/yast_inf_finish.rb
-EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(scrconf_DATA)
$(schemafiles_DATA) $(desktop_DATA) $(fillup_DATA) $(ylib_DATA)
$(ylibtransfer_DATA)
+ylibdialogdir = "${yast2dir}/lib/installation/dialogs"
+ylibdialog_DATA = \
+ lib/installation/dialogs/ssh_import.rb
+
+EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(scrconf_DATA)
$(schemafiles_DATA) $(desktop_DATA) $(fillup_DATA) $(ylibdialog_DATA)
$(ylib_DATA) $(ylibtransfer_DATA)
include $(top_srcdir)/Makefile.am.common
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/clients/inst_ssh_import.rb
new/yast2-installation-3.1.187/src/clients/inst_ssh_import.rb
--- old/yast2-installation-3.1.184/src/clients/inst_ssh_import.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/src/clients/inst_ssh_import.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,22 @@
+# encoding: utf-8
+
+# Copyright (c) 2016 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 "installation/dialogs/ssh_import"
+Yast::SshImportDialog.new.run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/clients/ssh_import_proposal.rb
new/yast2-installation-3.1.187/src/clients/ssh_import_proposal.rb
--- old/yast2-installation-3.1.184/src/clients/ssh_import_proposal.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/src/clients/ssh_import_proposal.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,2 @@
+require "installation/clients/ssh_import_proposal"
+Yast::SshImportProposalClient.run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/clients/copy_files_finish.rb
new/yast2-installation-3.1.187/src/lib/installation/clients/copy_files_finish.rb
---
old/yast2-installation-3.1.184/src/lib/installation/clients/copy_files_finish.rb
2016-05-09 14:24:55.000000000 +0200
+++
new/yast2-installation-3.1.187/src/lib/installation/clients/copy_files_finish.rb
2016-05-18 11:28:09.000000000 +0200
@@ -29,6 +29,7 @@
# Jiri Srain <[email protected]>
#
require "fileutils"
+require "installation/ssh_importer"
module Yast
class CopyFilesFinishClient < Client
@@ -199,82 +200,12 @@
# FATE #301937, items are defined in the control file
SystemFilesCopy.SaveInstSysContent
- # Remove old eula.txt
- # bugzilla #208908
- @eula_txt = Builtins.sformat(
- "%1%2/eula.txt",
- Installation.destdir,
- Directory.etcdir
- )
- if FileUtils.Exists(@eula_txt)
- SCR.Execute(path(".target.remove"), @eula_txt)
- end
-
- # FATE #304865: Enhance YaST Modules to cooperate better handling the
product licenses
- @license_dir = ProductFeatures.GetStringFeature(
- "globals",
- "base_product_license_directory"
- )
- if @license_dir.nil? || @license_dir == ""
- @license_dir = Builtins.sformat(
- "%1%2/licenses/base/",
- Installation.destdir,
- Directory.etcdir
- )
- Builtins.y2warning(
- "No 'base_product_license_directory' set, using %1",
- @license_dir
- )
- else
- @license_dir = Builtins.sformat(
- "%1/%2",
- Installation.destdir,
- @license_dir
- )
- Builtins.y2milestone("Using license dir: %1", @license_dir)
- end
-
- # BNC #594042: Multiple license locations
- @license_locations = ["/usr/share/doc/licenses/", "/"]
-
- Builtins.foreach(@license_locations) do |license_location|
- license_location = Builtins.sformat(
- "%1/license.tar.gz",
- license_location
- )
- next if !FileUtils.Exists(license_location)
- # Copy licenses so it can be used in firstboot later
- # bnc #396976
- cmd = Convert.to_map(
- WFM.Execute(
- path(".local.bash_output"),
- Builtins.sformat(
- "mkdir -p '%1' && cd '%1' && rm -rf license*.*; cd '%1' && tar
-xf '%2'",
- String.Quote(@license_dir),
- String.Quote(license_location)
- )
- )
- )
- if Ops.get_integer(cmd, "exit", -1) == 0
- Builtins.y2milestone(
- "Copying %1 to %2 was successful",
- license_location,
- @license_dir
- )
- else
- Builtins.y2error(
- "Copying %1 to %2 has failed: %3",
- license_location,
- @license_dir,
- cmd
- )
- end
- raise Break
- end
-
# bugzila #328126
# Copy 70-persistent-cd.rules ... if not updating
CopyHardwareUdevRules() if !Mode.update
+
+ # fate#319624
+ copy_ssh_files
else
Builtins.y2error("unknown function: %1", @func)
@ret = nil
@@ -408,6 +339,11 @@
nil
end
+ def copy_ssh_files
+ log.info "Copying SSH keys and config files"
+ ::Installation::SshImporter.instance.write(Installation.destdir)
+ end
+
# Prevent from re-defining client class
# Re-defining would produce warnings that constants were already
initialized
end unless defined? CopyFilesFinishClient
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/clients/inst_complex_welcome.rb
new/yast2-installation-3.1.187/src/lib/installation/clients/inst_complex_welcome.rb
---
old/yast2-installation-3.1.184/src/lib/installation/clients/inst_complex_welcome.rb
2016-05-09 14:24:55.000000000 +0200
+++
new/yast2-installation-3.1.187/src/lib/installation/clients/inst_complex_welcome.rb
2016-05-18 11:28:09.000000000 +0200
@@ -79,6 +79,7 @@
Yast.import "Timezone"
Yast.import "UI"
Yast.import "Wizard"
+ Yast.import "ProductFeatures"
end
private
@@ -91,10 +92,10 @@
case ret
when :back
return ret
- when :abort
+ when :abort, :cancel
next unless Popup.ConfirmAbort(:painless)
Wizard.RestoreNextButton
- return ret
+ return :abort
when :keyboard
read_ui_state
Keyboard.Set(@keyboard)
@@ -388,6 +389,30 @@
@text_mode = UI.TextMode
end
+ # Showing where the EULA will be installed
+ def license_location
+ file_location = ProductFeatures.GetStringFeature(
+ "globals",
+ "base_product_license_directory"
+ )
+ if file_location.nil?
+ Empty()
+ else
+ Left(
+ ReplacePoint(
+ Id(:license_location),
+ Label(
+ # TRANSLATORS: addition license information
+ # %1 is replaced with the filename. Please keep
+ # the translation VERY short.
+ _("EULA location in the installed system: %s") %
+ file_location
+ )
+ )
+ )
+ end
+ end
+
def dialog_content
# this type of contents will be shown only for initial installation
dialog
VBox(
@@ -423,6 +448,10 @@
Left(ReplacePoint(Id(:base_license_rp), Empty()))
)
),
+ VSpacing(text_mode? ? 0.5 : 1),
+ HBox(
+ license_location
+ ),
VSpacing(text_mode? ? 0.1 : 0.5),
MinHeight(
1,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/clients/inst_pre_install.rb
new/yast2-installation-3.1.187/src/lib/installation/clients/inst_pre_install.rb
---
old/yast2-installation-3.1.184/src/lib/installation/clients/inst_pre_install.rb
2016-05-09 14:24:55.000000000 +0200
+++
new/yast2-installation-3.1.187/src/lib/installation/clients/inst_pre_install.rb
2016-05-18 11:28:09.000000000 +0200
@@ -18,6 +18,9 @@
# To contact Novell about this file by physical or electronic mail, you may
find
# current contact information at www.novell.com.
#
------------------------------------------------------------------------------
+
+require "installation/ssh_importer"
+
module Yast
class InstPreInstallClient < Client
include Yast::Logger
@@ -55,6 +58,7 @@
from: "any",
to: "list <map>"
)
+ @copy_items ||= []
@copy_items.each do |one_copy_item|
item_id = one_copy_item["id"]
@@ -85,7 +89,10 @@
end
end
- read_users
+ each_mounted_partition do |device, mount_point|
+ read_users(device, mount_point) if can_read_users?
+ read_ssh_info(device, mount_point)
+ end
# free the memory
@useful_partitions = nil
@@ -205,23 +212,6 @@
nil
end
- # Stores all found user databases (/etc/passwd and friends) into
- # UsersDatabase.all, so it can be used during the users import step
- def read_users
- require_users_database
- return unless defined? Users::UsersDatabase
- each_mounted_partition do |device, mount_point|
- log.info "Reading users information from #{device}"
- Users::UsersDatabase.import(mount_point)
- end
- end
-
- def require_users_database
- require "users/users_database"
- rescue LoadError
- log.error "UsersDatabase not found. YaST2-users is missing, old or
broken."
- end
-
def Initialize
Builtins.y2milestone("Evaluating all current partitions")
@@ -300,6 +290,41 @@
protected
+ # Checks whether it's possible to read the existing users databases
+ def can_read_users?
+ @can_read_users ||= begin
+ require_users_database
+ defined? Users::UsersDatabase
+ end
+ end
+
+ # Requires users_database if possible, not failing otherwise
+ def require_users_database
+ require "users/users_database"
+ rescue LoadError
+ log.error "UsersDatabase not found. YaST2-users is missing, old or
broken."
+ end
+
+ # Stores the users database (/etc/passwd and friends) of a given filesystem
+ # in UsersDatabase.all, so it can be used during the users import step
+ #
+ # @param device [String] device name of the filesystem
+ # @param mount_point [String] path where the filesystem is mounted
+ def read_users(device, mount_point)
+ log.info "Reading users information from #{device}"
+ Users::UsersDatabase.import(mount_point)
+ end
+
+ # Stores the SSH configuration of a given partition in the SSH importer
+ # @see CopyFilesFinishClient and SshImportProposalClient
+ #
+ # @param device [String] device name of the filesystem
+ # @param mount_point [String] path where the filesystem is mounted
+ def read_ssh_info(device, mount_point)
+ log.info "Reading SSH information from #{device}"
+ ::Installation::SshImporter.instance.add_config(mount_point, device)
+ end
+
def each_mounted_partition(&block)
mnt_tmpdir = "#{Directory.tmpdir}/tmp_mnt_for_check"
mnt_tmpdir = SystemFilesCopy.CreateDirectoryIfMissing(mnt_tmpdir)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/clients/ssh_import_proposal.rb
new/yast2-installation-3.1.187/src/lib/installation/clients/ssh_import_proposal.rb
---
old/yast2-installation-3.1.184/src/lib/installation/clients/ssh_import_proposal.rb
1970-01-01 01:00:00.000000000 +0100
+++
new/yast2-installation-3.1.187/src/lib/installation/clients/ssh_import_proposal.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,82 @@
+require "installation/proposal_client"
+require "installation/ssh_importer"
+
+module Yast
+ # Proposal client for SSH keys import
+ class SshImportProposalClient < ::Installation::ProposalClient
+ include Yast::I18n
+ include Yast::Logger
+
+ def initialize
+ Yast.import "UI"
+ textdomain "installation"
+ end
+
+ protected
+
+ def description
+ {
+ # proposal part - bootloader label
+ "rich_text_title" => _("Import SSH Host Keys and Configuration"),
+ # menubutton entry
+ "menu_title" => _("&Import SSH Host Keys and Configuration"),
+ "id" => "ssh_import"
+ }
+ end
+
+ def make_proposal(attrs)
+ importer.reset if attrs["force_reset"]
+ {
+ "preformatted_proposal" => preformatted_proposal,
+ "links" => ["ssh_import"]
+ }
+ end
+
+ def importer
+ ::Installation::SshImporter.instance
+ end
+
+ def preformatted_proposal
+ if importer.configurations.empty?
+ return _("No previous Linux installation found - not importing any SSH
Key")
+ end
+ if importer.device.nil?
+ res = _("No existing SSH host keys will be copied")
+ else
+ ssh_config = importer.configurations[importer.device]
+ partition = ssh_config.system_name
+ if importer.copy_config?
+ # TRANSLATORS: %s is the name of a Linux system found in the hard
+ # disk, like 'openSUSE 13.2'
+ res = _("SSH host keys and configuration will be copied from %s") %
partition
+ else
+ # TRANSLATORS: %s is the name of a Linux system found in the hard
+ # disk, like 'openSUSE 13.2'
+ res = _("SSH host keys will be copied from %s") % partition
+ end
+ end
+ # TRANSLATORS: link to change the proposal
+ res += " " + _("(<a href=%s>change</a>)") % '"ssh_import"'
+ Yast::HTML.List([res])
+ end
+
+ def ask_user(param)
+ args = {
+ "enable_back" => true,
+ "enable_next" => param.fetch("has_next", false),
+ "going_back" => true
+ }
+
+ log.info "Asking user which SSH keys to import"
+ begin
+ Yast::Wizard.OpenAcceptDialog
+ result = WFM.CallFunction("inst_ssh_import", [args])
+ ensure
+ Yast::Wizard.CloseDialog
+ end
+ log.info "Returning from ssh_import ask_user with #{result}"
+
+ { "workflow_sequence" => result }
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/dialogs/ssh_import.rb
new/yast2-installation-3.1.187/src/lib/installation/dialogs/ssh_import.rb
--- old/yast2-installation-3.1.184/src/lib/installation/dialogs/ssh_import.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/src/lib/installation/dialogs/ssh_import.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,118 @@
+# Copyright (c) 2016 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 "yast"
+require "ui/installation_dialog"
+require "installation/ssh_importer"
+
+module Yast
+ class SshImportDialog < ::UI::InstallationDialog
+ def initialize
+ super
+
+ Yast.import "UI"
+ Yast.import "Label"
+
+ textdomain "installation"
+ end
+
+ # Event callback for the 'ok' button
+ def next_handler
+ partition = UI.QueryWidget(Id(:device), :Value)
+ partition = nil if partition == :none
+ copy_config = UI.QueryWidget(Id(:copy_config), :Value)
+ log.info "SshImportDialog partition => #{partition} copy_config =>
#{copy_config}"
+ importer.device = partition
+ importer.copy_config = copy_config
+ super
+ end
+
+ private
+
+ def importer
+ @importer ||= ::Installation::SshImporter.instance
+ end
+
+ def partitions
+ @partitions ||= importer.configurations
+ end
+
+ def device
+ @device ||= importer.device
+ end
+
+ def copy_config
+ @copy_config ||= importer.copy_config
+ end
+
+ def dialog_content
+ HSquash(
+ VBox(
+ Left(Label(_("System to Import SSH Host Keys from"))),
+ partitions_list_widget,
+ VSpacing(1),
+ Left(copy_config_widget)
+ )
+ )
+ end
+
+ def dialog_title
+ _("Import SSH Host Keys and Configuration")
+ end
+
+ def help_text
+ _(
+ "<p>Every SSH server is identified by one or several public host keys.
" \
+ "Choose an existing Linux installation to reuse the host keys -and " \
+ "thus the identity- of its SSH server. The key files found in /etc/ssh
" \
+ "(one pair of files per host key) will be copied to the new system " \
+ "being installed.</p>" \
+ "<p>Check <b>Copy Whole SSH Configuration</b> to also copy other files
" \
+ "found in /etc/ssh, in addition to the keys.</p>"
+ )
+ end
+
+ def partitions_list_widget
+ sorted_partitions = partitions.to_a.sort_by(&:first)
+ part_widgets = sorted_partitions.map do |device, partition|
+ Left(partition_widget(device, partition))
+ end
+
+ RadioButtonGroup(
+ Id(:device),
+ VBox(
+ # TRANSLATORS: option to select no partition for SSH keys import
+ Left(RadioButton(Id(:none), _("None"), device.nil?)),
+ *part_widgets
+ )
+ )
+ end
+
+ def partition_widget(dev, partition)
+ strings = { system_name: partition.system_name, device: dev }
+ # TRANSLATORS: %{system_name} is a string like "openSUSE 13.2", %{device}
+ # is a string like /dev/sda1
+ name = _("%{system_name} at %{device}") % strings
+ RadioButton(Id(dev), name, device == dev)
+ end
+
+ def copy_config_widget
+ CheckBox(Id(:copy_config), _("Copy Whole SSH Configuration"),
copy_config)
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/ssh_config.rb
new/yast2-installation-3.1.187/src/lib/installation/ssh_config.rb
--- old/yast2-installation-3.1.184/src/lib/installation/ssh_config.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/src/lib/installation/ssh_config.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,166 @@
+# Copyright (c) 2016 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 "yast"
+require "installation/ssh_key"
+require "installation/ssh_config_file"
+require "fileutils"
+
+module Installation
+ # Class that allows to memorize the list of SSH keys and config files found
in
+ # a filesystem (i.e. the content of the /etc/ssh directory)
+ #
+ # Used by the SSH keys importing functionality.
+ class SshConfig
+ extend Yast::I18n
+ textdomain "installation"
+
+ class << self
+ # Creates a new object with the information read from a filesystem
+ #
+ # @param root_dir [String] Path where the original "/" is mounted
+ def from_dir(root_dir)
+ config = SshConfig.new(name_for(root_dir))
+ dir = ssh_dir(root_dir)
+ config.read_files(dir)
+ config
+ end
+
+ def ssh_dir(root_dir)
+ File.join(root_dir, "etc", "ssh")
+ end
+
+ protected
+
+ def os_release_file(root_dir)
+ File.join(root_dir, "etc", "os-release")
+ end
+
+ # Find out the name for a previous Linux installation.
+ # This uses /etc/os-release which is specified in
+ # https://www.freedesktop.org/software/systemd/man/os-release.html
+ #
+ # @param mount_point [String] Path where the original "/" is mounted
+ # @return [String] Speaking name of the Linux installation
+ def name_for(mount_point)
+ # TRANSLATORS: default name for a found Linux system (we don't know if
+ # it's an openSUSE, Ubuntu...)
+ default_name = _("Linux")
+ os_release = parse_ini_file(os_release_file(mount_point))
+
+ name = os_release["PRETTY_NAME"]
+ if name.empty?
+ name = os_release[NAME] || default_name
+ name += " #{os_release[VERSION]}"
+ end
+ name
+ rescue Errno::ENOENT # No /etc/os-release found
+ default_name
+ end
+
+ # Parse a simple .ini file and return the content in a hash.
+ #
+ # @param filename [String] Name of the file to parse
+ # @return [Hash<String, String>] file content as hash
+ #
+ def parse_ini_file(filename)
+ content = {}
+ File.readlines(filename).each do |line|
+ line = line.lstrip.chomp
+ next if line.empty? || line.start_with?("#")
+ (key, value) = line.split("=")
+ value.gsub!(/^\s*"/, "")
+ value.gsub!(/"\s*$/, "")
+ content[key] = value
+ end
+ content
+ end
+ end
+
+ # @return [String] name to help the user identify the configuration
+ attr_accessor :system_name
+ # @return [Array<SshKey>] keys found in the partition
+ attr_accessor :keys
+ # @return [Array<SshConfigFile>] configuration files found in the partition
+ attr_accessor :config_files
+
+ def initialize(system_name)
+ self.system_name = system_name
+ self.keys = []
+ self.config_files = []
+ end
+
+ # Populates the list of keys and config files from a ssh configuration
+ # directory
+ #
+ # @param dir [String] path of the SSH configuration directory
+ def read_files(dir)
+ filenames = Dir.glob("#{dir}/*")
+
+ # Let's process keys first, pairs of files like "xyz" & "xyz.pub"
+ pub_key_filenames = filenames.select { |f|
f.end_with?(SshKey::PUBLIC_FILE_SUFFIX) }
+ pub_key_filenames.each do |pub_file|
+ # Remove the .pub suffix
+ priv_file = pub_file.chomp(SshKey::PUBLIC_FILE_SUFFIX)
+ add_key(priv_file)
+ filenames.delete(pub_file)
+ filenames.delete(priv_file)
+ end
+
+ filenames.each do |name|
+ add_config_file(name)
+ end
+ end
+
+ # Writes keys and/or configuration files to a filesystem
+ #
+ # @param root_dir [String] path where the target filesystem (/) is mounted
+ # @param write_keys [Boolean] whether to copy the keys
+ # @param write_config_files [Boolean] whether to copy the config files
+ def write_files(root_dir, write_keys: true, write_config_files: true)
+ dir = self.class.ssh_dir(root_dir)
+ ::FileUtils.mkdir_p(dir)
+
+ keys.each { |k| k.write_files(dir) } if write_keys
+ config_files.each { |f| f.write(dir) } if write_config_files
+ end
+
+ # Access time of the most recently accessed SSH key.
+ #
+ # Needed to keep the default behavior backward compatible.
+ #
+ # @return [Time]
+ def keys_atime
+ keys.map(&:atime).max
+ end
+
+ protected
+
+ def add_key(priv_filename)
+ key = SshKey.new(File.basename(priv_filename))
+ key.read_files(priv_filename)
+ keys << key
+ end
+
+ def add_config_file(filename)
+ file = SshConfigFile.new(File.basename(filename))
+ file.read(filename)
+ config_files << file
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/ssh_config_file.rb
new/yast2-installation-3.1.187/src/lib/installation/ssh_config_file.rb
--- old/yast2-installation-3.1.184/src/lib/installation/ssh_config_file.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/src/lib/installation/ssh_config_file.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,61 @@
+# Copyright (c) 2016 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 "fileutils"
+
+module Installation
+ # Class that allows to memorize a particular SSH config file found in a
+ # partition.
+ #
+ # Used by the SSH configuration importing functionality.
+ class SshConfigFile
+ BACKUP_SUFFIX = ".yast.orig"
+
+ # @return [String] file name
+ attr_accessor :name
+ # @return [Time] access time of the original file
+ attr_accessor :atime
+ # @return [String] content of the file
+ attr_accessor :content
+ # @return [Fixmum] mode of the original file. @see File.chmod
+ attr_accessor :permissions
+
+ def initialize(name)
+ @name = name
+ end
+
+ def read(path)
+ self.content = IO.read(path)
+ self.atime = File.atime(path)
+ self.permissions = File.stat(path).mode
+ end
+
+ def write(dir)
+ path = File.join(dir, name)
+ backup(path)
+ IO.write(path, content)
+ File.chmod(permissions, path)
+ end
+
+ protected
+
+ def backup(filename)
+ ::FileUtils.mv(filename, filename + BACKUP_SUFFIX) if
File.exist?(filename)
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/ssh_importer.rb
new/yast2-installation-3.1.187/src/lib/installation/ssh_importer.rb
--- old/yast2-installation-3.1.184/src/lib/installation/ssh_importer.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/src/lib/installation/ssh_importer.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,106 @@
+# Copyright (c) 2016 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 "installation/ssh_config"
+
+module Installation
+ # Entry point for the SSH keys importing functionality.
+ #
+ # This singleton class provides methods to hold a list of configurations
found
+ # in the hard disk and to copy its files to the target system
+ class SshImporter
+ include Singleton
+
+ # @return [String] device name of the source filesystem (i.e. the
+ # SshConfig to copy the keys from)
+ attr_accessor :device
+ # @return [boolean] whether to copy also the config files in addition to
the
+ # keys
+ attr_accessor :copy_config
+ # @return [Hash{String => SshConfig}] found configurations, indexed by
device
+ # name
+ attr_reader :configurations
+
+ alias_method :copy_config?, :copy_config
+
+ def initialize
+ @configurations = {}
+ reset
+ end
+
+ # Set default settings (#device and #copy_config?)
+ #
+ # To ensure backwards compatibility, the default behavior is to copy the
SSH
+ # keys, but not other config files, from the most recently accessed config
+ def reset
+ set_device
+ @copy_config = false
+ end
+
+ # Reads ssh keys and config files from a given root directory, stores the
+ # information in #configurations and updates #device according to the
+ # default behavior.
+ #
+ # Directories without keys in /etc/ssh are ignored.
+ #
+ # @param root_dir [String] Path where the original "/" is mounted
+ # @param device [String] Name of the mounted device
+ def add_config(root_dir, device)
+ config = SshConfig.from_dir(root_dir)
+ return if config.keys.empty?
+
+ configurations[device] = config
+ set_device
+ end
+
+ # Writes the SSH keys from the selected device (and also other
configuration
+ # files if #copy_config? is true) in the target filesystem
+ #
+ # @param root_dir [String] Path to use as "/" to locate the ssh directory
+ def write(root_dir)
+ return unless device
+ configurations[device].write_files(
+ root_dir,
+ write_keys: true,
+ write_config_files: copy_config
+ )
+ end
+
+ protected
+
+ # Sets #device according to the logic implemented in the old
+ # "copy_to_system" feature, to ensure backwards compatibility. That means
+ # selecting the device which contains the most recently accessed (atime)
+ # key file.
+ #
+ # For some background, see fate#300421, fate#305019, fate#319624
+ def set_device
+ if configurations.empty?
+ @device = nil
+ else
+ with_atime = configurations.to_a.select { |_dev, config|
config.keys_atime }
+ if with_atime.empty?
+ @device = configurations.keys.first
+ else
+ recent = with_atime.max_by { |_dev, config| config.keys_atime }
+ @device = recent.first
+ end
+ end
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/src/lib/installation/ssh_key.rb
new/yast2-installation-3.1.187/src/lib/installation/ssh_key.rb
--- old/yast2-installation-3.1.184/src/lib/installation/ssh_key.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/src/lib/installation/ssh_key.rb
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1,64 @@
+# Copyright (c) 2016 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
+
+module Installation
+ # Class that allows to memorize a particular SSH keys found in a partition.
+ #
+ # Used to implement the SSH keys importing functionality.
+ class SshKey
+ PUBLIC_FILE_SUFFIX = ".pub"
+
+ # @return [String] name for the user to identify the key
+ attr_accessor :name
+ # @return [Time] access time of the most recently accessed file
+ attr_accessor :atime
+ # @return [Array<Keyfile>] list of files associated to the key
+ attr_accessor :files
+
+ def initialize(name)
+ @name = name
+ @files = []
+ end
+
+ def read_files(priv_filename)
+ add_file(priv_filename) if File.exist?(priv_filename)
+ pub_filename = priv_filename + PUBLIC_FILE_SUFFIX
+ add_file(pub_filename) if File.exist?(pub_filename)
+ end
+
+ def write_files(dir)
+ files.each do |file|
+ path = File.join(dir, file.filename)
+ IO.write(path, file.content)
+ File.chmod(file.permissions, path)
+ end
+ end
+
+ protected
+
+ KeyFile = Struct.new(:filename, :content, :permissions)
+
+ def add_file(path)
+ content = IO.read(path)
+ permissions = File.stat(path).mode
+ files << KeyFile.new(File.basename(path), content, permissions)
+ atime = File.atime(path)
+ self.atime = atime unless self.atime && self.atime > atime
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/driver_update_test.rb
new/yast2-installation-3.1.187/test/driver_update_test.rb
--- old/yast2-installation-3.1.184/test/driver_update_test.rb 2016-05-09
14:24:55.000000000 +0200
+++ new/yast2-installation-3.1.187/test/driver_update_test.rb 2016-05-18
11:28:09.000000000 +0200
@@ -7,8 +7,6 @@
Yast.import "Linuxrc"
describe Installation::DriverUpdate do
- FIXTURES_DIR = Pathname.new(__FILE__).dirname.join("fixtures")
-
subject(:update) { Installation::DriverUpdate.new(update_path) }
let(:update_path) { FIXTURES_DIR.join("updates", "dud_000") }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/os-release
new/yast2-installation-3.1.187/test/fixtures/root1/etc/os-release
--- old/yast2-installation-3.1.184/test/fixtures/root1/etc/os-release
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root1/etc/os-release
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+PRETTY_NAME="Operating system 1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/moduli
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/moduli
--- old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/moduli
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/moduli
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root1: content of moduli file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_config
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_config
--- old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_config
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_config
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root1: content of ssh_config file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_dsa_key
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_dsa_key
--- old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_dsa_key
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_dsa_key
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root1: content of ssh_host_dsa_key file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_dsa_key.pub
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_dsa_key.pub
---
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_dsa_key.pub
1970-01-01 01:00:00.000000000 +0100
+++
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_dsa_key.pub
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root1: content of ssh_host_dsa_key.pub file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_key
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_key
--- old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_key
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_key
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root1: content of ssh_host_key file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_key.pub
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_key.pub
--- old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/ssh_host_key.pub
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/ssh_host_key.pub
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root1: content of ssh_host_key.pub file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/sshd_config
new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/sshd_config
--- old/yast2-installation-3.1.184/test/fixtures/root1/etc/ssh/sshd_config
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root1/etc/ssh/sshd_config
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root1: content of sshd_config file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/known_hosts
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/known_hosts
--- old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/known_hosts
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/known_hosts
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root2: content of known_hosts file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_config
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_config
--- old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_config
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_config
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root2: content of ssh_config file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key
---
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key
1970-01-01 01:00:00.000000000 +0100
+++
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root2: content of ssh_host_ed25519_key file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key.pub
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key.pub
---
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key.pub
1970-01-01 01:00:00.000000000 +0100
+++
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_ed25519_key.pub
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root2: content of ssh_host_ed25519_key.pub file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_key
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_key
--- old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_key
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_key
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root2: content of ssh_host_key file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_key.pub
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_key.pub
--- old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/ssh_host_key.pub
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/ssh_host_key.pub
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root2: content of ssh_host_key.pub file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/sshd_config
new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/sshd_config
--- old/yast2-installation-3.1.184/test/fixtures/root2/etc/ssh/sshd_config
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root2/etc/ssh/sshd_config
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root2: content of sshd_config file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-installation-3.1.184/test/fixtures/root3/etc/ssh/ssh_config
new/yast2-installation-3.1.187/test/fixtures/root3/etc/ssh/ssh_config
--- old/yast2-installation-3.1.184/test/fixtures/root3/etc/ssh/ssh_config
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/fixtures/root3/etc/ssh/ssh_config
2016-05-18 11:28:09.000000000 +0200
@@ -0,0 +1 @@
+root3: content of ssh_config file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-installation-3.1.184/test/ssh_config_test.rb
new/yast2-installation-3.1.187/test/ssh_config_test.rb
--- old/yast2-installation-3.1.184/test/ssh_config_test.rb 1970-01-01
01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/ssh_config_test.rb 2016-05-18
11:28:09.000000000 +0200
@@ -0,0 +1,222 @@
+#! /usr/bin/rspec
+# Copyright (c) 2016 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_relative "./test_helper"
+require "installation/ssh_config"
+require "tmpdir"
+require "fileutils"
+
+describe Installation::SshConfig do
+ describe ".from_dir" do
+ textdomain "installation"
+
+ let(:recent_root1_atime) { Time.now }
+ let(:old_root1_atime) { Time.now - 60 }
+ let(:root1_dir) { FIXTURES_DIR.join("root1") }
+ let(:root2_dir) { FIXTURES_DIR.join("root2") }
+
+ before do
+ # The ssh_host private key file is more recent than any other file
+ allow(File).to receive(:atime) do |path|
+ path =~ /ssh_host_key$/ ? recent_root1_atime : old_root1_atime
+ end
+ end
+
+ it "reads the name of the systems with /etc/os-release" do
+ root1 = described_class.from_dir(root1_dir)
+ expect(root1.system_name).to eq "Operating system 1"
+ end
+
+ it "uses 'Linux' as name for systems without /etc/os-release" do
+ root2 = described_class.from_dir(root2_dir)
+ expect(root2.system_name).to eq _("Linux")
+ end
+
+ it "stores all the keys and files with their names" do
+ root1 = described_class.from_dir(root1_dir)
+ root2 = described_class.from_dir(root2_dir)
+
+ expect(root1.config_files.map(&:name)).to contain_exactly(
+ "moduli", "ssh_config", "sshd_config"
+ )
+ expect(root1.keys.map(&:name)).to contain_exactly(
+ "ssh_host_dsa_key", "ssh_host_key"
+ )
+ expect(root2.config_files.map(&:name)).to contain_exactly(
+ "known_hosts", "ssh_config", "sshd_config"
+ )
+ expect(root2.keys.map(&:name)).to contain_exactly(
+ "ssh_host_ed25519_key", "ssh_host_key"
+ )
+ end
+
+ it "stores the content of the config files" do
+ root1 = described_class.from_dir(root1_dir)
+ expect(root1.config_files.map(&:content)).to contain_exactly(
+ "root1: content of moduli file\n",
+ "root1: content of ssh_config file\n",
+ "root1: content of sshd_config file\n"
+ )
+ end
+
+ it "stores the content of both files for the keys" do
+ root1 = described_class.from_dir(root1_dir)
+ contents = root1.keys.map { |k| k.files.map(&:content) }
+ expect(contents).to contain_exactly(
+ ["root1: content of ssh_host_dsa_key file\n", "root1: content of
ssh_host_dsa_key.pub file\n"],
+ ["root1: content of ssh_host_key file\n", "root1: content of
ssh_host_key.pub file\n"]
+ )
+ end
+
+ it "uses the most recent file of each key to set #atime" do
+ root1 = described_class.from_dir(root1_dir)
+ host_key = root1.keys.detect { |k| k.name == "ssh_host_key" }
+ host_dsa_key = root1.keys.detect { |k| k.name == "ssh_host_dsa_key" }
+
+ expect(host_key.atime).to eq recent_root1_atime
+ expect(host_dsa_key.atime).to eq old_root1_atime
+ end
+ end
+
+ describe ".write_files" do
+ def permissions(file)
+ format("%o", File.stat(file).mode)[-3..-1]
+ end
+
+ around do |example|
+ # Git does not preserve file permissions (only the executable bit),
+ # so let's copy test/fixtures to a temporal directory and ensure
+ # sensible permissions there
+ Dir.mktmpdir do |dir|
+ ::FileUtils.cp_r(FIXTURES_DIR.join("root1"), dir)
+ Dir.glob("#{dir}/root1/etc/ssh/*").each do |file|
+ if file.end_with?("_key") || file.end_with?("sshd_config") ||
file.end_with?("moduli")
+ File.chmod(0600, file)
+ else
+ File.chmod(0644, file)
+ end
+ end
+ @config = Installation::SshConfig.from_dir(File.join(dir, "root1"))
+ end
+
+ Dir.mktmpdir do |dir|
+ @target_dir = dir
+ example.run
+ end
+ end
+
+ let(:ssh_dir) { File.join(@target_dir, "etc", "ssh") }
+
+ it "creates /etc/ssh/ if it does not exist" do
+ @config.write_files(@target_dir)
+ expect(Dir.glob("#{@target_dir}/etc/*")).to eq ["#{@target_dir}/etc/ssh"]
+ end
+
+ it "reuses /etc/ssh if it's already there" do
+ ::FileUtils.mkdir_p(ssh_dir)
+ ::FileUtils.touch(File.join(ssh_dir, "preexisting_file"))
+
+ @config.write_files(@target_dir, write_keys: false)
+
+ files = Dir.glob("#{ssh_dir}/*")
+ expect(files.size).to eq(@config.config_files.size + 1)
+ expect(files).to include "#{ssh_dir}/preexisting_file"
+ end
+
+ it "writes all the files by default" do
+ @config.write_files(@target_dir)
+
+ target_content = Dir.glob("#{ssh_dir}/*")
+ expect(target_content).to contain_exactly(
+ "#{ssh_dir}/ssh_host_key", "#{ssh_dir}/ssh_host_key.pub",
+ "#{ssh_dir}/ssh_host_dsa_key", "#{ssh_dir}/ssh_host_dsa_key.pub",
+ "#{ssh_dir}/moduli", "#{ssh_dir}/ssh_config", "#{ssh_dir}/sshd_config"
+ )
+ end
+
+ it "writes only the key files if write_config_files is false" do
+ @config.write_files(@target_dir, write_config_files: false)
+
+ target_content = Dir.glob("#{ssh_dir}/*")
+ expect(target_content).to contain_exactly(
+ "#{ssh_dir}/ssh_host_key", "#{ssh_dir}/ssh_host_key.pub",
+ "#{ssh_dir}/ssh_host_dsa_key", "#{ssh_dir}/ssh_host_dsa_key.pub"
+ )
+ end
+
+ it "writes only the config files if write_keys is false" do
+ @config.write_files(@target_dir, write_keys: false)
+
+ target_content = Dir.glob("#{ssh_dir}/*")
+ expect(target_content).to contain_exactly(
+ "#{ssh_dir}/moduli", "#{ssh_dir}/ssh_config", "#{ssh_dir}/sshd_config"
+ )
+ end
+
+ it "preserves original permissions for files and keys" do
+ @config.write_files(@target_dir)
+
+ expect(permissions("#{ssh_dir}/moduli")).to eq "600"
+ expect(permissions("#{ssh_dir}/ssh_config")).to eq "644"
+ expect(permissions("#{ssh_dir}/ssh_host_key")).to eq "600"
+ expect(permissions("#{ssh_dir}/ssh_host_key.pub")).to eq "644"
+ end
+
+ it "backups config files found in the target directory" do
+ ::FileUtils.mkdir_p(ssh_dir)
+ ::FileUtils.touch(File.join(ssh_dir, "moduli"))
+
+ @config.write_files(@target_dir)
+
+ expect(File.exist?(File.join(ssh_dir, "moduli.yast.orig"))).to eq true
+ end
+
+ it "writes the original content for each file" do
+ @config.write_files(@target_dir)
+
+ expect(IO.read("#{ssh_dir}/moduli")).to eq(
+ "root1: content of moduli file\n"
+ )
+ expect(IO.read("#{ssh_dir}/ssh_host_key")).to eq(
+ "root1: content of ssh_host_key file\n"
+ )
+ expect(IO.read("#{ssh_dir}/ssh_host_key.pub")).to eq(
+ "root1: content of ssh_host_key.pub file\n"
+ )
+ end
+ end
+
+ describe "#keys_atime" do
+ subject(:config) { ::Installation::SshConfig.new("name") }
+ let(:now) { Time.now }
+
+ it "returns the access time of the most recently accessed key" do
+ config.keys = [
+ instance_double("Installation::SshKey", atime: now),
+ instance_double("Installation::SshKey", atime: now + 1200),
+ instance_double("Installation::SshKey", atime: now - 1200)
+ ]
+ expect(config.keys_atime).to eq(now + 1200)
+ end
+
+ it "returns nil if no keys has been read" do
+ expect(config.keys_atime).to be_nil
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-installation-3.1.184/test/ssh_importer_test.rb
new/yast2-installation-3.1.187/test/ssh_importer_test.rb
--- old/yast2-installation-3.1.184/test/ssh_importer_test.rb 1970-01-01
01:00:00.000000000 +0100
+++ new/yast2-installation-3.1.187/test/ssh_importer_test.rb 2016-05-18
11:28:09.000000000 +0200
@@ -0,0 +1,178 @@
+#! /usr/bin/rspec
+# Copyright (c) 2016 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_relative "./test_helper"
+require "installation/ssh_importer"
+require "installation/ssh_config"
+
+describe Installation::SshImporter do
+ subject(:importer) { Installation::SshImporter.instance }
+
+ describe "#add_config" do
+ before do
+ importer.configurations.clear
+ importer.reset
+ end
+
+ it "stores the configuration if /etc/ssh contains keys" do
+ importer.add_config(FIXTURES_DIR.join("root1"), "dev")
+ expect(importer.configurations).to_not be_empty
+ end
+
+ it "does nothing if there are no keys in /etc/ssh" do
+ importer.add_config(FIXTURES_DIR.join("root3"), "dev")
+ expect(importer.configurations).to be_empty
+ end
+
+ it "does nothing if there is no /etc/ssh directory" do
+ importer.add_config(FIXTURES_DIR.join("root1/etc"), "dev")
+ expect(importer.configurations).to be_empty
+ end
+
+ it "does nothing if the root directory does not exist" do
+ importer.add_config("/non-existent", "dev")
+ expect(importer.configurations).to be_empty
+ end
+
+ context "reading several valid directories" do
+ let(:now) { Time.now }
+ let(:root2_atime) { Time.now - 60 }
+ # We just want all config to have some keys, no matter which
+ let(:keys) { [instance_double(Installation::SshKey)] }
+ let(:root1) { instance_double("Installation::SshConfig", keys_atime: now
- 1200, keys: keys) }
+ let(:root2) { instance_double("Installation::SshConfig", keys_atime:
now, keys: keys) }
+ let(:root3) { instance_double("Installation::SshConfig", keys_atime: now
- 60, keys: keys) }
+
+ before do
+ allow(Installation::SshConfig).to
receive(:from_dir).with("root1_dir").and_return root1
+ allow(Installation::SshConfig).to
receive(:from_dir).with("root2_dir").and_return root2
+ allow(Installation::SshConfig).to
receive(:from_dir).with("root3_dir").and_return root3
+ end
+
+ it "stores the device name and configuration for all systems" do
+ importer.add_config("root1_dir", "/dev/root1")
+ importer.add_config("root2_dir", "/dev/root2")
+ importer.add_config("root3_dir", "/dev/root3")
+
+ expect(importer.configurations).to eq(
+ "/dev/root1" => root1,
+ "/dev/root2" => root2,
+ "/dev/root3" => root3
+ )
+ end
+
+ it "sets #device to the most recently accessed configuration" do
+ expect(importer.device).to be_nil
+ importer.add_config("root1_dir", "/dev/root1")
+ expect(importer.device).to eq "/dev/root1"
+ importer.add_config("root2_dir", "/dev/root2")
+ expect(importer.device).to eq "/dev/root2"
+ importer.add_config("root3_dir", "/dev/root3")
+ expect(importer.device).to eq "/dev/root2"
+ end
+ end
+ end
+
+ describe ".write" do
+ let(:root1) { instance_double("Installation::SshConfig") }
+ let(:root2) { instance_double("Installation::SshConfig") }
+
+ before do
+ allow(importer).to receive(:configurations).and_return(
+ "/dev/root1" => root1,
+ "/dev/root2" => root2
+ )
+ end
+
+ context "if no device is selected" do
+ it "writes nothing" do
+ importer.device = nil
+
+ expect(root1).to_not receive(:write_files)
+ expect(root2).to_not receive(:write_files)
+
+ importer.write("/somewhere")
+ end
+ end
+
+ context "if a device is selected" do
+ before do
+ importer.device = "/dev/root2"
+ end
+
+ context "if #copy_config? is true" do
+ before do
+ importer.copy_config = true
+ end
+
+ it "writes the ssh keys of the choosen device" do
+ expect(root2).to receive(:write_files) do |_dir, flags|
+ expect(flags[:write_keys]).to eq true
+ end
+
+ importer.write("/somewhere")
+ end
+
+ it "writes the config files of the choosen device" do
+ expect(root2).to receive(:write_files) do |_dir, flags|
+ expect(flags[:write_config_files]).to eq true
+ end
+
+ importer.write("/somewhere")
+ end
+
+ it "does not write files from other devices" do
+ allow(root2).to receive(:write_files)
+ expect(root1).to_not receive(:write_files)
+
+ importer.write("/somewhere")
+ end
+ end
+
+ context "if #copy_config? is false" do
+ before do
+ importer.copy_config = false
+ end
+
+ it "writes the ssh keys of the choosen device" do
+ expect(root2).to receive(:write_files) do |_dir, flags|
+ expect(flags[:write_keys]).to eq true
+ end
+
+ importer.write("/somewhere")
+ end
+
+ it "does not write the config files of the choosen device" do
+ expect(root2).to receive(:write_files) do |_dir, flags|
+ expect(flags[:write_config_files]).to eq false
+ end
+
+ importer.write("/somewhere")
+ end
+
+ it "does not write files from other devices" do
+ allow(root2).to receive(:write_files)
+ expect(root1).to_not receive(:write_files)
+
+ importer.write("/somewhere")
+ end
+ end
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-installation-3.1.184/test/test_helper.rb
new/yast2-installation-3.1.187/test/test_helper.rb
--- old/yast2-installation-3.1.184/test/test_helper.rb 2016-05-09
14:24:55.000000000 +0200
+++ new/yast2-installation-3.1.187/test/test_helper.rb 2016-05-18
11:28:09.000000000 +0200
@@ -4,6 +4,9 @@
require "yast"
require "yast/rspec"
+require "pathname"
+
+FIXTURES_DIR = Pathname.new(__FILE__).dirname.join("fixtures")
# fake AutoinstConfigClass class which is not supported by Ubuntu
module Yast
@@ -20,11 +23,11 @@
AutoinstConfig = AutoinstConfigClass.new
# Faked Profile module
- class Profile
+ class ProfileClass
def current
end
end
- Profile = Profile.new
+ Profile = ProfileClass.new
end
if ENV["COVERAGE"]