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