Skip to content

Commit a80bd1e

Browse files
committed
updating builder to store compressed image on cloud
1 parent 6e02e3c commit a80bd1e

File tree

4 files changed

+79
-12
lines changed

4 files changed

+79
-12
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
name="singularity",
88

99
# Version number:
10-
version="0.30",
10+
version="0.32",
1111

1212
# Application author details:
1313
author="Vanessa Sochat",

singularity/build.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from oauth2client import client
2525
from oauth2client.service_account import ServiceAccountCredentials
2626

27+
import io
2728
import os
2829
import re
2930
import requests
@@ -38,6 +39,8 @@
3839

3940
# Log everything to stdout
4041
logging.basicConfig(stream=sys.stdout,level=logging.DEBUG)
42+
# if we want logging to variable or other, TBD
43+
#from singularity.logman import bot
4144

4245
##########################################################################################
4346
# GOOGLE STORAGE API #####################################################################
@@ -170,15 +173,19 @@ def run_build(build_dir=None,spec_file=None,repo_url=None,token=None,size=None,b
170173
output_folder=build_dir,
171174
build_dir=build_dir)
172175

173-
# Package the image
176+
# Compress image
177+
compressed_image = "%s.tar.gz" %image
178+
os.system('sudo singularity export %s | gzip -9 > %s' %(image,compressed_image))
179+
180+
# Package the image metadata (files, folders, etc)
174181
image_package = package(image_path=image,
175182
spec_path=spec_file,
176183
output_folder=build_dir,
177184
sudopw='',
178185
remove_image=True,
179186
verbose=True)
180187

181-
# Upload image to Google Storage
188+
# Upload image package files to Google Storage
182189
if os.path.exists(image_package):
183190
logging.info("Package %s successfully built",image_package)
184191
dest_dir = "%s/build" %(build_dir)
@@ -189,14 +196,14 @@ def run_build(build_dir=None,spec_file=None,repo_url=None,token=None,size=None,b
189196
# The path to the images on google drive will be the github url/commit folder
190197
image_path = "%s/%s" %(re.sub('^http.+//www[.]','',params['repo_url']),params['commit'])
191198
build_files = glob("%s/*" %(dest_dir))
199+
build_files.append(compressed_image)
192200
logging.info("Sending build files %s to storage",'\n'.join(build_files))
193201

194202
# Start the storage service, retrieve the bucket
195203
storage_service = get_storage_service()
196204
bucket = get_bucket(storage_service,bucket_name)
197205

198206
# For each file, upload to storage
199-
# TODO: here we need to skip image / layerize
200207
files = []
201208
for build_file in build_files:
202209
storage_file = upload_file(storage_service,
@@ -205,7 +212,6 @@ def run_build(build_dir=None,spec_file=None,repo_url=None,token=None,size=None,b
205212
file_name=build_file)
206213
files.append(storage_file)
207214

208-
209215
# Upload the package as well
210216
package_file = upload_file(storage_service,
211217
bucket=bucket,

singularity/logman.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import io
2+
import os
3+
import logging
4+
5+
class Logman:
6+
7+
def __init__(self,MESSAGELEVEL=None):
8+
self.level = get_logging_level(MESSAGELEVEL)
9+
logging.basicConfig(level=self.level)
10+
self.logger = logging.getLogger('shub_builder')
11+
self.formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
12+
self.capture = io.StringIO()
13+
14+
def start(self):
15+
self.ch = logging.StreamHandler(self.capture)
16+
self.ch.setLevel(self.level)
17+
self.ch.setFormatter(self.formatter)
18+
self.logger.addHandler(self.ch)
19+
20+
def stop(self):
21+
### Pull the contents back into a string and close the stream
22+
self.contents = self.capture.getvalue()
23+
self.capture.close()
24+
return self.contents
25+
26+
27+
def get_logging_level(MESSAGELEVEL=None):
28+
'''get_logging_level will return a logging level based on first
29+
a variable going into the function, then an environment variable
30+
MESSAGELEVEL, and then the default is DEBUG.
31+
:param MESSAGELEVEL: the level to get.
32+
'''
33+
if MESSAGELEVEL == None:
34+
MESSAGELEVEL = os.environ.get("MESSAGELEVEL","DEBUG")
35+
36+
print("Environment message level found to be %s" %MESSAGELEVEL)
37+
38+
if MESSAGELEVEL == "FATAL":
39+
return logging.FATAL
40+
41+
elif MESSAGELEVEL == "CRITICAL":
42+
return logging.CRITICAL
43+
44+
elif MESSAGELEVEL == "ERROR":
45+
return logging.ERROR
46+
47+
elif MESSAGELEVEL == "WARNING":
48+
return logging.WARNING
49+
50+
elif MESSAGELEVEL == "INFO":
51+
return logging.INFO
52+
53+
elif MESSAGELEVEL in "DEBUG":
54+
return logging.DEBUG
55+
56+
return logging.DEBUG
57+
58+
bot = Logman()
59+
bot.start()

singularity/package.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ def build_from_spec(spec=None,build_dir=None,size=None,sudopw=None,
4848
cli.create(image_path,size=size)
4949
result = cli.bootstrap(image_path=image_path,spec_path=spec_path)
5050
print(result)
51-
# Rename the image
52-
version = get_image_hash(image_path)
53-
final_path = "%s/%s" %(build_dir,version)
54-
os.rename(image_path,final_path)
55-
return final_path
51+
# If image, rename based on hash
52+
if build_folder == False:
53+
version = get_image_hash(image_path)
54+
final_path = "%s/%s" %(build_dir,version)
55+
os.rename(image_path,final_path)
56+
image_path = final_path
57+
return image_path
5658

5759

5860
def package(image_path,spec_path=None,output_folder=None,runscript=True,
@@ -118,7 +120,8 @@ def list_package(package_path):
118120
'''
119121
zf = zipfile.ZipFile(package_path, 'r')
120122
return zf.namelist()
121-
123+
124+
122125

123126
def calculate_similarity(pkg1,pkg2,include_files=False,include_folders=True):
124127
'''calculate_similarity will calculate similarity of images in packages based on
@@ -279,7 +282,6 @@ def get_image_hash(image_path):
279282
if the image matches the spec file
280283
:param image_path: full path to the singularity image
281284
'''
282-
print("Generating unique version of image (md5 hash)")
283285
hash_md5 = hashlib.md5()
284286
with open(image_path, "rb") as f:
285287
for chunk in iter(lambda: f.read(4096), b""):

0 commit comments

Comments
 (0)