diff --git a/src/apps.js b/src/apps.js index 8dc0f63d2..70b3b4f66 100644 --- a/src/apps.js +++ b/src/apps.js @@ -512,7 +512,7 @@ async function checkStorage(app, volumeId, prefix) { const rel = path.relative(sourceDir, targetDir); if (!rel.startsWith('../') && rel.split('/').length > 1) throw new BoxError(BoxError.BAD_FIELD, 'Only one level subdirectory moves are supported'); - const [error] = await safe(shell.promises.sudo('checkStorage', [ CHECKVOLUME_CMD, targetDir ], {})); + const [error] = await safe(shell.promises.sudo('checkStorage', [ CHECKVOLUME_CMD, targetDir, sourceDir ], {})); if (error && error.code === 2) throw new BoxError(BoxError.BAD_FIELD, `Target directory ${targetDir} is not empty`); if (error && error.code === 3) throw new BoxError(BoxError.BAD_FIELD, `Target directory ${targetDir} does not support chown`); diff --git a/src/scripts/checkvolume.sh b/src/scripts/checkvolume.sh index 67c012312..b5e72b932 100755 --- a/src/scripts/checkvolume.sh +++ b/src/scripts/checkvolume.sh @@ -17,14 +17,24 @@ if [[ "$1" == "--check" ]]; then exit 0 fi -volume_dir="$1" +target_dir="$1" +source_dir="$2" -readonly test_file="${volume_dir}/.chown-test" +source_stat=$(stat --format='%d,%i' "${source_dir}") +target_stat=$(stat --format='%d,%i' "${target_dir}") -mkdir -p "${volume_dir}" +# test sameness across bind mounts. if it's same, we can skip the emptiness check +if [[ "${source_stat}" == "${target_stat}" ]]; then + echo "Source dir and target dir are the same" + exit 0 +fi + +readonly test_file="${target_dir}/.chown-test" + +mkdir -p "${target_dir}" rm -f "${test_file}" # clean up any from previous run -if [[ -n $(ls -A "${volume_dir}") ]]; then +if [[ -n $(ls -A "${target_dir}") ]]; then echo "volume dir is not empty" exit 2 fi @@ -35,5 +45,5 @@ if ! chown yellowtent:yellowtent "${test_file}"; then exit 3 fi rm -f "${test_file}" -rm -r "${volume_dir}" # will get recreated by the local storage addon +rm -r "${target_dir}" # will get recreated by the local storage addon diff --git a/src/scripts/mvvolume.sh b/src/scripts/mvvolume.sh index e53e10659..e6a31254b 100755 --- a/src/scripts/mvvolume.sh +++ b/src/scripts/mvvolume.sh @@ -26,6 +26,15 @@ if [[ "${BOX_ENV}" == "test" ]]; then [[ "${target_dir}" != *"/.cloudron_test/"* ]] && exit 1 fi +source_stat=$(stat --format='%d,%i' "${source_dir}") +target_stat=$(stat --format='%d,%i' "${target_dir}") + +# test sameness across bind mounts +if [[ "${source_stat}" == "${target_stat}" ]]; then + echo "Source dir and target dir are the same" + exit 0 +fi + # copy and remove - this way if the copy fails, the original is intact # the find logic is so that move to a one level subdir works (and we also move hidden files) find "${source_dir}" -maxdepth 1 -mindepth 1 -not -wholename "${target_dir}" -exec cp -ar '{}' "${target_dir}" \;