Skip to content

Commit

Permalink
Merge pull request #246 from Cray-HPE/release-2.14
Browse files Browse the repository at this point in the history
Release 2.14.0
  • Loading branch information
mharding-hpe authored Feb 6, 2024
2 parents f2123f3 + 564f365 commit a21e03e
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 76 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [2.14.0] - 2024-02-06
### Added
- Scalable Boot Provisioning Service (SBPS) support

### Changed
- Removed unintended ability to update v2 session fields other than `status` and `components`.

## [2.13.0] - 2024-01-10
### Fixed
- Fix a broken build caused by PEP-668. Pin Alpine version to 3. This is less restrictive.
Expand Down
26 changes: 23 additions & 3 deletions api/openapi.yaml.in
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,24 @@ components:
status:
$ref: '#/components/schemas/V2SessionStatus'
additionalProperties: false
V2SessionUpdate:
description: |
A Session update object

## Link Relationships

* self : The Session object
type: object
properties:
components:
type: string
description: |
A comma-separated list of nodes, representing the initial list of nodes
the Session should operate against. The list will remain even if
other Sessions have taken over management of the nodes.
status:
$ref: '#/components/schemas/V2SessionStatus'
additionalProperties: false
V2SessionArray:
description: An array of Sessions.
type: array
Expand Down Expand Up @@ -1674,7 +1692,7 @@ components:
content:
application/json:
schema:
$ref: '#/components/schemas/V2Session'
$ref: '#/components/schemas/V2SessionUpdate'
V2applyStagedRequest:
description: A list of xnames that should have their staged Session applied.
required: true
Expand Down Expand Up @@ -2611,8 +2629,10 @@ paths:
404:
$ref: '#/components/responses/ResourceNotFound'
patch:
summary: Update a single Session
description: Update the state for a given Session in the BOS database
summary: Update status of a single Session
description: |
Update the state for a given Session in the BOS database.
This is intended only for internal use by the BOS service.
tags:
- v2
- sessions
Expand Down
14 changes: 14 additions & 0 deletions src/bos/operators/session_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,14 @@ def _generate_desired_state(self, boot_set, staged=False):
return state

def _get_state_from_boot_set(self, boot_set):
"""
Returns:
state: A dictionary containing two keys 'boot_artifacts' and 'configuration'.
'boot_artifacts' is itself a dictionary containing key/value pairs where the keys are the
boot artifacts (kernel, initrd, rootfs, and boot parameters) and the values are paths to
those artifacts in storage.
'configuration' is a string.
"""
state = {}
boot_artifacts = {}
image_metadata = BootImageMetaDataFactory(boot_set)()
Expand Down Expand Up @@ -324,6 +332,12 @@ def assemble_kernel_boot_parameters(self, boot_set, artifact_info):
Warning: We need to ensure that the 'root' parameter exists and is set correctly.
If any of the parameter locations are empty, they are simply not used.
Inputs:
boot_set: A boot set from the session template data
artifact_info: The artifact summary from the boot_set.
This is a dictionary containing keys which are boot artifacts (kernel, initrd, roots, and kernel boot parameters).
The values are the paths to those boot artifacts in S3.
It also contains the etags for the rootfs and kerenl boot parameters.
Returns:
A string containing the needed kernel boot parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ def kernel(self):
Get the kernel object
As an example, the object looks like this
{'link': {'etag': 'dcaa006fdd460586e62f9ec44e7f61cf',
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/boot_parameters',
'type': 's3'},
'md5': 'dcaa006fdd460586e62f9ec44e7f61cf',
'type': 'application/vnd.cray.image.parameters.boot'}
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/kernel',
'type': 's3'},
'md5': 'dcaa006fdd460586e62f9ec44e7f61cf',
'type': 'application/vnd.cray.image.parameters.boot'
}
"""
return self.boot_artifacts.kernel

Expand All @@ -101,10 +102,11 @@ def initrd(self):
Get the initrd object
As an example, the object looks like this
{'link': {'etag': 'be2927a765c88558370ee1c5edf1c50c-3',
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/initrd',
'type': 's3'},
'md5': 'aa69151d7fe8dcb66d74cbc05ef3e7cc',
'type': 'application/vnd.cray.image.initrd'}
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/initrd',
'type': 's3'},
'md5': 'aa69151d7fe8dcb66d74cbc05ef3e7cc',
'type': 'application/vnd.cray.image.initrd'
}
"""
return self.boot_artifacts.initrd

