@@ -60,7 +60,13 @@ CACHE_DIR = BUILD_DIR.join(".cache")
6060BANLISTS = CACHE_DIR .join(" banlists.txt" )
6161BROKEN_POST_URLS = CACHE_DIR .join(" broken_post_urls.txt" )
6262COMMON_ROOT = Path [" _ohmyvps/alpine/alpine-root" ]
63- MEDIA_BUILD_DIR = BUILD_DIR .join(MEDIA_HOST , " /var/www" , PUBLIC_MEDIA_HOST )
63+
64+ SERVER_MEDIA_DIR = Path [" var/www" ].join(PUBLIC_MEDIA_HOST )
65+ MEDIA_BUILD_DIR = BUILD_DIR .join(MEDIA_HOST , SERVER_MEDIA_DIR )
66+
67+ MIRROR_FROM_TO = [
68+ {MEDIA_HOST , [{MIRROR_HOST , SERVER_MEDIA_DIR }]},
69+ ]
6470
6571USER_AGENT = " Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
6672
@@ -317,6 +323,10 @@ def sync
317323 hosts = all_hosts()
318324 puts(" hosts: #{ hosts } " )
319325
326+ mirror = MIRROR_FROM_TO .map { |source_host , destination_and_files |
327+ {source_host, destination_and_files.select { |destination_host , _ | hosts.includes?(destination_host) }}
328+ }.to_h
329+
320330 common_files = git_ls(COMMON_ROOT )
321331 hosts_files : Hash (String , Set (Path )) = hosts.map { |host |
322332 host_dir = HOSTS_DIR .join(host)
@@ -327,7 +337,7 @@ def sync
327337 hosts.map { |host |
328338 done = Channel (Nil ).new
329339 spawn do
330- sync_host(host, hosts_files, common_files)
340+ sync_host(host, hosts_files: hosts_files , common_files: common_files, mirror_to: mirror[host]? )
331341 done.send(nil )
332342 end
333343 done
@@ -336,7 +346,7 @@ def sync
336346 ok(" sync finished\n " )
337347end
338348
339- def sync_host (host : String , hosts_files : Hash (String , Set (Path )), common_files : Set (Path ))
349+ def sync_host (host : String , * , hosts_files : Hash (String , Set (Path )), common_files : Set (Path ), mirror_to : Array ({ String , Path }) | Nil )
340350 host_files : Set (Path ) = hosts_files[host]
341351 all_hosts_files : Set (Path ) = hosts_files
342352 .flat_map { |_ , files | files.to_a }
@@ -352,6 +362,15 @@ def sync_host(host : String, hosts_files : Hash(String, Set(Path)), common_files
352362 host_build_files = children_recursive(host_build_dir).to_set
353363 filtered_sync(host, host_build_dir, upload: host_build_files) # TODO: with --delete specifically for jekyll ?
354364
365+ unless mirror_to.nil?
366+ mirror_to.each { |destination_host , dir |
367+ mirror_host_files = host_files.select { |i | i.to_s.starts_with?(dir.to_s) }
368+ mirror_host_build_files = host_build_files.select { |i | i.to_s.starts_with?(dir.to_s) }
369+ filtered_sync(destination_host, HOSTS_DIR .join(host), upload: mirror_host_files.to_set)
370+ filtered_sync(destination_host, BUILD_DIR .join(host), upload: mirror_host_build_files.to_set)
371+ }
372+ end
373+
355374 ssh(host, [" sudo etckeeper commit sync 2>>/dev/null" ])
356375end
357376
@@ -1066,23 +1085,25 @@ end
10661085
10671086def check_i2p_host (host : String )
10681087 puts(" checking i2p configuration at #{ host } " )
1069- private_key = File .read_lines(HOSTS_DIR .join(host).join(" etc/i2pd/tunnels.conf" ))
1070- .select { |i | i.starts_with?(" keys =" ) }
1071- .map { |i | i.split(" = " )[1 ] }[0 ]
10721088 service_dir = Path [" /var/lib/i2pd" ]
1089+ private_keys = File .read_lines(HOSTS_DIR .join(host).join(" etc/i2pd/tunnels.conf" ))
1090+ .select { |i | i.starts_with?(" keys =" ) }
1091+ .map { |i | i.split(" = " )[1 ] }
10731092 check_manual_upload(host, owner: " i2pd" , group: " i2pd" , mode: 700 , path: service_dir)
1074- check_manual_upload(host, owner: " i2pd" , group: " i2pd" , mode: 440 , path: service_dir.join(private_key))
1093+ private_keys.each { | i | check_manual_upload(host, owner: " i2pd" , group: " i2pd" , mode: 440 , path: service_dir.join(i)) }
10751094end
10761095
10771096def check_tor_host (host : String )
10781097 puts(" checking tor configuration at #{ host } " )
1079- service_dir = Path [ File .read_lines(HOSTS_DIR .join(host).join(" etc/tor/torrc" ))
1098+ service_dirs = File .read_lines(HOSTS_DIR .join(host).join(" etc/tor/torrc" ))
10801099 .select { |i | i.starts_with?(" HiddenServiceDir" ) }
1081- .map { |i | i.split(" " )[1 ] }[0 ]]
1082- check_manual_upload(host, owner: " tor" , group: " tor" , mode: 700 , path: service_dir)
1083- check_manual_upload(host, owner: " tor" , group: " tor" , mode: 400 , path: service_dir.join(" hs_ed25519_secret_key" ))
1084- check_manual_upload(host, owner: " tor" , group: " tor" , mode: 400 , path: service_dir.join(" hs_ed25519_public_key" ))
1085- check_manual_upload(host, owner: " tor" , group: " tor" , mode: 400 , path: service_dir.join(" hostname" ), data: service_dir.basename)
1100+ .map { |i | Path [i.split(" " )[1 ]] }
1101+ service_dirs.map { |i |
1102+ check_manual_upload(host, owner: " tor" , group: " tor" , mode: 700 , path: i)
1103+ check_manual_upload(host, owner: " tor" , group: " tor" , mode: 400 , path: i.join(" hs_ed25519_secret_key" ))
1104+ check_manual_upload(host, owner: " tor" , group: " tor" , mode: 400 , path: i.join(" hs_ed25519_public_key" ))
1105+ check_manual_upload(host, owner: " tor" , group: " tor" , mode: 400 , path: i.join(" hostname" ), data: i.basename)
1106+ }
10861107end
10871108
10881109def check_ssh_hosts (ps : Array (Tuple (Int64 , String )))
@@ -1132,12 +1153,15 @@ def check_existing_ssh_connection(host : String, ps : Array(Tuple(Int64, String)
11321153end
11331154
11341155def check_manual_upload (host : String , * , owner : String , group : String , mode : UInt16 , path : Path , data : String ? = nil )
1135- raise " #{ path } : unexpected owner" unless ssh(host, [" sudo stat -c %U #{ path } " ]) == owner
1136- raise " #{ path } : unexpected group" unless ssh(host, [" sudo stat -c %G #{ path } " ]) == group
1137- raise " #{ path } : unexpected mode" unless ssh(host, [" sudo stat -c %a #{ path } " ]).to_i == mode
1138- unless data.nil?
1139- raise " #{ path } : unexpected data" unless ssh(host, [" sudo cat #{ path } " ]).strip == data
1140- end
1156+ commands = [" stat -c %U,%G,%a" ]
1157+ commands += [" cat" ] unless data.nil?
1158+ output = ssh(host, commands.map { |i | " sudo #{ i } #{ path } " }).strip.split('\n' )
1159+ stat = output[0 ].split(',' )
1160+
1161+ raise " #{ path } : unexpected owner" unless stat[0 ] == owner
1162+ raise " #{ path } : unexpected group" unless stat[1 ] == group
1163+ raise " #{ path } : unexpected mode" unless stat[2 ].to_i == mode
1164+ raise " #{ path } : unexpected data" unless data.nil? || output[1 ] == data
11411165end
11421166
11431167def sync_nostr (config, * , profiles : Bool , output_relays : Array (String ))
0 commit comments