Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15496314
D19831.id47356.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Referenced Files
None
Subscribers
None
D19831.id47356.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -950,6 +950,7 @@
'DiffusionRepositoryHistoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryHistoryManagementPanel.php',
'DiffusionRepositoryIdentityEditor' => 'applications/diffusion/editor/DiffusionRepositoryIdentityEditor.php',
'DiffusionRepositoryIdentitySearchEngine' => 'applications/diffusion/query/DiffusionRepositoryIdentitySearchEngine.php',
+ 'DiffusionRepositoryLimitsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php',
'DiffusionRepositoryListController' => 'applications/diffusion/controller/DiffusionRepositoryListController.php',
'DiffusionRepositoryManageController' => 'applications/diffusion/controller/DiffusionRepositoryManageController.php',
'DiffusionRepositoryManagePanelsController' => 'applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php',
@@ -4101,6 +4102,7 @@
'PhabricatorRepositoryCommitRef' => 'applications/repository/engine/PhabricatorRepositoryCommitRef.php',
'PhabricatorRepositoryCommitTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php',
'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.php',
+ 'PhabricatorRepositoryCopyTimeLimitTransaction' => 'applications/repository/xaction/PhabricatorRepositoryCopyTimeLimitTransaction.php',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php',
'PhabricatorRepositoryDangerousTransaction' => 'applications/repository/xaction/PhabricatorRepositoryDangerousTransaction.php',
'PhabricatorRepositoryDefaultBranchTransaction' => 'applications/repository/xaction/PhabricatorRepositoryDefaultBranchTransaction.php',
@@ -4112,6 +4114,7 @@
'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php',
'PhabricatorRepositoryEnormousTransaction' => 'applications/repository/xaction/PhabricatorRepositoryEnormousTransaction.php',
'PhabricatorRepositoryFerretEngine' => 'applications/repository/search/PhabricatorRepositoryFerretEngine.php',
+ 'PhabricatorRepositoryFilesizeLimitTransaction' => 'applications/repository/xaction/PhabricatorRepositoryFilesizeLimitTransaction.php',
'PhabricatorRepositoryFulltextEngine' => 'applications/repository/search/PhabricatorRepositoryFulltextEngine.php',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
@@ -6358,6 +6361,7 @@
'DiffusionRepositoryHistoryManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRepositoryIdentityEditor' => 'PhabricatorApplicationTransactionEditor',
'DiffusionRepositoryIdentitySearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'DiffusionRepositoryLimitsManagementPanel' => 'DiffusionRepositoryManagementPanel',
'DiffusionRepositoryListController' => 'DiffusionController',
'DiffusionRepositoryManageController' => 'DiffusionController',
'DiffusionRepositoryManagePanelsController' => 'DiffusionRepositoryManageController',
@@ -10062,6 +10066,7 @@
'PhabricatorRepositoryCommitRef' => 'Phobject',
'PhabricatorRepositoryCommitTestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions',
+ 'PhabricatorRepositoryCopyTimeLimitTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDangerousTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryDefaultBranchTransaction' => 'PhabricatorRepositoryTransactionType',
@@ -10073,6 +10078,7 @@
'PhabricatorRepositoryEngine' => 'Phobject',
'PhabricatorRepositoryEnormousTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryFerretEngine' => 'PhabricatorFerretEngine',
+ 'PhabricatorRepositoryFilesizeLimitTransaction' => 'PhabricatorRepositoryTransactionType',
'PhabricatorRepositoryFulltextEngine' => 'PhabricatorFulltextEngine',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
diff --git a/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php b/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php
--- a/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php
+++ b/src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php
@@ -472,6 +472,25 @@
pht('Change the push policy of the repository.'))
->setConduitTypeDescription(pht('New policy PHID or constant.'))
->setValue($object->getPolicy(DiffusionPushCapability::CAPABILITY)),
+ id(new PhabricatorTextEditField())
+ ->setKey('filesizeLimit')
+ ->setLabel(pht('Filesize Limit'))
+ ->setTransactionType(
+ PhabricatorRepositoryFilesizeLimitTransaction::TRANSACTIONTYPE)
+ ->setDescription(pht('Maximum permitted file size.'))
+ ->setConduitDescription(pht('Change the filesize limit.'))
+ ->setConduitTypeDescription(pht('New repository filesize limit.'))
+ ->setValue($object->getFilesizeLimit()),
+ id(new PhabricatorTextEditField())
+ ->setKey('copyTimeLimit')
+ ->setLabel(pht('Clone/Fetch Timeout'))
+ ->setTransactionType(
+ PhabricatorRepositoryCopyTimeLimitTransaction::TRANSACTIONTYPE)
+ ->setDescription(
+ pht('Maximum permitted duration of internal clone/fetch.'))
+ ->setConduitDescription(pht('Change the copy time limit.'))
+ ->setConduitTypeDescription(pht('New repository copy time limit.'))
+ ->setValue($object->getCopyTimeLimit()),
);
}
diff --git a/src/applications/diffusion/engine/DiffusionCommitHookEngine.php b/src/applications/diffusion/engine/DiffusionCommitHookEngine.php
--- a/src/applications/diffusion/engine/DiffusionCommitHookEngine.php
+++ b/src/applications/diffusion/engine/DiffusionCommitHookEngine.php
@@ -1268,9 +1268,7 @@
private function rejectOversizedFiles(array $content_updates) {
$repository = $this->getRepository();
- // TODO: Allow repositories to be configured for a maximum filesize.
- $limit = 0;
-
+ $limit = $repository->getFilesizeLimit();
if (!$limit) {
return;
}
diff --git a/src/applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php
@@ -0,0 +1,101 @@
+<?php
+
+final class DiffusionRepositoryLimitsManagementPanel
+ extends DiffusionRepositoryManagementPanel {
+
+ const PANELKEY = 'limits';
+
+ public function getManagementPanelLabel() {
+ return pht('Limits');
+ }
+
+ public function getManagementPanelOrder() {
+ return 700;
+ }
+
+ public function shouldEnableForRepository(
+ PhabricatorRepository $repository) {
+ return $repository->isGit();
+ }
+
+ public function getManagementPanelIcon() {
+ $repository = $this->getRepository();
+
+ $any_limit = false;
+
+ if ($repository->getFilesizeLimit()) {
+ $any_limit = true;
+ }
+
+ if ($any_limit) {
+ return 'fa-signal';
+ } else {
+ return 'fa-signal grey';
+ }
+ }
+
+ protected function getEditEngineFieldKeys() {
+ return array(
+ 'filesizeLimit',
+ 'copyTimeLimit',
+ );
+ }
+
+ public function buildManagementPanelCurtain() {
+ $repository = $this->getRepository();
+ $viewer = $this->getViewer();
+ $action_list = $this->newActionList();
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $repository,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $limits_uri = $this->getEditPageURI();
+
+ $action_list->addAction(
+ id(new PhabricatorActionView())
+ ->setIcon('fa-pencil')
+ ->setName(pht('Edit Limits'))
+ ->setHref($limits_uri)
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit));
+
+ return $this->newCurtainView()
+ ->setActionList($action_list);
+ }
+
+ public function buildManagementPanelContent() {
+ $repository = $this->getRepository();
+ $viewer = $this->getViewer();
+
+ $view = id(new PHUIPropertyListView())
+ ->setViewer($viewer);
+
+ $byte_limit = $repository->getFilesizeLimit();
+ if ($byte_limit) {
+ $filesize_display = pht('%s Bytes', new PhutilNumber($byte_limit));
+ } else {
+ $filesize_display = pht('Unlimited');
+ $filesize_display = phutil_tag('em', array(), $filesize_display);
+ }
+
+ $view->addProperty(pht('Filesize Limit'), $filesize_display);
+
+ $copy_limit = $repository->getCopyTimeLimit();
+ if ($copy_limit) {
+ $copy_display = pht('%s Seconds', new PhutilNumber($copy_limit));
+ } else {
+ $copy_default = $repository->getDefaultCopyTimeLimit();
+ $copy_display = pht(
+ 'Default (%s Seconds)',
+ new PhutilNumber($copy_default));
+ $copy_display = phutil_tag('em', array(), $copy_display);
+ }
+
+ $view->addProperty(pht('Clone/Fetch Timeout'), $copy_display);
+
+ return $this->newBox(pht('Limits'), $view);
+ }
+
+}
diff --git a/src/applications/diffusion/protocol/DiffusionCommandEngine.php b/src/applications/diffusion/protocol/DiffusionCommandEngine.php
--- a/src/applications/diffusion/protocol/DiffusionCommandEngine.php
+++ b/src/applications/diffusion/protocol/DiffusionCommandEngine.php
@@ -139,7 +139,7 @@
// to try to avoid cases where `git fetch` hangs for some reason and we're
// left sitting with a held lock forever.
$repository = $this->getRepository();
- $future->setTimeout($repository->getCopyTimeLimit());
+ $future->setTimeout($repository->getEffectiveCopyTimeLimit());
return $future;
}
diff --git a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
--- a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
+++ b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
@@ -187,7 +187,7 @@
(string)$repository->getCloneURIObject(),
$path);
- $future->setTimeout($repository->getCopyTimeLimit());
+ $future->setTimeout($repository->getEffectiveCopyTimeLimit());
$futures[$directory] = $future;
}
@@ -284,7 +284,7 @@
}
$this->newExecvFuture($interface, $cmd, $arg)
- ->setTimeout($repository->getCopyTimeLimit())
+ ->setTimeout($repository->getEffectiveCopyTimeLimit())
->resolvex();
if (idx($spec, 'default')) {
@@ -310,7 +310,7 @@
try {
$this->newExecvFuture($interface, $cmd, $arg)
- ->setTimeout($repository->getCopyTimeLimit())
+ ->setTimeout($repository->getEffectiveCopyTimeLimit())
->resolvex();
} catch (CommandException $ex) {
$display_command = csprintf(
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -1898,9 +1898,33 @@
* @return int Maximum number of seconds to spend copying this repository.
*/
public function getCopyTimeLimit() {
+ return $this->getDetail('limit.copy');
+ }
+
+ public function setCopyTimeLimit($limit) {
+ return $this->setDetail('limit.copy', $limit);
+ }
+
+ public function getDefaultCopyTimeLimit() {
return phutil_units('15 minutes in seconds');
}
+ public function getEffectiveCopyTimeLimit() {
+ $limit = $this->getCopyTimeLimit();
+ if ($limit) {
+ return $limit;
+ }
+
+ return $this->getDefaultCopyTimeLimit();
+ }
+
+ public function getFilesizeLimit() {
+ return $this->getDetail('limit.filesize');
+ }
+
+ public function setFilesizeLimit($limit) {
+ return $this->setDetail('limit.filesize', $limit);
+ }
/**
* Retrieve the service URI for the device hosting this repository.
diff --git a/src/applications/repository/xaction/PhabricatorRepositoryCopyTimeLimitTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryCopyTimeLimitTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/repository/xaction/PhabricatorRepositoryCopyTimeLimitTransaction.php
@@ -0,0 +1,77 @@
+<?php
+
+final class PhabricatorRepositoryCopyTimeLimitTransaction
+ extends PhabricatorRepositoryTransactionType {
+
+ const TRANSACTIONTYPE = 'limit.copy';
+
+ public function generateOldValue($object) {
+ return $object->getCopyTimeLimit();
+ }
+
+ public function generateNewValue($object, $value) {
+ if (!strlen($value)) {
+ return null;
+ }
+
+ $value = (int)$value;
+ if (!$value) {
+ return null;
+ }
+
+ return $value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setCopyTimeLimit($value);
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ if ($old && $new) {
+ return pht(
+ '%s changed the copy time limit for this repository from %s seconds '.
+ 'to %s seconds.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ } else if ($new) {
+ return pht(
+ '%s set the copy time limit for this repository to %s seconds.',
+ $this->renderAuthor(),
+ $this->renderNewValue());
+ } else {
+ return pht(
+ '%s reset the copy time limit (%s seconds) for this repository '.
+ 'to the default value.',
+ $this->renderAuthor(),
+ $this->renderOldValue());
+ }
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ foreach ($xactions as $xaction) {
+ $new = $xaction->getNewValue();
+
+ if (!strlen($new)) {
+ continue;
+ }
+
+ if (!preg_match('/^\d+\z/', $new)) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'Unable to parse copy time limit, specify a positive number '.
+ 'of seconds.'),
+ $xaction);
+ continue;
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/repository/xaction/PhabricatorRepositoryFilesizeLimitTransaction.php b/src/applications/repository/xaction/PhabricatorRepositoryFilesizeLimitTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/repository/xaction/PhabricatorRepositoryFilesizeLimitTransaction.php
@@ -0,0 +1,78 @@
+<?php
+
+final class PhabricatorRepositoryFilesizeLimitTransaction
+ extends PhabricatorRepositoryTransactionType {
+
+ const TRANSACTIONTYPE = 'limit.filesize';
+
+ public function generateOldValue($object) {
+ return $object->getFilesizeLimit();
+ }
+
+ public function generateNewValue($object, $value) {
+ if (!strlen($value)) {
+ return null;
+ }
+
+ $value = phutil_parse_bytes($value);
+ if (!$value) {
+ return null;
+ }
+
+ return $value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setFilesizeLimit($value);
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ if ($old && $new) {
+ return pht(
+ '%s changed the filesize limit for this repository from %s bytes to '.
+ '%s bytes.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ } else if ($new) {
+ return pht(
+ '%s set the filesize limit for this repository to %s bytes.',
+ $this->renderAuthor(),
+ $this->renderNewValue());
+ } else {
+ return pht(
+ '%s removed the filesize limit (%s bytes) for this repository.',
+ $this->renderAuthor(),
+ $this->renderOldValue());
+ }
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ foreach ($xactions as $xaction) {
+ $new = $xaction->getNewValue();
+
+ if (!strlen($new)) {
+ continue;
+ }
+
+ try {
+ $value = phutil_parse_bytes($new);
+ } catch (Exception $ex) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'Unable to parse filesize limit: %s',
+ $ex->getMessage()),
+ $xaction);
+ continue;
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/docs/user/userguide/diffusion_managing.diviner b/src/docs/user/userguide/diffusion_managing.diviner
--- a/src/docs/user/userguide/diffusion_managing.diviner
+++ b/src/docs/user/userguide/diffusion_managing.diviner
@@ -236,37 +236,20 @@
These options are covered in detail in @{article:Diffusion User Guide: URIs}.
-Staging Area
-============
-
-The **Staging Area** panel configures staging areas, used to make proposed
-changes available to build and continuous integration systems.
-
-For more details, see @{article:Harbormaster User Guide}.
-
-
-Automation
-==========
-
-The **Automation** panel configures support for allowing Phabricator to make
-writes directly to the repository, so that it can perform operations like
-automatically landing revisions from the web UI.
-
-For details on repository automation, see
-@{article:Drydock User Guide: Repository Automation}.
-
-
-Symbols
+Limits
======
-The **Symbols** panel allows you to customize how symbols (like class and
-function names) are linked when viewing code in the repository, and when
-viewing revisions which propose code changes to the repository.
+The **Limits** panel allows you to configure limits and timeouts.
-To take advantage of this feature, you need to do additional work to build
-symbol indexes. For details on configuring and populating symbol indexes, see
-@{article:User Guide: Symbol Indexes}.
+**Filesize Limit**: Allows you to set a maximum filesize for any file in the
+repository. If a commit creates a larger file (or modifies an existing file so
+it becomes too large) it will be rejected. This option only applies to hosted
+repositories.
+**Clone/Fetch Timeout**: Configure the internal timeout for creating copies
+of this repository during operations like intracluster synchronization and
+Drydock working copy construction. This timeout does not affect external
+users.
Branches
========
@@ -311,6 +294,38 @@
discovers new commits, disable **Autoclose** for the repository.
+Staging Area
+============
+
+The **Staging Area** panel configures staging areas, used to make proposed
+changes available to build and continuous integration systems.
+
+For more details, see @{article:Harbormaster User Guide}.
+
+
+Automation
+==========
+
+The **Automation** panel configures support for allowing Phabricator to make
+writes directly to the repository, so that it can perform operations like
+automatically landing revisions from the web UI.
+
+For details on repository automation, see
+@{article:Drydock User Guide: Repository Automation}.
+
+
+Symbols
+======
+
+The **Symbols** panel allows you to customize how symbols (like class and
+function names) are linked when viewing code in the repository, and when
+viewing revisions which propose code changes to the repository.
+
+To take advantage of this feature, you need to do additional work to build
+symbol indexes. For details on configuring and populating symbol indexes, see
+@{article:User Guide: Symbol Indexes}.
+
+
Repository Identifiers and Names
================================
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 14, 6:28 AM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7705605
Default Alt Text
D19831.id47356.diff (19 KB)
Attached To
Mode
D19831: Make the repository "Filesize Limit" and "Clone/Fetch Timeout" configurable in the UI
Attached
Detach File
Event Timeline
Log In to Comment