Expand All @@ -114,10 +116,11 @@ def boot_parameters(self):
Get the boot parameters object
As an example, the object looks like this
{'link': {'etag': 'dcaa006fdd460586e62f9ec44e7f61cf',
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/boot_parameters',
'type': 's3'},
'md5': 'dcaa006fdd460586e62f9ec44e7f61cf',
'type': 'application/vnd.cray.image.parameters.boot'}
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/boot_parameters',
'type': 's3'},
'md5': 'dcaa006fdd460586e62f9ec44e7f61cf',
'type': 'application/vnd.cray.image.parameters.boot'
}
"""
return self.boot_artifacts.boot_parameters

Expand All @@ -127,10 +130,11 @@ def rootfs(self):
Get the rootfs object
As an example, the object looks like this
{'link': {'etag': 'f04af5f34635ae7c507322985e60c00c-131',
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/rootfs',
'type': 's3'},
'md5': 'e7d60fdcc8a2617b872a12fcf76f9d53',
'type': 'application/vnd.cray.image.rootfs.squashfs'}
'path': 's3://boot-images/1fb58f4e-ad23-489b-89b7-95868fca7ee6/rootfs',
'type': 's3'},
'md5': 'e7d60fdcc8a2617b872a12fcf76f9d53',
'type': 'application/vnd.cray.image.rootfs.squashfs'
}
"""
return self.boot_artifacts.rootfs

Expand Down
2 changes: 1 addition & 1 deletion src/bos/operators/utils/rootfs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def __init__(self, boot_set, artifact_info):

def __str__(self):
"""
The value to add to the boot parameter.
The value to add to the 'root=' kernel boot parameter.
"""
fields = []
if self.PROTOCOL:
Expand Down
57 changes: 57 additions & 0 deletions src/bos/operators/utils/rootfs/baserootfs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#
# MIT License
#
# (C) Copyright 2022-2023 Hewlett Packard Enterprise Development LP
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
'''
Provisioning mechanism, base class
The assumption is the artifact info contains information about the rootfs.
'''

from . import RootfsProvider

class BaseRootfsProvider(RootfsProvider):

PROTOCOL = None

@property
def provider_field(self):
return self.artifact_info['rootfs']

@property
def provider_field_id(self):
return self.artifact_info['rootfs_etag']

