@@ -100,12 +100,73 @@ def safe_rmtree(directory: str) -> bool:
100100 f"{ Fore .RED } Permission denied when removing { directory } . Please ensure no files are in use and you have proper permissions.{ Style .RESET_ALL } "
101101 )
102102 return False
103+
104+
105+ def cleanup_multiproxy_instances_dir (
106+ instances_dir : str = "m4b_proxy_instances" ,
107+ backup_root : str = ".backup" ,
108+ ) -> None :
109+ """
110+ Clean up multiproxy instances directory when multiproxy is disabled.
111+
112+ Behavior:
113+ - If directory does not exist: no-op
114+ - If directory is empty: remove it
115+ - If directory has content: move it to a timestamped backup folder
116+
117+ Args:
118+ instances_dir (str): Path to multiproxy instances directory.
119+ backup_root (str): Path to backup root directory.
120+ """
121+ if not os .path .isdir (instances_dir ):
122+ logging .info (
123+ "No multiproxy instances directory found. Nothing to clean up."
124+ )
125+ return
126+
127+ try :
128+ entries = os .listdir (instances_dir )
103129 except Exception as e :
104- logging .error (f"Failed to remove directory { directory } : { str (e )} " )
130+ logging .error (
131+ f"Unable to inspect multiproxy instances directory '{ instances_dir } ': { str (e )} "
132+ )
133+ return
134+
135+ if not entries :
136+ if safe_rmtree (instances_dir ):
137+ print (
138+ f"{ Fore .GREEN } Removed empty multiproxy instances directory '{ instances_dir } '.{ Style .RESET_ALL } "
139+ )
140+ logging .info (
141+ f"Removed empty multiproxy instances directory '{ instances_dir } '."
142+ )
143+ return
144+
145+ timestamp = time .strftime ("%Y%m%d_%H%M%S" )
146+ backup_base_dir = os .path .join (backup_root , "m4b_proxy_instances" )
147+ os .makedirs (backup_base_dir , exist_ok = True )
148+ backup_dir = os .path .join (backup_base_dir , f"instances_{ timestamp } " )
149+
150+ suffix = 1
151+ while os .path .exists (backup_dir ):
152+ backup_dir = os .path .join (backup_base_dir , f"instances_{ timestamp } _{ suffix } " )
153+ suffix += 1
154+
155+ try :
156+ shutil .move (instances_dir , backup_dir )
105157 print (
106- f"{ Fore .RED } Failed to remove directory { directory } : { str (e )} { Style .RESET_ALL } "
158+ f"{ Fore .YELLOW } Multiproxy disabled: moved existing instances to '{ backup_dir } '.{ Style .RESET_ALL } "
159+ )
160+ logging .info (
161+ f"Multiproxy disabled. Moved '{ instances_dir } ' to backup '{ backup_dir } '."
162+ )
163+ except Exception as e :
164+ logging .error (
165+ f"Failed to move multiproxy instances directory '{ instances_dir } ' to backup: { str (e )} "
166+ )
167+ print (
168+ f"{ Fore .RED } Failed to back up multiproxy instances directory '{ instances_dir } '.{ Style .RESET_ALL } "
107169 )
108- return False
109170
110171
111172def ipv4_to_int (ip_address : str ) -> int :
@@ -745,7 +806,7 @@ def setup_watchtower(user_config: dict[str, Any]) -> None:
745806 if ask_question_yn (
746807 "Do you want M4B to manage container auto-updates via its built-in Watchtower?\n "
747808 "(Disable only if another Watchtower instance is already running on this host)" ,
748- default = current_enabled ,
809+ default = True ,
749810 ):
750811 watchtower_config ["enabled" ] = True
751812 print ("M4B built-in Watchtower enabled. Container images will be auto-updated." )
@@ -1074,6 +1135,7 @@ def main(app_config_path: str, m4b_config_path: str, user_config_path: str) -> N
10741135 user_config ["proxies" ]["url" ] = ""
10751136 user_config ["proxies" ]["enabled" ] = False
10761137 write_json (user_config , user_config_path )
1138+ cleanup_multiproxy_instances_dir ()
10771139 assemble_docker_compose (
10781140 m4b_config_path ,
10791141 app_config_path ,
0 commit comments