Skip to content

Commit af61242

Browse files
authored
feat: optionally run in parallel (#16)
1 parent a6db9ca commit af61242

File tree

1 file changed

+83
-52
lines changed

1 file changed

+83
-52
lines changed

pullio.sh

Lines changed: 83 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ DOCKER_BINARY="${DOCKER_BINARY:-$(which 'docker')}"
55
CACHE_LOCATION=/tmp
66
TAG=""
77
DEBUG=""
8-
CURRENT_VERSION=0.0.6
8+
CURRENT_VERSION=0.0.7
99
LATEST_VERSION=$(curl -fsSL "https://api.github.com/repos/hotio/pullio/releases" | jq -r .[0].tag_name)
10-
10+
PARALLEL=1
1111
COMPOSE_TYPE="NONE"
12+
1213
# Check for V1
1314
if [[ -n "${COMPOSE_BINARY}" ]]; then
1415
COMPOSE_TYPE="V1"
@@ -25,61 +26,76 @@ while [ "$1" != "" ]; do
2526
VALUE=$1
2627
fi
2728
case $PARAM in
28-
--tag)
29-
[[ -n $VALUE ]] && [[ $VALUE != "--"* ]] && TAG=".$VALUE"
30-
;;
31-
--debug)
32-
[[ $VALUE != "--"* ]] && DEBUG="${VALUE:-debug}"
33-
;;
29+
--tag)
30+
[[ -n $VALUE ]] && [[ $VALUE != "--"* ]] && TAG=".$VALUE"
31+
;;
32+
--debug)
33+
[[ $VALUE != "--"* ]] && DEBUG="${VALUE:-debug}"
34+
;;
35+
--parallel)
36+
[[ $VALUE =~ ^[0-9]+$ ]] && PARALLEL=$VALUE
37+
;;
3438
esac
3539
shift
3640
done
3741

38-
echo "Running with \"DEBUG=$DEBUG\" and \"TAG=$TAG\"."
42+
echo "Running with \"DEBUG=$DEBUG\", \"TAG=$TAG\", and \"PARALLEL=$PARALLEL\"."
3943
echo "Current version: ${CURRENT_VERSION}"
4044
echo "Latest version: ${LATEST_VERSION}"
4145

46+
# Setups the environment variables
47+
setup_environment() {
48+
# Always export these variables
49+
export COMPOSE_BINARY DOCKER_BINARY CACHE_LOCATION TAG DEBUG COMPOSE_TYPE
50+
51+
# Export functions and additional variables only for parallel execution
52+
if [ "$PARALLEL" -gt 1 ]; then
53+
export -f process_container compose_pull_wrapper compose_up_wrapper
54+
export -f send_discord_notification send_generic_webhook export_env_vars
55+
export sum
56+
fi
57+
}
58+
4259
compose_pull_wrapper() {
4360
cd "$1" || exit 1
4461
case $COMPOSE_TYPE in
45-
"V1")
46-
"${COMPOSE_BINARY}" pull "$2"
47-
;;
48-
"V2")
49-
"${DOCKER_BINARY}" compose pull "$2"
50-
;;
51-
"NONE")
52-
if [[ -n "${DOCKER_BINARY}" ]]; then
53-
"${DOCKER_BINARY}" run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$1:$1" -w="$1" linuxserver/docker-compose pull "$2"
54-
else
55-
echo "Error: Neither Docker Compose nor Docker binary is available. Cannot pull." >&2
56-
return 1
57-
fi
58-
;;
62+
"V1")
63+
"${COMPOSE_BINARY}" pull "$2"
64+
;;
65+
"V2")
66+
"${DOCKER_BINARY}" compose pull "$2"
67+
;;
68+
"NONE")
69+
if [[ -n "${DOCKER_BINARY}" ]]; then
70+
"${DOCKER_BINARY}" run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$1:$1" -w="$1" linuxserver/docker-compose pull "$2"
71+
else
72+
echo "Error: Neither Docker Compose nor Docker binary is available. Cannot pull." >&2
73+
return 1
74+
fi
75+
;;
5976
esac
6077
}
6178

6279
compose_up_wrapper() {
6380
cd "$1" || exit 1
6481
case $COMPOSE_TYPE in
65-
"V1")
66-
"${COMPOSE_BINARY}" up -d --always-recreate-deps "$2"
67-
;;
68-
"V2")
69-
"${DOCKER_BINARY}" compose up -d --always-recreate-deps "$2"
70-
;;
71-
"NONE")
72-
if [[ -n "${DOCKER_BINARY}" ]]; then
73-
"${DOCKER_BINARY}" run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$1:$1" -w="$1" linuxserver/docker-compose up -d --always-recreate-deps "$2"
74-
else
75-
echo "Error: Neither Docker Compose nor Docker binary is available. Cannot bring up services." >&2
76-
return 1
77-
fi
78-
;;
82+
"V1")
83+
"${COMPOSE_BINARY}" up -d --always-recreate-deps "$2"
84+
;;
85+
"V2")
86+
"${DOCKER_BINARY}" compose up -d --always-recreate-deps "$2"
87+
;;
88+
"NONE")
89+
if [[ -n "${DOCKER_BINARY}" ]]; then
90+
"${DOCKER_BINARY}" run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$1:$1" -w="$1" linuxserver/docker-compose up -d --always-recreate-deps "$2"
91+
else
92+
echo "Error: Neither Docker Compose nor Docker binary is available. Cannot bring up services." >&2
93+
return 1
94+
fi
95+
;;
7996
esac
8097
}
8198

