Juju,

As part of my research of juju charms, we have a requirement to make charm compatible with Centos7 and RHEL. However, charm is now using Python3 (in some places) and it will fail at "import yum" on CentOS7. I have googled it for a few days now and there is limited information on how to resolve. this.

So to make things simpler (or more complicated down the road?), I have decided to make a Python2-compatible charm. Be warned this is currently as a quick hack that I just put together yesterday and proved working. I will produce a better documentation later. But for ppl who are in this same boat, this may save your headaches or ease your concerns knowing that there is a way to "work around".

Objective: Build a Python2 compatible charm that includes layer-basic to run on centos7

Two dists: test1 is from default "charm build -s centos7", test25 is modified build.

What to modify:

1. Anywhere you see /usr/bin/python3, change to /usr/bin/python. Most of these are in /hooks.

2. Add a blank "__init__.py" in /lib/charms. Python2 module search path differently from python3.

3. charmhelpers: yes you have to make a modification in charmhelpers: /usr/lib/python2.7/site-packages/charmhelpers/fetch/__init__.py.

*if __platform__ == "ubuntu":
    apt_cache = fetch.apt_cache
    apt_install = fetch.install
    apt_update = fetch.update
    apt_upgrade = fetch.upgrade
    apt_purge = fetch.purge
    apt_mark = fetch.apt_mark
    apt_hold = fetch.apt_hold
    apt_unhold = fetch.apt_unhold
    get_upstream_version = fetch.get_upstream_version
elif __platform__ == "centos":
    yum_search = fetch.yum_search

    # FENG: centos mapping
    apt_install = fetch.install
    apt_upgrade = fetch.upgrade
    apt_update = fetch.update
    apt_purge = fetch.purge
    apt_cache = fetch.yum_search
*

4. charms.reactive: yes you need to modify this too. Only one place, charms.reactive-0.4.7/charms/reactive/relations.py:

class RelationBase(object):
    __metaclass__=AutoAccessors

Now for details of diff of files changed and contents I modified to make this work:

1. Files to modify:

Files test1/bin/layer_option and test25/bin/layer_option differ
Files test1/.build.manifest and test25/.build.manifest differ
Files test1/hooks/config-changed and test25/hooks/config-changed differ
Files test1/hooks/hook.template and test25/hooks/hook.template differ
Files test1/hooks/install and test25/hooks/install differ
Files test1/hooks/leader-elected and test25/hooks/leader-elected differ
Files test1/hooks/leader-settings-changed and test25/hooks/leader-settings-changed differ
Files test1/hooks/start and test25/hooks/start differ
Files test1/hooks/stop and test25/hooks/stop differ
Files test1/hooks/update-status and test25/hooks/update-status differ
Files test1/hooks/upgrade-charm and test25/hooks/upgrade-charm differ
Files test1/layer.yaml and test25/layer.yaml differ
Only in test25/lib/charms: __init__.py
Files test1/lib/charms/layer/basic.py and test25/lib/charms/layer/basic.py differ
Only in test25/lib/charms/layer: basic.py.old
Files test1/lib/charms/layer/execd.py and test25/lib/charms/layer/execd.py differ
Files test1/metadata.yaml and test25/metadata.yaml differ
Files test1/wheelhouse/charmhelpers-0.15.0.tar.gz and test25/wheelhouse/charmhelpers-0.15.0.tar.gz differ Files test1/wheelhouse/charms.reactive-0.4.7.tar.gz and test25/wheelhouse/charms.reactive-0.4.7.tar.gz differ

2. File contents diff:

