@@ -41,20 +41,68 @@ def install_plugin(self) -> bool:
4141
4242 print (f"Installing certbot plugin: { self .provider .CERTBOT_PACKAGE } " )
4343
44- # Use virtual environment pip if available
45- pip_cmd = ["pip" , "install" , self .provider .CERTBOT_PACKAGE ]
44+ # Try multiple installation methods
45+ install_methods = []
46+
47+ # Method 1: Use the same python executable that's running this script
48+ import sys
49+ install_methods .append ([sys .executable , "-m" , "pip" , "install" , self .provider .CERTBOT_PACKAGE ])
50+
51+ # Method 2: Use virtual environment pip if available
4652 if "VIRTUAL_ENV" in os .environ :
4753 venv_pip = os .path .join (os .environ ["VIRTUAL_ENV" ], "bin" , "pip" )
4854 if os .path .exists (venv_pip ):
49- pip_cmd [0 ] = venv_pip
50-
51- try :
52- result = subprocess .run (pip_cmd , capture_output = True , text = True )
53- if result .returncode != 0 :
54- print (f"Failed to install plugin: { result .stderr } " , file = sys .stderr )
55- return False
55+ install_methods .append ([venv_pip , "install" , self .provider .CERTBOT_PACKAGE ])
56+
57+ # Method 3: Use system pip
58+ install_methods .append (["pip" , "install" , self .provider .CERTBOT_PACKAGE ])
59+
60+ # Method 4: Use pip3
61+ install_methods .append (["pip3" , "install" , self .provider .CERTBOT_PACKAGE ])
62+
63+ success = False
64+ for i , pip_cmd in enumerate (install_methods ):
65+ print (f"Trying installation method { i + 1 } " )
66+ print (f"Command: { ' ' .join (pip_cmd )} " )
67+ try :
68+ result = subprocess .run (pip_cmd , capture_output = True , text = True )
69+ if result .returncode == 0 :
70+ print (f"Installation method { i + 1 } succeeded" )
71+ success = True
72+ break
73+ else :
74+ print (f"Installation method { i + 1 } failed: { result .stderr } " )
75+ except Exception as e :
76+ print (f"Installation method { i + 1 } exception: { e } " )
77+
78+ if not success :
79+ print (f"All installation methods failed" , file = sys .stderr )
80+ return False
5681 print (f"Successfully installed { self .provider .CERTBOT_PACKAGE } " )
5782
83+ # Add diagnostic information
84+ try :
85+ print ("=== Diagnostic Information ===" )
86+ # Check which Python executable is being used
87+ import sys
88+ print (f"Python executable: { sys .executable } " )
89+ print (f"Python version: { sys .version } " )
90+
91+ # Check where the package was installed
92+ import pkg_resources
93+ try :
94+ dist = pkg_resources .get_distribution ("certbot-dns-namecheap" )
95+ print (f"Package location: { dist .location } " )
96+ print (f"Package version: { dist .version } " )
97+ except pkg_resources .DistributionNotFound :
98+ print ("Package not found in current environment" )
99+
100+ # Check sys.path
101+ print (f"Python path: { sys .path [:3 ]} ..." )
102+ print ("=== End Diagnostic Information ===" )
103+ except Exception as diag_error :
104+ print (f"Diagnostic error: { diag_error } " )
105+
58106 # For Docker environments, we need to check if the plugin is actually usable
59107 # Try a direct test of the plugin functionality
60108 try :
@@ -82,6 +130,41 @@ def install_plugin(self) -> bool:
82130 print (f"Plugin { self .provider .CERTBOT_PLUGIN } may not be properly installed" )
83131 if "dns-namecheap" not in test_result .stdout :
84132 print (f"Warning: dns-namecheap plugin not found in certbot plugins list" )
133+
134+ # Try some additional fixes
135+ print ("Attempting additional fixes..." )
136+
137+ # Try to reload Python modules
138+ try :
139+ import importlib
140+ import certbot_dns_namecheap
141+ importlib .reload (certbot_dns_namecheap )
142+ print ("Reloaded certbot_dns_namecheap module" )
143+ except Exception as reload_error :
144+ print (f"Module reload failed: { reload_error } " )
145+
146+ # Try installing with --force-reinstall
147+ try :
148+ print ("Trying force reinstall..." )
149+ import sys
150+ force_cmd = [sys .executable , "-m" , "pip" , "install" , "--force-reinstall" , self .provider .CERTBOT_PACKAGE ]
151+ print (f"Force reinstall command: { ' ' .join (force_cmd )} " )
152+ force_result = subprocess .run (force_cmd , capture_output = True , text = True )
153+ if force_result .returncode == 0 :
154+ print ("Force reinstall succeeded" )
155+ else :
156+ print (f"Force reinstall failed: { force_result .stderr } " )
157+ except Exception as force_error :
158+ print (f"Force reinstall error: { force_error } " )
159+
160+ # Test plugins again after fixes
161+ print ("Testing plugins again after fixes..." )
162+ retest_cmd = ["certbot" , "plugins" ]
163+ retest_result = subprocess .run (retest_cmd , capture_output = True , text = True , timeout = 10 )
164+ if retest_result .returncode == 0 and "dns-namecheap" in retest_result .stdout :
165+ print (f"Plugin { self .provider .CERTBOT_PLUGIN } is now available after fixes!" )
166+ return True
167+
85168 # In Docker environments, this might still work in practice
86169 print ("Continuing anyway - plugin may work in actual certbot execution" )
87170 return True
@@ -168,6 +251,13 @@ def obtain_certificate(self, domain: str, email: str) -> bool:
168251 """Obtain a new certificate for the domain."""
169252 print (f"Starting certificate obtaining process for { domain } using { self .provider_type } " )
170253
254+ # Ensure plugin is installed
255+ print (f"Checking plugin installation..." )
256+ if not self .install_plugin ():
257+ print (f"Failed to install plugin for { self .provider_type } " , file = sys .stderr )
258+ return False
259+ print (f"Plugin installation completed" )
260+
171261 # Check if credentials are set up
172262 print (f"Checking credentials setup..." )
173263 if not self .setup_credentials ():
@@ -227,6 +317,13 @@ def renew_certificate(self, domain: str) -> Tuple[bool, bool]:
227317 (success, renewed): success status and whether renewal was actually performed
228318 """
229319 print (f"Renewing certificate using { self .provider_type } " )
320+
321+ # Ensure plugin is installed for renewal too
322+ print (f"Checking plugin installation for renewal..." )
323+ if not self .install_plugin ():
324+ print (f"Failed to install plugin for renewal for { self .provider_type } " , file = sys .stderr )
325+ return False , False
326+ print (f"Plugin installation completed for renewal" )
230327
231328 cmd = self ._build_certbot_command ("renew" , domain , "" )
232329
0 commit comments