]> git.openstreetmap.org Git - chef.git/blob - cookbooks/tile/recipes/default.rb
963c3dd2f5b075e4485f4d453a354c264bbff3e6
[chef.git] / cookbooks / tile / recipes / default.rb
1 #
2 # Cookbook:: tile
3 # Recipe:: default
4 #
5 # Copyright:: 2013, 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 include_recipe "accounts"
21 include_recipe "apache"
22 include_recipe "git"
23 include_recipe "munin"
24 include_recipe "nodejs"
25 include_recipe "postgresql"
26 include_recipe "prometheus"
27 include_recipe "python"
28 include_recipe "ruby"
29 include_recipe "tools"
30
31 blocks = data_bag_item("tile", "blocks")
32 web_passwords = data_bag_item("web", "passwords")
33
34 apache_module "alias"
35 apache_module "cgi"
36 apache_module "expires"
37 apache_module "headers"
38 apache_module "remoteip"
39 apache_module "rewrite"
40
41 apache_module "tile" do
42   conf "tile.conf.erb"
43 end
44
45 apache_conf "renderd" do
46   action :disable
47 end
48
49 ssl_certificate node[:fqdn] do
50   domains [node[:fqdn], "tile.openstreetmap.org", "render.openstreetmap.org"]
51   notifies :reload, "service[apache2]"
52 end
53
54 remote_file "#{Chef::Config[:file_cache_path]}/fastly-ip-list.json" do
55   source "https://api.fastly.com/public-ip-list"
56   compile_time true
57   ignore_failure true
58 end
59
60 fastlyips = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/fastly-ip-list.json"))
61
62 apache_site "default" do
63   action :disable
64 end
65
66 apache_site "tileserver_site" do
67   action :disable
68 end
69
70 apache_site "tile.openstreetmap.org" do
71   template "apache.erb"
72   variables :fastly => fastlyips["addresses"]
73 end
74
75 template "/etc/logrotate.d/apache2" do
76   source "logrotate.apache.erb"
77   owner "root"
78   group "root"
79   mode "644"
80 end
81
82 directory "/srv/tile.openstreetmap.org" do
83   owner "tile"
84   group "tile"
85   mode "755"
86 end
87
88 directory "/srv/tile.openstreetmap.org/conf" do
89   owner "tile"
90   group "tile"
91   mode "755"
92 end
93
94 file "/srv/tile.openstreetmap.org/conf/ip.map" do
95   owner "tile"
96   group "adm"
97   mode "644"
98 end
99
100 package "renderd"
101
102 systemd_service "renderd" do
103   dropin "chef"
104   after "postgresql.service"
105   wants "postgresql.service"
106   limit_nofile 4096
107   sandbox true
108   restrict_address_families "AF_UNIX"
109   read_write_paths "/store/tiles"
110   restart "on-failure"
111 end
112
113 systemd_service "renderd" do
114   action :delete
115 end
116
117 service "renderd" do
118   action [:enable, :start]
119   subscribes :restart, "systemd_service[renderd]"
120 end
121
122 directory "/srv/tile.openstreetmap.org/tiles" do
123   owner "tile"
124   group "tile"
125   mode "755"
126 end
127
128 template "/etc/renderd.conf" do
129   source "renderd.conf.erb"
130   owner "root"
131   group "root"
132   mode "644"
133   notifies :reload, "service[apache2]"
134   notifies :restart, "service[renderd]"
135 end
136
137 remote_directory "/srv/tile.openstreetmap.org/html" do
138   source "html"
139   owner "tile"
140   group "tile"
141   mode "755"
142   files_owner "tile"
143   files_group "tile"
144   files_mode "644"
145 end
146
147 template "/srv/tile.openstreetmap.org/html/index.html" do
148   source "index.html.erb"
149   owner "tile"
150   group "tile"
151   mode "644"
152 end
153
154 package %w[
155   python3-cairo
156   python3-mapnik
157   python3-pyproj
158   python3-setuptools
159 ]
160
161 python_package "pyotp" do
162   python_version "3"
163 end
164
165 directory "/srv/tile.openstreetmap.org/cgi-bin" do
166   owner "tile"
167   group "tile"
168   mode "755"
169 end
170
171 template "/srv/tile.openstreetmap.org/cgi-bin/export" do
172   source "export.erb"
173   owner "tile"
174   group "tile"
175   mode "755"
176   variables :blocks => blocks, :totp_key => web_passwords["totp_key"]
177 end
178
179 template "/srv/tile.openstreetmap.org/cgi-bin/debug" do
180   source "debug.erb"
181   owner "tile"
182   group "tile"
183   mode "755"
184 end
185
186 template "/etc/cron.hourly/export" do
187   source "export.cron.erb"
188   owner "root"
189   group "root"
190   mode "755"
191 end
192
193 directory "/srv/tile.openstreetmap.org/data" do
194   owner "tile"
195   group "tile"
196   mode "755"
197 end
198
199 package %w[
200   mapnik-utils
201   tar
202   unzip
203 ]
204
205 node[:tile][:data].each_value do |data|
206   url = data[:url]
207   file = "/srv/tile.openstreetmap.org/data/#{File.basename(url)}"
208
209   if data[:directory]
210     directory = "/srv/tile.openstreetmap.org/data/#{data[:directory]}"
211
212     directory directory do
213       owner "tile"
214       group "tile"
215       mode "755"
216     end
217   else
218     directory = "/srv/tile.openstreetmap.org/data"
219   end
220
221   if file =~ /\.tgz$/
222     execute file do
223       action :nothing
224       command "tar -zxf #{file} -C #{directory}"
225       user "tile"
226       group "tile"
227     end
228   elsif file =~ /\.tar\.bz2$/
229     execute file do
230       action :nothing
231       command "tar -jxf #{file} -C #{directory}"
232       user "tile"
233       group "tile"
234     end
235   elsif file =~ /\.zip$/
236     execute file do
237       action :nothing
238       command "unzip -qq -o #{file} -d #{directory}"
239       user "tile"
240       group "tile"
241     end
242   end
243
244   execute "#{file}_shapeindex" do
245     action :nothing
246     command "find #{directory} -type f -iname '*.shp' -print0 | xargs -0 --no-run-if-empty shapeindex --shape_files"
247     user "tile"
248     group "tile"
249     subscribes :run, "execute[#{file}]", :immediately
250   end
251
252   remote_file file do
253     if data[:refresh]
254       action :create
255       use_conditional_get true
256       ignore_failure true
257     else
258       action :create_if_missing
259     end
260
261     source url
262     owner "tile"
263     group "tile"
264     mode "644"
265     backup false
266     notifies :run, "execute[#{file}]", :immediately
267     notifies :restart, "service[renderd]"
268   end
269 end
270
271 nodejs_package "carto"
272
273 systemd_service "update-lowzoom@" do
274   description "Low zoom tile update service for %i layer"
275   user "tile"
276   exec_start_pre "+/bin/systemctl stop render-lowzoom.service"
277   exec_start "/bin/bash /usr/local/bin/update-lowzoom-%i"
278   runtime_directory "update-lowzoom-%i"
279   sandbox true
280   restrict_address_families "AF_UNIX"
281   read_write_paths [
282     "/srv/tile.openstreetmap.org/tiles/%i",
283     "/var/log/tile"
284   ]
285   restart "on-failure"
286 end
287
288 directory "/srv/tile.openstreetmap.org/styles" do
289   owner "tile"
290   group "tile"
291   mode "755"
292 end
293
294 node[:tile][:styles].each do |name, details|
295   style_directory = "/srv/tile.openstreetmap.org/styles/#{name}"
296   tile_directory = "/srv/tile.openstreetmap.org/tiles/#{name}"
297
298   template "/usr/local/bin/update-lowzoom-#{name}" do
299     source "update-lowzoom.erb"
300     owner "root"
301     group "root"
302     mode "755"
303     variables :style => name
304   end
305
306   service "update-lowzoom@#{name}" do
307     action :disable
308     supports :restart => true
309   end
310
311   directory tile_directory do
312     owner "tile"
313     group "tile"
314     mode "755"
315   end
316
317   details[:tile_directories].each do |directory|
318     directory directory[:name] do
319       owner "_renderd"
320       group "_renderd"
321       mode "755"
322     end
323
324     directory[:min_zoom].upto(directory[:max_zoom]) do |zoom|
325       directory "#{directory[:name]}/#{zoom}" do
326         owner "_renderd"
327         group "_renderd"
328         mode "755"
329       end
330
331       link "#{tile_directory}/#{zoom}" do
332         to "#{directory[:name]}/#{zoom}"
333         owner "tile"
334         group "tile"
335       end
336     end
337   end
338
339   file "#{tile_directory}/planet-import-complete" do
340     action :create_if_missing
341     owner "tile"
342     group "tile"
343     mode "444"
344   end
345
346   git style_directory do
347     action :sync
348     repository details[:repository]
349     revision details[:revision]
350     user "tile"
351     group "tile"
352   end
353
354   link "#{style_directory}/data" do
355     to "/srv/tile.openstreetmap.org/data"
356     owner "tile"
357     group "tile"
358   end
359
360   if details[:fonts_script]
361     execute details[:fonts_script] do
362       action :nothing
363       command details[:fonts_script]
364       cwd style_directory
365       user "tile"
366       group "tile"
367       subscribes :run, "git[#{style_directory}]"
368     end
369   end
370
371   execute "#{style_directory}/project.mml" do
372     action :nothing
373     command "carto -a 3.0.22 project.mml > project.xml"
374     cwd style_directory
375     user "tile"
376     group "tile"
377     subscribes :run, "git[#{style_directory}]"
378     notifies :restart, "service[renderd]", :immediately
379     notifies :restart, "service[update-lowzoom@#{name}]"
380   end
381 end
382
383 postgresql_version = node[:tile][:database][:cluster].split("/").first
384 postgis_version = node[:tile][:database][:postgis]
385
386 package "postgresql-#{postgresql_version}-postgis-#{postgis_version}"
387
388 postgresql_user "jburgess" do
389   cluster node[:tile][:database][:cluster]
390   superuser true
391 end
392
393 postgresql_user "tomh" do
394   cluster node[:tile][:database][:cluster]
395   superuser true
396 end
397
398 postgresql_user "pnorman" do
399   cluster node[:tile][:database][:cluster]
400   superuser true
401 end
402
403 postgresql_user "tile" do
404   cluster node[:tile][:database][:cluster]
405 end
406
407 postgresql_user "www-data" do
408   cluster node[:tile][:database][:cluster]
409 end
410
411 postgresql_user "_renderd" do
412   cluster node[:tile][:database][:cluster]
413 end
414
415 postgresql_database "gis" do
416   cluster node[:tile][:database][:cluster]
417   owner "tile"
418 end
419
420 postgresql_extension "postgis" do
421   cluster node[:tile][:database][:cluster]
422   database "gis"
423 end
424
425 postgresql_extension "hstore" do
426   cluster node[:tile][:database][:cluster]
427   database "gis"
428   only_if { node[:tile][:database][:hstore] }
429 end
430
431 %w[geography_columns planet_osm_nodes planet_osm_rels planet_osm_ways raster_columns raster_overviews spatial_ref_sys].each do |table|
432   postgresql_table table do
433     cluster node[:tile][:database][:cluster]
434     database "gis"
435     owner "tile"
436     permissions "tile" => :all
437   end
438 end
439
440 %w[geometry_columns planet_osm_line planet_osm_point planet_osm_polygon planet_osm_roads].each do |table|
441   postgresql_table table do
442     cluster node[:tile][:database][:cluster]
443     database "gis"
444     owner "tile"
445     permissions "tile" => :all, "www-data" => :select, "_renderd" => :select
446   end
447 end
448
449 package %w[
450   gdal-bin
451   python3-yaml
452   python3-psycopg2
453 ]
454
455 if node[:tile][:database][:external_data_script]
456   execute node[:tile][:database][:external_data_script] do
457     command "#{node[:tile][:database][:external_data_script]} -R _renderd"
458     cwd "/srv/tile.openstreetmap.org"
459     user "tile"
460     group "tile"
461     ignore_failure true
462   end
463
464   Array(node[:tile][:database][:external_data_tables]).each do |table|
465     postgresql_table table do
466       cluster node[:tile][:database][:cluster]
467       database "gis"
468       owner "tile"
469       permissions "tile" => :all, "www-data" => :select, "_renderd" => :select
470     end
471   end
472 end
473
474 postgresql_munin "gis" do
475   cluster node[:tile][:database][:cluster]
476   database "gis"
477 end
478
479 directory File.dirname(node[:tile][:database][:node_file]) do
480   owner "root"
481   group "root"
482   mode "755"
483   recursive true
484 end
485
486 file node[:tile][:database][:node_file] do
487   owner "tile"
488   group "_renderd"
489   mode "660"
490 end
491
492 directory "/var/log/tile" do
493   owner "tile"
494   group "tile"
495   mode "755"
496 end
497
498 package %w[
499   osm2pgsql
500   osmium-tool
501   pyosmium
502   python3-pyproj
503 ]
504
505 gem_package "apachelogregex" do
506   gem_binary node[:ruby][:gem]
507 end
508
509 gem_package "file-tail" do
510   gem_binary node[:ruby][:gem]
511 end
512
513 gem_package "lru_redux" do
514   gem_binary node[:ruby][:gem]
515 end
516
517 remote_directory "/usr/local/bin" do
518   source "bin"
519   owner "root"
520   group "root"
521   mode "755"
522   files_owner "root"
523   files_group "root"
524   files_mode "755"
525 end
526
527 template "/usr/local/bin/tile-ratelimit" do
528   source "tile-ratelimit.erb"
529   owner "root"
530   group "root"
531   mode "755"
532 end
533
534 systemd_service "tile-ratelimit" do
535   description "Monitor tile requests and enforce rate limits"
536   after "apache2.service"
537   user "tile"
538   group "adm"
539   exec_start "/usr/local/bin/tile-ratelimit"
540   nice 10
541   sandbox true
542   read_write_paths "/srv/tile.openstreetmap.org/conf"
543   restart "on-failure"
544 end
545
546 service "tile-ratelimit" do
547   action [:enable, :start]
548   subscribes :restart, "file[/usr/local/bin/tile-ratelimit]"
549   subscribes :restart, "systemd_service[tile-ratelimit]"
550 end
551
552 template "/usr/local/bin/expire-tiles" do
553   source "expire-tiles.erb"
554   owner "root"
555   group "root"
556   mode "755"
557 end
558
559 directory "/var/lib/replicate" do
560   owner "tile"
561   group "tile"
562   mode "755"
563 end
564
565 directory "/var/lib/replicate/expire-queue" do
566   owner "tile"
567   group "_renderd"
568   mode "775"
569 end
570
571 template "/usr/local/bin/replicate" do
572   source "replicate.erb"
573   owner "root"
574   group "root"
575   mode "755"
576   variables :postgresql_version => postgresql_version.to_f
577 end
578
579 systemd_service "expire-tiles" do
580   description "Tile dirtying service"
581   type "simple"
582   user "_renderd"
583   exec_start "/usr/local/bin/expire-tiles"
584   nice 10
585   standard_output "null"
586   sandbox true
587   read_write_paths [
588     "/store/database/nodes",
589     "/store/tiles/%i",
590     "/var/lib/replicate/expire-queue",
591     "/var/log/tile"
592   ]
593 end
594
595 systemd_path "expire-tiles" do
596   description "Tile dirtying trigger"
597   directory_not_empty "/var/lib/replicate/expire-queue"
598 end
599
600 service "expire-tiles.path" do
601   action [:enable, :start]
602   subscribes :restart, "systemd_path[expire-tiles]"
603 end
604
605 systemd_service "replicate" do
606   description "Rendering database replication service"
607   after "postgresql.service"
608   wants "postgresql.service"
609   user "tile"
610   exec_start "/usr/local/bin/replicate"
611   sandbox :enable_network => true
612   restrict_address_families "AF_UNIX"
613   read_write_paths [
614     "/store/database/nodes",
615     "/var/lib/replicate",
616     "/var/log/tile"
617   ]
618   restart "on-failure"
619 end
620
621 service "replicate" do
622   action [:enable, :start]
623   subscribes :restart, "template[/usr/local/bin/replicate]"
624   subscribes :restart, "systemd_service[replicate]"
625 end
626
627 template "/etc/logrotate.d/replicate" do
628   source "replicate.logrotate.erb"
629   owner "root"
630   group "root"
631   mode "644"
632 end
633
634 template "/usr/local/bin/render-lowzoom" do
635   source "render-lowzoom.erb"
636   owner "root"
637   group "root"
638   mode "755"
639 end
640
641 systemd_service "render-lowzoom" do
642   description "Render low zoom tiles"
643   condition_path_exists_glob "!/run/update-lowzoom-*"
644   user "tile"
645   exec_start "/usr/local/bin/render-lowzoom"
646   sandbox true
647   restrict_address_families "AF_UNIX"
648   read_write_paths "/var/log/tile"
649 end
650
651 systemd_timer "render-lowzoom" do
652   description "Render low zoom tiles"
653   on_calendar "Fri *-*-* 23:00:00 UTC"
654 end
655
656 service "render-lowzoom.timer" do
657   action [:enable, :start]
658 end
659
660 package "liblockfile-simple-perl"
661 package "libfilesys-df-perl"
662
663 template "/usr/local/bin/cleanup-tiles" do
664   source "cleanup-tiles.erb"
665   owner "root"
666   group "root"
667   mode "755"
668 end
669
670 tile_directories = node[:tile][:styles].collect do |_, style|
671   style[:tile_directories].collect { |directory| directory[:name] }
672 end.flatten.sort.uniq
673
674 tile_directories.each do |directory|
675   label = directory.gsub("/", "-")
676
677   cron_d "cleanup-tiles#{label}" do
678     minute "0"
679     user "_renderd"
680     command "ionice -c 3 /usr/local/bin/cleanup-tiles #{directory}"
681     mailto "admins@openstreetmap.org"
682   end
683 end
684
685 munin_plugin "mod_tile_fresh"
686 munin_plugin "mod_tile_latency"
687 munin_plugin "mod_tile_response"
688 munin_plugin "mod_tile_zoom"
689
690 munin_plugin "renderd_processed"
691 munin_plugin "renderd_queue"
692 munin_plugin "renderd_queue_time"
693 munin_plugin "renderd_zoom"
694 munin_plugin "renderd_zoom_time"
695
696 munin_plugin "replication_delay"
697
698 package "ruby-webrick"
699
700 prometheus_exporter "modtile" do
701   port 9494
702 end
703
704 prometheus_exporter "renderd" do
705   port 9393
706 end