diff --git a/.circleci/config.yml b/.circleci/config.yml index 06bc6ea..1ff1dd0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -37,6 +37,7 @@ test_scompose: &test_scompose pytest -sv scompose/tests/test_depends_on.py pytest -sv scompose/tests/test_client.py pytest -sv scompose/tests/test_utils.py + pytest -sv scompose/tests/test_command_args.py install_dependencies: &install_dependencies name: Install Python dependencies diff --git a/CHANGELOG.md b/CHANGELOG.md index ae17680..4274526 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are: The versions coincide with releases on pypi. ## [0.0.x](https://github.com/singularityhub/singularity-compose/tree/master) (0.0.x) + - command, ability to associate arguments to the instance's startscript (0.0.19) - depends\_on, check circular dependencies at startup and shutdown in reverse order (0.0.18) - resolv.conf, etc.hosts generated if needed, network disabled non-sudo users (0.0.17) - resolv.conf needs to bind by default (0.0.16) diff --git a/docs/spec/spec-1.0.md b/docs/spec/spec-1.0.md index 3e894be..806427a 100644 --- a/docs/spec/spec-1.0.md +++ b/docs/spec/spec-1.0.md @@ -48,6 +48,21 @@ Since Singularity does not (currently) have control over custom networking, all instance ports are mapped to the host (localhost) and we don't have any configuration settings to control this (how to handle ports?) +## Startscript arguments + +It is possible to use the `command` option to pass arguments to an instance's +startscript. + +The following example shows how to pass the arguments `arg0 arg1 arg2` to the +startscript of instance `app`, + +```yaml + app: + build: + context: ./app + command: "arg0 arg1 arg2" +``` + ## Environment While Singularity compose doesn't currently have support for an environment diff --git a/scompose/project/instance.py b/scompose/project/instance.py index 966253e..15eb6fe 100644 --- a/scompose/project/instance.py +++ b/scompose/project/instance.py @@ -41,6 +41,7 @@ def __init__(self, name, working_dir, sudo=False, params=None): self.instance = None self.sudo = sudo self.set_name(name, params) + self.set_args(params) self.set_context(params) self.set_volumes(params) self.set_ports(params) @@ -139,6 +140,10 @@ def set_ports(self, params): # Commands + def set_args(self, params): + """set arguments to the startscript""" + self.args = params.get("command", "") + def _get_network_commands(self, ip_address=None): """take a list of ports, return the list of --network-args to ensure they are bound correctly. @@ -505,9 +510,13 @@ def create(self, ip_address=None, sudo=False, writable_tmpfs=False): options += ["--writable-tmpfs"] # Show the command to the user - commands = "%s %s %s" % (" ".join(options), image, self.name) + commands = "%s %s %s %s" % (" ".join(options), image, self.name, self.args,) bot.debug("singularity instance start %s" % commands) self.instance = self.client.instance( - name=self.name, sudo=self.sudo, options=options, image=image + name=self.name, + sudo=self.sudo, + options=options, + image=image, + args=self.args, ) diff --git a/scompose/tests/configs/cmd_args/Singularity b/scompose/tests/configs/cmd_args/Singularity new file mode 100644 index 0000000..6a7038f --- /dev/null +++ b/scompose/tests/configs/cmd_args/Singularity @@ -0,0 +1,5 @@ +Bootstrap: docker +From: busybox + +%startscript +echo "Following arguments: $@" diff --git a/scompose/tests/configs/cmd_args/singularity-compose.yml b/scompose/tests/configs/cmd_args/singularity-compose.yml new file mode 100644 index 0000000..5f730cc --- /dev/null +++ b/scompose/tests/configs/cmd_args/singularity-compose.yml @@ -0,0 +1,7 @@ +version: "1.0" +instances: + echo: + build: + context: . + recipe: Singularity + command: "arg0 arg1 arg2" diff --git a/scompose/tests/test_command_args.py b/scompose/tests/test_command_args.py new file mode 100644 index 0000000..d554795 --- /dev/null +++ b/scompose/tests/test_command_args.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +# Copyright (C) 2019-2020 Vanessa Sochat. + +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed +# with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from scompose.logger import bot +from scompose.project import Project +from scompose.utils import run_command +from time import sleep +import shutil +import pytest +import os + +here = os.path.dirname(os.path.abspath(__file__)) + + +def test_command_args(tmp_path): + bot.clear() ## Clear previously logged messages + + cmd_args = os.path.join(here, "configs", "cmd_args") + for filename in os.listdir(cmd_args): + source = os.path.join(cmd_args, filename) + dest = os.path.join(tmp_path, filename) + print("Copying %s to %s" % (filename, dest)) + shutil.copyfile(source, dest) + + # Test the simple apache example + os.chdir(tmp_path) + + # Check for required files + assert "singularity-compose.yml" in os.listdir() + + print("Creating project...") + + # Loading project validates config + project = Project() + + print("Testing build") + project.build() + + assert "echo.sif" in os.listdir(tmp_path) + + print("Testing view config") + project.view_config() + + print("Testing up") + project.up() + + print("Waiting for instances to start") + sleep(10) + + print("Bringing down") + project.down() + + log = bot.get_logs() + assert "echo arg0 arg1 arg2" in log diff --git a/scompose/version.py b/scompose/version.py index e5dfa28..3f4a744 100644 --- a/scompose/version.py +++ b/scompose/version.py @@ -8,7 +8,7 @@ """ -__version__ = "0.0.18" +__version__ = "0.0.19" AUTHOR = "Vanessa Sochat" AUTHOR_EMAIL = "vsochat@stanford.edu" NAME = "singularity-compose"