Skip to content

Commit 7e3829b

Browse files
authored
Merge pull request #150 from yast/wsl_systemd
Wsl systemd
2 parents c02b8a8 + ba68b44 commit 7e3829b

File tree

7 files changed

+191
-23
lines changed

7 files changed

+191
-23
lines changed

doc/testing_wsl.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## Testing WSL Changes
2+
3+
This document serve as reminder how is the optimal way to test changes done for WSL firstboot as working with
4+
windows server can be linux unfriendly and we would like to test without any mocking to get the best results.
5+
6+
### Creating Testing APPX
7+
8+
The easiest way is to use OBS. Find the target release for WSL image like `SUSE:SLE-15-SP6:Update:WSL`
9+
and branch there `kiwi-images-wsl` that is responsible for creation of appx. In your branch create package
10+
yast2-firstboot ( as it is usually inherited from target and does not live in WSL subproject ) and copy there
11+
modified sources with rake tarball. It is also mandatory to link or branch package `wsl-appx` as it ensures
12+
that certificate used for appx matches with the one used in kiwi.
13+
Another important think is to ensure that certificate for home repo is valid and not outdated. To check it use
14+
`osc signkey --sslcert home:...` and if it is invalid use `osc signkey --sslcert --create home:...`.
15+
16+
### Installing Modified APPX
17+
18+
Just follow instructions at https://en.opensuse.org/WSL/Manual_Installation
19+
Appx installer reports quite useless error when there is any issue, so use help at https://en.opensuse.org/WSL/Debugging_Hints

package/yast2-firstboot.changes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
-------------------------------------------------------------------
2+
Thu Dec 14 20:38:43 UTC 2023 - Josef Reidinger <jreidinger@suse.com>
3+
4+
- Allow selecting WSL systemd pattern (jsc#PED-5644, jsc#PED-5099)
5+
- 4.6.3
6+
17
-------------------------------------------------------------------
28
Fri Sep 01 19:57:03 UTC 2023 - Josef Reidinger <jreidinger@suse.com>
39

package/yast2-firstboot.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
Name: yast2-firstboot
20-
Version: 4.6.2
20+
Version: 4.6.3
2121
Release: 0
2222
Summary: YaST2 - Initial System Configuration
2323
License: GPL-2.0-only

src/lib/y2firstboot/clients/wsl_product_selection.rb

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,17 @@ def run
3838
return :auto if products.none?
3939

4040
dialog = Dialogs::WSLProductSelection.new(products,
41-
default_product: product,
42-
wsl_gui_pattern: wsl_gui_pattern?)
41+
default_product: product,
42+
wsl_gui_pattern: wsl_gui_pattern?,
43+
wsl_systemd_pattern: wsl_systemd_pattern?)
4344

4445
result = dialog.run
4546

46-
save(product: dialog.product, wsl_gui_pattern: dialog.wsl_gui_pattern) if result == :next
47+
if result == :next
48+
save(product: dialog.product,
49+
wsl_gui_pattern: dialog.wsl_gui_pattern,
50+
wsl_systemd_pattern: dialog.wsl_systemd_pattern)
51+
end
4752

4853
result
4954
end
@@ -52,14 +57,17 @@ def run
5257

5358
WSL_GUI_PATTERN = "wsl_gui".freeze
5459
private_constant :WSL_GUI_PATTERN
60+
WSL_SYSTEMD_PATTERN = "wsl_systemd".freeze
61+
private_constant :WSL_SYSTEMD_PATTERN
5562

5663
# Saves changes
5764
#
5865
# @param product [Hash] Selected product
5966
# @param wsl_gui_pattern [Boolean] Whether to install WSL GUI pattern
60-
def save(product:, wsl_gui_pattern:)
67+
def save(product:, wsl_gui_pattern:, wsl_systemd_pattern:)
6168
self.product = product
6269
self.wsl_gui_pattern = wsl_gui_pattern
70+
self.wsl_systemd_pattern = wsl_systemd_pattern
6371
update_registration
6472
end
6573

@@ -101,6 +109,26 @@ def wsl_gui_pattern=(value)
101109
end
102110
end
103111

