Display prestage status and versions in subcloud list

The prestage release can be either the previous or current release for
a subcloud. Checking the prestage release individually on thousands of
subclouds is impractical. Therefore, a new column called "prestage
versions" is added to the output of the "dcmanager subcloud list'
command. Besides, decoupling prestage status from deploy status.

Test plan:
PASS: Successful subcloud prestage with specified 22.12 or 23.09
      release, and verified the correct "prestage versions" output of
      the "dcmanager subcloud list" command.
PASS: Successful prestage strategy with specified 22.12 or 23.09
      release, and verified the correct "prestage versions" output of
      the "dcmanager subcloud list".
PASS: Verified the "prestage status" at each prestage stage.
PASS: Verified that the 'deploy status' was updated to 'complete' after
      upgrading the system controller from version 22.12 to 23.09.
      This verification was performed specifically for those subclouds
      that had a 'prestage-complete' deploy status with the previous
      22.12 system controller. The new columns, "perstage status" and
      "prestage versions", were empty after upgrading.

Depends-on:
https://review.opendev.org/c/starlingx/ansible-playbooks/+/904546

Story: 2010611
Task: 49367

Change-Id: Ica65b1e2e8e44b96352e7d45439a2e7a9063f7c9
Signed-off-by: lzhu1 <li.zhu@windriver.com>
This commit is contained in:
Li Zhu 2024-01-02 22:30:26 -05:00
parent 91c9d301d8
commit 00a3e50e71
31 changed files with 322 additions and 109 deletions

View File

@ -78,6 +78,8 @@ Response
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -222,6 +224,8 @@ This operation does not accept a request body.
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
- systemcontroller-gateway-ip: systemcontroller_gateway_ip - systemcontroller-gateway-ip: systemcontroller_gateway_ip
@ -286,6 +290,8 @@ This operation does not accept a request body.
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -399,6 +405,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -473,6 +481,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
- systemcontroller-gateway-ip: systemcontroller_gateway_ip - systemcontroller-gateway-ip: systemcontroller_gateway_ip
@ -544,6 +554,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -809,6 +821,8 @@ This operation does not accept a request body.
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -978,6 +992,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -1090,6 +1106,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -1815,6 +1833,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- error-description: error_description - error-description: error_description
- region-name: region_name - region-name: region_name
- management-subnet: management_subnet - management-subnet: management_subnet
@ -1883,6 +1903,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- error-description: error_description - error-description: error_description
- region-name: region_name - region-name: region_name
- management-subnet: management_subnet - management-subnet: management_subnet
@ -1951,6 +1973,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -2025,6 +2049,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -2093,6 +2119,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -2161,6 +2189,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- region-name: region_name - region-name: region_name
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
@ -2237,6 +2267,8 @@ Request Example
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- error-description: error_description - error-description: error_description
- region-name: region_name - region-name: region_name
- management-subnet: management_subnet - management-subnet: management_subnet
@ -2774,6 +2806,8 @@ This operation does not accept a request body.
- deploy-status: deploy_status - deploy-status: deploy_status
- backup-status: backup_status - backup-status: backup_status
- backup-datetime: backup_datetime - backup-datetime: backup_datetime
- prestage-status: prestage_status
- prestage-versions: prestage_versions
- openstack-installed: openstack_installed - openstack-installed: openstack_installed
- management-state: management_state - management-state: management_state
- systemcontroller-gateway-ip: systemcontroller_gateway_ip - systemcontroller-gateway-ip: systemcontroller_gateway_ip

View File

@ -478,6 +478,18 @@ prestage_software_version:
in: body in: body
required: true required: true
type: string type: string
prestage_status:
description: |
The prestage status of the subcloud.
in: body
required: true
type: string
prestage_versions:
description: |
All of the prestage versions of the subcloud.
in: body
required: true
type: string
region_name: region_name:
description: | description: |
The name provisioned for the subcloud (synonym for subcloud name). The name provisioned for the subcloud (synonym for subcloud name).

View File

@ -9,6 +9,8 @@
"deploy-status": "aborting-install", "deploy-status": "aborting-install",
"backup-status": null, "backup-status": null,
"backup-datetime": null, "backup-datetime": null,
"prestage-status": null,
"prestage-versions": null,
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -9,6 +9,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2023-05-02 11:23:58.132134", "backup-datetime": "2023-05-02 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -9,6 +9,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2023-05-02 11:23:58.132134", "backup-datetime": "2023-05-02 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -9,6 +9,8 @@
"deploy-status": "pre-install", "deploy-status": "pre-install",
"backup-status": null, "backup-status": null,
"backup-datetime": null, "backup-datetime": null,
"prestage-status": null,
"prestage-versions": null,
"error-description": "No errors present", "error-description": "No errors present",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"management-subnet": "192.168.102.0/24", "management-subnet": "192.168.102.0/24",

View File

@ -9,6 +9,8 @@
"deploy-status": "pre-install", "deploy-status": "pre-install",
"backup-status": null, "backup-status": null,
"backup-datetime": null, "backup-datetime": null,
"prestage-status": null,
"prestage-versions": null,
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -9,6 +9,8 @@
"deploy-status": "not-deployed", "deploy-status": "not-deployed",
"backup-status": null, "backup-status": null,
"backup-datetime": null, "backup-datetime": null,
"prestage-status": null,
"prestage-versions": null,
"error-description": "No errors present", "error-description": "No errors present",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"management-subnet": "192.168.102.0/24", "management-subnet": "192.168.102.0/24",

View File

@ -14,6 +14,8 @@
"error-description": "", "error-description": "",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -14,6 +14,8 @@
"error-description": "", "error-description": "",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -12,6 +12,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"openstack-installed": false, "openstack-installed": false,
"management-state": "managed", "management-state": "managed",

View File

@ -10,6 +10,8 @@
"deploy-status": "secondary", "deploy-status": "secondary",
"backup-status": null, "backup-status": null,
"backup-datetime": null, "backup-datetime": null,
"prestage-status": null,
"prestage-versions": null,
"error-description": "No errors present", "error-description": "No errors present",
"management-subnet": "192.168.38.0/24", "management-subnet": "192.168.38.0/24",
"management-start-ip": "192.168.38.2", "management-start-ip": "192.168.38.2",

