Skip to content

Commit

Permalink
Canasta 2.0 adding wiki farm support (#295)
Browse files Browse the repository at this point in the history
Canasta 2.0 adding wiki farm support
  • Loading branch information
chl178 authored Sep 29, 2023
1 parent 61ffc09 commit bf3a6f5
Show file tree
Hide file tree
Showing 11 changed files with 574 additions and 31 deletions.
12 changes: 9 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ RUN set x; \
php7.4-gd \
php7.4-mbstring \
php7.4-xml \
php7.4-mysql \
php7.4-intl \
php7.4-opcache \
php7.4-apcu \
php7.4-redis \
php7.4-curl \
php7.4-zip \
php7.4-fpm \
php7.4-yaml \
libapache2-mod-fcgid \
&& aptitude clean \
&& rm -rf /var/lib/apt/lists/*
Expand Down Expand Up @@ -663,11 +665,11 @@ RUN set -x; \
# Generate sample files for installing extensions and skins in LocalSettings.php
RUN set -x; \
cd $MW_HOME/extensions \
&& for i in $(ls -d */); do echo "#wfLoadExtension('${i%%/}');"; done > $MW_ORIGIN_FILES/installedExtensions.txt \
&& for i in $(ls -d */); do echo "#wfLoadExtension('${i%%/}');"; done > $MW_ORIGIN_FILES/installedExtensions.txt \
# Dirty hack for Semantic MediaWiki
&& sed -i "s/#wfLoadExtension('SemanticMediaWiki');/#enableSemantics('localhost');/g" $MW_ORIGIN_FILES/installedExtensions.txt \
&& cd $MW_HOME/skins \
&& for i in $(ls -d */); do echo "#wfLoadSkin('${i%%/}');"; done > $MW_ORIGIN_FILES/installedSkins.txt \
&& for i in $(ls -d */); do echo "#wfLoadSkin('${i%%/}');"; done > $MW_ORIGIN_FILES/installedSkins.txt \
# Load Vector skin by default in the sample file
&& sed -i "s/#wfLoadSkin('Vector');/wfLoadSkin('Vector');/" $MW_ORIGIN_FILES/installedSkins.txt

