Skip to content

Commit

Permalink
Merge pull request #81 from yast/misc-fixes
Browse files Browse the repository at this point in the history
bsc#1169410 fixes
  • Loading branch information
imobachgs committed May 25, 2020
2 parents 0499b2d + a269fd5 commit 827f51a
Show file tree
Hide file tree
Showing 44 changed files with 782 additions and 424 deletions.
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ the required workflow. In the example below, only the relevant parts are shown:
<metadata_root>/srv/formula_metadata</metadata_root>
</listentry>
</formulas_sets>
<states_roots config:type="list">
<listentry>/srv/salt</listentry>
</states_roots>
<!-- Default Salt Formulas pillar data directory -->
<pillar_root>/srv/pillar</pillar_root>
</configuration_management>
Expand Down Expand Up @@ -138,18 +141,19 @@ The supported widget types are listed in the

## Options Reference

Name | Type | Mode | Description
--- | --- | --- | ---
type | string | all | Configuration Management System (`salt` or `puppet`)
master | string | client | Master server (if not set, it will run as masterless
auth_attempts | integer | client | Number of attempts when connecting to the master server
auth_time_out | integer | client | Time (in seconds) between attempts to connect to the master
enable_services | boolean | client | Enable the configuration management service at the end
formulas_roots | list(string) | all | List of directories to search for Salt formulas
states_roots | list(string) | all | List of directories to search for Salt states
pillar_root | string | all | Path to write the Salt Pillar content
pillar_url | string | masterless | URL to get Pillar content from
keys_url | string | masterless | URL to get authentication keys from
states_url | string | masterless | URL to get the Salt states from
modules_url | list(string) | masterless | URL to get Puppet modules from
enabled_states | list(string) | masterless | List of states/formulas to apply
Name | Type | Provisioner | Mode | Description
--- | --- | --- | --- | ---
type | string | - | all | Configuration Management System (`salt` or `puppet`)
master | string | all | client | Master server (if not set, it will run as masterless
auth_attempts | integer | all | client | Number of attempts when connecting to the master server
auth_time_out | integer | all | client | Time (in seconds) between attempts to connect to the master
enable_services | boolean | all | client | Enable the configuration management service at the end
formulas_roots | list(string) | salt | all | List of directories to search for Salt formulas
states_roots | list(string) | salt | all | List of directories to search for Salt states
pillar_root | string | salt | all | Path to write the Salt Pillar content
pillar_url | string | salt | masterless | URL to get Pillar content from
keys_url | string | all | masterless | URL to get authentication keys from
states_url | string | salt | masterless | URL to get the Salt states from
modules_url | list(string) | puppet | masterless | URL to get Puppet modules from
enabled_states | list(string) | salt | masterless | List of states/formulas to apply
log_level | string | all | all | Log level when running the provisioner (default to 'info')
20 changes: 20 additions & 0 deletions package/yast2-configuration-management.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
-------------------------------------------------------------------
Thu May 21 21:20:44 UTC 2020 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

- bsc#1169410:
- Add an option to set the log level when running the
provisioners. By default, it is set to "info".
- By default, do not retry in masterless mode.
- Honor the AutoYaST reporting settings.
- When not running during autoinstallation, do not automatically
close the dialog after finishing.
- Allow using several locations to save pillars data.
- Do not leak passwords from pillars to the console.
- Add the /usr/share/salt-formulas to the list of directories
to search for formulas.
- Groups and namespaces are presented in the same way due to
some UI limitations.
- Fixes several problems related to widgets visibility.
- Take precedence over existing top.sls files.
- 4.2.5

-------------------------------------------------------------------
Mon Mar 30 21:01:50 UTC 2020 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-configuration-management.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


Name: yast2-configuration-management
Version: 4.2.4
Version: 4.2.5
Release: 0
Url: https://github.com/yast/yast-migration
Summary: YaST2 - YaST Configuration Management
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require "y2configuration_management/clients/provision"

Yast.import "Service"
Yast.import "Wizard"

module Y2ConfigurationManagement
# Client to write the provisioner's configuration
Expand All @@ -29,6 +30,7 @@ def initialize
# otherwise it returns false.
def write
return false if config.nil?
Yast::Wizard.CreateDialog
log.info("Provisioning Configuration Management with config #{config.inspect}")
configurator.prepare(require_formulas: false)
# saving settings to target system
Expand All @@ -39,6 +41,7 @@ def write
configurator.services.each { |s| Service.Enable(s) }
end

Yast::Wizard.CloseDialog
true
end

Expand Down
27 changes: 26 additions & 1 deletion src/lib/y2configuration_management/clients/provision.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require "y2configuration_management/dialogs/running"
require "y2configuration_management/configurations/base"

Yast.import "Report"

module Y2ConfigurationManagement
module Clients
# This client takes care of provisioning the system, although the real work
Expand All @@ -16,7 +18,7 @@ class Provision < Yast::Client
# Run the client
def run
return false unless runner
dialog = Y2ConfigurationManagement::Dialogs::Running.new
dialog = Y2ConfigurationManagement::Dialogs::Running.new(reporting_opts: reporting_opts)
dialog.run do |stdout, stderr|
# Connect stdout and stderr with the dialog
runner.run(stdout, stderr)
Expand All @@ -40,6 +42,29 @@ def runner
def config
@config ||= Y2ConfigurationManagement::Configurations::Base.current
end

DEFAULT_REPORTING_OPTS = {
open_after_success: true, open_after_error: true
}.freeze
private_constant :DEFAULT_REPORTING_OPTS

# Determines the reporting options
#
# During autoinstallation, the options depend on the AutoYaST reporting settings.
#
# @return [Hash]
def reporting_opts
return DEFAULT_REPORTING_OPTS unless Yast::Mode.auto
messages = Yast::Report.message_settings
errors = Yast::Report.error_settings
opts = {
open_after_success: messages["show"],
open_after_error: errors["show"]
}
opts[:timeout_after_success] = messages["timeout"] if opts[:open_after_success]
opts[:timeout_after_error] = errors["timeout"] if opts[:open_after_error]
opts
end
end
end
end
31 changes: 16 additions & 15 deletions src/lib/y2configuration_management/configurations/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class Base
attr_reader :keys_url
# @return [Boolean] CM Services will be enabled on the target system
attr_reader :enable_services
# @return [Symbol] Log level
attr_reader :log_level

class << self
# @return [Base] Current configuration
Expand Down Expand Up @@ -98,9 +100,10 @@ def initialize(options = {})
@master = options[:master]
@mode = @master ? :client : :masterless
@keys_url = URI(options[:keys_url]) if options[:keys_url]
@auth_attempts = options[:auth_attempts] || DEFAULT_AUTH_ATTEMPTS
@auth_time_out = options[:auth_time_out] || DEFAULT_AUTH_TIME_OUT
@auth_attempts = auth_required? ? options.fetch(:auth_attempts, DEFAULT_AUTH_ATTEMPTS) : 1
@auth_time_out = auth_required? ? options.fetch(:auth_time_out, DEFAULT_AUTH_TIME_OUT) : 0
@enable_services = !!options[:enable_services]
@log_level = options[:log_level] ? options[:log_level].to_sym : :info
post_initialize(options)
end

Expand All @@ -113,24 +116,22 @@ def post_initialize(_options)
nil
end

# Return a path to a temporal directory to extract states/pillars
# Return a path to a temporal directory to extract modules/states/pillars
#
# @param scope [Symbol] Path relative to inst-sys (:local) or the target system (:target)
# @return [String] Path name to the temporal directory
def work_dir(scope = :local)
@work_dir ||= build_work_dir_name
prefix = (scope == :target) ? "/" : Yast::Installation.destdir
Pathname.new(prefix).join(@work_dir)
def work_dir
@work_dir ||= Pathname.new(Yast::Directory.vardir).join(
"cm-#{Time.now.strftime("%Y%m%d%H%M")}"
)
end

private

# Build a path to be used as work_dir
# Determines whether the authentication is needed
#
# By default, authentication is needed only in :client mode.
#
# @return [Pathname] Relative work_dir path
def build_work_dir_name
path = Pathname.new(Yast::Directory.vardir).join("cm-#{Time.now.strftime("%Y%m%d%H%M")}")
path.relative_path_from(Pathname.new("/"))
# @return [Boolean]
def auth_required?
@mode == :client
end
end
end
Expand Down
10 changes: 10 additions & 0 deletions src/lib/y2configuration_management/configurations/formulas_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ class FormulasSet
# @return [Pathname,nil]
attr_reader :pillar_root

class << self
# Convenience method to create a set from a directory following the conventions
#
# @param path [Pathname] Directory for the formulas set
# @return [FormulasSet]
def from_directory(path)
new(path.join("metadata"), path.join("states"))
end
end

# Constructor
#
# @param metadata_root [Pathname] Directory where formulas metadata is located
Expand Down
78 changes: 27 additions & 51 deletions src/lib/y2configuration_management/configurations/salt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ module Configurations
# It extends the {Base} class with some Salt specific options. See #post_initialize for further
# information about those options.
#
# The methods that are related to path names ({#states_root}, {#formulas_roots}, {#pillar_root},
# {#pillar_roots}, are aware of the scope where YaST is running, so it takes
# `Yast::Installation.destdir` into account.
#
# @example Directories during installation
# config = Salt.new
# config.pillar_roots #=> [#<Pathname:/mnt/var/lib/YaST2/cm-202005120829/pillar>]
Expand All @@ -24,8 +20,6 @@ class Salt < Base
attr_reader :pillar_url
# @return [Array<String>] States (including formulas) which will be applied
attr_reader :enabled_states
# @return [Array<FormulasSet>] List of formulas locations
attr_reader :formulas_sets

class << self
# Returns a {Salt} object from a hash
Expand Down Expand Up @@ -68,83 +62,65 @@ def post_initialize(options)
@custom_pillar_root = Pathname.new(options[:pillar_root]) if options[:pillar_root]
@custom_states_roots = pathnames_from(options[:states_roots])
@enabled_states = options.fetch(:enabled_states, [])
@formulas_sets = options.fetch(:formulas_sets, [])
@custom_formulas_sets = options.fetch(:formulas_sets, [])
end

# Return path to the Salt main pillars directory (the one containing the top.sls)
#
# @param scope [Symbol] Path relative to inst-sys (:local) or the
# target system (:target)
# @return [Array<Pathname>] Path to Salt pillars
def pillar_roots(scope = :local)
paths = ([@custom_pillar_root] + formulas_sets.map(&:pillar_root)).compact
paths = scoped_paths(paths, scope)
paths << pillar_root(scope) unless @custom_pillar_root
paths
def pillar_roots
[default_pillar_root] + formulas_sets.map(&:pillar_root).compact
end

# Return path to the Salt pillars directory
# Return path to the default Salt pillars directory
#
# If it is not defined by the user, the default pillar directory lives
# under the {#work_dir}.
#
# @param scope [Symbol] Path relative to inst-sys (:local) or the
# target system (:target)
# @return [Pathname] Path to Salt pillars
def pillar_root(scope = :local)
work_dir(scope).join("pillar")
def default_pillar_root
@default_pillar_root ||= @custom_pillar_root || work_dir.join("pillar")
end

# Return paths to the states root
#
# @param scope [Symbol] Path relative to inst-sys (:local) or the
# target system (:target)
# @return [Array<Pathname>] Path to Salt state roots
def states_roots(scope = :local)
def states_roots
paths = @custom_states_roots + formulas_sets.map(&:states_root).compact
scoped_paths(paths, scope) + [states_root(scope)]
[default_states_root] + paths
end

# Return path to the Salt states directory
# Return path to the default Salt states directory
#
# The default Salt states directory lives under the {#work_dir}.
#
# @param scope [Symbol] Path relative to inst-sys (:local) or the
# target system (:target)
# @return [Pathname] Path to Salt states
def states_root(scope = :local)
work_dir(scope).join("salt")
def default_states_root
work_dir.join("salt")
end

# TODO: is still used?
# Return paths to all formulas directories
#
# @param scope [Symbol] Path relative to inst-sys (:local) or the
# target system (:target)
# @return [Array<Pathname>] Path to Salt formulas roots
def formulas_roots(scope = :local)
paths = formulas_sets.map(&:metadata_root).compact
scoped_paths(paths, scope) + [default_formulas_root(scope)]
def formulas_roots
formulas_sets.map(&:metadata_root).compact
end

# Return path to the default Salt formulas directory
# Return the list of formulas sets
#
#
# @param scope [Symbol] Path relative to inst-sys (:local) or the
# target system (:target)
# @return [Pathname] Path to Salt formulas
def default_formulas_root(scope = :local)
work_dir(scope).join("formulas")
# @return [Array<FormulasSet>] List of formulas sets
def formulas_sets
[default_formulas_set] + @custom_formulas_sets
end

private

# Convenience method for obtaining the list of given paths relative to
# inst-sys (scope: :local) or to the target system (scope: :target)
# Return path to the default Salt formulas directory
#
# @param paths [Array<Pathname>] list of path to be scoped
# @param scope [Symbol] Path relative to inst-sys (:local) or the
# target system (:target)
# @return [Array<Pathname>] list of the given paths prefixed by the
# destination directory in case of :local scope
def scoped_paths(paths, scope = :local)
return paths if scope == :target
prefix = Pathname.new(Yast::Installation.destdir)
paths.map { |d| prefix.join(d) }
# @return [Pathname] Path to Salt formulas
def default_formulas_set
@default_formula_set ||= FormulasSet.from_directory(work_dir.join("formulas"))
end

# Convenience method for converting from a list of directory names to a
Expand Down
9 changes: 8 additions & 1 deletion src/lib/y2configuration_management/configurators/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def services
#
# @see .mode
def prepare(opts = {})
::FileUtils.mkdir_p(config.work_dir) if mode?(:masterless)
::FileUtils.mkdir_p(target_path(config.work_dir)) if mode?(:masterless)
send("prepare_#{config.mode}", opts)
end

Expand Down Expand Up @@ -155,6 +155,13 @@ def fetch_keys(url, private_key_path, public_key_path)
return false if url.nil? # FIXME: should be move to the caller
KeyFinder.new(keys_url: url).fetch_to(private_key_path, public_key_path)
end

# Returns the path in the target system
#
# @return [Pathname]
def target_path(path)
Pathname.new(::File.join(Yast::Installation.destdir, path))
end
end
end
end
2 changes: 1 addition & 1 deletion src/lib/y2configuration_management/configurators/puppet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Puppet < Base
# :abort when configuration failed or was aborted.
mode(:masterless) do |_opts|
update_configuration
fetch_config(config.modules_url, config.work_dir) ? :finish : :abort
fetch_config(config.modules_url, target_path(config.work_dir)) ? :finish : :abort
end

# @return [Symbol] :finish when configuration was successful; :abort when configuration failed
Expand Down

0 comments on commit 827f51a

Please sign in to comment.