Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/harbormaster/management/HarbormasterManagementArchiveLogsWorkflow.php
12256 views
1
<?php
2
3
final class HarbormasterManagementArchiveLogsWorkflow
4
extends HarbormasterManagementWorkflow {
5
6
protected function didConstruct() {
7
$this
8
->setName('archive-logs')
9
->setExamples('**archive-logs** [__options__] --mode __mode__')
10
->setSynopsis(pht('Compress, decompress, store or destroy build logs.'))
11
->setArguments(
12
array(
13
array(
14
'name' => 'mode',
15
'param' => 'mode',
16
'help' => pht(
17
'Use "plain" to remove encoding, or "compress" to compress '.
18
'logs.'),
19
),
20
array(
21
'name' => 'details',
22
'help' => pht(
23
'Show more details about operations as they are performed. '.
24
'Slow! But also very reassuring!'),
25
),
26
));
27
}
28
29
public function execute(PhutilArgumentParser $args) {
30
$viewer = $this->getViewer();
31
32
$mode = $args->getArg('mode');
33
if (!$mode) {
34
throw new PhutilArgumentUsageException(
35
pht('Choose an archival mode with --mode.'));
36
}
37
38
$valid_modes = array(
39
'plain',
40
'compress',
41
);
42
43
$valid_modes = array_fuse($valid_modes);
44
if (empty($valid_modes[$mode])) {
45
throw new PhutilArgumentUsageException(
46
pht(
47
'Unknown mode "%s". Valid modes are: %s.',
48
$mode,
49
implode(', ', $valid_modes)));
50
}
51
52
$log_table = new HarbormasterBuildLog();
53
$logs = new LiskMigrationIterator($log_table);
54
55
$show_details = $args->getArg('details');
56
57
if ($show_details) {
58
$total_old = 0;
59
$total_new = 0;
60
}
61
62
foreach ($logs as $log) {
63
echo tsprintf(
64
"%s\n",
65
pht('Processing Harbormaster build log #%d...', $log->getID()));
66
67
if ($show_details) {
68
$old_stats = $this->computeDetails($log);
69
}
70
71
switch ($mode) {
72
case 'plain':
73
$log->decompressLog();
74
break;
75
case 'compress':
76
$log->compressLog();
77
break;
78
}
79
80
if ($show_details) {
81
$new_stats = $this->computeDetails($log);
82
$this->printStats($old_stats, $new_stats);
83
84
$total_old += $old_stats['bytes'];
85
$total_new += $new_stats['bytes'];
86
}
87
}
88
89
if ($show_details) {
90
echo tsprintf(
91
"%s\n",
92
pht(
93
'Done. Total byte size of affected logs: %s -> %s.',
94
new PhutilNumber($total_old),
95
new PhutilNumber($total_new)));
96
}
97
98
return 0;
99
}
100
101
private function computeDetails(HarbormasterBuildLog $log) {
102
$bytes = 0;
103
$chunks = 0;
104
$hash = hash_init('sha1');
105
106
foreach ($log->newChunkIterator() as $chunk) {
107
$bytes += strlen($chunk->getChunk());
108
$chunks++;
109
hash_update($hash, $chunk->getChunkDisplayText());
110
}
111
112
return array(
113
'bytes' => $bytes,
114
'chunks' => $chunks,
115
'hash' => hash_final($hash),
116
);
117
}
118
119
private function printStats(array $old_stats, array $new_stats) {
120
echo tsprintf(
121
" %s\n",
122
pht(
123
'%s: %s -> %s',
124
pht('Stored Bytes'),
125
new PhutilNumber($old_stats['bytes']),
126
new PhutilNumber($new_stats['bytes'])));
127
128
echo tsprintf(
129
" %s\n",
130
pht(
131
'%s: %s -> %s',
132
pht('Stored Chunks'),
133
new PhutilNumber($old_stats['chunks']),
134
new PhutilNumber($new_stats['chunks'])));
135
136
echo tsprintf(
137
" %s\n",
138
pht(
139
'%s: %s -> %s',
140
pht('Data Hash'),
141
$old_stats['hash'],
142
$new_stats['hash']));
143
144
if ($old_stats['hash'] !== $new_stats['hash']) {
145
throw new Exception(
146
pht('Log data hashes differ! Something is tragically wrong!'));
147
}
148
}
149
150
}
151
152