82-
8399
send_discord_notification() {
84100
if [[ "${LATEST_VERSION}" != "${CURRENT_VERSION}" ]]; then
85101
footer_text="Powered by Pullio (update available)"
@@ -167,12 +183,8 @@ export_env_vars() {
167183
export PULLIO_AUTHOR_URL=${13}
168184
}
169185

170-
sum="$(sha1sum "$0" | awk '{print $1}')"
171-
172-
mapfile -t containers < <("${DOCKER_BINARY}" ps --format '{{.Names}}' | sort -k1 | awk '{ print $1 }')
173-
174-
for i in "${!containers[@]}"; do
175-
IFS=" " read -r container_name <<< "${containers[i]}"
186+
process_container() {
187+
local container_name="$1"
176188
echo "$container_name: Checking..."
177189

178190
image_name=$("${DOCKER_BINARY}" inspect --format='{{.Config.Image}}' "$container_name")
@@ -195,10 +207,10 @@ for i in "${!containers[@]}"; do
195207
pullio_author_avatar=$("${DOCKER_BINARY}" inspect --format='{{ index .Config.Labels "org.hotio.pullio'"${TAG}"'.author.avatar" }}' "$container_name")
196208
pullio_author_url=$("${DOCKER_BINARY}" inspect --format='{{ index .Config.Labels "org.hotio.pullio'"${TAG}"'.author.url" }}' "$container_name")
197209

198-
if [[ ( -n $docker_compose_version ) && ( $pullio_update == true || $pullio_notify == true ) ]]; then
210+
if [[ (-n $docker_compose_version) && ($pullio_update == true || $pullio_notify == true) ]]; then
199211
if [[ -f $pullio_registry_authfile ]]; then
200212
echo "$container_name: Registry login..."
201-
jq -r .password < "$pullio_registry_authfile" | "${DOCKER_BINARY}" login --username "$(jq -r .username < "$pullio_registry_authfile")" --password-stdin "$(jq -r .registry < "$pullio_registry_authfile")"
213+
jq -r .password <"$pullio_registry_authfile" | "${DOCKER_BINARY}" login --username "$(jq -r .username <"$pullio_registry_authfile")" --password-stdin "$(jq -r .registry <"$pullio_registry_authfile")"
202214
fi
203215

204216
echo "$container_name: Pulling image..."
@@ -227,17 +239,17 @@ for i in "${!containers[@]}"; do
227239
status_generic="update_success"
228240
color=3066993
229241
else
230-
echo "$container_name: Updating container failed!"
242+
echo "${container_name}: Updating container failed!"
231243
status="I tried to update myself.\nIt didn't work out, I might need some help."
232244
status_generic="update_failure"
233245
color=15158332
234246
fi
235-
rm -f "$CACHE_LOCATION/$sum-$container_name.notified"
247+
rm -f "${CACHE_LOCATION}/${sum}-${container_name}.notified"
236248
fi
237249

238250
if [[ "${image_digest}" != "$container_image_digest" ]] && [[ $pullio_notify == true ]]; then
239-
touch "$CACHE_LOCATION/$sum-$container_name.notified"
240-
notified_digest=$(cat "$CACHE_LOCATION/$sum-$container_name.notified")
251+
touch "${CACHE_LOCATION}/${sum}-${container_name}.notified"
252+
notified_digest=$(cat "${CACHE_LOCATION}/${sum}-${container_name}.notified")
241253
if [[ $notified_digest != "$image_digest" ]]; then
242254
if [[ -n "${pullio_script_notify[*]}" ]]; then
243255
echo "$container_name: Executing notify script..."
@@ -252,11 +264,30 @@ for i in "${!containers[@]}"; do
252264
echo "$container_name: Sending generic webhook..."
253265
send_generic_webhook "$status_generic" "$container_name" "$old_opencontainers_image_version" "$new_opencontainers_image_version" "$image_name" "$pullio_generic_webhook" "$old_opencontainers_image_revision" "$new_opencontainers_image_revision" "${container_image_digest/sha256:/}" "${image_digest/sha256:/}" "$pullio_author_avatar" "$pullio_author_url"
254266
fi
255-
echo "$image_digest" > "$CACHE_LOCATION/$sum-$container_name.notified"
267+
echo "$image_digest" >"${CACHE_LOCATION}/${sum}-${container_name}.notified"
256268
fi
257269
fi
258270
fi
259-
done
271+
}
272+
273+
# Respect ctrl+c
274+
trap 'exit 130' INT
275+
276+
# Setup the environment
277+
sum="$(sha1sum "$0" | awk '{print $1}')"
278+
declare -a containers
279+
readarray -t containers < <("${DOCKER_BINARY}" ps --format '{{.Names}}' | sort -k1)
280+
setup_environment
281+
282+
echo "Processing ${#containers[@]} containers with parallelism of $PARALLEL"
283+
284+
if [ "$PARALLEL" -gt 1 ]; then
285+
printf '%s\n' "${containers[@]}" | xargs -P "$PARALLEL" -I {} bash -c 'process_container "$@"' _ {}
286+
else
287+
for container_name in "${containers[@]}"; do
288+
process_container "$container_name"
289+
done
290+
fi
260291

261292
echo "Pruning docker images..."
262293
"${DOCKER_BINARY}" image prune --force

0 commit comments

Comments
 (0)