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