Expand Down Expand Up @@ -729,8 +731,9 @@ COPY _sources/scripts/*.php $MW_HOME/maintenance/
COPY _sources/configs/robots.txt $WWW_ROOT/
COPY _sources/configs/.htaccess $WWW_ROOT/
COPY _sources/images/favicon.ico $WWW_ROOT/
COPY _sources/canasta/LocalSettings.php _sources/canasta/CanastaUtils.php _sources/canasta/CanastaDefaultSettings.php $MW_HOME/
COPY _sources/canasta/LocalSettings.php _sources/canasta/CanastaUtils.php _sources/canasta/CanastaDefaultSettings.php _sources/canasta/FarmConfigLoader.php $MW_HOME/
COPY _sources/canasta/getMediawikiSettings.php /
COPY _sources/canasta/canasta_img.php $MW_HOME/
COPY _sources/configs/mpm_event.conf /etc/apache2/mods-available/mpm_event.conf

RUN set -x; \
Expand All @@ -745,6 +748,9 @@ RUN set -x; \
&& sed -i 's/MW_CONFIG_FILE/CANASTA_CONFIG_FILE/g' "$MW_HOME/includes/CanastaNoLocalSettings.php" \
# Modify config
&& sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf \
&& sed -i '/<Directory \/var\/www\/>/i RewriteCond %{THE_REQUEST} \\s(.*?)\\s\nRewriteRule ^ - [E=ORIGINAL_URL:%{REQUEST_SCHEME}://%{HTTP_HOST}%1]' /etc/apache2/apache2.conf \
&& echo "Alias /w/images/ /var/www/mediawiki/w/canasta_img.php/" >> /etc/apache2/apache2.conf \
&& echo "Alias /w/images /var/www/mediawiki/w/canasta_img.php" >> /etc/apache2/apache2.conf \
&& a2enmod expires \
&& a2disconf other-vhosts-access-log \
# Enable environment variables for FPM workers
Expand Down
33 changes: 26 additions & 7 deletions _sources/canasta/CanastaDefaultSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
exit;
}

require_once "$IP/CanastaUtils.php";
require_once "{$IP}/CanastaUtils.php";

$canastaLocalSettingsFilePath = getenv( 'MW_VOLUME' ) . '/config/LocalSettings.php';
$canastaCommonSettingsFilePath = getenv( 'MW_VOLUME' ) . '/config/CommonSettings.php';

if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
// Called from WebInstaller or similar entry point

if ( !file_exists( $canastaLocalSettingsFilePath ) ) {
if ( !file_exists( $canastaLocalSettingsFilePath ) && !file_exists( $canastaCommonSettingsFilePath ) ) {
// Remove all variables, WebInstaller should decide that "$IP/LocalSettings.php" does not exist.
$vars = array_keys( get_defined_vars() );
foreach ( $vars as $v => $k ) {
Expand All @@ -24,7 +26,7 @@
// WebStart entry point

// Check that user's LocalSettings.php exists
if ( !is_readable( $canastaLocalSettingsFilePath ) ) {
if ( !is_readable( $canastaLocalSettingsFilePath ) && !is_readable( $canastaCommonSettingsFilePath ) ) {
// Emulate that "$IP/LocalSettings.php" does not exist

// Set CANASTA_CONFIG_FILE for NoLocalSettings template work correctly in includes/CanastaNoLocalSettings.php
Expand Down Expand Up @@ -70,10 +72,27 @@
$wgCdnServersNoPurge[] = '172.16.0.0/12'; // 172.16.0.0 – 172.31.255.255
$wgCdnServersNoPurge[] = '192.168.0.0/16'; // 192.168.0.0 – 192.168.255.255

# Include user defined CommonSettings.php file
if ( file_exists( $canastaCommonSettingsFilePath ) ) {
require_once "$canastaCommonSettingsFilePath";
}

# Include user defined LocalSettings.php file
require_once "$canastaLocalSettingsFilePath";
if ( file_exists( $canastaLocalSettingsFilePath ) ) {
require_once "$canastaLocalSettingsFilePath";
}

$filenames = glob( getenv( 'MW_VOLUME' ) . '/config/settings/*.php' );

if ( $filenames !== false && is_array( $filenames ) ) {
sort( $filenames );

foreach ( $filenames as $filename ) {
require_once "$filename";
}
}

# Include all php files in config/settings directory
foreach (glob(getenv( 'MW_VOLUME' ) . '/config/settings/*.php') as $filename) {
require_once $filename;
# Include the FarmConfig
if ( file_exists( getenv( 'MW_VOLUME' ) . '/config/wikis.yaml' ) ) {
require_once "$IP/FarmConfigLoader.php";
}
153 changes: 153 additions & 0 deletions _sources/canasta/FarmConfigLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php

# Protect against web entry
if ( !defined( 'MEDIAWIKI' ) ) {
exit;
}

// Get the original URL from the environment variables
$original_url = getenv( 'ORIGINAL_URL' );
$serverName = "";
$path = "";

// Check if the original URL is defined, else throw an exception
if ( $original_url === false && !defined( 'MW_WIKI_NAME' ) ) {
return;
}

// Parse the original URL
$urlComponents = parse_url( $original_url );

// Check if URL parsing was successful, else throw an exception
if ( $urlComponents === false ) {
throw new Exception( 'Error: Failed to parse the original URL' );
}

// Extract the server name (host) from the URL
if ( isset( $urlComponents['host'] ) ) {
$serverName = $urlComponents['host'];
}

// Extract the path from the URL, if any
if ( isset( $urlComponents['path'] ) ) {
// Split the path into parts
$pathParts = explode( '/', trim( $urlComponents['path'], '/' ) );

// Check if path splitting was successful, else throw an exception
if ( $pathParts === false ) {
throw new Exception( 'Error: Failed to split the path into parts' );
}

// If there is a path, store the first directory in the variable $path
if ( count( $pathParts ) > 0 ) {
$firstDirectory = $pathParts[0];
}

// If the first directory is not "wiki" or "w", store it in the variable $path
if ( $firstDirectory != "wiki" && $firstDirectory != "w" ) {
$path = $firstDirectory;
}
}

// Parse the YAML configuration file containing the wiki information
$wikiConfigurations = null;

try {
// Get the file path of the YAML configuration file
$file = getenv( 'MW_VOLUME' ) . '/config/wikis.yaml';

// Check if the configuration file exists, else throw an exception
if ( !file_exists( $file ) ) {
throw new Exception( 'The configuration file does not exist' );
}

// Parse the configuration file
$wikiConfigurations = yaml_parse_file( $file );

// Check if file parsing was successful, else throw an exception
if ( $wikiConfigurations === false ) {
throw new Exception( 'Error parsing the configuration file' );
}
} catch ( Exception $e ) {
die( 'Caught exception: ' . $e->getMessage() );
}

$wikiIdToConfigMap = [];
$urlToWikiIdMap = [];

// Populate the arrays with data from the configuration file
if ( isset( $wikiConfigurations ) && isset( $wikiConfigurations['wikis'] ) && is_array( $wikiConfigurations['wikis'] ) ) {
foreach ( $wikiConfigurations['wikis'] as $wiki ) {
// Check if 'url' and 'id' are set before using them
if ( isset( $wiki['url'] ) && isset( $wiki['id'] ) ) {
$urlToWikiIdMap[$wiki['url']] = $wiki['id'];
$wikiIdToConfigMap[$wiki['id']] = $wiki;
} else {
throw new Exception( 'Error: The wiki configuration is missing either the url or id attribute.' );
}
}
} else {
throw new Exception( 'Error: Invalid wiki configurations.' );
}

// Prepare the key using the server name and the path
if ( empty( $path ) ) {
$key = $serverName;
} else {
$key = $serverName . '/' . $path;
}

// Retrieve the wikiID if available
$wikiID = defined( 'MW_WIKI_NAME' ) ? MW_WIKI_NAME : null;

// Check if the key is null or if it exists in the urlToWikiIdMap, else throw an exception
if ( $key === null ) {
throw new Exception( "Error: Key is null." );
} elseif ( $wikiID === null && array_key_exists( $key, $urlToWikiIdMap ) ) {
$wikiID = $urlToWikiIdMap[$key];
} elseif ( $wikiID === null ) {
throw new Exception( "Error: $key does not exist in urlToWikiIdMap." );
}

// Get the configuration for the selected wiki
$selectedWikiConfig = $wikiIdToConfigMap[$wikiID] ?? null;

// Check if a matching configuration was found. If so, configure the wiki database, else terminate execution
if ( !empty( $selectedWikiConfig ) ) {
// Set database name to the wiki ID
$wgDBname = $wikiID;

// Set site name and meta namespace from the configuration, or use the wiki ID if 'name' is not set
$wgSitename = isset( $selectedWikiConfig['name'] ) ? $selectedWikiConfig['name'] : $wikiID;
$wgMetaNamespace = isset( $selectedWikiConfig['name'] ) ? $selectedWikiConfig['name'] : $wikiID;
} else {
die( 'Unknown wiki.' );
}

// Configure the wiki server and URL paths
$wgServer = "https://$serverName";
$wgScriptPath = !empty( $path )
? "/$path/w"
: "/w";

$wgArticlePath = !empty( $path )
? "/$path/wiki/$1"
: "/wiki/$1";
$wgCacheDirectory = "$IP/cache/$wikiID";
$wgUploadDirectory = "$IP/images/$wikiID";

// Load additional configuration files specific to the wiki ID
$files = glob( getenv( 'MW_VOLUME' ) . "/config/{$wikiID}/*.php" );

$wgEnableUploads = true;

// Check if the glob function was successful, else continue with the execution
if ( $files !== false && is_array( $files ) ) {
// Sort the files
sort( $files );

// Include each file
foreach ( $files as $filename ) {
require_once "$filename";
}
}
Loading

0 comments on commit bf3a6f5

Please sign in to comment.