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,176 @@
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/question"
24
+ require "dinstaller/luks_activation_question"
25
+ require "dinstaller/dbus/base_object"
26
+
27
+ module DInstaller
28
+ module DBus
29
+ # Class to represent a question on D-Bus
30
+ #
31
+ # Questions are dynamically exported on D-Bus. All questions are exported as children of
32
+ # {DBus::Questions} object.
33
+ #
34
+ # Clients should provide an answer for each question.
35
+ class Question < BaseObject
36
+ # This module contains the D-Bus interfaces that question D-Bus object can implement. The
37
+ # interfaces that a question implements are dynamically determined while creating a new
38
+ # D-Bus question.
39
+ module Interfaces
40
+ # Generic interface for a question
41
+ module Question
42
+ QUESTION_INTERFACE = "org.opensuse.DInstaller.Question1"
43
+ private_constant :QUESTION_INTERFACE
44
+
45
+ # @!method backend
46
+ # @note Classes including this mixin must define a #backend method
47
+ # @return [DInstaller::Question]
48
+
49
+ # Unique id of the question
50
+ #
51
+ # @return [Integer]
52
+ def id
53
+ backend.id
54
+ end
55
+
56
+ # Text of the question
57
+ #
58
+ # @return [String]
59
+ def text
60
+ backend.text
61
+ end
62
+
63
+ # Options the question admits as answer
64
+ #
65
+ # @note Clients are responsible of generating the proper label for each option.
66
+ #
67
+ # @return [Array<String>]
68
+ def options
69
+ backend.options.map(&:to_s)
70
+ end
71
+
72
+ # Default option a client should offer as answer
73
+ #
74
+ # @return [String]
75
+ def default_option
76
+ backend.default_option.to_s
77
+ end
78
+
79
+ # Answer selected for a client
80
+ #
81
+ # @return [String]
82
+ def answer
83
+ backend.answer.to_s
84
+ end
85
+
86
+ # Selects an option as answer
87
+ #
88
+ # @param option [String]
89
+ def answer=(option)
90
+ backend.answer = option.to_sym
91
+ end
92
+
93
+ def self.included(base)
94
+ base.class_eval do
95
+ dbus_interface QUESTION_INTERFACE do
96
+ dbus_reader :id, "u"
97
+ dbus_reader :text, "s"
98
+ dbus_reader :options, "as"
99
+ dbus_reader :default_option, "s"
100
+ dbus_accessor :answer, "s"
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ # Interface to provide information when activating a LUKS device
107
+ module LuksActivation
108
+ LUKS_ACTIVATION_INTERFACE = "org.opensuse.DInstaller.Question.LuksActivation1"
109
+ private_constant :LUKS_ACTIVATION_INTERFACE
110
+
111
+ # @!method backend
112
+ # @note Classes including this mixin must define a #backend method
113
+ # @return [DInstaller::Question]
114
+
115
+ # Given password
116
+ #
117
+ # @return [String]
118
+ def luks_password
119
+ backend.password || ""
120
+ end
121
+
122
+ # Sets a password
123
+ #
124
+ # @param value [String]
125
+ def luks_password=(value)
126
+ backend.password = value
127
+ end
128
+
129
+ # Current attempt for activating the device
130
+ #
131
+ # @return [Integer]
132
+ def activation_attempt
133
+ backend.attempt
134
+ end
135
+
136
+ def self.included(base)
137
+ base.class_eval do
138
+ dbus_interface LUKS_ACTIVATION_INTERFACE do
139
+ dbus_accessor :luks_password, "s", dbus_name: "Password"
140
+ dbus_reader :activation_attempt, "u", dbus_name: "Attempt"
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ # Defines the interfaces to implement according to the backend type
148
+ INTERFACES_TO_INCLUDE = {
149
+ DInstaller::Question => [Interfaces::Question],
150
+ DInstaller::LuksActivationQuestion => [Interfaces::Question, Interfaces::LuksActivation]
151
+ }.freeze
152
+ private_constant :INTERFACES_TO_INCLUDE
153
+
154
+ # Constructor
155
+ #
156
+ # @param path [::DBus::ObjectPath]
157
+ # @param backend [DInstaller::Question]
158
+ # @param logger [Logger]
159
+ def initialize(path, backend, logger)
160
+ super(path, logger: logger)
161
+ @backend = backend
162
+ add_interfaces
163
+ end
164
+
165
+ private
166
+
167
+ # @return [DInstaller::Question]
168
+ attr_reader :backend
169
+
170
+ # Adds interfaces to the question
171
+ def add_interfaces
172
+ INTERFACES_TO_INCLUDE[backend.class].each { |i| singleton_class.include(i) }
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,124 @@
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 "pathname"
24
+ require "dinstaller/dbus/question"
25
+
26
+ module DInstaller
27
+ module DBus
28
+ # This class represents a D-Bus object implementing ObjectManager interface for questions
29
+ #
30
+ # {DBus::Questions} uses a {QuestionsManager} as backend and exports a {DBus::Question} object
31
+ # when a {DInstaller::Question} is added to the questions manager. A {DBus::Question} is
32
+ # unexported when a {DInstaller::Question} is deleted from the questions manager.
33
+ #
34
+ # Callbacks of {QuestionsManager} are used to ensure that the proper D-Bus actions are performed
35
+ # when adding, deleting or waiting for answers.
36
+ class Questions < ::DBus::Object
37
+ PATH = "/org/opensuse/DInstaller/Questions1"
38
+ private_constant :PATH
39
+
40
+ OBJECT_MANAGER_INTERFACE = "org.freedesktop.DBus.ObjectManager"
41
+ private_constant :OBJECT_MANAGER_INTERFACE
42
+
43
+ # Constructor
44
+ #
45
+ # The callbacks of the backend are configured to perform the proper D-Bus actions, see
46
+ # {#register_callbacks}.
47
+ #
48
+ # @param backend [DInstaller::QuestionsManager]
49
+ # @param logger [Logger]
50
+ def initialize(backend, logger)
51
+ @backend = backend
52
+ @logger = logger
53
+ @exported_questions = []
54
+
55
+ register_callbacks
56
+
57
+ super(PATH)
58
+ end
59
+
60
+ # Information provided by ObjectManger for each exported object
61
+ #
62
+ # Returns a hash containing paths of exported objects as keys. Each value is the information
63
+ # of interfaces and properties for that object, see {BaseObject#interfaces_and_properties}.
64
+ #
65
+ # @return [Hash]
66
+ def managed_objects
67
+ exported_questions.each_with_object({}) { |q, h| h[q.path] = q.interfaces_and_properties }
68
+ end
69
+
70
+ dbus_interface OBJECT_MANAGER_INTERFACE do
71
+ dbus_method(:GetManagedObjects, "out res:a{oa{sa{sv}}}") { [managed_objects] }
72
+ dbus_signal(:InterfacesAdded, "object:o, interfaces_and_properties:a{sa{sv}}")
73
+ dbus_signal(:InterfacesRemoved, "object:o, interfaces:as")
74
+ end
75
+
76
+ private
77
+
78
+ # @return [DInstaller::QuestionsManager]
79
+ attr_reader :backend
80
+
81
+ # @return [Logger]
82
+ attr_reader :logger
83
+
84
+ # Currently exported questions
85
+ #
86
+ # @return [Array<DBus::Question>]
87
+ attr_reader :exported_questions
88
+
89
+ # Builds the question path (e.g., org.opensuse.DInstaller/Questions1/1)
90
+ #
91
+ # @param question [DInstaller::Question]
92
+ # @return [::DBus::ObjectPath]
93
+ def path_for(question)
94
+ path = Pathname.new(PATH).join(question.id.to_s)
95
+
96
+ ::DBus::ObjectPath.new(path.to_s)
97
+ end
98
+
99
+ # Callbacks with actions to do when adding, deleting or waiting for questions
100
+ def register_callbacks
101
+ # When adding a question, a new question is exported on D-Bus.
102
+ backend.on_add do |question|
103
+ dbus_object = DBus::Question.new(path_for(question), question, logger)
104
+ @service.export(dbus_object)
105
+ exported_questions << dbus_object
106
+ InterfacesAdded(dbus_object.path, dbus_object.interfaces_and_properties)
107
+ end
108
+
109
+ # When removing a question, the question is unexported from D-Bus.
110
+ backend.on_delete do |question|
111
+ dbus_object = exported_questions.find { |q| q.id == question.id }
112
+ if dbus_object
113
+ @service.unexport(dbus_object)
114
+ exported_questions.delete(dbus_object)
115
+ InterfacesRemoved(dbus_object.path, dbus_object.intfs.keys)
116
+ end
117
+ end
118
+
119
+ # Bus dispatches messages while waiting for questions to be answered
120
+ backend.on_wait { @service.bus.dispatch_message_queue }
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,97 @@
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 "eventmachine"
23
+ require "logger"
24
+
25
+ module DInstaller
26
+ module DBus
27
+ # Set up and run a given D-Bus service
28
+ #
29
+ # @example Run the manager service
30
+ # runner = ServiceRunner.new(:manager)
31
+ # runner.run
32
+ #
33
+ # @example Run the users service
34
+ # runner = ServiceRunner.new(:users)
35
+ # runner.run
36
+ class ServiceRunner
37
+ # @param name [Symbol,String] Service name (:manager, :users, etc.)
38
+ # @param logger [Logger] Service logger
39
+ def initialize(name, logger: Logger.new($stdout))
40
+ @name = name || :manager
41
+ @logger = logger
42
+ end
43
+
44
+ # Run the Service
45
+ #
46
+ # This method listens for D-Bus calls.
47
+ def run
48
+ initialize_yast
49
+ service = build_service(name, logger)
50
+ # TODO: implement a #start method in all services,
51
+ # which is equivalent to #export in most cases.
52
+ service.respond_to?(:start) ? service.start : service.export
53
+ EventMachine.run do
54
+ EventMachine::PeriodicTimer.new(0.1) { service.dispatch }
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ attr_reader :name, :logger
61
+
62
+ # Configuration
63
+ def config
64
+ # TODO: do not require "yast" until it is needed
65
+ require "dinstaller/config"
66
+ Config.load(logger) unless Config.current
67
+ Config.current
68
+ end
69
+
70
+ # Set up a service
71
+ #
72
+ # @param name [Symbol] Service name (ie, :users)
73
+ # @param logger [Logger] Service logger
74
+ # @return [#export,#dispatch] Class that implements #export and #dispatch methods.
75
+ def build_service(name, logger)
76
+ require "dinstaller/dbus/#{name}_service"
77
+ klass = DInstaller::DBus.const_get("#{name.capitalize}Service")
78
+ klass.new(config, logger)
79
+ rescue LoadError, NameError
80
+ raise "Service '#{name}' not found"
81
+ end
82
+
83
+ # Initializes YaST
84
+ def initialize_yast
85
+ require "yast"
86
+ Yast.import "Mode"
87
+ Yast.import "Stage"
88
+
89
+ Yast::Mode.SetUI("commandline")
90
+ Yast::Mode.SetMode("installation")
91
+ # Set stage to initial, so it will act as installer for some cases like
92
+ # proposing installer instead of reading current one
93
+ Yast::Stage.Set("initial")
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,87 @@
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
+ module DInstaller
23
+ module DBus
24
+ # Represents the status of a D-Installer service and allows to configure callbacks to be called
25
+ # when the status value changes
26
+ class ServiceStatus
27
+ # Possible values of the service status
28
+ IDLE = "idle"
29
+ BUSY = "busy"
30
+
31
+ # Constructor
32
+ #
33
+ # The service status is initialized as idle.
34
+ def initialize
35
+ @value = IDLE
36
+ @on_change_callbacks = []
37
+ end
38
+
39
+ # Whether the current service status value is busy
40
+ #
41
+ # @return [Boolean]
42
+ def busy?
43
+ value == BUSY
44
+ end
45
+
46
+ # Changes the service status value to idle
47
+ #
48
+ # @note Callbacks are called.
49
+ #
50
+ # @return [self]
51
+ def idle
52
+ change_to(IDLE)
53
+ self
54
+ end
55
+
56
+ # Changes the service status value to busy
57
+ #
58
+ # @note Callbacks are called.
59
+ #
60
+ # @return [self]
61
+ def busy
62
+ change_to(BUSY)
63
+ self
64
+ end
65
+
66
+ # Registers a callback to be called when the service status changes
67
+ #
68
+ # @param block [Proc]
69
+ def on_change(&block)
70
+ @on_change_callbacks << block
71
+ end
72
+
73
+ private
74
+
75
+ # @return [IDLE, BUSY]
76
+ attr_reader :value
77
+
78
+ # Changes the current service status value and runs the callbacks
79
+ #
80
+ # @param value [IDLE, BUSY]
81
+ def change_to(value)
82
+ @value = value
83
+ @on_change_callbacks.each(&:call)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,131 @@
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/base_object"
24
+ require "dinstaller/dbus/with_service_status"
25
+ require "dinstaller/dbus/clients/language"
26
+ require "dinstaller/dbus/interfaces/progress"
27
+ require "dinstaller/dbus/interfaces/service_status"
28
+
29
+ module DInstaller
30
+ module DBus
31
+ module Software
32
+ # D-Bus object to manage software installation
33
+ class Manager < BaseObject
34
+ include WithServiceStatus
35
+ include Interfaces::Progress
36
+ include Interfaces::ServiceStatus
37
+
38
+ PATH = "/org/opensuse/DInstaller/Software1"
39
+ private_constant :PATH
40
+
41
+ # Constructor
42
+ #
43
+ # @param backend [DInstaller::Software]
44
+ # @param logger [Logger]
45
+ def initialize(backend, logger)
46
+ super(PATH, logger: logger)
47
+ @backend = backend
48
+ register_callbacks
49
+ register_progress_callbacks
50
+ register_service_status_callbacks
51
+ end
52
+
53
+ SOFTWARE_INTERFACE = "org.opensuse.DInstaller.Software1"
54
+ private_constant :SOFTWARE_INTERFACE
55
+
56
+ dbus_interface SOFTWARE_INTERFACE do
57
+ dbus_reader :available_base_products, "a(ssa{sv})"
58
+
59
+ dbus_reader :selected_base_product, "s"
60
+
61
+ dbus_method :SelectProduct, "in ProductID:s" do |product_id|
62
+ logger.info "SelectProduct #{product_id}"
63
+
64
+ select_product(product_id)
65
+ dbus_properties_changed(SOFTWARE_INTERFACE, { "SelectedBaseProduct" => product_id }, [])
66
+ end
67
+
68
+ # TODO: just for performance comparison (see `perf.rb`)
69
+ dbus_method :ProvisionSelected, "in Provision:s, out Result:b" do |provision|
70
+ backend.provision_selected?(provision)
71
+ end
72
+
73
+ dbus_method :ProvisionsSelected, "in Provisions:as, out Result:ab" do |provisions|
74
+ [provisions.map { |p| backend.provision_selected?(p) }]
75
+ end
76
+
77
+ dbus_method(:Probe) { probe }
78
+ dbus_method(:Propose) { propose }
79
+ dbus_method(:Install) { install }
80
+ dbus_method(:Finish) { finish }
81
+ end
82
+
83
+ def available_base_products
84
+ backend.products.map do |id, data|
85
+ [id, data["name"], { "description" => data["description"] }].freeze
86
+ end
87
+ end
88
+
89
+ # Returns the selected base product
90
+ #
91
+ # @return [String] Product ID or an empty string if no product is selected
92
+ def selected_base_product
93
+ backend.product || ""
94
+ end
95
+
96
+ def select_product(product_id)
97
+ backend.select_product(product_id)
98
+ end
99
+
100
+ def probe
101
+ busy_while { backend.probe }
102
+ end
103
+
104
+ def propose
105
+ busy_while { backend.propose }
106
+ end
107
+
108
+ def install
109
+ busy_while { backend.install }
110
+ end
111
+
112
+ def finish
113
+ busy_while { backend.finish }
114
+ end
115
+
116
+ private
117
+
118
+ # @return [DInstaller::Software]
119
+ attr_reader :backend
120
+
121
+ # Registers callback to be called
122
+ def register_callbacks
123
+ client = DInstaller::DBus::Clients::Language.new
124
+ client.on_language_selected do |language_ids|
125
+ backend.languages = language_ids
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,82 @@
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 "yast"
23
+ require "dbus"
24
+ Yast.import "PackagesProposal"
25
+
26
+ module DInstaller
27
+ module DBus
28
+ module Software
29
+ # Software proposal D-Bus representation
30
+ #
31
+ # This class allows to change software proposal settings through D-Bus.
32
+ #
33
+ # @see Yast::PackagesProposal
34
+ class Proposal < ::DBus::Object
35
+ PATH = "/org/opensuse/DInstaller/Software/Proposal1"
36
+ private_constant :PATH
37
+
38
+ INTERFACE = "org.opensuse.DInstaller.Software.Proposal1"
39
+ private_constant :INTERFACE
40
+
41
+ TYPES = [:package, :pattern].freeze
42
+ private_constant :TYPES
43
+
44
+ # Constructor
45
+ #
46
+ # @param logger [Logger]
47
+ def initialize(logger)
48
+ @logger = logger
49
+
50
+ super(PATH)
51
+ end
52
+
53
+ dbus_interface INTERFACE do
54
+ dbus_method :AddResolvables,
55
+ "in Id:s, in Type:y, in Resolvables:as, in Optional:b" do |id, type, resolvables, opt|
56
+ Yast::PackagesProposal.AddResolvables(id, TYPES[type], resolvables, optional: opt)
57
+ end
58
+
59
+ dbus_method :GetResolvables,
60
+ "in Id:s, in Type:y, in Optional:b, out Resolvables:as" do |id, type, opt|
61
+ [Yast::PackagesProposal.GetResolvables(id, TYPES[type], optional: opt)]
62
+ end
63
+
64
+ dbus_method :SetResolvables,
65
+ "in Id:s, in Type:y, in Resolvables:as, in Optional:b" do |id, type, resolvables, opt|
66
+ Yast::PackagesProposal.SetResolvables(id, TYPES[type], resolvables, optional: opt)
67
+ end
68
+
69
+ dbus_method :RemoveResolvables,
70
+ "in Id:s, in Type:y, in Resolvables:as, in Optional:b" do |id, type, resolvables, opt|
71
+ Yast::PackagesProposal.RemoveResolvables(id, TYPES[type], resolvables, optional: opt)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ # @return [Logger]
78
+ attr_reader :logger
79
+ end
80
+ end
81
+ end
82
+ end