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.
- checksums.yaml +7 -0
- data/Gemfile +29 -0
- data/Gemfile.lock +75 -0
- data/bin/d-installer +74 -0
- data/etc/d-installer.yaml +284 -0
- data/lib/dinstaller/can_ask_question.rb +48 -0
- data/lib/dinstaller/cmdline_args.rb +80 -0
- data/lib/dinstaller/cockpit_manager.rb +176 -0
- data/lib/dinstaller/config.rb +128 -0
- data/lib/dinstaller/config_reader.rb +164 -0
- data/lib/dinstaller/dbus/base_object.rb +58 -0
- data/lib/dinstaller/dbus/clients/base.rb +71 -0
- data/lib/dinstaller/dbus/clients/language.rb +86 -0
- data/lib/dinstaller/dbus/clients/manager.rb +76 -0
- data/lib/dinstaller/dbus/clients/software.rb +185 -0
- data/lib/dinstaller/dbus/clients/users.rb +112 -0
- data/lib/dinstaller/dbus/clients/with_progress.rb +56 -0
- data/lib/dinstaller/dbus/clients/with_service_status.rb +75 -0
- data/lib/dinstaller/dbus/clients.rb +34 -0
- data/lib/dinstaller/dbus/interfaces/progress.rb +113 -0
- data/lib/dinstaller/dbus/interfaces/service_status.rb +89 -0
- data/lib/dinstaller/dbus/language.rb +93 -0
- data/lib/dinstaller/dbus/language_service.rb +92 -0
- data/lib/dinstaller/dbus/manager.rb +147 -0
- data/lib/dinstaller/dbus/manager_service.rb +132 -0
- data/lib/dinstaller/dbus/question.rb +176 -0
- data/lib/dinstaller/dbus/questions.rb +124 -0
- data/lib/dinstaller/dbus/service_runner.rb +97 -0
- data/lib/dinstaller/dbus/service_status.rb +87 -0
- data/lib/dinstaller/dbus/software/manager.rb +131 -0
- data/lib/dinstaller/dbus/software/proposal.rb +82 -0
- data/lib/dinstaller/dbus/software.rb +31 -0
- data/lib/dinstaller/dbus/software_service.rb +86 -0
- data/lib/dinstaller/dbus/storage/proposal.rb +170 -0
- data/lib/dinstaller/dbus/storage.rb +30 -0
- data/lib/dinstaller/dbus/users.rb +132 -0
- data/lib/dinstaller/dbus/users_service.rb +92 -0
- data/lib/dinstaller/dbus/with_service_status.rb +48 -0
- data/lib/dinstaller/dbus/y2dir/manager/modules/Package.rb +51 -0
- data/lib/dinstaller/dbus/y2dir/manager/modules/PackagesProposal.rb +62 -0
- data/lib/dinstaller/dbus/y2dir/modules/Autologin.rb +214 -0
- data/lib/dinstaller/dbus/y2dir/software/modules/SpaceCalculation.rb +44 -0
- data/lib/dinstaller/dbus.rb +11 -0
- data/lib/dinstaller/errors.rb +28 -0
- data/lib/dinstaller/installation_phase.rb +106 -0
- data/lib/dinstaller/language.rb +73 -0
- data/lib/dinstaller/luks_activation_question.rb +92 -0
- data/lib/dinstaller/manager.rb +261 -0
- data/lib/dinstaller/network.rb +53 -0
- data/lib/dinstaller/package_callbacks.rb +69 -0
- data/lib/dinstaller/progress.rb +149 -0
- data/lib/dinstaller/question.rb +103 -0
- data/lib/dinstaller/questions_manager.rb +145 -0
- data/lib/dinstaller/security.rb +96 -0
- data/lib/dinstaller/service_status_recorder.rb +58 -0
- data/lib/dinstaller/software.rb +232 -0
- data/lib/dinstaller/storage/actions.rb +90 -0
- data/lib/dinstaller/storage/callbacks/activate.rb +93 -0
- data/lib/dinstaller/storage/callbacks/activate_luks.rb +93 -0
- data/lib/dinstaller/storage/callbacks/activate_multipath.rb +77 -0
- data/lib/dinstaller/storage/callbacks.rb +30 -0
- data/lib/dinstaller/storage/manager.rb +104 -0
- data/lib/dinstaller/storage/proposal.rb +197 -0
- data/lib/dinstaller/storage.rb +30 -0
- data/lib/dinstaller/users.rb +156 -0
- data/lib/dinstaller/with_progress.rb +63 -0
- data/lib/dinstaller.rb +5 -0
- data/share/dbus.conf +38 -0
- data/share/dbus.service +5 -0
- data/share/systemd.service +14 -0
- 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
|