1616
1717import argparse
1818import os
19+ import signal
20+ import threading
1921
20- from lib .utils import run , run_as_root
21- from lib .target import Target
2222from lib .generator import Generator , stage0_arch_map
23+ from lib .simple_mirror import SimpleMirror
24+ from lib .target import Target
25+ from lib .utils import run , run_as_root
2326
2427def create_configuration_file (args ):
2528 """
@@ -177,6 +180,18 @@ def check_types():
177180 # Set constant umask
178181 os .umask (0o022 )
179182
183+ # file:// mirrors
184+ mirror_servers = []
185+ for i , mirror in enumerate (args .mirrors ):
186+ if mirror .startswith ("file://" ):
187+ path = mirror .removeprefix ("file://" )
188+ if not path .startswith ("/" ):
189+ raise ValueError ("A file:// mirror must be an absolute path." )
190+
191+ server = SimpleMirror (path )
192+ args .mirrors [i ] = f"http://127.0.0.1:{ server .port } "
193+ mirror_servers .append (server )
194+
180195 # bootstrap.cfg
181196 try :
182197 os .remove (os .path .join ('steps' , 'bootstrap.cfg' ))
@@ -193,15 +208,25 @@ def check_types():
193208 if args .tmpfs :
194209 target .tmpfs (size = args .tmpfs_size )
195210
211+ for server in mirror_servers :
212+ thread = threading .Thread (target = server .serve_forever )
213+ thread .start ()
214+
215+ def cleanup (* _ ):
216+ for server in mirror_servers :
217+ server .shutdown ()
218+ signal .signal (signal .SIGINT , cleanup )
219+
196220 generator = Generator (arch = args .arch ,
197221 external_sources = args .external_sources ,
198222 repo_path = args .repo ,
199223 early_preseed = args .early_preseed ,
200224 mirrors = args .mirrors )
201225
202- bootstrap (args , generator , target , args .target_size )
226+ bootstrap (args , generator , target , args .target_size , cleanup )
227+ cleanup ()
203228
204- def bootstrap (args , generator , target , size ):
229+ def bootstrap (args , generator , target , size , cleanup ):
205230 """Kick off bootstrap process."""
206231 print (f"Bootstrapping { args .arch } " , flush = True )
207232 if args .chroot :
@@ -216,7 +241,7 @@ def bootstrap(args, generator, target, size):
216241
217242 arch = stage0_arch_map .get (args .arch , args .arch )
218243 init = os .path .join (os .sep , 'bootstrap-seeds' , 'POSIX' , arch , 'kaem-optional-seed' )
219- run_as_root ('env' , '-i' , 'PATH=/bin' , chroot_binary , generator .target_dir , init )
244+ run_as_root ('env' , '-i' , 'PATH=/bin' , chroot_binary , generator .target_dir , init , cleanup = cleanup )
220245
221246 elif args .bwrap :
222247 init = '/init'
@@ -245,7 +270,8 @@ def bootstrap(args, generator, target, size):
245270 '--proc' , '/proc' ,
246271 '--bind' , '/sys' , '/sys' ,
247272 '--tmpfs' , '/tmp' ,
248- init )
273+ init ,
274+ cleanup = cleanup )
249275
250276 elif args .bare_metal :
251277 if args .kernel :
@@ -303,7 +329,7 @@ def bootstrap(args, generator, target, size):
303329 ]
304330 if not args .interactive :
305331 arg_list += ['-no-reboot' , '-nographic' ]
306- run (args .qemu_cmd , * arg_list )
332+ run (args .qemu_cmd , * arg_list , cleanup = cleanup )
307333
308334if __name__ == "__main__" :
309335 main ()
0 commit comments