• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yast / yast-network / 4859584370

pending completion
4859584370

Pull #1327

github

Unknown Committer
Unknown Commit Message
Pull Request #1327: [WIP] Firmware configured interface

81 of 81 new or added lines in 7 files covered. (100.0%)

9240 of 11493 relevant lines covered (80.4%)

20.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.92
/src/lib/y2network/widgets/boot_protocol.rb
1
# Copyright (c) [2019] SUSE LLC
2
#
3
# All Rights Reserved.
4
#
5
# This program is free software; you can redistribute it and/or modify it
6
# under the terms of version 2 of the GNU General Public License as published
7
# by the Free Software Foundation.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12
# more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with this program; if not, contact SUSE LLC.
16
#
17
# To contact SUSE LLC about this file by physical or electronic mail, you may
18
# find current contact information at www.suse.com.
19

20
require "yast"
1✔
21
require "cwm/custom_widget"
1✔
22

23
require "y2network/boot_protocol"
1✔
24

25
Yast.import "DNS"
1✔
26
Yast.import "Hostname"
1✔
27
Yast.import "IP"
1✔
28
Yast.import "Label"
1✔
29
Yast.import "Netmask"
1✔
30
Yast.import "NetHwDetection"
1✔
31
Yast.import "Popup"
1✔
32
Yast.import "ProductFeatures"
1✔
33
Yast.import "UI"
1✔
34

35
module Y2Network
1✔
36
  module Widgets
1✔
37
    class BootProtocol < CWM::CustomWidget
1✔
38
      def initialize(settings)
1✔
39
        textdomain "network"
31✔
40
        @settings = settings
31✔
41
      end
42

43
      def contents
1✔
44
        RadioButtonGroup(
1✔
45
          Id(:bootproto),
46
          VBox(
47
            Left(
48
              HBox(
49
                RadioButton(
50
                  Id(:bootproto_none),
51
                  Opt(:notify),
52
                  _("No Link and IP Setup (Bond Ports)")
53
                )
54
              )
55
            ),
56
            Left(
57
              HBox(
58
                RadioButton(Id(:bootproto_dynamic), Opt(:notify), _("Dynamic Address")),
59
                HSpacing(2),
60
                ComboBox(
61
                  Id(:bootproto_dyn),
62
                  Opt(:notify),
63
                  "",
64
                  [
65
                    Item(Id(:bootproto_dhcp), "DHCP"),
66
                    Item(Id(:bootproto_dhcp_auto), "DHCP+Zeroconf"),
67
                    Item(Id(:bootproto_auto), "Zeroconf")
68
                  ]
69
                ),
70
                HSpacing(2),
71
                ComboBox(
72
                  Id(:bootproto_dhcp_mode),
73
                  "",
74
                  [
75
                    Item(Id(:bootproto_dhcp_both), _("DHCP both version 4 and 6")),
76
                    Item(Id(:bootproto_dhcp_v4), _("DHCP version 4 only")),
77
                    Item(Id(:bootproto_dhcp_v6), _("DHCP version 6 only"))
78
                  ]
79
                )
80
              )
81
            ),
82
            VBox(
83
              Left(
84
                RadioButton(
85
                  Id(:bootproto_static),
86
                  Opt(:notify),
87
                  _("Statically Assigned IP Address")
88
                )
89
              ),
90
              HBox(
91
                # TODO: When object CWM top level is used, then use here IPAddress object
92
                InputField(Id(:bootproto_ipaddr), Opt(:hstretch), _("&IP Address")),
93
                HSpacing(1),
94
                InputField(Id(:bootproto_netmask), Opt(:hstretch), _("&Subnet Mask")),
95
                HSpacing(1),
96
                InputField(Id(:bootproto_hostname), Opt(:hstretch), _("&Hostname")),
97
                HStretch()
98
              )
99
            )
100
          )
101
        )
102
      end
103

104
      def init
1✔
105
        case @settings.boot_protocol
11✔
106
        when Y2Network::BootProtocol::STATIC
107
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_static)
4✔
108
          Yast::UI.ChangeWidget(
4✔
109
            Id(:bootproto_ipaddr),
110
            :Value,
111
            @settings.ip_address
112
          )
113
          Yast::UI.ChangeWidget(
4✔
114
            Id(:bootproto_netmask),
115
            :Value,
116
            @settings.subnet_prefix
117
          )
118
          Yast::UI.ChangeWidget(
4✔
119
            Id(:bootproto_hostname),
120
            :Value,
121
            @settings.hostname
122
          )
123
        when Y2Network::BootProtocol::DHCP
124
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_dynamic)
1✔
125
          Yast::UI.ChangeWidget(Id(:bootproto_dhcp_mode), :Value, :bootproto_dhcp_both)
1✔
126
          Yast::UI.ChangeWidget(Id(:bootproto_dyn), :Value, :bootproto_dhcp)
1✔
127
        when Y2Network::BootProtocol::DHCP4
128
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_dynamic)
1✔
129
          Yast::UI.ChangeWidget(Id(:bootproto_dhcp_mode), :Value, :bootproto_dhcp_v4)
