Skip to content

Compute hashes of executable files when migrating #2631

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

Merged
merged 3 commits into from
Aug 5, 2024

Conversation

tom93
Copy link
Contributor

@tom93 tom93 commented Jul 27, 2024

From the commit message:

The 'hash' column was added in commit bc1608f (Add hash to executable files and immutable executables., 2021-03-30), but the hashes were not computed for existing files, which breaks migrations from < 8.0.0 (judging fails with error message "Fetching executable failed for compile script '<n>': Unexpected hash ...").

This commit adds the code to an existing migration (Version20230508163415, added in DOMjudge 8.3.0, #2045) because the code in that migration uses the file hashes and won't work if they haven't been computed.

Users who already performed an upgrade from 7.x to 8.3.0 will need to manually re-run that migration:

bin/console doctrine:migrations:execute 'DoctrineMigrations\Version20230508163415' --down
bin/console doctrine:migrations:execute 'DoctrineMigrations\Version20230508163415' --up

Update: Switched to a fancier approach, see discussion.

This should fix the first issue mentioned in #2509 (steps to reproduce).

@tom93
Copy link
Contributor Author

tom93 commented Jul 28, 2024

Aside: I used executeStatement() like the existing code*, but I think it's better to use addSql() in migrations, otherwise --dry-run doesn't work for example. I wrote a patch to switch to addSql(), see commit c9bb5ef in branch 'wip/hash-migration-addSql' of my fork (not sure whether to add it to this PR or a separate PR, if at all).


*Actually, the existing code used executeQuery() and I changed that to executeStatement() in this PR because the query isn't returning results. Ironically, I accidentally used executeQuery() in the code that I added; I changed that to executeStatement() and force-pushed.

@tom93
Copy link
Contributor Author

tom93 commented Jul 30, 2024

Hmm, due to the way I've implemented this (modifying an relatively-new migration) this change can't be backported to 8.0-8.2. Should I change my patch to allow that? (I think move my code to a separate migration back-dated to when the 'hash' column was added, and insert a call to it in the existing migration to make sure it runs.)

@nickygerritsen
Copy link
Member

Hmm, due to the way I've implemented this (modifying an existing migration) this change can't be backported to 8.1 and 8.2. Should I change it to allow that? (I think move my code to a new migration back-dated to when the 'hash' column was added

This makes sense

, and insert a call to it in the existing migration to make sure it runs.)

Why do we need this? I think it will automatically run when not done yet, even if it has an old date.

@tom93
Copy link
Contributor Author

tom93 commented Jul 30, 2024

I think it will automatically run when not done yet, even if it has an old date.

Oh, okay, I didn't realise.

tom93 added 3 commits July 31, 2024 15:35
The 'hash' column was added to executable_file in commit bc1608f
(Add hash to executable files and immutable executables., 2021-03-30),
but the hashes were not computed for existing files. This broke
migrations from DOMjudge 7.x (judgehost error "Fetching executable
failed for compile script '<id>': Unexpected hash ...").

This commit fixes Version20210407120356.php (populate immutable
executable tables) so that it will compute the hashes, and also adds a
new migration to compute the hashes for databases that have already
been migrated from 7.x to 8.x.

This commit also re-runs migration Version20230508163415.php (update
hashes of immutable executables), because that migration uses the
hashes of the individual executable files. This is achieved by moving
that code to a new file (Version20230508180000.php) and converting the
original file to a no-op (we don't delete it to prevent warnings about
previously executed migrations that are not registered). This
automatically fixes the hashes of immutable executable in databases
migrated from 7.x to a DOMjudge version containing the original file
(8.2.1, 8.2.2, 8.2.3, and 8.3.0).
executeStatement() doesn't work well in migrations; for example it
doesn't respect the --dry-run option.

In Version20210407120356.php it's not possible to use addSql(),
because the statements use the results of previous statements. This
commit changes that file to use *only* executeStatement() for
consistency.

Also remove an unused import.
@tom93 tom93 force-pushed the pr/fix-immutable-exe-hash-migration branch from f62d0ec to 8687d5c Compare July 31, 2024 19:56
@tom93
Copy link
Contributor Author

tom93 commented Aug 1, 2024

I moved my code (which computes the executable_file hashes) into a new migration to allow backport. I also fixed Version20210407120356.php (Populate immutable executable tables), which should have calculated the hashes. (My new migration is still required for existing databases.)

I noticed that commit c920919 (which added migration Version20230508163415.php to update the immutable_executable hashes) has been backported to 8.2.1. So that migration will need to be re-run on those versions too, not just on 8.3.0 as I originally thought. Because of that, I decided to automatically re-run that migration. From the new commit message:

This commit also re-runs migration Version20230508163415.php (update hashes of immutable executables), because that migration uses the hashes of the individual executable files. This is achieved by moving that code to a new file (Version20230508180000.php) and converting the original file to a no-op (we don't delete it to prevent warnings about
previously executed migrations that are not registered). This automatically fixes the hashes of immutable executable in databases
migrated from 7.x to a DOMjudge version containing the original file (8.2.1, 8.2.2, 8.2.3, and 8.3.0).

I also added two cleanup commits (no functional changes, can be moved to moved to a separate PR). Style note: In one of them I used ? placeholders in an SQL statement, I hope that's okay (all the existing code uses named placeholders, but I didn't want to repeat all the column names).

I did several test (mostly with my patch applied to 8.2.3 rather than to main because the 8.2.3 Docker image was more convenient).

Here are the upgrade paths I tested (everything worked, but see notes at the very end):

  • 7.3.4 => 8.2.3-patched
  • 7.3.4 => 8.1.3 => 8.2.3-patched
  • 7.3.4 => 8.2.3 => 8.2.3-patched
  • 8.1.3 => 8.2.3-patched
  • (empty db) => 8.2.3-patched
  • 7.3.4 => main-patched

Steps:

  1. Start a fresh MariaDB container
  2. Run the old version(s), e.g. 7.3.4; terminate after setup
  3. Run the patched version, e.g. 8.2.3-patched
  4. Run judgehost:8.2.3
  5. Sign in as "dummy" (if DB created using 7.x) or "demo" (if DB created using 8.x)
  6. Submit hello.c, check result is "correct"

Regarding backporting, I tried to test my patch with 8.0.1 and 8.1.3 but I couldn't verify it because the judgehost crashed due to a separate issue, the message was "error: Argument 4 passed to fetch_executable() must be of the type string, null given, called in /opt/domjudge/judgehost/lib/judge/judgedaemon.main.php on line 1095". I'm not sure if it's worthwhile; the easy solution is to just document the limitations on upgrades from 7.x.


When I first tried main-patched something weird happened, I haven't been able to reproduce it and it could have been due to something silly, but I still want to mention it: When I signed in as the dummy/demo user I got a page saying there's no active contest, but when I signed in as admin the demo contest was there and looked fine (active, duration of almost a year, all teams). I can't remember exactly what I did; I think it happened twice, both when migrating from 7.3.4 and when starting from a clean database; but in my later attempts both worked fine.

Copy link
Member

@meisterT meisterT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@meisterT
Copy link
Member

meisterT commented Aug 3, 2024

When I first tried main-patched something weird happened, [...]

I haven't seen this behavior before and tried to trigger it but didn't succeed, please file a separate issue when you have a way to repro it.

@vmcj vmcj added this pull request to the merge queue Aug 5, 2024
Merged via the queue into DOMjudge:main with commit 6a99afc Aug 5, 2024
26 checks passed
@tom93 tom93 deleted the pr/fix-immutable-exe-hash-migration branch August 5, 2024 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants