blob: cc1b474178d2b74234271deb2b2c0303a5bc8cd0 [file] [log] [blame]
Adam Israel50227af2016-10-04 12:07:16 -07001from git import Repo as gitrepo
2from shutil import rmtree
3
4import os
5import subprocess
6
7from charmhelpers.core import host
8from charmhelpers.core import hookenv
9from charmhelpers.core import templating
10from charmhelpers.core.unitdata import kv
11from charmhelpers.core.hookenv import (
12 config,
13 log,
14 open_port,
15 status_set,
16)
17
18from charmhelpers.core.host import (
19 chownr,
20)
21
22from charms.reactive import (
23 when,
24 when_not,
25 set_state,
26 is_state,
27)
28
29kvdb = kv()
30
31INSTALL_PATH = '/opt/openmano'
32USER = 'openmanod'
33
34
35@when('openmano.installed')
36@when('openmano.available')
37def openmano_available(openmano):
38 # TODO make this configurable via charm config
39 openmano.configure(port=9090)
40
41
42@when('openmano.installed')
43@when('db.available', 'db.installed')
44@when('openvim-controller.available')
45@when('openmano.running')
46def openvim_available(openvim, db):
47 for service in openvim.services():
48 for endpoint in service['hosts']:
49 host = endpoint['hostname']
50 port = endpoint['port']
51 user = endpoint['user']
52
53 openvim_uri = '{}:{}'.format(host, port)
54 if kvdb.get('openvim_uri') == openvim_uri:
55 return
56
Adam Israel50227af2016-10-04 12:07:16 -070057 # TODO: encapsulate the logic in create-datacenter.sh into python
58 try:
59 cmd = './scripts/create-datacenter.sh {} {} {} {}'.format(
60 host, port, user, kvdb.get('openmano-tenant'))
61 out, err = _run(cmd)
62 except subprocess.CalledProcessError as e:
63 # Ignore the error if the datacenter already exists.
64 if e.returncode != 153:
65 raise
66
67 kvdb.set('openvim_uri', openvim_uri)
68 if not is_state('db.available'):
69 status_set('waiting', 'Waiting for database')
70 break
71 break
72
73
74@when('openmano.installed')
75@when('db.available', 'db.installed')
76@when('openvim-controller.available')
77@when_not('openmano.running')
78def start(*args):
79 # TODO: if the service fails to start, we should raise an error to the op
80 # Right now, it sets the state as running and the charm dies. Because
81 # service-openmano returns 0 when it fails.
82 cmd = "/home/{}/bin/service-openmano start".format(USER)
83 out, err = _run(cmd)
84
85 if not kvdb.get('openmano-tenant'):
86 out, err = _run('./scripts/create-tenant.sh')
87 kvdb.set('openmano-tenant', out.strip())
88
89 status_set(
90 'active',
91 'Up on {host}:{port}'.format(
92 host=hookenv.unit_public_ip(),
93 port='9090'))
94
95 set_state('openmano.running')
96
97
98@when('openmano.installed')
99@when('db.available')
100@when_not('db.installed')
101def setup_db(db):
102 """Setup the database
103
104 """
105 db_uri = 'mysql://{}:{}@{}:{}/{}'.format(
106 db.user(),
107 db.password(),
108 db.host(),
109 db.port(),
110 db.database(),
111 )
112
113 if kvdb.get('db_uri') == db_uri:
114 # We're already configured
115 return
116
117 status_set('maintenance', 'Initializing database')
118
119 try:
120 # HACK: use a packed version of init_mano_db until bug https://osm.etsi.org/bugzilla/show_bug.cgi?id=56 is fixed
121 # cmd = "{}/database_utils/init_mano_db.sh --createdb ".format(kvdb.get('repo'))
122 cmd = "./scripts//init_mano_db.sh --createdb "
123 cmd += "-u {} -p{} -h {} -d {} -P {}".format(
124 db.user(),
125 db.password(),
126 db.host(),
127 db.database(),
128 db.port(),
129 )
130 output, err = _run(cmd)
131 except subprocess.CalledProcessError:
132 # Eat this. init_mano_db.sh will return error code 1 on success
133 pass
134
135 context = {
136 'user': db.user(),
137 'password': db.password(),
138 'host': db.host(),
139 'database': db.database(),
140 'port': db.port(),
141 }
142 templating.render(
143 'openmanod.cfg',
144 os.path.join(kvdb.get('repo'), 'openmanod.cfg'),
145 context,
146 owner=USER,
147 group=USER,
148 )
149 kvdb.set('db_uri', db_uri)
150
151 status_set('active', 'Database installed.')
152 set_state('db.installed')
153
154@when_not('openvim-controller.available')
155def need_openvim():
156 status_set('waiting', 'Waiting for OpenVIM')
157
158
159@when_not('db.available')
160def need_db():
161 status_set('waiting', 'Waiting for database')
162
163
164@when_not('db.available')
165@when_not('openvim-controller.available')
166def need_everything():
167 status_set('waiting', 'Waiting for database and OpenVIM')
168
169
170@when_not('openmano.installed')
171def install_layer_openmano():
172 status_set('maintenance', 'Installing')
173
174 cfg = config()
175
176 # TODO change user home
177 # XXX security issue!
178 host.adduser(USER, password=USER)
179
180 if os.path.isdir(INSTALL_PATH):
181 rmtree(INSTALL_PATH)
182
183 gitrepo.clone_from(
184 cfg['repository'],
185 INSTALL_PATH,
186 branch=cfg['branch'],
187 )
188
189 chownr(
190 INSTALL_PATH,
191 owner=USER,
192 group=USER,
193 follow_links=False,
194 chowntopdir=True
195 )
196
197 os.mkdir(os.path.join(INSTALL_PATH, 'logs'))
198 chownr(INSTALL_PATH, USER, USER)
199 kvdb.set('repo', INSTALL_PATH)
200
201 os.mkdir('/home/{}/bin'.format(USER))
202
203 os.symlink(
204 "{}/openmano".format(INSTALL_PATH),
205 "/home/{}/bin/openmano".format(USER))
206 os.symlink(
207 "{}/scripts/openmano-report.sh".format(INSTALL_PATH),
208 "/home/{}/bin/openmano-report.sh".format(USER))
209 os.symlink(
210 "{}/scripts/service-openmano.sh".format(INSTALL_PATH),
211 "/home/{}/bin/service-openmano".format(USER))
212
213 open_port(9090)
214 set_state('openmano.installed')
215
216
217def _run(cmd, env=None):
218 if isinstance(cmd, str):
219 cmd = cmd.split() if ' ' in cmd else [cmd]
220
221 log(cmd)
222 p = subprocess.Popen(cmd,
223 env=env,
224 stdout=subprocess.PIPE,
225 stderr=subprocess.PIPE)
226 stdout, stderr = p.communicate()
227 retcode = p.poll()
228 if retcode > 0:
229 raise subprocess.CalledProcessError(
230 returncode=retcode,
231 cmd=cmd,
232 output=stderr.decode("utf-8").strip())
233 return (stdout.decode('utf-8'), stderr.decode('utf-8'))