Example API Interaction
For this example, I've taken an (already built) container on Singularity Hub, meaning we have a binary in Google Storage, and I'm exploring a proof of concept of providing its metadata statically here. Here is a direct link to download a container.
While the md5 is not registered and thus a valid type, I'm using it just for this example. The hash of the container is a1025471b564766d08bdf2cb062c795c
.
For demonstration I'll present this in Python. First, we get the image manifest.
import requests
registry = "https://singularityhub.github.io/container-storage"
namespace = "vanessa/greeting"
tag = "latest"
manifest_url = "%s/%s/manifests/%s" %(registry, namespace, tag)
manifest = requests.get(manifest_url).json()
print(json.dumps(manifest, indent=4))
{
"schemaVersion": 2,
"mediaType": "application/vnd.singularity.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.singularity.container.image.v1+json",
"size": 5539,
"digest": "sha256:8c7ad11d488a8dd933239b9543a81dbe226416e96dc2f441d3bd038d664c1c92"
},
"layers": [
{
"mediaType": "application/vnd.singularity.image.squashfs",
"size": 2065537,
"digest": "md5:a1025471b564766d08bdf2cb062c795c",
"urls": [
"https://storage.googleapis.com/singularityhub/singularityhub/github.com/vsoch/singularity-images/130504089d5b2b44e2788992d0de75b625da6796/a1025471b564766d08bdf2cb062c795c/a1025471b564766d08bdf2cb062c795c.simg"
]
}
]
}
This ignores the config and content type for now, and just downloads the image url. I would want to assume that the client knows that given a singularity squashfs, the correct thing to do is download the single binary. Let's write a function to stream it to the filesystem:
def stream_file(url, download_to):
response = requests.get(url, stream=True)
with open(download_to, 'wb') as filey:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
filey.write(chunk)
return download_to
layers = manifest['layers']
# {'digest': 'md5:a1025471b564766d08bdf2cb062c795c',
# 'mediaType': 'application/vnd.singularity.image.squashfs',
# 'size': 2065537,
# 'urls': ['https://storage.googleapis.com/singularityhub/singularityhub/github.com/vsoch/singularity-images/130504089d5b2b44e2788992d0de75b625da6796/a1025471b564766d08bdf2cb062c795c/a1025471b564766d08bdf2cb062c795c.simg']}
for layer in layers:
url = layer['urls'][0]
download_to = stream_file(url, 'mycontainer.simg')
Does it work?
$ singularity run mycontainer.simg
You say please, but all I see is pizza..
Yep!
Here is the md5sum:
$ md5sum mycontainer.simg
a1025471b564766d08bdf2cb062c795c mycontainer.simg
There are a couple of things to discuss here:
- The content type for Singularity I don't think exists. Can it exist and require a single binary (via a url) and then just be validated using a digest?
- What goes in the config section then?
- The storage needs to have an organizational standard. Given being stored in a Github repository, to me the logical answer is:
<github.com>/<username>/<reponame>/<commit>/<hash>/ [container]
Have a question? Ask away!