-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
modules/nilrt_ip.py: Add EtherCAT Support #48617
modules/nilrt_ip.py: Add EtherCAT Support #48617
Conversation
1cd1b8b
to
14dcec7
Compare
The possibilities for adapter mode are: TCP/IP, EhterCAT and Disabled. Signed-off-by: Alexandru Vasiu <alexandru.vasiu@ni.com> Signed-off-by: Ovidiu-Adrian Vancea <ovidiu.vancea@ni.com>
14dcec7
to
3e502c1
Compare
salt/modules/nilrt_ip.py
Outdated
config_parser = configparser.RawConfigParser(dict_type=CaseInsensitiveDict) | ||
config_parser.read_file(config_file) | ||
mode = '' if not config_parser.has_option(interface, 'mode') else \ | ||
_remove_quotes(config_parser.get(interface, 'mode').lower()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be an anti-pattern - doing an 'has_option' then a 'get()'. Can we use a default for the get() and do only that?
More than that, the first 5 lines seems to be a pattern that is repeated throughout the code. Can/Should we create a higher-level wrapper over the configparser to hide all this boilerplate code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get()
throws an exception if the option doesn't exist
We can make a class or a global variable where the config will be read only one time, but the problem is that if we write something with nirtcfg
then we should reload config from INI_FILE in configparser, so a method like this one will be ok:
def _get_option_configparser(section, option, default_value='', file=INI_FILE):
with salt.utils.files.fopen(file, 'r') as config_file:
config_parser = configparser.RawConfigParser(dict_type=CaseInsensitiveDict)
config_parser.read_file(config_file)
if config_parser.has_section(section) and config_parser.has_option(option):
return config_parser.get(section, option)
return default_value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be some option to pass defaults to the get, so you can avoid the has_option/get pair.
We shouldn't need a class, but only a function that can take a list of keys and returns a dict with keys/values
salt/modules/nilrt_ip.py
Outdated
if initial_mode == 'ethercat': | ||
__salt__['system.set_reboot_required_witnessed']() | ||
else: | ||
disable(interface) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there seem to be a lot of disable(interface) followed by enable(interface). Should we create a 'restart' or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep 👍
salt/modules/nilrt_ip.py
Outdated
''' | ||
if __grains__['lsb_distrib_id'] == 'nilrt': | ||
initial_mode = _get_adaptermode_info(interface) | ||
_set_adapter_mode(interface, 'EtherCAT') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why you spell 'EtherCAT' here, but do this in other places: if initial_mode == 'ethercat':
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is for network settings to understand the mode is EtherCAT
but when I parse INI_FILE, I user CaseInsensitiveDict
so that will transform EtherCAT
in ethercat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about creating a constant and use that everywhere?
I find confusing to see both 'EtherCAT' and 'ethercat' as values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will make a constant:
NIRTCFG_ETHERCAT = 'EtherCAT'
3e502c1
to
b3d626d
Compare
|
||
# some versions of nirtcfg don't set the dhcpenabled/linklocalenabled variables | ||
# when selecting "DHCP or Link Local" from MAX, so return it by default to avoid | ||
# having the requestmode "None" because none of the conditions above matched. | ||
return 'dhcp_linklocal' | ||
|
||
|
||
def _get_adapter_mode_info(interface): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this benefit from the newly created function? - _get_config_options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot about that function ... I'll change it
salt/modules/nilrt_ip.py
Outdated
}, | ||
'hwaddr': interface.hwaddr[:-1] | ||
} | ||
with salt.utils.files.fopen(INI_FILE, 'r') as config_file: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will delete that
salt/modules/nilrt_ip.py
Outdated
}, | ||
'hwaddr': interface.hwaddr[:-1] | ||
} | ||
with salt.utils.files.fopen(INI_FILE, 'r') as config_file: | ||
config_parser = configparser.RawConfigParser(dict_type=CaseInsensitiveDict) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this use the _persist_config method? And have that method fixed to use the config parser?
should we rename the _persist_config and _get_config_options to match i.e. (save/load or serialize/deserialize or something that makes sense).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe _save_config
for _persist_config
and _load_config
for _get_config_options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense
b3d626d
to
e0f8d6a
Compare
''' | ||
return adaptermode for given interface | ||
''' | ||
mode = _load_config(interface, ['mode'])['mode'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't put default_value = 'tcpip'
because the file may be corrupted and mode should be one of these values:
- disabled
- ethercat
- tcpip (default value)
''' | ||
return adaptermode for given interface | ||
''' | ||
mode = _load_config(interface, ['mode'])['mode'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will raise if 'mode' is not in the file.
Should you go with:
mode = _load_config(interface, ['mode']).get('mode') ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If mode is not in file, _load_config will return the default_value for it:
mode = {
'mode': ''
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, forgot about that.
salt/modules/nilrt_ip.py
Outdated
if out['retcode'] != 0: | ||
msg = 'Couldn\'t disable interface {0}. Error: {1}'.format(interface, out['stderr']) | ||
raise salt.exceptions.CommandExecutionError(msg) | ||
initial_mode = _get_adapter_mode_info(interface) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
up/down code is almost identical. Can you create a worker to share the logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A function called _change_state(state)
and state can be up
or down
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
The possibilities for adapter mode are: TCP/IP, EhterCAT and Disabled. Signed-off-by: Alexandru Vasiu <alexandru.vasiu@ni.com> Signed-off-by: Ovidiu-Adrian Vancea <ovidiu.vancea@ni.com>
read_file is available only since python 3.2 so readfp should be used instead Signed-off-by: Alexandru Vasiu <alexandru.vasiu@ni.com>
e0f8d6a
to
73f533e
Compare
Things look good to me. @gtmanfred can you take a look on these? They are something we'd need for Fluorine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is still a small cleanup to be made. I'm fine doing it in a different review since the functionality is correct as is.
salt/modules/nilrt_ip.py
Outdated
@@ -404,43 +495,81 @@ def get_interfaces_details(): | |||
return {'interfaces': list(map(_get_info, _interfaces))} | |||
|
|||
|
|||
def up(interface, iface_type=None): # pylint: disable=invalid-name,unused-argument | |||
def _set_adapter_mode(interface, mode): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I overlooked this before - but this shouldn't be needed. We should use _save_config() directly instead of this
@@ -504,7 +621,7 @@ def disable(interface): | |||
return down(interface) | |||
|
|||
|
|||
def _persist_config(section, token, value): | |||
def _save_config(section, token, value): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this was supposed to use the configparser too. Did we change our mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for reading, we use config parser and for writing nirtcfg (is also used by the system) ... we should test if the file will be corrupted if we are writing at the same time with nirtcfg and config parser
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. It looks good!
salt/modules/nilrt_ip.py
Outdated
if __grains__['lsb_distrib_id'] == 'nilrt': | ||
initial_mode = _get_adapter_mode_info(interface) | ||
_set_adapter_mode(interface, NIRTCFG_ETHERCAT) | ||
if __salt__['cmd.run_all']('{0} --set section={1},token=MasterID,value={2}'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not _save_config()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just have a couple of small requests.
salt/modules/nilrt_ip.py
Outdated
@@ -258,45 +259,102 @@ def _remove_quotes(value): | |||
return value | |||
|
|||
|
|||
def _get_requestmode_info(interface): | |||
def _load_config(section, options, default_value='', file=INI_FILE): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use a variable name other than file
here? It's a reserved word and can cause problems.
salt/modules/nilrt_ip.py
Outdated
@@ -258,45 +259,102 @@ def _remove_quotes(value): | |||
return value | |||
|
|||
|
|||
def _get_requestmode_info(interface): | |||
def _load_config(section, options, default_value='', file=INI_FILE): | |||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is picky, but can you use single quotes for docstrings? That's how we like them in Salt. :)
salt/modules/nilrt_ip.py
Outdated
''' | ||
Enable the specified interface | ||
def _change_state(interface, new_state): | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single quotes here, too.
salt/modules/nilrt_ip.py
Outdated
|
||
|
||
def _restart(interface): | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here. :)
20210cb
to
7cd5543
Compare
Signed-off-by: Alexandru Vasiu <alexandru.vasiu@ni.com>
7cd5543
to
a429ef8
Compare
@rares-pop How does this look to you now? |
@rallytime - the code looks good and works correctly. In the near future we'll replace the _save_config to use the ConfigParser as opposed to a binary that's saving the things in the ini.. It's fine to leave it in a separate commit since it's not critical by any means and we have to check that the ConfigParser is 'thread-safe' in terms of not corrupting the ini file when called multiple times from multiple processes. |
@alexvasiu There's one lint error that needs to be fixed here: https://jenkinsci.saltstack.com/job/pr-lint/job/PR-48617/10/ |
Signed-off-by: Alexandru Vasiu <alexandru.vasiu@ni.com>
e54d761
to
354e664
Compare
@rallytime Fixed UPDATE: Lint failed because of |
The possibilities for adapter mode are:
TCP/IP
,EhterCAT
andDisabled
.Signed-off-by: Alexandru Vasiu alexandru.vasiu@ni.com
Signed-off-by: Ovidiu-Adrian Vancea ovidiu.vancea@ni.com
read_file is available only since python 3.2 so readfp should
be used instead
Signed-off-by: Alexandru Vasiu alexandru.vasiu@ni.com