Merge lp:~chris.macnaughton/openstack-mojo-specs/upgrade-spec into lp:~ost-maintainers/openstack-mojo-specs/openstack-mojo-specs-1802

Proposed by Chris MacNaughton
Status: Needs review
Proposed branch: lp:~chris.macnaughton/openstack-mojo-specs/upgrade-spec
Merge into: lp:~ost-maintainers/openstack-mojo-specs/openstack-mojo-specs-1802
Diff against target: 357 lines (+297/-3)
6 files modified
helper/bundles/ubuntu-lite.yaml (+5/-0)
helper/collect/collect-ubuntu-lite (+1/-0)
helper/scripts/upgrade_all_units.py (+13/-0)
helper/utils/mojo_utils.py (+261/-3)
specs/dev/series_upgrade_ubuntu_lite/SPEC_INFO.txt (+1/-0)
specs/dev/series_upgrade_ubuntu_lite/manifest (+16/-0)
To merge this branch: bzr merge lp:~chris.macnaughton/openstack-mojo-specs/upgrade-spec
Reviewer Review Type Date Requested Status
David Ames (community) Needs Fixing
Review via email: mp+341397@code.launchpad.net
To post a comment you must log in.
333. By Chris MacNaughton

rename upgrade script

Revision history for this message
David Ames (thedac) wrote :

I still need to do a full review but make lint fails with a number of lint problems.

review: Needs Fixing
Revision history for this message
David Ames (thedac) wrote :

Ok, so we have a lot of context in https://code.launchpad.net/~chris.macnaughton/openstack-mojo-specs/upgrade-spec/+merge/337646 which I would like to continue.

My recommendation is we merge the 18.02 branch without this change, abandon this MP and continue with the original MP which has several unaddressed comments.

334. By Chris MacNaughton

update to resolve lint issues and resolve discussions

- remove prints
- shift to use `juju run` where possible

Unmerged revisions

334. By Chris MacNaughton

update to resolve lint issues and resolve discussions

- remove prints
- shift to use `juju run` where possible

333. By Chris MacNaughton

rename upgrade script

332. By Chris MacNaughton

updating series upgrade spec

331. By Chris MacNaughton

update handlers to get units started correctly

330. By Chris MacNaughton

tidy a bit

329. By Chris MacNaughton

add helper to upgrade all units in a model

328. By Chris MacNaughton

