-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Matthew Giarra
committed
Jun 10, 2021
1 parent
dbdee6d
commit 46bc853
Showing
3 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.DS_Store | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# docker2singularity | ||
This script exports a [Docker](https://www.docker.com/) image as a [Singularity](https://sylabs.io/singularity/) `.sif` file. This can be useful for porting Dockerized code to run on shared user systems like clusters, which sometimes run Singularity rather than Docker. | ||
|
||
# Prerequisites | ||
- Install Docker (tested with `20.10.6`) | ||
|
||
# Usage | ||
1. Build or pull the Docker image you wish to export to a Singularity `.sif` file | ||
|
||
```bash | ||
docker pull ubuntu:latest | ||
``` | ||
|
||
2. Run `docker2sif.sh` to export the image as a `.sif` file | ||
|
||
```bash | ||
cd docker2singularity | ||
./docker2singularity.sh ubuntu | ||
``` | ||
|
||
This should write a file called `ubuntu.sif` in the current working directory, e.g., `docker2singularity/ubuntu.sif` | ||
|
||
Optionally, you can specify where to save the output `.sif` file: | ||
|
||
```bash | ||
./docker2singularity.sh ubuntu $HOME/ubuntu_singularity.sif | ||
``` | ||
#### Expected Output | ||
If it worked, you'll see output similiar to the following: | ||
|
||
```bash | ||
Exporting docker image ubuntu --> /Users/giarrmn1/ubuntu_singularity.sif | ||
|
||
Image Format: squashfs | ||
Docker Image: ubuntu | ||
Container Name: ubuntu_singularity.sif | ||
|
||
Inspected Size: 73 MB | ||
|
||
(1/10) Creating a build sandbox... | ||
(2/10) Exporting filesystem... | ||
(3/10) Creating labels... | ||
(4/10) Adding run script... | ||
(5/10) Setting ENV variables... | ||
(6/10) Adding mount points... | ||
(7/10) Fixing permissions... | ||
(8/10) Stopping and removing the container... | ||
(9/10) Building squashfs container... | ||
INFO: Starting build... | ||
INFO: Creating SIF file... | ||
INFO: Build complete: /tmp/ubuntu_singularity.sif | ||
(10/10) Moving the image to the output folder... | ||
27,717,632 100% 80.25MB/s 0:00:00 (xfr#1, to-chk=0/1) | ||
Final Size: 27MB | ||
Exported Docker image ubuntu --> /Users/giarrmn1/ubuntu_singularity.sif | ||
|
||
``` | ||
|
||
#### Help | ||
Run `./docker2singularity -h` to print the help screen, including usage. | ||
|
||
# Caveats | ||
- The docker image you wish to export must be available locally, i.e., you need to have built the image before you can export it to `.sif`. There's no reason we couldn't go straight from `Dockerfile` to `.sif` by including the option to `docker build` in the script, but we haven't implemented that yet. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
#!/bin/bash | ||
# Export Docker image as Singularity .sif file | ||
# Maintainer: Matthew N. Giarra <[email protected]> | ||
# First commit 2021-06-10 | ||
|
||
# Colors for printing | ||
DIR='\033[95m' | ||
OKBLUE='\033[94m' | ||
OKCYAN='\033[96m' | ||
OKGREEN='\033[92m' | ||
ENDC='\033[0m' | ||
BOLD='\033[1m' | ||
UNDERLINE='\033[4m' | ||
WARNING='\033[93m' | ||
FAIL='\033[91m' | ||
|
||
# Color to print on success | ||
SUCCESS=$OKCYAN | ||
|
||
# Function to display help | ||
display_help(){ | ||
echo -e "$SUCCESS $(basename $0): export docker image as a singularity .sif image file" | ||
echo " Usage: $(basename $0) <docker_image_name>" | ||
echo " Usage: $(basename $0) <docker_image_name> <sif_path_out>" | ||
echo " Example: " | ||
echo " docker pull ubuntu:latest" | ||
echo " ./$(basename $0) ubuntu ubuntu.sif" | ||
echo " Note: run \"docker image ls\" to print available docker images" | ||
echo -e "$ENDC" | ||
exit | ||
} | ||
|
||
# Display help if no inputs are supplied | ||
if [ $# -eq 0 ]; then | ||
display_help | ||
fi | ||
|
||
# Display help if -h or --h is supplied as the only input | ||
while true; do | ||
case "$1" in | ||
-h | --help) | ||
display_help;; | ||
*) | ||
break;; | ||
esac | ||
done | ||
|
||
# Tag of the docker image to export as Singularity .sif file | ||
IMAGE_NAME_IN="$1" | ||
|
||
# Make sure the image exists so that we can print an informative message if it doesn't | ||
MATCHING_IMAGES=$(docker images -q $IMAGE_NAME_IN) | ||
if [ -z $MATCHING_IMAGES ]; then | ||
echo -e "$FAIL Error: $IMAGE_NAME_IN does not appear to be a locally-available docker image" | ||
echo -e "Available docker image tags:" | ||
echo -e "$(docker images | tail -n +2 | awk '{print $1}')" | ||
echo -e " Hint: run \"docker image ls\" to print available docker images $ENDC" | ||
exit | ||
fi | ||
|
||
if [ $# -ge 2 ]; then | ||
# User-specified output path for .sif file | ||
IMAGE_PATH_OUT="$2" | ||
else | ||
# Default to .sif file with same name as docker tag | ||
IMAGE_PATH_OUT="$IMAGE_NAME_IN.sif" | ||
fi | ||
|
||
# Path to the output directory | ||
OUT_DIR=$(dirname "$IMAGE_PATH_OUT") | ||
|
||
# Make the output directory if it doesn't exist | ||
if [ ! -d "$OUT_DIR" ]; then | ||
mkdir -p "$OUT_DIR" | ||
if [ -d "$OUT_DIR" ]; then | ||
echo -e "$SUCCESS Created directory $DIR$OUT_DIR $ENDC" | ||
else | ||
echo -e "$FAIL Error: could not create directory $DIR$OUT_DIR $ENDC" | ||
exit | ||
fi | ||
fi | ||
|
||
# Absolute path to output directory | ||
OUT_DIR_ABS=$(cd "$OUT_DIR"; pwd) | ||
|
||
# Name of the output image | ||
IMAGE_NAME_OUT=$(basename "$IMAGE_PATH_OUT") | ||
|
||
# Absolute path to the output file | ||
IMAGE_PATH_OUT_ABS="$OUT_DIR_ABS/$IMAGE_NAME_OUT" | ||
|
||
# If the output file exists, ask if we want to overwrite it | ||
if [ -f "$IMAGE_PATH_OUT_ABS" ]; then | ||
while true; do | ||
echo -e "$DIR$IMAGE_PATH_OUT_ABS$WARNING exists. Overwrite [y/N]? $ENDC" | ||
read -p "" yn | ||
case $yn in | ||
[Yy]* ) break;; | ||
[Nn]* ) exit;; | ||
* ) exit;; | ||
esac | ||
done | ||
fi | ||
|
||
# Backup sif file if it already exists | ||
if [ -f "$IMAGE_PATH_OUT_ABS" ]; then | ||
IMAGE_PATH_ABS_BACKUP="$IMAGE_PATH_OUT_ABS.backup" | ||
mv "$IMAGE_PATH_OUT_ABS" "$IMAGE_PATH_ABS_BACKUP" | ||
|
||
if [ -f "$IMAGE_PATH_ABS_BACKUP" ]; then | ||
echo -e "$SUCCESS Backed up $DIR$IMAGE_PATH_OUT_ABS $SUCCESS-->$DIR $IMAGE_PATH_ABS_BACKUP $ENDC" | ||
fi | ||
fi | ||
|
||
# Inform the user that we're about to execute the export | ||
echo -e "$SUCCESS Exporting docker image $DIR$IMAGE_NAME_IN $SUCCESS--> $DIR$IMAGE_PATH_OUT_ABS $ENDC" | ||
|
||
# Export the docker image to a Singularity .sif file | ||
docker run -v /var/run/docker.sock:/var/run/docker.sock -v "$OUT_DIR_ABS":/output -it --rm quay.io/singularity/docker2singularity --name $IMAGE_NAME_OUT $IMAGE_NAME_IN | ||
|
||
# Check that the sif file actually got saved | ||
if [ -f "$IMAGE_PATH_OUT_ABS" ]; then | ||
echo -e "$SUCCESS Exported Docker image $IMAGE_NAME_IN --> $DIR$IMAGE_PATH_OUT_ABS $ENDC" | ||
|
||
# Remove the backup image | ||
if [ -f "$IMAGE_PATH_ABS_BACKUP" ]; then | ||
rm "$IMAGE_PATH_ABS_BACKUP" | ||
fi | ||
|
||
else | ||
# Replace the image with the backup image | ||
if [ -f "$IMAGE_PATH_ABS_BACKUP" ]; then | ||
echo -e "$WARNING Canceled exporting $DIR$IMAGE_NAME_IN $WARNING--> $DIR$IMAGE_PATH_OUT_ABS$ENDC" | ||
mv "$IMAGE_PATH_ABS_BACKUP" "$IMAGE_PATH_OUT_ABS" | ||
else | ||
echo -e "$FAIL Warning: $DIR$IMAGE_PATH_OUT_ABS$FAIL not found; exporting docker image $IMAGE_NAME_IN --> $DIR$IMAGE_PATH_OUT_ABS$FAIL appears to have failed. $ENDC" | ||
fi | ||
fi |