From 897ad8b72ac35a9a7205167eb99a6ddec07485e5 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Thu, 17 Nov 2022 12:51:51 +0000 Subject: [PATCH] [docs] extend docs for upgrading from 0.x --- doc/upgrading-from-0.x.md | 177 +++++++++++++++++++++++++++++++++++--- 1 file changed, 167 insertions(+), 10 deletions(-) diff --git a/doc/upgrading-from-0.x.md b/doc/upgrading-from-0.x.md index 789a08f..72ba8ba 100644 --- a/doc/upgrading-from-0.x.md +++ b/doc/upgrading-from-0.x.md @@ -3,7 +3,7 @@ Thank you for your continued trust in Overleaf as a long term customer of Server Pro! > **Note** -> For reference Server CE/Pro version 1.x was released in 2017. +> For reference: Server CE/Pro version 1.x was released in 2017. > > If you are still using 0.x and plan to upgrade, please do so one major version at a time (e.g. from 0.6.3 to 1.24, then 2.7.1, then the [latest release of `3.x.x`](https://github.com/overleaf/overleaf/wiki/Release-Notes-3.x.x)). @@ -12,6 +12,8 @@ Thank you for your continued trust in Overleaf as a long term customer of Server ### Duplicate indexes +#### projectInvites + > MongoError: Error during migrate "20190912145023_create_projectInvites_indexes": Index with name: expires_1 already exists with different options Early versions of Server CE/Pro had their indexes defined inline in the model layer of the application. @@ -32,15 +34,9 @@ bin/docker-compose stop sharelatex # Check the existing indexes echo 'db.projectInvites.getIndexes()' | bin/docker-compose exec -T mongo mongo --quiet sharelatex -# Expected output: +# Expected output variant 1 (use of Server CE from August 2016, changed `expireAfterSeconds` attribute): # [ -# { -# "v" : 2, -# "key" : { -# "_id" : 1 -# }, -# "name" : "_id_" -# }, +# ... # { # "v" : 2, # "key" : { @@ -50,8 +46,26 @@ echo 'db.projectInvites.getIndexes()' | bin/docker-compose exec -T mongo mongo - # "expireAfterSeconds" : 2592000, # "background" : true # } +# ... # ] +# Expected output variant 2 (use of an old mongodb version, offending `"safe":null` attribute): +# [ +# ... +# { +# "v" : 2, +# "key" : { +# "expires" : 1 +# }, +# "name" : "expires_1", +# "expireAfterSeconds" : 10, +# "background" : true, +# "safe": null +# } +# ... +# ] + + # Also check for completed migrations echo 'db.migrations.count({"name":"20190912145023_create_projectInvites_indexes"})' | bin/docker-compose exec -T mongo mongo --quiet sharelatex # Expected output: @@ -63,8 +77,151 @@ echo 'db.migrations.count({"name":"20190912145023_create_projectInvites_indexes" # If the output matches, continue below. # Drop the expires_1 index -echo 'db.projectInvites.dropIndex("expires_1")' | bin/docker-compose exec -T mongo mongo sharelatex +echo 'db.projectInvites.dropIndex("expires_1")' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output (NOTE: the "nIndexesWas" number may differ) +# { "nIndexesWas" : 3, "ok" : 1 } # Start the application again bin/docker-compose start sharelatex ``` + +#### templates + +> MongoError: Error during migrate "20190912145030_create_templates_indexes": Index with name: project_id_1 already exists with different options + +See comment in projectInvites section. + +It is safe to delete the `project_id_1` index for re-creation by the `20190912145030_create_templates_indexes` migration. +The `user_id_1` and `name_1` indexes are likely affected as well, and you can delete them right away as well. +Please make sure that the application (Server CE/Pro) is not running. + +```shell +# Change the directory to the root of the toolkit checkout. E.g.: +# cd ~/toolkit + +# Stop the application +bin/docker-compose stop sharelatex + +# Check the existing indexes +echo 'db.templates.getIndexes()' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output (use of an old mongodb version, offending `"safe":null` attribute): +# [ +# ... +# { +# "v" : 1, +# "key" : { +# "name" : 1 +# }, +# "name" : "name_1", +# "ns" : "sharelatex.templates", +# "background" : true, +# "safe" : null +# }, +# { +# "v" : 1, +# "unique" : true, +# "key" : { +# "project_id" : 1 +# }, +# "name" : "project_id_1", +# "ns" : "sharelatex.templates", +# "background" : true, +# "safe" : null +# }, +# { +# "v" : 1, +# "key" : { +# "user_id" : 1 +# }, +# "name" : "user_id_1", +# "ns" : "sharelatex.templates", +# "background" : true, +# "safe" : null +# } +# ] + +# Also check for completed migrations +echo 'db.migrations.count({"name":"20190912145030_create_templates_indexes"})' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output: +# 0 + +# If the output of any of the two above commands does not match, stop here. +# Please reach out to support@overleaf.com for assistance and provide the output. + + +# If the output matches, continue below. +# Drop the project_id_1, user_id_1 and name_1 index +echo 'db.templates.dropIndex("project_id_1")' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output (NOTE: the "nIndexesWas" number may differ) +# { "nIndexesWas" : 4, "ok" : 1 } +echo 'db.templates.dropIndex("user_id_1")' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output (NOTE: the "nIndexesWas" number may differ) +# { "nIndexesWas" : 3, "ok" : 1 } +echo 'db.templates.dropIndex("name_1")' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output (NOTE: the "nIndexesWas" number may differ) +# { "nIndexesWas" : 2, "ok" : 1 } + +# Start the application again +bin/docker-compose start sharelatex +``` + +### Users with non-unique emails + +> MongoError: Error during migrate "20190912145032_create_users_indexes": E11000 duplicate key error collection: sharelatex.users index: email_case_insensitive collation + +Older versions of Server Pro did not normalize emails sufficiently to ensure that unique emails are used by different users. + +Server Pro 3.x applies stricter normalization. It is possible that old databases have users with non-unique emails. + +The first step is identifying the scope of this issue: + +```shell +# Change the directory to the root of the toolkit checkout. E.g.: +# cd ~/toolkit + +# list emails that have more than one related user when normalized to lower case. +echo 'db.users.aggregate([{"$group":{"_id":{"$toLower":"$email"},"count":{"$sum":1}}},{"$match":{"count":{"$gt":1}}}])' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output +# { "_id" : "foo@bar.com", "count" : 2 } +# ... +``` + +There are two options to deal with a duplicate. + +> **Note** Please take a DB backup before making any of these changes. + +1. You can change the email address of one of these account (see query below) and deal with the project access later. +2. Do that later task now: + 1. You will need to check the contents of both accounts and decide which of these should be the primary account moving forward. + 2. The admin panel of Server Pro can help here, and you can find it under "https:///admin/user" (requires an admin account). + 3. On this page you can enter the users email address, and it should display two user entries (if not, try different casing, see query below). + 4. When you click on the individual list entries you should see a user info page. + 5. The "projects" tab lists all the users projects. + 6. You will need to transfer the ownership of each of these projects into the desired account using the "Transfer ownership" button. + 7. Once all projects are migrated out of one account, you can use the "Delete User" button on the admin user info page. (The user deletion here is a soft-deletion and you can restore it later if needed.) + +```shell +# Change the directory to the root of the toolkit checkout. E.g.: +# cd ~/toolkit + +# Change the email of one of the accounts and deal with the project access later. +# Replace the three placeholders "foo@bar.com" with an actual email address that has two related users. +# The "^" and "$" characters around the email ensure that we do not match similar emails, e.g. "this-is-not-foo@bar.com" also contains "foo@bar.com". +echo 'db.users.updateOne({"email":/^foo@bar.com$/i},{"$set":{"email":"duplicate-foo@bar.com","emails.0.email":"duplicate-foo@bar.com"}})' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output +# { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 } +``` + +```shell +# Change the directory to the root of the toolkit checkout. E.g.: +# cd ~/toolkit +# Find exact casing of the email addresses +# Replace the placeholder "foo@bar.com" with an actual email address that has two related users. +# The "^" and "$" characters around the email ensure that we do not match similar emails, e.g. "this-is-not-foo@bar.com" also contains "foo@bar.com". +echo 'db.users.find({"email":/^foo@bar.com$/i},{"email":1})' | bin/docker-compose exec -T mongo mongo --quiet sharelatex +# Expected output +# { "_id" : ObjectId("637276cd42fab6008ec8c88c"), "email" : "foo@bar.com" } +# { "_id" : ObjectId("637276cd42fab6008ec8c88d"), "email" : "FOO@bar.com" } +``` + +Please do not hesitate to reach out to [support@overleaf.com](mailto:support@overleaf.com) if you have any questions or concerns about this process. We are happy to help!