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

yast / yast-yast2 / 13440235285

20 Feb 2025 04:40PM UTC coverage: 41.869% (-0.02%) from 41.889%
13440235285

push

github

web-flow
Merge pull request #1316 from yast/agama_kernel_conf

Respect Agama kernel parameters

2 of 4 new or added lines in 1 file covered. (50.0%)

265 existing lines in 40 files now uncovered.

12605 of 30106 relevant lines covered (41.87%)

10.76 hits per line

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

63.64
/library/network/src/modules/NetworkService.rb
1
# ***************************************************************************
2
#
3
# Copyright (c) 2002 - 2012 Novell, Inc.
4
# All Rights Reserved.
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of version 2 of the GNU General Public License as
8
# published by the Free Software Foundation.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, contact Novell, Inc.
17
#
18
# To contact Novell about this file by physical or electronic mail,
19
# you may find current contact information at www.novell.com
20
#
21
# ***************************************************************************
22
# File:  modules/NetworkService.ycp
23
# Package:  Network configuration
24
# Summary:  Init script handling, ifup vs NetworkManager
25
# Authors:  Martin Vidner <mvidner@suse.cz>
26
#
27
# This module used to switch between /etc/init.d/network providing
28
# LSB network.service and the NetworkManager.service (or another),
29
# which installs a network.service alias link.
30
#
31
# The service name installing the network.sevice is visible in the
32
# "Id" systemctl property:
33
#
34
#     # systemctl --no-pager -p Id show network.service
35
#     Id=network.service
36
#     # systemctl --force          enable NetworkManager.service
37
#     # systemctl --no-pager -p Id show network.service
38
#     Id=NetworkManager.service
39
#
40
# The network.service alias link obsoletes the old master switch in
41
# /etc/sysconfig/network/config:NETWORKMANAGER (until openSUSE-12.2).
42
require "yast"
1✔
43
require "yast2/systemd/service"
1✔
44
require "shellwords"
1✔
45

46
module Yast
1✔
47
  class NetworkServiceClass < Module
1✔
48
    # return [String, nil] current network backend identification, nil is valid value for "no service selected / running"
49
    attr_accessor :current_name
1✔
50
    # return [String, nil] new network backend identification, nil is valid value for "no service selected / running"
51
    attr_writer :cached_name
1✔
52

53
    # network backend identification to service name mapping
54
    BACKENDS = {
55
      # <internal-id>        <service name>
56
      netconfig:       "network",
1✔
57
      network_manager: "NetworkManager",
58
      wicked:          "wicked"
59
    }.freeze
60

61
    # network backend identification to its rpm package name mapping
62
    BACKEND_PKG_NAMES = {
63
      # <internal-id>        <service name>
64
      netconfig:       "sysconfig-network",
1✔
65
      network_manager: "NetworkManager",
66
      wicked:          "wicked"
67
    }.freeze
68

69
    DEFAULT_BACKEND = :wicked
1✔
70

71
    include Yast::Logger
1✔
72

73
    def main
1✔
74
      Yast.import "NetworkConfig"
1✔
75
      Yast.import "Popup"
1✔
76
      Yast.import "Mode"
1✔
77
      Yast.import "Stage"
1✔
78
      Yast.import "Package"
1✔
79
      Yast.import "Systemd"
1✔
80

81
      textdomain "base"
1✔
82

83
      # if false, read needs to do work
84
      @initialized = false
1✔
85

86
      # Variable remembers that the question has been asked during this run already.
87
      # It avoids useless questions over and over again.
88
      @already_asked_for_NetworkManager = false
1✔
89
    end
90

91
    # Helper to run systemctl actions
92
    # @param service [String] name of service
93
    # @param action [String] action what to do with service
94
    # @param force [Boolean] if action should be forced
95
    # @return exit code
96
    def RunSystemCtl(service, action, force: false)
1✔
97
      raise ArgumentError, "No network service defined." if service.nil?
3✔
98

99
      cmd = "/usr/bin/systemctl "\
2✔
100
            "#{force ? "--force" : ""} " \
1✔
101
            "#{action.shellescape} " \
102
            "#{service.shellescape}.service"
103
      ret = SCR.Execute(path(".target.bash_output"), cmd, "TERM" => "raw")
2✔
104
      Builtins.y2debug("RunSystemCtl: Command '%1' returned '%2'", cmd, ret)
2✔
105
      Ops.get_integer(ret, "exit", -1)
