d-installer 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +29 -0
  3. data/Gemfile.lock +75 -0
  4. data/bin/d-installer +74 -0
  5. data/etc/d-installer.yaml +284 -0
  6. data/lib/dinstaller/can_ask_question.rb +48 -0
  7. data/lib/dinstaller/cmdline_args.rb +80 -0
  8. data/lib/dinstaller/cockpit_manager.rb +176 -0
  9. data/lib/dinstaller/config.rb +128 -0
  10. data/lib/dinstaller/config_reader.rb +164 -0
  11. data/lib/dinstaller/dbus/base_object.rb +58 -0
  12. data/lib/dinstaller/dbus/clients/base.rb +71 -0
  13. data/lib/dinstaller/dbus/clients/language.rb +86 -0
  14. data/lib/dinstaller/dbus/clients/manager.rb +76 -0
  15. data/lib/dinstaller/dbus/clients/software.rb +185 -0
  16. data/lib/dinstaller/dbus/clients/users.rb +112 -0
  17. data/lib/dinstaller/dbus/clients/with_progress.rb +56 -0
  18. data/lib/dinstaller/dbus/clients/with_service_status.rb +75 -0
  19. data/lib/dinstaller/dbus/clients.rb +34 -0
  20. data/lib/dinstaller/dbus/interfaces/progress.rb +113 -0
  21. data/lib/dinstaller/dbus/interfaces/service_status.rb +89 -0
  22. data/lib/dinstaller/dbus/language.rb +93 -0
  23. data/lib/dinstaller/dbus/language_service.rb +92 -0
  24. data/lib/dinstaller/dbus/manager.rb +147 -0
  25. data/lib/dinstaller/dbus/manager_service.rb +132 -0
  26. data/lib/dinstaller/dbus/question.rb +176 -0
  27. data/lib/dinstaller/dbus/questions.rb +124 -0
  28. data/lib/dinstaller/dbus/service_runner.rb +97 -0
  29. data/lib/dinstaller/dbus/service_status.rb +87 -0
  30. data/lib/dinstaller/dbus/software/manager.rb +131 -0
  31. data/lib/dinstaller/dbus/software/proposal.rb +82 -0
  32. data/lib/dinstaller/dbus/software.rb +31 -0
  33. data/lib/dinstaller/dbus/software_service.rb +86 -0
  34. data/lib/dinstaller/dbus/storage/proposal.rb +170 -0
  35. data/lib/dinstaller/dbus/storage.rb +30 -0
  36. data/lib/dinstaller/dbus/users.rb +132 -0
  37. data/lib/dinstaller/dbus/users_service.rb +92 -0
  38. data/lib/dinstaller/dbus/with_service_status.rb +48 -0
  39. data/lib/dinstaller/dbus/y2dir/manager/modules/Package.rb +51 -0
  40. data/lib/dinstaller/dbus/y2dir/manager/modules/PackagesProposal.rb +62 -0
  41. data/lib/dinstaller/dbus/y2dir/modules/Autologin.rb +214 -0
  42. data/lib/dinstaller/dbus/y2dir/software/modules/SpaceCalculation.rb +44 -0
  43. data/lib/dinstaller/dbus.rb +11 -0
  44. data/lib/dinstaller/errors.rb +28 -0
  45. data/lib/dinstaller/installation_phase.rb +106 -0
  46. data/lib/dinstaller/language.rb +73 -0
  47. data/lib/dinstaller/luks_activation_question.rb +92 -0
  48. data/lib/dinstaller/manager.rb +261 -0
  49. data/lib/dinstaller/network.rb +53 -0
  50. data/lib/dinstaller/package_callbacks.rb +69 -0
  51. data/lib/dinstaller/progress.rb +149 -0
  52. data/lib/dinstaller/question.rb +103 -0
  53. data/lib/dinstaller/questions_manager.rb +145 -0
  54. data/lib/dinstaller/security.rb +96 -0
  55. data/lib/dinstaller/service_status_recorder.rb +58 -0
  56. data/lib/dinstaller/software.rb +232 -0
  57. data/lib/dinstaller/storage/actions.rb +90 -0
  58. data/lib/dinstaller/storage/callbacks/activate.rb +93 -0
  59. data/lib/dinstaller/storage/callbacks/activate_luks.rb +93 -0
  60. data/lib/dinstaller/storage/callbacks/activate_multipath.rb +77 -0
  61. data/lib/dinstaller/storage/callbacks.rb +30 -0
  62. data/lib/dinstaller/storage/manager.rb +104 -0
  63. data/lib/dinstaller/storage/proposal.rb +197 -0
  64. data/lib/dinstaller/storage.rb +30 -0
  65. data/lib/dinstaller/users.rb +156 -0
  66. data/lib/dinstaller/with_progress.rb +63 -0
  67. data/lib/dinstaller.rb +5 -0
  68. data/share/dbus.conf +38 -0
  69. data/share/dbus.service +5 -0
  70. data/share/systemd.service +14 -0
  71. metadata +295 -0
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) [2022] SUSE LLC
4
+ #
5
+ # All Rights Reserved.
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify it
8
+ # under the terms of version 2 of the GNU General Public License as published
9
+ # by the Free Software Foundation.
10
+ #
11
+ # This program is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
+ # more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program; if not, contact SUSE LLC.
18
+ #
19
+ # To contact SUSE LLC about this file by physical or electronic mail, you may
20
+ # find current contact information at www.suse.com.
21
+
22
+ require "dbus"
23
+
24
+ module DInstaller
25
+ module DBus
26
+ module Interfaces
27
+ # Mixin to define the ServiceStatus D-Bus interface
28
+ #
29
+ # @note This mixin is expected to be included in a class inherited from {::DBus::Object} and
30
+ # it requires a #service_status method that returns a {DInstaller::DBus::ServiceStatus}
31
+ # object.
32
+ #
33
+ # @example
34
+ # class Demo < ::DBus::Object
35
+ # include DInstaller::DBus::Interfaces::ServiceStatus
36
+ #
37
+ # def initialize
38
+ # super("org.test.Demo")
39
+ # register_service_status_callbacks
40
+ # end
41
+ #
42
+ # def service_status
43
+ # @service_status ||= DInstaller::DBus::ServiceStatus.new
44
+ # end
45
+ module ServiceStatus
46
+ SERVICE_STATUS_INTERFACE = "org.opensuse.DInstaller.ServiceStatus1"
47
+
48
+ SERVICE_STATUS_IDLE = 0
49
+ SERVICE_STATUS_BUSY = 1
50
+
51
+ # Description of all possible service status values
52
+ #
53
+ # @return [Array<Hash>]
54
+ def service_status_all
55
+ [
56
+ { "id" => SERVICE_STATUS_IDLE, "label" => "idle" },
57
+ { "id" => SERVICE_STATUS_BUSY, "label" => "busy" }
58
+ ]
59
+ end
60
+
61
+ # Current value of the service status
62
+ #
63
+ # @return [Integer]
64
+ def service_status_current
65
+ service_status.busy? ? SERVICE_STATUS_BUSY : SERVICE_STATUS_IDLE
66
+ end
67
+
68
+ # Registers callbacks to be called when the value of the service status changes
69
+ #
70
+ # @note This method is expected to be called in the constructor.
71
+ def register_service_status_callbacks
72
+ service_status.on_change do
73
+ dbus_properties_changed(SERVICE_STATUS_INTERFACE,
74
+ { "Current" => service_status_current }, [])
75
+ end
76
+ end
77
+
78
+ def self.included(base)
79
+ base.class_eval do
80
+ dbus_interface SERVICE_STATUS_INTERFACE do
81
+ dbus_reader :service_status_all, "aa{sv}", dbus_name: "All"
82
+ dbus_reader :service_status_current, "u", dbus_name: "Current"
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) [2022] SUSE LLC
4
+ #
5
+ # All Rights Reserved.
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify it
8
+ # under the terms of version 2 of the GNU General Public License as published
9
+ # by the Free Software Foundation.
10
+ #
11
+ # This program is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
+ # more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program; if not, contact SUSE LLC.
18
+ #
19
+ # To contact SUSE LLC about this file by physical or electronic mail, you may
20
+ # find current contact information at www.suse.com.
21
+
22
+ require "dbus"
23
+ require "dinstaller/language"
24
+ require "dinstaller/errors"
25
+
26
+ module DInstaller
27
+ module DBus
28
+ # YaST D-Bus object (/org/opensuse/DInstaller/Language1)
29
+ #
30
+ # @see https://rubygems.org/gems/ruby-dbus
31
+ class Language < ::DBus::Object
32
+ PATH = "/org/opensuse/DInstaller/Language1"
33
+ private_constant :PATH
34
+
35
+ LANGUAGE_INTERFACE = "org.opensuse.DInstaller.Language1"
36
+ private_constant :LANGUAGE_INTERFACE
37
+
38
+ # @param backend [DInstaller::Language]
39
+ # @param logger [Logger]
40
+ def initialize(backend, logger)
41
+ @backend = backend
42
+ @logger = logger
43
+
44
+ super(PATH)
45
+ end
46
+
47
+ dbus_interface LANGUAGE_INTERFACE do
48
+ attr_accessor :available_languages
49
+
50
+ dbus_reader :available_languages, "a(ssa{sv})"
51
+
52
+ dbus_reader :marked_for_install, "as"
53
+
54
+ dbus_method :ToInstall, "in LangIDs:as" do |lang_ids|
55
+ logger.info "ToInstall #{lang_ids.inspect}"
56
+ result = select_to_install(lang_ids)
57
+
58
+ dbus_properties_changed(LANGUAGE_INTERFACE, { "MarkedForInstall" => lang_ids }, [])
59
+ result ? 0 : 1
60
+ end
61
+
62
+ dbus_method(:Finish) { finish }
63
+ end
64
+
65
+ def available_languages
66
+ @available_languages ||= backend.languages.map { |k, v| [k, v.first, {}] }
67
+ end
68
+
69
+ def marked_for_install
70
+ # TODO: change when installer support multiple target languages
71
+ result = [backend.language]
72
+ logger.info "MarkedForInstall #{result}"
73
+ result
74
+ end
75
+
76
+ def select_to_install(lang_ids)
77
+ backend.language = lang_ids.first
78
+ true
79
+ rescue Errors::InvalidValue
80
+ false
81
+ end
82
+
83
+ def finish
84
+ backend.finish
85
+ end
86
+
87
+ private
88
+
89
+ attr_reader :logger
90
+ attr_reader :backend
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) [2022] SUSE LLC
4
+ #
5
+ # All Rights Reserved.
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify it
8
+ # under the terms of version 2 of the GNU General Public License as published
9
+ # by the Free Software Foundation.
10
+ #
11
+ # This program is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
+ # more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program; if not, contact SUSE LLC.
18
+ #
19
+ # To contact SUSE LLC about this file by physical or electronic mail, you may
20
+ # find current contact information at www.suse.com.
21
+
22
+ require "dbus"
23
+ require "dinstaller/dbus/language"
24
+ require "dinstaller/language"
25
+
26
+ module DInstaller
27
+ module DBus
28
+ # D-Bus service (org.opensuse.DInstaller.Language)
29
+ #
30
+ # It connects to the system D-Bus and answers requests on objects below
31
+ # `/org/opensuse/DInstaller/Language1`.
32
+ class LanguageService
33
+ # Service name
34
+ #
35
+ # @return [String]
36
+ SERVICE_NAME = "org.opensuse.DInstaller.Language"
37
+ private_constant :SERVICE_NAME
38
+
39
+ # System D-Bus
40
+ #
41
+ # @return [::DBus::Connection]
42
+ attr_reader :bus
43
+
44
+ # @param config [Config] Configuration object
45
+ # @param logger [Logger]
46
+ def initialize(_config, logger = nil)
47
+ @logger = logger || Logger.new($stdout)
48
+ @bus = ::DBus::SystemBus.instance
49
+ end
50
+
51
+ # Exports the installer object through the D-Bus service
52
+ def export
53
+ dbus_objects.each { |o| service.export(o) }
54
+
55
+ paths = dbus_objects.map(&:path).join(", ")
56
+ logger.info "Exported #{paths} objects"
57
+ end
58
+
59
+ # Call this from some main loop to dispatch the D-Bus messages
60
+ def dispatch
61
+ bus.dispatch_message_queue
62
+ end
63
+
64
+ private
65
+
66
+ # @return [Logger]
67
+ attr_reader :logger
68
+
69
+ # @return [::DBus::Service]
70
+ def service
71
+ @service ||= bus.request_service(SERVICE_NAME)
72
+ end
73
+
74
+ # @return [Array<::DBus::Object>]
75
+ def dbus_objects
76
+ @dbus_objects ||= [
77
+ language_dbus
78
+ ]
79
+ end
80
+
81
+ # @return [DInstaller::DBus::Language]
82
+ def language_dbus
83
+ @language_dbus ||= DInstaller::DBus::Language.new(language_backend(logger), logger)
84
+ end
85
+
86
+ # @return [DInstaller::Language]
87
+ def language_backend(logger)
88
+ @language_backend ||= DInstaller::Language.new(logger).tap(&:probe)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) [2021] SUSE LLC
4
+ #
5
+ # All Rights Reserved.
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify it
8
+ # under the terms of version 2 of the GNU General Public License as published
9
+ # by the Free Software Foundation.
10
+ #
11
+ # This program is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
+ # more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program; if not, contact SUSE LLC.
18
+ #
19
+ # To contact SUSE LLC about this file by physical or electronic mail, you may
20
+ # find current contact information at www.suse.com.
21
+
22
+ require "dbus"
23
+ require "dinstaller/manager"
24
+ require "dinstaller/dbus/base_object"
25
+ require "dinstaller/dbus/with_service_status"
26
+ require "dinstaller/dbus/interfaces/progress"
27
+ require "dinstaller/dbus/interfaces/service_status"
28
+
29
+ module DInstaller
30
+ module DBus
31
+ # D-Bus object to manage the installation process
32
+ class Manager < BaseObject
33
+ include WithServiceStatus
34
+ include Interfaces::Progress
35
+ include Interfaces::ServiceStatus
36
+
37
+ PATH = "/org/opensuse/DInstaller/Manager1"
38
+ private_constant :PATH
39
+
40
+ # Constructor
41
+ #
42
+ # @param backend [DInstaller::Manager]
43
+ # @param logger [Logger]
44
+ def initialize(backend, logger)
45
+ super(PATH, logger: logger)
46
+ @backend = backend
47
+ register_callbacks
48
+ register_progress_callbacks
49
+ register_service_status_callbacks
50
+ end
51
+
52
+ MANAGER_INTERFACE = "org.opensuse.DInstaller.Manager1"
53
+ private_constant :MANAGER_INTERFACE
54
+
55
+ STARTUP_PHASE = 0
56
+ CONFIG_PHASE = 1
57
+ INSTALL_PHASE = 2
58
+
59
+ dbus_interface MANAGER_INTERFACE do
60
+ dbus_method(:Probe, "") { config_phase }
61
+ dbus_method(:Commit, "") { install_phase }
62
+ dbus_reader :installation_phases, "aa{sv}"
63
+ dbus_reader :current_installation_phase, "u"
64
+ dbus_reader :busy_services, "as"
65
+ end
66
+
67
+ # Runs the config phase
68
+ def config_phase
69
+ safe_run do
70
+ busy_while { backend.config_phase }
71
+ end
72
+ end
73
+
74
+ # Runs the install phase
75
+ def install_phase
76
+ safe_run do
77
+ busy_while { backend.install_phase }
78
+ end
79
+ end
80
+
81
+ # Description of all possible installation phase values
82
+ #
83
+ # @return [Array<Hash>]
84
+ def installation_phases
85
+ [
86
+ { "id" => STARTUP_PHASE, "label" => "startup" },
87
+ { "id" => CONFIG_PHASE, "label" => "config" },
88
+ { "id" => INSTALL_PHASE, "label" => "install" }
89
+ ]
90
+ end
91
+
92
+ # Current value of the installation phase
93
+ #
94
+ # @return [Integer]
95
+ def current_installation_phase
96
+ return STARTUP_PHASE if backend.installation_phase.startup?
97
+ return CONFIG_PHASE if backend.installation_phase.config?
98
+ return INSTALL_PHASE if backend.installation_phase.install?
99
+ end
100
+
101
+ # Name of the services that are currently busy
102
+ #
103
+ # @return [Array<String>]
104
+ def busy_services
105
+ backend.busy_services
106
+ end
107
+
108
+ private
109
+
110
+ # @return [DInstaller::Manager]
111
+ attr_reader :backend
112
+
113
+ # Executes the given block only if the service is idle
114
+ #
115
+ # @note The service still dispatches messages while waiting for a D-Bus answer.
116
+ #
117
+ # @param block [Proc]
118
+ def safe_run(&block)
119
+ raise busy_error if service_status.busy?
120
+
121
+ block.call
122
+ end
123
+
124
+ def busy_error
125
+ ::DBus.error("org.opensuse.DInstaller.Error.Busy")
126
+ end
127
+
128
+ # Registers callback to be called
129
+ def register_callbacks
130
+ backend.installation_phase.on_change do
131
+ dbus_properties_changed(MANAGER_INTERFACE,
132
+ { "CurrentInstallationPhase" => current_installation_phase }, [])
133
+ end
134
+
135
+ backend.on_services_status_change do
136
+ dbus_properties_changed(MANAGER_INTERFACE, { "BusyServices" => busy_services }, [])
137
+ end
138
+
139
+ backend.software.on_product_selected do |product|
140
+ safe_run do
141
+ busy_while { backend.select_product(product) }
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) [2022] SUSE LLC
4
+ #
5
+ # All Rights Reserved.
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify it
8
+ # under the terms of version 2 of the GNU General Public License as published
9
+ # by the Free Software Foundation.
10
+ #
11
+ # This program is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
+ # more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program; if not, contact SUSE LLC.
18
+ #
19
+ # To contact SUSE LLC about this file by physical or electronic mail, you may
20
+ # find current contact information at www.suse.com.
21
+
22
+ require "dbus"
23
+ require "dinstaller/manager"
24
+ require "dinstaller/cockpit_manager"
25
+ require "dinstaller/dbus/manager"
26
+ require "dinstaller/dbus/language"
27
+ require "dinstaller/dbus/storage/proposal"
28
+ require "dinstaller/dbus/questions"
29
+
30
+ module DInstaller
31
+ module DBus
32
+ # D-Bus service (org.opensuse.DInstaller)
33
+ #
34
+ # It connects to the system D-Bus and answers requests on objects below
35
+ # `/org/opensuse/DInstaller`.
36
+ class ManagerService
37
+ # Service name
38
+ #
39
+ # @return [String]
40
+ SERVICE_NAME = "org.opensuse.DInstaller"
41
+ private_constant :SERVICE_NAME
42
+
43
+ # System D-Bus
44
+ #
45
+ # @return [::DBus::Connection]
46
+ attr_reader :bus
47
+
48
+ # Installation manager
49
+ #
50
+ # @return [DInstaller::Manager]
51
+ attr_reader :manager
52
+
53
+ # @param config [Config] Configuration
54
+ # @param logger [Logger]
55
+ def initialize(config, logger = nil)
56
+ @config = config
57
+ @manager = DInstaller::Manager.new(config, logger)
58
+ @logger = logger || Logger.new($stdout)
59
+ @bus = ::DBus::SystemBus.instance
60
+ end
61
+
62
+ # Initializes and exports the D-Bus API
63
+ #
64
+ # @note The service runs its startup phase
65
+ def start
66
+ setup_cockpit
67
+ export
68
+ manager.on_progress_change { dispatch } # make single thread more responsive
69
+ manager.startup_phase
70
+ end
71
+
72
+ # Exports the installer object through the D-Bus service
73
+ def export
74
+ dbus_objects.each { |o| service.export(o) }
75
+
76
+ paths = dbus_objects.map(&:path).join(", ")
77
+ logger.info "Exported #{paths} objects"
78
+ end
79
+
80
+ # Call this from some main loop to dispatch the D-Bus messages
81
+ def dispatch
82
+ bus.dispatch_message_queue
83
+ end
84
+
85
+ private
86
+
87
+ # @return [Logger]
88
+ attr_reader :logger
89
+
90
+ # @return [Config]
91
+ attr_reader :config
92
+
93
+ def setup_cockpit
94
+ cockpit = CockpitManager.new(logger)
95
+ cockpit.setup(config.data["web"])
96
+ end
97
+
98
+ # @return [::DBus::Service]
99
+ def service
100
+ @service ||= bus.request_service(SERVICE_NAME)
101
+ end
102
+
103
+ # @return [Array<::DBus::Object>]
104
+ def dbus_objects
105
+ @dbus_objects ||= [
106
+ manager_dbus,
107
+ language_dbus,
108
+ storage_proposal_dbus,
109
+ questions_dbus
110
+ ]
111
+ end
112
+
113
+ def manager_dbus
114
+ @manager_dbus ||= DInstaller::DBus::Manager.new(manager, logger)
115
+ end
116
+
117
+ def language_dbus
118
+ @language_dbus ||= DInstaller::DBus::Language.new(manager.language, logger)
119
+ end
120
+
121
+ def storage_proposal_dbus
122
+ @storage_proposal_dbus ||= DInstaller::DBus::Storage::Proposal.new(
123
+ manager.storage.proposal, logger
124
+ )
125
+ end
126
+
127
+ def questions_dbus
128
+ @questions_dbus ||= DInstaller::DBus::Questions.new(manager.questions_manager, logger)
129
+ end
130
+ end
131
+ end
132
+ end