github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/assess_upgrade_series.py (about)

     1  #!/usr/bin/env python
     2  """Assess upgrading using the 'upgrade-series' commands."""
     3  
     4  from __future__ import print_function
     5  
     6  import argparse
     7  import logging
     8  import os
     9  import subprocess
    10  import sys
    11  
    12  from deploy_stack import (
    13      BootstrapManager,
    14  )
    15  from jujucharm import (
    16      local_charm_path,
    17  )
    18  from utility import (
    19      add_basic_testing_arguments,
    20      configure_logging,
    21      JujuAssertionError,
    22  )
    23  
    24  __metaclass__ = type
    25  
    26  log = logging.getLogger("assess_upgrade_series")
    27  
    28  
    29  DEFAULT_FROM_SERIES = 'xenial'
    30  DEFAULT_TO_SERIES = 'bionic'
    31  
    32  
    33  def assess_juju_upgrade_series(client, args):
    34      target_machine = '0'
    35      assert_correct_series(client, target_machine, args.from_series)
    36      upgrade_series_prepare(client, target_machine, args.to_series, agree=True)
    37      do_release_upgrade(client, target_machine)
    38      reboot_machine(client, target_machine)
    39      upgrade_series_complete(client, target_machine)
    40      assert_correct_series(client, target_machine, args.to_series)
    41      set_application_series(client, "dummy-subordinate", args.to_series)
    42  
    43  
    44  def upgrade_series_prepare(client, machine, series, **flags):
    45      args = (machine, 'prepare', series)
    46      if flags['agree']:
    47          args += ('-y',)
    48      client.juju('upgrade-series', args)
    49  
    50  
    51  def upgrade_series_complete(client, machine):
    52      args = (machine, 'complete')
    53      client.juju('upgrade-series', args)
    54  
    55  
    56  def do_release_upgrade(client, machine):
    57      try:
    58          output = client.get_juju_output(
    59              'ssh', machine, 'sudo do-release-upgrade -f '
    60              'DistUpgradeViewNonInteractive', timeout=3600)
    61      except subprocess.CalledProcessError as e:
    62          raise AssertionError(
    63              "do-release-upgrade failed on {}: {}".format(machine, e))
    64  
    65      log.info("do-release-upgrade response: ".format(output))
    66  
    67  
    68  def reboot_machine(client, machine):
    69      try:
    70          log.info("Restarting: {}".format(machine))
    71          cmd = build_ssh_cmd(client, machine, 'sudo shutdown -r now && exit')
    72          output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    73          log.info("Restarting machine output: {}\n".format(output))
    74      except subprocess.CalledProcessError as e:
    75          logging.info(
    76              "Error running shutdown:\nstdout: %s\nstderr: %s",
    77              e.output, getattr(e, 'stderr', None))
    78  
    79      log.info("wait_for_started()")
    80      client.wait_for_started()
    81  
    82  def set_application_series(client, application, series)
    83      args = (application, series)
    84      client.juju('set-series', args)
    85  
    86  
    87  def build_ssh_cmd(client, machine, command):
    88      ssh_opts = [
    89          "-o", "User ubuntu",
    90          "-o", "UserKnownHostsFile /dev/null",
    91          "-o", "StrictHostKeyChecking no",
    92          "-o", "PasswordAuthentication no",
    93      ]
    94  
    95      status = client.get_status()
    96      machine_name = status.get_machine_dns_name(machine)
    97      cmd = ["ssh"] + ssh_opts + [machine_name] + [command]
    98      return cmd
    99  
   100  
   101  def assert_correct_series(client, machine, expected):
   102      """Verify that juju knows the correct series for the machine"""
   103      status = client.get_status()
   104      machine_series = status.status['machines'][machine]['series']
   105      if machine_series != expected:
   106          raise JujuAssertionError(
   107              "Machine {} series of {} doesn't match the expected series: {}"
   108              .format(machine, machine_series, expected))
   109  
   110  
   111  def setup(client, series):
   112      dummy_sink = local_charm_path(
   113          charm='charms/dummy-sink',
   114          juju_ver=client.version,
   115          series=series,
   116          repository=os.environ['JUJU_REPOSITORY'])
   117      dummy_subordinate = local_charm_path(
   118          charm='charms/dummy-subordinate',
   119          juju_ver=client.version,
   120          series=series,
   121          repository=os.environ['JUJU_REPOSITORY'])
   122      _, complete_primary = client.deploy(dummy_sink, series=series)
   123      _, complete_subordinate = client.deploy(dummy_subordinate, series=series)
   124      client.juju('add-relation', ('dummy-sink', 'dummy-subordinate'))
   125      client.set_config('dummy-subordinate', {'token': 'Canonical'})
   126      client.wait_for(complete_primary)
   127      client.wait_for(complete_subordinate)
   128  
   129  
   130  def parse_args(argv):
   131      parser = argparse.ArgumentParser(description="Test juju update series.")
   132      add_basic_testing_arguments(parser)
   133      parser.add_argument('--from-series', default=DEFAULT_FROM_SERIES,
   134                          dest='from_series',
   135                          help='Series to start machine and units with')
   136      parser.add_argument('--to-series', default=DEFAULT_TO_SERIES,
   137                          dest='to_series',
   138                          help='Series to upgrade machine and units to')
   139      return parser.parse_args(argv)
   140  
   141  
   142  def main(argv=None):
   143      args = parse_args(argv)
   144      configure_logging(args.verbose)
   145      bs_manager = BootstrapManager.from_args(args)
   146      with bs_manager.booted_context(args.upload_tools):
   147          setup(bs_manager.client, args.from_series)
   148          assess_juju_upgrade_series(bs_manager.client, args)
   149      return 0
   150  
   151  
   152  if __name__ == '__main__':
   153      sys.exit(main())