1717
1818class TftpError (Exception ):
1919 """Base exception for TFTP server errors"""
20-
2120 pass
2221
23-
2422class ServerNotRunning (TftpError ):
2523 """Server is not running"""
26-
2724 pass
2825
29-
3026class FileNotFound (TftpError ):
3127 """File not found"""
32-
3328 pass
3429
35-
3630@dataclass (kw_only = True )
3731class Tftp (Driver ):
3832 """TFTP Server driver for Jumpstarter"""
3933
4034 root_dir : str = "/var/lib/tftpboot"
4135 host : str = field (default = '' )
4236 port : int = 69
43- checksum_suffix : str = ".sha256"
4437 server : Optional ["TftpServer" ] = field (init = False , default = None )
4538 server_thread : Optional [threading .Thread ] = field (init = False , default = None )
4639 _shutdown_event : threading .Event = field (init = False , default_factory = threading .Event )
4740 _loop_ready : threading .Event = field (init = False , default_factory = threading .Event )
4841 _loop : Optional [asyncio .AbstractEventLoop ] = field (init = False , default = None )
49- _checksums : dict [str , str ] = field (default_factory = dict )
5042
5143 def __post_init__ (self ):
5244 super ().__post_init__ ()
@@ -73,10 +65,7 @@ def _start_server(self):
7365 asyncio .set_event_loop (self ._loop )
7466 self .server = TftpServer (host = self .host , port = self .port , root_dir = self .root_dir )
7567 try :
76- # Signal that the loop is ready
7768 self ._loop_ready .set ()
78-
79- # Run the server until shutdown is requested
8069 self ._loop .run_until_complete (self ._run_server ())
8170 except Exception as e :
8271 self .logger .error (f"Error running TFTP server: { e } " )
@@ -86,7 +75,6 @@ def _start_server(self):
8675 self ._loop .close ()
8776 except Exception as e :
8877 self .logger .error (f"Error during event loop cleanup: { e } " )
89-
9078 self ._loop = None
9179 self .logger .info ("TFTP server thread completed" )
9280
@@ -111,11 +99,9 @@ def start(self):
11199 self .logger .warning ("TFTP server is already running" )
112100 return
113101
114- # Clear any previous shutdown state
115102 self ._shutdown_event .clear ()
116103 self ._loop_ready .clear ()
117104
118- # Start the server thread
119105 self .server_thread = threading .Thread (target = self ._start_server , daemon = True )
120106 self .server_thread .start ()
121107
@@ -133,7 +119,6 @@ def stop(self):
133119 return
134120
135121 self .logger .info ("Initiating TFTP server shutdown" )
136-
137122 self ._shutdown_event .set ()
138123 self .server_thread .join (timeout = 10 )
139124 if self .server_thread .is_alive ():
@@ -148,7 +133,6 @@ def list_files(self) -> list[str]:
148133
149134 @export
150135 async def put_file (self , filename : str , src_stream , client_checksum : str ):
151- """Compute and store checksum at write time"""
152136 file_path = os .path .join (self .root_dir , filename )
153137
154138 try :
@@ -160,47 +144,37 @@ async def put_file(self, filename: str, src_stream, client_checksum: str):
160144 async for chunk in src :
161145 await dst .send (chunk )
162146
163- current_checksum = self ._compute_checksum (file_path )
164- self ._checksums [filename ] = current_checksum
165- self ._write_checksum_file (filename , current_checksum )
166147 return filename
167148 except Exception as e :
168149 raise TftpError (f"Failed to upload file: { str (e )} " ) from e
169150
170-
171151 @export
172152 def delete_file (self , filename : str ):
173- """Delete file and its checksum file"""
174153 file_path = os .path .join (self .root_dir , filename )
175- checksum_path = self ._get_checksum_path (filename )
176154
177155 if not os .path .exists (file_path ):
178156 raise FileNotFound (f"File { filename } not found" )
179157
180158 try :
181159 os .remove (file_path )
182- if os .path .exists (checksum_path ):
183- os .remove (checksum_path )
184- self ._checksums .pop (filename , None )
160+ return filename
185161 except Exception as e :
186162 raise TftpError (f"Failed to delete { filename } " ) from e
187163
188164 @export
189165 def check_file_checksum (self , filename : str , client_checksum : str ) -> bool :
190- """
191- check if the checksum of the file matches the client checksum
192- """
193-
194166 file_path = os .path .join (self .root_dir , filename )
167+ self .logger .debug (f"checking checksum for file: { filename } " )
168+ self .logger .debug (f"file path: { file_path } " )
169+
195170 if not os .path .exists (file_path ):
171+ self .logger .debug (f"File { filename } does not exist" )
196172 return False
197173
198174 current_checksum = self ._compute_checksum (file_path )
175+ self .logger .debug (f"Computed checksum: { current_checksum } " )
176+ self .logger .debug (f"Client checksum: { client_checksum } " )
199177
200- self ._checksums [filename ] = current_checksum
201- self ._write_checksum_file (filename , current_checksum )
202-
203- self .logger .debug (f"Client checksum: { client_checksum } , server checksum: { current_checksum } " )
204178 return current_checksum == client_checksum
205179
206180 @export
@@ -216,28 +190,6 @@ def close(self):
216190 self .stop ()
217191 super ().close ()
218192
219- def _get_checksum_path (self , filename : str ) -> str :
220- return os .path .join (self .root_dir , f"{ filename } { self .checksum_suffix } " )
221-
222- def _read_checksum_file (self , filename : str ) -> Optional [str ]:
223- try :
224- checksum_path = self ._get_checksum_path (filename )
225- if os .path .exists (checksum_path ):
226- with open (checksum_path , 'r' ) as f :
227- return f .read ().strip ()
228- except Exception as e :
229- self .logger .warning (f"Failed to read checksum file for { filename } : { e } " )
230- return None
231-
232- def _write_checksum_file (self , filename : str , checksum : str ):
233- """Write checksum to the checksum file"""
234- try :
235- checksum_path = self ._get_checksum_path (filename )
236- with open (checksum_path , 'w' ) as f :
237- f .write (f"{ checksum } \n " )
238- except Exception as e :
239- self .logger .error (f"Failed to write checksum file for { filename } : { e } " )
240-
241193 def _compute_checksum (self , path : str ) -> str :
242194 hasher = hashlib .sha256 ()
243195 with open (path , "rb" ) as f :
0 commit comments