Path: blob/master/src/applications/diffusion/management/DiffusionRepositoryStorageManagementPanel.php
13395 views
<?php12final class DiffusionRepositoryStorageManagementPanel3extends DiffusionRepositoryManagementPanel {45const PANELKEY = 'storage';67public function getManagementPanelLabel() {8return pht('Storage');9}1011public function getManagementPanelOrder() {12return 600;13}1415public function getManagementPanelIcon() {16$repository = $this->getRepository();1718if ($repository->getAlmanacServicePHID()) {19return 'fa-sitemap';20} else if ($repository->isHosted()) {21return 'fa-database';22} else {23return 'fa-download';24}25}2627public function buildManagementPanelCurtain() {28$repository = $this->getRepository();29$viewer = $this->getViewer();30$action_list = $this->newActionList();3132$doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories');3334$action_list->addAction(35id(new PhabricatorActionView())36->setIcon('fa-book')37->setHref($doc_href)38->setName(pht('Cluster Documentation')));3940return $this->newCurtainView()41->setActionList($action_list);42}4344public function buildManagementPanelContent() {45return array(46$this->buildStorageStatusPanel(),47$this->buildClusterStatusPanel(),48$this->buildRefsStatusPanels(),49);50}5152private function buildStorageStatusPanel() {53$repository = $this->getRepository();54$viewer = $this->getViewer();5556$view = id(new PHUIPropertyListView())57->setViewer($viewer);5859if ($repository->usesLocalWorkingCopy()) {60$storage_path = $repository->getLocalPath();61} else {62$storage_path = phutil_tag('em', array(), pht('No Local Working Copy'));63}6465$service_phid = $repository->getAlmanacServicePHID();66if ($service_phid) {67$storage_service = $viewer->renderHandle($service_phid);68} else {69$storage_service = phutil_tag('em', array(), pht('Local'));70}7172$view->addProperty(pht('Storage Path'), $storage_path);73$view->addProperty(pht('Storage Cluster'), $storage_service);7475return $this->newBox(pht('Storage'), $view);76}7778private function buildClusterStatusPanel() {79$repository = $this->getRepository();80$viewer = $this->getViewer();8182$service_phid = $repository->getAlmanacServicePHID();83if ($service_phid) {84$service = id(new AlmanacServiceQuery())85->setViewer($viewer)86->withServiceTypes(87array(88AlmanacClusterRepositoryServiceType::SERVICETYPE,89))90->withPHIDs(array($service_phid))91->needActiveBindings(true)92->executeOne();93if (!$service) {94// TODO: Viewer may not have permission to see the service, or it may95// be invalid? Raise some more useful error here?96throw new Exception(pht('Unable to load cluster service.'));97}98} else {99$service = null;100}101102Javelin::initBehavior('phabricator-tooltips');103104$rows = array();105if ($service) {106$bindings = $service->getActiveBindings();107$bindings = mgroup($bindings, 'getDevicePHID');108109// This is an unusual read which always comes from the master.110if (PhabricatorEnv::isReadOnly()) {111$versions = array();112} else {113$versions = PhabricatorRepositoryWorkingCopyVersion::loadVersions(114$repository->getPHID());115}116117$versions = mpull($versions, null, 'getDevicePHID');118119$sort = array();120foreach ($bindings as $key => $binding_group) {121$sort[$key] = id(new PhutilSortVector())122->addString(head($binding_group)->getDevice()->getName());123}124$sort = msortv($sort, 'getSelf');125$bindings = array_select_keys($bindings, array_keys($sort)) + $bindings;126127foreach ($bindings as $binding_group) {128$any_binding = head($binding_group);129130$binding_icon = 'fa-folder-open green';131$binding_tip = pht('Active');132133$binding_icon = id(new PHUIIconView())134->setIcon($binding_icon)135->addSigil('has-tooltip')136->setMetadata(137array(138'tip' => $binding_tip,139));140141$device = $any_binding->getDevice();142143$version = idx($versions, $device->getPHID());144if ($version) {145$version_number = $version->getRepositoryVersion();146147$href = null;148if ($repository->isHosted()) {149$href = "/diffusion/pushlog/view/{$version_number}/";150} else {151$commit = id(new DiffusionCommitQuery())152->setViewer($viewer)153->withIDs(array($version_number))154->executeOne();155if ($commit) {156$href = $commit->getURI();157}158}159160if ($href) {161$version_number = phutil_tag(162'a',163array(164'href' => $href,165),166$version_number);167}168} else {169$version_number = '-';170}171172if ($version && $version->getIsWriting()) {173$is_writing = id(new PHUIIconView())174->setIcon('fa-pencil green');175} else {176$is_writing = id(new PHUIIconView())177->setIcon('fa-pencil grey');178}179180$write_properties = null;181if ($version) {182$write_properties = $version->getWriteProperties();183if ($write_properties) {184try {185$write_properties = phutil_json_decode($write_properties);186} catch (Exception $ex) {187$write_properties = null;188}189}190}191192$last_writer = null;193$writer_epoch = null;194if ($write_properties) {195$writer_phid = idx($write_properties, 'userPHID');196197if ($writer_phid) {198$last_writer = $viewer->renderHandle($writer_phid);199}200201$writer_epoch = idx($write_properties, 'epoch');202if ($writer_epoch) {203$writer_epoch = phabricator_datetime($writer_epoch, $viewer);204}205}206207$rows[] = array(208$binding_icon,209phutil_tag(210'a',211array(212'href' => $device->getURI(),213),214$device->getName()),215$version_number,216$is_writing,217$last_writer,218$writer_epoch,219);220}221}222223$table = id(new AphrontTableView($rows))224->setNoDataString(pht('This is not a cluster repository.'))225->setHeaders(226array(227null,228pht('Device'),229pht('Version'),230pht('Writing'),231pht('Last Writer'),232pht('Last Write At'),233))234->setColumnClasses(235array(236null,237null,238null,239'right wide',240null,241'date',242));243244return $this->newBox(pht('Cluster Status'), $table);245}246247private function buildRefsStatusPanels() {248$repository = $this->getRepository();249250$service_phid = $repository->getAlmanacServicePHID();251if (!$service_phid) {252// If this repository isn't clustered, don't bother rendering anything.253// There are enough other context clues that another empty panel isn't254// useful.255return;256}257258$all_protocols = array(259'http',260'https',261'ssh',262);263264$readable_panel = $this->buildRefsStatusPanel(265pht('Readable Service Refs'),266array(267'neverProxy' => false,268'protocols' => $all_protocols,269'writable' => false,270));271272$writable_panel = $this->buildRefsStatusPanel(273pht('Writable Service Refs'),274array(275'neverProxy' => false,276'protocols' => $all_protocols,277'writable' => true,278));279280return array(281$readable_panel,282$writable_panel,283);284}285286private function buildRefsStatusPanel(287$title,288$options) {289290$repository = $this->getRepository();291$viewer = $this->getViewer();292293$caught = null;294try {295$refs = $repository->getAlmanacServiceRefs($viewer, $options);296} catch (Exception $ex) {297$caught = $ex;298} catch (Throwable $ex) {299$caught = $ex;300}301302$info_view = null;303if ($caught) {304$refs = array();305$info_view = id(new PHUIInfoView())306->setErrors(307array(308phutil_escape_html_newlines($caught->getMessage()),309));310}311312$phids = array();313foreach ($refs as $ref) {314$phids[] = $ref->getDevicePHID();315}316317$handles = $viewer->loadHandles($phids);318319$icon_writable = id(new PHUIIconView())320->setIcon('fa-pencil', 'green');321322$icon_unwritable = id(new PHUIIconView())323->setIcon('fa-times', 'grey');324325$rows = array();326foreach ($refs as $ref) {327$device_phid = $ref->getDevicePHID();328$device_handle = $handles[$device_phid];329330if ($ref->isWritable()) {331$writable_icon = $icon_writable;332$writable_text = pht('Read/Write');333} else {334$writable_icon = $icon_unwritable;335$writable_text = pht('Read Only');336}337338$rows[] = array(339$device_handle->renderLink(),340$ref->getURI(),341$writable_icon,342$writable_text,343);344}345346$table = id(new AphrontTableView($rows))347->setNoDataString(pht('No repository service refs available.'))348->setHeaders(349array(350pht('Device'),351pht('Internal Service URI'),352null,353pht('I/O'),354))355->setColumnClasses(356array(357null,358'wide',359'icon',360null,361));362363$box_view = $this->newBox($title, $table);364365if ($info_view) {366$box_view->setInfoView($info_view);367}368369return $box_view;370}371372}373374375