2✔
106
    end
107

108
    def run_wicked(*params)
1✔
109
      cmd = "/usr/sbin/wicked #{params.map(&:shellescape).join(" ")}"
×
110
      ret = SCR.Execute(
×
111
        path(".target.bash"),
112
        cmd
113
      )
114

115
      Builtins.y2milestone("run_wicked: #{cmd} -> #{ret}")
×
116
    end
117

118
    # Whether a network service change were requested
119
    # @return true when service change were requested
120
    def Modified
1✔
121
      Read()
×
122
      @cached_name != @current_name
×
123
    end
124

125
    # Checks if given network backend is available in the system
126
    def backend_available?(backend)
1✔
127
      Package.Installed(BACKEND_PKG_NAMES[backend], target: :system)
×
128
    end
129

130
    alias_method :is_backend_available, :backend_available?
1✔
131

132
    # Checks if configuration is managed by NetworkManager
133
    #
134
    # @return true  when the network is managed by an external tool,
135
    #               like NetworkManager, false otherwise
136
    def network_manager?
1✔
137
      cached_service?(:network_manager)
1✔
138
    end
139

140
    alias_method :is_network_manager, :network_manager?
1✔
141

142
    def netconfig?
1✔
143
      cached_service?(:netconfig)
1✔
144
    end
145

146
    alias_method :is_netconfig, :netconfig?
1✔
147

148
    def wicked?
1✔
149
      cached_service?(:wicked)
3✔
150
    end
151

152
    alias_method :is_wicked, :wicked?
1✔
153

154
    def disabled?
1✔
155
      cached_service?(nil)
×
156
    end
157

158
    alias_method :is_disabled, :disabled?
1✔
159

160
    # Choose the given backend as the one to be used
161
    #
162
    # @param name [Symbol] backend name
163
    # @param [Boolean] return whether the given backend was selected or not
164
    def use(name)
1✔
165
      return false unless BACKENDS.key?(name)
6✔
166

167
      Read()
3✔
168
      @cached_name = name
3✔
169

170
      true
3✔
171
    end
172

173
    def use_network_manager
1✔
174
      Read()
×
175
      @cached_name = :network_manager
×
176

UNCOV
177
      nil
×
178
    end
179

180
    def use_netconfig
1✔
181
      Read()
×
182
      @cached_name = :netconfig
×
183

UNCOV
184
      nil
×
185
    end
186

187
    def use_wicked
1✔
188
      Read()
×
189
      @cached_name = :wicked
×
190

UNCOV
191
      nil
×
192
    end
193

194
    # disables network service completely
195
    def disable
1✔
196
      @cached_name = nil
×
197
      stop_service(@current_name)
×
198
      disable_service(@current_name)
×
199

200
      Read()
×
201
    end
202

203
    # Determines which backend is in use based on the network service. In an
204
    # (auto)installation it returns the default backend except if systemd is
205
    # running (live) where the systemd service can be checked.
206
    #
207
    # @return [Symbol,nil] backend in use or nil
208
    def backend_in_use
1✔
209
      backend = nil
9✔
210

211
      if Stage.initial && !Systemd.Running
9✔
212
        backend = DEFAULT_BACKEND
1✔
213
        log.info "Running in installer/AutoYaST, use default: #{backend}"
1✔
214
      else
215
        service = Yast2::Systemd::Service.find("network")
8✔
216
        backend = BACKENDS.invert[service.name] if service
8✔
217
      end
218

219
      backend
9✔
220
    end
221

222
    # Initialize module data
223
    def Read
1✔
224
      return if @initialized
16✔
225

226
      @cached_name = @current_name = backend_in_use
10✔
227

228
      log.info "Current backend: #{@current_name}"
10✔
229
      @initialized = true
10✔
230

231
      nil
10✔
232
    end
233

234
    def reset!
1✔
235
      @initialized = false
7✔
236
      @current_name = nil
7✔
237
      @cached_name = nil
7✔
238
    end
239

240
    # Helper to apply a change of the network service enabling the service selected and taking care
241
    # of disabling the current one in case of modified.
242
    #
243
    # TODO: this method could take care of disabling all the services except the one selected in
244
    #   order to prevent that multiple backends are enabled at the same time.
245
    #
246
    # @param force [Boolean] whether the service should forced to be enabled or not; it will not
247
    #   disable other services apart of the one currently in use in case of modified
248
    def EnableDisableNow(force: false)
