/
bootloader_proposal.rb
264 lines (237 loc) · 9.28 KB
/
bootloader_proposal.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# encoding: utf-8
# Module: bootloader_proposal.ycp
#
# $Id$
#
# Author: Klaus Kaempf <kkaempf@suse.de>
#
# Purpose: Proposal function dispatcher - bootloader.
#
# See also file proposal-API.txt for details.
module Yast
class BootloaderProposalClient < Client
def main
Yast.import "UI"
textdomain "bootloader"
Yast.import "Arch"
Yast.import "BootCommon"
Yast.import "Bootloader"
Yast.import "GfxMenu"
Yast.import "Installation"
Yast.import "Storage"
Yast.import "Mode"
Yast.import "BootSupportCheck"
Yast.include self, "bootloader/routines/wizards.rb"
@func = Convert.to_string(WFM.Args(0))
@param = Convert.to_map(WFM.Args(1))
@ret = {}
# This will be called every time we enter the proposal widget. Here we can
# return cached data, but when force_reset is set, we must create a new
# proposal based on freshly discovered data (ie. from Storage:: and
# perl-Bootloader (etc.?)).
if @func == "MakeProposal"
@force_reset = Ops.get_boolean(@param, "force_reset", false)
@language_changed = Ops.get_boolean(@param, "language_changed", false)
if @force_reset && !Mode.autoinst
# force re-calculation of bootloader proposal
# this deletes any internally cached values, a new proposal will
# not be partially based on old data now any more
Builtins.y2milestone(
"Recalculation of bootloader configuration forced"
)
Bootloader.Reset
end
# proposal not changed by user so repropose it from scratch
if !Bootloader.proposed_cfg_changed && !Mode.autoinst
Builtins.y2milestone "Proposal not modified, so repropose from scratch"
Bootloader.ResetEx(false)
end
if Mode.update
if ["grub2", "grub2-efi"].include? old_bootloader
Builtins.y2milestone "update of grub2, do not repropose"
if !BootCommon.was_read || @force_reset
# blRead(reread, avoid_reading_device_map)
Bootloader.blRead(true, true)
BootCommon.was_read = true
end
else
if !BootCommon.was_proposed || @force_reset
# Repropose the type. A regular Reset/Propose is not enough.
# For more details see bnc#872081
BootCommon.setLoaderType(nil)
Bootloader.Reset
Bootloader.Propose
end
end
else
# in installation always propose missing stuff
Bootloader.Propose
end
if Bootloader.getLoaderType == "grub2"
@ret["links"] = [
"enable_boot_mbr",
"disable_boot_mbr",
"enable_boot_root",
"disable_boot_root",
"enable_boot_boot",
"disable_boot_boot"
]
end
# to make sure packages will get installed
BootCommon.setLoaderType(BootCommon.getLoaderType(false))
@ret["raw_proposal"] = Bootloader.Summary
#F#300779 - Install diskless client (NFS-root)
#kokso: bootloader will not be installed
@device = BootCommon.getBootDisk
if @device == "/dev/nfs"
Builtins.y2milestone(
"bootlader_proposal::MakeProposal -> Boot partition is nfs type, bootloader will not be installed."
)
Builtins.y2milestone("Type of BootPartitionDevice: %1", @device)
return deep_copy(@ret)
end
Builtins.y2milestone("Type of BootPartitionDevice: %1", @device)
#F#300779 - end
if Bootloader.getLoaderType == ""
Builtins.y2error("No bootloader selected")
@ret = Builtins.add(@ret, "warning_level", :error)
# warning text in the summary richtext
@ret = Builtins.add(
@ret,
"warning",
_(
"No boot loader is selected for installation. Your system might not be bootable."
)
)
end
if !BootCommon.BootloaderInstallable
@ret = {
"warning_level" => :error,
# error in the proposal
"warning" => _(
"Because of the partitioning, the bootloader cannot be installed properly"
)
}
end
if !BootSupportCheck.SystemSupported
@ret = Convert.convert(
Builtins.union(
@ret,
{
"warning_level" => :error,
"warning" => BootSupportCheck.StringProblems,
"raw_proposal" => Bootloader.Summary
}
),
:from => "map",
:to => "map <string, any>"
)
end
# cache the values
Bootloader.cached_settings = Bootloader.Export
BootCommon.cached_settings_base_data_change_time = Storage.GetTargetChangeTime(
)
Bootloader.cached_proposal = deep_copy(@ret)
# This is a request to start some dialog and interact with the user to set
# up the Bootloader setting. Called when the user presses the link to set
# up the Bootloader.
elsif @func == "AskUser"
@chosen_id = Ops.get(@param, "chosen_id")
@result = :next
Builtins.y2milestone(
"Bootloader wanted to change with id %1",
@chosen_id
)
# enable boot from MBR
if @chosen_id == "enable_boot_mbr"
Builtins.y2milestone("Boot from MBR enabled by a single-click")
Ops.set(BootCommon.globals, "boot_mbr", "true")
Bootloader.proposed_cfg_changed = true
# disable boot from MBR
elsif @chosen_id == "disable_boot_mbr"
Builtins.y2milestone("Boot from MBR disabled by a single-click")
Ops.set(BootCommon.globals, "boot_mbr", "false")
Bootloader.proposed_cfg_changed = true
# enable boot from /boot
elsif @chosen_id == "enable_boot_boot"
Builtins.y2milestone("Boot from /boot enabled by a single-click")
Ops.set(BootCommon.globals, "boot_boot", "true")
Bootloader.proposed_cfg_changed = true
# disable boot from /boot
elsif @chosen_id == "disable_boot_boot"
Builtins.y2milestone("Boot from /boot disabled by a single-click")
Ops.set(BootCommon.globals, "boot_boot", "false")
Bootloader.proposed_cfg_changed = true
# enable boot from /
elsif @chosen_id == "enable_boot_root"
Builtins.y2milestone("Boot from / enabled by a single-click")
Ops.set(BootCommon.globals, "boot_root", "true")
Bootloader.proposed_cfg_changed = true
# disable boot from /
elsif @chosen_id == "disable_boot_root"
Builtins.y2milestone("Boot from / disabled by a single-click")
Ops.set(BootCommon.globals, "boot_root", "false")
Bootloader.proposed_cfg_changed = true
else
@has_next = Ops.get_boolean(@param, "has_next", false)
@settings = Bootloader.Export
# don't ask for abort confirm if nothing was changed (#29496)
BootCommon.changed = false
@result = BootloaderAutoSequence()
# set to true, simply because must be saved during installation
BootCommon.changed = true
if @result != :next
Bootloader.Import(
Convert.convert(
@settings,
:from => "map",
:to => "map <string, any>"
)
)
else
Bootloader.proposed_cfg_changed = true
end
end
# Fill return map
Ops.set(@ret, "workflow_sequence", @result)
# This describes the "active" parts of the Bootloader proposal section.
elsif @func == "Description"
# Fill return map.
#
# Static values do just nicely here, no need to call a function.
@ret = {
# proposal part - bootloader label
"rich_text_title" => _("Booting"),
# menubutton entry
"menu_title" => _("&Booting"),
"id" => "bootloader_stuff"
}
# Before the system is installed there is no place to write to yet. This
# code is not called. The bootloader will be installed later during
# inst_finish.
elsif @func == "Write"
@succ = Bootloader.Write
@ret = { "success" => @succ }
# update GfxMenu texts after language was changed
elsif @func == "UpdateGfxMenu"
GfxMenu.Update
end
deep_copy(@ret)
end
private
BOOT_SYSCONFIG_PATH = "/etc/sysconfig/bootloader"
# read bootloader from /mnt as SCR is not yet switched in proposal
# phase of update (bnc#874646)
def old_bootloader
target_boot_sysconfig_path = ::File.join(Installation.destdir, BOOT_SYSCONFIG_PATH)
return nil unless ::File.exists? target_boot_sysconfig_path
boot_sysconfig = ::File.read target_boot_sysconfig_path
old_bootloader = boot_sysconfig.lines.grep /^\s*LOADER_TYPE/
Builtins.y2milestone "bootloader entry #{old_bootloader.inspect}"
retur nil if old_bootloader.empty?
# get value from entry
old_bootloader.last.sub(/^.*=\s*(\S*).*/,"\\1").delete('"')
end
end unless defined? Yast::BootloaderProposalClient
end
Yast::BootloaderProposalClient.new.main