Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add image version option #180

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion .mk/docker.mk
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@

.PHONY: docker-setup

## Setup environment variables required for docker-compose
## Setup environment variables required for docker-compose if needed
docker-setup:
@scripts/docker-setup.sh

.PHONY: docker-setup-update

## Update environment variables required for docker-compose
docker-setup-update:
@scripts/docker-setup.sh --force-update


.PHONY: docker-run

Expand All @@ -19,11 +25,27 @@ docker-run: docker-setup
docker-stop:
sudo docker-compose stop

.PHONY: docker-build

## Build docker images for docker-compose application
docker-build:
sudo docker-compose build

.PHONY: docker-rebuild

## Rebuild docker images
docker-rebuild:
sudo docker-compose rm -s -f
sudo docker-compose build

.PHONY: docker-update

## Update docker images (rebuild local or pull latest from repository depending on configuration).
docker-update:
@scripts/docker-update.sh

.PHONY: docker-purge

## Shut-down docker-compose application and remove all its images and volumes.
docker-purge:
sudo docker-compose down --rmi all -v --remove-orphans --timeout 0
18 changes: 17 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,28 @@ stop: docker-stop

.PHONY: setup

## Setup docker-compose application (generate .env file)
## Setup docker-compose application (generate .env file in needed)
setup: docker-setup

.PHONY: update-setup

## Update docker-compose application (regenerate .env file)
setup-update: docker-setup-update

.PHONY: rebuild

## Rebuild docker-compose images
rebuild: docker-rebuild

.PHONY: update

## Update images of the docker-compose application
update: docker-update

.PHONY: purge

## Remove docker-compose application and all its images and volumes.
purge: docker-purge

# Define default goal
.DEFAULT_GOAL := help
2 changes: 1 addition & 1 deletion docker-compose/prebuilt.cpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ version: '2.3'

services:
dedup-app:
image: johnhbenetech/videodeduplication:cpu
image: "johnhbenetech/videodeduplication:cpu${BENETECH_MODE}"
runtime: runc
2 changes: 1 addition & 1 deletion docker-compose/prebuilt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ version: '2.3'

services:
dedup-app:
image: johnhbenetech/videodeduplication:gpu
image: "johnhbenetech/videodeduplication:gpu${BENETECH_MODE}"
7 changes: 7 additions & 0 deletions scripts/docker-run.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/usr/bin/env bash

# This script runs the docker-compose application
# according to the configuration saved in .env file.

if ! [ -f ".env" ]; then
echo -e "\e[31mERROR\e[0m Environment file not found: $(pwd)/.env"
echo -e "\e[31mERROR\e[0m Please run script/docker-setup.sh first."
Expand All @@ -15,11 +18,15 @@ if ! [ -d "$BENETECH_DATA_LOCATION" ] || [ -z "$BENETECH_RUNTIME" ] || [ -z "$BE
fi

if [ "$BENETECH_RUNTIME" = "GPU" ] && [ "$BENETECH_PREBUILT" = "NO" ]; then
set -x
sudo docker-compose up -d
elif [ "$BENETECH_RUNTIME" = "CPU" ] && [ "$BENETECH_PREBUILT" = "NO" ]; then
set -x
sudo docker-compose -f docker-compose.yml -f docker-compose/build.cpu.yml up -d
elif [ "$BENETECH_RUNTIME" = "GPU" ] && [ "$BENETECH_PREBUILT" = "YES" ]; then
set -x
sudo docker-compose -f docker-compose.yml -f docker-compose/prebuilt.yml up -d
elif [ "$BENETECH_RUNTIME" = "CPU" ] && [ "$BENETECH_PREBUILT" = "YES" ]; then
set -x
sudo docker-compose -f docker-compose.yml -f docker-compose/prebuilt.cpu.yml up -d
fi
91 changes: 60 additions & 31 deletions scripts/docker-setup.sh
Original file line number Diff line number Diff line change
@@ -1,54 +1,83 @@
#!/usr/bin/env bash

read -r -d '' HELP << ENDOFHELP
usage: ./docker-setup.sh [--help] [-f | --force-update]

Generate .env file used by docker-compose tool
and some docker-related scripts under the ./script
directory.

See also https://docs.docker.com/compose/env-file/
ENDOFHELP

FORCE_UPDATE=NO;

# Read arguments
while (( $# > 0 )); do
case $1 in
-f|--force-update)
FORCE_UPDATE=YES;
shift;
;;
--help)
echo "$HELP";
exit 0;
;;
*)
echo "Unrecognized argument: $1";
echo "$HELP"
exit 1;
esac
done


