diff --git a/releasenotes/notes/external-update-upgrade-8c354d66d8ad5ecc.yaml b/releasenotes/notes/external-update-upgrade-8c354d66d8ad5ecc.yaml new file mode 100644 index 000000000..86ee90343 --- /dev/null +++ b/releasenotes/notes/external-update-upgrade-8c354d66d8ad5ecc.yaml @@ -0,0 +1,10 @@ +--- +upgrade: + - | + New `openstack overcloud external-update run` and `openstack + overcloud external-upgrade run` commands are defined. These are + meant to perform updates and upgrades for services deployed via + external_deploy_tasks. A separate command is used because external + installers don't fit well within the --nodes and --roles selection + pattern we've established for the normal `update run` and `upgrade + run` commands. diff --git a/setup.cfg b/setup.cfg index 8e04e20fe..31c9b8e5f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -90,6 +90,8 @@ openstack.tripleoclient.v1 = overcloud_upgrade_prepare = tripleoclient.v1.overcloud_upgrade:UpgradePrepare overcloud_upgrade_run = tripleoclient.v1.overcloud_upgrade:UpgradeRun overcloud_upgrade_converge = tripleoclient.v1.overcloud_upgrade:UpgradeConvergeOvercloud + overcloud_external-update_run = tripleoclient.v1.overcloud_external_update:ExternalUpdateRun + overcloud_external-upgrade_run = tripleoclient.v1.overcloud_external_upgrade:ExternalUpgradeRun overcloud_ceph-upgrade_run = tripleoclient.v1.overcloud_ceph_upgrade:CephUpgrade overcloud_ffwd-upgrade_prepare = tripleoclient.v1.overcloud_ffwd_upgrade:FFWDUpgradePrepare overcloud_ffwd-upgrade_run = tripleoclient.v1.overcloud_ffwd_upgrade:FFWDUpgradeRun diff --git a/tripleoclient/constants.py b/tripleoclient/constants.py index 41fd83e30..d2c74bf0d 100644 --- a/tripleoclient/constants.py +++ b/tripleoclient/constants.py @@ -44,6 +44,8 @@ UPDATE_QUEUE = 'update' UPGRADE_QUEUE = 'upgrade' FFWD_UPGRADE_QUEUE = 'ffwdupgrade' CEPH_UPGRADE_QUEUE = 'cephupgrade' +EXTERNAL_UPDATE_QUEUE = 'externalupdate' +EXTERNAL_UPGRADE_QUEUE = 'externalupgrade' STACK_TIMEOUT = 240 @@ -56,6 +58,8 @@ MAJOR_UPGRADE_PLAYBOOKS = ["upgrade_steps_playbook.yaml", "deploy_steps_playbook.yaml", "post_upgrade_steps_playbook.yaml"] MAJOR_UPGRADE_SKIP_TAGS = ['validation', 'pre-upgrade'] +EXTERNAL_UPDATE_PLAYBOOKS = ['external_update_steps_playbook.yaml'] +EXTERNAL_UPGRADE_PLAYBOOKS = ['external_upgrade_steps_playbook.yaml'] # upgrade environment files expected by the client in the --templates # tripleo-heat-templates default above $TRIPLEO_HEAT_TEMPLATES UPDATE_PREPARE_ENV = "environments/lifecycle/update-prepare.yaml" diff --git a/tripleoclient/tests/v1/overcloud_external_update/__init__.py b/tripleoclient/tests/v1/overcloud_external_update/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tripleoclient/tests/v1/overcloud_external_update/fakes.py b/tripleoclient/tests/v1/overcloud_external_update/fakes.py new file mode 100644 index 000000000..8867cd35f --- /dev/null +++ b/tripleoclient/tests/v1/overcloud_external_update/fakes.py @@ -0,0 +1,49 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import mock +from osc_lib.tests import utils + +from tripleoclient.tests import fakes + + +class FakeClientWrapper(object): + + def __init__(self): + self._instance = mock.Mock() + self.object_store = FakeObjectClient() + + def messaging_websocket(self): + return fakes.FakeWebSocket() + + +class FakeObjectClient(object): + + def __init__(self): + self._instance = mock.Mock() + self.put_object = mock.Mock() + + def get_object(self, *args): + return + + +class TestOvercloudExternalUpdateRun(utils.TestCommand): + + def setUp(self): + super(TestOvercloudExternalUpdateRun, self).setUp() + + self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN") + self.app.client_manager.tripleoclient = FakeClientWrapper() + self.app.client_manager.workflow_engine = mock.Mock() diff --git a/tripleoclient/tests/v1/overcloud_external_update/test_overcloud_external_update.py b/tripleoclient/tests/v1/overcloud_external_update/test_overcloud_external_update.py new file mode 100644 index 000000000..9e014a60a --- /dev/null +++ b/tripleoclient/tests/v1/overcloud_external_update/test_overcloud_external_update.py @@ -0,0 +1,66 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import mock + +from tripleoclient import constants +from tripleoclient.tests.v1.overcloud_external_update import fakes +from tripleoclient.v1 import overcloud_external_update + + +class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun): + + def setUp(self): + super(TestOvercloudExternalUpdateRun, self).setUp() + + # Get the command object to test + app_args = mock.Mock() + app_args.verbose_level = 1 + self.cmd = overcloud_external_update.ExternalUpdateRun( + self.app, app_args) + + uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4") + self.mock_uuid4 = uuid4_patcher.start() + self.addCleanup(self.mock_uuid4.stop) + + @mock.patch('tripleoclient.workflows.package_update.update_ansible', + autospec=True) + @mock.patch('os.path.expanduser') + @mock.patch('oslo_concurrency.processutils.execute') + @mock.patch('six.moves.builtins.open') + def test_update_with_user_and_tags(self, mock_open, mock_execute, + mock_expanduser, update_ansible): + mock_expanduser.return_value = '/home/fake/' + argslist = ['--ssh-user', 'tripleo-admin', + '--tags', 'ceph'] + verifylist = [ + ('ssh_user', 'tripleo-admin'), + ('tags', 'ceph'), + ] + + parsed_args = self.check_parser(self.cmd, argslist, verifylist) + with mock.patch('os.path.exists') as mock_exists: + mock_exists.return_value = True + self.cmd.take_action(parsed_args) + update_ansible.assert_called_once_with( + self.app.client_manager, + nodes='all', + inventory_file=mock_open().read(), + playbook='external_update_steps_playbook.yaml', + ansible_queue_name=constants.EXTERNAL_UPDATE_QUEUE, + node_user='tripleo-admin', + tags='ceph', + skip_tags='', + ) diff --git a/tripleoclient/tests/v1/overcloud_external_upgrade/__init__.py b/tripleoclient/tests/v1/overcloud_external_upgrade/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tripleoclient/tests/v1/overcloud_external_upgrade/fakes.py b/tripleoclient/tests/v1/overcloud_external_upgrade/fakes.py new file mode 100644 index 000000000..60d5d8c33 --- /dev/null +++ b/tripleoclient/tests/v1/overcloud_external_upgrade/fakes.py @@ -0,0 +1,49 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import mock +from osc_lib.tests import utils + +from tripleoclient.tests import fakes + + +class FakeClientWrapper(object): + + def __init__(self): + self._instance = mock.Mock() + self.object_store = FakeObjectClient() + + def messaging_websocket(self): + return fakes.FakeWebSocket() + + +class FakeObjectClient(object): + + def __init__(self): + self._instance = mock.Mock() + self.put_object = mock.Mock() + + def get_object(self, *args): + return + + +class TestOvercloudExternalUpgradeRun(utils.TestCommand): + + def setUp(self): + super(TestOvercloudExternalUpgradeRun, self).setUp() + + self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN") + self.app.client_manager.tripleoclient = FakeClientWrapper() + self.app.client_manager.workflow_engine = mock.Mock() diff --git a/tripleoclient/tests/v1/overcloud_external_upgrade/test_overcloud_external_upgrade.py b/tripleoclient/tests/v1/overcloud_external_upgrade/test_overcloud_external_upgrade.py new file mode 100644 index 000000000..b85aa86b6 --- /dev/null +++ b/tripleoclient/tests/v1/overcloud_external_upgrade/test_overcloud_external_upgrade.py @@ -0,0 +1,66 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import mock + +from tripleoclient import constants +from tripleoclient.tests.v1.overcloud_external_upgrade import fakes +from tripleoclient.v1 import overcloud_external_upgrade + + +class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun): + + def setUp(self): + super(TestOvercloudExternalUpgradeRun, self).setUp() + + # Get the command object to test + app_args = mock.Mock() + app_args.verbose_level = 1 + self.cmd = overcloud_external_upgrade.ExternalUpgradeRun( + self.app, app_args) + + uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4") + self.mock_uuid4 = uuid4_patcher.start() + self.addCleanup(self.mock_uuid4.stop) + + @mock.patch('tripleoclient.workflows.package_update.update_ansible', + autospec=True) + @mock.patch('os.path.expanduser') + @mock.patch('oslo_concurrency.processutils.execute') + @mock.patch('six.moves.builtins.open') + def test_upgrade_with_user_and_tags(self, mock_open, mock_execute, + mock_expanduser, update_ansible): + mock_expanduser.return_value = '/home/fake/' + argslist = ['--ssh-user', 'tripleo-admin', + '--tags', 'ceph'] + verifylist = [ + ('ssh_user', 'tripleo-admin'), + ('tags', 'ceph'), + ] + + parsed_args = self.check_parser(self.cmd, argslist, verifylist) + with mock.patch('os.path.exists') as mock_exists: + mock_exists.return_value = True + self.cmd.take_action(parsed_args) + update_ansible.assert_called_once_with( + self.app.client_manager, + nodes='all', + inventory_file=mock_open().read(), + playbook='external_upgrade_steps_playbook.yaml', + ansible_queue_name=constants.EXTERNAL_UPGRADE_QUEUE, + node_user='tripleo-admin', + tags='ceph', + skip_tags='', + ) diff --git a/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py b/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py index 32c175acc..a80211eee 100644 --- a/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py +++ b/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py @@ -163,6 +163,7 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun): nodes='', playbook=constants.FFWD_UPGRADE_PLAYBOOK, node_user='heat-admin', + tags='', skip_tags='' ) @@ -188,6 +189,7 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun): nodes='', playbook=constants.FFWD_UPGRADE_PLAYBOOK, node_user='my-user', + tags='', skip_tags='' ) diff --git a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py index 286c20282..30edb8db9 100644 --- a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py +++ b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py @@ -152,6 +152,7 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun): playbook='fake-playbook.yaml', ansible_queue_name=constants.UPDATE_QUEUE, node_user='tripleo-admin', + tags='', skip_tags='' ) @@ -182,6 +183,7 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun): playbook=book, ansible_queue_name=constants.UPDATE_QUEUE, node_user='heat-admin', + tags='', skip_tags='' ) @@ -211,6 +213,7 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun): playbook=book, ansible_queue_name=constants.UPDATE_QUEUE, node_user='heat-admin', + tags='', skip_tags='' ) diff --git a/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py b/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py index ee69a17fe..fd2ceeaae 100644 --- a/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py +++ b/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py @@ -170,6 +170,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): playbook='fake-playbook.yaml', ansible_queue_name=constants.UPGRADE_QUEUE, node_user='tripleo-admin', + tags='', skip_tags='' ) @@ -202,6 +203,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): playbook=book, ansible_queue_name=constants.UPGRADE_QUEUE, node_user='heat-admin', + tags='', skip_tags='validation' ) @@ -232,6 +234,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): playbook='fake-playbook.yaml', ansible_queue_name=constants.UPGRADE_QUEUE, node_user='heat-admin', + tags='', skip_tags='' ) @@ -262,6 +265,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): playbook=book, ansible_queue_name=constants.UPGRADE_QUEUE, node_user='heat-admin', + tags='', skip_tags='' ) @@ -294,6 +298,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): playbook=book, ansible_queue_name=constants.UPGRADE_QUEUE, node_user='heat-admin', + tags='', skip_tags='pre-upgrade,validation' ) diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index b27fda1e7..88dfc7223 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -948,7 +948,7 @@ def process_multiple_environments(created_env_files, tht_root, def run_update_ansible_action(log, clients, nodes, inventory, playbook, queue, all_playbooks, action, ssh_user, - skip_tags=''): + tags='', skip_tags=''): playbooks = [playbook] if playbook == "all": playbooks = all_playbooks @@ -956,7 +956,8 @@ def run_update_ansible_action(log, clients, nodes, inventory, playbook, log.debug("Running ansible playbook %s " % book) action.update_ansible(clients, nodes=nodes, inventory_file=inventory, playbook=book, ansible_queue_name=queue, - node_user=ssh_user, skip_tags=skip_tags) + node_user=ssh_user, tags=tags, + skip_tags=skip_tags) def prepend_environment(environment_files, templates_dir, environment): diff --git a/tripleoclient/v1/overcloud_external_update.py b/tripleoclient/v1/overcloud_external_update.py new file mode 100644 index 000000000..e7e48623b --- /dev/null +++ b/tripleoclient/v1/overcloud_external_update.py @@ -0,0 +1,102 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +from oslo_config import cfg +from oslo_log import log as logging + +from osc_lib.i18n import _ +from osc_lib import utils + +from tripleoclient import command +from tripleoclient import constants +from tripleoclient import utils as oooutils +from tripleoclient.workflows import package_update + +CONF = cfg.CONF +logging.register_options(CONF) +logging.setup(CONF, '') + + +class ExternalUpdateRun(command.Command): + """Run external minor update Ansible playbook + + This will run the external minor update Ansible playbook, + executing tasks from the undercloud. The update playbooks are + made available after completion of the 'overcloud update + prepare' command. + + """ + + log = logging.getLogger(__name__ + ".ExternalUpdateRun") + + def get_parser(self, prog_name): + parser = super(ExternalUpdateRun, self).get_parser(prog_name) + parser.add_argument('--static-inventory', + dest='static_inventory', + action="store", + default=None, + help=_('Path to an existing ansible inventory to ' + 'use. If not specified, one will be ' + 'generated in ' + '~/tripleo-ansible-inventory.yaml') + ) + parser.add_argument("--ssh-user", + dest="ssh_user", + action="store", + default="heat-admin", + help=_("The ssh user name for connecting to " + "the overcloud nodes.") + ) + parser.add_argument('--tags', + dest='tags', + action="store", + default="", + help=_('A string specifying the tag or comma ' + 'separated list of tags to be passed ' + 'as --tags to ansible-playbook. ') + ) + parser.add_argument('--skip-tags', + dest='skip_tags', + action="store", + default="", + help=_('A string specifying the tag or comma ' + 'separated list of tags to be passed ' + 'as --skip-tags to ansible-playbook. ') + ) + parser.add_argument('--stack', dest='stack', + help=_('Name or ID of heat stack ' + '(default=Env: OVERCLOUD_STACK_NAME)'), + default=utils.env('OVERCLOUD_STACK_NAME', + default='overcloud')) + + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)" % parsed_args) + clients = self.app.client_manager + stack = parsed_args.stack + + # Run ansible: + inventory = oooutils.get_tripleo_ansible_inventory( + parsed_args.static_inventory, parsed_args.ssh_user, stack) + limit_hosts = 'all' + playbook = 'all' + oooutils.run_update_ansible_action( + self.log, clients, limit_hosts, inventory, playbook, + constants.EXTERNAL_UPDATE_QUEUE, + constants.EXTERNAL_UPDATE_PLAYBOOKS, + package_update, parsed_args.ssh_user, + tags=parsed_args.tags, skip_tags=parsed_args.skip_tags) + + self.log.info("Completed Overcloud External Update Run.") diff --git a/tripleoclient/v1/overcloud_external_upgrade.py b/tripleoclient/v1/overcloud_external_upgrade.py new file mode 100644 index 000000000..e6f1b3c39 --- /dev/null +++ b/tripleoclient/v1/overcloud_external_upgrade.py @@ -0,0 +1,102 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +from oslo_config import cfg +from oslo_log import log as logging + +from osc_lib.i18n import _ +from osc_lib import utils + +from tripleoclient import command +from tripleoclient import constants +from tripleoclient import utils as oooutils +from tripleoclient.workflows import package_update + +CONF = cfg.CONF +logging.register_options(CONF) +logging.setup(CONF, '') + + +class ExternalUpgradeRun(command.Command): + """Run external major upgrade Ansible playbook + + This will run the external major upgrade Ansible playbook, + executing tasks from the undercloud. The upgrade playbooks are + made available after completion of the 'overcloud upgrade + prepare' command. + + """ + + log = logging.getLogger(__name__ + ".ExternalUpgradeRun") + + def get_parser(self, prog_name): + parser = super(ExternalUpgradeRun, self).get_parser(prog_name) + parser.add_argument('--static-inventory', + dest='static_inventory', + action="store", + default=None, + help=_('Path to an existing ansible inventory to ' + 'use. If not specified, one will be ' + 'generated in ' + '~/tripleo-ansible-inventory.yaml') + ) + parser.add_argument("--ssh-user", + dest="ssh_user", + action="store", + default="heat-admin", + help=_("The ssh user name for connecting to " + "the overcloud nodes.") + ) + parser.add_argument('--tags', + dest='tags', + action="store", + default="", + help=_('A string specifying the tag or comma ' + 'separated list of tags to be passed ' + 'as --tags to ansible-playbook. ') + ) + parser.add_argument('--skip-tags', + dest='skip_tags', + action="store", + default="", + help=_('A string specifying the tag or comma ' + 'separated list of tags to be passed ' + 'as --skip-tags to ansible-playbook. ') + ) + parser.add_argument('--stack', dest='stack', + help=_('Name or ID of heat stack ' + '(default=Env: OVERCLOUD_STACK_NAME)'), + default=utils.env('OVERCLOUD_STACK_NAME', + default='overcloud')) + + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)" % parsed_args) + clients = self.app.client_manager + stack = parsed_args.stack + + # Run ansible: + inventory = oooutils.get_tripleo_ansible_inventory( + parsed_args.static_inventory, parsed_args.ssh_user, stack) + limit_hosts = 'all' + playbook = 'all' + oooutils.run_update_ansible_action( + self.log, clients, limit_hosts, inventory, playbook, + constants.EXTERNAL_UPGRADE_QUEUE, + constants.EXTERNAL_UPGRADE_PLAYBOOKS, + package_update, parsed_args.ssh_user, + tags=parsed_args.tags, skip_tags=parsed_args.skip_tags) + + self.log.info("Completed Overcloud External Upgrade Run.") diff --git a/tripleoclient/v1/overcloud_upgrade.py b/tripleoclient/v1/overcloud_upgrade.py index c368b5867..939ee6d8e 100644 --- a/tripleoclient/v1/overcloud_upgrade.py +++ b/tripleoclient/v1/overcloud_upgrade.py @@ -219,7 +219,8 @@ class UpgradeRun(command.Command): constants.UPGRADE_QUEUE, constants.MAJOR_UPGRADE_PLAYBOOKS, package_update, - parsed_args.ssh_user, skip_tags) + parsed_args.ssh_user, + skip_tags=skip_tags) playbooks = (constants.MAJOR_UPGRADE_PLAYBOOKS if playbook == 'all' else playbook)