@@ -172,31 +172,40 @@ class _ChRootContext(typing.ContextManager[None]):
172172 :type conn: ExecHelper
173173 :param path: chroot path or None for no chroot
174174 :type path: str | pathlib.Path | None
175- :raises TypeError: incorrect type of path variable
175+ :param chroot_exe: chroot executable
176+ :type chroot_exe: str
177+ :raises TypeError: incorrect type of path or chroot_exe variable
176178
177179 .. versionadded:: 4.1.0
178180 """
179181
180- __slots__ = ("_chroot_status" , "_conn" , "_path" )
182+ __slots__ = ("_chroot_status" , "_chroot_exe_status" , " _conn" , "_path" , "_exe " )
181183
182- def __init__ (self , conn : ExecHelper , path : ChRootPathSetT = None ) -> None :
184+ def __init__ (self , conn : ExecHelper , path : ChRootPathSetT = None , chroot_exe : str = "chroot" ) -> None :
183185 """Context manager for call commands with sudo.
184186
185- :raises TypeError: incorrect type of path variable
187+ :raises TypeError: incorrect type of path or chroot_exe variable
186188 """
187189 self ._conn : ExecHelper = conn
188190 self ._chroot_status : str | None = conn ._chroot_path
191+ self ._chroot_exe_status : str = conn ._chroot_exe
189192 if path is None or isinstance (path , str ):
190193 self ._path : str | None = path
191194 elif isinstance (path , pathlib .Path ):
192195 self ._path = path .as_posix () # get absolute path
193196 else :
194197 raise TypeError (f"path={ path !r} is not instance of { ChRootPathSetT } " )
198+ if isinstance (chroot_exe , str ):
199+ self ._exe : str = chroot_exe
200+ else :
201+ raise TypeError (f"chroot_exe={ chroot_exe !r} is not instance of str" )
195202
196203 def __enter__ (self ) -> None :
197204 self ._conn .__enter__ ()
198205 self ._chroot_status = self ._conn ._chroot_path
199206 self ._conn ._chroot_path = self ._path
207+ self ._chroot_exe_status = self ._conn ._chroot_exe
208+ self ._conn ._chroot_exe = self ._exe
200209
201210 def __exit__ (
202211 self ,
@@ -205,6 +214,7 @@ def __exit__(
205214 exc_tb : TracebackType | None ,
206215 ) -> None :
207216 self ._conn ._chroot_path = self ._chroot_status
217+ self ._conn ._chroot_exe = self ._chroot_exe_status
208218 self ._conn .__exit__ (exc_type , exc_val , exc_tb )
209219
210220
@@ -224,10 +234,12 @@ class ExecHelper(
224234 .. versionchanged:: 1.2.0 log_mask_re regex rule for masking cmd
225235 .. versionchanged:: 1.3.5 make API public to use as interface
226236 .. versionchanged:: 4.1.0 support chroot
237+ .. versionchanged:: 8.1.0 support chroot_exe
227238 """
228239
229240 __slots__ = (
230241 "__chroot_path" ,
242+ "__chroot_exe" ,
231243 "__context_count" ,
232244 "__lock" ,
233245 "__logger" ,
@@ -240,6 +252,7 @@ def __init__(self, log_mask_re: LogMaskReT = None, *, logger: logging.Logger) ->
240252 self .__logger : logging .Logger = logger
241253 self .log_mask_re : LogMaskReT = log_mask_re
242254 self .__chroot_path : str | None = None
255+ self .__chroot_exe : str = "chroot"
243256 self .__context_count = 0
244257
245258 @property
@@ -292,18 +305,51 @@ def _chroot_path(self) -> None:
292305 """
293306 self .__chroot_path = None
294307
295- def chroot (self , path : ChRootPathSetT ) -> _ChRootContext :
308+ @property
309+ def _chroot_exe (self ) -> str :
310+ """Exe for chroot
311+
312+ :rtype: str
313+ .. versionadded:: 8.1.0
314+ """
315+ return self .__chroot_exe
316+
317+ @_chroot_exe .setter
318+ def _chroot_exe (self , new_state : str ) -> None :
319+ """Executable for chroot if set.
320+
321+ :param new_state: new exe
322+ :type new_state: str
323+ :raises TypeError: Not supported exe information
324+ .. versionadded:: 8.1.0
325+ """
326+ if isinstance (new_state , str ):
327+ self .__chroot_exe = new_state
328+ else :
329+ raise TypeError (f"chroot_exe is expected to be string, but set { new_state !r} " )
330+
331+ @_chroot_exe .deleter
332+ def _chroot_exe (self ) -> None :
333+ """Restore chroot executable.
334+
335+ .. versionadded:: 8.1.0
336+ """
337+ self .__chroot_exe = "chroot"
338+
339+ def chroot (self , path : ChRootPathSetT , chroot_exe : str = "chroot" ) -> _ChRootContext :
296340 """Context manager for changing chroot rules.
297341
298342 :param path: chroot path or none for working without chroot.
299343 :type path: str | pathlib.Path | None
344+ :param chroot_exe: chroot exe
345+ :type chroot_exe: str
300346 :return: context manager with selected chroot state inside
301347 :rtype: typing.ContextManager
302348
303349 .. Note:: Enter and exit main context manager is produced as well.
304350 .. versionadded:: 4.1.0
305351 """
306- return _ChRootContext (conn = self , path = path )
352+ return _ChRootContext (conn = self , path = path , chroot_exe = chroot_exe )
307353
308354 @property
309355 def _context_count (self ) -> int :
@@ -348,7 +394,7 @@ def _mask_command(self, cmd: str, log_mask_re: LogMaskReT = None) -> str:
348394
349395 return _helpers .mask_command (cmd .rstrip (), self .log_mask_re , log_mask_re )
350396
351- def _prepare_command (self , cmd : str , chroot_path : str | None = None ) -> str :
397+ def _prepare_command (self , cmd : str , chroot_path : str | None = None , chroot_exe : str = "chroot" ) -> str :
352398 """Prepare command: cower chroot and other cases.
353399
354400 :param cmd: main command
@@ -358,7 +404,7 @@ def _prepare_command(self, cmd: str, chroot_path: str | None = None) -> str:
358404 :return: final command, includes chroot, if required
359405 :rtype: str
360406 """
361- return _helpers .chroot_command (cmd , chroot_path = chroot_path or self ._chroot_path )
407+ return _helpers .chroot_command (cmd , chroot_path = chroot_path or self ._chroot_path , chroot_exe = chroot_exe )
362408
363409 @abc .abstractmethod
364410 def _exec_command (
@@ -427,6 +473,7 @@ def open_execute_context(
427473 open_stdout : bool = True ,
428474 open_stderr : bool = True ,
429475 chroot_path : str | None = None ,
476+ chroot_exe : str = "chroot" ,
430477 ** kwargs : typing .Any ,
431478 ) -> ExecuteContext :
432479 """Get execution context manager.
@@ -441,6 +488,8 @@ def open_execute_context(
441488 :type open_stderr: bool
442489 :param chroot_path: chroot path override
443490 :type chroot_path: str | None
491+ :param chroot_exe: chroot exe override
492+ :type chroot_exe: str
444493 :param kwargs: additional parameters for call.
445494 :type kwargs: typing.Any
446495
@@ -460,6 +509,7 @@ def execute(
460509 open_stderr : bool = True ,
461510 log_stderr : bool = True ,
462511 chroot_path : str | None = None ,
512+ chroot_exe : str = "chroot" ,
463513 ** kwargs : typing .Any ,
464514 ) -> exec_result .ExecResult :
465515 """Execute command and wait for return code.
@@ -485,6 +535,8 @@ def execute(
485535 :type log_stderr: bool
486536 :param chroot_path: chroot path override
487537 :type chroot_path: str | None
538+ :param chroot_exe: chroot exe override
539+ :type chroot_exe: str
488540 :param kwargs: additional parameters for call.
489541 :type kwargs: typing.Any
490542 :return: Execution result
@@ -495,6 +547,7 @@ def execute(
495547 .. versionchanged:: 2.1.0 Allow parallel calls
496548 .. versionchanged:: 7.0.0 Allow command as list of arguments. Command will be joined with components escaping.
497549 .. versionchanged:: 8.0.0 chroot path exposed.
550+ .. versionchanged:: 8.1.0 chroot_exe added.
498551 """
499552 log_level : int = logging .INFO if verbose else logging .DEBUG
500553 cmd = _helpers .cmd_to_string (command )
@@ -511,6 +564,7 @@ def execute(
511564 open_stdout = open_stdout ,
512565 open_stderr = open_stderr ,
513566 chroot_path = chroot_path ,
567+ chroot_exe = chroot_exe ,
514568 ** kwargs ,
515569 ) as async_result :
516570 result : exec_result .ExecResult = self ._exec_command (
@@ -540,6 +594,7 @@ def __call__(
540594 open_stderr : bool = True ,
541595 log_stderr : bool = True ,
542596 chroot_path : str | None = None ,
597+ chroot_exe : str = "chroot" ,
543598 ** kwargs : typing .Any ,
544599 ) -> exec_result .ExecResult :
545600 """Execute command and wait for return code.
@@ -565,6 +620,8 @@ def __call__(
565620 :type log_stderr: bool
566621 :param chroot_path: chroot path override
567622 :type chroot_path: str | None
623+ :param chroot_exe: chroot exe override
624+ :type chroot_exe: str
568625 :param kwargs: additional parameters for call.
569626 :type kwargs: typing.Any
570627 :return: Execution result
@@ -584,6 +641,7 @@ def __call__(
584641 open_stderr = open_stderr ,
585642 log_stderr = log_stderr ,
586643 chroot_path = chroot_path ,
644+ chroot_exe = chroot_exe ,
587645 ** kwargs ,
588646 )
589647
0 commit comments