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