1✔
249
      return unless force || Modified()
4✔
250

251
      if current_name && Modified()
4✔
252
        stop_service(current_name)
2✔
253
        disable_service(current_name)
2✔
254
      end
255

256
      enable_service(cached_name) if cached_name
4✔
257

258
      @initialized = false
4✔
259
      Read()
4✔
260

261
      nil
4✔
262
    end
263

264
    # Reports if network service is active or not.
265
    # It does not report if network is connected.
266
    # @return true when network service is active
267
    def IsActive
1✔
268
      RunSystemCtl("network", "is-active") == 0
×
269
    end
270

271
    # Reload or restars the network service.
272
    def ReloadOrRestart
1✔
273
      if Stage.initial
×
274
        # inst-sys is not running systemd nor sysV init, so systemctl call
275
        # is not available and service has to be restarted directly
276
        wicked_restart
×
277
      else
278
        systemctl_reload_restart
×
279
      end
280
    end
281

282
    # Restarts the network service
283
    def Restart
1✔
284
      if Stage.initial
×
285
        wicked_restart
×
286
      else
287
        systemctl_restart
×
288
      end
289

UNCOV
290
      nil
×
291
    end
292

293
    # This is an old, confusing name for ReloadOrRestart() now
294
    def StartStop
1✔
295
      ReloadOrRestart()
×
296

UNCOV
297
      nil
×
298
    end
299

300
    # Opens up a continue/cancel confirmation popup
301
    # in the case when NetworkManager is enabled.
302
    # User is informed that continuing the configuration
303
    # may produce undefined results.
304
    # If NetworkManager is not used, silently returns true.
305
    #
306
    # @return [Boolean] continue
307
    def ConfirmNetworkManager
1✔
308
      return true if @already_asked_for_NetworkManager || !network_manager?
×
309

310
      # TRANSLATORS: pop-up question when reading the service configuration
311
      cont = Popup.ContinueCancel(
×
312
        _(
313
          "Your network interfaces are currently controlled by NetworkManager\n" \
314
          "but the service to configure might not work well with it.\n" \
315
          "\n" \
316
          "Really continue?"
317
        )
318
      )
319
      Builtins.y2milestone(
×
320
        "Network is controlled by NetworkManager, user decided %1...",
321
        cont ? "to continue" : "not to continue"
×
322
      )
323
      @already_asked_for_NetworkManager = true
×
324

325
      cont
×
326
    end
327

328
    def isNetworkRunning
1✔
329
      isNetworkv4Running || isNetworkv6Running
×
330
    end
331

332
    # test for IPv4
333
    def isNetworkv4Running
1✔
334
      net = SCR.Execute(
×
335
        path(".target.bash"),
336
        "/bin/ip addr | /usr/bin/grep -v '127.0.0\\|inet6' | /usr/bin/grep -c inet"
337
      )
338
      if net == 0
×
339
        Builtins.y2milestone("IPv4 network is running ...")
×
340
        true
×
341
      else
342
        Builtins.y2milestone("IPv4 network is not running ...")
×
343
        false
×
344
      end
345
    end
346

347
    # test for IPv6
348
    def isNetworkv6Running
1✔
349
      net = SCR.Execute(
×
350
        path(".target.bash"),
351
        "/bin/ip addr | /usr/bin/grep -v 'inet6 ::1\\|inet6 fe80' | /usr/bin/grep -c inet6"
352
      )
353

354
      if net == 0
×
355
        Builtins.y2milestone("IPv6 network is running ...")
×
356
        true
×
357
      else
358
        Builtins.y2milestone("IPv6 network is not running ...")
×
359
        false
×
360
      end
361
    end
362

363
    # If there is network running, return true.
364
    # Otherwise show error popup depending on Stage and return false
365
    # @return true if network running
366
    def RunningNetworkPopup
1✔
367
      network_running = isNetworkRunning
×
368

369
      log.info "RunningNetworkPopup #{network_running}"
×
370

371
      return true if network_running
×
372

373
      error_text = if Stage.initial
×
374
        _(
×
375
          "No running network detected.\n" \
376
          "Restart installation and configure network in Linuxrc\n" \
377
          "or continue without network."
378
        )
379
      else
380
        _(
×
381
          "No running network detected.\n" \
382
          "Configure network with YaST or Network Manager plug-in\n" \
383
          "and start this module again\n" \
384
          "or continue without network."
385
        )
