Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
truenas-rk3588
truenas
Commits
7c2f1b35
Unverified
Commit
7c2f1b35
authored
1 year ago
by
themylogin
Committed by
GitHub
1 year ago
Browse files
Options
Download
Email Patches
Plain Diff
Network interface `link_address_b` (#11497)
parent
5b7380e2
truenas/13.3-stable
13.1-smb-testing
13.1-test_425
NAS-124317-13.1
adjust-dcerpcd-kill
awalker_testing_core
expand-failure-scenarios
fix-collectd-daemon
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
src/freenas/usr/local/lib/middlewared_truenas/plugins/failover_/event.py
+4
-0
.../local/lib/middlewared_truenas/plugins/failover_/event.py
src/middlewared/middlewared/alembic.ini
+1
-1
src/middlewared/middlewared/alembic.ini
src/middlewared/middlewared/alembic/versions/13.1/2023-06-13_12-04_link_address_b.py
+32
-0
.../alembic/versions/13.1/2023-06-13_12-04_link_address_b.py
src/middlewared/middlewared/plugins/interface/link_address.py
+60
-110
...middlewared/middlewared/plugins/interface/link_address.py
src/middlewared/middlewared/plugins/network.py
+7
-1
src/middlewared/middlewared/plugins/network.py
with
104 additions
and
112 deletions
+104
-112
src/freenas/usr/local/lib/middlewared_truenas/plugins/failover_/event.py
View file @
7c2f1b35
...
...
@@ -696,6 +696,8 @@ class FailoverService(Service):
logger
.
warning
(
'Initializing KMIP keys'
)
self
.
run_call
(
'kmip.initialize_keys'
)
self
.
run_call
(
'interface.persist_link_addresses'
)
logger
.
warning
(
'Failover event complete.'
)
except
AlreadyLocked
:
logger
.
warning
(
'Failover event handler failed to aquire master lockfile'
)
...
...
@@ -890,6 +892,8 @@ class FailoverService(Service):
# Sync GELI and/or ZFS encryption keys from MASTER node
self
.
middleware
.
call_sync
(
'failover.sync_keys_from_remote_node'
)
self
.
run_call
(
'failover.call_remote'
,
'interface.persist_link_addresses'
)
# if we're the backup controller then it means
# the SED drives have already been unlocked so
# set this accordingly so we don't try to unlock
...
...
This diff is collapsed.
Click to expand it.
src/middlewared/middlewared/alembic.ini
View file @
7c2f1b35
...
...
@@ -29,7 +29,7 @@ timezone = UTC
# version location specification; this defaults
# to alembic/versions. When using multiple version
# directories, initial revisions must be specified with --version-path
version_locations
=
alembic/versions/1
2.0
alembic/versions/13.0
version_locations
=
alembic/versions/1
3.1
alembic/versions/13.0
alembic/versions/12.0
# the output encoding used when revision files
# are written from script.py.mako
...
...
This diff is collapsed.
Click to expand it.
src/middlewared/middlewared/alembic/versions/13.1/2023-06-13_12-04_link_address_b.py
0 → 100644
View file @
7c2f1b35
"""Network interface link_address_b
Revision ID: b412304844e1
Revises: 88bfe11b5be5
Create Date: 2023-06-13 12:04:07.420120+00:00
"""
from
alembic
import
op
import
sqlalchemy
as
sa
# revision identifiers, used by Alembic.
revision
=
'b412304844e1'
down_revision
=
'88bfe11b5be5'
branch_labels
=
None
depends_on
=
None
def
upgrade
():
# ### commands auto generated by Alembic - please adjust! ###
with
op
.
batch_alter_table
(
'network_interfaces'
,
schema
=
None
)
as
batch_op
:
batch_op
.
add_column
(
sa
.
Column
(
'int_link_address_b'
,
sa
.
String
(
length
=
17
),
nullable
=
True
))
# ### end Alembic commands ###
def
downgrade
():
# ### commands auto generated by Alembic - please adjust! ###
with
op
.
batch_alter_table
(
'network_interfaces'
,
schema
=
None
)
as
batch_op
:
batch_op
.
drop_column
(
'int_link_address_b'
)
# ### end Alembic commands ###
This diff is collapsed.
Click to expand it.
src/middlewared/middlewared/plugins/interface/link_address.py
View file @
7c2f1b35
import
r
e
from
middlewared.service
import
private
,
Servic
e
from
middlewared.utils
import
osc
RE_FREEBSD_BRIDGE
=
re
.
compile
(
r
"bridge([0-9]+)$"
)
RE_FREEBSD_LAGG
=
re
.
compile
(
r
"lagg([0-9]+)$"
)
class
InterfaceService
(
Service
):
class
Config
:
namespace_alias
=
"interfaces"
@
private
async
def
persist_link_addresses
(
self
):
try
:
if
await
self
.
middleware
.
call
(
"failover.node"
)
==
"B"
:
local_key
=
"link_address_b"
remote_key
=
"link_address"
else
:
local_key
=
"link_address"
remote_key
=
"link_address_b"
real_interfaces
=
RealInterfaceCollection
(
await
self
.
middleware
.
call
(
"interface.query"
,
[[
"fake"
,
"!="
,
True
]]),
)
real_interfaces_remote
=
None
if
await
self
.
middleware
.
call
(
"failover.status"
)
==
"MASTER"
:
try
:
real_interfaces_remote
=
RealInterfaceCollection
(
await
self
.
middleware
.
call
(
"failover.call_remote"
,
"interface.query"
,
[[[
"fake"
,
"!="
,
True
]]]),
)
except
Exception
as
e
:
self
.
middleware
.
logger
.
warning
(
f
"Exception while retrieving remote network interfaces:
{
e
!
r
}
"
)
db_interfaces
=
DatabaseInterfaceCollection
(
await
self
.
middleware
.
call
(
"datastore.query"
,
"network.interfaces"
,
[],
{
"prefix"
:
"int_"
}),
)
# Update link addresses for interfaces in the database
for
db_interface
in
db_interfaces
:
update
=
{}
self
.
__handle_update
(
real_interfaces
,
db_interface
,
local_key
,
update
)
if
real_interfaces_remote
is
not
None
:
self
.
__handle_update
(
real_interfaces_remote
,
db_interface
,
remote_key
,
update
)
if
update
:
await
self
.
middleware
.
call
(
"datastore.update"
,
"network.interfaces"
,
db_interface
[
"id"
],
update
,
{
"prefix"
:
"int_"
})
except
Exception
:
self
.
middleware
.
logger
.
error
(
"Unhandled exception while persisting network interfaces link addresses"
,
exc_info
=
True
)
def
__handle_update
(
self
,
real_interfaces
,
db_interface
,
key
,
update
):
real_interface
=
real_interfaces
.
by_name
.
get
(
db_interface
[
"interface"
])
if
real_interface
is
None
:
link_address_local
=
None
else
:
link_address_local
=
real_interface
[
"state"
][
"link_address"
]
if
db_interface
[
key
]
!=
link_address_local
:
self
.
middleware
.
logger
.
debug
(
f
"Setting interface
{
db_interface
[
'interface'
]
!
r
}
{
key
}
=
{
link_address_local
!
r
}
"
,
)
update
[
key
]
=
link_address_local
class
InterfaceCollection
:
...
...
@@ -14,127 +69,22 @@ class InterfaceCollection:
def
by_name
(
self
):
return
{
self
.
get_name
(
i
):
i
for
i
in
self
.
interfaces
}
@
property
def
by_link_address
(
self
):
return
{
self
.
get_link_address
(
i
):
i
for
i
in
self
.
interfaces
}
def
__iter__
(
self
):
return
iter
(
self
.
interfaces
)
def
get_name
(
self
,
i
):
raise
NotImplementedError
def
get_link_address
(
self
,
i
):
raise
NotImplementedError
class
DatabaseInterfaceCollection
(
InterfaceCollection
):
def
get_name
(
self
,
i
):
return
i
[
"interface"
]
def
get_link_address
(
self
,
i
):
return
i
[
"link_address"
]
class
RealInterfaceCollection
(
InterfaceCollection
):
def
get_name
(
self
,
i
):
return
i
[
"name"
]
def
get_link_address
(
self
,
i
):
return
i
[
"state"
][
"link_address"
]
async
def
rename_interface
(
middleware
,
db_interface
,
name
):
middleware
.
logger
.
info
(
"Renaming interface %r to %r"
,
db_interface
[
"interface"
],
name
)
await
middleware
.
call
(
"datastore.update"
,
"network.interfaces"
,
db_interface
[
"id"
],
{
"interface"
:
name
},
{
"prefix"
:
"int_"
})
for
bridge
in
await
middleware
.
call
(
"datastore.query"
,
"network.bridge"
):
try
:
index
=
bridge
[
"members"
].
index
(
db_interface
[
"interface"
])
except
ValueError
:
continue
bridge
[
"members"
][
index
]
=
name
middleware
.
logger
.
info
(
"Setting bridge %r members: %r"
,
bridge
[
"id"
],
bridge
[
"members"
])
await
middleware
.
call
(
"datastore.update"
,
"network.bridge"
,
bridge
[
"id"
],
{
"members"
:
bridge
[
"members"
]})
for
lagg_member
in
await
middleware
.
call
(
"datastore.query"
,
"network.lagginterfacemembers"
):
if
lagg_member
[
"lagg_physnic"
]
==
db_interface
[
"interface"
]:
middleware
.
logger
.
info
(
"Setting LAGG member %r physical NIC %r"
,
lagg_member
[
"id"
],
name
)
await
middleware
.
call
(
"datastore.update"
,
"network.lagginterfacemembers"
,
lagg_member
[
"id"
],
{
"lagg_physnic"
:
name
})
for
vlan
in
await
middleware
.
call
(
"datastore.query"
,
"network.vlan"
):
if
vlan
[
"vlan_pint"
]
==
db_interface
[
"interface"
]:
middleware
.
logger
.
info
(
"Setting VLAN %r parent NIC %r"
,
vlan
[
"vlan_vint"
],
vlan
[
"vlan_pint"
])
await
middleware
.
call
(
"datastore.update"
,
"network.vlan"
,
vlan
[
"id"
],
{
"vlan_pint"
:
name
})
async
def
setup
(
middleware
):
try
:
real_interfaces
=
RealInterfaceCollection
(
await
middleware
.
call
(
"interface.query"
,
[[
"fake"
,
"!="
,
True
]]))
db_interfaces
=
DatabaseInterfaceCollection
(
await
middleware
.
call
(
"datastore.query"
,
"network.interfaces"
,
[],
{
"prefix"
:
"int_"
}),
)
# Migrate BSD network interfaces to Linux
if
osc
.
IS_LINUX
:
for
db_interface
in
db_interfaces
:
if
m
:
=
RE_FREEBSD_BRIDGE
.
match
(
db_interface
[
"interface"
]):
name
=
f
"br
{
m
.
group
(
1
)
}
"
await
rename_interface
(
middleware
,
db_interface
,
name
)
db_interface
[
"interface"
]
=
name
if
m
:
=
RE_FREEBSD_LAGG
.
match
(
db_interface
[
"interface"
]):
name
=
f
"bond
{
m
.
group
(
1
)
}
"
await
rename_interface
(
middleware
,
db_interface
,
name
)
db_interface
[
"interface"
]
=
name
if
db_interface
[
"link_address"
]
is
not
None
:
if
real_interfaces
.
by_name
.
get
(
db_interface
[
"interface"
])
is
not
None
:
# There already is an interface that matches DB cached one, doing nothing
continue
real_interface_by_link_address
=
real_interfaces
.
by_link_address
.
get
(
db_interface
[
"link_address"
])
if
real_interface_by_link_address
is
None
:
middleware
.
logger
.
warning
(
"Interface with link address %r does not exist anymore (its name was %r)"
,
db_interface
[
"link_address"
],
db_interface
[
"interface"
],
)
continue
db_interface_for_real_interface
=
db_interfaces
.
by_name
.
get
(
real_interface_by_link_address
[
"name"
])
if
db_interface_for_real_interface
is
not
None
:
if
db_interface_for_real_interface
!=
db_interface
:
middleware
.
logger
.
warning
(
"Database already has interface %r (we wanted to set that name for interface %r "
"because it matches its link address %r)"
,
real_interface_by_link_address
[
"name"
],
db_interface
[
"interface"
],
db_interface
[
"link_address"
],
)
continue
middleware
.
logger
.
info
(
"Interface %r is now %r (matched by link address %r)"
,
db_interface
[
"interface"
],
real_interface_by_link_address
[
"name"
],
db_interface
[
"link_address"
],
)
await
rename_interface
(
middleware
,
db_interface
,
real_interface_by_link_address
[
"name"
])
db_interface
[
"interface"
]
=
real_interface_by_link_address
[
"name"
]
# Update link addresses for interfaces in the database
for
db_interface
in
db_interfaces
:
real_interface
=
real_interfaces
.
by_name
.
get
(
db_interface
[
"interface"
])
if
real_interface
is
None
:
link_address
=
None
else
:
link_address
=
real_interface
[
"state"
][
"link_address"
]
if
db_interface
[
"link_address"
]
!=
link_address
:
middleware
.
logger
.
debug
(
"Setting link address %r for interface %r"
,
link_address
,
db_interface
[
"interface"
])
await
middleware
.
call
(
"datastore.update"
,
"network.interfaces"
,
db_interface
[
"id"
],
{
"link_address"
:
link_address
},
{
"prefix"
:
"int_"
})
except
Exception
:
middleware
.
logger
.
error
(
"Unhandled exception while migrating network interfaces"
,
exc_info
=
True
)
await
middleware
.
call
(
"interface.persist_link_addresses"
)
This diff is collapsed.
Click to expand it.
src/middlewared/middlewared/plugins/network.py
View file @
7c2f1b35
...
...
@@ -487,6 +487,7 @@ class NetworkInterfaceModel(sa.Model):
int_mtu
=
sa
.
Column
(
sa
.
Integer
(),
nullable
=
True
)
int_disable_offload_capabilities
=
sa
.
Column
(
sa
.
Boolean
(),
default
=
False
)
int_link_address
=
sa
.
Column
(
sa
.
String
(
17
),
nullable
=
True
)
int_link_address_b
=
sa
.
Column
(
sa
.
String
(
17
),
nullable
=
True
)
class
NetworkLaggInterfaceModel
(
sa
.
Model
):
...
...
@@ -1561,11 +1562,16 @@ class InterfaceService(CRUDService):
{
'int_interface'
:
new
[
'name'
]},
)
link_address_update
=
{
'int_link_address'
:
iface
[
'state'
][
'link_address'
]}
if
await
self
.
middleware
.
call
(
'system.is_enterprise_ix_hardware'
):
if
await
self
.
middleware
.
call
(
'failover.node'
)
==
'B'
:
link_address_update
=
{
'int_link_address_b'
:
iface
[
'state'
][
'link_address'
]}
await
self
.
middleware
.
call
(
'datastore.update'
,
'network.interfaces'
,
config
[
'id'
],
{
'int_
link_address
'
:
iface
[
'state'
][
'link_address'
]}
,
link_address
_update
,
)
if
iface
[
'type'
]
==
'BRIDGE'
:
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help