LIBS="$(realpath "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/lib" )"
source "$LIBS/ask.choose.sh"
source "$LIBS/ask.confirm.sh"
source "$LIBS/ask.path.sh"

if [ -f ".env" ]; then
source .env
fi

# Read source data locaion
while ! [ -d "$BENETECH_DATA_LOCATION" ]; do
# Read source data location
if [ "$FORCE_UPDATE" = "YES" ] || ! [ -d "$BENETECH_DATA_LOCATION" ]; then
DIRTY=yes
echo -n -e "\e[36mPlease specify the root folder with your video files (use Tab for auto-complete): \e[0m"
read -e -r BENETECH_DATA_LOCATION
if ! [ -d "$BENETECH_DATA_LOCATION" ]; then
echo -e "\e[31mERROR\e[0m No such directory: $BENETECH_DATA_LOCATION"
fi
done
read-dir-path BENETECH_DATA_LOCATION "Please specify the root folder with your video files (use Tab for auto-complete)"
echo
fi

# Choose data analysis runtime
while [ -z "$BENETECH_RUNTIME" ]; do
if [ "$FORCE_UPDATE" = "YES" ] || [ -z "$BENETECH_RUNTIME" ]; then
DIRTY=yes
echo -n -e "\e[36mWould you like to use GPU for data analysis? [Y/n]: \e[0m"
read -r RUNTIME_ANSWER
if [ -z "$RUNTIME_ANSWER" ] || [[ "$RUNTIME_ANSWER" =~ [Yy] ]]; then
export BENETECH_RUNTIME=GPU
elif [[ "$RUNTIME_ANSWER" =~ [Nn] ]]; then
export BENETECH_RUNTIME=CPU
else
echo -e "\e[31mERROR\e[0m Cannot recognize answer. Please answer 'y' or 'n'"
fi
done
tput setaf 6; echo "Would you like to use GPU for data processing?"; tput sgr0;
choose BENETECH_RUNTIME GPU="Use GPU for data processing." CPU="Use CPU for data processing."
echo
fi

# Decide whether to use prebuilt images
while [ -z "$BENETECH_PREBUILT" ]; do
if [ "$FORCE_UPDATE" = "YES" ] || [ -z "$BENETECH_PREBUILT" ]; then
DIRTY=yes
echo -n -e "\e[36mWould you like to use pre-built images? [y/N]: \e[0m"
read -r PREBUILT_ANSWER
if [ -z "$PREBUILT_ANSWER" ] || [[ "$PREBUILT_ANSWER" =~ [Nn] ]]; then
export BENETECH_PREBUILT=NO
elif [[ "$PREBUILT_ANSWER" =~ [Yy] ]]; then
export BENETECH_PREBUILT=YES
else
echo -e "\e[31mERROR\e[0m Cannot recognize answer. Please answer 'y' or 'n'"
tput setaf 6; echo "Would you like to use pre-built Docker images?"; tput sgr0;
choose BENETECH_PREBUILT YES="Pull pre-built images from Docker Hub." NO="Build images locally."
echo

# Ask if user would like to use dev or prod images
if [ "$BENETECH_PREBUILT" = "YES" ]; then
tput setaf 6; echo "Would you like to use production Docker images?"; tput sgr0;
choose BENETECH_MODE ''="Use production images." '-dev'="Use dev-images."
echo
fi
done
fi

# Write data to the .env file
if [ -n "$DIRTY" ]; then
{
echo "BENETECH_DATA_LOCATION=$BENETECH_DATA_LOCATION"
echo "BENETECH_RUNTIME=$BENETECH_RUNTIME"
echo "BENETECH_PREBUILT=$BENETECH_PREBUILT"
echo "BENETECH_MODE=$BENETECH_MODE"
} > .env

echo -e "\e[1mOK\e[0m Configuration is written to the $(pwd)/.env file"
tput setaf 2; echo -n "OK"; tput sgr0;
echo " Configuration is written to the $(pwd)/.env";
fi
36 changes: 36 additions & 0 deletions scripts/docker-update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

# This script updates the docker-images used by the application.

if ! [ -f ".env" ]; then
echo -e "\e[31mERROR\e[0m Environment file not found: $(pwd)/.env"
echo -e "\e[31mERROR\e[0m Please run script/docker-setup.sh first."
exit 1
fi

source .env

if ! [ -d "$BENETECH_DATA_LOCATION" ] || [ -z "$BENETECH_RUNTIME" ] || [ -z "$BENETECH_PREBUILT" ]; then
echo -e "\e[31mERROR\e[0m Environment file is incomplete."
echo -e "\e[31mERROR\e[0m Please run script/docker-setup.sh first."
exit 1
fi


