Skip to content

Commit

Permalink
intermediate work
Browse files Browse the repository at this point in the history
  • Loading branch information
ademariag committed May 1, 2024
1 parent e9d0736 commit 8ae0ec8
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 34 deletions.
7 changes: 7 additions & 0 deletions compiled/minikube-es/script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

set -ex

compile_dir=$1

echo "This is going into a file" > "${compile_dir}/${FILE_NAME}"
1 change: 1 addition & 0 deletions kapitan/inputs/jinja2.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from kapitan.inputs.base import CompiledFile, InputType
from kapitan.resources import inventory
from kapitan.utils import render_jinja2
import kapitan.cached as cached

logger = logging.getLogger(__name__)

Expand Down
3 changes: 3 additions & 0 deletions kapitan/inputs/jinja2_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def load_jinja2_filters_from_file(env, jinja2_filters):
if filter points to default file and in case it doesn't exist then proceed silently, no error
else try to load module (which will throw error in case of non existence of file)
"""
if not jinja2_filters:
return

jinja2_filters = os.path.normpath(jinja2_filters)
if jinja2_filters == defaults.DEFAULT_JINJA2_FILTERS_PATH:
if not os.path.isfile(jinja2_filters):
Expand Down
14 changes: 1 addition & 13 deletions kapitan/inventory/inv_omegaconf/inv_omegaconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def render_targets(self, targets: list[InventoryTarget] = None, ignore_class_not
# store parameters and classes
for target_name, rendered_target in shared_targets.items():
self.targets[target_name].parameters = rendered_target["parameters"]
self.targets[target_name].rendered = True

@staticmethod
def inventory_worker(zipped_args):
Expand Down Expand Up @@ -159,16 +160,3 @@ def _resolve_parameters(target_parameters: DictConfig):
OmegaConf.resolve(target_parameters, escape_interpolation_strings=False)
return OmegaConf.to_container(target_parameters)

@staticmethod
def _add_metadata(target: InventoryTarget):
# append meta data (legacy: _reclass_)
_kapitan_ = {
"name": {
"full": target.name,
"parts": target.name.split("."),
"path": target.name.replace(".", "/"),
"short": target.name.split(".")[-1],
}
}
target.parameters["_kapitan_"] = _kapitan_
target.parameters["_reclass_"] = _kapitan_ # legacy
1 change: 1 addition & 0 deletions kapitan/inventory/inv_reclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def render_targets(self, targets: list[InventoryTarget] = None, ignore_class_not
self.targets[target_name].classes = rendered_target["classes"]
self.targets[target_name].applications = rendered_target["applications"]
self.targets[target_name].exports = rendered_target["exports"]
self.targets[target_name].rendered = True

except ReclassException as e:
if isinstance(e, NotFoundError):
Expand Down
31 changes: 26 additions & 5 deletions kapitan/inventory/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@

import logging
import os
import time
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import overload, Union

from kapitan.errors import KapitanError
from reclass.values import item

logger = logging.getLogger(__name__)

Expand All @@ -22,11 +19,34 @@
class InventoryTarget:
name: str
path: str
parameters: dict = field(default_factory=dict)
rendered: bool = False
__parameters: dict = field(default_factory=dict)
classes: list = field(default_factory=list)
applications: list = field(default_factory=list)
exports: list = field(default_factory=dict)

@property
def parameters(self):
return self.__parameters

@parameters.setter
def parameters(self, parameters: dict):
self.__parameters = parameters
self._add_metadata()

def _add_metadata(self):
metadata = {
"name": {
"full": self.name,
"parts": self.name.split("."),
"path": self.name.replace(".", "/"),
"short": self.name.split(".")[-1],
}
}
self.parameters["_kapitan_"] = metadata
if "_reclass_" not in self.parameters:
self.parameters["_reclass_"] = metadata # legacy


class Inventory(ABC):
_default_path: str = "inventory"
Expand Down Expand Up @@ -112,7 +132,7 @@ def get_targets(self, target_names: list[str] = [], ignore_class_not_found: bool
raise InventoryError(f"target not found: {e}")

for target in targets.values():
if not target.parameters:
if not target.rendered:
targets_to_render.append(target)

if targets_to_render:
Expand Down Expand Up @@ -157,3 +177,4 @@ class InvalidTargetError(InventoryError):
"""inventory validation error"""

pass

31 changes: 15 additions & 16 deletions kapitan/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ def compile_targets(

if fetch:
# skip classes that are not yet available
target_objs = load_target_inventory(inventory_path, updated_targets, ignore_class_notfound=True)
target_objs = load_target_inventory_parameters(inventory_path, updated_targets, ignore_class_notfound=True)
else:
# ignore_class_notfound = False by default
target_objs = load_target_inventory(inventory_path, updated_targets)
target_objs = load_target_inventory_parameters(inventory_path, updated_targets)

# append "compiled" to output_path so we can safely overwrite it
compile_path = os.path.join(output_path, "compiled")
Expand All @@ -118,15 +118,15 @@ def compile_targets(
pool,
)
cached.reset_inv()
target_objs = load_target_inventory(
target_objs = load_target_inventory_parameters(
inventory_path, updated_targets, ignore_class_notfound=True
)
cached.inv_sources.update(new_sources)
new_sources = list(set(list_sources(target_objs)) - cached.inv_sources)
# reset inventory cache and load target objs to check for missing classes
if new_sources:
cached.reset_inv()
target_objs = load_target_inventory(inventory_path, updated_targets, ignore_class_notfound=False)
target_objs = load_target_inventory_parameters(inventory_path, updated_targets, ignore_class_notfound=False)
# fetch dependencies
if fetch:
fetch_dependencies(output_path, target_objs, dep_cache_dir, force_fetch, pool)
Expand All @@ -151,7 +151,7 @@ def compile_targets(
fetch_dependencies(output_path, fetch_objs, dep_cache_dir, True, pool)

logger.info("Rendered inventory (%.2fs)", time.time() - rendering_start)

logger.error("target_objs: %s", target_objs)
worker = partial(
compile_target,
search_paths=search_paths,
Expand Down Expand Up @@ -362,7 +362,7 @@ def save_inv_cache(compile_path, targets):
yaml.dump(cached.inv_cache, stream=f, default_flow_style=False)


def load_target_inventory(inventory_path, targets, ignore_class_notfound=False):
def load_target_inventory_parameters(inventory_path, targets, ignore_class_notfound=False):
"""returns a list of target objects from the inventory"""
target_objs = []
inv = get_inventory(inventory_path)
Expand All @@ -375,16 +375,15 @@ def load_target_inventory(inventory_path, targets, ignore_class_notfound=False):

for target_name in targets_list:
try:
target_obj = inv.get_parameters(target_name, ignore_class_notfound).get("kapitan")
target_inventory_parameters = inv.get_parameters(target_name, ignore_class_notfound)
# check if parameters.kapitan is empty
if not target_obj:
if not target_inventory_parameters["kapitan"]:
raise InventoryError(f"InventoryError: {target_name}: parameters.kapitan has no assignment")
target_obj["target_full_path"] = inv.targets[target_name].name.replace(".", "/")
require_compile = not ignore_class_notfound
valid_target_obj(target_obj, require_compile)
validate_matching_target_name(target_name, target_obj, inventory_path)
valid_target_obj(target_inventory_parameters["kapitan"], require_compile)
validate_matching_target_name(target_name, target_inventory_parameters["kapitan"], inventory_path)
logger.debug(f"load_target_inventory: found valid kapitan target {target_name}")
target_objs.append(target_obj)
target_objs.append(target_inventory_parameters)
except KeyError:
logger.debug(f"load_target_inventory: target {target_name} has no kapitan compile obj")

Expand Down Expand Up @@ -432,8 +431,8 @@ def search_targets(inventory_path, targets, labels):
def compile_target(target_obj, search_paths, compile_path, ref_controller, globals_cached=None, **kwargs):
"""Compiles target_obj and writes to compile_path"""
start = time.time()
compile_objs = target_obj["compile"]
ext_vars = target_obj["vars"]
compile_objs = target_obj["parameters"]["kapitan"]["compile"]
ext_vars = target_obj["parameters"]["kapitan"]["vars"]
target_name = ext_vars["target"]

if globals_cached:
Expand Down Expand Up @@ -484,7 +483,7 @@ def compile_target(target_obj, search_paths, compile_path, ref_controller, globa
traceback.print_exception(type(e), e, e.__traceback__)
raise CompileError(f"Error compiling {target_name}: {e}")

logger.info("Compiled %s (%.2fs)", target_obj["target_full_path"], time.time() - start)
logger.info("Compiled %s (%.2fs)", target_obj["_kapitan_"]["name"]["path"], time.time() - start)


@hashable_lru_cache
Expand Down Expand Up @@ -765,7 +764,7 @@ def schema_validate_compiled(args):
pool = multiprocessing.Pool(args.parallelism)

try:
target_objs = load_target_inventory(args.inventory_path, args.targets)
target_objs = load_target_inventory_parameters(args.inventory_path, args.targets)
validate_map = create_validate_mapping(target_objs, args.compiled_path)

[p.get() for p in pool.imap_unordered(worker, validate_map.items()) if p]
Expand Down
50 changes: 50 additions & 0 deletions tests/test_compile_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3

# Copyright 2019 The Kapitan Authors
# SPDX-FileCopyrightText: 2020 The Kapitan Authors <kapitan-admins@googlegroups.com>
#
# SPDX-License-Identifier: Apache-2.0

"compile tests"

import unittest
import os

from tempfile import TemporaryDirectory
from kapitan.resources import inventory
from kapitan.cached import args
from kapitan.targets import compile_target

INSTALLATION_PATH = "examples/kubernetes"
SEARCH_PATHS = [
os.getcwd(),
INSTALLATION_PATH,
]

class CompileCodeTest(unittest.TestCase):
def setUp(self):
args.inventory_backend = "reclass"
args.inventory_path = "inventory"
args.inv = inventory([INSTALLATION_PATH])

def test_compile(self):
target_name = "minikube-es"
with TemporaryDirectory() as dir:
target_obj = args.inv[target_name]
compile_target(
target_obj,
SEARCH_PATHS,
dir,
None,
None)

for root, dirs, files in os.walk(dir):
path = root.split(os.sep)
print((len(path) - 1) * '---', os.path.basename(root))
for file in files:
print(len(path) * '---', file)
assert os.path.exists(os.path.join(dir, target_name, "script.sh"))




0 comments on commit 8ae0ec8

Please sign in to comment.