112+
# Whether the WSL systemd pattern should be installed
113+
#
114+
# @see ẂSLConfig
115+
#
116+
# @return [Boolean]
117+
def wsl_systemd_pattern?
118+
WSLConfig.instance.patterns.include?(WSL_SYSTEMD_PATTERN)
119+
end
120+
121+
# Sets whether to install the WSL systemd pattern
122+
#
123+
# @param value [Boolean]
124+
def wsl_systemd_pattern=(value)
125+
if value
126+
WSLConfig.instance.patterns.push(WSL_SYSTEMD_PATTERN).uniq!
127+
else
128+
WSLConfig.instance.patterns.delete(WSL_SYSTEMD_PATTERN)
129+
end
130+
end
131+
104132
# Updates values stored in registration
105133
#
106134
# Those values indicates to registration what product was selected and whether the product
@@ -109,7 +137,8 @@ def wsl_gui_pattern=(value)
109137
# @see Registration::Storage::InstallationOptions
110138
def update_registration
111139
yaml_product = WSLConfig.instance.product
112-
force_registration = WSLConfig.instance.product_switched? || wsl_gui_pattern?
140+
force_registration = WSLConfig.instance.product_switched? ||
141+
wsl_gui_pattern? || wsl_systemd_pattern?
113142

114143
Registration::Storage::InstallationOptions.instance.yaml_product = yaml_product
115144
Registration::Storage::InstallationOptions.instance.force_registration = force_registration

src/lib/y2firstboot/dialogs/wsl_product_selection.rb

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,26 @@ class WSLProductSelection < ::UI::InstallationDialog
3939
# @return [Boolean]
4040
attr_reader :wsl_gui_pattern
4141

42+
# Whether the WSL systemd pattern was selected
43+
#
44+
# @return [Boolean]
45+
attr_reader :wsl_systemd_pattern
46+
4247
# Constructor
4348
#
4449
# @param products [Array<Hash>] All possible products
4550
# @param default_product [Hash] Product selected by default
4651
# @param wsl_gui_pattern [Boolean] Whether WSL GUI pattern is selected by default
47-
def initialize(products, default_product: nil, wsl_gui_pattern: false)
52+
# @param wsl_systemd_pattern [Boolean] Whether WSL systemd pattern is selected by default
53+
def initialize(products, default_product: nil, wsl_gui_pattern: false,
54+
wsl_systemd_pattern: false)
4855
textdomain "firstboot"
4956

5057
super()
5158
@products = products
5259
@product = default_product || products.first
5360
@wsl_gui_pattern = wsl_gui_pattern
61+
@wsl_systemd_pattern = wsl_systemd_pattern
5462
end
5563

5664
def next_handler
@@ -65,6 +73,8 @@ def dialog_title
6573
_("Product Selection")
6674
end
6775

76+
# disable rubocop metrics as yast ui is constructed with methods
77+
# rubocop:disable Metrics/AbcSize
6878
def dialog_content
6979
items = products.map { |p| item_for(p) }
7080

@@ -81,24 +91,40 @@ def dialog_content
8191
),
8292
VSpacing(2),
8393
# TRANSLATORS:
84-
Label(_("The WSL GUI pattern provides some needed packages for\n" \
85-
"a better experience with graphical applications in WSL.")),
94+
Left(Label(_("The WSL GUI pattern provides some needed packages for\n" \
95+
"a better experience with graphical applications in WSL."))),
8696
VSpacing(1),
8797
# TRANSLATORS: check box label
8898
Left(CheckBox(Id(:wsl_gui_pattern),
8999
_("Install WSL GUI pattern (requires registration)"),
90-
wsl_gui_pattern))
100+
wsl_gui_pattern)),
101+
VSpacing(2),
102+
# TRANSLATORS:
103+
Left(Label(_("The WSL systemd pattern provides wsl.conf adjustment\n" \
104+
"and init symlink for systemd enablement in WSL."))),
105+
VSpacing(1),
106+
# TRANSLATORS: check box label
107+
Left(CheckBox(Id(:wsl_systemd_pattern),
108+
_("Install WSL systemd pattern (requires registration)"),
109+
wsl_systemd_pattern))
91110
)
92111
)
93112
end
113+
# rubocop:enable Metrics/AbcSize
94114

