Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/actions/features_parse/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ outputs:
runs:
using: composite
steps:
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/[email protected].0
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/[email protected].2
- id: result
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/flavors_parse/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ outputs:
runs:
using: composite
steps:
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/[email protected].0
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/[email protected].2
- id: matrix
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Installs the given GardenLinux Python library
inputs:
version:
description: GardenLinux Python library version
default: "0.7.0"
default: "0.7.2"
runs:
using: composite
steps:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "gardenlinux"
version = "0.7.0"
version = "0.7.2"
description = "Contains tools to work with the features directory of gardenlinux, for example deducting dependencies from feature sets or validating cnames"
authors = ["Garden Linux Maintainers <[email protected]>"]
license = "Apache-2.0"
Expand Down
4 changes: 2 additions & 2 deletions src/gardenlinux/oci/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Container(Registry):
:author: Garden Linux Maintainers
:copyright: Copyright 2024 SAP SE
:package: gardenlinux
:subpackage: flavors
:subpackage: oci
:since: 0.7.0
:license: https://www.apache.org/licenses/LICENSE-2.0
Apache License, Version 2.0
Expand Down Expand Up @@ -401,7 +401,7 @@ def push_manifest_and_artifacts(
cleanup_blob = True

manifest.append_layer(layer)
layer_dict = layer.to_dict()
layer_dict = layer.dict

self._logger.debug(f"Layer: {layer_dict}")

Expand Down
50 changes: 45 additions & 5 deletions src/gardenlinux/oci/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,25 @@


class Index(dict):
"""
OCI image index

:author: Garden Linux Maintainers
:copyright: Copyright 2024 SAP SE
:package: gardenlinux
:subpackage: oci
:since: 0.7.0
:license: https://www.apache.org/licenses/LICENSE-2.0
Apache License, Version 2.0
"""

def __init__(self, *args, **kwargs):
"""
Constructor __init__(Index)

:since: 0.7.0
"""

dict.__init__(self)

self.update(deepcopy(EmptyIndex))
Expand All @@ -16,23 +34,45 @@ def __init__(self, *args, **kwargs):

@property
def json(self):
"""
Returns the OCI image index as a JSON

:return: (bytes) OCI image index as JSON
:since: 0.7.0
"""

return json.dumps(self).encode("utf-8")

@property
def manifests_as_dict(self):
"""
Returns the OCI image manifests of the index

:return: (dict) OCI image manifests with CNAME or digest as key
:since: 0.7.0
"""

manifests = {}

for manifest in self["manifests"]:
if "cname" not in manifest.get("annotations", {}):
raise RuntimeError(
"Unexpected manifest with missing annotation 'cname' found"
)
if "annotations" not in manifest or "cname" not in manifest["annotations"]:
manifest_key = manifest["digest"]
else:
manifest_key = manifest["annotations"]["cname"]

manifests[manifest["annotations"]["cname"]] = manifest
manifests[manifest_key] = manifest

return manifests

def append_manifest(self, manifest):
"""
Appends the given OCI image manifest to the index

:param manifest: OCI image manifest

:since: 0.7.0
"""

if not isinstance(manifest, dict):
raise RuntimeError("Unexpected manifest type given")

Expand Down
71 changes: 56 additions & 15 deletions src/gardenlinux/oci/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,34 @@


class Layer(_Layer, Mapping):
"""
OCI image layer

:author: Garden Linux Maintainers
:copyright: Copyright 2024 SAP SE
:package: gardenlinux
:subpackage: oci
:since: 0.7.0
:license: https://www.apache.org/licenses/LICENSE-2.0
Apache License, Version 2.0
"""

def __init__(
self,
blob_path: PathLike | str,
media_type: Optional[str] = None,
is_dir: bool = False,
):
"""
Constructor __init__(Index)

:param blob_path: The path of the blob for the layer
:param media_type: Media type for the blob (optional)
:param is_dir: Is the blob a directory?

:since: 0.7.0
"""

if not isinstance(blob_path, PathLike):
blob_path = Path(blob_path)

Expand All @@ -28,11 +50,26 @@ def __init__(
ANNOTATION_TITLE: blob_path.name,
}

@property
def dict(self):
"""
Return a dictionary representation of the layer

:return: (dict) OCI manifest layer metadata dictionary
:since: 0.7.2
"""
layer = _Layer.to_dict(self)
layer["annotations"] = self._annotations

return layer

def __delitem__(self, key):
"""
python.org: Called to implement deletion of self[key].

:param key: Mapping key

:since: 0.7.0
"""

if key == "annotations":
Expand All @@ -49,6 +86,7 @@ def __getitem__(self, key):
:param key: Mapping key

:return: (mixed) Mapping key value
:since: 0.7.0
"""

if key == "annotations":
Expand All @@ -63,6 +101,7 @@ def __iter__(self):
python.org: Return an iterator object.

:return: (object) Iterator object
:since: 0.7.0
"""

iter(_SUPPORTED_MAPPING_KEYS)
Expand All @@ -71,7 +110,8 @@ def __len__(self):
"""
python.org: Called to implement the built-in function len().

:return: (int) Number of database instance attributes
:return: (int) Number of attributes
:since: 0.7.0
"""

return len(_SUPPORTED_MAPPING_KEYS)
Expand All @@ -82,6 +122,8 @@ def __setitem__(self, key, value):

:param key: Mapping key
:param value: self[key] value

:since: 0.7.0
"""

if key == "annotations":
Expand All @@ -91,21 +133,16 @@ def __setitem__(self, key, value):
f"'{self.__class__.__name__}' object is not subscriptable except for keys: {_SUPPORTED_MAPPING_KEYS}"
)

def to_dict(self):
"""
Return a dictionary representation of the layer
"""
layer = _Layer.to_dict(self)
layer["annotations"] = self._annotations

return layer

@staticmethod
def generate_metadata_from_file_name(file_name: PathLike | str, arch: str) -> dict:
"""
:param str file_name: file_name of the blob
:param str arch: the arch of the target image
:return: dict of oci layer metadata for a given layer file
Generates OCI manifest layer metadata for the given file path and name.

:param file_name: File path and name of the target layer
:param arch: The arch of the target image

:return: (dict) OCI manifest layer metadata dictionary
:since: 0.7.0
"""

if not isinstance(file_name, PathLike):
Expand All @@ -122,8 +159,12 @@ def generate_metadata_from_file_name(file_name: PathLike | str, arch: str) -> di
@staticmethod
def lookup_media_type_for_file_name(file_name: str) -> str:
"""
:param str file_name: file_name of the target layer
:return: mediatype
Looks up the media type based on file extension.

:param file_name: File path and name of the target layer

:return: (str) Media type
:since: 0.7.0
"""

if not isinstance(file_name, PathLike):
Expand Down
Loading