if [ "$BENETECH_RUNTIME" = "GPU" ] && [ "$BENETECH_PREBUILT" = "NO" ]; then
set -x
sudo docker-compose rm -s -f
sudo docker-compose build
elif [ "$BENETECH_RUNTIME" = "CPU" ] && [ "$BENETECH_PREBUILT" = "NO" ]; then
set -x
sudo docker-compose rm -s -f
sudo docker-compose -f docker-compose.yml -f docker-compose/build.cpu.yml build
elif [ "$BENETECH_RUNTIME" = "GPU" ] && [ "$BENETECH_PREBUILT" = "YES" ]; then
set -x
sudo docker-compose rm -s -f
sudo docker-compose -f docker-compose.yml -f docker-compose/prebuilt.yml pull
elif [ "$BENETECH_RUNTIME" = "CPU" ] && [ "$BENETECH_PREBUILT" = "YES" ]; then
set -x
sudo docker-compose rm -s -f
sudo docker-compose -f docker-compose.yml -f docker-compose/prebuilt.cpu.yml pull
fi
116 changes: 116 additions & 0 deletions scripts/lib/ask.choose.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env bash
# This module provides a 'choose' function which allows
# users to choose from a set of options using arrow keys.
# You should source this module to make it available in
# your script.
# Based on: https://www.bughunter2k.de/blog/cursor-controlled-selectmenu-in-bash


# Get choice value.
# Args:
# $1: Choice in the form of value="Display text."
function choose.option-value() {
local entry=$1;
echo "$entry" | grep -Po "^[^=]+"
}

# Get choice display text.
# Args:
# $1: Choice in the form of value="Display text."
function choose.option-text() {
local entry=$1;
echo "$entry" | grep -Po "(?<==).*$"
}

# Print choices.
# Args:
# $1 (number): Index of currently selected choice.
# *: Any number of choices in the form of value="Display text".
function choose.print-options() {
local cur=$1; shift 1;
local entries=( "$@" )
for entry in "${entries[@]}"; do
if [[ ${entries[$cur]} == "$entry" ]]; then
# Print green. See http://linuxcommand.org/lc3_adv_tput.php, "Text Effects"
tput setaf 2; echo ">$(choose.option-text "$entry")"; tput sgr0;
else
echo " $(choose.option-text "$entry")";
fi
done
}

# Erase printed choices.
# Args:
# $1 (number): Number of choices.
function choose.erase-options() {
local count=$1;
for _ in $(seq "$count"); do
# Move cursor one line up
# See http://linuxcommand.org/lc3_adv_tput.php, "Controlling The Cursor"
tput cuu1;
done
# Clear from the cursor to the end of the screen
# See http://linuxcommand.org/lc3_adv_tput.php, "Clearing The Screen"
tput ed;
}

# Ask user to select from the list of options using arrow keys.
# Args:
# $1 (variable reference): Variable to write result to.
# *: Any number of choices in the form value="Display text"
# Example:
# local MODE;
# choose MODE prod="Use production mode" dev="Use development mode"
function choose() {
# Use function name as a var-name prefix
# to prevent circular name reference
# See https://stackoverflow.com/a/33777659
# See http://mywiki.wooledge.org/BashFAQ/048#line-120
local -n _choose_result=$1; shift 1
local entries=( "$@" )
local cur=0;

choose.print-options "$cur" "${entries[@]}"

while read -sN1 key; do
# Catch multi-char special key sequences
# See https://stackoverflow.com/a/11759139
read -sN1 -t 0.0001 k1
read -sN1 -t 0.0001 k2
read -sN1 -t 0.0001 k3
key+=${k1}${k2}${k3}

# Enter or Space was pressed
if [ -z "$key" ]; then
# shellcheck disable=SC2034
# Variable is passed by reference
_choose_result="$(choose.option-value "${entries[$cur]}")";
return 0;
fi

case "$key" in
# Arrow up or left: previous item:
$'\e[A'|$'\e0A'|$'\e[D'|$'\e0D')
((cur > 0)) && ((cur--));;

# Arrow down or right: next item:
$'\e[B'|$'\e0B'|$'\e[C'|$'\e0C')
((cur < ${#entries[@]}-1)) && ((cur++));;

# Home: first item
$'\e[1~'|$'\e0H'|$'\e[H')
cur=0;;

# End: last item
$'\e[4~'|$'\e0F'|$'\e[F')
((cur=${#entries[@]}-1));;

# 'q' or carriage return: Quit
q|$'\e')
return 1;;
esac

choose.erase-options "${#entries[@]}"
choose.print-options "$cur" "${entries[@]}"
done
}
Loading