95115
def help_text
96-
# TRANSLATORS: help text (1/2)
116+
# TRANSLATORS: help text (1/3)
97117
_("<p>Select the product to use with Windows Subsystem for Linux (WSL). " \
98118
"Some products might require registration.</p>") +
99-
# TRANSLATORS: help text (2/2)
100-
_("<p>To use graphical programs in WSL you need to install the WSL GUI pattern. " \
101-
"In that case the system needs to be registered as well.</p>")
119+
# TRANSLATORS: help text (2/3)
120+
_("<p>For smoother experience with graphical programs in WSL " \
121+
"the WSL GUI pattern provides recommended config, tools and libraries. " \
122+
"In that case the system needs to be registered as well.</p>") +
123+
# TRANSLATORS: help text (3/3)
124+
_("<p>For enablement of systemd in WSL the WSL systemd pattern provides wsl.conf " \
125+
"and /sbin/init adjustments. " \
126+
"In that case the system needs to be registered as well. " \
127+
"Relaunch is required to use systemd.</p>")
102128
end
103129

104130
private
@@ -146,6 +172,7 @@ def product_label(product)
146172

147173
def save
148174
@wsl_gui_pattern = Yast::UI.QueryWidget(Id(:wsl_gui_pattern), :Value)
175+
@wsl_systemd_pattern = Yast::UI.QueryWidget(Id(:wsl_systemd_pattern), :Value)
149176

150177
selected_id = Yast::UI.QueryWidget(Id(:product_selector), :Value)
151178
@product = products.find { |p| item_id(p) == selected_id }

test/y2firstboot/clients/wsl_product_selection_test.rb

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,16 @@ class InstallationOptions
104104

105105
let(:dialog) do
106106
instance_double(Y2Firstboot::Dialogs::WSLProductSelection,
107-
run: dialog_result,
108-
product: selected_product,
109-
wsl_gui_pattern: wsl_gui_pattern)
107+
run: dialog_result,
108+
product: selected_product,
109+
wsl_gui_pattern: wsl_gui_pattern,
110+
wsl_systemd_pattern: wsl_systemd_pattern)
110111
end
111112

112113
let(:dialog_result) { :abort }
113114
let(:selected_product) { nil }
114115
let(:wsl_gui_pattern) { nil }
116+
let(:wsl_systemd_pattern) { nil }
115117

116118
let(:product_switched) { false }
117119

@@ -159,6 +161,34 @@ class InstallationOptions
159161
end
160162
end
161163

164+
context "if the WSL systemd pattern was selected" do
165+
let(:wsl_systemd_pattern) { true }
166+
167+
before do
168+
Y2Firstboot::WSLConfig.instance.patterns = []
169+
end
170+
171+
it "stores the WSL systemd pattern in the WSL config" do
172+
subject.run
173+
174+
expect(Y2Firstboot::WSLConfig.instance.patterns).to include("wsl_systemd")
175+
end
176+
end
177+
178+
context "if the WSL systemd pattern was not selected" do
179+
let(:wsl_systemd_pattern) { false }
180+
181+
before do
182+
Y2Firstboot::WSLConfig.instance.patterns = ["wsl_systemd"]
183+
end
184+
185+
it "does not store the WSL systemd pattern in the WSL config" do
186+
subject.run
187+
188+
expect(Y2Firstboot::WSLConfig.instance.patterns).to_not include("wsl_systemd")
189+
end
190+
end
191+
162192
it "updates the product in registration storage" do
163193
Registration::Storage::InstallationOptions.instance.yaml_product = nil
164194

@@ -170,6 +200,7 @@ class InstallationOptions
170200
context "if the product was switched" do
171201
let(:product_switched) { true }
172202
let(:wsl_gui_pattern) { false }
203+
let(:wsl_systemd_pattern) { false }
173204

174205
it "updates registration storage to force registration" do
175206
Registration::Storage::InstallationOptions.instance.force_registration = false
@@ -200,13 +231,30 @@ class InstallationOptions
200231
context "and the WSL GUI pattern was not selected" do
201232
let(:wsl_gui_pattern) { false }
202233

203-
it "updates registration storage to not force registration" do
204-
Registration::Storage::InstallationOptions.instance.force_registration = true
234+
context "and the WSL systemd pattern was selected" do
235+
let(:wsl_systemd_pattern) { true }
205236

