diff --git a/pillar/role/wiki.sls b/pillar/role/wiki.sls
new file mode 100644
index 0000000..b251cc5
--- /dev/null
+++ b/pillar/role/wiki.sls
@@ -0,0 +1,45 @@
+apparmor:
+ profiles:
+ httpd2-prefork:
+ source: salt://profile/wiki/files/httpd2-prefork.apparmor
+ template: jinja
+ memcached:
+ source: salt://profile/wiki/files/memcached.apparmor
+
+# list of wikis running MediaWiki 1.27 (this will allow us to migrate to a new version one by one later)
+mediawiki_1_27:
+ elasticsearch_server: 192.168.122.105
+ mysql_server: 192.168.122.106
+ wikis:
+ en:
+ alias: wikimove.opensuse.org
+ dbpass: not_in_salt_yet
+# readonly_msg: 'This wiki is in read-only mode for maintenance!'
+# site_notice: 'Welcome to the updated openSUSE wiki! If you notice any issues, please send a mail to admin [at] opensuse.org'
+ en-test:
+ bento_lang: en
+ dbpass: not_in_salt_yet
+ lang: en
+ site_notice: 'This is a test wiki. You are more than welcome to do test edits, but please keep in mind that all changes will be lost when we import a newer database dump.'
+
+# special cases for bento_lang:
+# cz -> bento_lang cs
+# pt-br -> bento_lang pt_BR
+# zh_tw -> bento_lang zh_TW
+# full bento_lang list: https://github.com/openSUSE/opensuse-themes/tree/master/bento/js/l10n
+
+zypper:
+ packages:
+ apache2: {}
+ apache2-mod_apparmor: {}
+ apache2-prefork: {}
+ mediawiki_1_27-openSUSE: {}
+ mariadb-client: {}
+ # needed for migration to unpack tarballs
+ tar: {}
+ repositories:
+ openSUSE:infrastructure:wiki:
+ baseurl: http://download.opensuse.org/repositories/openSUSE:/infrastructure:/wiki/openSUSE_Leap_{{ grains['osrelease'] }}
+ gpgcheck: 0
+ priority: 100
+ refresh: True
diff --git a/salt/profile/wiki/apache.sls b/salt/profile/wiki/apache.sls
new file mode 100644
index 0000000..1b65b8a
--- /dev/null
+++ b/salt/profile/wiki/apache.sls
@@ -0,0 +1,28 @@
+# zypper-formula already uses/blocks the "apache2" name :-(
+apache2_running:
+ service.running:
+ - enable: True
+ - name: apache2
+
+{% set mediawiki_1_27 = salt['pillar.get']('mediawiki_1_27:wikis', {}) %}
+{% for wiki, data in mediawiki_1_27.items() %}
+
+/etc/apache2/vhosts.d/{{ wiki }}.opensuse.org.conf:
+ file.managed:
+ - context:
+ alias: {{ data.get('alias', '') }}
+ wiki: {{ wiki }}
+ - listen_in:
+ - service: apache2
+ - source: salt://profile/wiki/files/apache-vhost.conf
+ - template: jinja
+
+{% endfor %}
+
+/etc/sysconfig/apache2:
+ file.replace:
+ - pattern: ^APACHE_MODULES=.*$
+ # original line: "actions alias auth_basic authn_file authz_host authz_groupfile authz_core authz_user autoindex cgi dir env expires include log_config mime negotiation setenvif ssl socache_shmcb userdir reqtimeout authn_core php7 rewrite"
+ - repl: APACHE_MODULES=" alias apparmor auth_basic authn_file authz_host authz_groupfile authz_core authz_user dir env expires include log_config mime negotiation setenvif socache_shmcb reqtimeout authn_core php7 rewrite"
+ - listen_in:
+ - service: apache2
diff --git a/salt/profile/wiki/docroot.sls b/salt/profile/wiki/docroot.sls
new file mode 100644
index 0000000..67b6772
--- /dev/null
+++ b/salt/profile/wiki/docroot.sls
@@ -0,0 +1,60 @@
+#
+# create the DocumentRoot and the directories and symlinks needed for all wikis
+#
+
+{% set mediawiki_1_27 = salt['pillar.get']('mediawiki_1_27:wikis', {}) %}
+
+# create /srv/www/$lang.opensuse.org and all symlinks and directories needed in it
+{% for wiki, data in mediawiki_1_27.items() %}
+
+/srv/www/{{ wiki }}.opensuse.org/public:
+ file.directory:
+ - user: root
+ - group: root
+ - mode: 755
+ - makedirs: True
+
+{% set mediawiki_1_27_wwwrun_dirs = [ 'cache', 'tmp', 'public/images' ] %}
+
+{% for dir in mediawiki_1_27_wwwrun_dirs %}
+/srv/www/{{ wiki }}.opensuse.org/{{ dir }}:
+ file.directory:
+ - user: wwwrun
+ - group: root
+ - mode: 755
+ - makedirs: True
+{%endfor%}
+
+/srv/www/{{ wiki }}.opensuse.org/public/mediawiki_src:
+ file.symlink:
+ - target: /usr/share/mediawiki_1_27/
+
+{% set mediawiki_1_27_symlinks = [ 'api.php', 'autoload.php', 'extensions', 'img_auth.php', 'includes', 'index.php', 'languages', 'load.php', 'maintenance',
+ 'opensearch_desc.php', 'resources', 'serialized', 'skins', 'thumb_handler.php', 'thumb.php', 'vendor', ] %}
+{% for symlink in mediawiki_1_27_symlinks %}
+/srv/www/{{ wiki }}.opensuse.org/public/{{ symlink }}:
+ file.symlink:
+ - target: mediawiki_src/{{ symlink }}
+{%endfor%}
+
+/srv/www//{{ wiki }}.opensuse.org/public/LocalSettings.php:
+ file.managed:
+ - source: salt://profile/wiki/files/LocalSettings.php
+
+/srv/www//{{ wiki }}.opensuse.org/wiki_settings.php:
+ file.managed:
+ - context:
+ data: {{ data }}
+ mysql_server: {{ pillar['mediawiki_1_27']['mysql_server'] }}
+ elasticsearch_server: {{ pillar['mediawiki_1_27']['elasticsearch_server'] }}
+ wiki: {{ wiki }}
+ - source: salt://profile/wiki/files/wiki_settings.php
+ - template: jinja
+
+{%endfor%}
+
+# SQL commands to migrate old hit counter data
+# can be removed after updating all wikis to 1.27
+/srv/www/migrate-wiki-counter.sql:
+ file.managed:
+ - source: salt://profile/wiki/files/migrate-wiki-counter.sql
diff --git a/salt/profile/wiki/files/LocalSettings.php b/salt/profile/wiki/files/LocalSettings.php
new file mode 100644
index 0000000..20ec5fd
--- /dev/null
+++ b/salt/profile/wiki/files/LocalSettings.php
@@ -0,0 +1,357 @@
+ '127.0.0.1:11211' );
+$wgMainCacheType = CACHE_MEMCACHED;
+
+$wgSessionCacheType = CACHE_DB; # session cache needs to be persistent, see https://www.mediawiki.org/wiki/Topic:T75cloz7981b8i92
+
+$configdate = gmdate( 'YmdHis', @filemtime( __FILE__ ) );
+$wgCacheEpoch = max( $wgCacheEpoch, $configdate );
+$wgEnableSidebarCache = true;
+
+## To enable image uploads, make sure the 'images' directory
+## is writable, then uncomment this:
+$wgEnableUploads = true;
+$wgUseImageResize = true;
+$wgUseImageMagick = false;
+#$wgImageMagickConvertCommand = "/usr/bin/convert";
+
+## If you want to use image uploads under safe mode,
+## create the directories images/archive, images/thumb and
+## images/temp, and make them all writable. Then uncomment
+## this, if it's not already uncommented:
+# $wgHashedUploadDirectory = false;
+
+## If you have the appropriate support software installed
+## you can enable inline LaTeX equations:
+# $wgUseTeX = true;
+$wgMathPath = "{$wgUploadPath}/math";
+$wgMathDirectory = "{$wgUploadDirectory}/math";
+$wgTmpDirectory = "{$wgUploadDirectory}/temp";
+
+$wgLocalInterwiki = $wgSitename;
+
+$wgCookieDomain = "opensuse.org";
+
+## For attaching licensing metadata to pages, and displaying an
+## appropriate copyright notice / icon. GNU Free Documentation
+## License and Creative Commons licenses are supported so far.
+# $wgEnableCreativeCommonsRdf = true;
+$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
+$wgRightsUrl = "";
+$wgRightsText = "";
+$wgRightsIcon = "";
+# $wgRightsCode = ""; # Not yet used
+
+$wgDefaultSkin = 'bento';
+wfLoadSkin('bento');
+
+# $wgLocalTZoffset = date("Z") / 3600; # 3600 is obviously wrong, since the value is expected in minutes
+$wgGroupPermissions['*']['edit'] = false;
+$wgFavicon = "//www.opensuse.org/favicon.ico";
+$wgDiff3 = "/usr/bin/diff3";
+
+#--------------------------------------------------------------
+# Custom config section
+#
+
+##### Namespace configuration #####
+#
+#
+# Project (meta) namespace
+$wgMetaNamespace = 'openSUSE';
+# Custom namespaces
+define( 'NS_SDB', 100 );
+define( 'NS_SDB_TALK', 101 );
+define( 'NS_PORTAL', 102 );
+define( 'NS_PORTAL_TALK', 103 );
+define( 'NS_ARCHIVE', 104 );
+define( 'NS_ARCHIVE_TALK', 105 );
+define( 'NS_HCL', 106 );
+define( 'NS_HCL_TALK', 107 );
+# $wgExtraNamespaces[108] = '11.2';
+# $wgExtraNamespaces[109] = '11.2_Talk';
+define( 'NS_BOOK', 110 );
+define( 'NS_BOOK_TALK', 111 );
+
+$wgExtraNamespaces[NS_SDB] = 'SDB';
+$wgExtraNamespaces[NS_SDB_TALK] = 'SDB_Talk';
+$wgExtraNamespaces[NS_PORTAL] = 'Portal';
+$wgExtraNamespaces[NS_PORTAL_TALK] = 'Portal_Talk';
+$wgExtraNamespaces[NS_ARCHIVE] = 'Archive';
+$wgExtraNamespaces[NS_ARCHIVE_TALK] = 'Archive_Talk';
+$wgExtraNamespaces[NS_HCL] = 'HCL';
+$wgExtraNamespaces[NS_HCL_TALK] = 'HCL_Talk';
+$wgExtraNamespaces[NS_BOOK] = 'Book';
+$wgExtraNamespaces[NS_BOOK_TALK] = 'Book_Talk';
+
+# Enable/Disable subpages
+$wgNamespacesWithSubpages[NS_SPECIAL] = false;
+$wgNamespacesWithSubpages[NS_MAIN] = true;
+$wgNamespacesWithSubpages[NS_TALK] = true;
+$wgNamespacesWithSubpages[NS_USER] = true;
+$wgNamespacesWithSubpages[NS_USER_TALK] = true;
+$wgNamespacesWithSubpages[NS_PROJECT] = true;
+$wgNamespacesWithSubpages[NS_PROJECT_TALK] = true;
+$wgNamespacesWithSubpages[NS_FILE] = false;
+$wgNamespacesWithSubpages[NS_FILE_TALK] = true;
+$wgNamespacesWithSubpages[NS_MEDIAWIKI] = false;
+$wgNamespacesWithSubpages[NS_MEDIAWIKI_TALK] = true;
+$wgNamespacesWithSubpages[NS_TEMPLATE] = true;
+$wgNamespacesWithSubpages[NS_TEMPLATE_TALK] = true;
+$wgNamespacesWithSubpages[NS_SDB] = true;
+$wgNamespacesWithSubpages[NS_SDB_TALK] = true;
+$wgNamespacesWithSubpages[NS_PORTAL] = true;
+$wgNamespacesWithSubpages[NS_PORTAL_TALK] = true;
+$wgNamespacesWithSubpages[NS_ARCHIVE] = true;
+$wgNamespacesWithSubpages[NS_ARCHIVE_TALK] = true;
+$wgNamespacesWithSubpages[NS_BOOK] = true;
+
+$wgContentNamespaces = array (NS_MAIN, NS_PROJECT, NS_HELP, NS_SDB, NS_PORTAL, NS_ARCHIVE, NS_HCL, NS_BOOK);
+
+$wgAllowCategorizedRecentChanges = true;
+
+$wgNamespacesToBeSearchedDefault = array(
+ NS_MAIN => true,
+ NS_USER => true,
+ NS_PROJECT => true,
+ NS_FILE => true,
+ NS_TEMPLATE => true,
+ NS_HELP => true,
+ NS_CATEGORY => true,
+ NS_SDB => true,
+ NS_PORTAL => true,
+ NS_ARCHIVE => true,
+ NS_HCL => true,
+);
+
+##### Misc #####
+
+$wgUseAjax = true; // Enable Ajax
+$wgAllowExternalImages = true; // Enable links to external images
+# Allow upload of files with the following extensions
+$wgFileExtensions = array( 'doc', 'docx', 'gif', 'jpg', 'jpeg', 'odp', 'ods', 'odt', 'pdf', 'png', 'ppt', 'pptx', 'sxc', 'sxw', 'xls', 'xlsx' );
+# Add XMPP functionality
+$wgUrlProtocols[] = 'xmpp:';
+
+# To be removed once the wiki transition is finished
+$wgGroupPermissions['user']['import'] = true;
+$wgGroupPermissions['user']['importupload'] = true;
+$wgGroupPermissions['sysop']['deleterevision'] = true;
+$wgGroupPermissions['user']['move'] = true;
+
+# make the real IPs visible to the wiki instead of the auth proxy (AccessManager) IPs. Without this, IP blocking blocks the proxy IP and therefore edits from everywhere.
+$wgUseSquid = true;
+$wgSquidServers = array();
+$wgSquidServers[] = '192.168.254.4';
+$wgSquidServers[] = '149.44.161.63';
+
+# Category watching ----------------------------------
+# see https://www.mediawiki.org/wiki/Manual:CategoryMembershipChanges
+$wgRCWatchCategoryMembership = true;
+$wgDefaultUserOptions['hidecategorization'] = 0;
+$wgDefaultUserOptions['watchlisthidecategorization'] = 0;
+
+##### Extensions #####
+
+# Login proxy / Auth_remoteuser -------------------
+wfLoadExtension( 'Auth_remoteuser' );
+$wgAuthRemoteuserUserUrls = [ 'logout' => '/cmd/ICSLogout/?url=' . htmlentities($_SERVER['REQUEST_URI']) ];
+
+if (isset($_SERVER['HTTP_X_USERNAME'])) { # avoid logging 'undefined index' warnings
+ $wgAuthRemoteuserUserName = [ $_SERVER['HTTP_X_USERNAME'] ];
+ $wgAuthRemoteuserUserPrefsForced = [ 'email' => $_SERVER['HTTP_X_EMAIL'] ];
+} else {
+ $wgAuthRemoteuserUserName = [ '' ];
+ $wgAuthRemoteuserUserPrefsForced = [ 'email' => '' ];
+}
+
+# UserMerge ------------------------
+require_once( "$IP/extensions/UserMerge/UserMerge.php" );
+// By default nobody can use this function, enable for bureaucrat?
+$wgGroupPermissions['bureaucrat']['usermerge'] = true;
+
+# WikiEditor -----------------------
+require_once("$IP/extensions/WikiEditor/WikiEditor.php");
+$wgDefaultUserOptions['usebetatoolbar'] = 1;
+$wgDefaultUserOptions['usebetatoolbar-cgd'] = 1;
+$wgDefaultUserOptions['wikieditor-preview'] = 1;
+
+# Intersection ---------------------
+include("$IP/extensions/intersection/DynamicPageList.php");
+
+# RSS -----------------------
+include("$IP/extensions/RSS/RSS.php");
+$wgRSSUrlWhitelist = array('*');
+
+# InputBox -------------------------
+require_once($IP.'/extensions/InputBox/InputBox.php');
+
+# ParserFunctions -----------------
+require_once( "$IP/extensions/ParserFunctions/ParserFunctions.php" );
+
+# CategoryTree.php ----------------
+require_once("$IP/extensions/CategoryTree/CategoryTree.php");
+$wgCategoryTreeMaxDepth = array(CT_MODE_PAGES => 2, CT_MODE_ALL => 2, CT_MODE_CATEGORIES => 3);
+
+# EventCountdown ------------------
+require_once("$IP/extensions/EventCountdown.php");
+
+# MultiBoilerplate ----------------
+require_once( "$IP/extensions/MultiBoilerplate/MultiBoilerplate.php" );
+$wgMultiBoilerplateOptions = false;
+$wgMultiBoilerplatePerNamespace = true;
+
+# Replace Text ----------------------------------------------
+require_once( "$IP/extensions/ReplaceText/ReplaceText.php" );
+
+# Interwiki links management ----------------------------------
+require_once("$IP/extensions/Interwiki/Interwiki.php");
+$wgInterwikiMagic=true;
+$wgHideInterlanguageLinks=false;
+$wgGroupPermissions['*']['interwiki'] = false;
+$wgGroupPermissions['sysop']['interwiki'] = true;
+
+# Flash video links ----------------------------------
+require_once("extensions/videoflash.php");
+
+# Syntax highlighting ----------------------------------
+require_once("$IP/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.php");
+
+# Hide page title ----------------------------------
+require_once("$IP/extensions/notitle.php");
+
+# Semantic Maps ----------------------------------
+# by using autoload, we get everything we need (Maps, Validator [needed by Maps] and ParamProcessor [needed by Validator] automagically:
+require_once("$IP/extensions/maps-vendor/autoload.php");
+
+$GLOBALS['egMapsGMaps3ApiKey'] = $google_maps_key;
+
+# XXX instead of Google?
+#$GLOBALS['egMapsDefaultService'] = 'openlayers';
+#$GLOBALS['egMapsDefaultService'] = 'leaflet';
+
+# protect user pages ----------------------------------
+include_once( "$IP/extensions/UserPageEditProtection/UserPageEditProtection.php" );
+$wgOnlyUserEditUserPage = true; /* Set this to true to turn on user page protection */
+$wgGroupPermissions['sysop']['editalluserpages'] = true; /* Set this to allow sysops to edit all user pages */
+
+# google coop ----------------------------------
+include("$IP/extensions/google-coop.php");
+
+# mass deletion ----------------------------------
+include_once( "$IP/extensions/Nuke/Nuke.php");
+
+# spam filter ----------------------------------
+include_once( "$IP/extensions/AbuseFilter/AbuseFilter.php");
+# set higher EmergencyDisable limits to prevent spam filter from getting disabled with
+# "Warning: This filter was automatically disabled as a safety measure. It reached the limit of matching more than 5.00% of actions."
+$wgAbuseFilterEmergencyDisableThreshold['default'] = 0.50; # default 0.05
+$wgAbuseFilterEmergencyDisableCount['default'] = 50; # default 2
+
+$wgGroupPermissions['sysop']['abusefilter-modify'] = true;
+$wgGroupPermissions['*']['abusefilter-log-detail'] = true;
+$wgGroupPermissions['*']['abusefilter-view'] = true;
+$wgGroupPermissions['*']['abusefilter-log'] = true;
+$wgGroupPermissions['sysop']['abusefilter-private'] = true;
+$wgGroupPermissions['sysop']['abusefilter-modify-restricted'] = true;
+$wgGroupPermissions['sysop']['abusefilter-revert'] = true;
+
+# Hit counter ----------------------------------
+wfLoadExtension('HitCounters');
+
+# include READMEs etc. from GitHub ----------------------------------
+require_once("$IP/extensions/GitHub/GitHub.php");
+
+# search ----------------------------------
+wfLoadExtension( 'Elastica' );
+require_once "$IP/extensions/CirrusSearch/CirrusSearch.php";
+$wgCirrusSearchServers = array($elasticsearch_server);
+$wgSearchType = 'CirrusSearch';
+
+$wgCirrusSearchNamespaceWeights = array(
+ NS_MAIN => 1,
+ NS_USER => 0.05, # default
+ NS_PROJECT => 0.6,
+ NS_MEDIAWIKI => 0.05, # default
+ NS_FILE => 0.02,
+ NS_TEMPLATE => 0.005, # default
+ NS_HELP => 0.1, # default
+ NS_CATEGORY => 0.02,
+ NS_SDB => 0.6,
+ NS_PORTAL => 1,
+ NS_ARCHIVE => 0.2,
+ NS_HCL => 0.2,
+);
+
+# ----------------------------------
diff --git a/salt/profile/wiki/files/apache-vhost.conf b/salt/profile/wiki/files/apache-vhost.conf
new file mode 100644
index 0000000..e9b6e00
--- /dev/null
+++ b/salt/profile/wiki/files/apache-vhost.conf
@@ -0,0 +1,36 @@
+
+ ServerName {{ wiki }}.opensuse.org
+ {% if alias %}
+ ServerAlias {{ alias }}
+ {% endif %}
+ UseCanonicalName Off
+
+ AADefaultHatName vhost_{{ wiki }}wiki
+
+ DocumentRoot /srv/www/{{ wiki }}.opensuse.org/public
+
+
+ Require all granted
+
+ Options +FollowSymlinks
+
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule ^(Index.php/)?(.+)$ index.php?title=$2 [PT,L,QSA]
+
+
+ SetEnv TMP /srv/www/{{ wiki }}.opensuse.org/tmp/
+
+ php_admin_flag engine on
+ php_admin_value open_basedir "/srv/www/{{ wiki }}.opensuse.org/:/usr/share/mediawiki_1_27/:/dev/urandom"
+ php_admin_value upload_tmp_dir /srv/www/{{ wiki }}.opensuse.org/tmp/
+ php_admin_value session.save_path /srv/www/{{ wiki }}.opensuse.org/tmp/
+ php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f noreply+{{ wiki }}-wiki@opensuse.org"
+
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combinedproxy
+ CustomLog "/var/log/apache2/access_log" combinedproxy
+
+
+
+# vim:ft=apache
diff --git a/salt/profile/wiki/files/httpd2-prefork.apparmor b/salt/profile/wiki/files/httpd2-prefork.apparmor
new file mode 100644
index 0000000..b9e331f
--- /dev/null
+++ b/salt/profile/wiki/files/httpd2-prefork.apparmor
@@ -0,0 +1,141 @@
+# managed by salt - do not edit!
+
+# $Id: usr.sbin.httpd2-prefork 12 2006-04-12 21:35:41Z steve-beattie $
+# ------------------------------------------------------------------
+#
+# Copyright (C) 2002-2005 Novell/SUSE
+# Copyright (C) 2017 Christian Boltz
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License published by the Free Software Foundation.
+#
+# ------------------------------------------------------------------
+
+#include
+
+@{wiki_upload_extensions}=doc docx gif jpg jpeg odp ods odt pdf png ppt pptx sxc sxw xls xlsx
+
+profile httpd2-prefork /usr/sbin/httpd{,2}-prefork flags=(complain,attach_disconnected) {
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+
+ capability dac_override,
+ capability kill,
+ capability net_admin,
+ capability net_bind_service,
+ capability setgid,
+ capability setuid,
+ capability sys_ptrace,
+ capability sys_tty_config,
+
+ / rw,
+ /bin/bash rix,
+ /dev/random r,
+ /etc/apache2/*.conf r,
+ owner /etc/apache2/conf.d/ r,
+ /etc/apache2/magic r,
+ /etc/apache2/mod_perl-startup.pl r,
+ /etc/apache2/sysconfig.d/ r,
+ /etc/apache2/vhosts.d/ r,
+ /etc/apache2/vhosts.d/hostings/ r,
+ /etc/apache2/{conf,sysconfig,vhosts}.d/* r,
+ /etc/fstab r,
+ /etc/mime.types r,
+ /etc/mtab r,
+ /etc/odbcinst.ini r,
+ /etc/php.d/** r,
+ /etc/php.ini r,
+ /proc/*/attr/current rw,
+ /proc/meminfo r,
+ /proc/sys/kernel/ngroups_max r,
+ /run/httpd.pid rw,
+ /tmp/magic* rw,
+ /usr/apache2/error/* r,
+ /usr/lib/apache2-leader/{lib,mod_}*.so* mr,
+ /usr/lib/apache2-metuxmpm/{lib,mod_}*.so* mr,
+ /usr/lib/apache2-prefork/{lib,mod_}*.so* mr,
+ /usr/lib/apache2-worker/{lib,mod_}*.so* mr,
+ /usr/lib/apache2/modules/{lib,mod_}*.so* mr,
+ /usr/lib/apache2/{lib,mod_}*.so mr,
+ /usr/lib/mysql/libmysql*.so* mr,
+ /usr/lib64/apache2-leader/{lib,mod_}*.so* mr,
+ /usr/lib64/apache2-metuxmpm/{lib,mod_}*.so* mr,
+ /usr/lib64/apache2-prefork/{lib,mod_}*.so* mr,
+ /usr/lib64/apache2-worker/{lib,mod_}*.so* mr,
+ /usr/lib64/apache2/modules/{lib,mod_}*.so* mr,
+ /usr/lib64/apache2/{lib,mod_}*.so* mr,
+ /usr/lib64/mysql/libmysql*.so* mr,
+ /usr/sbin/httpd{,2}-prefork mr,
+ /usr/sbin/suexec2 mrix,
+ /usr/share/apache2/error/** r,
+ /usr/share/apache2/icons/** r,
+ /usr/share/misc/magic.mime r,
+ /usr/share/snmp/mibs r,
+ /usr/share/snmp/mibs/*.{txt,mib} r,
+ /usr/share/snmp/mibs/.index rw,
+ /var/lib/apache2/ssl_mutex w,
+ /var/log/apache2/* rwl,
+
+ ^DEFAULT_URI flags=(complain,attach_disconnected) {
+ #include
+
+ /proc/meminfo r,
+ /usr/share/zoneinfo/ r,
+ /usr/share/zoneinfo/** r,
+ /var/log/apache2/access_log w,
+ /var/log/apache2/error_log w,
+
+ }
+
+ ^HANDLING_UNTRUSTED_INPUT flags=(complain,attach_disconnected) {
+ #include
+
+ /**/.htaccess r,
+ /dev/urandom r,
+ /proc/*/attr/current w,
+ /var/lib/apache2/ssl_mutex wk,
+ /var/log/apache2/access_log w,
+ /var/log/apache2/error_log w,
+ /var/log/apache2/error_log-20[12][0-9][01][0-9][0-3][0-9] w,
+ /var/log/apache2/ssl_request_log w,
+
+ }
+
+ # {% for wiki in pillar['mediawiki_1_27']['wikis'] %}
+ ^vhost_{{wiki}}wiki flags=(complain,attach_disconnected) {
+ #include
+ #include
+
+ / r,
+ /bin/bash rix,
+ /dev/tty rw,
+ /proc/meminfo r,
+ /usr/sbin/sendmail PUx,
+ /var/log/apache2/access_log w,
+ /var/log/apache2/error_log w,
+
+ /srv/www/{{wiki}}.opensuse.org/cache/ r,
+ /srv/www/{{wiki}}.opensuse.org/cache/* rw,
+ /srv/www/{{wiki}}.opensuse.org/public/ r,
+ /srv/www/{{wiki}}.opensuse.org/public/** r,
+ /srv/www/{{wiki}}.opensuse.org/public/images/**.@{wiki_upload_extensions} rw,
+ /srv/www/{{wiki}}.opensuse.org/tmp/php* rw,
+ /srv/www/{{wiki}}.opensuse.org/secrets.php r,
+ /srv/www/{{wiki}}.opensuse.org/wiki_settings.php r,
+ /usr/share/mediawiki_1_27/** r,
+
+ }
+ # {% endfor %}
+
+}
+
+# vim: ft=apparmor expandtab
+
diff --git a/salt/profile/wiki/files/memcached.apparmor b/salt/profile/wiki/files/memcached.apparmor
new file mode 100644
index 0000000..3e273f8
--- /dev/null
+++ b/salt/profile/wiki/files/memcached.apparmor
@@ -0,0 +1,27 @@
+# managed by salt - do not edit manually!
+
+# AppArmor profile for memcached 1.4.33
+
+# ------------------------------------------------------------------
+#
+# Copyright (C) 2017 Christian Boltz
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License published by the Free Software Foundation.
+#
+# ------------------------------------------------------------------
+
+#include
+
+profile memcached /usr/sbin/memcached flags=(complain) {
+ #include
+ #include
+
+ capability setgid,
+ capability setuid,
+
+ /usr/sbin/memcached mr,
+
+}
+
diff --git a/salt/profile/wiki/files/migrate-wiki-counter.sql b/salt/profile/wiki/files/migrate-wiki-counter.sql
new file mode 100644
index 0000000..4c25a10
--- /dev/null
+++ b/salt/profile/wiki/files/migrate-wiki-counter.sql
@@ -0,0 +1,15 @@
+/*
+ * migrate hit counter data to the separate table used by the HitCounters extension
+ *
+ * run this BEFORE running maintenance/update.php, or counter data will be lost!
+ *
+ * Source: https://www.mediawiki.org/wiki/Extension_talk:HitCounters#Manual_generation_of_DB_tables_during_upgrade
+ */
+
+RENAME TABLE hitcounter TO hit_counter_extension;
+CREATE TABLE hit_counter (
+ page_id INT(8) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ page_counter BIGINT(20) UNSIGNED NOT NULL DEFAULT '0'
+) ;
+CREATE INDEX page_counter ON hit_counter (page_counter);
+INSERT INTO hit_counter (page_id, page_counter) SELECT page.page_id, page.page_counter FROM page;
diff --git a/salt/profile/wiki/files/wiki_settings.php b/salt/profile/wiki/files/wiki_settings.php
new file mode 100644
index 0000000..3b73550
--- /dev/null
+++ b/salt/profile/wiki/files/wiki_settings.php
@@ -0,0 +1,25 @@
+