Beispiel #1
0
    def setUp(self):
        # create a build graph with 2 function definitions and 2 layer definitions
        self.build_graph = BuildGraph("build_dir")

        self.function1_1 = Mock()
        self.function1_1.inlinecode = None
        self.function1_2 = Mock()
        self.function1_2.inlinecode = None
        self.function2 = Mock()
        self.function2.inlinecode = None

        self.function_build_definition1 = FunctionBuildDefinition(
            "runtime", "codeuri", ZIP, {})
        self.function_build_definition1.functions = [
            self.function1_1, self.function1_2
        ]
        self.function_build_definition2 = FunctionBuildDefinition(
            "runtime2", "codeuri", ZIP, {})
        self.function_build_definition1.functions = [self.function2]
        self.build_graph.put_function_build_definition(
            self.function_build_definition1, Mock(packagetype=ZIP))
        self.build_graph.put_function_build_definition(
            self.function_build_definition2, Mock(packagetype=ZIP))

        self.layer_build_definition1 = LayerBuildDefinition(
            "layer1", "codeuri", "build_method", [])
        self.layer_build_definition2 = LayerBuildDefinition(
            "layer2", "codeuri", "build_method", [])
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition1, Mock())
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition2, Mock())
    def test_layer_build_should_fail_when_no_build_method_is_provided(self, mock_copy_tree, mock_path):
        given_layer = Mock()
        given_layer.build_method = None
        layer_build_definition = LayerBuildDefinition("layer1", "codeuri", "build_method", [])
        layer_build_definition.layer = given_layer

        build_graph = Mock(spec=BuildGraph)
        build_graph.get_layer_build_definitions.return_value = [layer_build_definition]
        build_graph.get_function_build_definitions.return_value = []
        default_build_strategy = DefaultBuildStrategy(build_graph, "build_dir", Mock(), Mock())

        self.assertRaises(MissingBuildMethodException, default_build_strategy.build)
Beispiel #3
0
    def _get_build_graph(self):
        """
        Converts list of functions and layers into a build graph, where we can iterate on each unique build and trigger
        build
        :return: BuildGraph, which represents list of unique build definitions
        """
        build_graph = BuildGraph(self._build_dir)
        functions = self._resources_to_build.functions
        layers = self._resources_to_build.layers
        for function in functions:
            function_build_details = FunctionBuildDefinition(
                function.runtime, function.codeuri, function.packagetype,
                function.metadata)
            build_graph.put_function_build_definition(function_build_details,
                                                      function)

        for layer in layers:
            layer_build_details = LayerBuildDefinition(
                layer.name, layer.codeuri, layer.build_method,
                layer.compatible_runtimes)
            build_graph.put_layer_build_definition(layer_build_details, layer)

        build_graph.clean_redundant_definitions_and_update(
            not self._is_building_specific_resource)
        return build_graph
