Skip to content

Commit 200331c

Browse files
committed
fixing test
Signed-off-by: Vanessa Sochat <[email protected]>
1 parent 9f25dd5 commit 200331c

File tree

3 files changed

+56
-28
lines changed

3 files changed

+56
-28
lines changed

singularity/analysis/reproduce/hash.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
def get_image_hashes(image_path, version=None, levels=None):
4141
'''get_image_hashes returns the hash for an image across all levels. This is the quickest,
42-
easiest way to define a container's reproducibility on each level.
42+
easiest way to define a container's reproducibility on each level.
4343
'''
4444
if levels is None:
4545
levels = get_levels(version=version)
@@ -179,13 +179,21 @@ def get_content_hashes(image_path,
179179
return results
180180

181181

182+
def get_image_file_hash(image_path, algorithm='sha256'):
183+
'''return an md5 hash of the file based on a criteria level. This
184+
is intended to give the file a reasonable version.
185+
186+
Parameters
187+
==========
188+
image_path: full path to the singularity image
182189
183-
def get_image_file_hash(image_path):
184-
'''get_image_hash will return an md5 hash of the file based on a criteria level.
185-
:param level: one of LOW, MEDIUM, HIGH
186-
:param image_path: full path to the singularity image
187190
'''
188-
hasher = hashlib.md5()
191+
try:
192+
hasher = getattr(hashlib, algorithm)()
193+
except AttributeError:
194+
bot.error("%s is an invalid algorithm.")
195+
bot.exit(' '.join(hashlib.algorithms_guaranteed))
196+
189197
with open(image_path, "rb") as f:
190198
for chunk in iter(lambda: f.read(4096), b""):
191199
hasher.update(chunk)

singularity/build/main.py

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
)
1818

1919
from spython.main import Client
20+
from spython.utils import stream_command
2021

2122
from singularity.analysis.apps import extract_apps
2223
from singularity.build.utils import (
@@ -103,46 +104,62 @@ def run_build(build_dir, params, verbose=True):
103104
bot.info("%s is a symbolic link." %params['spec_file'])
104105
params['spec_file'] = os.path.realpath(params['spec_file'])
105106

106-
# START TIMING
107-
start_time = datetime.now()
108-
109107
# Secure Build
110108
template = get_build_template_path("secure-build.sh")
111109
if not os.path.exists(template):
112110
bot.exit("Cannot find build template. Exiting.")
113111

114-
result = Client._run_command(["/bin/bash", template, params['spec_file'], "container.sif"])
115-
image = Client.build(recipe=params['spec_file'],
116-
build_folder=build_dir,
117-
isolated=True)
112+
# START TIMING
113+
start_time = datetime.now()
114+
115+
try:
116+
# Stream output
117+
for line in stream_command(["/bin/bash", template, "Singularity", "container.sif"]):
118+
print(line)
119+
except:
120+
bot.exit("Build error. See above for details")
121+
122+
# Ensure that the image exists
123+
image = os.path.join(build_dir, 'container.sif')
124+
if not os.path.exists(image):
125+
bot.exit("Final image does not exist.")
118126

119127
# Save has for metadata (also is image name)
120128
version = get_image_file_hash(image)
121129
params['version'] = version
122-
pickle.dump(params, open(passing_params,'wb'))
130+
pickle.dump(params, open(passing_params, 'wb'))
123131

124132
# Rename image to be hash
125-
finished_image = "%s/%s.simg" %(os.path.dirname(image), version)
133+
finished_image = "%s/%s.sif" %(os.path.dirname(image), version)
126134
image = shutil.move(image, finished_image)
127135

128136
final_time = (datetime.now() - start_time).seconds
129-
bot.info("Final time of build %s seconds." %final_time)
137+
bot.info("Final time of build %s seconds." % final_time)
130138

131139
# Did the container build successfully?
132140
test_result = test_container(image)
133141
if test_result['return_code'] != 0:
134-
bot.error("Image failed to build, cancelling.")
135-
sys.exit(1)
142+
bot.exit("Image failed to build, cancelling.")
136143

137144
# Get singularity version
138145
singularity_version = Client.version()
139146
Client.debug = False
140-
inspect = Client.inspect(image) # this is a string
147+
inspect = Client.inspect(image)
148+
149+
# Fix the incorrect data structure
150+
if "data" not in inspect:
151+
inspect["data"] = {}
152+
153+
if "attributes" in inspect:
154+
inspect["data"]['attributes'] = inspect['attributes']
155+
del inspect['attributes']
156+
141157
Client.debug = params['debug']
142158

143159
# Get information on apps
144160
Client.debug = False
145161
app_names = Client.apps(image)
162+
app_names = [a for a in app_names if "\x1b[0m" not in a]
146163
Client.debug = params['debug']
147164
apps = extract_apps(image, app_names)
148165

@@ -163,7 +180,7 @@ def run_build(build_dir, params, verbose=True):
163180

164181
# Tell the user what is actually there
165182
present_files = glob("*")
166-
bot.error("Build file %s not found in repository" %params['spec_file'])
183+
bot.error("Build file %s not found in repository" % params['spec_file'])
167184
bot.info("Found files are %s" %"\n".join(present_files))
168185
# Params have been exported, will be found by log
169186
sys.exit(1)
@@ -173,10 +190,13 @@ def run_build(build_dir, params, verbose=True):
173190
def send_build_data(build_dir, data, secret,
174191
response_url=None,clean_up=True):
175192
'''finish build sends the build and data (response) to a response url
176-
:param build_dir: the directory of the build
177-
:response_url: where to send the response. If None, won't send
178-
:param data: the data object to send as a post
179-
:param clean_up: If true (default) removes build directory
193+
194+
Parameters
195+
==========
196+
build_dir: the directory of the build
197+
response_url: where to send the response. If None, won't send
198+
the data object to send as a post
199+
clean_up: If true (default) removes build directory
180200
'''
181201
# Send with Authentication header
182202
body = '%s|%s|%s|%s|%s' %(data['container_id'],
@@ -210,9 +230,9 @@ def send_build_data(build_dir, data, secret,
210230
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000,retry_on_result=stop_if_result_none)
211231
def send_build_close(params,response_url):
212232
'''send build close sends a final response (post) to the server to bring down
213-
the instance. The following must be included in params:
233+
the instance. The following must be included in params:
214234
215-
repo_url, logfile, repo_id, secret, log_file, token
235+
repo_url, logfile, repo_id, secret, log_file, token
216236
'''
217237
# Finally, package everything to send back to shub
218238
response = {"log": json.dumps(params['log_file']),

singularity/build/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_container(image_path):
7070
# Build Templates
7171
################################################################################
7272

73-
def get_build_template(template_name,params=None,to_file=None):
73+
def get_build_template(template_name, params=None,to_file=None):
7474
'''get_build template returns a string or file for a particular build template, which is
7575
intended to build a version of a Singularity image on a cloud resource.
7676
@@ -80,7 +80,7 @@ def get_build_template(template_name,params=None,to_file=None):
8080
params: (if needed) a dictionary of parameters to substitute in the file
8181
to_file: if defined, will write to file. Default returns string.
8282
'''
83-
template_file = get_build_template_path(template_name)
83+
template_file = get_build_template_path(template_name) or ""
8484
if os.path.exists(template_file):
8585
bot.debug("Found template %s" %template_file)
8686

0 commit comments

Comments
 (0)