Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate MAC addresses and interface names in NetworkManager keyfiles during network configuration migration #3179

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

pcahyna
Copy link
Member

@pcahyna pcahyna commented Mar 14, 2024

Pull Request Details:
  • Type: Enhancement

  • Impact: Normal

  • Reference to related issue (URL):

  • How was this pull request tested?
    Migration of Fedora Linux system to different hardware (different NICs). With this patch, the network connections are preserved and functional after recovery, even though the NICs have different names and different MAC adresses.

  • Description of the changes in this pull request:
    Migrate NM keyfiles during network conf migration. See https://fedoramagazine.org/converting-networkmanager-from-ifcfg-to-keyfiles/ for more details on NetworkManager keyfiles.
    Only MAC addresses and interface names are migrated for now.
    TODO: migrate also IP addresses and routes.

See
https://fedoramagazine.org/converting-networkmanager-from-ifcfg-to-keyfiles/
for more details on NetworkManager keyfiles.

Only MAC addresses and interface names are migrated for now.

TODO: migrate also IP addresses and routes.
Otherwise patching fails on files with spaces in them, often used by
NetworkManager:

Failed to rewrite MAC addresses and network interfaces in /mnt/local/etc/NetworkManager/system-connections/ZSSK
Failed to rewrite MAC addresses and network interfaces in WIFI.nmconnection

(the original file is named 'ZSSK WIFI.nmconnection').
@jsmeix jsmeix added the enhancement Adaptions and new features label Mar 14, 2024
@jsmeix jsmeix added this to the ReaR v2.8 milestone Mar 14, 2024
network_config_file="$( valid_restored_file_for_patching "$restored_file" )" || continue
network_config_files+=( $network_config_file )
network_config_files+=( "$network_config_file" )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pcahyna
only out of curiosity:
Are there network config files with $IFS characters
or other problematic characters in their file names
or did you add quoting only to be on the safe side?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are, see the example in the commit message of fe60e55.
Such filenames do not occur for ifcfg files, but do with keyfiles - apparently the convention for keyfiles is to name them simply according to the ESSID of the wireless connection verbatim, while ifcfg file names are normalized to contain only "usual" characters.

Copy link
Member

@jsmeix jsmeix Mar 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since a longer time I am waiting for basic system files
with $IFS characters or other problematic characters
in their file names.

