Merge lp:~adalbas/ibmcharms/gpfs-config into lp:ibmcharms

Proposed by Adalberto Medeiros
Status: Merged
Merged at revision: 27
Proposed branch: lp:~adalbas/ibmcharms/gpfs-config
Merge into: lp:ibmcharms
Diff against target: 482 lines (+167/-64)
10 files modified
charms/trusty/gpfs/README.md (+5/-1)
charms/trusty/gpfs/config.yaml (+6/-0)
charms/trusty/gpfs/hooks/common-relation-changed (+5/-3)
charms/trusty/gpfs/hooks/common-relation-joined (+6/-3)
charms/trusty/gpfs/hooks/config-changed (+35/-2)
charms/trusty/gpfs/hooks/gpfshooklib.py (+90/-12)
charms/trusty/gpfs/hooks/install (+18/-42)
charms/trusty/gpfs/hooks/start (+1/-0)
charms/trusty/gpfs/hooks/stop (+1/-0)
charms/trusty/gpfs/tests/10-deploy (+0/-1)
To merge this branch: bzr merge lp:~adalbas/ibmcharms/gpfs-config
Reviewer Review Type Date Requested Status
Michael Chase-Salerno Approve
Review via email: mp+251319@code.launchpad.net

Description of the change

Add install to gpfshooklib.py
Add config-changed. Installation is done here if gpfs_url was not set before.
Add unit test. Still not fully tested

To post a comment you must log in.
Revision history for this message
Michael Chase-Salerno (mcs-chasal) wrote :

Looks good to me.

review: Approve
lp:~adalbas/ibmcharms/gpfs-config updated
27. By Adalberto Medeiros

Changes on installation for config-changed

28. By Adalberto Medeiros

Merge with dnsfixes

29. By Adalberto Medeiros

Fix pep8

30. By Adalberto Medeiros

