d-installer 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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