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

Updated for new installation scheme #30

Merged
merged 3 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
9 changes: 9 additions & 0 deletions .github/workflows/Release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@ jobs:
with:
src : packmol_step
secrets: inherit

docker:
name: Docker
needs: release
uses: molssi-seamm/devops/.github/workflows/Docker.yaml@main
with:
image : molssi-seamm/seamm-packmol
description: A Packmol executable packaged for use with SEAMM or standalone
secrets: inherit
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
=======
History
=======
2024.3.19 -- Updated installer for new scheme
* packmol-step-installer now uses the new scheme, which supports both Conda and
Docker installation.
* Added seamm-packmol Docker image

2024.1.16 -- Adding support for containers
* Added the ability to work in Docker containers.

Expand Down
8 changes: 8 additions & 0 deletions devtools/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM molssi/mamba141

COPY ./environment.yml /root/environment.yml

RUN mamba env update -f /root/environment.yml

WORKDIR /home
ENTRYPOINT ["packmol"]
8 changes: 8 additions & 0 deletions devtools/docker/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: base
channels:
- conda-forge
dependencies:
- python
# Executables, etc.
- packmol==20.2.2

17 changes: 2 additions & 15 deletions packmol_step/data/configuration.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
[packmol-step]
# Information about where/how the executables are installed
# installation may be 'user', 'conda' or 'module'. If a module is
# specified it will be loaded and those executables used. In this
# case, any path specified using -path will be ignored.

installation =
conda-environment =
modules =
# The level of logging for the Packmol Step

# The path to the executable. Can be empty or not present, in which
# case the default PATH is used. If a path is given, packmol
# from this location will be used.
#
# Ignored if a module is used. The default is to use the PATH
# environment variable.

packmol-path =
# log-level WARNING

71 changes: 71 additions & 0 deletions packmol_step/data/packmol.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Configuration options for how to run Packmol

[docker]
# The code to use. This may maybe more than just the name of the code, and variables in
# braces {} will be expanded. For example:
# code = mpiexec -np {NTASKS} lmp_mpi
# would expand {NTASKS} to the number of tasks and run the command

code = packmol

# The name and location of the Docker container to use, optionally with the version

container = ghcr.io/molssi-seamm/seamm-packmol:{version}

# In addition, you can specify the platform to use. This is useful on e.g. Macs with
# app silicon (M1, M3...) where the default platform is linux/arm64 but some containers
# are only available for linux/amd64.

# platform = linux/amd64

[local]
# The type of local installation to use. Options are:
# conda: Use a conda environment
# modules: Use the modules system
# local: Use a local installation
# docker: Use a Docker container
# By default SEAMM installs Packmol using conda.

installation = conda

# The command line to use, which should start with the executable followed by any options.
# Variables in braces {} will be expanded. For example:
#
# code = mpiexec -np {NTASKS} lmp_mpi
#
# would expand {NTASKS} to the number of tasks and run the command.
# For a 'local' installation, the command line should include the full path to the
# executable or it should be in the path.

code = packmol

######################### conda section ############################
# The full path to the conda executable:

# conda =

# The Conda environment to use. This is either the name or full path.

# conda-environment = seamm-packmol

######################### modules section ############################
# The modules to load to run Packmol, as a list of strings.
# For example, to load the modules packmol and openmpi, you would use:
# modules = packmol openmpi

# modules =

######################### local section ############################
# The full path to the Packmol executable should be in the 'code' option.

######################### docker section ############################
# The name and location of the Docker container to use, optionally with the version.
# {version} will be expanded to the version of the plug-in.

# container = ghcr.io/molssi-seamm/seamm-packmol:{version}

# In addition, you can specify the platform to use. This is useful on e.g. Macs with
# app silicon (M1, M3...) where the default platform is linux/arm64 but some containers
# are only available for linux/amd64.

# platform = linux/amd64
167 changes: 155 additions & 12 deletions packmol_step/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,40 +54,183 @@ def __init__(self, logger=logger):
logger.debug("Initializing the PACKMOL installer object.")

self.section = "packmol-step"
self.path_name = "packmol-path"
self.executables = ["packmol"]
self.resource_path = Path(pkg_resources.resource_filename(__name__, "data/"))

# The environment.yaml file for Conda installations.
logger.debug(f"data directory: {self.resource_path}")
self.environment_file = self.resource_path / "seamm-packmol.yml"

def check(self):
"""Check the status of the Packmol installation."""
print("Checking the Packmol installation.")

# What Conda environment is the default?
data = self.configuration.get_values(self.section)
path = self.configuration.path.parent / "packmol.ini"
if not path.exists():
text = (self.resource_path / "packmol.ini").read_text()
path.write_text(text)
print(f" The packmol.ini file did not exist. Created {path}")

self.exe_config.path = path

# Get the current values
data = self.exe_config.get_values("local")

if "conda-environment" in data and data["conda-environment"] != "":
self.environment = data["conda-environment"]
else:
self.environment = "seamm-packmol"

# The environment.yaml file for Conda installations.
path = Path(pkg_resources.resource_filename(__name__, "data/"))
logger.debug(f"data directory: {path}")
self.environment_file = path / "seamm-packmol.yml"
super().check()

def install(self):
"""Install Packmol in a conda environment."""
print("Installing Packmol.")

# What Conda environment is the default?
path = self.configuration.path.parent / "packmol.ini"
if not path.exists():
text = (self.resource_path / "packmol.ini").read_text()
path.write_text(text)
print(f" The packmol.ini file did not exist. Created {path}")

self.exe_config.path = path

# Get the current values
data = self.exe_config.get_values("local")

if "conda-environment" in data and data["conda-environment"] != "":
self.environment = data["conda-environment"]
else:
self.environment = "seamm-packmol"

super().install()

def show(self):
"""Show the status of the Packmol installation."""
print("Showing the Packmol installation.")

# What Conda environment is the default?
path = self.configuration.path.parent / "packmol.ini"
if not path.exists():
text = (self.resource_path / "packmol.ini").read_text()
path.write_text(text)
print(f" The packmol.ini file does not exist at {path}")
print(" The 'check' command will create it if Packmol is installed.")
print(" Otherwise 'install' will install Packmol.")
return

self.exe_config.path = path

if not self.exe_config.section_exists("local"):
print(
" Packmol is not configured: there is no 'local' section in "
f" {path}."
)
return

# Get the current values
data = self.exe_config.get_values("local")

if "conda-environment" in data and data["conda-environment"] != "":
self.environment = data["conda-environment"]
else:
self.environment = "seamm-packmol"

def exe_version(self, path):
super().show()

def uninstall(self):
"""Uninstall the Packmol installation."""
print("Uninstall the Packmol installation.")

# What Conda environment is the default?
path = self.configuration.path.parent / "packmol.ini"
if not path.exists():
text = (self.resource_path / "packmol.ini").read_text()
path.write_text(text)
print(
f"""" The packmol.ini file does not exist at {path}
Perhaps Packmol is not installed, but if it is the 'check' command may locate it
and create the ini file, after which 'uninstall' will remove it."""
)
return

self.exe_config.path = path

if not self.exe_config.section_exists("local"):
print(
f"""" The packmol.ini file at {path} does not have local section.
Perhaps Packmol is not installed, but if it is the 'check' command may locate it
and update the ini file, after which 'uninstall' will remove it."""
)
return

# Get the current values
data = self.exe_config.get_values("local")

if "conda-environment" in data and data["conda-environment"] != "":
self.environment = data["conda-environment"]
else:
self.environment = "seamm-packmol"

super().uninstall()

def update(self):
"""Updates the Packmol installation."""
print("Updating the Packmol installation.")

# What Conda environment is the default?
path = self.configuration.path.parent / "packmol.ini"
if not path.exists():
text = (self.resource_path / "packmol.ini").read_text()
path.write_text(text)
print(f" The packmol.ini file did not exist. Created {path}")

self.exe_config.path = path

# Get the current values
data = self.exe_config.get_values("local")

if "conda-environment" in data and data["conda-environment"] != "":
self.environment = data["conda-environment"]
else:
self.environment = "seamm-packmol"

super().update()

def exe_version(self, config):
"""Get the version of the PACKMOL executable.

Parameters
----------
path : pathlib.Path
Path to the executable.
config : dict
Dictionary of options for running Packmol

Returns
-------
str
"Packmol", str
The version reported by the executable, or 'unknown'.
"""
environment = config["conda-environment"]
conda = config["conda"]
if environment[0] == "~":
environment = str(Path(environment).expanduser())
command = f"'{conda}' run --live-stream -p '{environment}'"
elif Path(environment).is_absolute():
command = f"'{conda}' run --live-stream -p '{environment}'"
else:
command = f"'{conda}' run --live-stream -n '{environment}'"
command += " packmol -log none"

logger.debug(f" Running {command}")
try:
result = subprocess.run(
[str(path), "-log", "none"],
command,
stdin=subprocess.DEVNULL,
capture_output=True,
text=True,
shell=True,
)
except Exception:
version = "unknown"
Expand All @@ -103,4 +246,4 @@ def exe_version(self, path):
version = value
break

return version
return "Packmol", version
Loading
Loading