Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 56 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
MigrateCentralWiki | |
0.00% |
0 / 50 |
|
0.00% |
0 / 2 |
90 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 41 |
|
0.00% |
0 / 1 |
72 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\OAuth; |
4 | |
5 | /** |
6 | * Migrate oauth_registered_consumer and oauth_accepted_consumer tables to a |
7 | * new database with minimal downtime. This script assumes relatively small tables |
8 | * (The WMF has <100 consumers and aout 1000 authorizations right now). |
9 | * |
10 | * To migrate to a new central wiki within your cluster, you roughly want to: |
11 | * 1. Set $wgMWOAuthReadOnly = true for all wikis in your running config |
12 | * 2. Move the oauth_registered_consumer and oauth_accepted_consumer tables with this script |
13 | * 3. Update the cluster config to point to the new central wiki |
14 | * 4. Set $wgMWOAuthReadOnly back to false, so users can manage their consumers as normal. |
15 | * 5. Migrate the OAuth logs using importCentralWikiLogs.php. |
16 | * 6. Done! |
17 | * |
18 | * @ingroup Maintenance |
19 | */ |
20 | if ( getenv( 'MW_INSTALL_PATH' ) ) { |
21 | $IP = getenv( 'MW_INSTALL_PATH' ); |
22 | } else { |
23 | $IP = __DIR__ . '/../../..'; |
24 | } |
25 | |
26 | require_once "$IP/maintenance/Maintenance.php"; |
27 | |
28 | use MediaWiki\Extension\OAuth\Backend\Consumer; |
29 | use MediaWiki\Extension\OAuth\Backend\ConsumerAcceptance; |
30 | use MediaWiki\Extension\OAuth\Backend\MWOAuthDAO; |
31 | use MediaWiki\Maintenance\Maintenance; |
32 | use MediaWiki\MediaWikiServices; |
33 | |
34 | class MigrateCentralWiki extends Maintenance { |
35 | public function __construct() { |
36 | parent::__construct(); |
37 | $this->addDescription( "Migrate central wiki from one wiki to another. " . |
38 | "OAuth should be in Read Only mode while this is running." ); |
39 | $this->addOption( 'old', 'Previous central wiki', true, true ); |
40 | $this->addOption( 'target', 'New central wiki', true, true ); |
41 | $this->addOption( 'table', |
42 | 'Table name (oauth_registered_consumer or oauth_accepted_consumer)', true, true ); |
43 | $this->setBatchSize( 200 ); |
44 | $this->requireExtension( "OAuth" ); |
45 | } |
46 | |
47 | public function execute() { |
48 | $oldWiki = $this->getOption( 'old' ); |
49 | $targetWiki = $this->getOption( 'target' ); |
50 | $table = $this->getOption( 'table' ); |
51 | |
52 | if ( $table === 'oauth_registered_consumer' ) { |
53 | $idKey = 'oarc_id'; |
54 | $cmrClass = Consumer::class; |
55 | $type = 'consumer'; |
56 | } elseif ( $table === 'oauth_accepted_consumer' ) { |
57 | $idKey = 'oaac_id'; |
58 | $cmrClass = ConsumerAcceptance::class; |
59 | $type = 'grant'; |
60 | } else { |
61 | $this->fatalError( "Invalid table name. Must be one of 'oauth_registered_consumer' " . |
62 | "or 'oauth_accepted_consumer'.\n" ); |
63 | } |
64 | |
65 | $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); |
66 | $oldDb = $lbFactory->getMainLB( $oldWiki )->getConnection( DB_PRIMARY, [], $oldWiki ); |
67 | $targetDb = $lbFactory->getMainLB( $targetWiki ) |
68 | ->getConnection( DB_PRIMARY, [], $targetWiki ); |
69 | |
70 | $newMax = $targetDb->newSelectQueryBuilder() |
71 | ->select( "MAX($idKey)" ) |
72 | ->from( $table ) |
73 | ->caller( __METHOD__ ) |
74 | ->fetchField(); |
75 | |
76 | $oldMax = $oldDb->newSelectQueryBuilder() |
77 | ->select( "MAX($idKey)" ) |
78 | ->from( $table ) |
79 | ->caller( __METHOD__ ) |
80 | ->fetchField(); |
81 | |
82 | if ( $newMax >= $oldMax ) { |
83 | $this->output( "No new rows.\n" ); |
84 | } |
85 | |
86 | $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); |
87 | |
88 | for ( $currentId = $newMax + 1, $i = 1; $currentId <= $oldMax; ++$currentId, ++$i ) { |
89 | $this->output( "Migrating $type $currentId..." ); |
90 | /** @var MWOAuthDAO $cmrClass */ |
91 | $cmr = $cmrClass::newFromId( $oldDb, $currentId ); |
92 | if ( $cmr ) { |
93 | $cmr->updateOrigin( 'new' ); |
94 | $cmr->setPending( true ); |
95 | $cmr->save( $targetDb ); |
96 | $this->output( "done.\n" ); |
97 | } else { |
98 | $this->output( "missing.\n" ); |
99 | } |
100 | |
101 | if ( $this->mBatchSize && $i % $this->mBatchSize === 0 ) { |
102 | $lbFactory->waitForReplication( [ 'domain' => $targetWiki ] ); |
103 | } |
104 | } |
105 | } |
106 | |
107 | } |
108 | |
109 | $maintClass = MigrateCentralWiki::class; |
110 | require_once RUN_MAINTENANCE_IF_MAIN; |