Hello community, here is the log from the commit of package sesdev for openSUSE:Factory checked in at 2020-10-24 15:18:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/sesdev (Old) and /work/SRC/openSUSE:Factory/.sesdev.new.3463 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sesdev" Sat Oct 24 15:18:31 2020 rev:18 rq:843663 version:1.9.1+1603459604.g8c9ed2c Changes: -------- --- /work/SRC/openSUSE:Factory/sesdev/sesdev.changes 2020-10-10 00:29:26.089155496 +0200 +++ /work/SRC/openSUSE:Factory/.sesdev.new.3463/sesdev.changes 2020-10-24 15:18:59.428319467 +0200 @@ -1,0 +2,25 @@ +Fri Oct 23 13:26:53 UTC 2020 - Nathan Cutler <ncut...@suse.com> + +- Update to 1.9.1+1603459604.g8c9ed2c + + upstream 1.9.1 release (2020-10-23) + * sesdev --devel flag: let click deduct type (PR #550) + +------------------------------------------------------------------- +Fri Oct 23 10:23:07 UTC 2020 - Nathan Cutler <ncut...@suse.com> + +- Update to 1.9.0+1603448566.gcb3362c + + upstream 1.9.0 release (2020-10-23) + * constant: add missing SLE-15-SP[12] Product repos (PR #530) + * Implement "sesdev upgrade" subcommand (PR #531) + * Implement "sesdev reboot DEP_ID NODE" command (PR #532) + * contrib/upgrade-demo-ses6-to-ses7.sh: add upgrade demo script (PR #535) + * provision.sh: add helper_scripts Jinja template (PR #540) + * exceptions: have SesDevException return optional exit code (PR #538) + * deployment: wait for rebooted node to complete boot sequence (PR #539) + * sesdev: fix --filestore regression (PR #545) + * cephadm/deployment_day_2.sh.j2: do not fail on defective --dry-run (PR #546) + * setup.cfg: include seslib/templates/cephadm/ directory in packaging (PR #548) + * templates/zypper: do not install supportutils-plugin-ses in SES{5,6,7} (PR #526) + * deepsea/nautilus_pre_stage_0.sh: refrain from patching DeepSea (PR #547) + +------------------------------------------------------------------- Old: ---- sesdev-1.8.0+1602174240.g45df4dd.tar.gz New: ---- sesdev-1.9.1+1603459604.g8c9ed2c.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sesdev.spec ++++++ --- /var/tmp/diff_new_pack.EeNIyx/_old 2020-10-24 15:19:02.216322670 +0200 +++ /var/tmp/diff_new_pack.EeNIyx/_new 2020-10-24 15:19:02.220322674 +0200 @@ -16,7 +16,7 @@ # Name: sesdev -Version: 1.8.0+1602174240.g45df4dd +Version: 1.9.1+1603459604.g8c9ed2c Release: 1%{?dist} Summary: CLI tool to deploy and manage SES clusters License: MIT ++++++ sesdev-1.8.0+1602174240.g45df4dd.tar.gz -> sesdev-1.9.1+1603459604.g8c9ed2c.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/CHANGELOG.md new/sesdev-1.9.1+1603459604.g8c9ed2c/CHANGELOG.md --- old/sesdev-1.8.0+1602174240.g45df4dd/CHANGELOG.md 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/CHANGELOG.md 2020-10-23 15:26:43.976071088 +0200 @@ -7,6 +7,33 @@ ## [Unreleased] +## [1.9.1] - 2020-10-23 + +### Fixed +- sesdev --devel flag: let click deduct type (PR #550) + +## [1.9.0] - 2020-10-23 + +### Added +- constant: add missing SLE-15-SP[12] Product repos (PR #530) +- Implement "sesdev upgrade" subcommand (PR #531) +- Implement "sesdev reboot DEP_ID NODE" command (PR #532) +- contrib/upgrade-demo-ses6-to-ses7.sh: add upgrade demo script (PR #535) +- provision.sh: add helper_scripts Jinja template (PR #540) + +### Fixed +- exceptions: have SesDevException return optional exit code (PR #538) +- deployment: wait for rebooted node to complete boot sequence (PR #539) +- sesdev: fix --filestore regression (PR #545) +- cephadm/deployment_day_2.sh.j2: do not fail on defective --dry-run (PR #546) +- setup.cfg: include seslib/templates/cephadm/ directory in packaging (PR #548) + +### Changed +- templates/zypper: do not install supportutils-plugin-ses in SES{5,6,7} (PR #526) + +### Removed +- deepsea/nautilus_pre_stage_0.sh: refrain from patching DeepSea (PR #547) + ## [1.8.0] - 2020-10-08 ### Added @@ -568,7 +595,9 @@ - Minimal README with a few usage instructions. - The CHANGELOG file. -[unreleased]: https://github.com/SUSE/sesdev/compare/v1.8.0...HEAD +[unreleased]: https://github.com/SUSE/sesdev/compare/v1.9.1...HEAD +[1.9.1]: https://github.com/SUSE/sesdev/releases/tag/v1.9.1 +[1.9.0]: https://github.com/SUSE/sesdev/releases/tag/v1.9.0 [1.8.0]: https://github.com/SUSE/sesdev/releases/tag/v1.8.0 [1.7.0]: https://github.com/SUSE/sesdev/releases/tag/v1.7.0 [1.6.1]: https://github.com/SUSE/sesdev/releases/tag/v1.6.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/contrib/upgrade-demo-ses6-to-ses7.sh new/sesdev-1.9.1+1603459604.g8c9ed2c/contrib/upgrade-demo-ses6-to-ses7.sh --- old/sesdev-1.8.0+1602174240.g45df4dd/contrib/upgrade-demo-ses6-to-ses7.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/contrib/upgrade-demo-ses6-to-ses7.sh 2020-10-23 15:26:43.976071088 +0200 @@ -0,0 +1,186 @@ +#!/bin/bash -ex + +# SES6 -> SES7 upgrade demo script + +# Deploys a minimal SES6 cluster capable of being upgraded to SES7, and upgrades +# it. It is recommended to capture stdout in a file when running, so one can go +# back and see what happened while the script was running. + +# TODO: +# - after each step, programatically validate that the step actually did what it +# was supposed to do + +DEP_ID="ses6-to-ses7" + +echo +echo "=> destroy cluster from previous run (if any)" > /dev/null +sesdev destroy -f "$DEP_ID" || true + +echo +echo "=> create a SES6 cluster" > /dev/null +sesdev create ses6 \ + --roles="[admin,master],[admin,mon,mgr,storage],[admin,mon,mgr,storage],[admin,mon,mgr,storage]" \ + --non-interactive \ + "$DEP_ID" + +echo +echo "=> validate the previous step by demonstrating that the SES6 cluster is functional and healthy" > /dev/null +sesdev qa-test "$DEP_ID" + +echo +echo "=> assert that master node is SLE-15-SP1/SES6" +sesdev ssh "$DEP_ID" master /home/vagrant/is_os.sh sles-15.1 +sesdev ssh "$DEP_ID" master ceph versions +sesdev ssh "$DEP_ID" master ceph status + +echo +echo "=> upgrade the Salt Master node to SLE-15-SP2/SES7 (RPMs)" > /dev/null +sesdev upgrade "$DEP_ID" master --to ses7 +sesdev reboot "$DEP_ID" master + +echo +echo "=> assert that master node is SLE-15-SP2/SES7" +sesdev ssh "$DEP_ID" master /home/vagrant/is_os.sh sles-15.2 +sesdev ssh "$DEP_ID" master ceph versions +# TODO: validate 15.2.x +sesdev ssh "$DEP_ID" master ceph health +# TODO: validate HEALTH_OK + +echo +echo "=> disable DeepSea stages in DeepSea pillar data" > /dev/null +sesdev ssh "$DEP_ID" master "bash -c 'echo -en stage_prep: disabled\\\nstage_discovery: disabled\\\nstage_configure: disabled\\\nstage_deploy: disabled\\\nstage_services: disabled\\\nstage_remove: disabled\\\n >> /srv/pillar/ceph/stack/global.yml'" + +echo +echo "=> configure ses7_container_registries in DeepSea pillar data" > /dev/null +sesdev ssh "$DEP_ID" master "bash -c 'echo -en ses7_container_image: registry.suse.de/devel/storage/7.0/containers/ses/7/ceph/ceph\\\nses7_container_registries:\\\n \\ - location: registry.suse.de/devel/storage/7.0/containers/ses/7/ceph/ceph\\\n \\ \\ \\ insecure: true\\\n >> /srv/pillar/ceph/stack/global.yml'" + +echo "=> dump new pillar settings and refresh pillar" > /dev/null +sesdev ssh "$DEP_ID" master cat /srv/pillar/ceph/stack/global.yml +sesdev ssh "$DEP_ID" master "bash -c 'salt \\* saltutil.refresh_pillar'" + +# TODO: attempt to run a deepsea stage, validate that it fails + +echo +echo "=> assimilate /etc/ceph/ceph.conf into MON Config Store" > /dev/null +sesdev ssh "$DEP_ID" master "bash -c 'ceph config assimilate-conf -i /etc/ceph/ceph.conf'" + +# TODO: dump config store, check that settings expected to be populated are +# populated, use /etc/ceph/ceph.conf parsing tool to compare + +echo +echo "=> display cluster upgrade and health status" > /dev/null +sesdev ssh "$DEP_ID" master salt-run upgrade.status +# TODO: parse output of upgrade.status and compare actual with expected output +sesdev ssh "$DEP_ID" master ceph health +# TODO: assert HEALTH_OK + +function ping_salt_minion { + set +x + local minion="$1" + local seconds_to_wait + seconds_to_wait="600" + local interval_seconds + interval_seconds="15" + echo + echo "=> waiting up to $seconds_to_wait seconds for minion $minion to respond to ping" + while true ; do + if sesdev ssh "$DEP_ID" master "bash -x -c 'salt $minion test.ping'" ; then + break + fi + echo + echo "=> $minion did not respond to ping" + seconds_to_wait="$(( seconds_to_wait - interval_seconds ))" + echo + echo "=> waiting up to $seconds_to_wait more seconds for minion $minion to respond to ping" + if [ "$seconds_to_wait" -le "0" ] ; then + echo "ERROR: timeout expired with minion $minion still not responding to ping" + exit 1 + fi + sleep "$interval_seconds" + done + echo + echo "=> minion $minion responded to ping" + set -x +} + +function upgrade_node { + local node_short_hostname="$1" + echo + echo "=> upgrade $node_short_hostname of the Ceph cluster to SLE-15-SP2/SES7 RPMs" > /dev/null + sesdev upgrade "$DEP_ID" "$node_short_hostname" --to ses7 + sesdev reboot "$DEP_ID" "$node_short_hostname" + ping_salt_minion "${node_short_hostname}.${DEP_ID}.test" + + echo + echo "=> complete upgrade of $node_short_hostname of the Ceph cluster" > /dev/null + sesdev ssh "$DEP_ID" master salt "${node_short_hostname}.${DEP_ID}.test" state.apply ceph.upgrade.ses7.adopt + # TODO: compare actual with expected output + + echo + echo "=> assert that $node_short_hostname is now running SLE-15-SP2" /dev/null + sesdev ssh "$DEP_ID" "$node_short_hostname" /home/vagrant/is_os.sh sles-15.2 + + echo + echo "=> display cluster upgrade and health status" > /dev/null + sesdev ssh "$DEP_ID" master salt-run upgrade.status + # TODO: compare actual with expected output + sesdev ssh "$DEP_ID" master ceph health + # TODO: compare actual with expected output (probably won't be HEALTH_OK) +} + +echo +echo "=> BEGIN: upgrade node1" +sesdev ssh "$DEP_ID" master ceph osd add-noout node1 +# TODO: compare actual with expected output +upgrade_node node1 +sesdev ssh "$DEP_ID" master ceph osd rm-noout node1 +# TODO: compare actual with expected output +echo +echo "=> END: upgrade node1" + +echo +echo "=> BEGIN: upgrade node2" +sesdev ssh "$DEP_ID" master ceph osd add-noout node2 +# TODO: compare actual with expected output +upgrade_node node2 +sesdev ssh "$DEP_ID" master ceph osd rm-noout node2 +# TODO: compare actual with expected output +echo +echo "=> END: upgrade node2" + +echo +echo "=> BEGIN: upgrade node3" +sesdev ssh "$DEP_ID" master ceph osd add-noout node3 +# TODO: compare actual with expected output +upgrade_node node3 +sesdev ssh "$DEP_ID" master ceph osd rm-noout node3 +# TODO: compare actual with expected output +echo +echo "=> END: upgrade node3" + +echo +echo "=> fully upgraded SES7 cluster" > /dev/null +sesdev ssh "$DEP_ID" master ceph status + +echo +echo "=> export cluster configuration from deepsea" > /dev/null +sesdev ssh "$DEP_ID" master "bash -x -c 'salt-run upgrade.ceph_salt_config > ceph-salt-config.json'" +sesdev ssh "$DEP_ID" master "bash -x -c 'salt-run upgrade.generate_service_specs > specs.yaml'" +# TODO: validation (?) + +echo +echo "=> remove deepsea, install ceph-salt" > /dev/null +sesdev ssh "$DEP_ID" master "bash -x -c 'zypper --non-interactive rm deepsea deepsea-cli'" +sesdev ssh "$DEP_ID" master "bash -x -c 'zypper --non-interactive install ceph-salt'" +sesdev ssh "$DEP_ID" master "bash -x -c 'systemctl restart salt-master.service'" +sesdev ssh "$DEP_ID" master "bash -x -c 'salt \\* saltutil.sync_all'" +# TODO: validation (?) + +echo +echo "=> import and apply ceph-salt config" > /dev/null +sesdev ssh "$DEP_ID" master "bash -x -c 'ceph-salt import ceph-salt-config.json'" +sesdev ssh "$DEP_ID" master "bash -x -c 'ceph-salt config /ssh generate'" +sesdev ssh "$DEP_ID" master "bash -x -c 'ceph-salt config ls'" +# TODO: compare actual with expected output +sesdev ssh "$DEP_ID" master "bash -x -c 'ceph-salt apply'" +# TODO: validation (?) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/sesdev/__init__.py new/sesdev-1.9.1+1603459604.g8c9ed2c/sesdev/__init__.py --- old/sesdev-1.8.0+1602174240.g45df4dd/sesdev/__init__.py 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/sesdev/__init__.py 2020-10-23 15:26:43.980071088 +0200 @@ -26,6 +26,7 @@ OptionNotSupportedInContext, \ OptionNotSupportedInVersion, \ OptionValueError, \ + SSHCommandReturnedNonZero, \ VersionNotKnown, \ YouMustProvide from seslib.log import Log @@ -45,6 +46,8 @@ except SesDevException as ex: logger.exception(ex) click.echo(str(ex)) + if ex.args[0]: + return int(ex.args[0]) return 1 return 0 @@ -438,11 +441,13 @@ settings_dict['disk_size'] = disk_size if bluestore is not None: - settings_dict['filestore_osds'] = False - else: - settings_dict['filestore_osds'] = True - if not disk_size: - settings_dict['disk_size'] = 15 # default 8 GB disk size is too small for FileStore + if bluestore: + settings_dict['filestore_osds'] = False + else: + settings_dict['filestore_osds'] = True + if not disk_size: + # default 8 GB disk size is too small for FileStore + settings_dict['disk_size'] = 15 if libvirt_host is not None: settings_dict['libvirt_host'] = libvirt_host @@ -1064,6 +1069,14 @@ @cli.command() @click.argument('deployment_id') +@click.argument('node') +def reboot(deployment_id, node): + dep = Deployment.load(deployment_id) + dep.reboot_one_node(_print_log, node) + + +@cli.command() +@click.argument('deployment_id') @click.option('--non-interactive', '-n', '--force', '-f', is_flag=True, callback=_abort_if_false, @@ -1231,7 +1244,10 @@ node_name = 'master' if node is None else node if command: Log.info("Running SSH command on {}: {}".format(node_name, command)) - dep.ssh(node_name, command) + retval = dep.ssh(node_name, command) + assert isinstance(retval, int), "ssh method returned non-integer" + if retval != 0: + raise SSHCommandReturnedNonZero(retval) @cli.command() @@ -1471,3 +1487,22 @@ dep.dep_id) ) dep.start_port_forwarding(service, node, remote_port, local_port, local_address) + + +@cli.command() +@click.argument('deployment_id') +@click.argument('node') +@click.option('--devel/--product', 'devel_repos', default=True, is_flag=True, + help="Upgrade to devel or product repos (default: devel)") +@click.option('--to', 'to_version', default='octopus', type=str, show_default=True, + help='The local address to bind the tunnel') +def upgrade(deployment_id, node, devel_repos, to_version): + """ + What will happen when I issue this command on a node? + - old repositories will be wiped out + - new repositories will be added + - zypper dup + - reboot + """ + dep = Deployment.load(deployment_id) + dep.upgrade(_print_log, node, devel_repos, to_version) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/sesdev.spec new/sesdev-1.9.1+1603459604.g8c9ed2c/sesdev.spec --- old/sesdev-1.8.0+1602174240.g45df4dd/sesdev.spec 2020-10-08 18:24:00.346098514 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/sesdev.spec 2020-10-23 15:26:44.304071041 +0200 @@ -16,7 +16,7 @@ # Name: sesdev -Version: 1.8.0+1602174240.g45df4dd +Version: 1.9.1+1603459604.g8c9ed2c Release: 1%{?dist} Summary: CLI tool to deploy and manage SES clusters License: MIT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/constant.py new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/constant.py --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/constant.py 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/constant.py 2020-10-23 15:26:43.980071088 +0200 @@ -63,6 +63,13 @@ METADATA_FILENAME = ".metadata" + OPENSUSE_REPOS = { + 'leap-15.2': { + 'repo-oss': 'http://download.opensuse.org/distribution/leap/15.2/repo/oss/', + 'repo-update': 'http://download.opensuse.org/update/leap/15.2/oss/', + }, + } + OS_ALIASED_BOXES = { 'opensuse/Leap-15.2.x86_64': 'leap-15.2', 'opensuse/Tumbleweed.x86_64': 'tumbleweed', @@ -147,6 +154,8 @@ 'sles-15-sp1': { 'product': 'http://dist.suse.de/ibs/SUSE/Products/SLE-Product-SLES/15-SP1/x86_64/' 'product/', + 'product-update': 'http://dist.suse.de/ibs/SUSE/Updates/SLE-Product-SLES/15-SP1/' + 'x86_64/update/', 'base': 'http://download.suse.de/ibs/SUSE/Products/SLE-Module-Basesystem/15-SP1/' 'x86_64/product/', 'update': 'http://download.suse.de/ibs/SUSE/Updates/SLE-Module-Basesystem/15-SP1/' @@ -159,6 +168,10 @@ 'storage-update': 'http://download.suse.de/ibs/SUSE/Updates/Storage/6/x86_64/update/' }, 'sles-15-sp2': { + 'product': 'http://dist.suse.de/ibs/SUSE/Products/SLE-Product-SLES/15-SP2/x86_64/' + 'product/', + 'product-update': 'http://dist.suse.de/ibs/SUSE/Updates/SLE-Product-SLES/15-SP2/' + 'x86_64/update/', 'base': 'http://download.suse.de/ibs/SUSE/Products/SLE-Module-Basesystem/15-SP2/' 'x86_64/product/', 'update': 'http://download.suse.de/ibs/SUSE/Updates/SLE-Module-Basesystem/15-SP2/' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/deployment.py new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/deployment.py --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/deployment.py 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/deployment.py 2020-10-23 15:26:43.980071088 +0200 @@ -4,6 +4,7 @@ import random import re import shutil +import time from Cryptodome.PublicKey import RSA @@ -29,6 +30,7 @@ NoStorageRolesCephadm, \ NoSupportConfigTarballFound, \ ProductOptionOnlyOnSES, \ + RebootDidNotSucceed, \ RoleNotKnown, \ RoleNotSupported, \ ScpInvalidSourceOrDestination, \ @@ -39,7 +41,8 @@ VagrantSshConfigNoHostName, \ VersionOSNotSupported, \ UniqueRoleViolation, \ - UnsupportedVMEngine + UnsupportedVMEngine, \ + UpgradeNotSupported from .log import Log from .node import Node, NodeManager from .settings import Settings, SettingsEncoder @@ -100,6 +103,8 @@ self.version_devel_repos = None self.os_base_repos = None self.os_makecheck_repos = None + self.os_upgrade_repos = None + self.upgrade_devel_repos = None self.ceph_salt_fetch_github_pr_heads = None self.ceph_salt_fetch_github_pr_merges = None self.cephadm_bootstrap_node = None @@ -398,6 +403,12 @@ version = self.settings.version os_setting = self.settings.os version_devel_repos = self.settings.version_devel_repos[version][os_setting] + if version == 'nautilus': + upgrade_devel_repos = self.settings.version_devel_repos['octopus']['leap-15.2'] + elif version == 'ses6': + upgrade_devel_repos = self.settings.version_devel_repos['ses7']['sles-15-sp2'] + else: + upgrade_devel_repos = [] except KeyError as exc: raise VersionOSNotSupported(self.settings.version, self.settings.os) from exc # @@ -418,6 +429,7 @@ "priority": 0, } self.version_devel_repos.append(version_devel_repos_dict) + self.upgrade_devel_repos = upgrade_devel_repos Log.debug("_set_version_devel_repos: self.version_devel_repos: {}" .format(self.version_devel_repos)) @@ -426,6 +438,12 @@ self.os_base_repos = list(self.settings.os_repos[self.settings.os].items()) else: self.os_base_repos = [] + if self.settings.version == 'nautilus': + self.os_upgrade_repos = list(Constant.OPENSUSE_REPOS['leap-15.2'].items()) + elif self.settings.version == 'ses6': + self.os_upgrade_repos = list(self.settings.os_repos['sles-15-sp2'].items()) + else: + self.os_upgrade_repos = [] def __set_os_makecheck_repos(self): if self.settings.os in self.settings.os_makecheck_repos: @@ -569,6 +587,8 @@ 'bootstrap_mon_ip': self.bootstrap_mon_ip, 'msgr2_secure_mode': self.settings.msgr2_secure_mode, 'msgr2_prefer_secure': self.settings.msgr2_prefer_secure, + 'upgrade_devel_repos': self.upgrade_devel_repos, + 'os_upgrade_repos': self.os_upgrade_repos, } scripts = {} @@ -682,6 +702,53 @@ cmd.append('--debug') tools.run_async(cmd, log_handler, self._dep_dir) + def reboot_one_node(self, log_handler, node): + if node not in self.nodes: + raise NodeDoesNotExist(node, self.dep_id) + log_handler("=> running 'reboot' via SSH on node '{}'\n".format(node)) + ssh_cmd = ("bash -x -c 'reboot'",) + retval = self.ssh(node, ssh_cmd) + log_handler("=> interactive SSH command returned {}\n".format(retval)) + seconds_to_wait = 600 + log_handler("=> waiting up to {} seconds for node '{}' to come back from reboot\n" + .format(seconds_to_wait, node) + ) + interval_seconds = 15 + while True: + ssh_cmd = ("bash -x -c 'echo I am back'",) + retval = self.ssh(node, ssh_cmd) + if retval == 0: + break + log_handler("=> interactive SSH command returned {}\n".format(retval)) + seconds_to_wait -= interval_seconds + if seconds_to_wait <= 0: + log_handler("ERROR: node '{}' did not come back from reboot!\n".format(node)) + raise RebootDidNotSucceed(node, self.dep_id) + log_handler("=> waiting up to {} more seconds for node '{}' to come back from reboot\n" + .format(seconds_to_wait, node) + ) + time.sleep(interval_seconds) + log_handler("=> node '{}' is back from reboot!\n".format(node)) + seconds_to_wait = 600 + log_handler("=> waiting up to {} seconds for node '{}' to finish booting\n" + .format(seconds_to_wait, node) + ) + while True: + ssh_cmd = ("bash -x -c 'systemctl is-system-running'",) + retval = self.ssh(node, ssh_cmd) + if retval == 0: + break + log_handler("=> interactive SSH command returned {}\n".format(retval)) + seconds_to_wait -= interval_seconds + if seconds_to_wait <= 0: + log_handler("ERROR: node '{}' did not complete boot sequence!\n".format(node)) + raise RebootDidNotSucceed(node, self.dep_id) + log_handler("=> waiting up to {} more seconds for node '{}' to finish booting\n" + .format(seconds_to_wait, node) + ) + time.sleep(interval_seconds) + log_handler("=> node '{}' completed boot sequence!\n".format(node)) + def destroy(self, log_handler, destroy_networks=False): # if we are allowing networks to be destroyed, populate the networks @@ -1173,6 +1240,29 @@ ssh_cmd = ('rm', '/var/log/{}'.format(glob_to_get),) self.ssh(name, ssh_cmd) + def upgrade(self, log_handler, node, devel_repos=True, to_version='octopus'): + if node not in self.nodes: + raise NodeDoesNotExist(node, self.dep_id) + from_version = self.settings.version + if devel_repos: + devel_product = 'devel' + else: + devel_product = 'product' + version_combo_ok = False + if from_version == 'nautilus' and to_version == 'octopus': + version_combo_ok = True + if from_version == 'ses6' and to_version == 'ses7': + version_combo_ok = True + if version_combo_ok: + tools.run_async( + ["vagrant", "provision", node, "--provision-with", + 'upgrade-from-{}-to-{}-{}'.format(from_version, to_version, devel_product)], + log_handler, + self._dep_dir + ) + else: + raise UpgradeNotSupported(from_version, to_version) + def qa_test(self, log_handler): tools.run_async( ["vagrant", "provision", "--provision-with", "qa-test"], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/exceptions.py new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/exceptions.py --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/exceptions.py 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/exceptions.py 2020-10-23 15:26:43.980071088 +0200 @@ -1,5 +1,14 @@ class SesDevException(Exception): - pass + + def __init__(self, message, code=None): + self.message = message + self.code = code + super().__init__(self.code) + + def __str__(self): + if self.code is None: + return self.message + return "{} (code: {})".format(self.message, self.code) class AddRepoNoUpdateWithExplicitRepo(SesDevException): @@ -239,6 +248,14 @@ ) +class RebootDidNotSucceed(SesDevException): + def __init__(self, node, deployment_id): + super().__init__( + "Attempted to reboot node '{}' of deployment '{}', but ran into problems" + .format(node, deployment_id) + ) + + class RoleNotKnown(SesDevException): def __init__(self, role): super().__init__( @@ -298,6 +315,14 @@ ) +class SSHCommandReturnedNonZero(SesDevException): + def __init__(self, exitcode): + super().__init__( + "SSH command returned non-zero exit code", + code=exitcode + ) + + class SubcommandNotSupportedInVersion(SesDevException): def __init__(self, subcmd, version): super().__init__( @@ -352,6 +377,14 @@ ) +class UpgradeNotSupported(SesDevException): + def __init__(self, from_version, to_version): + super().__init__( + "You asked to upgrade a '{}' node to '{}', but this combination " + "is not supported".format(from_version, to_version) + ) + + class YouMustProvide(SesDevException): def __init__(self, what): super().__init__( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/Vagrantfile.j2 new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/Vagrantfile.j2 --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/Vagrantfile.j2 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/Vagrantfile.j2 2020-10-23 15:26:43.980071088 +0200 @@ -47,6 +47,23 @@ node.vm.provision "add-devel-repo-and-update", type: "shell", run: "never" do |s| s.inline = "/home/vagrant/add-devel-repo.sh --update" end + + node.vm.provision "upgrade-from-nautilus-to-octopus-devel", type: "shell", run: "never" do |s| + s.inline = "/home/vagrant/upgrade.sh --from nautilus --to octopus --devel" + end + + node.vm.provision "upgrade-from-nautilus-to-octopus-product", type: "shell", run: "never" do |s| + s.inline = "/home/vagrant/upgrade.sh --from nautilus --to octopus" + end + + node.vm.provision "upgrade-from-ses6-to-ses7-devel", type: "shell", run: "never" do |s| + s.inline = "/home/vagrant/upgrade.sh --from ses6 --to ses7 --devel" + end + + node.vm.provision "upgrade-from-ses6-to-ses7-product", type: "shell", run: "never" do |s| + s.inline = "/home/vagrant/upgrade.sh --from ses6 --to ses7" + end + end {% endfor %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/cephadm/deployment_day_2.sh.j2 new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/cephadm/deployment_day_2.sh.j2 --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/cephadm/deployment_day_2.sh.j2 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/cephadm/deployment_day_2.sh.j2 2020-10-23 15:26:43.980071088 +0200 @@ -73,7 +73,7 @@ {% if ceph_orch_apply_needed %} cat {{ service_spec_core }} -ceph orch apply -i {{ service_spec_core }} --dry-run +ceph orch apply -i {{ service_spec_core }} --dry-run || true ceph orch apply -i {{ service_spec_core }} {% endif %}{# ceph_orch_apply_needed #} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/helper_scripts.j2 new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/helper_scripts.j2 --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/helper_scripts.j2 1970-01-01 01:00:00.000000000 +0100 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/helper_scripts.j2 2020-10-23 15:26:43.980071088 +0200 @@ -0,0 +1,31 @@ + +# populate helper scripts +{% set is_os_script = "/home/vagrant/is_os.sh" %} +cat > {{ is_os_script }} << 'EOF' +#!/bin/bash -e +[[ "$*" =~ "sles-15.2" ]] && OS="sles-15.2" +[[ "$*" =~ "sles-15.1" ]] && OS="sles-15.1" +[[ "$*" =~ "leap-15.2" ]] && OS="leap-15.2" +[[ "$*" =~ "leap-15.1" ]] && OS="leap-15.1" +if [ -z "$OS" ] ; then + echo "is_os.sh: ERROR: unsupported OS" + exit 1 +fi + +function check_os { + local id_should_be="$1" + local version_id_should_be="$2" + source /etc/os-release + if [ "$ID" = "$id_should_be" ] && [ "$VERSION_ID" = "$version_id_should_be" ] ; then + exit 0 + else + exit 1 + fi +} + +[ "$OS" = "sles-15.2" ] && check_os sles 15.2 +[ "$OS" = "sles-15.1" ] && check_os sles 15.1 +[ "$OS" = "leap-15.1" ] && check_os opensuse-leap 15.1 +[ "$OS" = "leap-15.1" ] && check_os opensuse-leap 15.1 +EOF +chmod 755 {{ is_os_script }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/provision.sh.j2 new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/provision.sh.j2 --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/provision.sh.j2 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/provision.sh.j2 2020-10-23 15:26:43.980071088 +0200 @@ -55,14 +55,14 @@ set +x echo "Stopping the deployment now because the --no-provision option was given" exit 0 -{% endif %} {# not provision #} +{% endif %}{# not provision #} # if --ssd option was given, set rotational flag on first additional disk {% if ssd %} if [ -f /sys/block/vdb/queue/rotational ] ; then echo "0" > /sys/block/vdb/queue/rotational fi -{% endif %} {# ssd #} +{% endif %}{# ssd #} {% if package_manager == 'zypper' %} {% include "zypper.j2" ignore missing %} @@ -72,7 +72,10 @@ {% include "yum.j2" ignore missing %} {% elif package_manager == 'dnf' %} {% include "dnf.j2" ignore missing %} -{% endif %} {# package_manager == 'zypper' #} +{% endif %}{# package_manager == 'zypper' #} + +# include helper scripts +{% include "helper_scripts.j2" %} # sync clocks if needed {% include "sync_clocks.j2" %} @@ -85,7 +88,7 @@ {% if node == master %} {% include "salt/deepsea/deepsea_deployment.sh.j2" %} {% include "salt/qa_test.j2" %} -{% endif %} {# node == master #} +{% endif %}{# node == master #} # SUMA {% elif suma and node == suma %} @@ -99,7 +102,7 @@ {% include "salt/ceph-salt/deployment_day_1.sh.j2" %} {% include "cephadm/deployment_day_2.sh.j2" %} {% include "salt/qa_test.j2" %} -{% endif %} {# node == master #} +{% endif %}{# node == master #} # caasp4 {% elif version == 'caasp4' %} @@ -113,4 +116,4 @@ {% elif os.startswith('ubuntu') %} {% include "ubuntu/provision.sh.j2" %} -{% endif %} {# end of deploy state machine #} +{% endif %}{# end of deploy state machine #} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/salt/ceph-salt/deployment_day_1.sh.j2 new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/salt/ceph-salt/deployment_day_1.sh.j2 --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/salt/ceph-salt/deployment_day_1.sh.j2 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/salt/ceph-salt/deployment_day_1.sh.j2 2020-10-23 15:26:43.980071088 +0200 @@ -67,7 +67,7 @@ {% endif %} ceph-salt config /ssh/ generate -ceph-salt config /time_server/server_hostname set {{ master.fqdn }} +ceph-salt config /time_server/servers add {{ master.fqdn }} {% set external_timeserver = "pool.ntp.org" %} ceph-salt config /time_server/external_servers add {{ external_timeserver }} ceph-salt config /time_server/subnet set {{ public_network }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/salt/deepsea/nautilus_pre_stage_0.sh.j2 new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/salt/deepsea/nautilus_pre_stage_0.sh.j2 --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/salt/deepsea/nautilus_pre_stage_0.sh.j2 2020-10-08 18:24:00.026098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/salt/deepsea/nautilus_pre_stage_0.sh.j2 2020-10-23 15:26:43.980071088 +0200 @@ -7,23 +7,3 @@ echo "updates_init: nop" >> /srv/pillar/ceph/stack/global.yml echo "updates_restart: nop" >> /srv/pillar/ceph/stack/global.yml - -# cp /srv/salt/ceph/updates/default_my.sls /srv/salt/ceph/time -# sed -i 's/default/default_my/g' /srv/salt/ceph/time/init.sls - -cat > /root/mds-get-name.patch <<EOF ---- /srv/salt/_modules/mds.py -+++ /srv/salt/_modules/mds.py -@@ -17,6 +17,6 @@ def get_name(host): - MDS names must not start with a digit, so filter those out and prefix them - with "mds.". - """ -- if host[0].isdigit(): -+ if host[0].isdigit() or host == 'master': - return 'mds.{}'.format(host) - return host -EOF - -pushd / -patch -p0 < /root/mds-get-name.patch -popd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/zypper.j2 new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/zypper.j2 --- old/sesdev-1.8.0+1602174240.g45df4dd/seslib/templates/zypper.j2 2020-10-08 18:24:00.030098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/seslib/templates/zypper.j2 2020-10-23 15:26:43.980071088 +0200 @@ -3,6 +3,9 @@ # do not exclude documentation files when installing RPM packages sed -i 's/^rpm\.install\.excludedocs.*$/# rpm.install.excludedocs = no/' /etc/zypp/zypp.conf +# do not ignore "Recommends" and "Supplements" when resolving dependencies of RPM packages +sed -i 's/^solver\.onlyRequires.*$/# solver.onlyRequires = false/' /etc/zypp/zypp.conf + # enable autorefresh on all zypper repos find /etc/zypp/repos.d -type f -exec sed -i -e 's/^autorefresh=.*/autorefresh=1/' {} \; @@ -11,14 +14,14 @@ # known, allowing them to be explicitly declared {% if version != 'ses5' %} zypper --non-interactive remove curl || true -{% endif %} {# version != 'ses5' #} +{% endif %}{# version != 'ses5' #} zypper --non-interactive remove rsync || true zypper --non-interactive remove which || true # remove Python 2 so it doesn't pollute the environment {% if os != 'sles-12-sp3' %} zypper --non-interactive remove python-base || true -{% endif %} {# os != 'sles-12-sp3' #} +{% endif %}{# os != 'sles-12-sp3' #} # remove Non-OSS repos in openSUSE {% if os.startswith('leap') or os == "tumbleweed" %} @@ -27,7 +30,7 @@ zypper --non-interactive removerepo repo-debug-non-oss || true zypper --non-interactive removerepo repo-debug-update-non-oss || true zypper --non-interactive removerepo repo-source-non-oss || true -{% endif %} {# os.startswith('leap') or os == "tumbleweed" #} +{% endif %}{# os.startswith('leap') or os == "tumbleweed" #} # base repos {% for os_repo_name, os_repo_url in os_base_repos %} @@ -39,12 +42,12 @@ {% for os_repo_name, os_repo_url in os_makecheck_repos %} zypper addrepo --refresh {{ os_repo_url }} {{ os_repo_name }} {% endfor %} -{% endif %} {# version == 'makecheck' #} +{% endif %}{# version == 'makecheck' #} # devel repos {% set devel_repo_script = "/home/vagrant/add-devel-repo.sh" %} cat > {{ devel_repo_script }} << 'EOF' -#!/bin/bash +#!/bin/bash -x [[ "$*" =~ "--update" ]] && UPDATE="yes" set -x {% set devel_repo_count = version_devel_repos|length %} @@ -78,7 +81,7 @@ echo "{{ devel_repo_script }} failed! Bailing out." false fi -{% endif %} {# devel_repo or not core_version #} +{% endif %}{# devel_repo or not core_version #} # custom repos {% for _repo in node.custom_repos %} @@ -89,6 +92,85 @@ {{ _repo.url }} {{ _repo.name }} {% endfor %} +# populate upgrade script +{% set upgrade_script = "/home/vagrant/upgrade.sh" %} +cat > {{ upgrade_script }} << 'EOF' +#!/bin/bash -x +TEMP=$(getopt -o h --long "to:,from:,devel" -n 'upgrade.sh' -- "$@") || ( echo "Terminating..." >&2 ; exit 1 ) +eval set -- "$TEMP" +while true ; do + case "$1" in + --devel) DEVEL="--devel" ; shift ;; + --from) shift ; FROM_VERSION="$1" ; shift ;; + --to) shift ; TO_VERSION="$1" ; shift ;; + --) shift ; break ;; + *) echo "Internal error" ; exit 1 ;; + esac +done +source /etc/os-release +if [ "$FROM_VERSION" = "nautilus" ] ; then + if [ "$ID" = "opensuse-leap" ] && [ "$VERSION_ID" = "15.1" ] ; then + echo "Upgrading from Ceph Nautilus (openSUSE Leap 15.1)" + else + echo "ID is ->$ID<-" + echo "VERSION_ID is ->$VERSION_ID<-" + echo "Does not match ->opensuse-leap<- and ->15.1<-" + echo "Yet we were asked to upgrade from Ceph Nautilus" + exit 1 + fi + if [ "$TO_VERSION" = "octopus" ] ; then + echo "Upgrading to Ceph Octopus (openSUSE Leap 15.2)" + else + echo "TO_VERSION is ->$TO_VERSION<-" + echo "Does not match ->octopus<-" + echo "Yet we only support upgrading Nautilus to Octopus" + exit 1 + fi +elif [ "$FROM_VERSION" = "ses6" ] ; then + if [ "$ID" = "sles" ] && [ "$VERSION_ID" = "15.1" ] ; then + echo "Upgrading from SES6 (SLE-15-SP1)" + else + echo "ID is ->$ID<-" + echo "VERSION_ID is ->$VERSION_ID<-" + echo "Does not match ->sles<- and ->15.1<-" + echo "Yet we were asked to upgrade from SES6" + exit 1 + fi + if [ "$TO_VERSION" = "ses7" ] ; then + echo "Upgrading to SES7 (SLE-15-SP2)" + else + echo "TO_VERSION is ->$TO_VERSION<-" + echo "Does not match ->ses7<-" + echo "Yet we only support upgrading SES6 to SES7" + exit 1 + fi +fi +echo "=> clobber existing repos" > /dev/null +cp -a /etc/zypp/repos.d /etc/zypp/repos.d.bck +rm -f /etc/zypp/repos.d/* +echo "=> add os repos for $TO_VERSION" > /dev/null +{% for os_repo_name, os_repo_url in os_upgrade_repos %} +zypper addrepo --refresh {{ os_repo_url }} {{ os_repo_name }} +{% endfor %} +echo "=> add devel repos for $TO_VERSION" > /dev/null +if [ "$DEVEL" ] ; then +{% set devel_repo_count = upgrade_devel_repos|length %} +{% for _repo in upgrade_devel_repos %} +{% set devel_repo_name = "devel-repo-" ~ loop.index %} + zypper addrepo --refresh {{ _repo }} {{ devel_repo_name }} +{% endfor %} +fi +echo "=> refresh local metadata cache" > /dev/null +zypper --non-interactive --no-gpg-checks refresh +echo "=> dist-upgrade" > /dev/null +zypper dist-upgrade \ + --allow-vendor-change \ + --auto-agree-with-licenses \ + --no-confirm +EOF +chmod 755 {{ upgrade_script }} +cat {{ upgrade_script }} + # SUSE:CA repo on SLE {% if os.startswith("sle") %} zypper addrepo --refresh @@ -99,7 +181,7 @@ {%- elif os == 'sles-12-sp3' %} http://download.suse.de/ibs/SUSE:/CA/SLE_12_SP3/SUSE:CA.repo {% endif %} -{% endif %} {# os.startswith("sle") #} +{% endif %}{# os.startswith("sle") #} zypper --gpg-auto-import-keys refresh zypper repos --details @@ -107,7 +189,7 @@ {% if os == "sles-12-sp3" %} zypper --non-interactive install --from storage-update --force python-base python-xml zypper --non-interactive install --from update --force libncurses5 libncurses6 -{% endif %} {# os == "sles-12-sp3" #} +{% endif %}{# os == "sles-12-sp3" #} {% set basic_pkgs_to_install = [ 'vim', @@ -125,19 +207,18 @@ zypper --non-interactive install {{ basic_pkgs_to_install | join(' ') }} ntp {% else %} zypper --non-interactive install {{ basic_pkgs_to_install | join(' ') }} chrony hostname -{% endif %} {# os == 'sles-12-sp3' #} +{% endif %}{# os == 'sles-12-sp3' #} {% if os.startswith("sle") %} {% set sle_pkgs_to_install = [ 'ca-certificates-suse', 'supportutils', - 'supportutils-plugin-ses', ] %} zypper --non-interactive install {{ sle_pkgs_to_install | join(' ') }} -{% endif %} {# os.startswith("sle") #} +{% endif %}{# os.startswith("sle") #} {% if os in ['leap-15.2', 'sles-15-sp2'] %} # install rbd-nbd on all nodes: on SLE-15-SP2 it should be in the Base System # module zypper --non-interactive install rbd-nbd -{% endif %} {# os in ['leap-15.2', 'sles-15-sp2'] #} +{% endif %}{# os in ['leap-15.2', 'sles-15-sp2'] #} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sesdev-1.8.0+1602174240.g45df4dd/setup.cfg new/sesdev-1.9.1+1603459604.g8c9ed2c/setup.cfg --- old/sesdev-1.8.0+1602174240.g45df4dd/setup.cfg 2020-10-08 18:24:00.030098542 +0200 +++ new/sesdev-1.9.1+1603459604.g8c9ed2c/setup.cfg 2020-10-23 15:26:43.980071088 +0200 @@ -43,6 +43,7 @@ templates/salt/ceph-salt/*.j2 templates/salt/deepsea/*.j2 templates/salt/suma/*.j2 + templates/cephadm/*.j2 [options.entry_points] console_scripts =