Repository: cekit/cekit

Issue:
Add new fields to module.yaml envs
We are doing some automation that uses module.yaml. 
We would need need fields added to envs. Currently we only have name and description, we need required="true"|"false" and usage="build-time"|"execution-time".


Discussion:

Patch:
diff --git a/cekit/descriptor/env.py b/cekit/descriptor/env.py
index 036a4f4..5d7949b 100644
--- a/cekit/descriptor/env.py
+++ b/cekit/descriptor/env.py
@@ -6,7 +6,9 @@ from cekit.descriptor import Descriptor
 
 env_schema = yaml.safe_load(
     """
-map:
+type: map
+allowempty: True
+mapping:
   name: {type: str, required: True}
   value: {type: any}
   example: {type: any}
diff --git a/cekit/descriptor/execute.py b/cekit/descriptor/execute.py
index a88c766..f54d97d 100644
--- a/cekit/descriptor/execute.py
+++ b/cekit/descriptor/execute.py
@@ -13,13 +13,6 @@ execute_schemas = yaml.safe_load(
           user: {type: text}"""
 )
 
-# TODO: This seems unused?
-container_schemas = yaml.safe_load(
-    """
-        seq:
-          - {type: any}"""
-)
-
 logger = logging.getLogger("cekit")
 
 
diff --git a/cekit/descriptor/packages.py b/cekit/descriptor/packages.py
index d93b23f..4f4b064 100644
--- a/cekit/descriptor/packages.py
+++ b/cekit/descriptor/packages.py
@@ -45,10 +45,6 @@ map:
       repository: {type: str}
   rpm: {type: str}
   description: {type: str}
