Skip to content

Commit

Permalink
Add function to create volumes for mounting on login
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbarton committed Oct 2, 2015
1 parent a0a68c6 commit 0f88b83
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tmp
.images
images/test-install/requirements.txt
biobox_verify
.biobox_tmp

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
17 changes: 16 additions & 1 deletion biobox_cli/assets/login_parameters.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
---
short_read_assembler: "params"
short_read_assembler:
- /bbx/output:
- /bbx/input:
- type: path
src: genome_paired_reads.fq.gz
dst: reads.fq.gz
- type: literal
dst: biobox.yaml
src: |
version: 0.9.0
arguments:
- fastq:
- value: /bbx/input/reads.fq.gz
type: paired
id: 0
27 changes: 18 additions & 9 deletions biobox_cli/command/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@
"""

import yaml
import os.path
import shutil

import biobox_cli.util.misc as util
import biobox_cli.util.assets as asset
import biobox_cli.util.error as error
import biobox_cli.container as docker

TEMPORARY_DIRECTORY = '.biobox_tmp'


def get_login_parameters(biobox_type):
"""
Determines if the biobox type is currently supported for login. Returns
Expand All @@ -33,18 +38,22 @@ def get_login_parameters(biobox_type):


def create_login_file(dir_, params):
from os.path import join
from shutil import copyfile

is_literal = params['type'] == 'literal'
dst = join(dir_, params['dst'])
dst = os.path.join(dir_, params['dst'])

if is_literal:
with open(dst, 'w') as f:
f.write(params['src'])
else:
src = asset.get_data_file_path(params['src'])
copyfile(src, dst)
shutil.copyfile(src, dst)


def create_login_volume((dir_name, files)):
src = util.mkdir_p(os.path.join(TEMPORARY_DIRECTORY, dir_name.strip("/")))
for f in files:
create_login_file(src, f)
return docker.mount_string(src, dir_name, False)


def run(argv):
Expand All @@ -55,14 +64,14 @@ def run(argv):
tty = not "--no-tty" in opts["<args>"]
remove = not "--no-rm" in opts["<args>"]

docker.exit_if_no_image_available(image)

params = get_login_parameters(biobox_type)
if params is None:
error.err_exit("unknown_command",
{"command_type" : "biobox type", "command" : biobox_type})

docker.exit_if_no_image_available(image)

ctnr = docker.create_tty(image, tty)
volumes = map(create_login_volume, params)
ctnr = docker.create_tty(image, tty, volumes)
docker.login(ctnr)

if remove:
Expand Down
3 changes: 3 additions & 0 deletions biobox_cli/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def mount_string(host_dir, container_dir, read_only = True):
def output_directory_mount_string(directory):
return mount_string(directory, "/bbx/output", False)

def input_directory_mount_string(directory):
return mount_string(directory, "/bbx/input", True)

def biobox_file_mount_string(directory):
return mount_string(directory, "/bbx/input")

Expand Down
12 changes: 12 additions & 0 deletions biobox_cli/util/misc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys
import os.path
import biobox_cli.util.error as error

def select_module(module, name):
Expand All @@ -20,3 +21,14 @@ def parse_docopt(doc, argv, is_main_module):
argv = argv,
version = __version__,
options_first = is_main_module)

# http://stackoverflow.com/a/600612
def mkdir_p(path):
import os, errno
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else: raise
return os.path.abspath(path)
1 change: 1 addition & 0 deletions features/login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ Feature: Allow a user to ssh into an image to test internally
input:
biobox.yaml reads.fq.gz
"""
And the directory ".biobox_tmp" should not exist
12 changes: 11 additions & 1 deletion test/helper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import os, os.path
import nose.tools as nose
import biobox_cli.container as ctn

def project_root():
Expand All @@ -10,3 +11,12 @@ def is_ci_server():
def remove_container(container):
if not is_ci_server():
ctn.remove(container)

def assert_file_not_empty(file_):
file_size = os.stat(file_).st_size
nose.assert_not_equal(file_size, 0,
"File should not be empty but is: {}".format(file_))

def assert_file_contents_equal(file_, contents):
with open(file_, 'r') as f:
nose.assert_equal(f.read(), contents)
46 changes: 32 additions & 14 deletions test/test_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,42 @@
import helper as hlpr
import tempfile as tmp

from os.path import join
from os import stat
import os.path
import shutil

def test_get_login_parameters_with_unknown_type():
nose.assert_equal(None, login.get_login_parameters('unknown'))


TMP_DIR = tmp.mkdtemp()
TMP_FILE_NAME = 'tmp_file'
TMP_PATH = os.path.join(TMP_DIR, TMP_FILE_NAME)

def rm_tmp_file():
if os.path.exists(TMP_PATH):
os.remove(TMP_PATH)

def rm_tmp_login_dir():
shutil.rmtree(login.TEMPORARY_DIRECTORY)

@nose.with_setup(teardown = rm_tmp_file)
def test_create_login_file_literal():
file_name = 'file_name'
value = {'type': 'literal', 'src': 'literal_string', 'dst': file_name}
directory = tmp.mkdtemp()
login.create_login_file(directory, value)
with open(join(directory, file_name)) as f:
nose.assert_equal('literal_string', f.read())
value = {'type': 'literal', 'src': 'literal_string', 'dst': TMP_FILE_NAME}
login.create_login_file(TMP_DIR, value)
hlpr.assert_file_contents_equal(TMP_PATH, 'literal_string')

@nose.with_setup(teardown = rm_tmp_file)
def test_create_login_file_path():
file_name = 'file_name'
value = {'type': 'path', 'src': 'genome_paired_reads.fq.gz', 'dst': file_name}
directory = tmp.mkdtemp()
login.create_login_file(directory, value)
file_size = stat(join(directory, file_name)).st_size
nose.assert_not_equal(file_size, 0)
value = {'type': 'path', 'src': 'genome_paired_reads.fq.gz', 'dst': TMP_FILE_NAME}
login.create_login_file(TMP_DIR, value)
hlpr.assert_file_not_empty(TMP_PATH)

@nose.with_setup(teardown = rm_tmp_login_dir)
def test_create_login_volume():
dst_dir = '/bbx/input'
value = [dst_dir, [{'type': 'literal', 'src': 'literal_string', 'dst': TMP_FILE_NAME}]]
volume = login.create_login_volume(value)
dir_path = os.path.join(login.TEMPORARY_DIRECTORY, dst_dir.strip("/"))
hlpr.assert_file_not_empty(os.path.join(dir_path, TMP_FILE_NAME))
hlpr.assert_file_contents_equal(os.path.join(dir_path, TMP_FILE_NAME), 'literal_string')
nose.assert_in(':'.join([dir_path, dst_dir, 'rw']), volume)

0 comments on commit 0f88b83

Please sign in to comment.