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

yast / yast-network / 7221660698

15 Dec 2023 11:50AM UTC coverage: 80.058% (+0.03%) from 80.032%
7221660698

push

github

web-flow
Merge pull request #1350 from yast/fix_bonding_doc

Fix bonding documentation (SLE-15-SP3)

9129 of 11403 relevant lines covered (80.06%)

18.6 hits per line

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

94.79
/src/lib/y2network/connection_config/base.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 "y2storage"
1✔
22
require "y2network/ip_address"
1✔
23
require "y2network/interface_type"
1✔
24
require "y2network/boot_protocol"
1✔
25
require "y2network/startmode"
1✔
26
require "y2network/connection_config/ip_config"
1✔
27

28
Yast.import "Mode"
1✔
29

30
module Y2Network
1✔
31
  module ConnectionConfig
1✔
32
    # This class is reponsible of a connection configuration
33
    #
34
    # It holds a configuration (IP addresses, MTU, WIFI settings, etc.) that can be applied to an
35
    # interface. By comparison, it is the equivalent of the "Connection" concept in NetworkManager.
36
    # When it comes to sysconfig, a "ConnectionConfig" is defined using a "ifcfg-*" file.
37
    #
38
    # Additionally, each connection config gets an internal ID which makes easier to track changes
39
    # between two different {Y2Network::Config} objects. When they are copied, the same IDs are
40
    # kept, so it is easy to find out which connections have been added, removed or simply changed.
41
    class Base
1✔
42
      include Yast::Logger
1✔
43
      # A connection could belongs to a specific interface or not. In case of
44
      # no specific interface then it could be activated by the first available
45
      # device.
46
      #
47
      # @return [String] Connection name
48
      attr_accessor :name
1✔
49

50
      # @return [String, nil] Interface to apply the configuration to
51
      # FIXME: Maybe in the future it could be a matcher. By now we will use
52
      #   the interface's name.
53
      attr_accessor :interface
1✔
54

55
      # @return [BootProtocol] Bootproto
56
      attr_accessor :bootproto
1✔
57
      # @return [IPConfig, nil] Primary IP configuration
58
      attr_accessor :ip
1✔
59
      # @return [Array<IPConfig>] Additional IP configurations (also known as 'aliases')
60
      attr_accessor :ip_aliases
1✔
61
      # @return [Integer, nil]
62
      attr_accessor :mtu
1✔
63
      # @return [Startmode]
64
      attr_accessor :startmode
1✔
65
      # @return [String, nil] Connection's custom description (e.g., "Ethernet Card 0")
66
      attr_accessor :description
1✔
67
      # @return [String] Link layer address
68
      attr_accessor :lladdress
1✔
69
      # @return [String] configuration for ethtools when initializing
70
      attr_accessor :ethtool_options
1✔
71
      # @return [String] assigned firewall zone to interface
72
      attr_accessor :firewall_zone
1✔
73
      # @return [Array<String>] interface's hostnames
74
      attr_accessor :hostnames
1✔
75
      # @return [Boolean, nil] set to true if dhcp from this interface sets machine hostname,
76
      #   false if not and nil if not specified
77
      attr_accessor :dhclient_set_hostname
1✔
78

79
      # @return [String] Connection identifier
80
      attr_reader :id
1✔
81

82
      # @return [Integer] Connection identifier counter
83
      @@last_id = 0
1✔
84

85
      # Constructor
86
      def initialize
1✔
87
        @id = @@last_id += 1
1,014✔
88
        @ip_aliases = []
1,014✔
89
        # TODO: maybe do test query if physical interface is attached to proposal?
90
        @bootproto = BootProtocol::STATIC
1,014✔
91
        @ip = IPConfig.new(IPAddress.from_string("0.0.0.0/32"))
1,014✔
92
        @startmode = Startmode.create("manual")
1,014✔
93
        @ethtool_options = ""
1,014✔
94
        @firewall_zone = ""
1,014✔
95
        @hostnames = []
1,014✔
96
      end
97

98
      # Compares ConnectionConfigs
99
      #
100
      # @return [Boolean] true when both connections are same
101
      #                   false otherwise
102
      def ==(other)
1✔
103
        return false if self.class != other.class
30✔
104

105
        [:name, :interface, :bootproto, :ip, :ip_aliases, :mtu, :startmode,
106
         :description, :lladdress, :ethtool_options, :firewall_zone, :hostname].all? do |method|
26✔
107
          public_send(method) == other.public_send(method)
312✔
108
        end
109
      end
110

111
      alias_method :eql?, :==
1✔
112

113
      PROPOSED_PPPOE_MTU = 1492 # suggested value for PPPoE
1✔
114

115
      # Propose reasonable defaults for given config. Useful for newly created devices.
116
      # @note difference between constructor and propose is that initialize should set simple