merge tests

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'charms/trusty/gpfs/README.md'
--- charms/trusty/gpfs/README.md 2015-01-27 12:40:23 +0000
+++ charms/trusty/gpfs/README.md 2015-03-09 15:35:58 +0000
@@ -30,13 +30,17 @@
30Configure config.yaml with the repository url30Configure config.yaml with the repository url
3131
32 gpfs_url: "http://<server-name>/debs/gpfs4.1"32 gpfs_url: "http://<server-name>/debs/gpfs4.1"
33 **Packages.gz should be on the same directory as the packages. The install hook will add Linux/x86_64 to the URL33 **Packages.gz should be on the same directory as the packages. The install hook will add Linux/x86_64 to the URL**
3434
35You can also set gpfs_url with "juju set" after deploy the charm
35## Deploy36## Deploy
3637
37 juju deploy gpfs gpfs-manager38 juju deploy gpfs gpfs-manager
38 juju deploy gpfs gpfs-client39 juju deploy gpfs gpfs-client
3940
41 # If gpfs_url is not set
42 juju set gpfs-manager gpfs_url="http://<server-name>/debs/gpfs4.1"
43
40 juju add relation gpfs-manager:manager gpfs-client:client44 juju add relation gpfs-manager:manager gpfs-client:client
4145
42# Configuration46# Configuration
4347
=== modified file 'charms/trusty/gpfs/config.yaml'
--- charms/trusty/gpfs/config.yaml 2015-01-27 12:19:54 +0000
+++ charms/trusty/gpfs/config.yaml 2015-03-09 15:35:58 +0000
@@ -11,3 +11,9 @@
11 type: string11 type: string
12 default: "4.1"12 default: "4.1"
13 description: "Version of GPFS"13 description: "Version of GPFS"
14 quorum:
15 type: string
16 default: "quorum"
17 description: >
18 Designation for nodes. Values can be quorum,
19 non-quorum or empty string (this assumes non-quorum)
1420
=== modified file 'charms/trusty/gpfs/hooks/common-relation-changed'
--- charms/trusty/gpfs/hooks/common-relation-changed 2015-03-03 17:57:57 +0000
+++ charms/trusty/gpfs/hooks/common-relation-changed 2015-03-09 15:35:58 +0000
@@ -24,13 +24,15 @@
24 rlhn = hookenv.relation_get(attribute='lhostname', unit=runit, rid=relid)24 rlhn = hookenv.relation_get(attribute='lhostname', unit=runit, rid=relid)
25 llhn = socket.getfqdn()25 llhn = socket.getfqdn()
26 if not rlhn is None:26 if not rlhn is None:
27 gpfshooklib.chk_dns(rlhn,rip)27 gpfshooklib.chk_dns(rlhn, rip)
2828
29 if hookname == "client-relation-changed":29 if hookname == "client-relation-changed":
30 # Save the keypair from the manager30 # Save the keypair from the manager
31 log("Copying keys to client")31 log("Copying keys to client")
32 pubkey = hookenv.relation_get(attribute='pubkey', unit=runit, rid=relid)32 pubkey = hookenv.relation_get(attribute='pubkey', unit=runit,
33 privkey = hookenv.relation_get(attribute='privkey', unit=runit, rid=relid)33 rid=relid)
34 privkey = hookenv.relation_get(attribute='privkey', unit=runit,
35 rid=relid)
34 gpfshooklib.set_ssh_key(pubkey, private=False)36 gpfshooklib.set_ssh_key(pubkey, private=False)
35 gpfshooklib.set_ssh_key(privkey, private=True)37 gpfshooklib.set_ssh_key(privkey, private=True)
36 if hookname == "manager-relation-changed" and not rlhn is None:38 if hookname == "manager-relation-changed" and not rlhn is None:
3739
=== modified file 'charms/trusty/gpfs/hooks/common-relation-joined'
--- charms/trusty/gpfs/hooks/common-relation-joined 2015-03-03 17:57:57 +0000
+++ charms/trusty/gpfs/hooks/common-relation-joined 2015-03-09 15:35:58 +0000
@@ -12,6 +12,7 @@
12)12)
1313
14log = hookenv.log14log = hookenv.log
15config = hookenv.config()
1516
1617
17def main():18def main():
@@ -34,11 +35,13 @@
34 })35 })
35 if hookname == "client-relation-joined":36 if hookname == "client-relation-joined":
36 # Set the node designation values and hostname37 # Set the node designation values and hostname
38 quorum = gpfshooklib.validate_quorum(config.get('quorum'))
37 hookenv.relation_set(hookenv.relation_id(), {39 hookenv.relation_set(hookenv.relation_id(), {
38 'quorum': 'quorum',40 'hostname': socket.gethostname(),
41 'quorum': quorum,
39 'client': 'client'42 'client': 'client'
40 }) 43 })
41 44
42 # Configure sshd to allow root ssh45 # Configure sshd to allow root ssh
43 # Avoid the host key confirmation (all relation-joined)46 # Avoid the host key confirmation (all relation-joined)
44 gpfshooklib.configure_ssh()47 gpfshooklib.configure_ssh()
4548
=== modified file 'charms/trusty/gpfs/hooks/config-changed'
--- charms/trusty/gpfs/hooks/config-changed 2015-01-21 19:48:09 +0000
+++ charms/trusty/gpfs/hooks/config-changed 2015-03-09 15:35:58 +0000
@@ -9,8 +9,7 @@
9 hookenv,9 hookenv,
10 host,10 host,
11)11)
1212import gpfshooklib
13#from start import start
1413
15hooks = hookenv.Hooks()14hooks = hookenv.Hooks()
16log = hookenv.log15log = hookenv.log
@@ -22,15 +21,49 @@
22def config_changed():21def config_changed():
23 config = hookenv.config()22 config = hookenv.config()
2423
24 install_bool = False
25 for key in config:25 for key in config:
26 if config.changed(key):26 if config.changed(key):
27 log("config['{}'] changed from {} to {}".format(27 log("config['{}'] changed from {} to {}".format(
28 key, config.previous(key), config[key]))28 key, config.previous(key), config[key]))
29 if key in ['gpfs_url', 'version', 'update']:
30 install_bool = True
31
32 # If installation configuration has changed, reinstall gpfs
33 log("Installation: %s" % install_bool)
34 gpfs_url = config['gpfs_url']
35 version = config['version']
36 update = config['update']
37
38 # exit if there is no source
39 gpfshooklib.check_empty_source(gpfs_url)
40 # If source changed, install packages from new source
41 if install_bool:
42 install_gpfs(gpfs_url, version, update)
43
44 # if quorum changed, change node designation
45 if config.changed('quorum'):
46 unit = hookenv.local_unit()
47 quorum = config.get('quorum')
48 change_node_designation(unit, quorum)
2949
30 config.save()50 config.save()
31 #start.start()51 #start.start()
3252
3353
54def install_gpfs(gpfs_url, version, update):
55 # install gpfs
56
57 gpfshooklib.gpfs_install(gpfs_url, version)
58 gpfshooklib.gpfs_install_updates(gpfs_url, version, update)
59 gpfshooklib.build_modules()
60
61
62def change_node_designation(unit, quorum='quorum'):
63 # TODO, change unit designation to quorum or non-quorum
64 pass
65
66
34if __name__ == "__main__":67if __name__ == "__main__":
35 # execute a hook based on the name the program is called by68 # execute a hook based on the name the program is called by
36 hooks.execute(sys.argv)69 hooks.execute(sys.argv)
3770
=== modified file 'charms/trusty/gpfs/hooks/gpfshooklib.py'
--- charms/trusty/gpfs/hooks/gpfshooklib.py 2015-03-03 17:57:57 +0000
+++ charms/trusty/gpfs/hooks/gpfshooklib.py 2015-03-09 15:35:58 +0000
@@ -7,24 +7,75 @@
7import tempfile7import tempfile
8import socket8import socket
9from shlex import split9from shlex import split
10import subprocess
10from subprocess import (11from subprocess import (
11 call,12 call,
12 check_call,13 check_call,
13 check_output14 check_output,
15 Popen,
16 CalledProcessError
14)17)
1518
16sys.path.insert(0, os.path.join(os.environ['CHARM_DIR'], 'lib'))19sys.path.insert(0, os.path.join(os.environ['CHARM_DIR'], 'lib'))
1720
21from charmhelpers import fetch
18from charmhelpers.core import (22from charmhelpers.core import (
19 hookenv,23 hookenv,
20)24)
21log = hookenv.log25log = hookenv.log
2226
27GPFS_PATH = '/Linux/x86_64'
28
29
23def add_to_path(p, new):30def add_to_path(p, new):
24 return p if new in p.split(':') else p + ':' + new31 return p if new in p.split(':') else p + ':' + new
2532
26os.environ['PATH'] = add_to_path(os.environ['PATH'], '/usr/lpp/mmfs/bin')33os.environ['PATH'] = add_to_path(os.environ['PATH'], '/usr/lpp/mmfs/bin')
2734
35
36## installation methods ##
37def _get_source(url, source_dir=""):
38 return "deb %s%s ./" % (url, source_dir)
39
40
41def check_empty_source(gpfs_url):
42 # Check if there is a repository to install from
43 # TODO: check if packages are already installed
44 if not gpfs_url:
45 log("No GPFS source available. Use juju set gpfs gpfs_url=<url> "
46 "to install packages. See README for more info.", log.ERROR)
47 sys.exit(0)
48
49
50def gpfs_install(url, version):
51 # install main gpfs packages
52 gpfs_source = _get_source(url, source_dir=GPFS_PATH)
53 log('Gpfs source' + gpfs_source)
54
55 # Add gpfs source and update apt
56 fetch.add_source(gpfs_source)
57 try:
58 fetch.apt_update(fatal=True)
59 # Install gpfs packages
60 fetch.apt_install("gpfs*", options=["--allow-unauthenticated"],
61 fatal=True)
62 except CalledProcessError:
63 #TODO: verify source was configured correctly
64 raise
65
66
67def gpfs_install_updates(url, version, update=True):
68 # install update packages (patches), if given
69 if update:
70 log('Applying patches')
71 source_dir = '/gpfs' + version + '_patches' + GPFS_PATH
72 patch_source = _get_source(url, source_dir=source_dir)
73 fetch.add_source(patch_source)
74 fetch.apt_update(fatal=True)
75 fetch.apt_install("gpfs*", options=["--allow-unauthenticated"],
76 fatal=True)
77
78
28## ssh key methods ##79## ssh key methods ##
29def create_ssh_keys():80def create_ssh_keys():
30 # Generate ssh keys if needed81 # Generate ssh keys if needed
@@ -34,7 +85,8 @@
34 # Ensure permissions are good85 # Ensure permissions are good
35 os.chmod('/root/.ssh/id_rsa.pub', 0600)86 os.chmod('/root/.ssh/id_rsa.pub', 0600)
36 os.chmod('/root/.ssh/id_rsa', 0600)87 os.chmod('/root/.ssh/id_rsa', 0600)
37 88
89
38def get_ssh_keys():90def get_ssh_keys():
39 # get public and private ssh keys91 # get public and private ssh keys
40 with open("/root/.ssh/id_rsa.pub", "r") as idfile:92 with open("/root/.ssh/id_rsa.pub", "r") as idfile:
@@ -48,9 +100,10 @@
48 idfile.close()100 idfile.close()
49 return [privkey, pubkey]101 return [privkey, pubkey]
50102
103
51def set_ssh_key(key, private=False):104def set_ssh_key(key, private=False):
52 if key:105 if key:
53 if private == False:106 if private is False:
54 f = open("/root/.ssh/id_rsa.pub", "w")107 f = open("/root/.ssh/id_rsa.pub", "w")
55 f.write(key)108 f.write(key)
56 f.close()109 f.close()
@@ -65,6 +118,7 @@
65 f.close()118 f.close()
66 os.chmod('/root/.ssh/id_rsa', 0600)119 os.chmod('/root/.ssh/id_rsa', 0600)
67120
121
68def configure_ssh():122def configure_ssh():
69 # Configure sshd_config file to allow root123 # Configure sshd_config file to allow root
70 sshconf = open("/etc/ssh/sshd_config", 'r')124 sshconf = open("/etc/ssh/sshd_config", 'r')
@@ -91,53 +145,78 @@
91 idfile.write("StrictHostKeyChecking no\n")145 idfile.write("StrictHostKeyChecking no\n")
92 idfile.close()146 idfile.close()
93147
148
149## Other utility methods##
150def validate_quorum(quorum):
151 valid_values = ['', 'quorum', 'non-quorum']
152 return quorum if quorum in valid_values else ''
153
154
94## cluster management methods ##155## cluster management methods ##
156def build_modules():
157# build binary gpfs modules after installation
158 try:
159 check_call(["mmbuildgpl"])
160 except CalledProcessError:
161 log('mmbuildgpl was not executed', level=hookenv.WARNING)
162 except OSError:
163 log('mmbuildgpl not found/installed')
164
95165
96def start():166def start():
97 # Only manager can start/stop cluster167 # Only manager can start/stop cluster
98 if is_manager():168 if is_manager():
99 log(check_output(split('mmstartup -a')))169 log(check_output(split('mmstartup -a')))
100170
171
101def stop():172def stop():
102 # stop the server173 # stop the server
103 if is_manager():174 if is_manager():
104 check_output(split('mmshutdown -a'))175 check_output(split('mmshutdown -a'))
105176
177
106def node_exists(nodename):178def node_exists(nodename):
107 # Check if node has already been added to cluster179 # Check if node has already been added to cluster
108 lscluster = check_output('mmlscluster')180 lscluster = check_output('mmlscluster')
109 node = re.search('^.*\d+.*%s.*\n' % nodename, lscluster, re.M)181 node = re.search('^.*\d+.*%s.*\n' % nodename, lscluster, re.M)
110 return False if node is None else True182 return False if node is None else True
111183
184
112def add_node(nodename, m_designation='client', q_designation='nonquorum'):185def add_node(nodename, m_designation='client', q_designation='nonquorum'):
113 # add new node to the cluster186 # add new node to the cluster
114 if cluster_exists() and not node_exists(nodename):187 if cluster_exists() and not node_exists(nodename):
115 log(check_output(split('mmaddnode -N %s:%s-%s' % \188 log(check_output(split('mmaddnode -N %s:%s-%s' %
116 (nodename, m_designation, q_designation))))189 (nodename, m_designation, q_designation))))
117 else:190 else:
118 log('Node %s could not be added. Manager not defined' % nodename)191 log('Node %s could not be added. Manager not defined' % nodename)
119 192
193
120def apply_license(nodename):194def apply_license(nodename):
121 check_output(split('mmchlicense server --accept -N %s' % nodename))195 check_output(split('mmchlicense server --accept -N %s' % nodename))
122196
197
123def set_manager_file():198def set_manager_file():
124 # define a file that indicates the node is a manager199 # define a file that indicates the node is a manager
125 open("/var/mmfs/.manager","a").close()200 open("/var/mmfs/.manager", "a").close()
201
126202
127def is_manager():203def is_manager():
128 # check if the node is a manager204 # check if the node is a manager
129 if os.path.exists("/var/mmfs/.manager"):205 if os.path.exists("/var/mmfs/.manager"):
130 return True206 return True
131207
208
132def cluster_exists():209def cluster_exists():
133 # Check if cluster is already defined210 # Check if cluster is already defined
134 return True if call('mmlscluster') == 0 else False211 return True if call('mmlscluster') == 0 else False
135 212
213
136def create_cluster(hostname):214def create_cluster(hostname):
137 # create the cluster for the hostname, manager only215 # create the cluster for the hostname, manager only
138 if is_manager() and not cluster_exists():216 if is_manager() and not cluster_exists():
139 log(check_output(split('mmcrcluster -N %s:quorum-manager' % \217 log(check_output(split('mmcrcluster -N %s:quorum-manager' %
140 hostname + ' -r /usr/bin/ssh -R /usr/bin/scp')))218 hostname + ' -r /usr/bin/ssh -R /usr/bin/scp')))
219
141220
142def chk_dns(hostname, ip):221def chk_dns(hostname, ip):
143 try:222 try:
@@ -145,6 +224,5 @@
145 except:224 except:
146 log("Hostname not resolving, adding to /etc/hosts")225 log("Hostname not resolving, adding to /etc/hosts")
147 with open("/etc/hosts", "a") as hostfile:226 with open("/etc/hosts", "a") as hostfile:
148 hostfile.write("%s %s\n" % (ip, hostname) )227 hostfile.write("%s %s\n" % (ip, hostname))
149 hostfile.close()228 hostfile.close()
150
151229
=== modified file 'charms/trusty/gpfs/hooks/install'
--- charms/trusty/gpfs/hooks/install 2015-02-09 11:42:31 +0000
+++ charms/trusty/gpfs/hooks/install 2015-03-09 15:35:58 +0000
@@ -11,66 +11,42 @@
11 hookenv,11 hookenv,
12)12)
1313
14import gpfshooklib
15
14hooks = hookenv.Hooks()16hooks = hookenv.Hooks()
15log = hookenv.log17log = hookenv.log
16config = hookenv.config()18config = hookenv.config()
1719
18SERVICE = 'gpfs'20# development packages needed to build kernel modules for GPFS cluster
19
20PREREQS = ["ksh", "binutils", "m4", "libaio1", "g++", "cpp", "make", "gcc"]21PREREQS = ["ksh", "binutils", "m4", "libaio1", "g++", "cpp", "make", "gcc"]
21# TODO: gpfs.msg.en_us - change it to any language22
22GPFS_PKGS = ["gpfs.base", "gpfs.crypto", "gpfs.docs", "gpfs.ext",
23 "gpfs.gpl", "gpfs.gski", "gpfs.msg.en_us"]
24GPFS_PATH = '/Linux/x86_64'
2523
26@hooks.hook('install')24@hooks.hook('install')
27def install():25def install():
28 log('Installing gpfs')26 log('Installing gpfs')
2927
30 # Things that need to happen here28 # Things that need to happen here
31 # Fetch GPFS packages from user given location?
32 gpfs_url = config.get('gpfs_url')29 gpfs_url = config.get('gpfs_url')
33 version = config.get('version')30 version = config.get('version')
34 update = config.get('update') # boolean value whether to apply patches31 update = config.get('update') # boolean value whether to apply patches
3532
36 gpfs_source = get_source(gpfs_url, source_dir=GPFS_PATH) 33 # install kernel prereq and other prereqs
37 log('Gpfs source' + gpfs_source)
38
39 # Add gpfs source and update apt
40 fetch.add_source(gpfs_source)
41 fetch.apt_update()
42 # Apt install prereqs
43 fetch.apt_install(PREREQS)
44 # install kernel prereq
45 linux_headers = "linux-headers-%s" % get_kernel_version()34 linux_headers = "linux-headers-%s" % get_kernel_version()
46 fetch.apt_install(linux_headers) 35 fetch.apt_install(PREREQS + [linux_headers])
4736
48 # Install gpfs packages37 if gpfs_url == "":
49 fetch.apt_install("gpfs*", options=["--allow-unauthenticated"])38 log("""No GPFS source packages. Use juju set gpfs gpfs_url=<url>
5039 to install packages. See README for more info""",
51 # Apply patch packages40 level=hookenv.ERROR)
52 if update:41 sys.exit(0)
53 log('Applying patches')42
54 source_dir = '/gpfs' + version + '_patches' + GPFS_PATH43 gpfshooklib.gpfs_install(gpfs_url, version)
55 patch_source = get_source(gpfs_url, source_dir=source_dir)44 gpfshooklib.gpfs_install_updates(gpfs_url, version, update)
56 fetch.add_source(patch_source)45 gpfshooklib.build_modules()
57 fetch.apt_update()46
58 fetch.apt_install("gpfs*", options=["--allow-unauthenticated"])
59
60 # Build binary modules
61 os.environ['PATH'] += (':/usr/lpp/mmfs/bin')
62 try:
63 subprocess.check_call(["mmbuildgpl"])
64 except subprocess.CalledProcessError:
65 log('mmbuildgpl was not executed', level=hookenv.WARNING)
66 except OSError:
67 log('mmbuildgpl not found/installed')
68
69def get_source(url, source_dir=""):
70 return "deb %s%s ./" % (url,source_dir)
7147
72def get_kernel_version():48def get_kernel_version():
73 return subprocess.check_output(['uname','-r']).strip()49 return subprocess.check_output(['uname', '-r']).strip()
7450
75if __name__ == "__main__":51if __name__ == "__main__":
76 # execute a hook based on the name the program is called by52 # execute a hook based on the name the program is called by
7753
=== modified file 'charms/trusty/gpfs/hooks/start'
--- charms/trusty/gpfs/hooks/start 2015-02-10 02:11:55 +0000
+++ charms/trusty/gpfs/hooks/start 2015-03-09 15:35:58 +0000
@@ -15,6 +15,7 @@
15hooks = hookenv.Hooks()15hooks = hookenv.Hooks()
16log = hookenv.log16log = hookenv.log
1717
18
18@hooks.hook('start')19@hooks.hook('start')
19def start():20def start():
20 log("Starting cluster (manager only)")21 log("Starting cluster (manager only)")
2122
=== modified file 'charms/trusty/gpfs/hooks/stop'
--- charms/trusty/gpfs/hooks/stop 2015-02-10 02:11:55 +0000
+++ charms/trusty/gpfs/hooks/stop 2015-03-09 15:35:58 +0000
@@ -14,6 +14,7 @@
14hooks = hookenv.Hooks()14hooks = hookenv.Hooks()
15log = hookenv.log15log = hookenv.log
1616
17
17@hooks.hook('stop')18@hooks.hook('stop')
18def stop():19def stop():
19 gpfshooklib.stop()20 gpfshooklib.stop()
2021
=== modified file 'charms/trusty/gpfs/tests/10-deploy'
--- charms/trusty/gpfs/tests/10-deploy 2015-03-09 15:24:07 +0000
+++ charms/trusty/gpfs/tests/10-deploy 2015-03-09 15:35:58 +0000
@@ -25,7 +25,6 @@
2525
26unit_manager_0 = d.sentry.unit['gpfs/0']26unit_manager_0 = d.sentry.unit['gpfs/0']
27unit_client_0 = d.sentry.unit['gpfs-client/0']27unit_client_0 = d.sentry.unit['gpfs-client/0']
28
29print(unit_manager_0.info)28print(unit_manager_0.info)
3029
31# verify unit_manager is manager30# verify unit_manager is manager

Subscribers

People subscribed via source and target branches