Skip to content

Commit

Permalink
fix: Fix ftp failures (#5585)
Browse files Browse the repository at this point in the history
- fix exception handling when retr fails
- test: Close connection on failure
- test: Ensure server is running before it is queried
  • Loading branch information
holmanb committed Aug 5, 2024
1 parent b7b11bc commit a99d797
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
42 changes: 23 additions & 19 deletions cloudinit/url_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ def read_ftps(url: str, timeout: float = 5.0, **kwargs: dict) -> "FtpResponse":
user=user,
passwd=url_parts.password or "",
)
LOG.debug("Creating a secure connection")
ftp_tls.prot_p()
LOG.debug("Reading file: %s", url_parts.path)
ftp_tls.retrbinary(
f"RETR {url_parts.path}", callback=buffer.write
)

response = FtpResponse(buffer.getvalue(), url)
LOG.debug("Closing connection")
except ftplib.error_perm as e:
LOG.warning(
"Attempted to connect to an insecure ftp server but used "
Expand All @@ -156,15 +165,9 @@ def read_ftps(url: str, timeout: float = 5.0, **kwargs: dict) -> "FtpResponse":
headers=None,
url=url,
) from e
LOG.debug("Creating a secure connection")
ftp_tls.prot_p()
LOG.debug("Reading file: %s", url_parts.path)
ftp_tls.retrbinary(f"RETR {url_parts.path}", callback=buffer.write)

response = FtpResponse(buffer.getvalue(), url)
LOG.debug("Closing connection")
ftp_tls.close()
return response
finally:
ftp_tls.close()
return response
else:
try:
ftp = ftplib.FTP()
Expand All @@ -176,6 +179,14 @@ def read_ftps(url: str, timeout: float = 5.0, **kwargs: dict) -> "FtpResponse":
port=port,
timeout=timeout or 5.0, # uses float internally
)
LOG.debug("Attempting to login with user [%s]", user)
ftp.login(
user=user,
passwd=url_parts.password or "",
)
LOG.debug("Reading file: %s", url_parts.path)
ftp.retrbinary(f"RETR {url_parts.path}", callback=buffer.write)
response = FtpResponse(buffer.getvalue(), url)
except ftplib.all_errors as e:
code = ftp_get_return_code_from_exception(e)
raise UrlError(
Expand All @@ -187,16 +198,9 @@ def read_ftps(url: str, timeout: float = 5.0, **kwargs: dict) -> "FtpResponse":
headers=None,
url=url,
) from e
LOG.debug("Attempting to login with user [%s]", user)
ftp.login(
user=user,
passwd=url_parts.password or "",
)
LOG.debug("Reading file: %s", url_parts.path)
ftp.retrbinary(f"RETR {url_parts.path}", callback=buffer.write)
response = FtpResponse(buffer.getvalue(), url)
LOG.debug("Closing connection")
ftp.close()
finally:
LOG.debug("Closing connection")
ftp.close()
return response


Expand Down
7 changes: 6 additions & 1 deletion tests/integration_tests/datasources/test_nocloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ def _boot_with_cmdline(
#!/usr/bin/python3
import logging
from systemd.daemon import notify
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler, TLS_FTPHandler
from pyftpdlib.servers import FTPServer
Expand Down Expand Up @@ -298,6 +300,9 @@ def _boot_with_cmdline(
handler.abstracted_fs = UnixFilesystem
server = FTPServer(("localhost", 2121), handler)
# tell systemd to proceed
notify("READY=1")
# start the ftp server
server.serve_forever()
"""
Expand Down Expand Up @@ -357,7 +362,7 @@ def _boot_with_cmdline(
Before=cloud-init-network.service
[Service]
Type=exec
Type=notify
ExecStart=/server.py
[Install]
Expand Down

0 comments on commit a99d797

Please sign in to comment.