Hooray :-( now I know about the first real-world example.

The current ReaR code will break at very many places
when basic system values contain $IFS characters
or other problematic characters.

Basically this means all usage of strings to store
more than a single value must be replaced with arrays.
Doable but a huge pile of legwork.

It also means that such values must be properly marked
as as single value in user output messages,
e.g. instead of

File not found: this that

where it is not clear if this that is one or two files
better

File not found: 'this that'

which looks "interesting" when the value contains '

# files=( "Mike's letter" 'Say "Hello"' "File not found" )

# for f in "${files[@]}" ; do echo "File not found: '$f'" ; done
File not found: 'Mike's letter'
File not found: 'Say "Hello"'
File not found: 'File not found'

Sigh!

Copy link
Member Author

@pcahyna pcahyna Mar 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically this means all usage of strings to store more than a single value must be replaced with arrays. Doable but a huge pile of legwork.

yes, we should gradually change the code this way. It will help with consistency anyway if the variable is meant to be user-settable, because we have a lot of array configuration variables already and it is simpler for the user to know that variables that store multiple values are always arrays than to remember when the variable is an array and when it is a single string of space-separated values.

It also means that such values must be properly marked as as single value in user output messages, e.g. instead of

File not found: this that

where it is not clear if this that is one or two files better

File not found: 'this that'

We have been already doing that AFAICT, at least that has been my experience with existing log or terminal messages - they are usually quoted this way and I tried to respect it.

which looks "interesting" when the value contains '

# files=( "Mike's letter" 'Say "Hello"' "File not found" )

# for f in "${files[@]}" ; do echo "File not found: '$f'" ; done
File not found: 'Mike's letter'
File not found: 'Say "Hello"'
File not found: 'File not found'

Sigh!

True. I don't expect this to occur often, but it is true that the "saxonic genitive" makes it more likely to happen.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I experimented with several variable expansion flags, hoping that they would lead to quoting of such strange characters, but I have not been successful:

$ network_config_files=( "Pavel's WIFI" )
$ for network_config_file in "${network_config_files[@]}" ; do echo "Wrote new MAC addresses and network interfaces in '$network_config_file'"; done
Wrote new MAC addresses and network interfaces in 'Pavel's WIFI'
$ for network_config_file in "${network_config_files[@]}" ; do echo "Wrote new MAC addresses and network interfaces in '${network_config_file:Q}'"; done
Wrote new MAC addresses and network interfaces in 'Pavel's WIFI'
$ for network_config_file in "${network_config_files[@]}" ; do echo "Wrote new MAC addresses and network interfaces in '${network_config_file:K}'"; done
Wrote new MAC addresses and network interfaces in 'Pavel's WIFI'

I want the code being correct and safe for any possible input, but in the case of code used purely for display / informational purposes I am willing to relax this requirement: I don't want to spend too much time and make the code more complicated / less readable just to get a better formatting of log messages in corner cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pcahyna
I didn't mean my

looks "interesting" when the value contains '

part that we should implement sophisticated code
to make such corner cases look nicer in ReaR.

Simple enclosing values with ' in user messages like

LogPrint "... '$variable' ..."

is sufficient.

It is also in general useful to clearly show
when $variable is empty or blanks.

Forthermore simple ' is predictable what the output
will look like from plain looking at the code.
Because at least I cannot find right now where
${var:Q} and ${var:K} are documented
(searching for Q or K is not very helpful ;-)
So far up to now I only found ${var@Q} and ${var@K} in
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsmeix oops! I meant the stuff with @, but I used :! Now it looks better:

$ network_config_files=( "Pavel's WIFI" )
$ for network_config_file in "${network_config_files[@]}" ; do echo "Wrote new MAC addresses and network interfaces in '${network_config_file@Q}'"; done
Wrote new MAC addresses and network interfaces in ''Pavel'\''s WIFI''
$ for network_config_file in "${network_config_files[@]}" ; do echo "Wrote new MAC addresses and network interfaces in '${network_config_file@K}'"; done
Wrote new MAC addresses and network interfaces in ''Pavel'\''s WIFI''

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One should drop the single quotes then, as apparently @Q produces an always-quoted version:

$ network_config_files=( "Pavel's WIFI" "Pavels WIFI"   "WIFI" )
$ for network_config_file in "${network_config_files[@]}" ; do echo "Wrote new MAC addresses and network interfaces in ${network_config_file@Q}"; done
Wrote new MAC addresses and network interfaces in 'Pavel'\''s WIFI'
Wrote new MAC addresses and network interfaces in 'Pavels WIFI'
Wrote new MAC addresses and network interfaces in 'WIFI'

I would say this is simple enough to be used instead of the single quotes, but of course it has the disadvantage of diminished readability of the code.
More seriously, even in RHEL 7 this does not work (bash is too old), so I think I will drop the idea.

Copy link
Member

@jsmeix jsmeix Mar 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For user info messages I find

... in 'Pavel'\''s WIFI'

much harder to understand what the value actually is than

... in 'Pavel's WIFI'

where I think the human's brain "fuzzy logic"
does "the right magic" to deduce that
the correct meaning is Pavel's WIFI

And 'Pavel'\''s WIFI' may even confuse some users
when something goes wrong related to Pavel's WIFI
that the reason is that Pavel'\''s WIFI is not
the expected Pavel's WIFI - e.g. think about

File not found: '/path/to/Pavel'\''s WIFI'

in contrast to

File not found: '/path/to/Pavel's WIFI'

where the latter looks more clear (at least to me)
that the file /path/to/Pavel's WIFI is meant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically the use for 'Pavel'\''s WIFI' is that you can copy and paste it to the command line and it will work without any modification, which is perhaps not that important for our purposes.

@pcahyna
Copy link
Member Author

pcahyna commented Mar 14, 2024

Regarding "TODO: migrate also IP addresses and routes."

Is it worth supporting migration of IP addresses and routes? What is the use case? I suppose it is for machine cloning to several not completely identical (different network address) copies, as I don't see how it is useful for the typical use of ReaR (disaster and recovery) where you need an identical address after recovery. Would it be acceptable to remove this feature (say in ReaR 3.0)?

@jsmeix
Copy link
Member

jsmeix commented Mar 15, 2024

@pcahyna
offhandedly I don't know what the use case is
for migration of IP addresses and routes.

My guess is similar as yours that at some time in the past
someone (mis?)used ReaR for migration of networking setup?

Perhaps (also only a guess) the idea behind is to use ReaR
to migrate a system from one environment into a different
environment, for example from bare metal hardware in one
network environment to a VM in another network environment
or something like that?

On the one hand ReaR has too many (often half-baked) features
that are almost never used in practice (and bit-rotting)
so I would like to drop corner-case features that are not
sufficiently well implemented and basically unmaintained
at ReaR upstream because it is a nightmare to maintain
when customers have issues with such features.

On the other hand such features can be a starting point for
further development to get them sufficiently well implemented
so such features could become business opportunities when
customers want to pay for further development.

I think the solution out of this conflict is
deprecation via ErrorIfDeprecated().

This way we learn via somewhat enforced user feedback
which of those features are actually in use and
we can ask back those users what their use-case is
so we better understand those corner-case features
and then we can make an informed decision
what to do with each individual corner-case feature
(drop it, keep it as is, further develop it).

@jsmeix
Copy link
Member

jsmeix commented Mar 15, 2024

@pcahyna
could you by the way show $network_config_file values
in user output messages with ' to make it clear
when a single value consists of more than one word.

As far as I see it is those two code places

Log "Wrote new MAC addresses and network interfaces in $network_config_file"
...
LogPrintError "Failed to rewrite MAC addresses and network interfaces in $network_config_file"

that should be enhanced to

Log "Wrote new MAC addresses and network interfaces in '$network_config_file'"
...
LogPrintError "Failed to rewrite MAC addresses and network interfaces in '$network_config_file'"

@pcahyna
Copy link
Member Author

pcahyna commented Mar 15, 2024

My guess is similar as yours that at some time in the past someone (mis?)used ReaR for migration of networking setup?

Perhaps (also only a guess) the idea behind is to use ReaR to migrate a system from one environment into a different environment, for example from bare metal hardware in one network environment to a VM in another network environment or something like that?

I supposed the idea was to use ReaR for cloning, i.e. backup a machine once and then restore it to multiple instances, each one will then need a different IP address. It seems though that according to the commit message of 844d50b by @schlomo where this functionality was introduced, they had indeed rather the idea of "migrating bare metal hardware in one network environment to a VM in another network environment" in mind.

@schlomo
Copy link
Member

schlomo commented Mar 15, 2024

Oh yes, that was the first version of migration support developed for P2V.

It is our common practice to log and show messages with single-quoted
file names like "Processed the file 'file name'" and it is
especially useful with file names containing spaces.
Instead of chjecking whether the first member of the array is empty,
check whether the array is actually empty.
@pcahyna
Copy link
Member Author

pcahyna commented Mar 15, 2024

@pcahyna could you by the way show $network_config_file values in user output messages with ' to make it clear when a single value consists of more than one word.

As far as I see it is those two code places

Log "Wrote new MAC addresses and network interfaces in $network_config_file"
...
LogPrintError "Failed to rewrite MAC addresses and network interfaces in $network_config_file"

that should be enhanced to

Log "Wrote new MAC addresses and network interfaces in '$network_config_file'"
...
LogPrintError "Failed to rewrite MAC addresses and network interfaces in '$network_config_file'"

@jsmeix sure, 5ea58a7

@pcahyna
Copy link
Member Author

pcahyna commented Mar 15, 2024

I now pushed another change, 5ea58a7, for a proper test for an empty array. Unfortunately, the code is now untested, as I have not tested with this change.

@pcahyna pcahyna changed the title Migrate NetworkManager keyfiles Migrate MAC addresses and interface names in NetworkManager keyfiles during network configuration migration Mar 15, 2024
Copy link
Member

@schlomo schlomo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pcahyna this looks good to me and I think it is a great idea.

I'd suggest to just merge it as it doesn't seem harmful.

Personally I wouldn't optimise ReaR for machine cloning use cases but rather point people to the ability to use cloud-init (or other tools) after the recovery to further customise the system, and this can be added to ReaR simply via configuration without coding.

@schlomo
Copy link
Member

schlomo commented May 24, 2024

Ping @rear/contributors can we merge this or should we drop this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Adaptions and new features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants