Skip to content

Commit

Permalink
Merge pull request #30 from paulsaxe/main
Browse files Browse the repository at this point in the history
Updated for new installation scheme
  • Loading branch information
seamm authored Mar 19, 2024
2 parents 9b6a2b2 + 6f77cf5 commit 2ac9731
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 46 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ on:
pull_request:
branches:
- "main"
schedule:
# Run on master by default Sunday morning at 3:30:
# Scheduled workflows run on the latest commit on the default or base branch.
# (from https://help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule)
- cron: "30 3 * * 0"

jobs:
ci:
Expand Down
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

0 comments on commit 2ac9731

Please sign in to comment.