Skip to content

Commit 32e7ede

Browse files
tom93vmcj
authored andcommitted
Compute hashes of executable files when migrating
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).
1 parent 0023f38 commit 32e7ede

File tree

4 files changed

+102
-30
lines changed

4 files changed

+102
-30
lines changed

webapp/migrations/Version20210407120356.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public function up(Schema $schema) : void
5353
}
5454
$this->connection->executeStatement(
5555
'INSERT INTO executable_file '
56-
. '(`immutable_execid`, `filename`, `ranknumber`, `file_content`, `is_executable`) '
56+
. '(`immutable_execid`, `filename`, `ranknumber`, `file_content`, `hash`, `is_executable`) '
5757
. 'VALUES (' . $immutable_execid . ', "' . $filename . '", '
58-
. $idx . ', ' . $encodedContent . ', '
58+
. $idx . ', ' . $encodedContent . ', "' . md5($content) . '", '
5959
. $executableBit . ')'
6060
);
6161
}

webapp/migrations/Version20230508163415.php

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,28 @@
44

55
namespace DoctrineMigrations;
66

7-
use App\Entity\ExecutableFile;
87
use Doctrine\DBAL\Schema\Schema;
98
use Doctrine\Migrations\AbstractMigration;
109

11-
/**
12-
* Auto-generated Migration: Please modify to your needs!
13-
*/
1410
final class Version20230508163415 extends AbstractMigration
1511
{
12+
// The code that was in this file was moved to Version20230508180000.php so
13+
// that it will re-run after Version20230508170000.php. This file has been
14+
// kept as a no-op to prevent warnings about previously executed migrations
15+
// that are not registered.
16+
1617
public function getDescription(): string
1718
{
18-
return 'Update hashes of immutable executables';
19+
return '[Deleted]';
1920
}
2021

2122
public function up(Schema $schema): void
2223
{
23-
$immutableExecutables = $this->connection->fetchAllAssociative('SELECT immutable_execid FROM immutable_executable');
24-
foreach ($immutableExecutables as $immutableExecutable) {
25-
$files = $this->connection->fetchAllAssociative('SELECT hash, filename, is_executable FROM executable_file WHERE immutable_execid = :id', ['id' => $immutableExecutable['immutable_execid']]);
26-
uasort($files, fn(array $a, array $b) => strcmp($a['filename'], $b['filename']));
27-
$newHash = md5(
28-
join(
29-
array_map(
30-
fn(array $file) => $file['hash'] . $file['filename'] . (bool)$file['is_executable'],
31-
$files
32-
)
33-
)
34-
);
35-
$this->connection->executeQuery('UPDATE immutable_executable SET hash = :hash WHERE immutable_execid = :id', [
36-
'hash' => $newHash,
37-
'id' => $immutableExecutable['immutable_execid'],
38-
]);
39-
}
24+
$this->addSql('-- no-op'); // suppress warning "Migration <name> was executed but did not result in any SQL statements."
4025
}
4126

4227
public function down(Schema $schema): void
4328
{
44-
// We don't handle this case
45-
}
46-
47-
public function isTransactional(): bool
48-
{
49-
return false;
29+
$this->addSql('-- no-op');
5030
}
5131
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
final class Version20230508170000 extends AbstractMigration
11+
{
12+
public function getDescription(): string
13+
{
14+
return 'Compute hashes of executable files';
15+
// This migration is only required for databases that were migrated
16+
// from DOMjudge 7.x using certain DOMjudge versions in the range 8.0.0
17+
// to 8.3.0. Databases migrated from 7.x straight to 8.3.1+ will have
18+
// the hashes computed by Version20201219154651.php.
19+
}
20+
21+
public function up(Schema $schema): void
22+
{
23+
$executableFiles = $this->connection->fetchAllAssociative('SELECT execfileid, file_content FROM executable_file WHERE hash IS NULL');
24+
foreach ($executableFiles as $file) {
25+
$this->addSql('UPDATE executable_file SET hash = :hash WHERE execfileid = :id', [
26+
'hash' => md5($file['file_content']),
27+
'id' => $file['execfileid']
28+
]);
29+
}
30+
}
31+
32+
public function down(Schema $schema): void
33+
{
34+
// We don't handle this case
35+
}
36+
37+
public function isTransactional(): bool
38+
{
39+
return false;
40+
}
41+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use App\Entity\ExecutableFile;
8+
use Doctrine\DBAL\Schema\Schema;
9+
use Doctrine\Migrations\AbstractMigration;
10+
11+
/**
12+
* Auto-generated Migration: Please modify to your needs!
13+
*/
14+
final class Version20230508180000 extends AbstractMigration
15+
{
16+
public function getDescription(): string
17+
{
18+
return 'Update hashes of immutable executables';
19+
}
20+
21+
public function up(Schema $schema): void
22+
{
23+
$immutableExecutables = $this->connection->fetchAllAssociative('SELECT immutable_execid FROM immutable_executable');
24+
foreach ($immutableExecutables as $immutableExecutable) {
25+
$files = $this->connection->fetchAllAssociative('SELECT hash, filename, is_executable FROM executable_file WHERE immutable_execid = :id', ['id' => $immutableExecutable['immutable_execid']]);
26+
uasort($files, fn(array $a, array $b) => strcmp($a['filename'], $b['filename']));
27+
$newHash = md5(
28+
join(
29+
array_map(
30+
fn(array $file) => $file['hash'] . $file['filename'] . (bool)$file['is_executable'],
31+
$files
32+
)
33+
)
34+
);
35+
$this->connection->executeQuery('UPDATE immutable_executable SET hash = :hash WHERE immutable_execid = :id', [
36+
'hash' => $newHash,
37+
'id' => $immutableExecutable['immutable_execid'],
38+
]);
39+
}
40+
}
41+
42+
public function down(Schema $schema): void
43+
{
44+
// We don't handle this case
45+
}
46+
47+
public function isTransactional(): bool
48+
{
49+
return false;
50+
}
51+
}

0 commit comments

Comments
 (0)