starting framing upgrade spec

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'helper/bundles/ubuntu-lite.yaml'
--- helper/bundles/ubuntu-lite.yaml 1970-01-01 00:00:00 +0000
+++ helper/bundles/ubuntu-lite.yaml 2018-03-20 07:12:59 +0000
@@ -0,0 +1,5 @@
1series: "{{ series }}"
2services:
3 ubuntu-lite:
4 charm: ubuntu-lite
5 num_units: 3
06
=== added file 'helper/collect/collect-ubuntu-lite'
--- helper/collect/collect-ubuntu-lite 1970-01-01 00:00:00 +0000
+++ helper/collect/collect-ubuntu-lite 2018-03-20 07:12:59 +0000
@@ -0,0 +1,1 @@
1ubuntu-lite cs:~jameinel/ubuntu-lite
02
=== added file 'helper/scripts/upgrade_all_units.py'
--- helper/scripts/upgrade_all_units.py 1970-01-01 00:00:00 +0000
+++ helper/scripts/upgrade_all_units.py 2018-03-20 07:12:59 +0000
@@ -0,0 +1,13 @@
1#!/usr/bin/env python
2import sys
3import utils.mojo_utils as mojo_utils
4import os
5
6
7def main(argv):
8 mojo_utils.setup_logging()
9 mojo_utils.upgrade_all_units()
10
11
12if __name__ == "__main__":
13 sys.exit(main(sys.argv))
014
=== modified file 'helper/utils/mojo_utils.py'
--- helper/utils/mojo_utils.py 2018-02-28 10:53:42 +0000
+++ helper/utils/mojo_utils.py 2018-03-20 07:12:59 +0000
@@ -1,5 +1,5 @@
1#!/usr/bin/env python1#!/usr/bin/env python
22import six
3import logging3import logging
4import os4import os
5import shutil5import shutil
@@ -465,8 +465,8 @@
465 files.append(os.path.join(os.path.dirname(__file__), filename))465 files.append(os.path.join(os.path.dirname(__file__), filename))
466 # Up one directory from called file466 # Up one directory from called file
467 files.append(os.path.join(467 files.append(os.path.join(
468 os.path.dirname(os.path.dirname(__file__)),468 os.path.dirname(os.path.dirname(__file__)),
469 filename))469 filename))
470470
471 for file_path in files:471 for file_path in files:
472 if os.path.isfile(file_path):472 if os.path.isfile(file_path):
@@ -563,6 +563,264 @@
563 time.sleep(30)563 time.sleep(30)
564564
565565
566# Begin upgrade code
567
568def do_release_upgrade(unit):
569 """Runs do-release-upgrade noninteractive"""
570 logging.info('Upgrading ' + unit)
571 subprocess.call([kiki.cmd(), 'run', '--unit', unit, 'status-set',
572 'maintenance', 'Doing release upgrade'])
573 cmd = [kiki.cmd(), 'ssh', unit, 'sudo',
574 'do-release-upgrade', '-f', 'DistUpgradeViewNonInteractive']
575 try:
576 subprocess.check_call(cmd)
577 except subprocess.CalledProcessError as e:
578 logging.warn("Failed do-release-upgrade for {}".format(unit))
579 logging.warn(e)
580 return False
581 finally:
582 subprocess.call([kiki.cmd(), 'run', '--unit', unit, 'status-set',
583 'active'])
584 return True
585
586
587def reboot(unit):
588 """Reboot machine"""
589 cmd = [kiki.cmd(), 'run', '--unit', unit, 'sudo', 'reboot', '&&', 'exit']
590 try:
591 subprocess.check_call(cmd)
592 except subprocess.CalledProcessError as e:
593 logging.info(e)
594 pass
595
596
597def upgrade_machine(app_name, unit, machine, machine_num):
598 """Run the upgrade process for a single machine"""
599 cmd = [kiki.cmd(), 'run', '--unit', unit, 'status-set',
600 'maintenance', 'Upgrading series']
601 subprocess.call(cmd)
602 if not do_release_upgrade(unit):
603 return False
604 if machine["series"] == "trusty":
605 upstart_to_systemd(machine_num)
606 cmd = [kiki.cmd(), 'run', '--unit', unit, 'status-set',
607 'active']
608 subprocess.call(cmd)
609 logging.debug("Rebooting")
610 reboot(unit)
611 cmd = [kiki.cmd(), "ssh", unit, "exit"]
612 while(True):
613 try:
614 subprocess.check_call(cmd)
615 break
616 except subprocess.CalledProcessError:
617 logging.debug("Waiting 2 more seconds")
618 time.sleep(2)
619 update_machine_series(app_name, machine_num)
620 return True
621
622
623def update_machine_series(app_name, machine_num):
624 cmd = [kiki.cmd(), 'run', '--machine',
625 machine_num, 'lsb_release', '-c', '-s']
626 codename = subprocess.check_output(cmd)
627 if six.PY3:
628 codename = codename.decode('utf-8')
629 codename = codename.strip()
630 logging.debug("Telling juju that {} series is {}".format(
631 machine_num, codename))
632 cmd = [kiki.cmd(), 'update-series', str(machine_num), codename]
633 subprocess.call(cmd)
634 cmd = [kiki.cmd(), 'update-series', app_name, codename]
635 subprocess.call(cmd)
636
637
638SYSTEMD_JUJU_MACHINE_AGENT_SCRIPT = """#!/usr/bin/env bash
639
640# Set up logging.
641touch '/var/log/juju/machine-{machine_id}.log'
642chown syslog:syslog '/var/log/juju/machine-{machine_id}.log'
643chmod 0600 '/var/log/juju/machine-{machine_id}.log'
644exec >> '/var/log/juju/machine-{machine_id}.log'
645exec 2>&1
646
647# Run the script.
648'/var/lib/juju/tools/machine-{machine_id}/jujud' machine --data-dir '/var/lib/juju' --machine-id {machine_id} --debug
649""" # nopep8
650
651SYSTEMD_JUJU_UNIT_AGENT_SCRIPT = """#!/usr/bin/env bash
652
653# Set up logging.
654touch '/var/log/juju/unit-{application_name}-{application_number}.log'
655chown syslog:syslog '/var/log/juju/unit-{application_name}-{application_number}.log'
656chmod 0600 '/var/log/juju/unit-{application_name}-{application_number}.log'
657exec >> '/var/log/juju/unit-{application_name}-{application_number}.log'
658exec 2>&1
659
660# Run the script.
661'/var/lib/juju/tools/unit-{application_name}-{application_number}/jujud' unit --data-dir '/var/lib/juju' --unit-name {application} --debug
662""" # nopep8
663
664SYSTEMD_JUJU_MACHINE_INIT_FILE = """[Unit]
665Description=juju agent for machine-{name}
666After=syslog.target
667After=network.target
668After=systemd-user-sessions.service
669
670[Service]
671LimitNOFILE=20000
672ExecStart=/var/lib/juju/init/jujud-machine-{name}/exec-start.sh
673Restart=on-failure
674TimeoutSec=300
675
676[Install]
677WantedBy=multi-user.target
678""" # nopep8
679
680
681SYSTEMD_JUJU_UNIT_INIT_FILE = """[Unit]
682Description=juju unit agent for unit-{application_name}-{application_number}
683After=syslog.target
684After=network.target
685After=systemd-user-sessions.service
686
687[Service]
688Environment="JUJU_CONTAINER_TYPE="
689ExecStart=/var/lib/juju/init/jujud-unit-{application_name}-{application_number}/exec-start.sh
690Restart=on-failure
691TimeoutSec=300
692
693[Install]
694WantedBy=multi-user.target
695"""
696
697
698def upstart_to_systemd(machine_number):
699 """Upgrade upstart scripts to Systemd after upgrade from Trusty"""
700 base_command = [kiki.cmd(), 'run', '--machine', str(machine_number), '--']
701 commands = [
702 base_command + [
703 "sudo", "mkdir", "-p",
704 "/var/lib/juju/init/jujud-machine-{}".format(machine_number)],
705 base_command + [
706 'echo', SYSTEMD_JUJU_MACHINE_AGENT_SCRIPT.format(
707 machine_id=machine_number),
708 '|', 'sudo', 'tee',
709 ('/var/lib/juju/init/jujud-machine-{machine_id}'
710 '/exec-start.sh').format(
711 machine_id=machine_number)],
712 base_command + [
713 'echo', SYSTEMD_JUJU_MACHINE_INIT_FILE.format(
714 name=machine_number), '|', 'sudo', 'tee',
715 ('/var/lib/juju/init/jujud-machine-{name}'
716 '/jujud-machine-{name}.service').format(
717 name=machine_number)],
718 base_command + [
719 'sudo', 'chmod', '755',
720 ('/var/lib/juju/init/jujud-machine-{machine_id}/'
721 'exec-start.sh').format(machine_id=machine_number)],
722 base_command + [
723 'sudo', 'ln', '-s',
724 ('/var/lib/juju/init/jujud-machine-{machine_id}/'
725 'jujud-machine-{machine_id}.service').format(
726 machine_id=machine_number
727 ), '/etc/systemd/system/'],
728 base_command + [
729 'sudo', 'ln', '-s',
730 ('/var/lib/juju/init/jujud-machine-{machine_id}/'
731 'jujud-machine-{machine_id}.service').format(
732 machine_id=machine_number),
733 ('/etc/systemd/system/multi-user.target.wants/'
734 'jujud-machine-{machine_id}.service').format(
735 machine_id=machine_number
736 )
737 ]
738 ]
739 commands += units_upstart_to_systemd_commands(machine_number)
740 for cmd in commands:
741 try:
742 subprocess.check_call(cmd)
743 except subprocess.CalledProcessError as e:
744 logging.warn(e)
745 return False
746
747
748def units_upstart_to_systemd_commands(machine_number):
749 """Upgrade a specific application unit from Upstart to Systemd"""
750 units = get_juju_status(unit=str(machine_number))["applications"]
751 base_command = [kiki.cmd(), 'run', '--machine', str(machine_number), '--']
752 commands = []
753 for (name, app_unit) in units.iteritems():
754 for (unit_name, unit) in app_unit["units"].iteritems():
755 logging.debug("Updating {} [{}]".format(name, unit_name))
756 app_number = unit_name.split("/")[-1]
757 systemd_file_name = ("jujud-unit-{app_name}"
758 "-{app_number}.service").format(
759 app_name=name, app_number=app_number)
760 systemd_file_path = ('/var/lib/juju/init/jujud-unit-{app_name}'
761 '-{app_number}/{file_name}').format(
762 app_name=name,
763 app_number=app_number,
764 file_name=systemd_file_name)
765 commands += [
766 base_command + [
767 "sudo", "mkdir", "-p",
768 "/var/lib/juju/init/jujud-unit-{}-{}".format(
769 name, app_number)],
770 base_command + [
771 'echo', SYSTEMD_JUJU_UNIT_AGENT_SCRIPT.format(
772 application=unit_name,
773 application_name=name,
774 application_number=app_number),
775 '|', 'sudo', 'tee',
776 ('/var/lib/juju/init/jujud-unit-{app_name}-'
777 '{app_number}/exec-start.sh').format(
778 app_name=name, app_number=app_number)],
779 base_command + [
780 'echo', SYSTEMD_JUJU_UNIT_INIT_FILE.format(
781 application_name=name, application_number=app_number),
782 '|', 'sudo', 'tee', systemd_file_path],
783 base_command + [
784 'sudo', 'chmod', '755',
785 ('/var/lib/juju/init/jujud-unit-{app_name}-'
786 '{app_number}/exec-start.sh').format(
787 app_name=name, app_number=app_number)],
788 base_command + [
789 'sudo', 'ln', '-s', systemd_file_path,
790 '/etc/systemd/system/'],
791 base_command + [
792 'sudo', 'ln', '-s', systemd_file_path,
793 ('/etc/systemd/system/multi-user.target.wants/'
794 '{file_name}').format(
795 machine_id=machine_number,
796 file_name=systemd_file_name)
797 ]
798 ]
799 return commands
800
801
802def upgrade_all_units(juju_status=None):
803 if not juju_status:
804 juju_status = get_juju_status()
805 # Upgrade the rest
806 upgraded_machines = []
807 for (app_name, details) in juju_status['applications'].items():
808 for name, unit_details in details['units'].items():
809 logging.debug("Details for {}: {}".format(name, unit_details))
810 machine_id = unit_details["machine"]
811 if machine_id in upgraded_machines:
812 continue
813 if not upgrade_machine(
814 app_name,
815 name,
816 juju_status["machines"][machine_id],
817 machine_id
818 ):
819 logging.warn("No series upgrade found for {}".format(name))
820 upgraded_machines.append(machine_id)
821# End upgrade code
822
823
566def parse_mojo_arg(options, mojoarg, multiargs=False):824def parse_mojo_arg(options, mojoarg, multiargs=False):
567 if mojoarg.upper() in os.environ:825 if mojoarg.upper() in os.environ:
568 if multiargs:826 if multiargs:
569827
=== added directory 'specs/dev/series_upgrade_ubuntu_lite'
=== added file 'specs/dev/series_upgrade_ubuntu_lite/SPEC_INFO.txt'
--- specs/dev/series_upgrade_ubuntu_lite/SPEC_INFO.txt 1970-01-01 00:00:00 +0000
+++ specs/dev/series_upgrade_ubuntu_lite/SPEC_INFO.txt 2018-03-20 07:12:59 +0000
@@ -0,0 +1,1 @@
1Deploys ubuntu-lite, and upgrades the charm between series.
02
=== added symlink 'specs/dev/series_upgrade_ubuntu_lite/check_juju.py'
=== target is u'../../../helper/tests/check_juju.py'
=== added symlink 'specs/dev/series_upgrade_ubuntu_lite/collect-ubuntu-lite'
=== target is u'../../../helper/collect/collect-ubuntu-lite'
=== added file 'specs/dev/series_upgrade_ubuntu_lite/manifest'
--- specs/dev/series_upgrade_ubuntu_lite/manifest 1970-01-01 00:00:00 +0000
+++ specs/dev/series_upgrade_ubuntu_lite/manifest 2018-03-20 07:12:59 +0000
@@ -0,0 +1,16 @@
1# Collect the charm
2collect config=collect-ubuntu-lite
3
4# Deploy ubuntu-lite bundle
5deploy config=ubuntu-lite.yaml delay=0 wait=False
6
7# Wait for deployment to settle
8verify config=check_juju.py
9
10# Upgrade units
11script config=scripts/upgrade_all_units.py
12
13# Wait for deployment to settle
14verify config=check_juju.py
15
16# Success
017
=== added symlink 'specs/dev/series_upgrade_ubuntu_lite/scripts'
=== target is u'../../../helper/scripts'
=== added symlink 'specs/dev/series_upgrade_ubuntu_lite/ubuntu-lite.yaml'
=== target is u'../../../helper/bundles/ubuntu-lite.yaml'

Subscribers

People subscribed via source and target branches