2020#
2121# #
2222
23- # By default create files owned by root
23+ if [ -z " $REDIS_IMG " ]; then
24+ echo " REDIS_IMG may not be empty"
25+ exit 1
26+ fi
27+ # By default create files owned by root to avoid intersecting with container user
2428HOST_UID=0
2529HOST_GID=0
2630if docker info 2> /dev/null | grep -qi rootless; then
27- # For rootless docker use current user
31+ # For rootless docker we have to use current user
2832 HOST_UID=$( id -u)
2933 HOST_GID=$( id -g)
3034fi
@@ -33,13 +37,13 @@ HOST_OWNER=$HOST_UID:$HOST_GID
3337get_container_user_uid_gid_on_the_host () {
3438 container_user=" $1 "
3539 dir=$( mktemp -d -p .)
36- docker run --rm -v ` pwd` /$dir :/w -w /w --entrypoint=/bin/sh $REDIS_IMG -c " chown $container_user ."
40+ docker run --rm -v " $( pwd) /$dir " :/w -w /w --entrypoint=/bin/sh " $REDIS_IMG " -c " chown $container_user ."
3741 stat -c " %u %g" " $dir "
3842 sudo rm -rf " $dir "
3943}
4044
4145# Detect how redis user and group from the container are mapped to the host ones
42- read REDIS_UID REDIS_GID <<< " $(get_container_user_uid_gid_on_the_host redis:redis)"
46+ read -r REDIS_UID _ <<< " $(get_container_user_uid_gid_on_the_host redis:redis)"
4347
4448if [ " $REDIS_UID " == " $HOST_UID " ]; then
4549 echo " Cannot test ownership as redis user uid is the same as current user"
4852
4953# Helper functions #
5054
55+ # creates one entry of directory structure
5156# used in combination with iterate_dir_structure_with
5257create_entry () {
5358 dir=" $1 "
@@ -63,15 +68,16 @@ create_entry() {
6368 sudo chown " $initial_owner " " $dir /$entry "
6469}
6570
71+ # asserts ownership and permissions for one entry from directory structure
6672# used in combination with iterate_dir_structure_with
6773assert_entry () {
6874 dir=" $1 "
6975 msg=" $2 "
7076 actual_uid=$( sudo stat -c %u " $dir /$entry " )
7177 actual_mode=0$( sudo stat -c ' %a' " $dir /$entry " )
72- actual_mask=$( printf " 0%03o" $(( $ actual_mode & $ expected_mode_mask )) )
73- assertEquals " $msg : Owner for $type '$entry '" $expected_owner $actual_uid
74- assertEquals " $msg : Mode mask for $type '$entry '" $expected_mode_mask $actual_mask
78+ actual_mask=$( printf " 0%03o" $(( actual_mode & expected_mode_mask )) )
79+ assertEquals " $msg : Owner for $type '$entry '" " $expected_owner " " $actual_uid "
80+ assertEquals " $msg : Mode mask for $type '$entry '" " $expected_mode_mask " " $actual_mask "
7581}
7682
7783# Iterates over directory structure assigning variables and executing command
@@ -151,7 +157,7 @@ run_docker_and_test_ownership() {
151157 ;;
152158 esac
153159 done
154- docker_cmd=" $@ "
160+ docker_cmd=" $* "
155161
156162 if [ -z " $mount_target " ]; then
157163 fail " Mount target is empty"
@@ -160,9 +166,9 @@ run_docker_and_test_ownership() {
160166
161167 dir=$( mktemp -d -p .)
162168
163- iterate_dir_structure_with create_entry " $dir " <<< $dir_structure
169+ iterate_dir_structure_with create_entry " $dir " <<< " $dir_structure"
164170
165- docker_run=" docker run --rm -v ` pwd` /$dir :$mount_target $docker_flags $REDIS_IMG $docker_cmd "
171+ docker_run=" docker run --rm -v " $( pwd) /$dir " :$mount_target $docker_flags $REDIS_IMG $docker_cmd "
166172 if [ " $TEST_VERBOSE " ]; then
167173 echo -e " \n#### ownership test: $docker_cmd "
168174 echo " running $docker_run "
@@ -179,7 +185,7 @@ run_docker_and_test_ownership() {
179185 echo " $docker_output "
180186 fi
181187
182- iterate_dir_structure_with assert_entry " $dir " " $docker_cmd " <<< $dir_structure
188+ iterate_dir_structure_with assert_entry " $dir " " $docker_cmd " <<< " $dir_structure"
183189
184190 if [ " $extra_assert " ]; then
185191 $extra_assert
@@ -192,19 +198,19 @@ run_docker_and_test_ownership() {
192198# -v option will make redis-server to either return version or fail (if config has been provided)
193199# either one is OK for us
194200run_docker_and_test_ownership_with_common_flags_for_server () {
195- run_docker_and_test_ownership " ${common_flags[@]} " $@ -v
196- run_docker_and_test_ownership " ${common_flags[@]} " redis-server $@ -v
197- run_docker_and_test_ownership " ${common_flags[@]} " /usr/local/bin/redis-server $@ -v
201+ run_docker_and_test_ownership " ${common_flags[@]} " " $@ " -v
202+ run_docker_and_test_ownership " ${common_flags[@]} " redis-server " $@ " -v
203+ run_docker_and_test_ownership " ${common_flags[@]} " /usr/local/bin/redis-server " $@ " -v
198204}
199205
200206# running redis-sentinel using different forms and --dumb-option
201207# expecting sentinel to fail, it's ok as we are only interested in entrypoint testing here
202208run_docker_and_test_ownership_with_common_flags_for_sentinel () {
203- run_docker_and_test_ownership " ${common_flags[@]} " $@ --sentinel --dumb-option
204- run_docker_and_test_ownership " ${common_flags[@]} " redis-sentinel $@ --dumb-option
205- run_docker_and_test_ownership " ${common_flags[@]} " /usr/local/bin/redis-sentinel $@ --dumb-option
206- run_docker_and_test_ownership " ${common_flags[@]} " redis-server $@ --sentinel --dumb-option
207- run_docker_and_test_ownership " ${common_flags[@]} " /usr/local/bin/redis-server $@ --sentinel --dumb-option
209+ run_docker_and_test_ownership " ${common_flags[@]} " " $@ " --sentinel --dumb-option
210+ run_docker_and_test_ownership " ${common_flags[@]} " redis-sentinel " $@ " --dumb-option
211+ run_docker_and_test_ownership " ${common_flags[@]} " /usr/local/bin/redis-sentinel " $@ " --dumb-option
212+ run_docker_and_test_ownership " ${common_flags[@]} " redis-server " $@ " --sentinel --dumb-option
213+ run_docker_and_test_ownership " ${common_flags[@]} " /usr/local/bin/redis-server " $@ " --sentinel --dumb-option
208214}
209215
210216# start redis server or sentinel and check process uid and gid
@@ -230,7 +236,7 @@ run_redis_docker_and_check_uid_gid() {
230236 shift 2
231237 ;;
232238 --docker-flags)
233- docker_flags=" $2 "
239+ docker_flags=$2
234240 shift 2
235241 ;;
236242 --file-owner)
@@ -248,7 +254,7 @@ run_redis_docker_and_check_uid_gid() {
248254 done
249255
250256 if echo " $expected_cmd " | grep -q " sentinel" ; then
251- dir=$( readlink -f $( mktemp -d -p .) )
257+ dir=" $( readlink -f " $( mktemp -d -p .) " ) "
252258 touch " $dir /sentinel.conf"
253259 if [ " $file_owner " ]; then
254260 sudo chown -R " $file_owner " " $dir "
@@ -257,7 +263,8 @@ run_redis_docker_and_check_uid_gid() {
257263 fi
258264
259265 docker_cmd=" $* "
260- container=$( docker run $docker_flags -d $REDIS_IMG $docker_cmd )
266+ # shellcheck disable=SC2086
267+ container=$( docker run $docker_flags -d " $REDIS_IMG " $docker_cmd )
261268 ret=$?
262269
263270 assertTrue " Container '$docker_flags $REDIS_IMG $docker_cmd ' created" " [ $ret -eq 0 ]"
@@ -269,8 +276,8 @@ run_redis_docker_and_check_uid_gid() {
269276 cmdline=$( docker exec " $container " cat /proc/1/cmdline| tr -d \\ 0)
270277 assertContains " $docker_flags $docker_cmd , cmdline: $cmdline " " $cmdline " " $expected_cmd "
271278
272- redis_user_uid=$( docker exec " $container " id -u $user )
273- redis_user_gid=$( docker exec " $container " id -g $group )
279+ redis_user_uid=$( docker exec " $container " id -u " $user " )
280+ redis_user_gid=$( docker exec " $container " id -g " $group " )
274281
275282 status=$( docker exec " $container " cat /proc/1/status)
276283 process_uid=$( echo " $status " | grep Uid | cut -f2)
@@ -287,10 +294,11 @@ run_redis_docker_and_check_uid_gid() {
287294
288295run_redis_docker_and_check_modules () {
289296 docker_cmd=" $1 "
290- container=$( docker run --rm -d $REDIS_IMG $docker_cmd )
297+ # shellcheck disable=SC2086
298+ container=$( docker run --rm -d " $REDIS_IMG " $docker_cmd )
291299 info=$( docker exec " $container " redis-cli info)
292300
293- [ " $PLATFORM " -a " $PLATFORM " != " amd64" ] && startSkipping
301+ [ " $PLATFORM " ] && [ " $PLATFORM " != " amd64" ] && startSkipping
294302 assertContains " $info " " module:name=timeseries"
295303 assertContains " $info " " module:name=search"
296304 assertContains " $info " " module:name=bf"
@@ -313,7 +321,7 @@ assert_redis_v8() {
313321# Tests #
314322
315323test_redis_version () {
316- ret=$( docker run --rm $REDIS_IMG -v| tail -n 1)
324+ ret=$( docker run --rm " $REDIS_IMG " -v| tail -n 1)
317325 assert_redis_v8 " $ret "
318326}
319327
@@ -478,7 +486,9 @@ test_config_owner_and_perms_changed_by_sentinel_when_config_is_WO() {
478486# test that entrypoint tries to start redis even when config is non existent dir
479487test_redis_start_reached_when_config_dir_does_not_exist () {
480488 assert_has_config_error () {
489+ # shellcheck disable=SC2317
481490 assertContains " $docker_output " " Fatal error, can't open config file"
491+ # shellcheck disable=SC2317
482492 assertContains " $docker_output " " No such file or directory"
483493 }
484494 common_flags=(--mount-target /etc/somewhere --extra-assert assert_has_config_error)
@@ -487,6 +497,7 @@ test_redis_start_reached_when_config_dir_does_not_exist() {
487497
488498test_redis_start_reached_when_chown_on_data_dir_is_denied () {
489499 assert_internal () {
500+ # shellcheck disable=SC2317
490501 assert_redis_v8 " $docker_output "
491502 }
492503 dir_structure="
@@ -533,19 +544,22 @@ test_redis_server_persistence_with_bind_mount() {
533544 # make data directory non writable
534545 chmod 0444 " $dir "
535546
536- container=$( docker run --rm -d -v ` pwd` /$dir :/data $REDIS_IMG )
547+ container=$( docker run --rm -d -v " $( pwd) /$dir " :/data " $REDIS_IMG " --appendonly yes )
537548
538- result=$( echo save | docker exec -i $container redis-cli)
549+ result=$( echo save | docker exec -i " $container " redis-cli)
539550 assertEquals " OK" " $result "
540551
541552 # save container hash as a value
542- result=$( echo " SET FOO $container " | docker exec -i $container redis-cli)
553+ result=$( echo " SET FOO $container " | docker exec -i " $container " redis-cli)
543554 assertEquals " OK" " $result "
544555
545556 docker stop " $container " > /dev/null
546557
547- container2=$( docker run --rm -d -v ` pwd` /$dir :/data $REDIS_IMG )
548- value=$( echo " GET FOO" | docker exec -i $container2 redis-cli)
558+ # change the owner
559+ sudo chown -R " $HOST_OWNER " " $dir "
560+
561+ container2=$( docker run --rm -d -v " $( pwd) /$dir " :/data " $REDIS_IMG " )
562+ value=$( echo " GET FOO" | docker exec -i " $container2 " redis-cli)
549563 assertEquals " $container " " $value "
550564
551565 docker stop " $container2 " > /dev/null
@@ -558,19 +572,25 @@ test_redis_server_persistence_with_volume() {
558572
559573 docker volume create test_redis > /dev/null
560574
561- container=$( docker run --rm -d -v test_redis:/data $REDIS_IMG )
575+ # change owner of the data volume
576+ docker run --rm -v test_redis:/data --entrypoint=/bin/sh " $REDIS_IMG " -c ' chown -R 0:0 /data'
577+
578+ container=$( docker run --rm -d -v test_redis:/data " $REDIS_IMG " --appendonly yes)
562579
563- result=$( echo save | docker exec -i $container redis-cli)
580+ result=$( echo save | docker exec -i " $container " redis-cli)
564581 assertEquals " OK" " $result "
565582
566583 # save container hash as a value
567- result=$( echo " SET FOO $container " | docker exec -i $container redis-cli)
584+ result=$( echo " SET FOO $container " | docker exec -i " $container " redis-cli)
568585 assertEquals " OK" " $result "
569586
570587 docker stop " $container " > /dev/null
571588
572- container2=$( docker run --rm -d -v test_redis:/data $REDIS_IMG )
573- value=$( echo " GET FOO" | docker exec -i $container2 redis-cli)
589+ # change owner and permissions of files in data volume
590+ docker run --rm -v test_redis:/data --entrypoint=/bin/sh " $REDIS_IMG " -c ' chown -R 0:0 /data && chmod 0000 -R /data'
591+
592+ container2=$( docker run --rm -d -v test_redis:/data " $REDIS_IMG " )
593+ value=$( echo " GET FOO" | docker exec -i " $container2 " redis-cli)
574594 assertEquals " $container " " $value "
575595
576596 docker stop " $container2 " > /dev/null
@@ -591,19 +611,19 @@ test_redis_process_uid_and_gid_are_redis() {
591611}
592612
593613test_redis_process_uid_and_gid_respects_docker_user_arg () {
594- read daemon_user_uid _ <<< " $(get_container_user_uid_gid_on_the_host daemon:daemon)"
614+ read -r daemon_user_uid _ <<< " $(get_container_user_uid_gid_on_the_host daemon:daemon)"
595615
596616 # disable persistence as directory data dir would not be writable
597617 common_flags=(--user daemon --group daemon --docker-flags " --user daemon" )
598618 run_redis_docker_and_check_uid_gid " ${common_flags[@]} " " " --save " "
599619 run_redis_docker_and_check_uid_gid " ${common_flags[@]} " redis-server --save " "
600620 run_redis_docker_and_check_uid_gid " ${common_flags[@]} " /usr/local/bin/redis-server --save " "
601621
602- run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner $daemon_user_uid --expected-cmd redis-sentinel redis-sentinel /etc/sentinel/sentinel.conf
603- run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner $daemon_user_uid --expected-cmd redis-sentinel /usr/local/bin/redis-sentinel /etc/sentinel/sentinel.conf
604- run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner $daemon_user_uid --expected-cmd " [sentinel]" /etc/sentinel/sentinel.conf --sentinel
605- run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner $daemon_user_uid --expected-cmd " [sentinel]" redis-server /etc/sentinel/sentinel.conf --sentinel
606- run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner $daemon_user_uid --expected-cmd " [sentinel]" /usr/local/bin/redis-server /etc/sentinel/sentinel.conf --sentinel
622+ run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner " $daemon_user_uid " --expected-cmd redis-sentinel redis-sentinel /etc/sentinel/sentinel.conf
623+ run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner " $daemon_user_uid " --expected-cmd redis-sentinel /usr/local/bin/redis-sentinel /etc/sentinel/sentinel.conf
624+ run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner " $daemon_user_uid " --expected-cmd " [sentinel]" /etc/sentinel/sentinel.conf --sentinel
625+ run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner " $daemon_user_uid " --expected-cmd " [sentinel]" redis-server /etc/sentinel/sentinel.conf --sentinel
626+ run_redis_docker_and_check_uid_gid " ${common_flags[@]} " --file-owner " $daemon_user_uid " --expected-cmd " [sentinel]" /usr/local/bin/redis-server /etc/sentinel/sentinel.conf --sentinel
607627}
608628
609629test_redis_process_uid_and_gid_are_root_when_SKIP_DROP_PRIVS_is_used () {
@@ -625,4 +645,5 @@ test_redis_server_modules_are_loaded() {
625645 run_redis_docker_and_check_modules /usr/local/bin/redis-server
626646}
627647
648+ # shellcheck disable=SC1091
628649. ./shunit2
0 commit comments