Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.14.0 #243

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ 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-01-10
### Added
- Scalable Boot Provisioning Service (SBPS) support

## [2.13.0] 2024-01-10
### Fixed
- Fix a broken build caused by PEP-668. Pin Alpine version to 3. This is less restrictive.

## [2.12.0] - 2024-01-02
### Changed
Expand Down
13 changes: 9 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

# Upstream Build Args
ARG OPENAPI_IMAGE=artifactory.algol60.net/csm-docker/stable/docker.io/openapitools/openapi-generator-cli:v6.6.0
ARG ALPINE_BASE_IMAGE=artifactory.algol60.net/csm-docker/stable/docker.io/library/alpine:3.18
ARG ALPINE_BASE_IMAGE=artifactory.algol60.net/csm-docker/stable/docker.io/library/alpine:3

# Generate Code
FROM $OPENAPI_IMAGE as codegen
Expand Down Expand Up @@ -56,8 +56,13 @@ COPY constraints.txt requirements.txt /app/
RUN apk add --upgrade --no-cache apk-tools busybox && \
apk update && \
apk add --no-cache gcc g++ python3-dev py3-pip musl-dev libffi-dev openssl-dev && \
apk -U upgrade --no-cache && \
pip3 install --no-cache-dir -U pip
apk -U upgrade --no-cache
# Create a virtual environment in which we can install Python packages. This
# isolates our installation from the system installation.
ENV VIRTUAL_ENV=/app/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
RUN pip3 install --no-cache-dir -U pip
RUN --mount=type=secret,id=netrc,target=/root/.netrc pip3 install --no-cache-dir -r requirements.txt
RUN cd lib && pip3 install --no-cache-dir .

Expand Down Expand Up @@ -87,7 +92,7 @@ CMD [ "./docker_api_test_entry.sh" ]
FROM base as intermediate
WORKDIR /app
EXPOSE 9000
RUN apk add --no-cache uwsgi-python3
RUN pip3 install --no-cache-dir uWSGI
COPY config/uwsgi.ini ./
ENTRYPOINT ["uwsgi", "--ini", "/app/uwsgi.ini"]

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'
Loading