@@ -273,6 +273,11 @@ fn configure_owned_windows_podman_for_compose(
273273 configure_host_gateway_after_start ( & mut run, true )
274274}
275275
276+ /// Run before Compose even when an existing engine skipped the install/start steps.
277+ pub fn prepare_for_compose ( address : & Address ) -> Result < ( ) , String > {
278+ configure_owned_windows_podman_for_compose ( address, podman, cfg ! ( target_os = "windows" ) )
279+ }
280+
276281fn owned_windows_podman_address ( address : & Address , target_is_windows : bool ) -> bool {
277282 target_is_windows
278283 && address. engine == Engine :: Podman
@@ -301,10 +306,17 @@ fn validate_host_gateway_ip(ip: Ipv4Addr) -> Result<Ipv4Addr, String> {
301306
302307fn host_gateway_config_script ( ip : Ipv4Addr ) -> String {
303308 format ! (
304- "mkdir -p \" $HOME/.config/containers/containers.conf.d\" && \
305- tmp=\" $HOME/{HOST_GATEWAY_CONFIG}.tmp\" && \
309+ "set -e; \
310+ mkdir -p \" $HOME/.config/containers/containers.conf.d\" ; \
311+ target=\" $HOME/{HOST_GATEWAY_CONFIG}\" ; \
312+ tmp=\" $target.tmp\" ; \
306313 cat > \" $tmp\" <<'EOF'\n [containers]\n host_containers_internal_ip=\" {ip}\" \n EOF\n \
307- mv \" $tmp\" \" $HOME/{HOST_GATEWAY_CONFIG}\" "
314+ if [ -f \" $target\" ] && cmp -s \" $tmp\" \" $target\" ; then \
315+ rm \" $tmp\" ; \
316+ else \
317+ mv \" $tmp\" \" $target\" ; \
318+ systemctl --user try-restart podman.service; \
319+ fi"
308320 )
309321}
310322
@@ -792,26 +804,52 @@ mod tests {
792804
793805 #[ test]
794806 #[ cfg( unix) ]
795- fn joined_podman_ssh_write_command_creates_expected_host_config ( ) {
796- let home = temp_root ( "openbot-host-gateway-home" ) ;
807+ fn joined_podman_ssh_write_command_restarts_api_only_when_config_changes ( ) {
808+ let root = temp_root ( "openbot-host-gateway-home" ) ;
809+ let home = root. join ( "home" ) ;
810+ let bin = root. join ( "bin" ) ;
797811 std:: fs:: create_dir_all ( & home) . unwrap ( ) ;
812+ std:: fs:: create_dir_all ( & bin) . unwrap ( ) ;
813+ let calls = root. join ( "systemctl-calls" ) ;
814+ let fake_systemctl = bin. join ( "systemctl" ) ;
815+ std:: fs:: write (
816+ & fake_systemctl,
817+ format ! ( "#!/bin/sh\n printf '%s\n ' \" $*\" >> '{}'\n " , calls. display( ) ) ,
818+ )
819+ . unwrap ( ) ;
820+ {
821+ use std:: os:: unix:: fs:: PermissionsExt ;
822+ std:: fs:: set_permissions ( & fake_systemctl, std:: fs:: Permissions :: from_mode ( 0o755 ) )
823+ . unwrap ( ) ;
824+ }
798825 let command = host_gateway_config_script ( "192.168.127.254" . parse ( ) . unwrap ( ) ) ;
799826 let joined_remote_command = [ command. as_str ( ) ] . join ( " " ) ;
827+ let path = format ! (
828+ "{}:{}" ,
829+ bin. display( ) ,
830+ std:: env:: var( "PATH" ) . unwrap_or_default( )
831+ ) ;
800832
801- let status = std:: process:: Command :: new ( "sh" )
802- . arg ( "-c" )
803- . arg ( & joined_remote_command)
804- . env ( "HOME" , & home)
805- . status ( )
806- . expect ( "execute joined remote command under sh" ) ;
833+ for _ in 0 ..2 {
834+ let status = std:: process:: Command :: new ( "sh" )
835+ . arg ( "-c" )
836+ . arg ( & joined_remote_command)
837+ . env ( "HOME" , & home)
838+ . env ( "PATH" , & path)
839+ . status ( )
840+ . expect ( "execute joined remote command under sh" ) ;
841+
842+ assert ! ( status. success( ) , "joined command failed: {status}" ) ;
843+ }
807844
808- assert ! ( status. success( ) , "joined command failed: {status}" ) ;
809845 let written = std:: fs:: read_to_string ( home. join ( HOST_GATEWAY_CONFIG ) ) . unwrap ( ) ;
810846 assert_eq ! (
811847 written,
812848 "[containers]\n host_containers_internal_ip=\" 192.168.127.254\" \n "
813849 ) ;
814- let _ = std:: fs:: remove_dir_all ( home) ;
850+ let systemctl_calls = std:: fs:: read_to_string ( & calls) . unwrap ( ) ;
851+ assert_eq ! ( systemctl_calls, "--user try-restart podman.service\n " ) ;
852+ let _ = std:: fs:: remove_dir_all ( root) ;
815853 }
816854
817855 #[ test]
0 commit comments