penguin.penguin_config.structure module

class penguin.penguin_config.structure.Core(*, arch=None, kernel=None, fs='./base/fs.tar.gz', plugin_path='/pyplugins', root_shell=False, strace=False, ltrace=False, gdbserver=None, force_www=False, cpu=None, show_output=False, immutable=True, network=False, shared_dir=None, version, auto_patching=True, guest_cmd=False, extra_qemu_args=None, mem='2G', kernel_quiet=True, smp=1, graphics=False)[source]

Bases: PartialModelMixin, BaseModel

Core configuration options for this rehosting

Parameters:
  • arch (Annotated[Literal['armel', 'aarch64', 'mipsel', 'mipseb', 'mips64el', 'mips64eb', 'powerpc', 'powerpc64', 'powerpc64le', 'riscv64', 'loongarch64', 'intel64'] | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Architecture of guest', examples=['armel', 'aarch64', 'mipsel', 'mipseb', 'mips64el', 'mips64eb', 'intel64'])])

  • kernel (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Path to kernel image', examples=['/igloo_static/kernels/zImage.armel', '/igloo_static/kernels/zImage.arm64', '/igloo_static/kernels/vmlinux.mipsel', '/igloo_static/kernels/vmlinux.mipseb', '/igloo_static/kernels/vmlinux.mips64el', '/igloo_static/kernels/vmlinux.mips64eb'])])

  • fs (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default='./base/fs.tar.gz', title='Project-relative path to filesystem tarball', examples=['base/fs.tar.gz'])])

  • plugin_path (Annotated[str, FieldInfo(annotation=NoneType, required=False, default='/pyplugins', title='Path to search for PyPlugins', examples=['/pyplugins'])])

  • root_shell (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Enable root shell', description='Whether to enable a root shell into the guest', examples=[False, True])])

  • strace (Annotated[bool | list[str], FieldInfo(annotation=NoneType, required=False, default=False, title='Enable strace', description='If true, run strace for entire system starting from init. If names of programs, enable strace only for those programs.', examples=[False, True, ['lighttpd']])])

  • ltrace (Annotated[bool | list[str], FieldInfo(annotation=NoneType, required=False, default=False, title='Enable ltrace', description='If true, run ltrace for entire system starting from init. If names of programs, enable ltrace only for those programs.', examples=[False, True, ['lighttpd']])])

  • gdbserver (GDBServerPrograms | None)

  • force_www (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Try to force webserver start', description='Whether to try forcing webserver start', examples=[False, True])])

  • cpu (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='CPU model', description='Specify non-default QEMU CPU model')])

  • show_output (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Write serial to stdout', description='Whether to print QEMU serial output to stdout instead of writing to a log file', examples=[False, True])])

  • immutable (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Enable immutable mode', description='Whether to run the guest filesystem in immutable mode', examples=[False, True])])

  • network (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Connect guest to network', description='Whether to connect the guest to the network', examples=[False, True])])

  • shared_dir (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Project-relative path of shared directory', description='Share this directory as /igloo/shared in the guest.', examples=['my_shared_directory'])])

  • version (Annotated[Literal['1.0.0', 2], FieldInfo(annotation=NoneType, required=True, title='Config format version', description='Version of the config file format')])

  • auto_patching (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Enable automatic patching', description='Whether to automatically apply patches named patch_*.yaml or from patches/*.yaml in the project directory', examples=[False, True])])

  • guest_cmd (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Enable running commands in the guest', description='When enabled, starts the guesthopper daemon in the guest that the host can use to run commands over vsock', examples=[False, True])])

  • extra_qemu_args (Annotated[StrSepSpace | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Extra QEMU arguments', description='A list of additional QEMU command-line arguments to use when booting the guest', examples=['-vnc :0 -vga std -device usb-kbd -device usb-tablet'])])

  • mem (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default='2G', title='Panda Memory Value', description='Allows users to customize memory allocation for guest', examples=['16K', '512M', '1G', '2G'])])

  • kernel_quiet (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Whether to include quiet flag in kernel command line', description='If true, the kernel command line will include the quiet flag, otherwise all kernel boot messages will be printed to the console', examples=[False, True])])

  • smp (Annotated[int | None, FieldInfo(annotation=NoneType, required=False, default=1, title='Number of CPUs', description='Number of CPUs to emulate in the guest (Warning: This can break things)', examples=[1, 2, 4])])

  • graphics (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Enable graphics', description='Whether to enable graphics in the guest', examples=[False, True])])

arch: Annotated[Literal['armel', 'aarch64', 'mipsel', 'mipseb', 'mips64el', 'mips64eb', 'powerpc', 'powerpc64', 'powerpc64le', 'riscv64', 'loongarch64', 'intel64'] | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Architecture of guest', examples=['armel', 'aarch64', 'mipsel', 'mipseb', 'mips64el', 'mips64eb', 'intel64'])]
auto_patching: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Enable automatic patching', description='Whether to automatically apply patches named patch_*.yaml or from patches/*.yaml in the project directory', examples=[False, True])]
cpu: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='CPU model', description='Specify non-default QEMU CPU model')]
extra_qemu_args: Annotated[StrSepSpace | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Extra QEMU arguments', description='A list of additional QEMU command-line arguments to use when booting the guest', examples=['-vnc :0 -vga std -device usb-kbd -device usb-tablet'])]
force_www: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Try to force webserver start', description='Whether to try forcing webserver start', examples=[False, True])]
fs: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default='./base/fs.tar.gz', title='Project-relative path to filesystem tarball', examples=['base/fs.tar.gz'])]
gdbserver: GDBServerPrograms | None
graphics: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Enable graphics', description='Whether to enable graphics in the guest', examples=[False, True])]
guest_cmd: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Enable running commands in the guest', description='When enabled, starts the guesthopper daemon in the guest that the host can use to run commands over vsock', examples=[False, True])]
immutable: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Enable immutable mode', description='Whether to run the guest filesystem in immutable mode', examples=[False, True])]
kernel: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Path to kernel image', examples=['/igloo_static/kernels/zImage.armel', '/igloo_static/kernels/zImage.arm64', '/igloo_static/kernels/vmlinux.mipsel', '/igloo_static/kernels/vmlinux.mipseb', '/igloo_static/kernels/vmlinux.mips64el', '/igloo_static/kernels/vmlinux.mips64eb'])]
kernel_quiet: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Whether to include quiet flag in kernel command line', description='If true, the kernel command line will include the quiet flag, otherwise all kernel boot messages will be printed to the console', examples=[False, True])]
ltrace: Annotated[bool | list[str], FieldInfo(annotation=NoneType, required=False, default=False, title='Enable ltrace', description='If true, run ltrace for entire system starting from init. If names of programs, enable ltrace only for those programs.', examples=[False, True, ['lighttpd']])]
mem: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default='2G', title='Panda Memory Value', description='Allows users to customize memory allocation for guest', examples=['16K', '512M', '1G', '2G'])]
model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'title': 'Core configuration options'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

network: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Connect guest to network', description='Whether to connect the guest to the network', examples=[False, True])]
plugin_path: Annotated[str, FieldInfo(annotation=NoneType, required=False, default='/pyplugins', title='Path to search for PyPlugins', examples=['/pyplugins'])]
root_shell: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Enable root shell', description='Whether to enable a root shell into the guest', examples=[False, True])]
shared_dir: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Project-relative path of shared directory', description='Share this directory as /igloo/shared in the guest.', examples=['my_shared_directory'])]
show_output: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=False, title='Write serial to stdout', description='Whether to print QEMU serial output to stdout instead of writing to a log file', examples=[False, True])]
smp: Annotated[int | None, FieldInfo(annotation=NoneType, required=False, default=1, title='Number of CPUs', description='Number of CPUs to emulate in the guest (Warning: This can break things)', examples=[1, 2, 4])]
strace: Annotated[bool | list[str], FieldInfo(annotation=NoneType, required=False, default=False, title='Enable strace', description='If true, run strace for entire system starting from init. If names of programs, enable strace only for those programs.', examples=[False, True, ['lighttpd']])]
version: Annotated[Literal['1.0.0', 2], FieldInfo(annotation=NoneType, required=True, title='Config format version', description='Version of the config file format')]
class penguin.penguin_config.structure.ExternalNetwork(*, mac='52:54:00:12:34:56', pcap=None)[source]

Bases: PartialModelMixin, BaseModel

Configuration for NAT for external connections

Parameters:
  • mac (str | None)

  • pcap (bool | None)

mac: str | None
model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'title': 'Set up NAT for outgoing connections'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

pcap: bool | None
class penguin.penguin_config.structure.LibInject(*, aliases=None, extra=None)[source]

Bases: PartialModelMixin, BaseModel

Library functions to be intercepted

Parameters:
  • aliases (Annotated[LibInjectAliases | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Function names to alias to existing library function shims', json_schema_extra={'descriptions': 'Mapping between new names (e.g., my_nvram_get) and existing library function shims (e.g., nvram_get)'})])

  • extra (Annotated[StrLines | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Extra injected library code', description='Custom source code for library functions to intercept and model')])

aliases: , nvram_get)'})]
extra: Annotated[StrLines | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Extra injected library code', description='Custom source code for library functions to intercept and model')]
model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'title': 'Injected library configuration'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class penguin.penguin_config.structure.Main(*, core, patches=None, env, pseudofiles, nvram, netdevs=[], uboot_env=None, blocked_signals=[], lib_inject, static_files, plugins, network=None)[source]

Bases: PartialModelMixin, BaseModel

Configuration file for config-file-based rehosting with IGLOO

Parameters:
  • core (Core)

  • patches (Patches | None)

  • env (Env)

  • pseudofiles (Pseudofiles)

  • nvram (NVRAM)

  • netdevs (List[str])

  • uboot_env (UBootEnv | None)

  • blocked_signals (List[int])

  • lib_inject (LibInject)

  • static_files (StaticFiles)

  • plugins (Annotated[dict[str, Plugin], FieldInfo(annotation=NoneType, required=True, title='Plugins')])

  • network (Network | None)

blocked_signals: List[int]
core: Core
env: Env
lib_inject: LibInject
model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'title': 'Penguin Configuration'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

netdevs: List[str]
network: Network | None
nvram: NVRAM
patches: Patches | None
plugins: Annotated[dict[str, Plugin], FieldInfo(annotation=NoneType, required=True, title='Plugins')]
pseudofiles: Pseudofiles
static_files: StaticFiles
uboot_env: UBootEnv | None
class penguin.penguin_config.structure.Network(*, external=<factory>)[source]

Bases: PartialModelMixin, BaseModel

Configuration for networks to attach to guest

Parameters:

external (ExternalNetwork)

external: ExternalNetwork
model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'title': 'Network Configuration'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class penguin.penguin_config.structure.Plugin(*, description=None, depends_on=None, enabled=True, version=None, **extra_data)[source]

Bases: PartialModelMixin, BaseModel

Parameters:
  • description (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Plugin description')])

  • depends_on (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Plugin dependency')])

  • enabled (Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Enable this plugin (default depends on plugin)')])

  • version (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Plugin version')])

  • extra_data (Any)

depends_on: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Plugin dependency')]
description: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Plugin description')]
enabled: Annotated[bool, FieldInfo(annotation=NoneType, required=False, default=True, title='Enable this plugin (default depends on plugin)')]
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'title': 'Plugin'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

version: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='Plugin version')]
class penguin.penguin_config.structure.Pseudofile(*, name=None, size=None, read=None, write=None, ioctl=None)[source]

Bases: PartialModelMixin, BaseModel

How to emulate a device file

Parameters:
  • name (Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='MTD name', description='Name of an MTD device (ignored for non-mtd)', examples=['flash', 'uboot'])])

  • size (Annotated[int | None, FieldInfo(annotation=NoneType, required=False, default=None, title='File size', description='Size of the pseudofile to be reported by stat(). This must be specified for mmap() on the pseudofile to work.', examples=[1, 4096])])

  • read (Read | None)

  • write (Write | None)

  • ioctl (Ioctls | None)

ioctl: Ioctls | None
model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'title': 'File emulation spec'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: Annotated[str | None, FieldInfo(annotation=NoneType, required=False, default=None, title='MTD name', description='Name of an MTD device (ignored for non-mtd)', examples=['flash', 'uboot'])]
read: Read | None
size: Annotated[int | None, FieldInfo(annotation=NoneType, required=False, default=None, title='File size', description='Size of the pseudofile to be reported by stat(). This must be specified for mmap() on the pseudofile to work.', examples=[1, 4096])]
write: Write | None
class penguin.penguin_config.structure.StaticFiles(root=PydanticUndefined)[source]

Bases: RootModel

Files to create in the guest filesystem

Parameters:

root (dict[str, StaticFileAction])

model_config: ClassVar[ConfigDict] = {'json_schema_extra': {'examples': [{}, {'/path/to/file': {'contents': 'Hello world!', 'type': 'file'}}, {'/path/to/symlink/source': {'target': '/path/to/symlink/target', 'type': 'symlink'}}, {'/dev/some_device': {'devtype': 'char', 'major': 1, 'minor': 2, 'mode': 438, 'type': 'dev'}}]}, 'title': 'Static files'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

root: dict[str, StaticFileAction]
class penguin.penguin_config.structure.StrLines(root=PydanticUndefined)[source]

Bases: StrSep

Parameters:

root (str)

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

separator: ClassVar = '\n'
class penguin.penguin_config.structure.StrSep(root=PydanticUndefined)[source]

Bases: RootModel

Parameters:

root (str)

merge(other)[source]
classmethod merge_behavior()[source]
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

root: str
separator: ClassVar = None
class penguin.penguin_config.structure.StrSepSpace(root=PydanticUndefined)[source]

Bases: StrSep

Parameters:

root (RootModelRootType)

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

separator: ClassVar = ' '