github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/repository/xenial/mysql/hooks/lib/utils.py (about) 1 # 2 # Copyright 2012 Canonical Ltd. 3 # 4 # This file is sourced from lp:openstack-charm-helpers 5 # 6 # Authors: 7 # James Page <james.page@ubuntu.com> 8 # Paul Collins <paul.collins@canonical.com> 9 # Adam Gandelman <adamg@ubuntu.com> 10 # 11 12 import json 13 import os 14 import subprocess 15 import socket 16 import sys 17 18 19 def do_hooks(hooks): 20 hook = os.path.basename(sys.argv[0]) 21 22 try: 23 hook_func = hooks[hook] 24 except KeyError: 25 juju_log('INFO', 26 "This charm doesn't know how to handle '{}'.".format(hook)) 27 else: 28 hook_func() 29 30 31 def install(*pkgs): 32 cmd = [ 33 'apt-get', 34 '-y', 35 'install' 36 ] 37 for pkg in pkgs: 38 cmd.append(pkg) 39 subprocess.check_call(cmd) 40 41 TEMPLATES_DIR = 'templates' 42 43 try: 44 import jinja2 45 except ImportError: 46 install('python-jinja2') 47 import jinja2 48 49 try: 50 import dns.resolver 51 except ImportError: 52 install('python-dnspython') 53 import dns.resolver 54 55 56 def render_template(template_name, context, template_dir=TEMPLATES_DIR): 57 templates = jinja2.Environment( 58 loader=jinja2.FileSystemLoader(template_dir) 59 ) 60 template = templates.get_template(template_name) 61 return template.render(context) 62 63 CLOUD_ARCHIVE = \ 64 """ # Ubuntu Cloud Archive 65 deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main 66 """ 67 68 CLOUD_ARCHIVE_POCKETS = { 69 'folsom': 'precise-updates/folsom', 70 'folsom/updates': 'precise-updates/folsom', 71 'folsom/proposed': 'precise-proposed/folsom', 72 'grizzly': 'precise-updates/grizzly', 73 'grizzly/updates': 'precise-updates/grizzly', 74 'grizzly/proposed': 'precise-proposed/grizzly' 75 } 76 77 78 def configure_source(): 79 source = str(config_get('openstack-origin')) 80 if not source: 81 return 82 if source.startswith('ppa:'): 83 cmd = [ 84 'add-apt-repository', 85 source 86 ] 87 subprocess.check_call(cmd) 88 if source.startswith('cloud:'): 89 install('ubuntu-cloud-keyring') 90 pocket = source.split(':')[1] 91 with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt: 92 apt.write(CLOUD_ARCHIVE.format(CLOUD_ARCHIVE_POCKETS[pocket])) 93 if source.startswith('deb'): 94 l = len(source.split('|')) 95 if l == 2: 96 (apt_line, key) = source.split('|') 97 cmd = [ 98 'apt-key', 99 'adv', '--keyserver keyserver.ubuntu.com', 100 '--recv-keys', key 101 ] 102 subprocess.check_call(cmd) 103 elif l == 1: 104 apt_line = source 105 106 with open('/etc/apt/sources.list.d/quantum.list', 'w') as apt: 107 apt.write(apt_line + "\n") 108 cmd = [ 109 'apt-get', 110 'update' 111 ] 112 subprocess.check_call(cmd) 113 114 # Protocols 115 TCP = 'TCP' 116 UDP = 'UDP' 117 118 119 def expose(port, protocol='TCP'): 120 cmd = [ 121 'open-port', 122 '{}/{}'.format(port, protocol) 123 ] 124 subprocess.check_call(cmd) 125 126 127 def juju_log(severity, message): 128 cmd = [ 129 'juju-log', 130 '--log-level', severity, 131 message 132 ] 133 subprocess.check_call(cmd) 134 135 136 def relation_ids(relation): 137 cmd = [ 138 'relation-ids', 139 relation 140 ] 141 result = str(subprocess.check_output(cmd)).split() 142 if result == "": 143 return None 144 else: 145 return result 146 147 148 def relation_list(rid): 149 cmd = [ 150 'relation-list', 151 '-r', rid, 152 ] 153 result = str(subprocess.check_output(cmd)).split() 154 if result == "": 155 return None 156 else: 157 return result 158 159 160 def relation_get(attribute, unit=None, rid=None): 161 cmd = [ 162 'relation-get', 163 ] 164 if rid: 165 cmd.append('-r') 166 cmd.append(rid) 167 cmd.append(attribute) 168 if unit: 169 cmd.append(unit) 170 value = subprocess.check_output(cmd).strip() # IGNORE:E1103 171 if value == "": 172 return None 173 else: 174 return value 175 176 177 def relation_set(**kwargs): 178 cmd = [ 179 'relation-set' 180 ] 181 args = [] 182 for k, v in kwargs.items(): 183 if k == 'rid': 184 if v: 185 cmd.append('-r') 186 cmd.append(v) 187 else: 188 args.append('{}={}'.format(k, v)) 189 cmd += args 190 subprocess.check_call(cmd) 191 192 193 def unit_get(attribute): 194 cmd = [ 195 'unit-get', 196 attribute 197 ] 198 value = subprocess.check_output(cmd).strip() # IGNORE:E1103 199 if value == "": 200 return None 201 else: 202 return value 203 204 205 def config_get(attribute): 206 cmd = [ 207 'config-get', 208 '--format', 209 'json', 210 ] 211 out = subprocess.check_output(cmd).strip() # IGNORE:E1103 212 cfg = json.loads(out) 213 214 try: 215 return cfg[attribute] 216 except KeyError: 217 return None 218 219 220 def get_unit_hostname(): 221 return socket.gethostname() 222 223 224 def get_host_ip(hostname=unit_get('private-address')): 225 try: 226 # Test to see if already an IPv4 address 227 socket.inet_aton(hostname) 228 return hostname 229 except socket.error: 230 answers = dns.resolver.query(hostname, 'A') 231 if answers: 232 return answers[0].address 233 return None 234 235 236 def _svc_control(service, action): 237 subprocess.check_call(['service', service, action]) 238 239 240 def restart(*services): 241 for service in services: 242 _svc_control(service, 'restart') 243 244 245 def stop(*services): 246 for service in services: 247 _svc_control(service, 'stop') 248 249 250 def start(*services): 251 for service in services: 252 _svc_control(service, 'start') 253 254 255 def reload(*services): 256 for service in services: 257 try: 258 _svc_control(service, 'reload') 259 except subprocess.CalledProcessError: 260 # Reload failed - either service does not support reload 261 # or it was not running - restart will fixup most things 262 _svc_control(service, 'restart') 263 264 265 def running(service): 266 try: 267 output = subprocess.check_output(['service', service, 'status']) 268 except subprocess.CalledProcessError: 269 return False 270 else: 271 if ("start/running" in output or 272 "is running" in output): 273 return True 274 else: 275 return False 276 277 278 def is_relation_made(relation, key='private-address'): 279 for r_id in (relation_ids(relation) or []): 280 for unit in (relation_list(r_id) or []): 281 if relation_get(key, rid=r_id, unit=unit): 282 return True 283 return False