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

Add cylc-flow, cylc-rose, cylc-uiserver from spack develop; update setup-meta-modules extension for Python #377

Merged
merged 28 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3096809
New package py-ansimarkup
climbfuji Nov 21, 2023
52b5119
New package py-metomi-isodatetime
climbfuji Nov 21, 2023
f9a635e
New package py-graphql-relay
climbfuji Nov 21, 2023
cfe703d
Add py-aniso8601@7.0.0
climbfuji Nov 21, 2023
2726365
New package py-graphene
climbfuji Nov 21, 2023
5918da2
New package py-cylc-flow
climbfuji Nov 21, 2023
47f640d
Add py-mepo
climbfuji Nov 21, 2023
52814c3
Merge branch 'jcsda_emc_spack_stack' of https://github.com/jcsda/spac…
climbfuji Dec 4, 2023
87e5331
Merge branch 'nov2023_spackmerge' of https://github.com/alexanderrich…
climbfuji Dec 4, 2023
8b893af
py-metomi-isodatetime: fix url parsing
adamjstewart Dec 4, 2023
b3c8168
Update py-werkzeug version dependency for py-graphene-tornado@2.6.1
climbfuji Dec 5, 2023
b91f89c
Add note on diverging version requirements for py-werkzeug in py-grap…
climbfuji Dec 5, 2023
7853d5c
Update logic in for 'spack stack setup-meta-modules (lib/jcsda-emc/sp…
climbfuji Dec 5, 2023
e49e9bf
Merge branch 'nov2023_spackmerge' of https://github.com/alexanderrich…
climbfuji Dec 7, 2023
7c5f0de
Merge branch 'jcsda_emc_spack_stack' of https://github.com/jcsda/spac…
climbfuji Dec 7, 2023
b32d6d5
Remove unnecessary and wrong package py-mepo
climbfuji Dec 7, 2023
1fe069d
Fix style errors in lib/jcsda-emc/spack-stack/stack/meta_modules.py
climbfuji Dec 7, 2023
6c5d71a
Add variants ecflow and cylc for ewok-env
climbfuji Dec 7, 2023
7843506
Merge branch 'jcsda_emc_spack_stack' of https://github.com/jcsda/spac…
climbfuji Dec 11, 2023
6d01484
Fix typo in var/spack/repos/jcsda-emc-bundles/packages/ewok-env/packa…
climbfuji Dec 11, 2023
d75abcc
fms: add v2023.04 (#41475)
AlexanderRichert-NOAA Dec 11, 2023
bd372d2
Add @climbfuji to fms maintainers (#41550)
climbfuji Dec 11, 2023
9e24e59
Skip 'icc.patch' in var/spack/repos/builtin/packages/py-gevent/packag…
climbfuji Dec 11, 2023
b0baa0a
Proceed without MPI or Python modules if not in environment
climbfuji Dec 12, 2023
e256fe2
Fix formatting errors in lib/jcsda-emc/spack-stack/stack/meta_modules.py
climbfuji Dec 12, 2023
aa011fc
Remove black.patch
climbfuji Dec 12, 2023
1bf79af
Merge branch 'jcsda_emc_spack_stack' of https://github.com/jcsda/spac…
climbfuji Dec 13, 2023
d1998c1
Merge branch 'jcsda_emc_spack_stack' into feature/add_cylc_flow
climbfuji Dec 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 38 additions & 78 deletions lib/jcsda-emc/spack-stack/stack/meta_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ def get_matched_dict(root_dir, candidate_list, sub_candidate_list=None):
matched_dict[matched_name] = [matched_version]
else:
matched_dict[matched_name].append(matched_version)
# Dedupe
matched_dict[matched_name] = list(set(matched_dict[matched_name]))
# MPI providers or example depend on compilers
else:
if matched_name not in matched_dict.keys():
Expand Down Expand Up @@ -302,11 +304,7 @@ def setup_meta_modules():
# Then, check for mpi providers - recursively for compilers
mpi_dict = get_matched_dict(module_dir, mpi_candidate_list, compiler_candidate_list)
if not mpi_dict:
user_input = input(
"No matching MPI providers found, proceed without creating MPI module hierarchy? (yes/no): "
)
if not user_input.lower() in ["yes", "y"]:
raise Exception("No matching MPI providers found")
logging.warn("No matching MPI providers found, skipping MPI module hierarchy")
else:
logging.info(" ... stack mpi providers: '{}'".format(mpi_dict))

Expand Down Expand Up @@ -697,83 +695,47 @@ def setup_meta_modules():
f.write(module_content)
logging.info(" ... writing {}".format(mpi_module_file))

try:
del package_name
except:
pass
# Create python modules. Need to accommodate both external
# Python distributions and spack-built Python distributions.
# If there is no package config info for Python, then we are
# using a spack-built Python without knowing the version - not supported.
if not "python" in package_config.keys():
raise Exception(
"""No information on Python in package config. For external
Python distributions, specify complete specifications. For spack-built
Python, list the correct version in the package config"""
)
else:
package_name = "python"
if "externals" in package_config[package_name].keys():
# Loop through all external specs and find the
# latest version, this is what spack is using
spack_python_build = False
python_version = None
for i in range(len(package_config[package_name]["externals"])):
(python_name, python_version_test) = get_name_and_version_from_spec(
package_config[package_name]["externals"][i]["spec"]
)
if not python_version or versiontuple(python_version_test) > versiontuple(
python_version
):
python_version = python_version_test
python_package_config = package_config[python_name]["externals"][i]
logging.debug(" ... using external python version {}".format(python_version))
else:
spack_python_build = True
python_name = "python"
python_version = None
python_package_config = None
# Loop through versions, pick the most-recent
for python_version_test in package_config[package_name]["version"]:
if not python_version or versiontuple(python_version_test) > versiontuple(
python_version
):
python_version = python_version_test
logging.debug(" ... using spack-built python version {}".format(python_version))
# Check that the Python version we determined is indeed what's installed
python_candidate_list = ["python@{}".format(python_version)]
for compiler_name in compiler_dict.keys():
for compiler_version in compiler_dict[compiler_name]:
compiler_install_dir = os.path.join(
install_dir, compiler_name, compiler_version
)
python_dict = get_matched_dict(compiler_install_dir, python_candidate_list)
logging.info(" ... stack python providers: '{}'".format(python_dict))
if not python_dict:
user_input = input(
"No matching Python version found found, proceed without creating Python modules? (yes/no): "
)
if not user_input.lower() in ["yes", "y"]:
raise Exception(
""""No matching Python version found. Make sure that the
Python version in the package config matches what spack installed."""
)
else:
logging.info(
"Metamodule generation completed successfully in {}".format(
meta_module_dir
)
)
return
python_dict = {}
python_name = "python"

# First, collect all Python packages in the environment
for spec in ev.installed_specs():
if spec.name == python_name:
compiler_name = spec.compiler.name
compiler_version = str(spec.compiler.version)
if not compiler_name in python_dict.keys():
python_dict[compiler_name] = {}
if compiler_version in python_dict[compiler_name].keys():
raise Exception("Duplicate Python packages for compiler {spec.compiler}")
python_dict[compiler_name][compiler_version] = spec

for compiler_name in compiler_dict.keys():
for compiler_version in compiler_dict[compiler_name]:
if (
not compiler_name in python_dict.keys()
or not compiler_version in python_dict[compiler_name].keys()
):
logging.warn(
"No Python version found for compiler {compiler_name}@{compiler_version}, skipping Python modules"
)
continue
spec = python_dict[compiler_name][compiler_version]
python_version = str(spec.version)
logging.info(
" ... configuring stack python interpreter {}@{} for compiler {}@{}".format(
python_name, python_version, compiler_name, compiler_version
)
)

if spec.external:
logging.debug(f" ... using external python version {python_version}")
prefix = spec.external_path
modules = spec.external_modules
else:
logging.debug(f" ... using spack-built python version {python_version}")

# Path and name for lua module file
python_module_dir = os.path.join(
module_dir, compiler_name, compiler_version, "stack-" + python_name
Expand All @@ -783,12 +745,12 @@ def setup_meta_modules():
)

substitutes = SUBSTITUTES_TEMPLATE.copy()
#
if spack_python_build:
# Spack-built Python vs external Python
if not spec.external:
module = "python/{}".format(python_version)
# Load spack python module
substitutes["MODULELOADS"] += module_load_command(module_choice, module)
elif "modules" in python_package_config.keys():
elif modules:
# Existing non-spack modules to load
for module in python_package_config["modules"]:
substitutes["MODULELOADS"] += module_load_command(module_choice, module)
Expand All @@ -798,14 +760,12 @@ def setup_meta_modules():
logging.debug(" ... ... MODULELOADS: {}".format(substitutes["MODULELOADS"]))
logging.debug(" ... ... MODULEPREREQS: {}".format(substitutes["MODULEPREREQS"]))
# python_name_ROOT - replace "-" in python_name with "_" for environment variables
if "prefix" in python_package_config.keys():
prefix = python_package_config["prefix"]
if prefix:
substitutes["PYTHONROOT"] = setenv_command(
module_choice, python_name.replace("-", "_") + "_ROOT", prefix
)
logging.debug(" ... ... PYTHONROOT: {}".format(substitutes["PYTHONROOT"]))
elif "prefix" in python_package_config.keys():
prefix = python_package_config["prefix"]
elif prefix:
# PATH
bindir = os.path.join(prefix, "bin")
if os.path.isdir(bindir):
Expand Down
9 changes: 7 additions & 2 deletions var/spack/repos/builtin/packages/py-cylc-flow/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ class PyCylcFlow(PythonPackage):
homepage = "https://cylc.org"
pypi = "cylc-flow/cylc-flow-8.1.4.tar.gz"

maintainers("LydDeb")
maintainers("LydDeb", "climbfuji")

version("8.2.3", sha256="dd5bea9e4b8dad00edd9c3459a38fb778e5a073da58ad2725bc9b84ad718e073")
version("8.2.0", sha256="cbe35e0d72d1ca36f28a4cebe9b9040a3445a74253bc94051a3c906cf179ded0")
version("8.1.4", sha256="d1835ac18f6f24f3115c56b2bc821185484e834a86b12fd0033ff7e4dc3c1f63")

Expand All @@ -24,7 +25,8 @@ class PyCylcFlow(PythonPackage):
depends_on("py-colorama@0.4:1", type=("build", "run"))
depends_on("py-graphene@2.1:2", type=("build", "run"))
depends_on("py-jinja2@3.0", type=("build", "run"))
depends_on("py-metomi-isodatetime@3.0", type=("build", "run"))
depends_on("py-metomi-isodatetime@3.0", type=("build", "run"), when="@:8.2.0")
depends_on("py-metomi-isodatetime@3:3.1", type=("build", "run"), when="@8.2.3:")
depends_on("py-protobuf@4.21.2:4.21", type=("build", "run"))
depends_on("py-psutil@5.6.0:", type=("build", "run"))
depends_on("py-pyzmq@22:", type=("build", "run"), when="@8.2:")
Expand All @@ -34,3 +36,6 @@ class PyCylcFlow(PythonPackage):
depends_on("py-rx", type=("build", "run"))
depends_on("py-promise", type=("build", "run"))
depends_on("py-tomli@2:", type=("build", "run"), when="^python@:3.10")

# Non-Python dependencies
depends_on("graphviz", type="run")
2 changes: 1 addition & 1 deletion var/spack/repos/builtin/packages/py-gevent/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class PyGevent(PythonPackage):
conflicts("^py-cython@3:", when="@:20.5.0")

# Deprecated compiler options. upstream PR: https://github.com/gevent/gevent/pull/1896
patch("icc.patch", when="%intel")
patch("icc.patch", when="@:21.12.0 %intel")

@run_before("install")
def recythonize(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ class PyGrapheneTornado(PythonPackage):
depends_on("py-graphene@2.1:2", type=("build", "run"))
depends_on("py-jinja2@2.10.1:", type=("build", "run"))
depends_on("py-tornado@5.1.0:", type=("build", "run"))
depends_on("py-werkzeug@0.12.2", type=("build", "run"))
# py-werkzeug version requirements differ between setup.py (0.12.2)
# and requirements.txt (0.15.3); the latter seems to be correct,
# see also https://github.com/spack/spack/pull/41426
depends_on("py-werkzeug@0.15.3", type=("build", "run"))
depends_on("py-pytest", type=("build"))
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ class PyMetomiIsodatetime(PythonPackage):

maintainers("LydDeb")

version("3.1.0", sha256="2ec15eb9c323d5debd0678f33af99bc9a91aa0b534ee5f65f3487aed518ebf2d")
version("3.0.0", sha256="2141e8aaa526ea7f7f1cb883e6c8ed83ffdab73269658d84d0624f63a6e1357e")

depends_on("py-setuptools", type="build")

def url_for_version(self, version):
url = "https://files.pythonhosted.org/packages/source/m/metomi-isodatetime/metomi-isodatetime-1!{}.tar.gz"
return url.format(version)
11 changes: 10 additions & 1 deletion var/spack/repos/jcsda-emc-bundles/packages/ewok-env/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class EwokEnv(BundlePackage):

version("1.0.0")

# Variants for workflow engines
variant("ecflow", default=True, description="Use ecflow workflow engine")
variant("cylc", default=False, description="Use cylc workflow engine")

# Variants defining repositories that are not yet publicly available
variant("solo", default=False, description="Build solo (general tools for Python programmers)")
variant(
Expand All @@ -41,7 +45,12 @@ class EwokEnv(BundlePackage):
depends_on("py-ruamel-yaml-clib", type="run")

# Workflow engines
depends_on("ecflow", type="run")
with when("+ecflow"):
depends_on("ecflow", type="run")
with when("+cylc"):
depends_on("py-cylc-flow", type="run")
depends_on("py-cylc-rose", type="run")
depends_on("py-cylc-uiserver", type="run")

# R2D2 mysql backend
depends_on("mysql", type="run")
Expand Down