]> git.openstreetmap.org Git - chef.git/blob - cookbooks/mediawiki/resources/site.rb
Port custom firewall rule to nftables
[chef.git] / cookbooks / mediawiki / resources / site.rb
1 #
2 # Cookbook:: mediawiki
3 # Resource:: mediawiki_site
4 #
5 # Copyright:: 2015, OpenStreetMap Foundation
6 #
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
10 #
11 # https://www.apache.org/licenses/LICENSE-2.0
12 #
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
18 #
19
20 unified_mode true
21
22 default_action :create
23
24 property :site, :kind_of => String, :name_property => true
25 property :aliases, :kind_of => [String, Array]
26 property :directory, :kind_of => String
27 property :version, :kind_of => String, :default => "1.39"
28 property :database_name, :kind_of => String, :required => true
29 property :database_user, :kind_of => String, :required => [:create, :update]
30 property :database_password, :kind_of => String, :required => [:create, :update]
31 property :sitename, :kind_of => String, :default => "OpenStreetMap Wiki"
32 property :metanamespace, :kind_of => String, :default => "OpenStreetMap"
33 property :logo, :kind_of => String, :default => "$wgStylePath/common/images/wiki.png"
34 property :email_contact, :kind_of => String, :default => ""
35 property :email_sender, :kind_of => String, :default => ""
36 property :email_sender_name, :kind_of => String, :default => "MediaWiki Mail"
37 property :commons, :kind_of => [TrueClass, FalseClass], :default => true
38 property :skin, :kind_of => String, :default => "vector"
39 property :site_notice, :kind_of => [String, TrueClass, FalseClass], :default => false
40 property :site_readonly, :kind_of => [String, TrueClass, FalseClass], :default => false
41 property :admin_user, :kind_of => String, :default => "Admin"
42 property :admin_password, :kind_of => String, :required => [:create]
43 property :private_accounts, :kind_of => [TrueClass, FalseClass], :default => false
44 property :private_site, :kind_of => [TrueClass, FalseClass], :default => false
45 property :hcaptcha_public_key, :kind_of => String, :default => ""
46 property :hcaptcha_private_key, :kind_of => String, :default => ""
47 property :extra_file_extensions, :kind_of => [String, Array], :default => []
48 property :fpm_max_children, :kind_of => Integer, :default => 5
49 property :fpm_start_servers, :kind_of => Integer, :default => 2
50 property :fpm_min_spare_servers, :kind_of => Integer, :default => 1
51 property :fpm_max_spare_servers, :kind_of => Integer, :default => 3
52 property :fpm_request_terminate_timeout, :kind_of => Integer, :default => 300
53 property :fpm_prometheus_port, :kind_of => Integer
54 property :reload_apache, :kind_of => [TrueClass, FalseClass], :default => true
55
56 action :create do
57   node.default[:mediawiki][:sites][new_resource.site] = {
58     :directory => site_directory,
59     :version => new_resource.version
60   }
61
62   mysql_user "#{new_resource.database_user}@localhost" do
63     password new_resource.database_password
64     reload true
65   end
66
67   mysql_database new_resource.database_name do
68     permissions "#{new_resource.database_user}@localhost" => :all
69   end
70
71   mediawiki_directory = "#{site_directory}/w"
72
73   declare_resource :directory, site_directory do
74     owner node[:mediawiki][:user]
75     group node[:mediawiki][:group]
76     mode "775"
77   end
78
79   declare_resource :directory, mediawiki_directory do
80     owner node[:mediawiki][:user]
81     group node[:mediawiki][:group]
82     mode "775"
83   end
84
85   git mediawiki_directory do
86     action :sync
87     repository "https://gerrit.wikimedia.org/r/mediawiki/core.git"
88     revision mediawiki_reference
89     depth 1
90     user node[:mediawiki][:user]
91     group node[:mediawiki][:group]
92   end
93
94   template "#{mediawiki_directory}/composer.local.json" do
95     cookbook "mediawiki"
96     source "composer.local.json.erb"
97     owner node[:mediawiki][:user]
98     group node[:mediawiki][:group]
99     mode "664"
100   end
101
102   execute "#{mediawiki_directory}/composer.json" do
103     command "composer update --no-dev"
104     cwd mediawiki_directory
105     user node[:mediawiki][:user]
106     group node[:mediawiki][:group]
107     environment "COMPOSER_HOME" => site_directory
108     not_if { ::File.exist?("#{mediawiki_directory}/composer.lock") }
109   end
110
111   execute "#{mediawiki_directory}/maintenance/install.php" do
112     # Use metanamespace as Site Name to ensure correct set namespace
113     command "php maintenance/install.php --server '#{name}' --dbtype 'mysql' --dbname '#{new_resource.database_name}' --dbuser '#{new_resource.database_user}' --dbpass '#{new_resource.database_password}' --dbserver 'localhost' --scriptpath /w --pass '#{new_resource.admin_password}' '#{new_resource.metanamespace}' '#{new_resource.admin_user}'"
114     cwd mediawiki_directory
115     user node[:mediawiki][:user]
116     group node[:mediawiki][:group]
117     not_if { ::File.exist?("#{mediawiki_directory}/LocalSettings.php") }
118   end
119
120   declare_resource :directory, "#{mediawiki_directory}/images" do
121     owner "www-data"
122     group node[:mediawiki][:group]
123     mode "775"
124   end
125
126   declare_resource :directory, "#{mediawiki_directory}/cache" do
127     owner "www-data"
128     group node[:mediawiki][:group]
129     mode "775"
130   end
131
132   declare_resource :directory, "#{mediawiki_directory}/LocalSettings.d" do
133     user node[:mediawiki][:user]
134     group node[:mediawiki][:group]
135     mode "775"
136   end
137
138   template "#{mediawiki_directory}/LocalSettings.php" do
139     cookbook "mediawiki"
140     source "LocalSettings.php.erb"
141     owner node[:mediawiki][:user]
142     group node[:mediawiki][:group]
143     mode "664"
144     variables :name => new_resource.site,
145               :directory => mediawiki_directory,
146               :database_params => database_params,
147               :mediawiki => mediawiki_params,
148               :secret_key => secret_key
149   end
150
151   service "mediawiki-sitemap@#{new_resource.site}.timer" do
152     action [:enable, :start]
153     only_if { ::File.exist?("#{mediawiki_directory}/LocalSettings.php") }
154   end
155
156   service "mediawiki-jobs@#{new_resource.site}.timer" do
157     action [:enable, :start]
158     only_if { ::File.exist?("#{mediawiki_directory}/LocalSettings.php") }
159   end
160
161   service "mediawiki-email-jobs@#{new_resource.site}.timer" do
162     action [:enable, :start]
163     only_if { ::File.exist?("#{mediawiki_directory}/LocalSettings.php") }
164   end
165
166   service "mediawiki-refresh-links@#{new_resource.site}.timer" do
167     action [:enable, :start]
168     only_if { ::File.exist?("#{mediawiki_directory}/LocalSettings.php") }
169   end
170
171   template "/etc/cron.daily/mediawiki-#{cron_name}-backup" do
172     cookbook "mediawiki"
173     source "mediawiki-backup.cron.erb"
174     owner "root"
175     group "root"
176     mode "700"
177     variables :name => new_resource.site,
178               :directory => site_directory,
179               :database_params => database_params
180     only_if { ::File.exist?("#{mediawiki_directory}/LocalSettings.php") }
181   end
182
183   # MobileFrontend extension is required by MinervaNeue skin
184   mediawiki_extension "MobileFrontend" do
185     site new_resource.site
186     template "mw-ext-MobileFrontend.inc.php.erb"
187     update_site false
188   end
189
190   # MobileFrontend extension is required by MinervaNeue skin
191   mediawiki_skin "MinervaNeue" do
192     site new_resource.site
193     update_site false
194     legacy false
195   end
196
197   mediawiki_skin "CologneBlue" do
198     site new_resource.site
199     update_site false
200     legacy false
201   end
202
203   mediawiki_skin "Modern" do
204     site new_resource.site
205     update_site false
206     legacy false
207   end
208
209   mediawiki_skin "MonoBook" do
210     site new_resource.site
211     update_site false
212     legacy false
213   end
214
215   mediawiki_skin "Vector" do
216     site new_resource.site
217     update_site false
218     legacy false
219   end
220
221   mediawiki_extension "Cite" do
222     site new_resource.site
223     update_site false
224   end
225
226   mediawiki_extension "CiteThisPage" do
227     site new_resource.site
228     update_site false
229   end
230
231   if new_resource.private_accounts || new_resource.private_site
232     mediawiki_extension "ConfirmEdit" do
233       site new_resource.site
234       update_site false
235       action :delete
236     end
237   else
238     mediawiki_extension "ConfirmEdit" do
239       site new_resource.site
240       template "mw-ext-ConfirmEdit.inc.php.erb"
241       variables :public_key => new_resource.hcaptcha_public_key,
242                 :private_key => new_resource.hcaptcha_private_key
243       update_site false
244     end
245   end
246
247   mediawiki_extension "Gadgets" do
248     site new_resource.site
249     update_site false
250   end
251
252   mediawiki_extension "ImageMap" do
253     site new_resource.site
254     update_site false
255   end
256
257   mediawiki_extension "InputBox" do
258     site new_resource.site
259     update_site false
260   end
261
262   mediawiki_extension "Interwiki" do
263     site new_resource.site
264     template "mw-ext-Interwiki.inc.php.erb"
265     update_site false
266   end
267
268   mediawiki_extension "Nuke" do
269     site new_resource.site
270     update_site false
271   end
272
273   mediawiki_extension "ParserFunctions" do
274     site new_resource.site
275     template "mw-ext-ParserFunctions.inc.php.erb"
276     update_site false
277   end
278
279   mediawiki_extension "PdfHandler" do
280     site new_resource.site
281     template "mw-ext-PdfHandler.inc.php.erb"
282     update_site false
283   end
284
285   mediawiki_extension "Poem" do
286     site new_resource.site
287     update_site false
288   end
289
290   mediawiki_extension "Renameuser" do
291     site new_resource.site
292     update_site false
293   end
294
295   mediawiki_extension "SimpleAntiSpam" do
296     site new_resource.site
297     update_site false
298     action :delete
299   end
300
301   mediawiki_extension "SpamBlacklist" do
302     site new_resource.site
303     template "mw-ext-SpamBlacklist.inc.php.erb"
304     update_site false
305   end
306
307   mediawiki_extension "SyntaxHighlight_GeSHi" do
308     site new_resource.site
309     template "mw-ext-SyntaxHighlight.inc.php.erb"
310     update_site false
311   end
312
313   mediawiki_extension "TitleBlacklist" do
314     site new_resource.site
315     template "mw-ext-TitleBlacklist.inc.php.erb"
316     update_site false
317   end
318
319   mediawiki_extension "WikiEditor" do
320     site new_resource.site
321     update_site false
322   end
323
324   mediawiki_extension "Babel" do
325     site new_resource.site
326     template "mw-ext-Babel.inc.php.erb"
327     update_site false
328   end
329
330   mediawiki_extension "CategoryTree" do
331     site new_resource.site
332     update_site false
333   end
334
335   mediawiki_extension "cldr" do
336     site new_resource.site
337     template "mw-ext-cldr.inc.php.erb"
338     update_site false
339   end
340
341   mediawiki_extension "CleanChanges" do
342     site new_resource.site
343     template "mw-ext-CleanChanges.inc.php.erb"
344     update_site false
345   end
346
347   mediawiki_extension "LocalisationUpdate" do
348     site new_resource.site
349     template "mw-ext-LocalisationUpdate.inc.php.erb"
350     update_site false
351   end
352
353   # mediawiki_extension "Translate" do
354   #   site new_resource.site
355   #   template "mw-ext-Translate.inc.php.erb"
356   #   update_site false
357   # end
358
359   mediawiki_extension "UniversalLanguageSelector" do
360     site new_resource.site
361     template "mw-ext-UniversalLanguageSelector.inc.php.erb"
362     update_site false
363   end
364
365   mediawiki_extension "AntiSpoof" do
366     site new_resource.site
367     template "mw-ext-AntiSpoof.inc.php.erb"
368     update_site false
369   end
370
371   mediawiki_extension "AbuseFilter" do
372     site new_resource.site
373     template "mw-ext-AbuseFilter.inc.php.erb"
374     update_site false
375   end
376
377   mediawiki_extension "CheckUser" do
378     site new_resource.site
379     template "mw-ext-CheckUser.inc.php.erb"
380     update_site false
381   end
382
383   mediawiki_extension "DismissableSiteNotice" do
384     site new_resource.site
385     update_site false
386   end
387
388   mediawiki_extension "Elastica" do
389     site new_resource.site
390     update_site false
391   end
392
393   mediawiki_extension "CirrusSearch" do
394     site new_resource.site
395     template "mw-ext-CirrusSearch.inc.php.erb"
396     update_site false
397   end
398
399   mediawiki_extension "osmtaginfo" do
400     site new_resource.site
401     repository "https://github.com/openstreetmap/osmtaginfo.git"
402     tag "live"
403     update_site false
404   end
405
406   mediawiki_extension "OSMCALWikiWidget" do
407     site new_resource.site
408     repository "https://github.com/thomersch/OSMCALWikiWidget.git"
409     tag "live"
410     update_site false
411   end
412
413   mediawiki_extension "DisableAccount" do
414     site new_resource.site
415     template "mw-ext-DisableAccount.inc.php.erb"
416     update_site false
417   end
418
419   mediawiki_extension "VisualEditor" do
420     site new_resource.site
421     template "mw-ext-VisualEditor.inc.php.erb"
422     variables :version => new_resource.version
423     update_site false
424   end
425
426   mediawiki_extension "TemplateData" do
427     site new_resource.site
428     update_site false
429   end
430
431   if new_resource.commons
432     mediawiki_extension "QuickInstantCommons" do
433       site new_resource.site
434       update_site false
435     end
436   else
437     mediawiki_extension "QuickInstantCommons" do
438       site new_resource.site
439       update_site false
440       action :delete
441     end
442   end
443
444   cookbook_file "#{site_directory}/cc-wiki.png" do
445     cookbook "mediawiki"
446     owner node[:mediawiki][:user]
447     group node[:mediawiki][:group]
448     mode "644"
449     backup false
450   end
451
452   cookbook_file "#{site_directory}/googled06a989d1ccc8364.html" do
453     cookbook "mediawiki"
454     owner node[:mediawiki][:user]
455     group node[:mediawiki][:group]
456     mode "644"
457     backup false
458   end
459
460   cookbook_file "#{site_directory}/googlefac54c35e800caab.html" do
461     cookbook "mediawiki"
462     owner node[:mediawiki][:user]
463     group node[:mediawiki][:group]
464     mode "644"
465     backup false
466   end
467
468   ssl_certificate new_resource.site do
469     domains [new_resource.site] + Array(new_resource.aliases)
470   end
471
472   php_fpm new_resource.site do
473     pm_max_children new_resource.fpm_max_children
474     pm_start_servers new_resource.fpm_start_servers
475     pm_min_spare_servers new_resource.fpm_min_spare_servers
476     pm_max_spare_servers new_resource.fpm_max_spare_servers
477     request_terminate_timeout new_resource.fpm_request_terminate_timeout
478     php_admin_values "open_basedir" => "#{site_directory}/:/usr/share/php/:/dev/null:/tmp/"
479     php_values "memory_limit" => "500M",
480                "max_execution_time" => "240",
481                "upload_max_filesize" => "70M",
482                "post_max_size" => "100M"
483     prometheus_port new_resource.fpm_prometheus_port
484   end
485
486   apache_site new_resource.site do
487     cookbook "mediawiki"
488     template "apache.erb"
489     directory site_directory
490     variables :aliases => Array(new_resource.aliases),
491               :private_site => new_resource.private_site
492     reload_apache false
493   end
494
495   # FIXME: needs to run one
496   execute "#{mediawiki_directory}/extensions/CirrusSearch/maintenance/updateSearchIndexConfig.php" do
497     action :nothing
498     command "php extensions/CirrusSearch/maintenance/updateSearchIndexConfig.php"
499     cwd mediawiki_directory
500     user node[:mediawiki][:user]
501     group node[:mediawiki][:group]
502   end
503 end
504
505 action :update do
506   mediawiki_directory = "#{site_directory}/w"
507
508   execute "#{mediawiki_directory}/composer.json" do
509     command "composer update --no-dev"
510     cwd mediawiki_directory
511     user node[:mediawiki][:user]
512     group node[:mediawiki][:group]
513     environment "COMPOSER_HOME" => site_directory
514   end
515
516   template "#{mediawiki_directory}/LocalSettings.php" do
517     cookbook "mediawiki"
518     source "LocalSettings.php.erb"
519     owner node[:mediawiki][:user]
520     group node[:mediawiki][:group]
521     mode "664"
522     variables :name => new_resource.site,
523               :directory => mediawiki_directory,
524               :database_params => database_params,
525               :mediawiki => mediawiki_params,
526               :secret_key => secret_key
527   end
528
529   execute "#{mediawiki_directory}/maintenance/update.php" do
530     action :run
531     command "php maintenance/update.php --quick"
532     cwd mediawiki_directory
533     user node[:mediawiki][:user]
534     group node[:mediawiki][:group]
535     timeout 86400
536   end
537 end
538
539 action :delete do
540   apache_site new_resource.site do
541     action :delete
542     reload_apache false
543   end
544
545   declare_resource :directory, site_directory do
546     action :delete
547     recursive true
548   end
549
550   mysql_database new_resource.database_name do
551     action :drop
552   end
553
554   mysql_user "#{new_resource.database_user}@localhost" do
555     action :drop
556   end
557 end
558
559 action_class do
560   include OpenStreetMap::Mixin::PersistentToken
561
562   def site_directory
563     new_resource.directory || "/srv/#{new_resource.site}"
564   end
565
566   def mediawiki_reference
567     shell_out!("git", "ls-remote", "--refs", "--sort=-version:refname",
568                "https://gerrit.wikimedia.org/r/mediawiki/core.git",
569                "refs/tags/#{new_resource.version}.*")
570       .stdout
571       .split("\n")
572       .first
573       .split("/")
574       .last
575   end
576
577   def cron_name
578     new_resource.site.tr(".", "_")
579   end
580
581   def database_params
582     {
583       :host => "localhost",
584       :name => new_resource.database_name,
585       :username => new_resource.database_user,
586       :password => new_resource.database_password
587     }
588   end
589
590   def mediawiki_params
591     {
592       :sitename => new_resource.sitename,
593       :metanamespace => new_resource.metanamespace,
594       :logo => new_resource.logo,
595       :email_contact => new_resource.email_contact,
596       :email_sender => new_resource.email_sender,
597       :email_sender_name => new_resource.email_sender_name,
598       :commons => new_resource.commons,
599       :skin => new_resource.skin,
600       :site_notice => new_resource.site_notice,
601       :site_readonly => new_resource.site_readonly,
602       :extra_file_extensions => new_resource.extra_file_extensions,
603       :private_accounts => new_resource.private_accounts,
604       :private_site => new_resource.private_site
605     }
606   end
607
608   def secret_key
609     persistent_token("mediawiki", new_resource.site, "wgSecretKey")
610   end
611 end
612
613 def after_created
614   notifies :update, "mediawiki_site[#{site}]"
615   notifies :reload, "service[apache2]" if reload_apache
616 end