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

Add network configuration check and report to ros2doctor #319

Merged
merged 11 commits into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ros2doctor/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<depend>ros2cli</depend>

<exec_depend>python3-numpy</exec_depend>
<exec_depend>ifcfg_vendor</exec_depend>
<exec_depend>python3-rosdistro-modules</exec_depend>

<test_depend>ament_copyright</test_depend>
Expand Down
20 changes: 20 additions & 0 deletions ros2doctor/ros2doctor/api/format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2019 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


def print_term(k, v):
"""Print term only if it exists."""
if v:
# TODO(clairewang): 20 padding needs to be dynamically set
print('{:20}: {}'.format(k, v))
60 changes: 60 additions & 0 deletions ros2doctor/ros2doctor/api/network.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright 2019 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys

import ifcfg

from ros2doctor.api.format import print_term


def _is_unix_like_platform():
"""Return True if conforms to UNIX/POSIX-style APIs."""
return os.name == 'posix'


def check_network_config_helper():
"""Check if loopback and multicast IP addresses are found."""
has_loopback, has_non_loopback, has_multicast = False, False, False
for name, iface in ifcfg.interfaces().items():
flags = iface.get('flags')
if 'LOOPBACK' in flags:
has_loopback = True
else:
has_non_loopback = True
if 'MULTICAST' in flags:
has_multicast = True
return has_loopback, has_non_loopback, has_multicast


def check_network_config():
"""Conduct network checks and output error/warning messages."""
has_loopback, has_non_loopback, has_multicast = check_network_config_helper()
if not has_loopback:
sys.stderr.write('ERROR: No loopback IP address is found.\n')
if not has_non_loopback:
sys.stderr.write('WARNING: Only loopback IP address is found.\n')
if not has_multicast:
sys.stderr.write('WARNING: No multicast IP address is found.\n')
return has_loopback and has_non_loopback and has_multicast


def print_network():
"""Print all system and ROS network information."""
print('NETWORK CONFIGURATION')
for name, iface in ifcfg.interfaces().items():
for k, v in iface.items():
print_term(k, v)
print('\n')
50 changes: 26 additions & 24 deletions ros2doctor/ros2doctor/api/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import platform
import sys

from ros2doctor.api.format import print_term

import rosdistro


Expand All @@ -24,37 +26,38 @@ def print_platform_info():
platform_name = platform.system()
# platform info
print('PLATFORM INFORMATION')
print('system : ', platform_name)
print('Platform Info : ', platform.platform())
print_term('system', platform_name)
print_term('platform info', platform.platform())
if platform_name == 'Darwin':
print('Mac OS version : ', platform.mac_ver())
print('release : ', platform.release())
print('processor : ', platform.processor())
print_term('mac OS version', platform.mac_ver())
print_term('release', platform.release())
print_term('processor', platform.processor())

# python info
print('PYTHON INFORMATION')
print('version : ', platform.python_version())
print('compiler : ', platform.python_compiler())
print('build : ', platform.python_build())
print_term('version', platform.python_version())
print_term('compiler', platform.python_compiler())
print_term('build', platform.python_build())
Copy link
Contributor

Choose a reason for hiding this comment

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

This is definitely an improvement. I still think it would be good if the reports just returned information and the command was responsible for outputting it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking about making that change as a feature in the next PR. Like you suggested last time, I'd like to add arguments like --report_all or --report_failed to let users control what they would like to see based on the check results.

print('\n')


def check_platform_helper():
"""Check ROS_DISTRO related environment variables and distribution name."""
distro_name = os.environ.get('ROS_DISTRO')
if not distro_name:
sys.stderr.write('WARNING: ROS_DISTRO is not set.')
sys.stderr.write('WARNING: ROS_DISTRO is not set.\n')
return
else:
distro_name = distro_name.lower()
u = rosdistro.get_index_url()
if not u:
sys.stderr.write('WARNING: Unable to access ROSDISTRO_INDEX_URL\
or DEFAULT_INDEX_URL.')
sys.stderr.write('WARNING: Unable to access ROSDISTRO_INDEX_URL '
'or DEFAULT_INDEX_URL.\n')
return
i = rosdistro.get_index(u)
distro_info = i.distributions.get(distro_name)
if not distro_info:
sys.stderr.write("WARNING: Distribution name '%s' is not found" % distro_name)
sys.stderr.write("WARNING: Distribution name '%s' is not found\n" % distro_name)
return
distro_data = rosdistro.get_distribution(i, distro_name).get_data()
return distro_name, distro_info, distro_data
Expand All @@ -68,10 +71,11 @@ def print_ros2_info():
distro_name, distro_info, distro_data = distros

print('ROS INFORMATION')
print('distribution name : ', distro_name)
print('distribution type : ', distro_info.get('distribution_type'))
print('distribution status : ', distro_info.get('distribution_status'))
print('release platforms : ', distro_data.get('release_platforms'))
print_term('distribution name', distro_name)
print_term('distribution type', distro_info.get('distribution_type'))
print_term('distribution status', distro_info.get('distribution_status'))
print_term('release platforms', distro_data.get('release_platforms'))
print('\n')


def check_platform():
Expand All @@ -84,15 +88,13 @@ def check_platform():

# check distro status
if distro_info.get('distribution_status') == 'prerelease':
sys.stderr.write('WARNING: Distribution is not fully supported or tested.\
To get more stable features,\
Download a stable version at\
https://index.ros.org/doc/ros2/Installation/')
sys.stderr.write('WARNING: Distribution is not fully supported or tested. '
'To get more stable features, download a stable version at '
'https://index.ros.org/doc/ros2/Installation/\n')
elif distro_info.get('distribution_status') == 'end-of-life':
sys.stderr.write('WARNING: Distribution is no longer supported or deprecated.\
To get the latest features,\
Download the latest version at\
https://index.ros.org/doc/ros2/Installation/')
sys.stderr.write('WARNING: Distribution is no longer supported or deprecated. '
'To get the latest features, download the latest version at '
'https://index.ros.org/doc/ros2/Installation/')
else:
passed = True
return passed
2 changes: 1 addition & 1 deletion ros2doctor/ros2doctor/command/doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ def main(self, *, parser, args):


class WtfCommand(DoctorCommand):
"""Add `wtf` as alias to `doctor`."""
"""Use `wtf` as alias to `doctor`."""

pass
2 changes: 2 additions & 0 deletions ros2doctor/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
],
'ros2doctor.checks': [
'check_platform = ros2doctor.api.platform:check_platform',
'check_network_config = ros2doctor.api.network:check_network_config',
],
'ros2doctor.report': [
'report_platform = ros2doctor.api.platform:print_platform_info',
'report_ros_distro = ros2doctor.api.platform:print_ros2_info',
'report_network_config = ros2doctor.api.network:print_network',
],
}
)