5 # Copyright:: 2013, OpenStreetMap Foundation
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
11 # https://www.apache.org/licenses/LICENSE-2.0
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.
20 include_recipe "accounts"
21 include_recipe "apache"
23 include_recipe "munin"
24 include_recipe "nodejs"
25 include_recipe "postgresql"
26 include_recipe "prometheus"
27 include_recipe "python"
29 include_recipe "tools"
31 blocks = data_bag_item("tile", "blocks")
32 web_passwords = data_bag_item("web", "passwords")
36 apache_module "expires"
37 apache_module "headers"
38 apache_module "remoteip"
39 apache_module "rewrite"
41 apache_module "tile" do
45 apache_conf "renderd" do
49 ssl_certificate node[:fqdn] do
50 domains [node[:fqdn], "tile.openstreetmap.org", "render.openstreetmap.org"]
51 notifies :reload, "service[apache2]"
54 remote_file "#{Chef::Config[:file_cache_path]}/fastly-ip-list.json" do
55 source "https://api.fastly.com/public-ip-list"
60 fastlyips = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/fastly-ip-list.json"))
62 apache_site "default" do
66 apache_site "tileserver_site" do
70 apache_site "tile.openstreetmap.org" do
72 variables :fastly => fastlyips["addresses"]
75 template "/etc/logrotate.d/apache2" do
76 source "logrotate.apache.erb"
82 directory "/srv/tile.openstreetmap.org" do
88 directory "/srv/tile.openstreetmap.org/conf" do
94 file "/srv/tile.openstreetmap.org/conf/ip.map" do
102 systemd_service "renderd" do
104 after "postgresql.service"
105 wants "postgresql.service"
110 protect_system "full"
112 no_new_privileges true
116 systemd_service "renderd" do
121 action [:enable, :start]
122 subscribes :restart, "systemd_service[renderd]"
125 directory "/srv/tile.openstreetmap.org/tiles" do
131 template "/etc/renderd.conf" do
132 source "renderd.conf.erb"
136 notifies :reload, "service[apache2]"
137 notifies :restart, "service[renderd]"
140 remote_directory "/srv/tile.openstreetmap.org/html" do
150 template "/srv/tile.openstreetmap.org/html/index.html" do
151 source "index.html.erb"
164 python_package "pyotp" do
168 unifont = if node[:lsb][:release].to_f < 22.04
182 ["NotoSansArabicUI-Regular.ttf", "NotoSansArabicUI-Bold.ttf"].each do |font|
183 remote_file "/usr/share/fonts/truetype/noto/#{font}" do
184 action :create_if_missing
185 source "https://github.com/googlei18n/noto-fonts/raw/master/hinted/#{font}"
192 directory "/srv/tile.openstreetmap.org/cgi-bin" do
198 template "/srv/tile.openstreetmap.org/cgi-bin/export" do
203 variables :blocks => blocks, :totp_key => web_passwords["totp_key"]
206 template "/srv/tile.openstreetmap.org/cgi-bin/debug" do
213 template "/etc/cron.hourly/export" do
214 source "export.cron.erb"
220 directory "/srv/tile.openstreetmap.org/data" do
226 package "mapnik-utils"
228 node[:tile][:data].each_value do |data|
230 file = "/srv/tile.openstreetmap.org/data/#{File.basename(url)}"
233 directory = "/srv/tile.openstreetmap.org/data/#{data[:directory]}"
235 directory directory do
241 directory = "/srv/tile.openstreetmap.org/data"
249 command "tar -zxf #{file} -C #{directory}"
253 elsif file =~ /\.tar\.bz2$/
258 command "tar -jxf #{file} -C #{directory}"
262 elsif file =~ /\.zip$/
267 command "unzip -qq -o #{file} -d #{directory}"
273 execute "#{file}_shapeindex" do
275 command "find #{directory} -type f -iname '*.shp' -print0 | xargs -0 --no-run-if-empty shapeindex --shape_files"
278 subscribes :run, "execute[#{file}]", :immediately
284 use_conditional_get true
287 action :create_if_missing
295 notifies :run, "execute[#{file}]", :immediately
296 notifies :restart, "service[renderd]"
300 nodejs_package "carto"
302 systemd_service "update-lowzoom@" do
303 description "Low zoom tile update service for %i layer"
304 conflicts "render-lowzoom.service"
306 exec_start "/bin/bash /usr/local/bin/update-lowzoom-%i"
307 runtime_directory "update-lowzoom-%i"
311 protect_system "full"
313 no_new_privileges true
317 directory "/srv/tile.openstreetmap.org/styles" do
323 node[:tile][:styles].each do |name, details|
324 style_directory = "/srv/tile.openstreetmap.org/styles/#{name}"
325 tile_directory = "/srv/tile.openstreetmap.org/tiles/#{name}"
327 template "/usr/local/bin/update-lowzoom-#{name}" do
328 source "update-lowzoom.erb"
332 variables :style => name
335 service "update-lowzoom@#{name}" do
337 supports :restart => true
340 directory tile_directory do
346 details[:tile_directories].each do |directory|
347 directory directory[:name] do
353 directory[:min_zoom].upto(directory[:max_zoom]) do |zoom|
354 directory "#{directory[:name]}/#{zoom}" do
360 link "#{tile_directory}/#{zoom}" do
361 to "#{directory[:name]}/#{zoom}"
368 file "#{tile_directory}/planet-import-complete" do
369 action :create_if_missing
375 git style_directory do
377 repository details[:repository]
378 revision details[:revision]
383 link "#{style_directory}/data" do
384 to "/srv/tile.openstreetmap.org/data"
389 execute "#{style_directory}/project.mml" do
391 command "carto -a 3.0.0 project.mml > project.xml"
395 subscribes :run, "git[#{style_directory}]"
396 notifies :restart, "service[renderd]", :immediately
397 notifies :restart, "service[update-lowzoom@#{name}]"
401 postgresql_version = node[:tile][:database][:cluster].split("/").first
402 postgis_version = node[:tile][:database][:postgis]
404 package "postgresql-#{postgresql_version}-postgis-#{postgis_version}"
406 postgresql_user "jburgess" do
407 cluster node[:tile][:database][:cluster]
411 postgresql_user "tomh" do
412 cluster node[:tile][:database][:cluster]
416 postgresql_user "tile" do
417 cluster node[:tile][:database][:cluster]
420 postgresql_user "www-data" do
421 cluster node[:tile][:database][:cluster]
424 postgresql_user "_renderd" do
425 cluster node[:tile][:database][:cluster]
428 postgresql_database "gis" do
429 cluster node[:tile][:database][:cluster]
433 postgresql_extension "postgis" do
434 cluster node[:tile][:database][:cluster]
438 postgresql_extension "hstore" do
439 cluster node[:tile][:database][:cluster]
441 only_if { node[:tile][:database][:hstore] }
444 %w[geography_columns planet_osm_nodes planet_osm_rels planet_osm_ways raster_columns raster_overviews spatial_ref_sys].each do |table|
445 postgresql_table table do
446 cluster node[:tile][:database][:cluster]
449 permissions "tile" => :all
453 %w[geometry_columns planet_osm_line planet_osm_point planet_osm_polygon planet_osm_roads].each do |table|
454 postgresql_table table do
455 cluster node[:tile][:database][:cluster]
458 permissions "tile" => :all, "www-data" => :select, "_renderd" => :select
468 if node[:tile][:database][:external_data_script]
469 execute node[:tile][:database][:external_data_script] do
470 command "#{node[:tile][:database][:external_data_script]} -R _renderd"
471 cwd "/srv/tile.openstreetmap.org"
477 Array(node[:tile][:database][:external_data_tables]).each do |table|
478 postgresql_table table do
479 cluster node[:tile][:database][:cluster]
482 permissions "tile" => :all, "www-data" => :select, "_renderd" => :select
487 postgresql_munin "gis" do
488 cluster node[:tile][:database][:cluster]
492 directory File.dirname(node[:tile][:database][:node_file]) do
499 file node[:tile][:database][:node_file] do
505 directory "/var/log/tile" do
518 gem_package "apachelogregex" do
519 gem_binary node[:ruby][:gem]
522 gem_package "file-tail" do
523 gem_binary node[:ruby][:gem]
526 gem_package "lru_redux" do
527 gem_binary node[:ruby][:gem]
530 remote_directory "/usr/local/bin" do
540 template "/usr/local/bin/tile-ratelimit" do
541 source "tile-ratelimit.erb"
547 systemd_service "tile-ratelimit" do
548 description "Monitor tile requests and enforce rate limits"
549 after "apache2.service"
552 exec_start "/usr/local/bin/tile-ratelimit"
556 protect_system "full"
558 read_write_paths "/srv/tile.openstreetmap.org/conf"
559 no_new_privileges true
563 service "tile-ratelimit" do
564 action [:enable, :start]
565 subscribes :restart, "file[/usr/local/bin/tile-ratelimit]"
566 subscribes :restart, "systemd_service[tile-ratelimit]"
569 template "/usr/local/bin/expire-tiles" do
570 source "expire-tiles.erb"
576 directory "/var/lib/replicate" do
582 directory "/var/lib/replicate/expire-queue" do
588 template "/usr/local/bin/replicate" do
589 source "replicate.erb"
593 variables :postgresql_version => postgresql_version.to_f
596 systemd_service "expire-tiles" do
597 description "Tile dirtying service"
600 exec_start "/usr/local/bin/expire-tiles"
601 standard_output "null"
604 protect_system "full"
606 no_new_privileges true
609 systemd_path "expire-tiles" do
610 description "Tile dirtying trigger"
611 directory_not_empty "/var/lib/replicate/expire-queue"
614 service "expire-tiles.path" do
615 action [:enable, :start]
616 subscribes :restart, "systemd_path[expire-tiles]"
619 systemd_service "replicate" do
620 description "Rendering database replication service"
621 after "postgresql.service"
622 wants "postgresql.service"
624 exec_start "/usr/local/bin/replicate"
627 protect_system "full"
629 no_new_privileges true
633 service "replicate" do
634 action [:enable, :start]
635 subscribes :restart, "template[/usr/local/bin/replicate]"
636 subscribes :restart, "systemd_service[replicate]"
639 template "/etc/logrotate.d/replicate" do
640 source "replicate.logrotate.erb"
646 template "/usr/local/bin/render-lowzoom" do
647 source "render-lowzoom.erb"
653 systemd_service "render-lowzoom" do
654 description "Render low zoom tiles"
655 condition_path_exists_glob "!/run/update-lowzoom-*"
657 exec_start "/usr/local/bin/render-lowzoom"
661 protect_system "full"
663 no_new_privileges true
666 systemd_timer "render-lowzoom" do
667 description "Render low zoom tiles"
668 on_calendar "Fri *-*-* 23:00:00 UTC"
671 service "render-lowzoom.timer" do
672 action [:enable, :start]
675 package "liblockfile-simple-perl"
676 package "libfilesys-df-perl"
678 template "/usr/local/bin/cleanup-tiles" do
679 source "cleanup-tiles.erb"
685 tile_directories = node[:tile][:styles].collect do |_, style|
686 style[:tile_directories].collect { |directory| directory[:name] }
687 end.flatten.sort.uniq
689 tile_directories.each do |directory|
690 label = directory.gsub("/", "-")
692 cron_d "cleanup-tiles#{label}" do
695 command "ionice -c 3 /usr/local/bin/cleanup-tiles #{directory}"
696 mailto "admins@openstreetmap.org"
700 munin_plugin "mod_tile_fresh"
701 munin_plugin "mod_tile_latency"
702 munin_plugin "mod_tile_response"
703 munin_plugin "mod_tile_zoom"
705 munin_plugin "renderd_processed"
706 munin_plugin "renderd_queue"
707 munin_plugin "renderd_queue_time"
708 munin_plugin "renderd_zoom"
709 munin_plugin "renderd_zoom_time"
711 munin_plugin "replication_delay"
713 package "ruby-webrick"
715 prometheus_exporter "modtile" do
719 prometheus_exporter "renderd" do