Guarantee repositories have unique local paths
Summary: Ref T4039. Long ago these were more freely editable and there were some security concerns around creating a repository, then setting its local path to point somewhere it shouldn't. Local paths are no longer editable so there's no real reason we need to provide a uniqueness guarantee anymore, but you could still make a mistake with `bin/repository move-paths` by accident, and it's a little cleaner to pull them out into their own column with a key. (We still don't -- and, largely can't -- guarantee that two paths aren't //equivalent// since one might be symlinked to the other, or symlinked only on some hosts, or whatever, but the primary value here is as a sanity check that you aren't goofing things up and pointing a bunch of repositories at the same working copy by mistake.) Test Plan: - Ran migrations. - Grepped for `local-path`. - Listed and moved paths with `bin/repository`. - Created a new repository, verified its local path populated correctly. Reviewers: chad Reviewed By: chad Maniphest Tasks: T4039 Differential Revision: https://secure.phabricator.com/D15837
This commit is contained in:
2
resources/sql/autopatches/20160503.repo.01.lpath.sql
Normal file
2
resources/sql/autopatches/20160503.repo.01.lpath.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE {$NAMESPACE}_repository.repository
|
||||
ADD localPath VARCHAR(128) COLLATE {$COLLATE_TEXT};
|
||||
2
resources/sql/autopatches/20160503.repo.02.lpathkey.sql
Normal file
2
resources/sql/autopatches/20160503.repo.02.lpathkey.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE {$NAMESPACE}_repository.repository
|
||||
ADD UNIQUE KEY `key_local` (localPath);
|
||||
57
resources/sql/autopatches/20160503.repo.03.lpathmigrate.php
Normal file
57
resources/sql/autopatches/20160503.repo.03.lpathmigrate.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
$table = new PhabricatorRepository();
|
||||
$conn_w = $table->establishConnection('w');
|
||||
|
||||
$default_path = PhabricatorEnv::getEnvConfig('repository.default-local-path');
|
||||
$default_path = rtrim($default_path, '/');
|
||||
|
||||
foreach (new LiskMigrationIterator($table) as $repository) {
|
||||
$local_path = $repository->getLocalPath();
|
||||
if (strlen($local_path)) {
|
||||
// Repository already has a modern, unique local path.
|
||||
continue;
|
||||
}
|
||||
|
||||
$local_path = $repository->getDetail('local-path');
|
||||
if (!strlen($local_path)) {
|
||||
// Repository does not have a local path using the older format.
|
||||
continue;
|
||||
}
|
||||
|
||||
$random = Filesystem::readRandomCharacters(8);
|
||||
|
||||
// Try the configured path first, then a default path, then a path with some
|
||||
// random noise.
|
||||
$paths = array(
|
||||
$local_path,
|
||||
$default_path.'/'.$repository->getID().'/',
|
||||
$default_path.'/'.$repository->getID().'-'.$random.'/',
|
||||
);
|
||||
|
||||
foreach ($paths as $path) {
|
||||
// Set, then get the path to normalize it.
|
||||
$repository->setLocalPath($path);
|
||||
$path = $repository->getLocalPath();
|
||||
|
||||
try {
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'UPDATE %T SET localPath = %s WHERE id = %d',
|
||||
$table->getTableName(),
|
||||
$path,
|
||||
$repository->getID());
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Assigned repository "%s" to local path "%s".',
|
||||
$repository->getDisplayName(),
|
||||
$path));
|
||||
|
||||
break;
|
||||
} catch (AphrontDuplicateKeyQueryException $ex) {
|
||||
// Ignore, try the next one.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user