Here is how to make Juju charm working on CentOS7

fengxia fxia1 at lenovo.com
Mon May 22 02:34:17 UTC 2017


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
fxia1 at lenovo.com
  	
Lenovo.com
Twitter | Facebook | Instagram | Blogs | Forums

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/juju/attachments/20170521/c0ac17d9/attachment.html>


More information about the Juju mailing list