1✔
130
          Yast::UI.ChangeWidget(Id(:bootproto_dyn), :Value, :bootproto_dhcp)
1✔
131
        when Y2Network::BootProtocol::DHCP6
132
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_dynamic)
1✔
133
          Yast::UI.ChangeWidget(Id(:bootproto_dhcp_mode), :Value, :bootproto_dhcp_v6)
1✔
134
          Yast::UI.ChangeWidget(Id(:bootproto_dyn), :Value, :bootproto_dhcp)
1✔
135
        when Y2Network::BootProtocol::DHCP_AUTOIP
136
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_dynamic)
1✔
137
          Yast::UI.ChangeWidget(Id(:bootproto_dyn), :Value, :bootproto_dhcp_auto)
1✔
138
        when Y2Network::BootProtocol::AUTOIP
139
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_dynamic)
1✔
140
          Yast::UI.ChangeWidget(Id(:bootproto_dyn), :Value, :bootproto_auto)
1✔
141
        when Y2Network::BootProtocol::NONE
142
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_none)
1✔
143
        when Y2Network::BootProtocol::IBFT
144
          Yast::UI.ChangeWidget(Id(:bootproto), :CurrentButton, :bootproto_none)
1✔
145
        end
146

147
        handle
11✔
148
      end
149

150
      def handle
1✔
151
        case value
12✔
152
        when :bootproto_static
153
          static_enabled(true)
4✔
154
          dynamic_enabled(false)
4✔
155
          one_ip = Yast::UI.QueryWidget(Id(:bootproto_ipaddr), :Value)
4✔
156
          if one_ip.empty?
4✔
157
            current_hostname = Yast::Hostname.MergeFQ(Yast::DNS.hostname, Yast::DNS.domain)
×
158
            if ![nil, "", "localhost"].include?(current_hostname)
×
159
              log.info "Presetting global hostname"
×
160
              Yast::UI.ChangeWidget(Id(:bootproto_hostname), :Value, current_hostname)
×
161
            end
162
          end
163
        when :bootproto_dynamic
164
          static_enabled(false)
5✔
165
          dynamic_enabled(true)
5✔
166
        when :bootproto_none
167
          static_enabled(false)
3✔
168
          dynamic_enabled(false)
3✔
169
        else
170
          raise "Unexpected value for boot protocol #{value.inspect}"
×
171
        end
172

173
        nil
174
      end
175

176
      def store
1✔
177
        # FIXME: this value reset should be in backend in general not Yast::UI responsibility
178
        @settings.ip_address = ""
12✔
179
        @settings.subnet_prefix = ""
12✔
180
        case value
12✔
181
        when :bootproto_none
182
          bootproto = "none"
1✔
183
          @settings.boot_protocol = bootproto
1✔
184
        when :bootproto_static
185
          @settings.boot_protocol = "static"
6✔
186
          @settings.ip_address = Yast::UI.QueryWidget(:bootproto_ipaddr, :Value)
6✔
187
          @settings.subnet_prefix = Yast::UI.QueryWidget(:bootproto_netmask, :Value)
6✔
188
          @settings.hostname = Yast::UI.QueryWidget(:bootproto_hostname, :Value)
6✔
189
        when :bootproto_dynamic
190
          case Yast::UI.QueryWidget(:bootproto_dyn, :Value)
5✔
191
          when :bootproto_dhcp
192
            case Yast::UI.QueryWidget(:bootproto_dhcp_mode, :Value)
3✔
193
            when :bootproto_dhcp_both
194
              @settings.boot_protocol = "dhcp"
1✔
195
            when :bootproto_dhcp_v4
196
              @settings.boot_protocol = "dhcp4"
1✔
197
            when :bootproto_dhcp_v6
198
              @settings.boot_protocol = "dhcp6"
1✔
199
            else
200
              raise "Unexpected dhcp mode value " \
×
201
                "#{Yast::UI.QueryWidget(:bootproto_dhcp_mode, :Value).inspect}"
202
            end
203
          when :bootproto_dhcp_auto
204
            @settings.boot_protocol = "dhcp+autoip"
1✔
205
          when :bootproto_auto
206
            @settings.boot_protocol = "autoip"
1✔
207
          else
208
            raise "Unexpected dynamic mode value " \
×
209
              "#{Yast::UI.QueryWidget(:bootproto_dyn, :Value).inspect}"
210
          end
211
        else
212
          raise "Unexpected boot protocol value #{Yast::UI.QueryWidget(:bootproto, :Value).inspect}"
×
213
        end
214
      end
215

216
      def validate
1✔
217
        return true if value != :bootproto_static
1✔
218

219
        ipa = Yast::UI.QueryWidget(:bootproto_ipaddr, :Value)
×
220
        if !Yast::IP.Check(ipa)
×
221
          Yast::Popup.Error(_("No valid IP address."))
×
222
          Yast::UI.SetFocus(:bootproto_ipaddr)
×
223
          return false
×
224
        end
225

226
        mask = Yast::UI.QueryWidget(:bootproto_netmask, :Value)
×
227
        if mask != "" && !valid_netmask(ipa, mask)
