Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package yast2-ntp-client for
openSUSE:Factory checked in at 2023-01-26 13:56:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-ntp-client (Old)
and /work/SRC/openSUSE:Factory/.yast2-ntp-client.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-ntp-client"
Thu Jan 26 13:56:55 2023 rev:132 rq:1060832 version:4.5.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-ntp-client/yast2-ntp-client.changes
2022-11-22 16:09:54.717947492 +0100
+++
/work/SRC/openSUSE:Factory/.yast2-ntp-client.new.32243/yast2-ntp-client.changes
2023-01-26 14:12:21.556878068 +0100
@@ -1,0 +2,9 @@
+Mon Jan 23 18:50:11 UTC 2023 - Michal Filka <[email protected]>
+
+- bsc#1188980
+ - ntp dialog allows to manually set ntp source
+ - ntp source can be selected as pool or server
+ - ntp sources are written into /etc/chrony.d/pools.conf
+- 4.5.3
+
+-------------------------------------------------------------------
Old:
----
yast2-ntp-client-4.5.2.tar.bz2
New:
----
yast2-ntp-client-4.5.3.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast2-ntp-client.spec ++++++
--- /var/tmp/diff_new_pack.7BC8Uu/_old 2023-01-26 14:12:22.084880908 +0100
+++ /var/tmp/diff_new_pack.7BC8Uu/_new 2023-01-26 14:12:22.088880929 +0100
@@ -1,7 +1,7 @@
#
# spec file for package yast2-ntp-client
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: yast2-ntp-client
-Version: 4.5.2
+Version: 4.5.3
Release: 0
Summary: YaST2 - NTP Client Configuration
License: GPL-2.0-or-later
@@ -55,7 +55,7 @@
Requires: yast2-ruby-bindings >= 1.0.0
Requires: rubygem(%rb_default_ruby_abi:cfa) >= 0.6.0
-Obsoletes: yast2-ntp-client-devel-doc
+Obsoletes: yast2-ntp-client-devel-doc <= 3.1.23
Supplements: autoyast(ntp-client)
++++++ yast2-ntp-client-4.5.2.tar.bz2 -> yast2-ntp-client-4.5.3.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/package/yast2-ntp-client.changes
new/yast2-ntp-client-4.5.3/package/yast2-ntp-client.changes
--- old/yast2-ntp-client-4.5.2/package/yast2-ntp-client.changes 2022-11-21
16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/package/yast2-ntp-client.changes 2023-01-25
11:23:00.000000000 +0100
@@ -1,4 +1,13 @@
-------------------------------------------------------------------
+Mon Jan 23 18:50:11 UTC 2023 - Michal Filka <[email protected]>
+
+- bsc#1188980
+ - ntp dialog allows to manually set ntp source
+ - ntp source can be selected as pool or server
+ - ntp sources are written into /etc/chrony.d/pools.conf
+- 4.5.3
+
+-------------------------------------------------------------------
Mon Nov 21 14:40:27 UTC 2022 - Knut Anderssen <[email protected]>
- Fix the netconfig executable path using /sbin/netconfig instead
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-ntp-client-4.5.2/package/yast2-ntp-client.spec
new/yast2-ntp-client-4.5.3/package/yast2-ntp-client.spec
--- old/yast2-ntp-client-4.5.2/package/yast2-ntp-client.spec 2022-11-21
16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/package/yast2-ntp-client.spec 2023-01-25
11:23:00.000000000 +0100
@@ -17,7 +17,7 @@
Name: yast2-ntp-client
-Version: 4.5.2
+Version: 4.5.3
Release: 0
Summary: YaST2 - NTP Client Configuration
License: GPL-2.0-or-later
@@ -55,7 +55,7 @@
Requires: yast2-ruby-bindings >= 1.0.0
Requires: rubygem(%rb_default_ruby_abi:cfa) >= 0.6.0
-Obsoletes: yast2-ntp-client-devel-doc
+Obsoletes: yast2-ntp-client-devel-doc <= 3.1.23
Supplements: autoyast(ntp-client)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/src/clients/ntp-client_proposal.rb
new/yast2-ntp-client-4.5.3/src/clients/ntp-client_proposal.rb
--- old/yast2-ntp-client-4.5.2/src/clients/ntp-client_proposal.rb
2022-11-21 16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/src/clients/ntp-client_proposal.rb
2023-01-25 11:23:00.000000000 +0100
@@ -1,11 +1,18 @@
require "yast"
+require "y2ntp_client/widgets/sources_table"
+
module Yast
# This is used as the general interface between yast2-country
# (time,timezone) and yast2-ntp-client.
class NtpClientProposalClient < Client
include Yast::Logger
+ @sources_table = nil
+ @source_add_button = nil
+ @source_remove_button = nil
+ @source_type_combo = nil
+
def main
Yast.import "UI"
textdomain "ntp-client"
@@ -14,7 +21,6 @@
Yast.import "NetworkService"
Yast.import "NtpClient"
Yast.import "Service"
- Yast.import "String"
Yast.import "Stage"
Yast.import "Package"
Yast.import "Pkg"
@@ -24,6 +30,11 @@
Yast.import "Timezone"
Yast.import "Wizard"
+ @sources_table =
Y2NtpClient::Widgets::SourcesTable.new(NtpClient.GetUsedNtpSources)
+ @source_add_button = Y2NtpClient::Widgets::SourcesAdd.new
+ @source_remove_button = Y2NtpClient::Widgets::SourcesRemove.new
+ @source_type_combo = Y2NtpClient::Widgets::SourcesType.new
+
# API:
#
# Usual *_proposal functions: MakeProposal, AskUser, Write.
@@ -64,6 +75,14 @@
when "MakeProposal"
@ret = MakeProposal()
when "Write"
+ # compatibility layer for yast-country. Yast-country works with array
of servers
+ # which were obtained from here via dhcp_ntp_servers call. And dhcp
can never
+ # provide pool according to @see RFC 2132
+ if @param["servers"].is_a?(Array)
+ @param["servers"] = @param["servers"].each_with_object({}) do |addr,
acc|
+ acc[addr] = :server
+ end
+ end
@ret = Write(@param)
when "ui_help_text"
@ret = ui_help_text
@@ -124,7 +143,14 @@
else
UI.ChangeWidget(Id(:ntp_now), :Enabled, enabled)
end
+
UI.ChangeWidget(Id(:ntp_save), :Enabled, enabled)
+ UI.ChangeWidget(Id(:ntp_address), :Enabled, enabled)
+
+ @sources_table.send(enabled ? :enable : :disable)
+ @source_add_button.send(enabled ? :enable : :disable)
+ @source_remove_button.send(enabled ? :enable : :disable)
+ @source_type_combo.send(enabled ? :enable : :disable)
end
if UI.WidgetExists(Id(:ntp_configure))
# bnc#483787
@@ -174,52 +200,102 @@
NtpClient.ProcessNtpConf
end
- if select_ntp_server
- ntp_items = fallback_ntp_items
- # Once read or proposed any config we consider it as read (bnc#427712)
- NtpClient.config_has_been_read = true
-
- log.info "ntp_items :#{ntp_items}"
- UI.ChangeWidget(Id(:ntp_address), :Items, ntp_items)
- if !Stage.initial
- UI.ChangeWidget(Id(:ntp_address), :Value,
- NtpClient.GetUsedNtpServers.first)
- end
- end
+ # preparing known ntp sources to be offered by default. Propose a random
pool from
+ # control file by default
+ require "y2network/ntp_server"
+ source = Y2Network::NtpServer.default_servers.map(&:hostname).sample
+ ntp_sources = source ? { source => :pool } : {}
+
+ # propose only when a proposal was not made yet
+ if !NtpClient.config_has_been_read
+ # if something was already stored internally, clear it and update
according to the proposal
+ NtpClient.ntp_conf.clear_sources
+
+ ntp_sources.each { |addr, type|
NtpClient.ntp_conf.send("add_#{type}".downcase, addr) }
+ @sources_table.sources = ntp_sources
+ end
+
+ # Dhcp provided sources are "special" according to fate#323454 it is not
pre-configured
+ # by default, but will be offered
+ ntp_sources = dhcp_ntp_items.merge(ntp_sources)
+
+ # initialize the combo of suggested ntp sources (not selected to be
stored, just hint
+ # for user). We use timezone based list of ntp sources in addition to
dhcp ones for that
+ ntp_sources = ntp_sources.merge(timezone_ntp_items)
+ ntp_items = ntp_sources
+ .merge(NtpClient.GetUsedNtpSources)
+ .keys
+ .map { |a| Item(Id(a), a) }
+ UI.ChangeWidget(Id(:ntp_address), :Items, ntp_items)
+
+ # get in sync some prefilled values @see sources_table and @see
ntp_source_input_widget
+ # get in sync proposal and internal state
+ @source_type_combo.value = ntp_sources.values.first
+
+ # Once read or proposed any config we consider it as read (bnc#427712)
+ NtpClient.config_has_been_read = true
nil
end
+ # Creates a widget representing currently configured ntp servers
+ #
+ # @return YUI widget
+ def ntp_sources_list_table
+ to_yui_term(@sources_table)
+ end
+
+ # Creates an add button widget
+ #
+ # Intended for modifying sources table (@see ntp_sources_list_table)
+ #
+ # @return YUI widget
+ def ntp_source_add_button
+ to_yui_term(@source_add_button)
+ end
+
+ # Creates a remove button widget
+ #
+ # Intended for modifying sources table (@see ntp_sources_list_table)
+ #
+ # @return YUI widget
+ def ntp_source_remove_button
+ to_yui_term(@source_remove_button)
+ end
+
+ # Creates a combo for selecting source type
+ #
+ # Currently supported types are "Pool" or "Server" (@see
ntp_sources_list_table)
+ #
+ # @return YUI widget
+ def ntp_source_type_combo
+ to_yui_term(@source_type_combo)
+ end
+
+ # @param [AbstractWidget] widget a widget from new CWM model class tree
+ # @return [::CWM::UITerm] term for libyui
+ def to_yui_term(widget)
+ # Warning: Close your eyes
+ # Still looking? OK, so
+ # - we're going to translate CWM widgets
+ # - we have to bcs only reason for this (and related methods) is that it
creates
+ # part of dialog (in fact modifies on the fly) which is constructed in
yast2-country.
+ # We cannot use whole power of CWM and have to "emulate it"
+ # - involved methods are at least ui_init (creates relevant part of the
dialog) and
+ # ui_handle (processes user's input)
+ CWM.prepareWidget(widget.cwm_definition)["widget"]
+ # You can open eyes now
+ end
+
# @param [Yast::Term] replace_point id of replace point which should be
used
# @param [Boolean] first_time when asking for first time, we check if
service is running
# @return should our radio button be selected
def ui_init(replace_point, first_time)
- if select_ntp_server
- ntp_server_widget = ComboBox(
- Id(:ntp_address),
- Opt(:editable, :hstretch),
- # TRANSLATORS: combo box label
- _("&NTP Server Address")
- )
- else
- # Only show all ntp servers
- text = _("Synchronization Servers:\n").dup
- counter = (NtpClient.GetUsedNtpServers.size > 3) ? 3 :
NtpClient.GetUsedNtpServers.size
- counter.times do |i|
- text << NtpClient.GetUsedNtpServers[i]
- text << "\n"
- end
- if NtpClient.GetUsedNtpServers.size > 3
- # TRANSLATOR %{count} number of additional servers
- text << format(_("... (%{count} more servers)"),
- count: (NtpClient.GetUsedNtpServers.size - counter))
- end
- ntp_server_widget = Label(text)
- end
+ log.info("ui_init - enter")
if Stage.initial
# TRANSLATORS: push button label
- ntp_server_action_widget = Left(PushButton(Id(:ntp_now),
_("S&ynchronize now")))
+ ntp_server_action_widget = PushButton(Id(:ntp_now), _("S&ynchronize
now"))
save_run_widget = VBox(
HBox(
HSpacing(0.5),
@@ -247,31 +323,36 @@
save_run_widget = VBox()
end
- cont = VBox(
- VSpacing(0.5),
- HBox(
- HSpacing(3),
- HWeight(
- 1,
- Left(
- ntp_server_widget
- )
+ cont = HBox(
+ VBox(
+ Left(
+ ntp_sources_list_table
),
- HWeight(
- 1,
- VBox(
- # In TextMode and empty label is not filling an extra space, so
- # an explicit vertical space was added in order to move down the
- # push button being aligned with the combo box input.
- UI.TextMode ? VSpacing(1) : Label(""),
- ntp_server_action_widget
+ Left(
+ VSquash(
+ HBox(
+ Bottom(
+ ntp_source_type_combo
+ ),
+ Bottom(
+ ntp_source_input_widget
+ ),
+ Bottom(
+ ntp_source_add_button
+ )
+ )
)
)
),
- HBox(
- HSpacing(3),
- HWeight(
- 1,
+ Top(
+ VBox(
+ Left(
+ ntp_server_action_widget
+ ),
+ Left(
+ ntp_source_remove_button
+ ),
+ VSpacing(1),
save_run_widget
)
)
@@ -314,19 +395,22 @@
end
# Writes configuration for ntp client.
- # @param ntp_servers [Array<String>] list of servers to configure as ntp
sync sources
+ # @param ntp_sources [Hash<String, Symbol>] ntp sources ({ "address" =>
<:pool|:server> })
# @param ntp_server [String] fallback server that is used if `ntp_servers`
param is empty.
# @param run_service [Boolean] define if synchronize with systemd services
or via systemd timer
# @return true
- def WriteNtpSettings(ntp_servers, ntp_server, run_service)
- ntp_servers = deep_copy(ntp_servers)
+ def WriteNtpSettings(ntp_sources, ntp_server, run_service)
+ ntp_sources = deep_copy(ntp_sources)
NtpClient.modified = true
- if select_ntp_server
- # The user has changed the ntp-server(s). So we are writing them.
- NtpClient.ntp_conf.clear_pools
- ntp_servers << ntp_server if ntp_servers.empty?
- ntp_servers.each do |server|
- NtpClient.ntp_conf.add_pool(server)
+
+ # reason for this ... historical
+ ntp_sources = { ntp_server => :server } if ntp_sources.empty?
+
+ if !ntp_sources.empty?
+ # Servers list available. So we are writing them.
+ NtpClient.ntp_conf.clear_sources
+ ntp_sources.each_pair do |addr, type|
+ NtpClient.ntp_conf.send("add_#{type}", addr)
end
end
if run_service
@@ -355,7 +439,7 @@
#
# @param [Hash] params
# @option params [String] "server" The NTP server address, taken from the
UI if empty
- # @option params [Array<String>] "servers" A collection of NTP servers
+ # @option params [Hash<String, Symbol>] ntp sources ( { "address" =>
<:pool | :server> })
# @option params [Boolean] "run_service" Whether service should be active
and enable
# @option params [Boolean] "write_only" If only is needed to write the
settings, (bnc#589296)
# @option params [Boolean] "ntpdate_only" ? TODO: rename to onetime
@@ -370,14 +454,9 @@
params.compact!
ntp_server = params.fetch("server", "")
- ntp_servers = params.fetch("servers", NtpClient.GetUsedNtpServers)
+ ntp_servers = params.fetch("servers", NtpClient.GetUsedNtpSources)
run_service = params.fetch("run_service", NtpClient.run_service)
- # Get the ntp_server value from UI only if isn't present (probably
wasn't given as parameter)
- if ntp_server.strip.empty? && select_ntp_server
- ntp_server = UI.QueryWidget(Id(:ntp_address), :Value) || ""
- end
-
return :invalid_hostname if !ntp_server.empty? &&
!ValidateSingleServer(ntp_server)
add_or_install_required_package unless params["write_only"]
@@ -389,11 +468,7 @@
# Only if network is running try to synchronize
# the ntp server.
if NetworkService.isNetworkRunning &&
!Service.Active(NtpClient.service_name)
- ntp_servers = [ntp_server]
- if !select_ntp_server
- # Taking also the rest of the ntp servers, configured in the ntp
client module.
- ntp_servers += NtpClient.GetUsedNtpServers unless
NtpClient.GetUsedNtpServers.nil?
- end
+ ntp_servers = [ntp_server] + ntp_servers.keys
ntp_servers.delete("")
ntp_servers.uniq
exit_code = 0
@@ -414,6 +489,21 @@
def ui_handle(input)
redraw = false
case input
+ when @source_add_button.widget_id
+ ntp_source_address = UI.QueryWidget(Id(:ntp_address), :Value)
+ ntp_source_type = @source_type_combo.value
+ ntp_source = { ntp_source_address => ntp_source_type }
+
+ NtpClient.ntp_conf.send("add_#{ntp_source_type}".downcase,
ntp_source_address)
+
+ @sources_table.sources = @sources_table.sources.merge(ntp_source)
+ when @source_remove_button.widget_id
+ ntp_source_address = @sources_table.value
+ ntp_source_type = @source_type_combo.value
+
+ NtpClient.ntp_conf.send("delete_#{ntp_source_type}".downcase,
ntp_source_address)
+
+ @sources_table.remove_item(ntp_source_address)
when :ntp_configure
rv = AskUser()
if rv == :invalid_hostname
@@ -462,6 +552,8 @@
if Stage.initial
Ops.set(argmap, "ntpdate_only", true) if UI.QueryWidget(Id(:ntp_save),
:Value) == false
Ops.set(argmap, "run_service", true) if
UI.QueryWidget(Id(:run_service), :Value)
+
+ argmap["servers"] = @sources_table.sources
end
rv = Write(argmap)
@@ -470,7 +562,8 @@
# So we are done here.
return true unless select_ntp_server
- server = Convert.to_string(UI.QueryWidget(Id(:ntp_address), :Value))
+ # we get [ "address", :<type> ], we need only address here
+ server = @sources_table.sources.first[0]
Builtins.y2milestone("ui_try_save argmap %1", argmap)
if rv == :invalid_hostname
handle_invalid_hostname(server)
@@ -490,8 +583,9 @@
)
return false # loop on
elsif !Ops.get_boolean(argmap, "ntpdate_only", false)
+ # user explicitly wanted to get what (s)he configured, give it to him
WriteNtpSettings(
- [],
+ @sources_table.sources,
server,
Ops.get_boolean(argmap, "run_service", false)
) # may be the server is realy not accessable
@@ -522,28 +616,35 @@
# Public list of ntp servers Yast::Term items with the ntp address ID and
# label
#
- # @return [Array<Yast::Term>] ntp address Item
+ # @return [Hash<String, Symbol>] ntp address and its type (server / pool)
def timezone_ntp_items
timezone_country = Timezone.GetCountryForTimezone(Timezone.timezone)
servers = NtpClient.country_ntp_servers(timezone_country)
# Select the first occurrence of pool.ntp.org as the default option
(bnc#940881)
- selected = servers.find { |s| s.hostname.end_with?("pool.ntp.org") }
- servers.map do |server|
- Item(Id(server.hostname), server.hostname, server.hostname == selected)
+ servers.find { |s| s.hostname.end_with?("pool.ntp.org") }
+ servers.each_with_object({}) do |server, acc|
+ # currently no way how to safely decide whether the source is pool or
server
+ # so use pool as default (either it is from pool.ntp.org or we cannot
decide for sure)
+ acc[server.hostname] = :pool
end
end
# List of dhcp ntp servers Yast::Term items with the ntp address ID and
# label
#
- # @return [Array<Yast::Term>] ntp address table Item
+ # @return [Hash<String, Symbol>] ntp address and its type (server / pool)
def dhcp_ntp_items
- NtpClient.dhcp_ntp_servers.map { |s| Item(Id(s.hostname), s.hostname) }
+ NtpClient.dhcp_ntp_servers.each_with_object({}) do |server, acc|
+ # dhcp can contain only an IP addresses in option 042
+ # (This option specifies a list of IP addresses indicating NTP
+ # servers available to the client. @see RFC 2132)
+ acc[server.hostname] = :server
+ end
end
# List of ntp servers Yast::Term items with the ntp address ID and label
#
- # @return [Array<Yast::Term>] ntp address table Item
+ # @return [Hash<String, Symbol>] ntp address and its type (server / pool)
def fallback_ntp_items
return @cached_fallback_ntp_items if @cached_fallback_ntp_items
@@ -569,12 +670,25 @@
# module which is not defined in the combo box. In that case we do not
offer
# a selection. The user should go back to ntp-client to change it.
if NtpClient.GetUsedNtpServers.size == 1
- ret = fallback_ntp_items.any? do |item|
- item.params[1] == NtpClient.GetUsedNtpServers.first
+ ret = fallback_ntp_items.keys.any? do |item|
+ item == NtpClient.GetUsedNtpServers.first
end
end
ret
end
+
+ # Widget for entering custom ntp source configuration
+ def ntp_source_input_widget
+ MinWidth(
+ 20,
+ ComboBox(
+ Id(:ntp_address),
+ Opt(:editable, :hstretch),
+ # TRANSLATORS: combo box label, ntp source can be either "server" or
"pool"
+ _("&NTP Source Address")
+ )
+ )
+ end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/src/include/ntp-client/dialogs.rb
new/yast2-ntp-client-4.5.3/src/include/ntp-client/dialogs.rb
--- old/yast2-ntp-client-4.5.2/src/include/ntp-client/dialogs.rb
2022-11-21 16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/src/include/ntp-client/dialogs.rb
2023-01-25 11:23:00.000000000 +0100
@@ -28,12 +28,6 @@
@widgets = nil
end
- # Display the popup to confirm abort
- # @return [Boolean] true if confirmed
- def abortPopup
- Popup.ReallyAbort(true)
- end
-
# Read settings dialog
# @return `abort if aborted and `next otherwise
def ReadDialog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-ntp-client-4.5.2/src/lib/cfa/chrony_conf.rb
new/yast2-ntp-client-4.5.3/src/lib/cfa/chrony_conf.rb
--- old/yast2-ntp-client-4.5.2/src/lib/cfa/chrony_conf.rb 2022-11-21
16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/src/lib/cfa/chrony_conf.rb 2023-01-25
11:23:00.000000000 +0100
@@ -10,7 +10,7 @@
# @see
http://www.rubydoc.info/github/config-files-api/config_files_api/CFA/AugeasParser
#
class ChronyConf < ::CFA::BaseModel
- PATH = "/etc/chrony.conf".freeze
+ PATH = "/etc/chrony.d/pool.conf".freeze
def initialize(file_handler: nil)
super(CFA::AugeasParser.new("chrony.lns"), PATH, file_handler:
file_handler)
@@ -36,27 +36,13 @@
# When hash is used, then format is that key is option name and
# value is either nil for keyword options or String with value for key
value options
def add_pool(address, options = :default)
- options = default_pool_options if options == :default
- # if there is already pool entry, place it after, if not, try use comment
- existing_pools = pure_pools
- matcher = if existing_pools.empty?
- # for now first chrony have pools under comment mentioning pool.ntp.org
- # so try to place it below
- Matcher.new { |k, v| k.start_with?("#comment") && v =~
/www\.pool\.ntp\.org/ }
- else
- # place after the last pool available
- Matcher.new(key: existing_pools.last[:key],
- value_matcher: existing_pools.last[:value])
- end
- placer = AfterPlacer.new(matcher)
-
- key = "pool[]"
- value = AugeasTreeValue.new(AugeasTree.new, address)
- options.each_pair do |k, v|
- value.tree[k] = v
- end
+ add_source("pool[]", address, options) { pure_pools }
+ end
- data.add(key, value, placer)
+ def add_server(address, options = :default)
+ # we can have multiple servers defined (=> same keys). Augeas stores it
as a collection
+ # that's why [] is added to the key
+ add_source("server[]", address, options) { pure_servers }
end
# modifies pool entry with original address to new adress and specified
options
@@ -86,6 +72,12 @@
data.delete(matcher)
end
+ def delete_server(address)
+ matcher = server_matcher(address)
+
+ data.delete(matcher)
+ end
+
def default_pool_options
{ "iburst" => nil }
end
@@ -95,24 +87,24 @@
data.delete(POOLS_MATCHER)
end
+ def clear_servers
+ data.delete(SERVERS_MATCHER)
+ end
+
+ def clear_sources
+ clear_pools
+ clear_servers
+ end
+
# returns copy of available pools
# TODO allow modify of specific pool
# hash with key server and value is options hash
def pools
- pools_data = pure_pools.map { |p| p[:value] }
- pools_map = pools_data.map do |entry|
- case entry
- when String
- [entry, {}]
- when AugeasTreeValue
- options = Hash[entry.tree.data.map { |e| [e[:key], e[:value]] }]
- [entry.value, options]
- else
- raise "invalid pool data #{entry.inspect}"
- end
- end
+ sources(:pools)
+ end
- Hash[pools_map]
+ def servers
+ sources(:servers)
end
# Is there any hardware clock settings?
@@ -137,17 +129,71 @@
end
POOLS_MATCHER = Matcher.new(collection: "pool")
+ SERVERS_MATCHER = Matcher.new(collection: "server")
+
+ def sources(source)
+ sources_data = send("pure_#{source}").map { |p| p[:value] }
+ sources_map = sources_data.map do |entry|
+ case entry
+ when String
+ [entry, {}]
+ when AugeasTreeValue
+ options = Hash[entry.tree.data.map { |e| [e[:key], e[:value]] }]
+ [entry.value, options]
+ else
+ raise "invalid source data #{entry.inspect}"
+ end
+ end
+
+ Hash[sources_map]
+ end
+
+ def add_source(type, address, options = :default)
+ options = default_pool_options if options == :default
+ # if there is already ntp source entry, place it after, if not, try use
comment
+ existing = yield
+ matcher = if existing.empty?
+ # for now first chrony have list of sources under comment mentioning
pool.ntp.org
+ # so try to place it below
+ Matcher.new { |k, v| k.start_with?("#comment") && v =~
/www\.pool\.ntp\.org/ }
+ else
+ # place after the last pool available
+ Matcher.new(key: existing.last[:key],
+ value_matcher: existing.last[:value])
+ end
+ placer = AfterPlacer.new(matcher)
+
+ key = type
+ value = AugeasTreeValue.new(AugeasTree.new, address)
+ options.each_pair do |k, v|
+ value.tree[k] = v
+ end
+
+ data.add(key, value, placer)
+ end
# list of pools in internal data structure
def pure_pools
data.select(POOLS_MATCHER)
end
+ # list of ntp servers in internal data structure
+ def pure_servers
+ data.select(SERVERS_MATCHER)
+ end
+
def pool_matcher(address)
Matcher.new do |k, v|
k == "pool[]" &&
(v.respond_to?(:value) ? v.value == address : v == address)
end
end
+
+ def server_matcher(address)
+ Matcher.new do |k, v|
+ k == "server[]" &&
+ (v.respond_to?(:value) ? v.value == address : v == address)
+ end
+ end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/src/lib/y2ntp_client/client/finish.rb
new/yast2-ntp-client-4.5.3/src/lib/y2ntp_client/client/finish.rb
--- old/yast2-ntp-client-4.5.2/src/lib/y2ntp_client/client/finish.rb
2022-11-21 16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/src/lib/y2ntp_client/client/finish.rb
2023-01-25 11:23:00.000000000 +0100
@@ -38,17 +38,22 @@
# User config from installation time:
# fortunately so far we only have the server address(es)
pools = Yast::NtpClient.ntp_conf.pools
- log.info "pools added during installation #{pools.inspect}"
+ log.info "NTP pools added during installation #{pools.inspect}"
+ servers = Yast::NtpClient.ntp_conf.servers
+ log.info "NTP servers added during installation #{servers.inspect}"
# ntp.conf from the RPM
Yast::NtpClient.config_has_been_read = false
Yast::NtpClient.ProcessNtpConf
# put users server(s) back
- Yast::NtpClient.ntp_conf.clear_pools
+ Yast::NtpClient.ntp_conf.clear_sources
- pools.each_pair do |server, options|
- Yast::NtpClient.ntp_conf.add_pool(server, options)
+ pools.each_pair do |pool, options|
+ Yast::NtpClient.ntp_conf.add_pool(pool, options)
+ end
+ servers.each_pair do |server, options|
+ Yast::NtpClient.ntp_conf.add_server(server, options)
end
Yast::NtpClient.write_only = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/src/lib/y2ntp_client/widgets/sources_table.rb
new/yast2-ntp-client-4.5.3/src/lib/y2ntp_client/widgets/sources_table.rb
--- old/yast2-ntp-client-4.5.2/src/lib/y2ntp_client/widgets/sources_table.rb
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/src/lib/y2ntp_client/widgets/sources_table.rb
2023-01-25 11:23:00.000000000 +0100
@@ -0,0 +1,126 @@
+# Copyright (c) [2019] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+require "cwm/table"
+require "cwm/widget"
+
+module Y2NtpClient
+ module Widgets
+ # Table displaying list of defined NTP sources. It displays its type and
address.
+ class SourcesTable < CWM::Table
+ attr_reader :sources
+
+ SOURCES = {
+ pool: "Pool".freeze,
+ server: "Server".freeze
+ }.freeze
+
+ # @param sources [Hash<String, Symbol>] hash of ntp sources address (ip
or url)
+ # and type (pool or server)
+ def initialize(sources = {})
+ textdomain "ntp-client"
+
+ # TODO: validation of the input
+ @sources = sources
+ end
+
+ def header
+ [
+ _("Type"),
+ _("Address")
+ ]
+ end
+
+ def items
+ # <id, source-type, source-address>
+ @sources.map { |a, t| [a, SOURCES[t], a] }
+ end
+
+ def sources=(sources)
+ @sources = sources
+
+ change_items(items)
+ items&.each_with_object({}) { |i, acc| acc[i[1]] = i[2] }
+ end
+
+ # Adds one item into table's content
+ #
+ # @param item [Array] a table item in array format (<id, column1 value,
column2 value, ...)
+ def add_item(item)
+ change_items(items << item)
+ end
+
+ # Removes one item from table's content
+ #
+ # @param id [any] id of table's item to remove
+ def remove_item(id)
+ updated_items = items.delete_if { |i| i[0] == id }
+ change_items(updated_items)
+ end
+ end
+
+ # A button for adding an item into @see SourcesTable
+ class SourcesAdd < CWM::PushButton
+ def initialize
+ textdomain "ntp-client"
+ end
+
+ def label
+ _("Add")
+ end
+
+ def handle
+ nil
+ end
+ end
+
+ # A button for removing an item from @see SourcesTable
+ class SourcesRemove < CWM::PushButton
+ def initialize
+ textdomain "ntp-client"
+ end
+
+ def label
+ _("Remove")
+ end
+
+ def handle
+ nil
+ end
+ end
+
+ # A ComboBox containing varius supported types of NTP Sources
+ class SourcesType < CWM::ComboBox
+ def initialize
+ textdomain "ntp-client"
+ end
+
+ def label
+ _("Source Type")
+ end
+
+ def items
+ [
+ [:pool, _("Pool")],
+ [:server, _("Server")]
+ ]
+ end
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-ntp-client-4.5.2/src/modules/NtpClient.rb
new/yast2-ntp-client-4.5.3/src/modules/NtpClient.rb
--- old/yast2-ntp-client-4.5.2/src/modules/NtpClient.rb 2022-11-21
16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/src/modules/NtpClient.rb 2023-01-25
11:23:00.000000000 +0100
@@ -1,4 +1,3 @@
-# File: modules/NtpClient.ycp
# Package: Configuration of ntp-client
# Summary: Data for configuration of ntp-client, input and output functions.
# Authors: Jiri Srain <[email protected]>
@@ -34,7 +33,7 @@
# @see #http://www.pool.ntp.org/
RANDOM_POOL_NTP_SERVERS = ["0.pool.ntp.org", "1.pool.ntp.org",
"2.pool.ntp.org"].freeze
- NTP_FILE = "/etc/chrony.conf".freeze
+ NTP_FILE = "/etc/chrony.d/pool.conf".freeze
TIMER_FILE = "yast-timesync.timer".freeze
# The file name of systemd timer for the synchronization.
@@ -64,7 +63,6 @@
Yast.import "Directory"
Yast.import "FileUtils"
Yast.import "Lan"
- Yast.import "Language"
Yast.import "Message"
Yast.import "Mode"
Yast.import "Package"
@@ -338,6 +336,8 @@
# Read all ntp-client settings
# @return true on success
def Read
+ log.info("NtpClient::Read - enter")
+
return true if @config_has_been_read
# We do not set help text here, because it was set outside
@@ -386,6 +386,12 @@
ntp_conf.pools.keys
end
+ # @return [Hash<String, Symbol> pair of source address and type (server,
pool)
+ def GetUsedNtpSources
+ ntp_conf.servers.keys.each_with_object(sources = {}) { |s, res| res[s] =
:server }
+ ntp_conf.pools.keys.each_with_object(sources) { |s, res| res[s] = :pool }
+ end
+
# Write all ntp-client settings
# @return true on success
def Write
@@ -885,6 +891,7 @@
def timer_content
erb_template = ::File.read(Directory.find_data_file("#{TIMER_FILE}.erb"))
content = ERB.new(erb_template)
+ # warning on unused timeout is false positive - used in the erb loaded
above
timeout = @sync_interval
content.result(binding)
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/test/data/scr_root/etc/chrony.d/pool.conf.original
new/yast2-ntp-client-4.5.3/test/data/scr_root/etc/chrony.d/pool.conf.original
---
old/yast2-ntp-client-4.5.2/test/data/scr_root/etc/chrony.d/pool.conf.original
1970-01-01 01:00:00.000000000 +0100
+++
new/yast2-ntp-client-4.5.3/test/data/scr_root/etc/chrony.d/pool.conf.original
2023-01-25 11:23:00.000000000 +0100
@@ -0,0 +1,3 @@
+# Use public servers from the pool.ntp.org project.
+# Please consider joining the pool (http://www.pool.ntp.org/join.html).
+pool 2.opensuse.pool.ntp.org iburst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/test/ntp_client_proposal_test.rb
new/yast2-ntp-client-4.5.3/test/ntp_client_proposal_test.rb
--- old/yast2-ntp-client-4.5.2/test/ntp_client_proposal_test.rb 2022-11-21
16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/test/ntp_client_proposal_test.rb 2023-01-25
11:23:00.000000000 +0100
@@ -54,18 +54,18 @@
.and_return(["de.pool.ntp.org"])
allow(subject).to receive(:select_ntp_server).and_return(true)
allow(Yast::Stage).to receive(:initial).and_return(true)
+ allow(Yast::UI).to receive(:ChangeWidget)
+ allow(Y2Network::NtpServer).to receive(:default_servers).and_return({})
end
context "when NTP servers were found via DHCP" do
let(:dhcp_ntp_servers) { ["test.example.net"] }
it "proposes only the found servers" do
- expect(Yast::UI).to receive(:ChangeWidget) do |*args|
+ expect(Yast::UI).to receive(:ChangeWidget).with(Id(:ntp_address),
any_args) do |*args|
items = args.last
hostnames = items.map { |i| i[1] }
- expect(hostnames).to eq(
- ["test.example.net"]
- )
+ expect(hostnames).to include "test.example.net"
end
subject.MakeProposal
end
@@ -75,7 +75,7 @@
let(:dhcp_ntp_servers) { [] }
it "proposes the known public servers for the current timezone" do
- expect(Yast::UI).to receive(:ChangeWidget) do |*args|
+ expect(Yast::UI).to receive(:ChangeWidget).with(Id(:ntp_address),
any_args) do |*args|
items = args.last
hostnames = items.map { |i| i[1] }
expect(hostnames).to eq(["de.pool.ntp.org"])
@@ -88,7 +88,7 @@
let(:config_was_read?) { true }
it "proposes the known public servers for the current timezone" do
- expect(Yast::UI).to receive(:ChangeWidget) do |*args|
+ expect(Yast::UI).to receive(:ChangeWidget).with(Id(:ntp_address),
any_args) do |*args|
items = args.last
hostnames = items.map { |i| i[1] }
expect(hostnames).to eq(["de.pool.ntp.org"])
@@ -101,7 +101,7 @@
let(:ntp_was_selected?) { true }
it "proposes the known public servers for the current timezone" do
- expect(Yast::UI).to receive(:ChangeWidget) do |*args|
+ expect(Yast::UI).to receive(:ChangeWidget).with(Id(:ntp_address),
any_args) do |*args|
items = args.last
hostnames = items.map { |i| i[1] }
expect(hostnames).to eq(["de.pool.ntp.org"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/yast2-ntp-client-4.5.2/test/ntp_client_test.rb
new/yast2-ntp-client-4.5.3/test/ntp_client_test.rb
--- old/yast2-ntp-client-4.5.2/test/ntp_client_test.rb 2022-11-21
16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/test/ntp_client_test.rb 2023-01-25
11:23:00.000000000 +0100
@@ -18,10 +18,10 @@
let(:data_dir) { File.join(File.dirname(__FILE__), "data") }
around do |example|
- ::FileUtils.cp(File.join(data_dir, "scr_root/etc/chrony.conf.original"),
- File.join(data_dir, "scr_root/etc/chrony.conf"))
+ ::FileUtils.cp(File.join(data_dir,
"scr_root/etc/chrony.d/pool.conf.original"),
+ File.join(data_dir, "scr_root/etc/chrony.d/pool.conf"))
change_scr_root(File.join(data_dir, "scr_root"), &example)
- ::FileUtils.rm(File.join(data_dir, "scr_root/etc/chrony.conf"))
+ ::FileUtils.rm(File.join(data_dir, "scr_root/etc/chrony.d/pool.conf"))
end
# mock to allow read of scr chrooted env
@@ -258,7 +258,7 @@
subject.ntp_conf.add_pool("tik.cesnet.cz")
expect(subject.Write).to eq true
- lines = File.read(File.join(data_dir, "scr_root/etc/chrony.conf"))
+ lines = File.read(File.join(data_dir, "scr_root/etc/chrony.d/pool.conf"))
expect(lines.lines).to include("pool tik.cesnet.cz iburst\n")
end
@@ -703,7 +703,7 @@
end
it "returns false if config doesn't exist" do
- allow(Yast::FileUtils).to
receive(:Exists).with("/etc/chrony.conf").and_return(false)
+ allow(Yast::FileUtils).to
receive(:Exists).with("/etc/chrony.d/pool.conf").and_return(false)
expect(subject.ProcessNtpConf).to eql(false)
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/yast2-ntp-client-4.5.2/test/y2ntp_client/client/auto_test.rb
new/yast2-ntp-client-4.5.3/test/y2ntp_client/client/auto_test.rb
--- old/yast2-ntp-client-4.5.2/test/y2ntp_client/client/auto_test.rb
2022-11-21 16:11:18.000000000 +0100
+++ new/yast2-ntp-client-4.5.3/test/y2ntp_client/client/auto_test.rb
2023-01-25 11:23:00.000000000 +0100
@@ -74,7 +74,7 @@
end
it "disables progress" do
- expect(Yast::Progress).to
receive(:set).with(false).and_return(false).twice
+ expect(Yast::Progress).to
receive(:set).with(false).and_return(false).at_least(2)
subject.write
end
end