config/sysinv/cgts-client/cgts-client/cgtsclient/v1/device_image.py
Teresa Ho 2b23452a1c Preserve states for functional user and bmc image
Currently, there are two kinds of functional images: user and bmc.
However there is no attribute to distinguish between the two kinds.
If an user image is already applied, applying bmc image would delete
the state of the applied user image.

A new parameter is added to specify a functional BMC image.
The state of last updated user image and BMC image are to be kept.
The order in which the two kinds of BMC images is applied determine
which one is to be kept.
If a BMC image with retimer is applied before a BMC image without
retimer, the states of both images must be kept.
If a BMC image without retimer is applied before a BMC image with
retimer, the state of the BMC image without retimer can be deleted.

Tox unit tests are added for the various scenarios.

Closes-Bug: 1951602

Change-Id: Ifdcbc09d9f14270a57ecc307fbea7517b048351b
Signed-off-by: Teresa Ho <teresa.ho@windriver.com>
2021-11-22 14:41:28 -05:00

82 lines
2.5 KiB
Python

#
# Copyright (c) 2020-2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from cgtsclient.common import base
from cgtsclient.common import utils
from cgtsclient import exc
CREATION_ATTRIBUTES = [
'bitstream_type', 'pci_vendor', 'pci_device',
'bitstream_id', 'key_signature', 'revoke_key_id',
'name', 'description', 'image_version', 'uuid', 'bmc', 'retimer_included']
class DeviceImage(base.Resource):
def __repr__(self):
return "<DeviceImage %s>" % self._info
class DeviceImageManager(base.Manager):
resource_class = DeviceImage
@staticmethod
def _path(uuid=None):
return '/v1/device_images/%s' % uuid if uuid else '/v1/device_images'
def list(self):
return self._list(self._path(), "device_images")
def get(self, device_image_id):
try:
return self._list(self._path(device_image_id))[0]
except IndexError:
return None
def upload(self, file, **kwargs):
data = {}
for (key, value) in kwargs.items():
if key in CREATION_ATTRIBUTES:
data[key] = value
else:
raise exc.InvalidAttribute('%s' % key)
return self._upload_multipart(self._path(), dict(file=file), data=data)
def apply(self, device_image_id, labels=None):
return self._update(self._path(device_image_id) + '?action=apply',
labels)
def remove(self, device_image_id, labels=None):
return self._update(self._path(device_image_id) + '?action=remove',
labels)
def delete(self, device_image_id):
return self._delete(self._path(device_image_id))
def _find_device_image(cc, device_image):
if device_image.isdigit() and not utils.is_uuid_like(device_image):
device_image_list = cc.device_image.list()
for n in device_image_list:
if str(n.id) == device_image:
return n
else:
raise exc.CommandError('device image not found: %s' % device_image)
elif utils.is_uuid_like(device_image):
try:
h = cc.device_image.get(device_image)
except exc.HTTPNotFound:
raise exc.CommandError('device image not found: %s' % device_image)
else:
return h
else:
device_image_list = cc.device_image.list()
for n in device_image_list:
if n.name == device_image:
return n
else:
raise exc.CommandError('device image not found: %s' % device_image)