×
228
          Yast::Popup.Error(_("No valid netmask or prefix length."))
×
229
          Yast::UI.SetFocus(:bootproto_netmask)
×
230
          return false
×
231
        end
232

233
        hname = Yast::UI.QueryWidget(:bootproto_hostname, :Value)
×
234
        if !hname.empty?
×
235
          if !Yast::Hostname.CheckFQ(hname)
×
236
            Yast::Popup.Error(_("Invalid hostname."))
×
237
            Yast::UI.SetFocus(:bootproto_hostname)
×
238
            return false
×
239
          end
240
        # There'll be no 127.0.0.2 -> remind user to define some hostname
241
        elsif !Yast::Popup.YesNo(
×
242
          _(
243
            "No hostname has been specified. We recommend to associate \n" \
244
              "a hostname with a static IP, otherwise the machine name will \n" \
245
              "not be resolvable without an active network connection.\n" \
246
              "\n" \
247
              "Really leave the hostname blank?\n"
248
          )
249
        )
250
          Yast::UI.SetFocus(:bootproto_hostname)
×
251
          return false
×
252
        end
253

254
        # validate duplication
255
        if Yast::NetHwDetection.DuplicateIP(ipa)
×
256
          Yast::UI.SetFocus(:bootproto_ipaddr)
×
257
          # Popup text
258
          if !Yast::Popup.YesNoHeadline(
×
259
            Yast::Label.WarningMsg,
260
            _("Duplicate IP address detected.\nReally continue?\n")
261
          )
262
            return false
×
263
          end
264
        end
265

266
        true
×
267
      end
268

269
      def help
1✔
270
        res = _(
1✔
271
          "<p><b><big>Address Setup</big></b></p>\n" \
272
            "<p>Select <b>No Address Setup</b> if you do not want " \
273
            "to assign an IP address to this device.\n" \
274
            "This is particularly useful for bonding ethernet devices.</p>\n"
275
        ) +
276
          # Address dialog help 2/8
277
          _(
278
            "<p>Select <b>Dynamic Address</b> if you do not have a static IP address \n" \
279
              "assigned by the system administrator or your Internet provider.</p>\n"
280
          ) +
281
          # Address dialog help 3/8
282
          _(
283
            "<p>Choose one of the dynamic address assignment methods. Select <b>DHCP</b>\n" \
284
              "if you have a DHCP server running on your local network. Network addresses \n" \
285
              "are then automatically obtained from the server.</p>\n"
286
          ) +
287
          # Address dialog help 4/8
288
          _(
289
            "<p>To search for an IP address and assign it statically, select \n" \
290
              "<b>Zeroconf</b>. To use DHCP and fall back to zeroconf, " \
291
              "select <b>DHCP + Zeroconf\n" \
292
              "</b>. Otherwise, the network addresses must be assigned <b>Statically</b>.</p>\n"
293
          )
294

295
        if Yast::ProductFeatures.GetBooleanFeature("network", "force_static_ip")
1✔
296
          res += _(
×
297
            "<p>DHCP configuration is not recommended for this product.\n" \
298
              "Components of this product might not work with DHCP.</p>"
299
          )
300
        end
301

302
        res
1✔
303
      end
304

305
      def dynamic_enabled(value)
1✔
306
        Yast::UI.ChangeWidget(Id(:bootproto_dyn), :Enabled, value)
12✔
307
        if value
12✔
308
          # dhcp mode works only with plain dhcp
309
          if :bootproto_dhcp == Yast::UI.QueryWidget(Id(:bootproto_dyn), :Value)
5✔
310
            Yast::UI.ChangeWidget(Id(:bootproto_dhcp_mode), :Enabled, value)
×
311
          else
312
            Yast::UI.ChangeWidget(Id(:bootproto_dhcp_mode), :Enabled, false)
5✔
313
          end
314
        else
315
          Yast::UI.ChangeWidget(Id(:bootproto_dhcp_mode), :Enabled, value)
7✔
316
        end
317
      end
318

319
      def static_enabled(value)
1✔
320
        Yast::UI.ChangeWidget(Id(:bootproto_ipaddr), :Enabled, value)
12✔
321
        Yast::UI.ChangeWidget(Id(:bootproto_netmask), :Enabled, value)
12✔
322
        Yast::UI.ChangeWidget(Id(:bootproto_hostname), :Enabled, value)
12✔
323
      end
324

325
      def value
1✔
326
        Yast::UI.QueryWidget(Id(:bootproto), :CurrentButton)
×
327
      end
328

329
      def valid_netmask(ip, mask)
1✔
330
        valid_mask = false
×
331
        mask = mask[1..-1] if mask.start_with?("/")
×
332

333
        if Yast::IP.Check4(ip) && (Yast::Netmask.Check4(mask) || Yast::Netmask.CheckPrefix4(mask))
×
334
          valid_mask = true
×
335
        elsif Yast::IP.Check6(ip) && Yast::Netmask.Check6(mask)
×
336
          valid_mask = true
×
337
        else
338
          log.warn "IP address #{ip} is not valid"
×
339
        end
340
        valid_mask
×
341
      end
342
    end
343
  end
344
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc