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