View File

@ -9,6 +9,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "21.12,22.12",
"openstack-installed": false, "openstack-installed": false,
"management-state": "managed", "management-state": "managed",
"systemcontroller-gateway-ip": "192.168.204.101", "systemcontroller-gateway-ip": "192.168.204.101",

View File

@ -9,6 +9,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "21.12,22.12",
"openstack-installed": false, "openstack-installed": false,
"management-state": "managed", "management-state": "managed",
"systemcontroller-gateway-ip": "192.168.204.101", "systemcontroller-gateway-ip": "192.168.204.101",

View File

@ -11,6 +11,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "21.12,22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -11,6 +11,8 @@
"deploy-status": "pre-install", "deploy-status": "pre-install",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "21.12,22.12",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,
"location": "YOW", "location": "YOW",

View File

@ -9,6 +9,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "21.12,22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"description": "Ottawa Site", "description": "Ottawa Site",
"group_id": 1, "group_id": 1,

View File

@ -12,6 +12,8 @@
"deploy-status": "complete", "deploy-status": "complete",
"backup-status": "complete", "backup-status": "complete",
"backup-datetime": "2022-07-08 11:23:58.132134", "backup-datetime": "2022-07-08 11:23:58.132134",
"prestage-status": "complete",
"prestage-versions": "21.12,22.12",
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4", "region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
"openstack-installed": false, "openstack-installed": false,
"management-state": "managed", "management-state": "managed",

View File

@ -20,7 +20,6 @@ from dcmanager.common.context import RequestContext
from dcmanager.common import exceptions from dcmanager.common import exceptions
from dcmanager.common.i18n import _ from dcmanager.common.i18n import _
from dcmanager.common import phased_subcloud_deploy as psd_common from dcmanager.common import phased_subcloud_deploy as psd_common
from dcmanager.common import prestage
from dcmanager.common import utils from dcmanager.common import utils
from dcmanager.db import api as db_api from dcmanager.db import api as db_api
from dcmanager.db.sqlalchemy import models from dcmanager.db.sqlalchemy import models
@ -301,11 +300,14 @@ class PhasedSubcloudDeployController(object):
if not payload: if not payload:
pecan.abort(400, _('Body required')) pecan.abort(400, _('Body required'))
if not (subcloud.deploy_status in VALID_STATES_FOR_DEPLOY_CONFIG or if subcloud.deploy_status not in VALID_STATES_FOR_DEPLOY_CONFIG:
prestage.is_deploy_status_prestage(subcloud.deploy_status)):
allowed_states_str = ', '.join(VALID_STATES_FOR_DEPLOY_CONFIG) allowed_states_str = ', '.join(VALID_STATES_FOR_DEPLOY_CONFIG)
pecan.abort(400, _('Subcloud deploy status must be either ' pecan.abort(400, _('Subcloud deploy status must be %s') %
'%s or prestage-...') % allowed_states_str) allowed_states_str)
if subcloud.prestage_status in consts.STATES_FOR_ONGOING_PRESTAGE:
pecan.abort(400, _('Subcloud prestage is ongoing %s') %
subcloud.prestage_status)
psd_common.populate_payload_with_pre_existing_data( psd_common.populate_payload_with_pre_existing_data(
payload, subcloud, SUBCLOUD_CONFIG_GET_FILE_CONTENTS) payload, subcloud, SUBCLOUD_CONFIG_GET_FILE_CONTENTS)

View File

