Fix containerize view symlink issue (#39419)
This commit is contained in:
parent
f0ed159a1b
commit
a2a52dfb21
@ -5,8 +5,8 @@
|
|||||||
"""Writers for different kind of recipes and related
|
"""Writers for different kind of recipes and related
|
||||||
convenience functions.
|
convenience functions.
|
||||||
"""
|
"""
|
||||||
import collections
|
|
||||||
import copy
|
import copy
|
||||||
|
from collections import namedtuple
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
@ -159,13 +159,13 @@ def depfile(self):
|
|||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Information related to the run image."""
|
"""Information related to the run image."""
|
||||||
Run = collections.namedtuple("Run", ["image"])
|
Run = namedtuple("Run", ["image"])
|
||||||
return Run(image=self.final_image)
|
return Run(image=self.final_image)
|
||||||
|
|
||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
def build(self):
|
def build(self):
|
||||||
"""Information related to the build image."""
|
"""Information related to the build image."""
|
||||||
Build = collections.namedtuple("Build", ["image"])
|
Build = namedtuple("Build", ["image"])
|
||||||
return Build(image=self.build_image)
|
return Build(image=self.build_image)
|
||||||
|
|
||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
@ -176,12 +176,13 @@ def strip(self):
|
|||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
def paths(self):
|
def paths(self):
|
||||||
"""Important paths in the image"""
|
"""Important paths in the image"""
|
||||||
Paths = collections.namedtuple("Paths", ["environment", "store", "hidden_view", "view"])
|
Paths = namedtuple("Paths", ["environment", "store", "view_parent", "view", "former_view"])
|
||||||
return Paths(
|
return Paths(
|
||||||
environment="/opt/spack-environment",
|
environment="/opt/spack-environment",
|
||||||
store="/opt/software",
|
store="/opt/software",
|
||||||
hidden_view="/opt/._view",
|
view_parent="/opt/views",
|
||||||
view="/opt/view",
|
view="/opt/views/view",
|
||||||
|
former_view="/opt/view", # /opt/view -> /opt/views/view for backward compatibility
|
||||||
)
|
)
|
||||||
|
|
||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
@ -257,7 +258,7 @@ def _package_info_from(self, package_list):
|
|||||||
|
|
||||||
update, install, clean = commands_for(os_pkg_manager)
|
update, install, clean = commands_for(os_pkg_manager)
|
||||||
|
|
||||||
Packages = collections.namedtuple("Packages", ["update", "install", "list", "clean"])
|
Packages = namedtuple("Packages", ["update", "install", "list", "clean"])
|
||||||
return Packages(update=update, install=install, list=package_list, clean=clean)
|
return Packages(update=update, install=install, list=package_list, clean=clean)
|
||||||
|
|
||||||
def _os_pkg_manager(self):
|
def _os_pkg_manager(self):
|
||||||
@ -273,7 +274,7 @@ def _os_pkg_manager(self):
|
|||||||
|
|
||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
def extra_instructions(self):
|
def extra_instructions(self):
|
||||||
Extras = collections.namedtuple("Extra", ["build", "final"])
|
Extras = namedtuple("Extra", ["build", "final"])
|
||||||
extras = self.container_config.get("extra_instructions", {})
|
extras = self.container_config.get("extra_instructions", {})
|
||||||
build, final = extras.get("build", None), extras.get("final", None)
|
build, final = extras.get("build", None), extras.get("final", None)
|
||||||
return Extras(build=build, final=final)
|
return Extras(build=build, final=final)
|
||||||
@ -295,7 +296,7 @@ def bootstrap(self):
|
|||||||
context = {"bootstrap": {"image": self.bootstrap_image, "spack_checkout": command}}
|
context = {"bootstrap": {"image": self.bootstrap_image, "spack_checkout": command}}
|
||||||
bootstrap_recipe = env.get_template(template_path).render(**context)
|
bootstrap_recipe = env.get_template(template_path).render(**context)
|
||||||
|
|
||||||
Bootstrap = collections.namedtuple("Bootstrap", ["image", "recipe"])
|
Bootstrap = namedtuple("Bootstrap", ["image", "recipe"])
|
||||||
return Bootstrap(image=self.bootstrap_image, recipe=bootstrap_recipe)
|
return Bootstrap(image=self.bootstrap_image, recipe=bootstrap_recipe)
|
||||||
|
|
||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
@ -303,7 +304,7 @@ def render_phase(self):
|
|||||||
render_bootstrap = bool(self.bootstrap_image)
|
render_bootstrap = bool(self.bootstrap_image)
|
||||||
render_build = not (self.last_phase == "bootstrap")
|
render_build = not (self.last_phase == "bootstrap")
|
||||||
render_final = self.last_phase in (None, "final")
|
render_final = self.last_phase in (None, "final")
|
||||||
Render = collections.namedtuple("Render", ["bootstrap", "build", "final"])
|
Render = namedtuple("Render", ["bootstrap", "build", "final"])
|
||||||
return Render(bootstrap=render_bootstrap, build=render_build, final=render_final)
|
return Render(bootstrap=render_bootstrap, build=render_build, final=render_final)
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
|
@ -51,15 +51,17 @@ FROM {{ run.image }}
|
|||||||
|
|
||||||
COPY --from=builder {{ paths.environment }} {{ paths.environment }}
|
COPY --from=builder {{ paths.environment }} {{ paths.environment }}
|
||||||
COPY --from=builder {{ paths.store }} {{ paths.store }}
|
COPY --from=builder {{ paths.store }} {{ paths.store }}
|
||||||
COPY --from=builder {{ paths.hidden_view }} {{ paths.hidden_view }}
|
|
||||||
COPY --from=builder {{ paths.view }} {{ paths.view }}
|
# paths.view is a symlink, so copy the parent to avoid dereferencing and duplicating it
|
||||||
|
COPY --from=builder {{ paths.view_parent }} {{ paths.view_parent }}
|
||||||
|
|
||||||
RUN { \
|
RUN { \
|
||||||
echo '#!/bin/sh' \
|
echo '#!/bin/sh' \
|
||||||
&& echo '.' {{ paths.environment }}/activate.sh \
|
&& echo '.' {{ paths.environment }}/activate.sh \
|
||||||
&& echo 'exec "$@"'; \
|
&& echo 'exec "$@"'; \
|
||||||
} > /entrypoint.sh \
|
} > /entrypoint.sh \
|
||||||
&& chmod a+x /entrypoint.sh
|
&& chmod a+x /entrypoint.sh \
|
||||||
|
&& ln -s {{ paths.view }} {{ paths.former_view }}
|
||||||
|
|
||||||
{% block final_stage %}
|
{% block final_stage %}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ EOF
|
|||||||
{% for application, help_text in apps.items() %}
|
{% for application, help_text in apps.items() %}
|
||||||
|
|
||||||
%apprun {{ application }}
|
%apprun {{ application }}
|
||||||
exec /opt/view/bin/{{ application }} "$@"
|
exec {{ paths.view }}/bin/{{ application }} "$@"
|
||||||
|
|
||||||
%apphelp {{ application }}
|
%apphelp {{ application }}
|
||||||
{{help_text }}
|
{{help_text }}
|
||||||
@ -61,11 +61,14 @@ Stage: final
|
|||||||
%files from build
|
%files from build
|
||||||
{{ paths.environment }} /opt
|
{{ paths.environment }} /opt
|
||||||
{{ paths.store }} /opt
|
{{ paths.store }} /opt
|
||||||
{{ paths.hidden_view }} /opt
|
{{ paths.view_parent }} /opt
|
||||||
{{ paths.view }} /opt
|
|
||||||
{{ paths.environment }}/environment_modifications.sh {{ paths.environment }}/environment_modifications.sh
|
{{ paths.environment }}/environment_modifications.sh {{ paths.environment }}/environment_modifications.sh
|
||||||
|
|
||||||
%post
|
%post
|
||||||
|
|
||||||
|
# Symlink the old view location
|
||||||
|
ln -s {{ paths.view }} {{ paths.former_view }}
|
||||||
|
|
||||||
{% block final_stage %}
|
{% block final_stage %}
|
||||||
{% if os_packages_final.list %}
|
{% if os_packages_final.list %}
|
||||||
# Update, install and cleanup of system packages needed at run-time
|
# Update, install and cleanup of system packages needed at run-time
|
||||||
|
Loading…
Reference in New Issue
Block a user