diff -r test1/bin/layer_option test25/bin/layer_option
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
4c4,5
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/.build.manifest test25/.build.manifest
4c4
<     "test1",
---
>     "test25",
31c31
< "621b556cd208005e131e9f648859294347da9376609745a73ca2e808dd2032f9"
---
> "cf7f9c2bec7447406495c1bec5a549276ff26d9220b5bee3c3994253cad86b3d"
34c34
<       "test1",
---
>       "test25",
89c89
<       "test1",
---
>       "test25",
91c91,96
< "f2986d765f3980311b0064cccebdd9080e218a7c25100ae66d52b78f8fb2243c"
---
> "3d93ebb41e22cd44db352b5d87296a3fd67f5deb87729ee17f8b24b5fcd48955"
>     ],
>     "lib/charms/__init__.py": [
>       "layer:basic",
>       "static",
> "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
101c106,111
< "d09706ef3a224eb60d34366a2867c382791aa30157ab5b77eda37f29731df2e2"
---
> "80389fe735b9d9766515ed36d9134321838fc5bb88c225cdace57a50bbf739e1"
>     ],
>     "lib/charms/layer/basic.py.old": [
>       "layer:basic",
>       "static",
> "0f353699ba6b5213596354add24a7283273a4cee665a1a038556128f3fdd28db"
106c116
< "af1f2409869f990cdb33cffc4120fb6713876e8e680ac5f064ea510bbdca1073"
---
> "b7a88558cfd3511ea1eff0564524d0caef6e16daa5bf12b80f01183a1e73e4ff"
109c119
<       "test1",
---
>       "test25",
111c121
< "a3ff3ba5321d2b502dd1b9454976e62cc4dfc146d36c18626066c1dfc19787eb"
---
> "2949e0b71e303ac97855af82a938207fd3a1d52aee3f87780b5c48910ce1dad8"
119c129
<       "test1",
---
>       "test25",
129c139
<       "test1",
---
>       "test25",
diff -r test1/hooks/config-changed test25/hooks/config-changed
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/hook.template test25/hooks/hook.template
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/install test25/hooks/install
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/leader-elected test25/hooks/leader-elected
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/leader-settings-changed test25/hooks/leader-settings-changed
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/start test25/hooks/start
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/stop test25/hooks/stop
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/update-status test25/hooks/update-status
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
5c5,6
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/hooks/upgrade-charm test25/hooks/upgrade-charm
1c1
< #!/usr/bin/env python3
---
> #!/usr/bin/env python
6c6,7
< sys.path.append('lib')
---
> import os
> sys.path.append(os.path.join(os.getcwd(),'lib'))
diff -r test1/layer.yaml test25/layer.yaml
2d1
<   "test1": {}
3a3
>     "packages": ["git"]
5d4
<     "packages": []
6a6
>   "test25": {}
10c10
< "is": "test1"
---
> "is": "test25"
Only in test25/lib/charms: __init__.py
diff -r test1/lib/charms/layer/basic.py test25/lib/charms/layer/basic.py
52,57c52,76
<         apt_install([
<             'python3-pip',
<             'python3-setuptools',
<             'python3-yaml',
<             'python3-dev',
<         ])
---
>         me = platform.linux_distribution()[0]
>         if 'ubuntu' in me.lower():
>             apt_install([
>                 'python3-pip',
>                 'python3-setuptools',
>                 'python3-yaml',
>                 'python3-dev',
>             ])
>         elif 'cent' in me.lower():
>             # if using python3
>             #apt_install([
>             #    'redhat-lsb-core',
>             #    'python34-setuptools',
>             #    'python34-pip',
>             #    'python34-yaml',
>             #    'python34-devel',
>             #])
>             apt_install([
>                 'redhat-lsb-core',
>                 'python-setuptools',
>                 'python-pip',
>                 'python-yaml',
>                 'python-devel',
>             ])
>
65c84,87
<                 series = lsb_release()['DISTRIB_CODENAME']
---
>                 try:
>                     series = lsb_release()['DISTRIB_CODENAME']
>                 except:
>                     series = 'centos7'
67a90
>                     pip = vpip
69c92,95
<                     apt_install(['virtualenv'])
---
>                     # pip = 'pip3' # if using python3
>                     pip = 'pip'
> check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse','pip'])
>                     check_call([pip, 'install', 'virtualenv'])
75d100
<             pip = vpip
77c102,103
<             pip = 'pip3'
---
>             # pip = 'pip3' # if using python3
>             pip = vpip
84,85c110,113
< check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse',
<                     'pip'])
---
>
>         # TODO: feng
>         pip = 'pip' # this is a hack to use Python2
> check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse','pip'])
87,88c115
< check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse'] +
<                    glob('wheelhouse/*'))
---
> check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse'] + glob('wheelhouse/*'))
114c141,142
<         sys.path.append('lib')
---
>         import os
>         sys.path.append(os.path.join(os.getcwd(),'lib'))
161,164c189
<     elif 'cent' in me.lower():
<         my_cmd = 'yum'
<
<     cmd = [my_cmd,
---
>         cmd = [my_cmd,
167a193,198
>     elif 'cent' in me.lower():
>         my_cmd = 'yum'
>         cmd = [my_cmd,
>            '--assumeyes',
>            'install']
>
Only in test25/lib/charms/layer: basic.py.old
diff -r test1/lib/charms/layer/execd.py test25/lib/charms/layer/execd.py
17a18
> from __future__ import print_function
114,115c115
<             print("ERROR ({}) running {}".format(e.returncode, e.cmd),
<                   file=stderr)
---
> print("ERROR ({}) running {}".format(e.returncode, e.cmd),file=stderr)
diff -r test1/metadata.yaml test25/metadata.yaml
1c1
< "name": "test1"
---
> "name": "test25"
Binary files test1/wheelhouse/charmhelpers-0.15.0.tar.gz and test25/wheelhouse/charmhelpers-0.15.0.tar.gz differ Binary files test1/wheelhouse/charms.reactive-0.4.7.tar.gz and test25/wheelhouse/charms.reactive-0.4.7.tar.gz differ





--
Feng xia
Engineer
Lenovo USA

Phone: 5088011794
fx...@lenovo.com
        
Lenovo.com
Twitter | Facebook | Instagram | Blogs | Forums

-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju

Reply via email to