@ -601,16 +601,16 @@ class SubcloudsController(object):
# Rename the subcloud # Rename the subcloud
new_subcloud_name = payload.get('name') new_subcloud_name = payload.get('name')
if new_subcloud_name is not None: if new_subcloud_name is not None:
# To be renamed the subcloud must be in unmanaged and valid deploy # To be renamed the subcloud must be in unmanaged, valid deploy
# state # state, and no going prestage
if (subcloud.management_state != if (subcloud.management_state !=
dccommon_consts.MANAGEMENT_UNMANAGED or dccommon_consts.MANAGEMENT_UNMANAGED or
subcloud.deploy_status not in subcloud.deploy_status != consts.DEPLOY_STATE_DONE or
consts.STATES_FOR_SUBCLOUD_RENAME): subcloud.prestage_status in
msg = ( consts.STATES_FOR_ONGOING_PRESTAGE):
'Subcloud %s must be unmanaged and in a valid deploy state ' msg = ('Subcloud %s must be deployed, unmanaged and '
'for the subcloud rename operation.' % subcloud.name 'no ongoing prestage for the subcloud rename '
) 'operation.' % subcloud.name)
pecan.abort(400, msg) pecan.abort(400, msg)
# Validates new name # Validates new name
@ -890,8 +890,9 @@ class SubcloudsController(object):
try: try:
self.dcmanager_rpc_client.prestage_subcloud(context, payload) self.dcmanager_rpc_client.prestage_subcloud(context, payload)
# local update to deploy_status - this is just for CLI response: # local update to prestage_status - this is just for
subcloud.deploy_status = consts.PRESTAGE_STATE_PACKAGES # CLI response:
subcloud.prestage_status = consts.PRESTAGE_STATE_PACKAGES
subcloud_dict = db_api.subcloud_db_model_to_dict(subcloud) subcloud_dict = db_api.subcloud_db_model_to_dict(subcloud)
subcloud_dict.update( subcloud_dict.update(

View File

@ -33,7 +33,6 @@ from dcmanager.common import context
from dcmanager.common import exceptions from dcmanager.common import exceptions
from dcmanager.common.i18n import _ from dcmanager.common.i18n import _
from dcmanager.common import manager from dcmanager.common import manager
from dcmanager.common import prestage
from dcmanager.common import scheduler from dcmanager.common import scheduler
from dcmanager.db import api as db_api from dcmanager.db import api as db_api
from dcmanager.rpc import client as dcmanager_rpc_client from dcmanager.rpc import client as dcmanager_rpc_client
@ -124,9 +123,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
consts.DEPLOY_STATE_RESTORING, consts.DEPLOY_STATE_RESTORING,
consts.DEPLOY_STATE_RESTORE_PREP_FAILED, consts.DEPLOY_STATE_RESTORE_PREP_FAILED,
consts.DEPLOY_STATE_RESTORE_FAILED, consts.DEPLOY_STATE_RESTORE_FAILED,
consts.DEPLOY_STATE_REHOME_PENDING] consts.DEPLOY_STATE_REHOME_PENDING]) or (
and not prestage.is_deploy_status_prestage(
subcloud.deploy_status)) or (
(subcloud.deploy_status in [ (subcloud.deploy_status in [
consts.DEPLOY_STATE_INSTALLING, consts.DEPLOY_STATE_INSTALLING,
consts.DEPLOY_STATE_REHOME_PENDING]) consts.DEPLOY_STATE_REHOME_PENDING])
@ -431,8 +428,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
# Avoid a network call to sysinv here if possible: # Avoid a network call to sysinv here if possible:
# If prestaging is active we can assume that the subcloud # If prestaging is active we can assume that the subcloud
# is online (otherwise prestaging will fail): # is online (otherwise prestaging will fail):
if subcloud.deploy_status in (consts.PRESTAGE_STATE_PACKAGES, if subcloud.prestage_status in consts.STATES_FOR_ONGOING_PRESTAGE:
consts.PRESTAGE_STATE_IMAGES):
avail_to_set = dccommon_consts.AVAILABILITY_ONLINE avail_to_set = dccommon_consts.AVAILABILITY_ONLINE
else: else:
avail_to_set = self._get_subcloud_availability_status( avail_to_set = self._get_subcloud_availability_status(

View File

@ -325,8 +325,12 @@ UPGRADE_STATE_ACTIVATION_COMPLETE = 'activation-complete'
# Prestage States # Prestage States
PRESTAGE_STATE_PACKAGES = STRATEGY_STATE_PRESTAGE_PACKAGES PRESTAGE_STATE_PACKAGES = STRATEGY_STATE_PRESTAGE_PACKAGES
PRESTAGE_STATE_IMAGES = STRATEGY_STATE_PRESTAGE_IMAGES PRESTAGE_STATE_IMAGES = STRATEGY_STATE_PRESTAGE_IMAGES
PRESTAGE_STATE_FAILED = 'prestage-failed' PRESTAGE_STATE_FAILED = 'failed'
PRESTAGE_STATE_COMPLETE = 'prestage-complete' PRESTAGE_STATE_COMPLETE = 'complete'
# States to indicate if a prestage operation is currently in progress
STATES_FOR_ONGOING_PRESTAGE = [PRESTAGE_STATE_PACKAGES,
PRESTAGE_STATE_IMAGES]
# Alarm aggregation # Alarm aggregation
ALARMS_DISABLED = "disabled" ALARMS_DISABLED = "disabled"
@ -406,10 +410,6 @@ DEFAULT_PERSISTENT_SIZE = 30000
PLATFORM_RETRY_MAX_ATTEMPTS = 5 PLATFORM_RETRY_MAX_ATTEMPTS = 5
PLATFORM_RETRY_SLEEP_MILLIS = 5000 PLATFORM_RETRY_SLEEP_MILLIS = 5000
# States to reject when processing a subcloud-backup create request
VALID_DEPLOY_STATES_FOR_BACKUP = [DEPLOY_STATE_DONE,
PRESTAGE_STATE_COMPLETE]
# States to reject when processing a subcloud-backup restore request # States to reject when processing a subcloud-backup restore request
INVALID_DEPLOY_STATES_FOR_RESTORE = [DEPLOY_STATE_CREATING, INVALID_DEPLOY_STATES_FOR_RESTORE = [DEPLOY_STATE_CREATING,
DEPLOY_STATE_PRE_INSTALL, DEPLOY_STATE_PRE_INSTALL,
@ -455,8 +455,6 @@ SUPPORTED_UPGRADES_METADATA_FILE_PATH = '/usr/rootdirs/opt/upgrades/metadata.xml
# Required for subcloud name configuration # Required for subcloud name configuration
CERT_MON_HTTP_AGENT = 'cert-mon/1.0' CERT_MON_HTTP_AGENT = 'cert-mon/1.0'
OS_REGION_NAME = "OS_REGION_NAME" OS_REGION_NAME = "OS_REGION_NAME"
STATES_FOR_SUBCLOUD_RENAME = [DEPLOY_STATE_DONE,
PRESTAGE_STATE_COMPLETE]
# Required for GEO-redundancy # Required for GEO-redundancy
# User-Agent check for subcloud by region_name request. # User-Agent check for subcloud by region_name request.

View File

@ -1,4 +1,4 @@
# Copyright (c) 2022-2023 Wind River Systems, Inc. # Copyright (c) 2022-2024 Wind River Systems, Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -50,13 +50,9 @@ ANSIBLE_PRESTAGE_SUBCLOUD_PACKAGES_PLAYBOOK = \
ANSIBLE_PRESTAGE_SUBCLOUD_IMAGES_PLAYBOOK = \ ANSIBLE_PRESTAGE_SUBCLOUD_IMAGES_PLAYBOOK = \
"/usr/share/ansible/stx-ansible/playbooks/prestage_images.yml" "/usr/share/ansible/stx-ansible/playbooks/prestage_images.yml"
ANSIBLE_PRESTAGE_INVENTORY_SUFFIX = '_prestage_inventory.yml' ANSIBLE_PRESTAGE_INVENTORY_SUFFIX = '_prestage_inventory.yml'
PRINT_PRESTAGE_VERSIONS_TASK = \
'prestage\/prestage-versions : Print prestage versions'
def is_deploy_status_prestage(deploy_status): PRESTAGE_VERSIONS_KEY_STR = 'prestage_versions:'
return deploy_status in (consts.PRESTAGE_STATE_PACKAGES,
consts.PRESTAGE_STATE_IMAGES,
consts.PRESTAGE_STATE_FAILED,
consts.PRESTAGE_STATE_COMPLETE)
def _get_system_controller_upgrades(): def _get_system_controller_upgrades():
@ -138,17 +134,24 @@ def initial_subcloud_validate(subcloud, installed_loads, software_version):
details="Prestage operation is not allowed while" details="Prestage operation is not allowed while"
" backup is in progress.") " backup is in progress.")
allowed_deploy_states = [consts.DEPLOY_STATE_DONE, if subcloud.deploy_status != consts.DEPLOY_STATE_DONE:
consts.PRESTAGE_STATE_FAILED, raise exceptions.PrestagePreCheckFailedException(
consts.PRESTAGE_STATE_COMPLETE] subcloud=subcloud.name,
if subcloud.deploy_status not in allowed_deploy_states: orch_skip=True,
details="Prestage operation is not allowed when"
" subcloud deploy is not completed.")
allowed_prestage_states = [consts.PRESTAGE_STATE_FAILED,
consts.PRESTAGE_STATE_COMPLETE]
if (subcloud.prestage_status and
(subcloud.prestage_status not in allowed_prestage_states)):
raise exceptions.PrestagePreCheckFailedException( raise exceptions.PrestagePreCheckFailedException(
subcloud=subcloud.name, subcloud=subcloud.name,
orch_skip=True, orch_skip=True,
details="Prestage operation is only allowed while" details="Prestage operation is only allowed while"
" subcloud deploy status is one of: %s." " subcloud prestage status is one of: %s."
" The current deploy status is %s." " The current prestage status is %s."
% (', '.join(allowed_deploy_states), subcloud.deploy_status)) % (', '.join(allowed_prestage_states), subcloud.prestage_status))
# The request software version must be either the same as the software version # The request software version must be either the same as the software version
# of the subcloud or any active/inactive/imported load on the system controller # of the subcloud or any active/inactive/imported load on the system controller
@ -212,20 +215,21 @@ def validate_prestage(subcloud, payload):
def prestage_start(context, subcloud_id): def prestage_start(context, subcloud_id):
subcloud = db_api.subcloud_update( subcloud = db_api.subcloud_update(
context, subcloud_id, context, subcloud_id,
deploy_status=consts.PRESTAGE_STATE_PACKAGES) prestage_status=consts.PRESTAGE_STATE_PACKAGES)
return subcloud return subcloud
def prestage_complete(context, subcloud_id): def prestage_complete(context, subcloud_id, prestage_versions):
db_api.subcloud_update( db_api.subcloud_update(
context, subcloud_id, context, subcloud_id,
deploy_status=consts.PRESTAGE_STATE_COMPLETE) prestage_status=consts.PRESTAGE_STATE_COMPLETE,
prestage_versions=prestage_versions)
def prestage_fail(context, subcloud_id): def prestage_fail(context, subcloud_id):
db_api.subcloud_update( db_api.subcloud_update(
context, subcloud_id, context, subcloud_id,
deploy_status=consts.PRESTAGE_STATE_FAILED) prestage_status=consts.PRESTAGE_STATE_FAILED)
def is_local(subcloud_version, specified_version): def is_local(subcloud_version, specified_version):
@ -275,11 +279,16 @@ def prestage_subcloud(context, payload):
def _prestage_standalone_thread(context, subcloud, payload): def _prestage_standalone_thread(context, subcloud, payload):
"""Run the prestage operations inside a separate thread""" """Run the prestage operations inside a separate thread"""
log_file = utils.get_subcloud_ansible_log_file(subcloud.name)
try: try:
prestage_packages(context, subcloud, payload) prestage_packages(context, subcloud, payload)
prestage_images(context, subcloud, payload) # Get the prestage versions from the logs generated by
# the prestage packages playbook
prestage_versions = utils.get_msg_output_info(
log_file, PRINT_PRESTAGE_VERSIONS_TASK, PRESTAGE_VERSIONS_KEY_STR)
prestage_complete(context, subcloud.id) prestage_images(context, subcloud, payload)
prestage_complete(context, subcloud.id, prestage_versions)
LOG.info("Prestage complete: %s", subcloud.name) LOG.info("Prestage complete: %s", subcloud.name)
except Exception: except Exception:
@ -314,7 +323,7 @@ def _get_prestage_subcloud_info(subcloud):
def _run_ansible(context, prestage_command, phase, def _run_ansible(context, prestage_command, phase,
subcloud, deploy_status, subcloud, prestage_status,
sysadmin_password, oam_floating_ip, sysadmin_password, oam_floating_ip,
software_version, software_version,
ansible_subcloud_inventory_file, ansible_subcloud_inventory_file,
@ -328,9 +337,7 @@ def _run_ansible(context, prestage_command, phase,
db_api.subcloud_update(context, db_api.subcloud_update(context,
subcloud.id, subcloud.id,
deploy_status=deploy_status) prestage_status=prestage_status)
log_file = os.path.join(consts.DC_ANSIBLE_LOG_DIR, subcloud.name) + \
'_playbook_output.log'
# Create the ansible inventory for the new subcloud # Create the ansible inventory for the new subcloud
utils.create_subcloud_inventory_with_admin_creds( utils.create_subcloud_inventory_with_admin_creds(
@ -339,6 +346,8 @@ def _run_ansible(context, prestage_command, phase,
oam_floating_ip, oam_floating_ip,
ansible_pass=utils.decode_and_normalize_passwd(sysadmin_password)) ansible_pass=utils.decode_and_normalize_passwd(sysadmin_password))
log_file = utils.get_subcloud_ansible_log_file(subcloud.name)
try: try:
ansible = AnsiblePlaybook(subcloud.name) ansible = AnsiblePlaybook(subcloud.name)
ansible.run_playbook(log_file, prestage_command, timeout=timeout_seconds, ansible.run_playbook(log_file, prestage_command, timeout=timeout_seconds,

View File

@ -788,7 +788,6 @@ def find_ansible_error_msg(subcloud_name, log_file, stage=None):
error_found = False error_found = False
error_msg = [] error_msg = []
failed_task = '' failed_task = ''
files_for_search = []
cmd_1 = 'awk' cmd_1 = 'awk'
# awk command to get the information iside the last match found # awk command to get the information iside the last match found
@ -801,23 +800,16 @@ def find_ansible_error_msg(subcloud_name, log_file, stage=None):
f = f ? (f "\\n" $0) : $0} # assign or append to f f = f ? (f "\\n" $0) : $0} # assign or append to f
END {print f} END {print f}
''') ''')
# necessary check since is possible to have
# the error in rotated ansible log
log_file_temp = log_file + '.1'
if os.path.exists(log_file_temp):
files_for_search.append(log_file_temp)
if os.path.exists(log_file):
files_for_search.append(log_file)
else:
files_for_search.append(log_file)
if len(files_for_search) < 2:
cmd_list = ([cmd_1, cmd_2, files_for_search[0]])
else:
cmd_list = ([cmd_1, cmd_2, files_for_search[0], files_for_search[1]])
try: try:
# necessary check since is possible to have
# the error in rotated ansible log
files_for_search = add_latest_rotated_file(log_file)
if len(files_for_search) < 2:
cmd_list = ([cmd_1, cmd_2, files_for_search[0]])
else:
cmd_list = ([cmd_1, cmd_2, files_for_search[0], files_for_search[1]])
error_msg_raw = subprocess.check_output( error_msg_raw = subprocess.check_output(
cmd_list, cmd_list,
stderr=subprocess.STDOUT).decode('utf-8') stderr=subprocess.STDOUT).decode('utf-8')
@ -851,6 +843,38 @@ def find_ansible_error_msg(subcloud_name, log_file, stage=None):
return msg return msg
def add_latest_rotated_file(log_file):
"""Find the latest rotated file for the given log file.
Check the existence of the given log file with its latest rotated file.
Returns the log file itself if it exists and the latest rotated file
doesn't exist;
or the log file and its latest rotated file if both exist;
or the latest rotated file only if it exists but the log file itself
doesn't exit.
Raises exception if both of the log file and its latest rotated file
don't exist.
"""
log_files = []
# the latest rotated log file
log_file_temp = log_file + '.1'
if os.path.exists(log_file_temp):
log_files.append(log_file_temp)
if os.path.exists(log_file):
log_files.append(log_file)
if len(log_files) == 0:
raise Exception("Log file %s and its latest rotated file don't exist."
% log_file)
return log_files
def get_failed_task(files): def get_failed_task(files):
"""Get last task failed """Get last task failed
@ -933,9 +957,10 @@ def is_valid_for_backup_operation(operation, subcloud, bootstrap_address_dict=No
def _is_valid_for_backup_create(subcloud): def _is_valid_for_backup_create(subcloud):
if subcloud.availability_status != dccommon_consts.AVAILABILITY_ONLINE \ if subcloud.availability_status != dccommon_consts.AVAILABILITY_ONLINE \
or subcloud.management_state != dccommon_consts.MANAGEMENT_MANAGED \ or subcloud.management_state != dccommon_consts.MANAGEMENT_MANAGED \
or subcloud.deploy_status not in consts.VALID_DEPLOY_STATES_FOR_BACKUP: or subcloud.deploy_status != consts.DEPLOY_STATE_DONE \
msg = ('Subcloud %s must be online, managed and have valid ' or subcloud.prestage_status in consts.STATES_FOR_ONGOING_PRESTAGE:
'deploy-status for the subcloud-backup ' msg = ('Subcloud %s must be deployed, online, managed, '
'and no ongoing prestage for the subcloud-backup '
'create operation.' % subcloud.name) 'create operation.' % subcloud.name)
raise exceptions.ValidateFail(msg) raise exceptions.ValidateFail(msg)
@ -1559,3 +1584,47 @@ def get_local_system():
endpoint=endpoint) endpoint=endpoint)
system = sysinv_client.get_system() system = sysinv_client.get_system()
return system return system
def get_msg_output_info(log_file, target_task, target_str):
"""Get msg output by searching the target string from the given task.
It receives an ansible log file and searches for the last msg output
matching the target string from the given task.
Returns the msg output
"""
# awk command to get the last occurrence string after 'msg: {target_str}'
# between 'TASK \[{target_task}' and 'PLAY RECAP' delimiters.
awk_script = f'''
/TASK \[{target_task}/,/PLAY RECAP/ {{
if ($0 ~ /msg: \'{target_str}(.+)\'/) {{
result = $0
}}
}}
END {{
if (result) {{
match(result, /msg: \'{target_str}(.+)\'/, arr)
print arr[1]
}}
}}
'''
try:
# necessary check since is possible to have
# the message in rotated ansible log
files_for_search = add_latest_rotated_file(log_file)
awk_cmd = ['awk', awk_script] + files_for_search
# Run the AWK script using subprocess
result = subprocess.run(
awk_cmd, capture_output=True, text=True, check=True)
return result.stdout.strip()
except Exception as e:
LOG.error("Failed getting msg output by searching '%s' "
"from task '%s': %s" % (target_str, target_task, e))
return None
def get_subcloud_ansible_log_file(subcloud_name):
return os.path.join(consts.DC_ANSIBLE_LOG_DIR,
subcloud_name + '_playbook_output.log')

View File

@ -119,6 +119,8 @@ def subcloud_db_model_to_dict(subcloud):
"management-end-ip": subcloud.management_end_ip, "management-end-ip": subcloud.management_end_ip,
"management-gateway-ip": subcloud.management_gateway_ip, "management-gateway-ip": subcloud.management_gateway_ip,
"openstack-installed": subcloud.openstack_installed, "openstack-installed": subcloud.openstack_installed,
"prestage-status": subcloud.prestage_status,
"prestage-versions": subcloud.prestage_versions,
"systemcontroller-gateway-ip": "systemcontroller-gateway-ip":
subcloud.systemcontroller_gateway_ip, subcloud.systemcontroller_gateway_ip,
"data_install": subcloud.data_install, "data_install": subcloud.data_install,
@ -193,7 +195,8 @@ def subcloud_update(
backup_datetime=None, error_description=None, openstack_installed=None, backup_datetime=None, error_description=None, openstack_installed=None,
group_id=None, data_install=None, data_upgrade=None, group_id=None, data_install=None, data_upgrade=None,
first_identity_sync_complete=None, systemcontroller_gateway_ip=None, first_identity_sync_complete=None, systemcontroller_gateway_ip=None,
peer_group_id=None, rehome_data=None, rehomed=None peer_group_id=None, rehome_data=None, rehomed=None,
prestage_status=None, prestage_versions=None
): ):
"""Update a subcloud or raise if it does not exist.""" """Update a subcloud or raise if it does not exist."""
return IMPL.subcloud_update( return IMPL.subcloud_update(
@ -203,7 +206,7 @@ def subcloud_update(
audit_fail_count, deploy_status, backup_status, backup_datetime, audit_fail_count, deploy_status, backup_status, backup_datetime,
error_description, openstack_installed, group_id, data_install, data_upgrade, error_description, openstack_installed, group_id, data_install, data_upgrade,
first_identity_sync_complete, systemcontroller_gateway_ip, peer_group_id, first_identity_sync_complete, systemcontroller_gateway_ip, peer_group_id,
rehome_data, rehomed rehome_data, rehomed, prestage_status, prestage_versions
) )

View File

@ -422,7 +422,8 @@ def subcloud_update(context, subcloud_id, management_state=None,
first_identity_sync_complete=None, first_identity_sync_complete=None,
systemcontroller_gateway_ip=None, systemcontroller_gateway_ip=None,
peer_group_id=None, peer_group_id=None,
rehome_data=None, rehomed=None): rehome_data=None, rehomed=None,
prestage_status=None, prestage_versions=None):
with write_session() as session: with write_session() as session:
subcloud_ref = subcloud_get(context, subcloud_id) subcloud_ref = subcloud_get(context, subcloud_id)
if management_state is not None: if management_state is not None:
@ -477,6 +478,10 @@ def subcloud_update(context, subcloud_id, management_state=None,
subcloud_ref.rehome_data = rehome_data subcloud_ref.rehome_data = rehome_data
if rehomed is not None: if rehomed is not None:
subcloud_ref.rehomed = rehomed subcloud_ref.rehomed = rehomed
if prestage_status is not None:
subcloud_ref.prestage_status = prestage_status
if prestage_versions is not None:
subcloud_ref.prestage_versions = prestage_versions
subcloud_ref.save(session) subcloud_ref.save(session)
return subcloud_ref return subcloud_ref

View File

@ -0,0 +1,30 @@
#
# Copyright (c) 2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from sqlalchemy import Column, MetaData, Table, String
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
subclouds = Table('subclouds', meta, autoload=True)
# Add the 'prestage_status' and 'prestage_versions' columns to
# the subclouds table.
subclouds.create_column(Column('prestage_status', String(255)))
subclouds.create_column(Column('prestage_versions', String(255)))
# Update existing subclouds that have the old prestaging deploy status
subclouds.update().where( # pylint: disable=E1120
subclouds.c.deploy_status.like('prestage%')).values(
{'deploy_status': 'complete'}).execute()
return True
def downgrade(migrate_engine):
raise NotImplementedError('Database downgrade is unsupported.')

View File

@ -186,6 +186,8 @@ class Subcloud(BASE, DCManagerBase):
peer_group_id = Column(Integer, peer_group_id = Column(Integer,
ForeignKey('subcloud_peer_group.id')) ForeignKey('subcloud_peer_group.id'))
rehome_data = Column(Text()) rehome_data = Column(Text())
prestage_status = Column(String(255))
prestage_versions = Column(String(255))
# multiple subclouds can be in a particular group # multiple subclouds can be in a particular group
group_id = Column(Integer, group_id = Column(Integer,

View File

@ -135,8 +135,6 @@ TRANSITORY_STATES = {
consts.DEPLOY_STATE_RESTORING: consts.DEPLOY_STATE_RESTORE_FAILED, consts.DEPLOY_STATE_RESTORING: consts.DEPLOY_STATE_RESTORE_FAILED,
consts.DEPLOY_STATE_PRE_REHOME: consts.DEPLOY_STATE_REHOME_PREP_FAILED, consts.DEPLOY_STATE_PRE_REHOME: consts.DEPLOY_STATE_REHOME_PREP_FAILED,
consts.DEPLOY_STATE_REHOMING: consts.DEPLOY_STATE_REHOME_FAILED, consts.DEPLOY_STATE_REHOMING: consts.DEPLOY_STATE_REHOME_FAILED,
consts.PRESTAGE_STATE_PACKAGES: consts.PRESTAGE_STATE_FAILED,
consts.PRESTAGE_STATE_IMAGES: consts.PRESTAGE_STATE_FAILED,
# The next two states are needed due to upgrade scenario: # The next two states are needed due to upgrade scenario:
# TODO(gherzman): remove states when they are no longer needed # TODO(gherzman): remove states when they are no longer needed
consts.DEPLOY_STATE_PRE_DEPLOY: consts.DEPLOY_STATE_PRE_CONFIG_FAILED, consts.DEPLOY_STATE_PRE_DEPLOY: consts.DEPLOY_STATE_PRE_CONFIG_FAILED,
@ -149,6 +147,11 @@ TRANSITORY_BACKUP_STATES = {
consts.BACKUP_STATE_IN_PROGRESS: consts.BACKUP_STATE_FAILED consts.BACKUP_STATE_IN_PROGRESS: consts.BACKUP_STATE_FAILED
} }
TRANSITORY_PRESTAGE_STATES = {
consts.PRESTAGE_STATE_PACKAGES: consts.PRESTAGE_STATE_FAILED,
consts.PRESTAGE_STATE_IMAGES: consts.PRESTAGE_STATE_FAILED
}
MAX_PARALLEL_SUBCLOUD_BACKUP_CREATE = 250 MAX_PARALLEL_SUBCLOUD_BACKUP_CREATE = 250
MAX_PARALLEL_SUBCLOUD_BACKUP_DELETE = 250 MAX_PARALLEL_SUBCLOUD_BACKUP_DELETE = 250
MAX_PARALLEL_SUBCLOUD_BACKUP_RESTORE = 100 MAX_PARALLEL_SUBCLOUD_BACKUP_RESTORE = 100
@ -2744,16 +2747,13 @@ class SubcloudManager(manager.Manager):
# No need for further validation # No need for further validation
return return
deploy_status_complete = (
subcloud.deploy_status == consts.DEPLOY_STATE_DONE
or prestage.is_deploy_status_prestage(subcloud.deploy_status)
)
allowed_deploy_transition = ( allowed_deploy_transition = (
subcloud.deploy_status == consts.DEPLOY_STATE_REHOME_PENDING subcloud.deploy_status == consts.DEPLOY_STATE_REHOME_PENDING
and new_deploy_status == consts.DEPLOY_STATE_DONE and new_deploy_status == consts.DEPLOY_STATE_DONE
) )
if not deploy_status_complete and not allowed_deploy_transition: if (subcloud.deploy_status != consts.DEPLOY_STATE_DONE and
not allowed_deploy_transition):
msg = (f"Unable to manage {subcloud.name}: its deploy_status " msg = (f"Unable to manage {subcloud.name}: its deploy_status "
f"must be either '{consts.DEPLOY_STATE_DONE}' or " f"must be either '{consts.DEPLOY_STATE_DONE}' or "
f"'{consts.DEPLOY_STATE_REHOME_PENDING}'") f"'{consts.DEPLOY_STATE_REHOME_PENDING}'")
@ -3269,9 +3269,12 @@ class SubcloudManager(manager.Manager):
# Identify subclouds in transitory states # Identify subclouds in transitory states
new_deploy_status = TRANSITORY_STATES.get(subcloud.deploy_status) new_deploy_status = TRANSITORY_STATES.get(subcloud.deploy_status)
new_backup_status = TRANSITORY_BACKUP_STATES.get(subcloud.backup_status) new_backup_status = TRANSITORY_BACKUP_STATES.get(subcloud.backup_status)
new_prestage_status = TRANSITORY_PRESTAGE_STATES.get(
subcloud.prestage_status)
# update deploy and backup states to the corresponding failure states # update deploy, backup and prestage states to
if new_deploy_status or new_backup_status: # the corresponding failure states
if new_deploy_status or new_backup_status or new_prestage_status:
if new_deploy_status: if new_deploy_status:
LOG.info("Changing subcloud %s deploy status from %s to %s." LOG.info("Changing subcloud %s deploy status from %s to %s."
% (subcloud.name, subcloud.deploy_status, % (subcloud.name, subcloud.deploy_status,
@ -3281,11 +3284,18 @@ class SubcloudManager(manager.Manager):
% (subcloud.name, subcloud.backup_status, % (subcloud.name, subcloud.backup_status,
new_backup_status)) new_backup_status))
if new_prestage_status:
LOG.info("Changing subcloud %s prestage status from %s"
" to %s."
% (subcloud.name, subcloud.prestage_status,
new_prestage_status))
db_api.subcloud_update( db_api.subcloud_update(
self.context, self.context,
subcloud.id, subcloud.id,
deploy_status=new_deploy_status or subcloud.deploy_status, deploy_status=new_deploy_status or subcloud.deploy_status,
backup_status=new_backup_status or subcloud.backup_status backup_status=new_backup_status or subcloud.backup_status,
prestage_status=new_prestage_status or subcloud.prestage_status
) )
@staticmethod @staticmethod

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2022-2023 Wind River Systems, Inc. # Copyright (c) 2022-2024 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -33,10 +33,10 @@ class PrestageState(BaseState):
try: try:
self._do_state_action(strategy_step) self._do_state_action(strategy_step)
except exceptions.StrategySkippedException: except exceptions.StrategySkippedException:
# Move deploy_status back to complete (nothing has changed) # Move prestage_status back to None (nothing has changed)
db_api.subcloud_update( db_api.subcloud_update(
self.context, strategy_step.subcloud.id, self.context, strategy_step.subcloud.id,
deploy_status=consts.DEPLOY_STATE_DONE) prestage_status=None)
raise raise
except Exception: except Exception:
prestage.prestage_fail(self.context, strategy_step.subcloud.id) prestage.prestage_fail(self.context, strategy_step.subcloud.id)
@ -141,6 +141,15 @@ class PrestageImagesState(PrestageState):
region_name=region_name) region_name=region_name)
def _do_state_action(self, strategy_step): def _do_state_action(self, strategy_step):
log_file = utils.get_subcloud_ansible_log_file(
strategy_step.subcloud.name)
# Get the prestage versions from the ansible playbook logs
# generated by the previous step - prestage packages.
prestage_versions = utils.get_msg_output_info(
log_file,
prestage.PRINT_PRESTAGE_VERSIONS_TASK,
prestage.PRESTAGE_VERSIONS_KEY_STR)
extra_args = utils.get_sw_update_strategy_extra_args(self.context) extra_args = utils.get_sw_update_strategy_extra_args(self.context)
payload = { payload = {
'sysadmin_password': extra_args['sysadmin_password'], 'sysadmin_password': extra_args['sysadmin_password'],
@ -153,4 +162,5 @@ class PrestageImagesState(PrestageState):
extra_args.get(consts.PRESTAGE_SOFTWARE_VERSION)}) extra_args.get(consts.PRESTAGE_SOFTWARE_VERSION)})
prestage.prestage_images(self.context, strategy_step.subcloud, payload) prestage.prestage_images(self.context, strategy_step.subcloud, payload)
self.info_log(strategy_step, "Images finished") self.info_log(strategy_step, "Images finished")
prestage.prestage_complete(self.context, strategy_step.subcloud.id) prestage.prestage_complete(
self.context, strategy_step.subcloud.id, prestage_versions)

View File

@ -2264,8 +2264,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
mock_run_playbook.assert_called_once() mock_run_playbook.assert_called_once()
mock_is_healthy.assert_called_once() mock_is_healthy.assert_called_once()
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct backup status
# consts.PRESTAGE_STATE_PACKAGES # consts.BACKUP_STATE_PRE_BACKUP
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.BACKUP_STATE_PRE_BACKUP, self.assertEqual(consts.BACKUP_STATE_PRE_BACKUP,
updated_subcloud.backup_status) updated_subcloud.backup_status)
@ -2293,8 +2293,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
mock_parallel_group_operation.assert_called_once() mock_parallel_group_operation.assert_called_once()
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct backup status
# consts.PRESTAGE_STATE_PACKAGES # consts.BACKUP_STATE_VALIDATE_FAILED
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.BACKUP_STATE_VALIDATE_FAILED, self.assertEqual(consts.BACKUP_STATE_VALIDATE_FAILED,
updated_subcloud.backup_status) updated_subcloud.backup_status)
@ -2322,8 +2322,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
mock_parallel_group_operation.assert_called_once() mock_parallel_group_operation.assert_called_once()
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct backup status
# consts.PRESTAGE_STATE_PACKAGES # consts.BACKUP_STATE_VALIDATE_FAILED
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.BACKUP_STATE_VALIDATE_FAILED, self.assertEqual(consts.BACKUP_STATE_VALIDATE_FAILED,
updated_subcloud.backup_status) updated_subcloud.backup_status)
@ -2351,8 +2351,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
mock_parallel_group_operation.assert_called_once() mock_parallel_group_operation.assert_called_once()
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct backup status
# consts.PRESTAGE_STATE_PACKAGES # consts.BACKUP_STATE_VALIDATE_FAILED
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.BACKUP_STATE_VALIDATE_FAILED, self.assertEqual(consts.BACKUP_STATE_VALIDATE_FAILED,
updated_subcloud.backup_status) updated_subcloud.backup_status)
@ -2382,8 +2382,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
mock_parallel_group_operation.assert_called_once() mock_parallel_group_operation.assert_called_once()
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct backup status
# consts.PRESTAGE_STATE_PACKAGES # consts.BACKUP_STATE_UNKNOWN
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.BACKUP_STATE_UNKNOWN, self.assertEqual(consts.BACKUP_STATE_UNKNOWN,
updated_subcloud.backup_status) updated_subcloud.backup_status)
@ -2413,8 +2413,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
mock_parallel_group_operation.assert_called_once() mock_parallel_group_operation.assert_called_once()
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct backup status
# consts.PRESTAGE_STATE_PACKAGES # consts.BACKUP_STATE_UNKNOWN
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.BACKUP_STATE_UNKNOWN, self.assertEqual(consts.BACKUP_STATE_UNKNOWN,
updated_subcloud.backup_status) updated_subcloud.backup_status)
@ -2628,7 +2628,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct deploy status
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.PRESTAGE_STATE_COMPLETE, self.assertEqual(consts.PRESTAGE_STATE_COMPLETE,
updated_subcloud.deploy_status) updated_subcloud.prestage_status)
# Verify both of prestage package and image ansible playbooks were called # Verify both of prestage package and image ansible playbooks were called
self.assertEqual(mock_run_ansible.call_count, 2) self.assertEqual(mock_run_ansible.call_count, 2)
@ -2664,7 +2664,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct deploy status
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.PRESTAGE_STATE_COMPLETE, self.assertEqual(consts.PRESTAGE_STATE_COMPLETE,
updated_subcloud.deploy_status) updated_subcloud.prestage_status)
# Verify that only prestage package playbook is called # Verify that only prestage package playbook is called
self.assertEqual(mock_run_ansible.call_count, 1) self.assertEqual(mock_run_ansible.call_count, 1)
@ -2695,7 +2695,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct deploy status
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.PRESTAGE_STATE_COMPLETE, self.assertEqual(consts.PRESTAGE_STATE_COMPLETE,
updated_subcloud.deploy_status) updated_subcloud.prestage_status)
# Verify both of prestage package and image ansible playbooks were called # Verify both of prestage package and image ansible playbooks were called
self.assertEqual(mock_run_ansible.call_count, 2) self.assertEqual(mock_run_ansible.call_count, 2)
@ -2731,7 +2731,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
# Verify that subcloud has the correct deploy status # Verify that subcloud has the correct deploy status
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.PRESTAGE_STATE_COMPLETE, self.assertEqual(consts.PRESTAGE_STATE_COMPLETE,
updated_subcloud.deploy_status) updated_subcloud.prestage_status)
# Verify both of prestage package and image ansible playbooks were called # Verify both of prestage package and image ansible playbooks were called
self.assertEqual(mock_run_ansible.call_count, 2) self.assertEqual(mock_run_ansible.call_count, 2)
@ -2769,7 +2769,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
# Verify that subcloud has the "prestage-complete" deploy status # Verify that subcloud has the "prestage-complete" deploy status
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name) updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
self.assertEqual(consts.PRESTAGE_STATE_COMPLETE, self.assertEqual(consts.PRESTAGE_STATE_COMPLETE,
updated_subcloud.deploy_status) updated_subcloud.prestage_status)
def test_get_cached_regionone_data(self): def test_get_cached_regionone_data(self):
mock_keystone_client = FakeKeystoneClient() mock_keystone_client = FakeKeystoneClient()
@ -3096,7 +3096,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
@mock.patch.object(subcloud_manager.SubcloudManager, @mock.patch.object(subcloud_manager.SubcloudManager,
'_unmanage_system_peer_subcloud') '_unmanage_system_peer_subcloud')
def test_migrate_manage_subcloud_called_unmanage_peer_subcloud( def test_migrate_manage_subcloud_called_unmanage_peer_subcloud(
self, mock_unmanage_system_peer_subcloud self, mock_unmanage_system_peer_subcloud
): ):
sm = subcloud_manager.SubcloudManager() sm = subcloud_manager.SubcloudManager()
system_peer_test = test_system_peer_manager.TestSystemPeerManager system_peer_test = test_system_peer_manager.TestSystemPeerManager