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

When MacOS is updated from Homebrew any Python2 YDK application fails #837

Closed
ygorelik opened this issue Nov 6, 2018 · 4 comments
Closed
Labels
documentation installation Mac Issues that appear specifically on Mac platform python
Milestone

Comments

@ygorelik
Copy link
Collaborator

ygorelik commented Nov 6, 2018

Current Behavior

When MacOS is updated from Homebrew, which is normal and expected behavior, any run of YDK Python2 based application fails with error:

Fatal Python error: PyThreadState_Get: no current thread

This is known and well documented issue, which has few suggested workaround processes. These solution must be tested on MacOS platform and well documented in YDK documentation along with suggested workaround.

The symptoms and workaround are also documented here.

Steps to Reproduce

Update MacOS from Homebrew using command:

$ brew update

Install ydk and IOS XR bundle:

$ pip install ydk
$ pip install ydk-models-cisco-ios-xr

Copy hello-ydk.py from below and try to run it:

$ python  hello-ydk.py

Observe the error.

Your script

# import providers, services and models
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_shellutil_oper as xr_shellutil_oper
from datetime import timedelta

def enable_logging(level):
    import logging
    log = logging.getLogger('ydk')
    log.setLevel(level)
    handler = logging.StreamHandler()
    formatter = logging.Formatter(("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
    handler.setFormatter(formatter)
    log.addHandler(handler)

if __name__ == "__main__":
    """Main execution path"""

    enable_logging(logging.INFO)
    
    # create NETCONF session
    provider = NetconfServiceProvider(address="192.168.122.169",
                                      port=830,
                                      username="admin",
                                      password="admin",
                                      protocol="ssh")
    # create CRUD service
    crud = CRUDService()

    # create system time object
    system_time = xr_shellutil_oper.SystemTime()

    # read system time from device
    system_time = crud.read(provider, system_time)

    # print system uptime
    print("System uptime is " +
          str(timedelta(seconds=system_time.uptime.uptime)))

    exit()

Logs

ANTHONYP-M-K0ZN:ydk-py-samples anthonyp$ ./hello-ydk.py 
Fatal Python error: PyThreadState_Get: no current thread
Abort trap: 6

System Information

YDK-0.7.3 + cisco-ios-xr bundle

@ygorelik ygorelik added documentation installation python Mac Issues that appear specifically on Mac platform labels Nov 6, 2018
@ghost
Copy link

ghost commented Jan 28, 2019

To fix this run the below commands:

pip uninstall ydk
export CMAKE_LIBRARY_PATH=/Library/Frameworks/Python.framework/Versions/2.7/lib/
pip install ydk

The issue is caused because macOS comes with a default python 2.7 library installed under /System. We need to link to the python 2.7 library under /System when building ydk

 cd /
/ > locate libpython2.7.dylib
/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib # Library we want to link to
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config/libpython2.7.dylib

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib # Default python installation we don't want to link to
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config/libpython2.7.dylib
/usr/lib/libpython2.7.dylib # Links to default python installation

/> ls -l /usr/lib/libpython2.7.dylib
lrwxr-xr-x  1 root  wheel  68 Nov 20 18:43 /usr/lib/libpython2.7.dylib@ -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/Python

@ghost
Copy link

ghost commented Mar 5, 2019

Need to add update the documentation and add it to Travis run

@ghost ghost modified the milestones: 0.8.3, 0.8.2 Mar 5, 2019
@ygorelik
Copy link
Collaborator Author

ygorelik commented Mar 11, 2019

The approach above did not work on MacOS virtual machine.
Another approach assumes use of Python2 virtual environment. To install and create virtual environment::

sudo pip install virtualenv virtualenvwrapper
source /usr/local/bin/virtualenvwrapper.sh
mkvirtualenv -p python2 ydk_venv
cd ydk-py
pip install -r requirements.txt
deactivate

To activate virtual environment::

source ~/.virtualenvs/ydk_venv/bin/activate

This approach is tested and proven to work in Mac VM. But it fails in Travis tests with intermittent segmentation fault.

ygorelik pushed a commit to ygorelik/ydk-gen that referenced this issue Mar 12, 2019
@ygorelik
Copy link
Collaborator Author

The following section was added to ydk-gen and ydk-py documentation:

Mac OS
======

The developers of Python2 on Mac OS might face an issue ([#837](https://github.com/CiscoDevNet/ydk-gen/issues/837)). 
This is well known and documented issue. Each developer might have different approaches for its resolution. 
One of them is to use Python2 virtual environment. See section below for details.

In addition it is required properly set CMAKE_LIBRARY_PATH environment variable to assure that `cmake` uses correct Python library. 
Follow these steps to find and set correct library path.

1. Find installations of `libpython2.7` library:

  locate libpython2.7.dylib
  
Example:

  $ locate libpython2.7.dylib
  /System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib
  /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config/libpython2.7.dylib
  /usr/lib/libpython2.7.dylib
  /usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib
  /usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config/libpython2.7.dylib
  
2. Choose non-system Python library installation and set CMAKE_LIBRARY_PATH before any YDK component installation. Example:

  export CMAKE_LIBRARY_PATH=/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib

3. Run YDK core package installation with '-v' flag to check that `PythonLibs` points to correct library path. Example:

  $ ./generate.py --core
  $ pip install -v gen-api/python/ydk/dist/ydk*.tar.gz
  
  # In 'cmake' log look for 'PythonLibs' and 'found version' setting
  -- Found PythonLibs: /usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib (found version "2.7.15")

4. Finally test you YDK core library installation from CLI, making sure there are no errors:

  $ python -c "import ydk.types"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation installation Mac Issues that appear specifically on Mac platform python
Projects
None yet
Development

No branches or pull requests

1 participant