@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make the repository "Filesize Limit" and "Clone/Fetch Timeout" configurable in the UI

Summary: Depends on D19830. Ref T13216. See PHI908. See PHI750. See PHI885. Allow users to configure a filesize limit, and allow them to adjust the clone/fetch timeout.

Test Plan:
{F6021356}

- Configured a filesize limit and pushed, hit it. Made the limit larger and pushed, change went through.

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: yelirekim, PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13216

Differential Revision: https://secure.phabricator.com/D19831

+352 -34
+6
src/__phutil_library_map__.php
··· 950 950 'DiffusionRepositoryHistoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryHistoryManagementPanel.php', 951 951 'DiffusionRepositoryIdentityEditor' => 'applications/diffusion/editor/DiffusionRepositoryIdentityEditor.php', 952 952 'DiffusionRepositoryIdentitySearchEngine' => 'applications/diffusion/query/DiffusionRepositoryIdentitySearchEngine.php', 953 + 'DiffusionRepositoryLimitsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php', 953 954 'DiffusionRepositoryListController' => 'applications/diffusion/controller/DiffusionRepositoryListController.php', 954 955 'DiffusionRepositoryManageController' => 'applications/diffusion/controller/DiffusionRepositoryManageController.php', 955 956 'DiffusionRepositoryManagePanelsController' => 'applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php', ··· 4104 4105 'PhabricatorRepositoryCommitRef' => 'applications/repository/engine/PhabricatorRepositoryCommitRef.php', 4105 4106 'PhabricatorRepositoryCommitTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryCommitTestCase.php', 4106 4107 'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.php', 4108 + 'PhabricatorRepositoryCopyTimeLimitTransaction' => 'applications/repository/xaction/PhabricatorRepositoryCopyTimeLimitTransaction.php', 4107 4109 'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php', 4108 4110 'PhabricatorRepositoryDangerousTransaction' => 'applications/repository/xaction/PhabricatorRepositoryDangerousTransaction.php', 4109 4111 'PhabricatorRepositoryDefaultBranchTransaction' => 'applications/repository/xaction/PhabricatorRepositoryDefaultBranchTransaction.php', ··· 4115 4117 'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php', 4116 4118 'PhabricatorRepositoryEnormousTransaction' => 'applications/repository/xaction/PhabricatorRepositoryEnormousTransaction.php', 4117 4119 'PhabricatorRepositoryFerretEngine' => 'applications/repository/search/PhabricatorRepositoryFerretEngine.php', 4120 + 'PhabricatorRepositoryFilesizeLimitTransaction' => 'applications/repository/xaction/PhabricatorRepositoryFilesizeLimitTransaction.php', 4118 4121 'PhabricatorRepositoryFulltextEngine' => 'applications/repository/search/PhabricatorRepositoryFulltextEngine.php', 4119 4122 'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php', 4120 4123 'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php', ··· 6361 6364 'DiffusionRepositoryHistoryManagementPanel' => 'DiffusionRepositoryManagementPanel', 6362 6365 'DiffusionRepositoryIdentityEditor' => 'PhabricatorApplicationTransactionEditor', 6363 6366 'DiffusionRepositoryIdentitySearchEngine' => 'PhabricatorApplicationSearchEngine', 6367 + 'DiffusionRepositoryLimitsManagementPanel' => 'DiffusionRepositoryManagementPanel', 6364 6368 'DiffusionRepositoryListController' => 'DiffusionController', 6365 6369 'DiffusionRepositoryManageController' => 'DiffusionController', 6366 6370 'DiffusionRepositoryManagePanelsController' => 'DiffusionRepositoryManageController', ··· 10070 10074 'PhabricatorRepositoryCommitRef' => 'Phobject', 10071 10075 'PhabricatorRepositoryCommitTestCase' => 'PhabricatorTestCase', 10072 10076 'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions', 10077 + 'PhabricatorRepositoryCopyTimeLimitTransaction' => 'PhabricatorRepositoryTransactionType', 10073 10078 'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO', 10074 10079 'PhabricatorRepositoryDangerousTransaction' => 'PhabricatorRepositoryTransactionType', 10075 10080 'PhabricatorRepositoryDefaultBranchTransaction' => 'PhabricatorRepositoryTransactionType', ··· 10081 10086 'PhabricatorRepositoryEngine' => 'Phobject', 10082 10087 'PhabricatorRepositoryEnormousTransaction' => 'PhabricatorRepositoryTransactionType', 10083 10088 'PhabricatorRepositoryFerretEngine' => 'PhabricatorFerretEngine', 10089 + 'PhabricatorRepositoryFilesizeLimitTransaction' => 'PhabricatorRepositoryTransactionType', 10084 10090 'PhabricatorRepositoryFulltextEngine' => 'PhabricatorFulltextEngine', 10085 10091 'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker', 10086 10092 'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
+19
src/applications/diffusion/editor/DiffusionRepositoryEditEngine.php
··· 472 472 pht('Change the push policy of the repository.')) 473 473 ->setConduitTypeDescription(pht('New policy PHID or constant.')) 474 474 ->setValue($object->getPolicy(DiffusionPushCapability::CAPABILITY)), 475 + id(new PhabricatorTextEditField()) 476 + ->setKey('filesizeLimit') 477 + ->setLabel(pht('Filesize Limit')) 478 + ->setTransactionType( 479 + PhabricatorRepositoryFilesizeLimitTransaction::TRANSACTIONTYPE) 480 + ->setDescription(pht('Maximum permitted file size.')) 481 + ->setConduitDescription(pht('Change the filesize limit.')) 482 + ->setConduitTypeDescription(pht('New repository filesize limit.')) 483 + ->setValue($object->getFilesizeLimit()), 484 + id(new PhabricatorTextEditField()) 485 + ->setKey('copyTimeLimit') 486 + ->setLabel(pht('Clone/Fetch Timeout')) 487 + ->setTransactionType( 488 + PhabricatorRepositoryCopyTimeLimitTransaction::TRANSACTIONTYPE) 489 + ->setDescription( 490 + pht('Maximum permitted duration of internal clone/fetch.')) 491 + ->setConduitDescription(pht('Change the copy time limit.')) 492 + ->setConduitTypeDescription(pht('New repository copy time limit.')) 493 + ->setValue($object->getCopyTimeLimit()), 475 494 ); 476 495 } 477 496
+1 -3
src/applications/diffusion/engine/DiffusionCommitHookEngine.php
··· 1268 1268 private function rejectOversizedFiles(array $content_updates) { 1269 1269 $repository = $this->getRepository(); 1270 1270 1271 - // TODO: Allow repositories to be configured for a maximum filesize. 1272 - $limit = 0; 1273 - 1271 + $limit = $repository->getFilesizeLimit(); 1274 1272 if (!$limit) { 1275 1273 return; 1276 1274 }
+101
src/applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php
··· 1 + <?php 2 + 3 + final class DiffusionRepositoryLimitsManagementPanel 4 + extends DiffusionRepositoryManagementPanel { 5 + 6 + const PANELKEY = 'limits'; 7 + 8 + public function getManagementPanelLabel() { 9 + return pht('Limits'); 10 + } 11 + 12 + public function getManagementPanelOrder() { 13 + return 700; 14 + } 15 + 16 + public function shouldEnableForRepository( 17 + PhabricatorRepository $repository) { 18 + return $repository->isGit(); 19 + } 20 + 21 + public function getManagementPanelIcon() { 22 + $repository = $this->getRepository(); 23 + 24 + $any_limit = false; 25 + 26 + if ($repository->getFilesizeLimit()) { 27 + $any_limit = true; 28 + } 29 + 30 + if ($any_limit) { 31 + return 'fa-signal'; 32 + } else { 33 + return 'fa-signal grey'; 34 + } 35 + } 36 + 37 + protected function getEditEngineFieldKeys() { 38 + return array( 39 + 'filesizeLimit', 40 + 'copyTimeLimit', 41 + ); 42 + } 43 + 44 + public function buildManagementPanelCurtain() { 45 + $repository = $this->getRepository(); 46 + $viewer = $this->getViewer(); 47 + $action_list = $this->newActionList(); 48 + 49 + $can_edit = PhabricatorPolicyFilter::hasCapability( 50 + $viewer, 51 + $repository, 52 + PhabricatorPolicyCapability::CAN_EDIT); 53 + 54 + $limits_uri = $this->getEditPageURI(); 55 + 56 + $action_list->addAction( 57 + id(new PhabricatorActionView()) 58 + ->setIcon('fa-pencil') 59 + ->setName(pht('Edit Limits')) 60 + ->setHref($limits_uri) 61 + ->setDisabled(!$can_edit) 62 + ->setWorkflow(!$can_edit)); 63 + 64 + return $this->newCurtainView() 65 + ->setActionList($action_list); 66 + } 67 + 68 + public function buildManagementPanelContent() { 69 + $repository = $this->getRepository(); 70 + $viewer = $this->getViewer(); 71 + 72 + $view = id(new PHUIPropertyListView()) 73 + ->setViewer($viewer); 74 + 75 + $byte_limit = $repository->getFilesizeLimit(); 76 + if ($byte_limit) { 77 + $filesize_display = pht('%s Bytes', new PhutilNumber($byte_limit)); 78 + } else { 79 + $filesize_display = pht('Unlimited'); 80 + $filesize_display = phutil_tag('em', array(), $filesize_display); 81 + } 82 + 83 + $view->addProperty(pht('Filesize Limit'), $filesize_display); 84 + 85 + $copy_limit = $repository->getCopyTimeLimit(); 86 + if ($copy_limit) { 87 + $copy_display = pht('%s Seconds', new PhutilNumber($copy_limit)); 88 + } else { 89 + $copy_default = $repository->getDefaultCopyTimeLimit(); 90 + $copy_display = pht( 91 + 'Default (%s Seconds)', 92 + new PhutilNumber($copy_default)); 93 + $copy_display = phutil_tag('em', array(), $copy_display); 94 + } 95 + 96 + $view->addProperty(pht('Clone/Fetch Timeout'), $copy_display); 97 + 98 + return $this->newBox(pht('Limits'), $view); 99 + } 100 + 101 + }
+1 -1
src/applications/diffusion/protocol/DiffusionCommandEngine.php
··· 139 139 // to try to avoid cases where `git fetch` hangs for some reason and we're 140 140 // left sitting with a held lock forever. 141 141 $repository = $this->getRepository(); 142 - $future->setTimeout($repository->getCopyTimeLimit()); 142 + $future->setTimeout($repository->getEffectiveCopyTimeLimit()); 143 143 144 144 return $future; 145 145 }
+3 -3
src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
··· 187 187 (string)$repository->getCloneURIObject(), 188 188 $path); 189 189 190 - $future->setTimeout($repository->getCopyTimeLimit()); 190 + $future->setTimeout($repository->getEffectiveCopyTimeLimit()); 191 191 192 192 $futures[$directory] = $future; 193 193 } ··· 284 284 } 285 285 286 286 $this->newExecvFuture($interface, $cmd, $arg) 287 - ->setTimeout($repository->getCopyTimeLimit()) 287 + ->setTimeout($repository->getEffectiveCopyTimeLimit()) 288 288 ->resolvex(); 289 289 290 290 if (idx($spec, 'default')) { ··· 310 310 311 311 try { 312 312 $this->newExecvFuture($interface, $cmd, $arg) 313 - ->setTimeout($repository->getCopyTimeLimit()) 313 + ->setTimeout($repository->getEffectiveCopyTimeLimit()) 314 314 ->resolvex(); 315 315 } catch (CommandException $ex) { 316 316 $display_command = csprintf(
+24
src/applications/repository/storage/PhabricatorRepository.php
··· 1898 1898 * @return int Maximum number of seconds to spend copying this repository. 1899 1899 */ 1900 1900 public function getCopyTimeLimit() { 1901 + return $this->getDetail('limit.copy'); 1902 + } 1903 + 1904 + public function setCopyTimeLimit($limit) { 1905 + return $this->setDetail('limit.copy', $limit); 1906 + } 1907 + 1908 + public function getDefaultCopyTimeLimit() { 1901 1909 return phutil_units('15 minutes in seconds'); 1902 1910 } 1903 1911 1912 + public function getEffectiveCopyTimeLimit() { 1913 + $limit = $this->getCopyTimeLimit(); 1914 + if ($limit) { 1915 + return $limit; 1916 + } 1917 + 1918 + return $this->getDefaultCopyTimeLimit(); 1919 + } 1920 + 1921 + public function getFilesizeLimit() { 1922 + return $this->getDetail('limit.filesize'); 1923 + } 1924 + 1925 + public function setFilesizeLimit($limit) { 1926 + return $this->setDetail('limit.filesize', $limit); 1927 + } 1904 1928 1905 1929 /** 1906 1930 * Retrieve the service URI for the device hosting this repository.
+77
src/applications/repository/xaction/PhabricatorRepositoryCopyTimeLimitTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorRepositoryCopyTimeLimitTransaction 4 + extends PhabricatorRepositoryTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'limit.copy'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getCopyTimeLimit(); 10 + } 11 + 12 + public function generateNewValue($object, $value) { 13 + if (!strlen($value)) { 14 + return null; 15 + } 16 + 17 + $value = (int)$value; 18 + if (!$value) { 19 + return null; 20 + } 21 + 22 + return $value; 23 + } 24 + 25 + public function applyInternalEffects($object, $value) { 26 + $object->setCopyTimeLimit($value); 27 + } 28 + 29 + public function getTitle() { 30 + $old = $this->getOldValue(); 31 + $new = $this->getNewValue(); 32 + 33 + if ($old && $new) { 34 + return pht( 35 + '%s changed the copy time limit for this repository from %s seconds '. 36 + 'to %s seconds.', 37 + $this->renderAuthor(), 38 + $this->renderOldValue(), 39 + $this->renderNewValue()); 40 + } else if ($new) { 41 + return pht( 42 + '%s set the copy time limit for this repository to %s seconds.', 43 + $this->renderAuthor(), 44 + $this->renderNewValue()); 45 + } else { 46 + return pht( 47 + '%s reset the copy time limit (%s seconds) for this repository '. 48 + 'to the default value.', 49 + $this->renderAuthor(), 50 + $this->renderOldValue()); 51 + } 52 + } 53 + 54 + public function validateTransactions($object, array $xactions) { 55 + $errors = array(); 56 + 57 + foreach ($xactions as $xaction) { 58 + $new = $xaction->getNewValue(); 59 + 60 + if (!strlen($new)) { 61 + continue; 62 + } 63 + 64 + if (!preg_match('/^\d+\z/', $new)) { 65 + $errors[] = $this->newInvalidError( 66 + pht( 67 + 'Unable to parse copy time limit, specify a positive number '. 68 + 'of seconds.'), 69 + $xaction); 70 + continue; 71 + } 72 + } 73 + 74 + return $errors; 75 + } 76 + 77 + }
+78
src/applications/repository/xaction/PhabricatorRepositoryFilesizeLimitTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorRepositoryFilesizeLimitTransaction 4 + extends PhabricatorRepositoryTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'limit.filesize'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getFilesizeLimit(); 10 + } 11 + 12 + public function generateNewValue($object, $value) { 13 + if (!strlen($value)) { 14 + return null; 15 + } 16 + 17 + $value = phutil_parse_bytes($value); 18 + if (!$value) { 19 + return null; 20 + } 21 + 22 + return $value; 23 + } 24 + 25 + public function applyInternalEffects($object, $value) { 26 + $object->setFilesizeLimit($value); 27 + } 28 + 29 + public function getTitle() { 30 + $old = $this->getOldValue(); 31 + $new = $this->getNewValue(); 32 + 33 + if ($old && $new) { 34 + return pht( 35 + '%s changed the filesize limit for this repository from %s bytes to '. 36 + '%s bytes.', 37 + $this->renderAuthor(), 38 + $this->renderOldValue(), 39 + $this->renderNewValue()); 40 + } else if ($new) { 41 + return pht( 42 + '%s set the filesize limit for this repository to %s bytes.', 43 + $this->renderAuthor(), 44 + $this->renderNewValue()); 45 + } else { 46 + return pht( 47 + '%s removed the filesize limit (%s bytes) for this repository.', 48 + $this->renderAuthor(), 49 + $this->renderOldValue()); 50 + } 51 + } 52 + 53 + public function validateTransactions($object, array $xactions) { 54 + $errors = array(); 55 + 56 + foreach ($xactions as $xaction) { 57 + $new = $xaction->getNewValue(); 58 + 59 + if (!strlen($new)) { 60 + continue; 61 + } 62 + 63 + try { 64 + $value = phutil_parse_bytes($new); 65 + } catch (Exception $ex) { 66 + $errors[] = $this->newInvalidError( 67 + pht( 68 + 'Unable to parse filesize limit: %s', 69 + $ex->getMessage()), 70 + $xaction); 71 + continue; 72 + } 73 + } 74 + 75 + return $errors; 76 + } 77 + 78 + }
+42 -27
src/docs/user/userguide/diffusion_managing.diviner
··· 236 236 These options are covered in detail in @{article:Diffusion User Guide: URIs}. 237 237 238 238 239 - Staging Area 240 - ============ 241 - 242 - The **Staging Area** panel configures staging areas, used to make proposed 243 - changes available to build and continuous integration systems. 244 - 245 - For more details, see @{article:Harbormaster User Guide}. 246 - 247 - 248 - Automation 249 - ========== 250 - 251 - The **Automation** panel configures support for allowing Phabricator to make 252 - writes directly to the repository, so that it can perform operations like 253 - automatically landing revisions from the web UI. 254 - 255 - For details on repository automation, see 256 - @{article:Drydock User Guide: Repository Automation}. 257 - 258 - 259 - Symbols 239 + Limits 260 240 ====== 261 241 262 - The **Symbols** panel allows you to customize how symbols (like class and 263 - function names) are linked when viewing code in the repository, and when 264 - viewing revisions which propose code changes to the repository. 242 + The **Limits** panel allows you to configure limits and timeouts. 265 243 266 - To take advantage of this feature, you need to do additional work to build 267 - symbol indexes. For details on configuring and populating symbol indexes, see 268 - @{article:User Guide: Symbol Indexes}. 244 + **Filesize Limit**: Allows you to set a maximum filesize for any file in the 245 + repository. If a commit creates a larger file (or modifies an existing file so 246 + it becomes too large) it will be rejected. This option only applies to hosted 247 + repositories. 269 248 249 + **Clone/Fetch Timeout**: Configure the internal timeout for creating copies 250 + of this repository during operations like intracluster synchronization and 251 + Drydock working copy construction. This timeout does not affect external 252 + users. 270 253 271 254 Branches 272 255 ======== ··· 309 292 When Phabricator discovers a new commit, it can automatically close associated 310 293 revisions and tasks. If you don't want Phabricator to close objects when it 311 294 discovers new commits, disable **Autoclose** for the repository. 295 + 296 + 297 + Staging Area 298 + ============ 299 + 300 + The **Staging Area** panel configures staging areas, used to make proposed 301 + changes available to build and continuous integration systems. 302 + 303 + For more details, see @{article:Harbormaster User Guide}. 304 + 305 + 306 + Automation 307 + ========== 308 + 309 + The **Automation** panel configures support for allowing Phabricator to make 310 + writes directly to the repository, so that it can perform operations like 311 + automatically landing revisions from the web UI. 312 + 313 + For details on repository automation, see 314 + @{article:Drydock User Guide: Repository Automation}. 315 + 316 + 317 + Symbols 318 + ====== 319 + 320 + The **Symbols** panel allows you to customize how symbols (like class and 321 + function names) are linked when viewing code in the repository, and when 322 + viewing revisions which propose code changes to the repository. 323 + 324 + To take advantage of this feature, you need to do additional work to build 325 + symbol indexes. For details on configuring and populating symbol indexes, see 326 + @{article:User Guide: Symbol Indexes}. 312 327 313 328 314 329 Repository Identifiers and Names