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