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())