Beispiel #4
0
    def test_layer_build_definition_to_toml_table(self):
        build_definition = LayerBuildDefinition("name", "codeuri", "method",
                                                "runtime")
        build_definition.layer = generate_function()

        toml_table = _layer_build_definition_to_toml_table(build_definition)

        self.assertEqual(toml_table[LAYER_NAME_FIELD], build_definition.name)
        self.assertEqual(toml_table[CODE_URI_FIELD], build_definition.codeuri)
        self.assertEqual(toml_table[BUILD_METHOD_FIELD],
                         build_definition.build_method)
        self.assertEqual(toml_table[COMPATIBLE_RUNTIMES_FIELD],
                         build_definition.compatible_runtimes)
        self.assertEqual(toml_table[LAYER_FIELD], build_definition.layer.name)
        self.assertEqual(toml_table[SOURCE_MD5_FIELD],
                         build_definition.source_md5)
    def setUp(self):
        # create a build graph with 2 function definitions and 2 layer definitions
        self.build_graph = BuildGraph("build_dir")

        self.function1_1 = Mock()
        self.function1_1.inlinecode = None
        self.function1_1.get_build_dir = Mock()
        self.function1_1.full_path = Mock()
        self.function1_2 = Mock()
        self.function1_2.inlinecode = None
        self.function1_2.get_build_dir = Mock()
        self.function1_2.full_path = Mock()
        self.function2 = Mock()
        self.function2.inlinecode = None
        self.function2.get_build_dir = Mock()
        self.function2.full_path = Mock()

        self.function_build_definition1 = FunctionBuildDefinition(
            "runtime", "codeuri", ZIP, {})
        self.function_build_definition2 = FunctionBuildDefinition(
            "runtime2", "codeuri", ZIP, {})
        self.build_graph.put_function_build_definition(
            self.function_build_definition1, self.function1_1)
        self.build_graph.put_function_build_definition(
            self.function_build_definition1, self.function1_2)
        self.build_graph.put_function_build_definition(
            self.function_build_definition2, self.function2)

        self.layer1 = Mock()
        self.layer2 = Mock()

        self.layer_build_definition1 = LayerBuildDefinition(
            "layer1", "codeuri", "build_method", [])
        self.layer_build_definition2 = LayerBuildDefinition(
            "layer2", "codeuri", "build_method", [])
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition1, self.layer1)
        self.build_graph.put_layer_build_definition(
            self.layer_build_definition2, self.layer2)
    def _get_build_graph(self,
                         inline_env_vars: Optional[Dict] = None,
                         env_vars_file: Optional[str] = None) -> BuildGraph:
        """
        Converts list of functions and layers into a build graph, where we can iterate on each unique build and trigger
        build
        :return: BuildGraph, which represents list of unique build definitions
        """
        build_graph = BuildGraph(self._build_dir)
        functions = self._resources_to_build.functions
        layers = self._resources_to_build.layers
        file_env_vars = {}
        if env_vars_file:
            try:
                with open(env_vars_file, "r", encoding="utf-8") as fp:
                    file_env_vars = json.load(fp)
            except Exception as ex:
                raise IOError(
                    "Could not read environment variables overrides from file {}: {}"
                    .format(env_vars_file, str(ex))) from ex

        for function in functions:
            container_env_vars = self._make_env_vars(function, file_env_vars,
                                                     inline_env_vars)
            function_build_details = FunctionBuildDefinition(
                function.runtime,
                function.codeuri,
                function.packagetype,
                function.metadata,
                env_vars=container_env_vars)
            build_graph.put_function_build_definition(function_build_details,
                                                      function)

        for layer in layers:
            container_env_vars = self._make_env_vars(layer, file_env_vars,
                                                     inline_env_vars)
            layer_build_details = LayerBuildDefinition(
                layer.name,
                layer.codeuri,
                layer.build_method,
                layer.compatible_runtimes,
                env_vars=container_env_vars)
            build_graph.put_layer_build_definition(layer_build_details, layer)

        build_graph.clean_redundant_definitions_and_update(
            not self._is_building_specific_resource)
        return build_graph
Beispiel #7
0
    def build_single_layer_definition(
            self, layer_definition: LayerBuildDefinition) -> Dict[str, str]:
        """
        Builds single layer definition with caching
        """
        code_dir = str(
            pathlib.Path(self._base_dir,
                         cast(str, layer_definition.codeuri)).resolve())
        source_md5 = dir_checksum(code_dir)
        cache_function_dir = pathlib.Path(self._cache_dir,
                                          layer_definition.uuid)
        layer_build_result = {}

        if not cache_function_dir.exists(
        ) or layer_definition.source_md5 != source_md5:
            LOG.info(
                "Cache is invalid, running build and copying resources to layer build definition of %s",
                layer_definition.uuid,
            )
            build_result = self._delegate_build_strategy.build_single_layer_definition(
                layer_definition)
            layer_build_result.update(build_result)

            if cache_function_dir.exists():
                shutil.rmtree(str(cache_function_dir))

            layer_definition.source_md5 = source_md5
            # Since all the build contents are same for a build definition, just copy any one of them into the cache
            for _, value in build_result.items():
                osutils.copytree(value, cache_function_dir)
                break
        else:
            LOG.info(
                "Valid cache found, copying previously built resources from layer build definition of %s",
                layer_definition.uuid,
            )
            # artifacts directory will be created by the builder
            artifacts_dir = str(
                pathlib.Path(self._build_dir,
                             layer_definition.layer.full_path))
            LOG.debug("Copying artifacts from %s to %s", cache_function_dir,
                      artifacts_dir)
            osutils.copytree(cache_function_dir, artifacts_dir)
            layer_build_result[
                layer_definition.layer.full_path] = artifacts_dir

        return layer_build_result