1717class InitramfsGenerator :
1818 def __init__ (self , config = '/etc/ugrd/config.toml' , * args , ** kwargs ):
1919 self .config_filename = config
20- self .build_pre = [self .generate_structure ]
2120 self .config_dict = InitramfsConfigDict (logger = self .logger )
2221
2322 # Used for functions that are added to the bash source file
2423 self .included_functions = {}
2524
25+ self .build_tasks = ['build_pre' , 'build_tasks' ]
26+
2627 # init_pre and init_final are run as part of generate_initramfs_main
2728 self .init_types = ['init_debug' , 'init_early' , 'init_main' , 'init_late' , 'init_premount' , 'init_mount' , 'init_cleanup' ]
2829
@@ -58,24 +59,18 @@ def load_config(self) -> None:
5859 def build_structure (self ) -> None :
5960 """
6061 builds the initramfs structure.
61- Cleans the build dir first if clean is set
6262 """
63- self ._run_hook ( 'build_pre' )
64- self ._run_hook ('build_tasks' )
63+ for hook in self .build_tasks :
64+ self ._run_hook (hook )
6565
66- def _run_func (self , function , external = False , force_include = False ) -> list [str ]:
66+ def _run_func (self , function , force_include = False ) -> list [str ]:
6767 """
6868 Runs a function.
69- External ones must have self passed as the first argument.
7069 If force_include is set, forces the function to be included in the bash source file.
7170 """
7271 self .logger .debug ("Running function: %s" % function .__name__ )
73- if external :
74- function_output = function (self )
75- else :
76- function_output = function ()
7772
78- if function_output :
73+ if function_output := function ( self ) :
7974 if isinstance (function_output , list ) and len (function_output ) == 1 :
8075 self .logger .debug ("[%s] Function returned list with one element: %s" % (function .__name__ , function_output [0 ]))
8176 function_output = function_output [0 ]
@@ -115,19 +110,11 @@ def _run_hook(self, hook: str, *args, **kwargs) -> list[str]:
115110 Runs a hook for imported functions
116111 """
117112 out = []
118- self .logger .info ("Running hook: %s" % hook )
119- if hasattr (self , hook ):
120- self .logger .debug ("Running internal functions for hook: %s" % hook )
121- out += self ._run_funcs (getattr (self , hook ), * args , ** kwargs )
122-
123- if external_functions := self .config_dict ['imports' ].get (hook ):
124- self .logger .debug ("Running external functions for hook: %s" % hook )
125- function_output = self ._run_funcs (external_functions , external = True , * args , ** kwargs )
126- out += function_output
127-
128- if out :
129- self .logger .debug ("[%s] Hook output: %s" % (hook , out ))
130- return out
113+ for function in self .config_dict ['imports' ].get (hook , []):
114+ self .logger .debug ("Running function: %s" % function )
115+ if function_output := self ._run_func (function , * args , ** kwargs ):
116+ out .append (function_output )
117+ return out
131118
132119 def _run_init_hook (self , level : str ) -> list [str ]:
133120 """
@@ -210,20 +197,6 @@ def generate_init(self) -> None:
210197 self ._write ('init' , init , 0o755 )
211198 self .logger .debug ("Final config:\n %s" % pretty_print (self .config_dict ))
212199
213- def generate_structure (self ) -> None :
214- """
215- Generates the initramfs directory structure
216- """
217- if not self .build_dir .is_dir ():
218- self ._mkdir (self .build_dir )
219-
220- for subdir in set (self .config_dict ['paths' ]):
221- # Get the relative path of each path, create the directory in the build dir
222- subdir_relative_path = subdir .relative_to (subdir .anchor )
223- target_dir = self .build_dir / subdir_relative_path
224-
225- self ._mkdir (target_dir )
226-
227200 def pack_build (self ) -> None :
228201 """
229202 Packs the initramfs based on self.config_dict['imports']['pack']
@@ -233,6 +206,18 @@ def pack_build(self) -> None:
233206 else :
234207 self .logger .warning ("No pack functions specified, the final build is present in: %s" % self .build_dir )
235208
209+ def _get_build_path (self , path : Union [Path , str ]) -> Path :
210+ """
211+ Returns the build path
212+ """
213+ if not isinstance (path , Path ):
214+ path = Path (path )
215+
216+ if path .is_absolute ():
217+ return self .build_dir / path .relative_to ('/' )
218+ else :
219+ return self .build_dir / path
220+
236221 def _mkdir (self , path : Path ) -> None :
237222 """
238223 Creates a directory, chowns it as self.config_dict['_file_owner_uid']
@@ -337,6 +322,38 @@ def _copy(self, source: Union[Path, str], dest=None) -> None:
337322
338323 self ._chown (dest_path )
339324
325+ def _symlink (self , source : Union [Path , str ], target : Union [Path , str ]) -> None :
326+ """
327+ Creates a symlink
328+ """
329+ from os import symlink
330+
331+ if not isinstance (source , Path ):
332+ source = Path (source )
333+
334+ target = self ._get_build_path (target )
335+
336+ if not target .parent .is_dir ():
337+ self .logger .debug ("Parent directory for '%s' does not exist: %s" % (target .name , target .parent ))
338+ self ._mkdir (target .parent )
339+
340+ self .logger .debug ("Creating symlink: %s -> %s" % (source , target ))
341+ symlink (source , target )
342+
343+ def _run (self , args : list [str ]) -> CompletedProcess :
344+ """
345+ Runs a command, returns the object
346+ """
347+ self .logger .debug ("Running command: %s" % ' ' .join (args ))
348+ cmd = run (args , capture_output = True )
349+ if cmd .returncode != 0 :
350+ self .logger .error ("Failed to run command: %s" % cmd .args )
351+ self .logger .error ("Command output: %s" % cmd .stdout .decode ())
352+ self .logger .error ("Command error: %s" % cmd .stderr .decode ())
353+ raise RuntimeError ("Failed to run command: %s" % cmd .args )
354+
355+ return cmd
356+
340357 def _rotate_old (self , file_name : Path , sequence = 0 ) -> None :
341358 """
342359 Copies a file to file_name.old then file_nane.old.n, where n is the next number in the sequence
@@ -381,48 +398,3 @@ def _rotate_old(self, file_name: Path, sequence=0) -> None:
381398 # Finally, rename the file
382399 self .logger .info ("[%d] Cycling file: %s -> %s" % (sequence , file_name , target_file ))
383400 file_name .rename (target_file )
384-
385- def _get_build_path (self , path : Union [Path , str ]) -> Path :
386- """
387- Returns the build path
388- """
389- if not isinstance (path , Path ):
390- path = Path (path )
391-
392- if path .is_absolute ():
393- return self .build_dir / path .relative_to ('/' )
394- else :
395- return self .build_dir / path
396-
397- def _symlink (self , source : Union [Path , str ], target : Union [Path , str ]) -> None :
398- """
399- Creates a symlink
400- """
401- from os import symlink
402-
403- if not isinstance (source , Path ):
404- source = Path (source )
405-
406- target = self ._get_build_path (target )
407-
408- if not target .parent .is_dir ():
409- self .logger .debug ("Parent directory for '%s' does not exist: %s" % (target .name , target .parent ))
410- self ._mkdir (target .parent )
411-
412- self .logger .debug ("Creating symlink: %s -> %s" % (source , target ))
413- symlink (source , target )
414-
415- def _run (self , args : list [str ]) -> CompletedProcess :
416- """
417- Runs a command, returns the object
418- """
419- self .logger .debug ("Running command: %s" % ' ' .join (args ))
420- cmd = run (args , capture_output = True )
421- if cmd .returncode != 0 :
422- self .logger .error ("Failed to run command: %s" % cmd .args )
423- self .logger .error ("Command output: %s" % cmd .stdout .decode ())
424- self .logger .error ("Command error: %s" % cmd .stderr .decode ())
425- raise RuntimeError ("Failed to run command: %s" % cmd .args )
426-
427- return cmd
428-
0 commit comments