206-
subject.run
237+
it "updates registration storage to force registration" do
238+
Registration::Storage::InstallationOptions.instance.force_registration = false
207239

208-
expect(Registration::Storage::InstallationOptions.instance.force_registration)
209-
.to eq(false)
240+
subject.run
241+
242+
expect(Registration::Storage::InstallationOptions.instance.force_registration)
243+
.to eq(true)
244+
end
245+
end
246+
247+
context "and the WSL systemd pattern was not selected" do
248+
let(:wsl_systemd_pattern) { false }
249+
250+
it "updates registration storage to not force registration" do
251+
Registration::Storage::InstallationOptions.instance.force_registration = true
252+
253+
subject.run
254+
255+
expect(Registration::Storage::InstallationOptions.instance.force_registration)
256+
.to eq(false)
257+
end
210258
end
211259
end
212260
end

test/y2firstboot/dialogs/wsl_product_selection_test.rb

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ def find_widget(regexp, content)
4343

4444
subject do
4545
described_class.new(products,
46-
default_product: default_product, wsl_gui_pattern: wsl_gui_pattern)
46+
default_product: default_product,
47+
wsl_gui_pattern: wsl_gui_pattern,
48+
wsl_systemd_pattern: wsl_systemd_pattern)
4749
end
4850

4951
let(:products) { [sles, sled] }
@@ -52,6 +54,7 @@ def find_widget(regexp, content)
5254

5355
let(:default_product) { sled }
5456
let(:wsl_gui_pattern) { false }
57+
let(:wsl_systemd_pattern) { false }
5558

5659
let(:installed_product) { double(Y2Packager::Resolvable, name: "SLES", version_version: "15.4") }
5760
before do
@@ -80,6 +83,12 @@ def find_widget(regexp, content)
8083
expect(widget).to_not be_nil
8184
end
8285

86+
it "shows a check box for selecting the WSL systemd pattern" do
87+
widget = find_widget(:wsl_systemd_pattern, subject.send(:dialog_content))
88+
89+
expect(widget).to_not be_nil
90+
end
91+
8392
it "automatically selects the default product" do
8493
widget = find_widget(/SLED/, subject.send(:dialog_content))
8594

@@ -105,12 +114,34 @@ def find_widget(regexp, content)
105114
expect(widget.params.last).to eq(false)
106115
end
107116
end
117+
118+
context "when WSL systemd pattern is indicated as selected" do
119+
let(:wsl_systemd_pattern) { true }
120+
121+
it "selects WSL systemd pattern checkbox by default" do
122+
widget = find_widget(:wsl_systemd_pattern, subject.send(:dialog_content))
123+
124+
expect(widget.params.last).to eq(true)
125+
end
126+
end
127+
128+
context "when WSL systemd pattern is not indicated as selected" do
129+
let(:wsl_systemd_pattern) { false }
130+
131+
it "does not select WSL systemd pattern checkbox by default" do
132+
widget = find_widget(:wsl_systemd_pattern, subject.send(:dialog_content))
133+
134+
expect(widget.params.last).to eq(false)
135+
end
136+
end
108137
end
109138

110139
describe "#next_handler" do
111140
before do
112141
allow(Yast::UI).to receive(:QueryWidget).and_call_original
113142
allow(Yast::UI).to receive(:QueryWidget).with(Id(:wsl_gui_pattern), :Value).and_return(true)
143+
allow(Yast::UI).to receive(:QueryWidget).with(Id(:wsl_systemd_pattern), :Value)
144+
.and_return(true)
114145
allow(Yast::UI).to receive(:QueryWidget).with(Id(:product_selector), :Value)
115146
.and_return("SLES:15.4")
116147
end
@@ -123,6 +154,14 @@ def find_widget(regexp, content)
123154
expect(subject.wsl_gui_pattern).to eq(true)
124155
end
125156

157+
it "saves whether the WSL GUI pattern checkbox was selected" do
158+
expect(subject.wsl_systemd_pattern).to eq(false)
159+
160+
subject.next_handler
161+
162+
expect(subject.wsl_systemd_pattern).to eq(true)
163+
end
164+
126165
it "saves the selected product" do
127166
expect(subject.product).to eq(sled)
128167

0 commit comments

Comments
 (0)