-  odcs:
-    map:
-     pulp: {type: str}
-  filename: {type: str}
   """
 )
 
@@ -162,19 +158,13 @@ class Repository(Descriptor):
         self.schema = repository_schema
         super(Repository, self).__init__(descriptor)
 
-        if not (
-            ("url" in descriptor)
-            ^ ("odcs" in descriptor)
-            ^ ("id" in descriptor)
-            ^ ("rpm" in descriptor)
-        ):
+        if not (("url" in descriptor) ^ ("id" in descriptor) ^ ("rpm" in descriptor)):
             raise CekitError(
                 "Repository '%s' is invalid, you can use only one of "
-                "['id', 'odcs', 'rpm', 'url']" % descriptor["name"]
+                "['id', 'rpm', 'url']" % descriptor["name"]
             )
 
-        if "filename" not in descriptor:
-            descriptor["filename"] = "%s.repo" % descriptor["name"].replace(" ", "_")
+        descriptor["filename"] = "%s.repo" % descriptor["name"].replace(" ", "_")
 
         if "url" not in descriptor:
             descriptor["url"] = {}
@@ -216,8 +206,6 @@ class Repository(Descriptor):
         self._descriptor["id"] = value
         self._descriptor.pop("url", None)
         self._descriptor.pop("rpm", None)
-        self._descriptor.pop("odcs", None)
-        self._descriptor.pop("filename", None)
 
     @property
     def url(self):
@@ -228,8 +216,6 @@ class Repository(Descriptor):
         self._descriptor["url"] = value
         self._descriptor.pop("id", None)
         self._descriptor.pop("rpm", None)
-        self._descriptor.pop("odcs", None)
-        self._descriptor.pop("filename", None)
 
     @property
     def rpm(self):
@@ -240,29 +226,3 @@ class Repository(Descriptor):
         self._descriptor["rpm"] = value
         self._descriptor.pop("id", None)
         self._descriptor.pop("url", None)
-        self._descriptor.pop("odcs", None)
-        self._descriptor.pop("filename", None)
-
-    @property
-    def odcs(self):
-        return self.get("odcs")
-
-    @odcs.setter
-    def odcs(self, value):
-        self._descriptor["odcs"] = value
-        self._descriptor.pop("id", None)
-        self._descriptor.pop("url", None)
-        self._descriptor.pop("rpm", None)
-        self._descriptor.pop("filename", None)
-
-    @property
-    def filename(self):
-        return self.get("filename")
-
-    @filename.setter
-    def filename(self, value):
-        self._descriptor["filename"] = value
-        self._descriptor.pop("id", None)
-        self._descriptor.pop("url", None)
-        self._descriptor.pop("rpm", None)
-        self._descriptor.pop("odcs", None)
diff --git a/cekit/generator/base.py b/cekit/generator/base.py
index c78f5a0..5b75fd5 100644
--- a/cekit/generator/base.py
+++ b/cekit/generator/base.py
@@ -589,10 +589,6 @@ class Generator(object):
             )
             return False
 
-        if "content_sets" in repo:
-            self._fetch_repos = True
-            return self._prepare_content_sets(repo)
-
         elif "rpm" in repo:
             self._prepare_repository_rpm(repo)
             return False
diff --git a/docs/descriptor/includes/envs.rst b/docs/descriptor/includes/envs.rst
index 3171143..c51c7a1 100644
--- a/docs/descriptor/includes/envs.rst
+++ b/docs/descriptor/includes/envs.rst
@@ -40,6 +40,11 @@ Environment variables can be divided into two types:
     generated to the build source (the Dockerfile). These can be used instead as a
     source for generating documentation.
 
+.. note::
+
+    Both forms support adding arbitrary additional keys. These are ignored by
+    CEKit, but might be useful for documentation or other tooling.
+
 .. code-block:: yaml
 
     envs:
@@ -58,3 +63,10 @@ Environment variables can be divided into two types:
         - name: "OPENSHIFT_KUBE_PING_LABELS"
             example: "application=eap-app"
             description: "Clustering labels selector."
+
+        # Both forms may have arbitrary additional metadata keys
+        - name: "OPENSHIFT_KUBE_PING_LABELS"
+            example: "application=eap-app"
+            description: "Clustering labels selector."
+            required: True
+            execution-time: True
diff --git a/tox.ini b/tox.ini
index eea6cad..0293735 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,10 @@ envlist = py36,py37,py38,py39,py310,py311
 [testenv]
 deps=pipenv
 setenv=PIPENV_VERBOSITY=-1
-passenv=USER HOME REGISTRY_AUTH_FILE
+passenv=
+        USER
+        HOME
+        REGISTRY_AUTH_FILE
 commands=
   pipenv install --dev --ignore-pipfile --skip-lock
   pipenv run pytest -vv --cov-report term --cov-report html --cov cekit --basetemp={envtmpdir} --junit-xml target/junit-{envname}.xml --junit-prefix {envname} {posargs}


Test patch:
diff --git a/tests/test_dockerfile.py b/tests/test_dockerfile.py
index 94e94c9..a93b09f 100644
--- a/tests/test_dockerfile.py
+++ b/tests/test_dockerfile.py
@@ -73,6 +73,7 @@ def print_test_name(value):
                         "value": "set_value",
                         "example": "example_value",
                         "description": "This is a description",
+                        "arbitraryField": "arbitrary value",
                     },
                 ]
             },
@@ -274,12 +275,7 @@ def test_dockerfile_osbs_odcs_pulp_no_redhat(tmpdir, mocker):
 
     target = str(tmpdir.mkdir("target"))
     desc_part = {
-        "packages": {
-            "repositories": [
-                {"name": "foo", "odcs": {"pulp": "rhel-7-server-rpms"}},
-            ],
-            "install": ["a"],
-        },
+        "packages": {"content_sets": {"x86_64": "foo"}, "install": ["a"]},
         "osbs": {"repository": {"name": "repo_name", "branch": "branch_name"}},
     }
 
diff --git a/tests/test_unit_descriptor.py b/tests/test_unit_descriptor.py
index 6bdd5fd..db0405d 100644
--- a/tests/test_unit_descriptor.py
+++ b/tests/test_unit_descriptor.py
@@ -185,6 +185,8 @@ def test_image():
     envs:
       - name: env1
         value: env1val
+        required: false
+        usage: build-time
     """
         ),
         "foo",
@@ -193,6 +195,7 @@ def test_image():
     assert image["name"] == "test/foo"
     assert type(image["labels"][0]) == Label
     assert image["labels"][0]["name"] == "test"
+    assert image["envs"][0]["required"] is False
 
 
 def test_image_missing_name():