@property
def nmd_field(self):
"""
The value to add to the kernel boot parameters for Node Memory Dump (NMD)
parameter.
"""
fields = []
if self.provider_field:
fields.append("url=%s" % self.provider_field)
if self.provider_field_id:
fields.append("etag=%s" % self.provider_field_id)
if fields:
return "nmd_data={}".format(",".join(fields))
else:
return ''
53 changes: 2 additions & 51 deletions src/bos/operators/utils/rootfs/cpss3.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,56 +28,7 @@
another protocol (iSCSI or DVS) depending on the product.
'''

from requests.exceptions import HTTPError
import logging
import os
from .baserootfs import BaseRootfsProvider

from . import RootfsProvider
from .. import ServiceNotReady
from bos.common.utils import PROTOCOL, requests_retry_session

LOGGER = logging.getLogger(__name__)
SERVICE_NAME = 'cray-cps'
VERSION = 'v1'
ENDPOINT = '%s://%s/%s' % (PROTOCOL, SERVICE_NAME, VERSION)


class CPSS3Provider(RootfsProvider):
class CPSS3Provider(BaseRootfsProvider):
PROTOCOL = 'craycps-s3'

@property
def provider_field(self):
return self.artifact_info['rootfs']

@property
def provider_field_id(self):
return self.artifact_info['rootfs_etag']

@property
def nmd_field(self):
"""
The value to add to the kernel boot parameters for Node Memory Dump (NMD)
parameter.
"""
fields = []
if self.provider_field:
fields.append("url=%s" % self.provider_field)
if self.provider_field_id:
fields.append("etag=%s" % self.provider_field_id)
if fields:
return "nmd_data={}".format(",".join(fields))
else:
return ''


def check_cpss3(session=None):
"""
A call to check on the health of the CPS microservice.
"""
session = session or requests_retry_session()
uri = os.path.join(ENDPOINT, 'contents')
try:
response = session.get(uri)
response.raise_for_status()
except HTTPError as he:
raise ServiceNotReady(he) from he
7 changes: 7 additions & 0 deletions src/bos/operators/utils/rootfs/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ class ProviderFactory(object):
a given agent instance.
"""
def __init__(self, boot_set, artifact_info):
"""
Inputs:
boot_set: A boot set from the session template data
artifact_info: The artifact summary from the boot_set.
This is a dictionary containing keys which are boot artifacts (kernel, initrd, roots, and kernel boot parameters)
the values are the paths to those boot artifacts in S3. It also contains the etags for the rootfs and kerenl boot parameters.
"""
self.boot_set = boot_set
self.artifact_info = artifact_info

Expand Down
31 changes: 31 additions & 0 deletions src/bos/operators/utils/rootfs/sbps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#
# MIT License
#
# (C) Copyright 2022-2023 Hewlett Packard Enterprise Development LP
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
'''
Provisioning mechanism using the Scalable Boot Provisioning Service
'''

from .baserootfs import BaseRootfsProvider

class SBPSProvider(BaseRootfsProvider):
PROTOCOL = 'sbps-s3'
22 changes: 17 additions & 5 deletions src/bos/server/controllers/v2/sessions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# MIT License
#
# (C) Copyright 2021-2023 Hewlett Packard Enterprise Development LP
# (C) Copyright 2021-2024 Hewlett Packard Enterprise Development LP
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -37,6 +37,7 @@
from bos.server.controllers.v2.sessiontemplates import get_v2_sessiontemplate
from bos.server.models.v2_session import V2Session as Session # noqa: E501
from bos.server.models.v2_session_create import V2SessionCreate as SessionCreate # noqa: E501
from bos.server.models.v2_session_update import V2SessionUpdate as SessionUpdate # noqa: E501
from .boot_set import validate_boot_sets, BOOT_SET_ERROR

LOGGER = logging.getLogger('bos.server.controllers.v2.session')
Expand Down Expand Up @@ -127,16 +128,27 @@ def patch_v2_session(session_id):
Returns:
Session Dictionary, Status Code
"""
if not connexion.request.is_json:
msg = "Post must be in JSON format"
LOGGER.error(msg)
return msg, 400

LOGGER.debug("connexion.request.is_json")
patch_data_json=connexion.request.get_json()
LOGGER.debug("type=%s", type(patch_data_json))
LOGGER.debug("Received: %s", patch_data_json)

# This call is just to ensure that the patch data
# coming in is valid per the API schema
SessionUpdate.from_dict(patch_data_json) # noqa: E501

session_key = get_tenant_aware_key(session_id, get_tenant_from_header())
if session_key not in DB:
return connexion.problem(
status=404, title="Session could not found.",
detail="Session {} could not be found".format(session_id))

if not connexion.request.is_json:
return "Post must be in JSON format", 400
data = connexion.request.get_json()
component = DB.patch(session_key, data)
component = DB.patch(session_key, patch_data_json)
return component, 200


Expand Down

0 comments on commit a21e03e

Please sign in to comment.