117
      #   defaults and propose have more tricky config that depends on env, product, etc.
118
      def propose
1✔
119
        propose_startmode
643✔
120
        self.mtu = PROPOSED_PPPOE_MTU if Yast::Arch.s390 && type.lcs?
643✔
121
      end
122

123
      def propose_startmode
1✔
124
        Yast.import "ProductFeatures"
643✔
125

126
        if root_filesystem_in_network?
643✔
127
          log.info "startmode nfsroot"
11✔
128
          @startmode = Startmode.create("nfsroot")
11✔
129
          return
11✔
130
        end
131

132
        product_startmode = Yast::ProductFeatures.GetStringFeature(
632✔
133
          "network",
134
          "startmode"
135
        )
136

137
        startmode = case product_startmode
632✔
138
        when "ifplugd"
139
          if replace_ifplugd?
91✔
140
            hotplug_interface? ? "hotplug" : "auto"
91✔
141
          else
142
            product_startmode
×
143
          end
144
        when "auto"
145
          "auto"
×
146
        else
147
          hotplug_interface? ? "hotplug" : "auto"
541✔
148
        end
149

150
        @startmode = Startmode.create(startmode)
632✔
151
      end
152

153
      # Returns the connection type
154
      #
155
      # Any subclass could define this method is the default
156
      # logic does not match.
157
      #
158
      # @return [InterfaceType] Interface type
159
      def type
1✔
160
        const_name = self.class.name.split("::").last.upcase
321✔
161
        InterfaceType.const_get(const_name)
321✔
162
      end
163

164
      # Whether a connection needs a virtual device associated or not.
165
      #
166
      # @return [Boolean]
167
      def virtual?
1✔
168
        false
545✔
169
      end
170

171
      # Returns all IP configurations
172
      #
173
      # @return [Array<IPConfig>]
174
      def all_ips
1✔
175
        ([ip] + ip_aliases).compact
8✔
176
      end
177

178
      # find master from given collection of configs
179
      # @param configs [ConnectionConfigsCollection]
180
      # @return [ConnectionConfig::Bonding, ConnectionConfig::Bridge, nil] gets bridge, bonding or
181
      # nil in which this device in enslaved
182
      def find_master(configs)
1✔
183
        configs.find do |config|
44✔
184
          # TODO: what about VLAN?
185
          if config.type.bonding?
77✔
186
            config.slaves.include?(name)
2✔
187
          elsif config.type.bridge?
75✔
188
            config.ports.include?(name)
26✔
189
          end
190
        end
191
      end
192

193
      # Return whether the connection is configured using the dhcp protocol or not
194
      #
195
      # @return [Boolean] true when using dhcp; false otherwise
196
      def dhcp?
1✔
197
        bootproto ? bootproto.dhcp? : false
16✔
198
      end
199

200
      # Return whether the connection is configured using a fixed IPADDR
201
      #
202
      # @return [Boolean] true when static protocol is used or not defined
203
      #   bootpro; false otherwise
204
      def static?
1✔
205
        bootproto ? bootproto.static? : true
41✔
206
      end
207

208
      # Return the first hostname associated with the primary IP address.
209
      #
210
      # @return [String, nil] returns the hostname associated with the primary
211
      #   IP address or nil
212
      def hostname
1✔
213
        hostnames&.first
71✔
214
      end
215

216
      # Convenience method in order to modify the canonical hostname mapped to
217
      # the primary IP address.
218
      #
219
      # @param hname [String, nil] hostnamme mapped to the primary IP address
220
      def hostname=(hname)
1✔
221
        short_name = hname&.split(".")&.first
16✔
222

223
        @hostnames = [hname, short_name].uniq.compact
16✔
224
        log.info("Assigned hostnames #{@hostnames.inspect} to connection #{name}")
16✔
225
      end
226

227
    private
1✔
228

229
      def replace_ifplugd?
1✔
230
        Yast.import "Arch"
91✔
231

232
        return true if !Yast::Arch.is_laptop
91✔
233
        # virtual devices cannot expect any event from ifplugd
234
        return true if virtual?
×
235

236
        false
×
237
      end
238

239
      def hotplug_interface?
1✔
240
        # virtual interface is not hotplugable
241
        return false if virtual?
632✔
242
        # if interface is not there
243
        return true unless interface
521✔
244

245
        false
×
246
        # TODO: interface is just string so interface.hardware.hotplug does not work
247
      end
248

249
      def root_filesystem_in_network?
1✔
250
        return false unless Yast::Mode.normal
643✔
251

252
        # see bsc#176804
253
        devicegraph = Y2Storage::StorageManager.instance.staging
632✔
254
        devicegraph.filesystem_in_network?("/")
632✔
255
      end
256
    end
257
  end
258
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