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

[Runtimes] Fix function config compilation to not ignore .spec.build.base_image for Nuclio runtimes #1565

Merged
14 changes: 9 additions & 5 deletions mlrun/runtimes/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,11 @@ def compile_function_config(function: RemoteRuntime):
)
update_in(config, "metadata.name", function.metadata.name)
update_in(config, "spec.volumes", function.spec.generate_nuclio_volumes())
base_image = get_in(config, "spec.build.baseImage") or function.spec.image
base_image = (
get_in(config, "spec.build.baseImage")
or function.spec.image
or function.spec.build.base_image
)
if base_image:
update_in(config, "spec.build.baseImage", enrich_image_url(base_image))

Expand All @@ -1153,10 +1157,12 @@ def compile_function_config(function: RemoteRuntime):
)

update_in(config, "spec.volumes", function.spec.generate_nuclio_volumes())
if function.spec.image:
base_image = function.spec.image or function.spec.build.base_image
if base_image:
update_in(
config, "spec.build.baseImage", enrich_image_url(function.spec.image)
config, "spec.build.baseImage", enrich_image_url(base_image),
)

name = get_fullname(name, project, tag)
function.status.nuclio_name = name

Expand All @@ -1166,7 +1172,6 @@ def compile_function_config(function: RemoteRuntime):


def enrich_function_with_ingress(config, mode, service_type):

# do not enrich with an ingress
if mode == NuclioIngressAddTemplatedIngressModes.never:
return
Expand All @@ -1181,7 +1186,6 @@ def enrich_function_with_ingress(config, mode, service_type):
# we would enrich it with an ingress
http_trigger = resolve_function_http_trigger(config["spec"])
if not http_trigger:

# function has an HTTP trigger without an ingress
# TODO: read from nuclio-api frontend-spec
http_trigger = {
Expand Down
45 changes: 43 additions & 2 deletions tests/api/runtimes/test_nuclio.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def _assert_deploy_called_basic_config(
expected_labels=None,
expected_env_from_secrets=None,
expected_service_account=None,
expected_build_base_image=None,
):
if expected_labels is None:
expected_labels = {}
Expand Down Expand Up @@ -164,7 +165,11 @@ def _assert_deploy_called_basic_config(
).decode("utf-8")
assert spec_source_code.startswith(original_source_code)

assert build_info["baseImage"] == self.image_name
if self.image_name or expected_build_base_image:
assert (
build_info["baseImage"] == self.image_name
or expected_build_base_image
)

if expected_env_from_secrets:
env_vars = deploy_config["spec"]["env"]
Expand Down Expand Up @@ -270,7 +275,6 @@ def _assert_node_selections(
== {}
)
if expected_affinity:

# deploy_spec returns affinity in CamelCase, V1Affinity is in snake_case
assert (
deepdiff.DeepDiff(
Expand Down Expand Up @@ -425,6 +429,43 @@ def test_deploy_basic_function(self, db: Session, client: TestClient):
self._serialize_and_deploy_nuclio_function(function)
self._assert_deploy_called_basic_config(expected_class=self.class_name)

def test_deploy_build_base_image(
self, db: Session, k8s_secrets_mock: K8sSecretsMock
):
expected_build_base_image = "mlrun/base_mlrun:latest"
self.image_name = None

function = self._generate_runtime(self.runtime_kind)
function.spec.build.base_image = expected_build_base_image

self._serialize_and_deploy_nuclio_function(function)
self._assert_deploy_called_basic_config(
expected_class=self.class_name,
expected_build_base_image=expected_build_base_image,
)

def test_deploy_image_name_and_build_base_image(
self, db: Session, k8s_secrets_mock: K8sSecretsMock
):
"""When spec.image and also spec.build.base_image are both defined the spec.image should be applied
to spec.baseImage in nuclio."""
Comment on lines +450 to +451
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""When spec.image and also spec.build.base_image are both defined the spec.image should be applied
to spec.baseImage in nuclio."""
"""When spec.image and also spec.build.base_image are both defined the spec.image should take precedence"""


function = self._generate_runtime(self.runtime_kind)
function.spec.build.base_image = "mlrun/base_mlrun:latest"

self._serialize_and_deploy_nuclio_function(function)
self._assert_deploy_called_basic_config(expected_class=self.class_name)

def test_deploy_without_image_and_build_base_image(
self, db: Session, k8s_secrets_mock: K8sSecretsMock
):
self.image_name = None

function = self._generate_runtime(self.runtime_kind)
self._serialize_and_deploy_nuclio_function(function)

self._assert_deploy_called_basic_config(expected_class=self.class_name)

def test_deploy_function_with_labels(self, db: Session, client: TestClient):
labels = {
"key": "value",
Expand Down