386
      end
387

388
      ret = Popup.ContinueCancel(error_text)
×
389

390
      log.error "Network not runing!"
×
391
      ret
×
392
    end
393

394
    # Replies with currently selected network service name
395
    #
396
    # Currently known backends:
397
    # - :network_manager - not supported by YaST
398
    # - :netconfig - supported
399
    # - :wicked - supported (via its backward compatibility to
400
    # ifup)
401
    #
402
    def cached_name
1✔
403
      Read()
9✔
404
      @cached_name
9✔
405
    end
406

407
  private
1✔
408

409
    # Checks if currently cached service is the given one
410
    def cached_service?(service)
1✔
411
      cached_name == service
5✔
412
    rescue StandardError
413
      Builtins.y2error("NetworkService: error when checking cached network service")
×
414
      false
×
415
    end
416

417
    # Restarts wicked backend directly
418
    def wicked_restart
1✔
419
      run_wicked("ifdown", "all")
×
420
      run_wicked("ifup", "all")
×
421
    end
422

423
    # Restarts network backend using systemctl call
424
    def systemctl_restart
1✔
425
      RunSystemCtl("network", "stop")
×
426
      EnableDisableNow()
×
427
      RunSystemCtl("network", "start")
×
428
    end
429

430
    # Restarts or reloads configuration for network backend when
431
    # systemctl is available
432
    def systemctl_reload_restart
1✔
433
      if IsActive()
×
434
        if Modified()
×
435
          # reload is not sufficient
436
          systemctl_restart
×
437
        else
438
          # reload may be unsupported
439
          RunSystemCtl("network", "reload-or-try-restart")
×
440
        end
441
      else
442
        # always stop, it does not hurt if the net was stopped.
443
        systemctl_restart
×
444
      end
445

UNCOV
446
      nil
×
447
    end
448

449
    # Stops backend network service
450
    def stop_service(service)
1✔
451
      return if !service
2✔
452

453
      if service == :wicked
2✔
454
        # FIXME: you really need to use 'wickedd'. Moreover kill action do not
455
        # kill all wickedd services - e.g. nanny, dhcp* ... stays running
456
        # This needs to be clarified with wicked people.
457
        # bnc#864619
458
        RunSystemCtl("wickedd", "stop")
×
459
      else
460
        # Stop should be called before, but when the service
461
        # were not correctly started until now, stop may have
462
        # no effect.
463
        # So let's kill all processes in the network service
464
        # cgroup to make sure e.g. dhcp clients are stopped.
465
        RunSystemCtl(BACKENDS[@current_name], "kill")
2✔
466
      end
467
    end
468

469
    def disable_service(service)
1✔
470
      RunSystemCtl(BACKENDS[service], "disable")
2✔
471
    end
472

473
    def enable_service(service)
1✔
474
      RunSystemCtl(BACKENDS[service], "enable", force: true)
3✔
475
    end
476

477
    publish function: :Read, type: "void ()"
1✔
478
    publish function: :Modified, type: "boolean ()"
1✔
479
    publish function: :is_backend_available, type: "boolean (symbol)"
1✔
480
    publish function: :is_network_manager, type: "boolean ()"
1✔
481
    publish function: :is_netconfig, type: "boolean ()"
1✔
482
    publish function: :is_wicked, type: "boolean ()"
1✔
483
    publish function: :is_disabled, type: "boolean ()"
1✔
484
    publish function: :use_network_manager, type: "void ()"
1✔
485
    publish function: :use_netconfig, type: "void ()"
1✔
486
    publish function: :use_wicked, type: "void ()"
1✔
487
    publish function: :IsActive, type: "boolean ()"
1✔
488
    publish function: :ReloadOrRestart, type: "void ()"
1✔
489
    publish function: :Restart, type: "void ()"
1✔
490
    publish function: :StartStop, type: "void ()"
1✔
491
    publish function: :ConfirmNetworkManager, type: "boolean ()"
1✔
492
    publish function: :isNetworkRunning, type: "boolean ()"
1✔
493
    publish function: :isNetworkv4Running, type: "boolean ()"
1✔
494
    publish function: :isNetworkv6Running, type: "boolean ()"
1✔
495
    publish function: :RunningNetworkPopup, type: "boolean ()"
1✔
496
  end
497

498
  NetworkService = NetworkServiceClass.new
1✔
499
  NetworkService.main
1✔
500
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

© 2026 Coveralls, Inc