API Reference
The engine and its context objects. Rendered from source via mkdocstrings.
Engine
netboot.Pixie
The engine: config in, provisioning decisions out.
Built from a merged config mapping, it resolves targets, images and DHCP
zones, builds render contexts, and arms or disarms DHCP through the
initialize/complete lifecycle. Every step fires a PixieEvent, so
behaviour can be changed without subclassing.
Source code in src/netboot/engine.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 | |
targets
instance-attribute
targets: dict[str, PixieTarget]
dhcpzones
instance-attribute
dhcpzones: dict[str, DHCPZone]
images
instance-attribute
images: dict[str, PixieImage]
repos
instance-attribute
repos: dict[str, Repository]
globals
instance-attribute
globals: dict[str, object]
templates_undefined
class-attribute
instance-attribute
templates_undefined: str = 'strict'
VERSION
class-attribute
instance-attribute
VERSION = __version__
hook
hook(
event: PixieEvent,
__value: T = None,
/,
**kwargs: object,
) -> T
Run the hook chain for event, threading value through it.
Each hook is called as f(event, netboot, value, kwargs) and must
return the value to pass on. value is positional-only.
Source code in src/netboot/engine.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
lookup_target
lookup_target(target: str) -> PixieTarget | None
Find the target a user named, or None.
Exact id first, then an exact hostname/MAC/IP match anywhere in the table,
then a unique hostname prefix. Raises PixieLookupError rather than
guessing when a query matches several targets.
Source code in src/netboot/engine.py
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | |
lookup_image
lookup_image(
name: str, target: PixieTarget | None = None
) -> PixieImage | None
The best-matching image, or None when none matches.
match may return a bool or a comparable score; anything falsy --
False, None, 0, an empty re.Match-less result -- means "not
this one". Scores are compared against each other, so a match
returning a non-comparable type raises rather than silently ordering
by chance.
Source code in src/netboot/engine.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | |
lookup_dhcpzone
lookup_dhcpzone(
name: str, target: PixieTarget = None
) -> DHCPZone | None
The zone for name, or the most specific one containing the target's IP.
The resolved id is cached back onto target.dhcpzone.
Source code in src/netboot/engine.py
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | |
make_context
make_context(
target: PixieTarget,
globals: list[dict] = None,
require_image: bool = True,
) -> PixieContext
Build the render context for target.
Resolves the image and zone, layers the globals (engine, then image, zone
and target), and attaches a renderer over the configured template roots.
require_image=False tolerates an image that is no longer configured, so
cleanup can still run.
Source code in src/netboot/engine.py
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | |
initialize
initialize(
target: PixieTarget, **options: object
) -> PixieContext
Arm DHCP for target and return its context.
A backend that fails is a warning; it raises only if none could be armed.
options (initiate's iscsi=) reach the Start/EndPixieInitialize
hooks as their keyword arguments.
Source code in src/netboot/engine.py
514 515 516 517 518 519 520 521 522 523 524 | |
complete
complete(
target: PixieTarget, **options: object
) -> PixieContext
Disarm DHCP for target and return its context.
Every backend is tried; one that fails is logged as a warning.
options reach the Start/EndPixieComplete hooks as keyword arguments.
Source code in src/netboot/engine.py
526 527 528 529 530 531 532 533 534 535 | |
Context
netboot.PixieContext
Bases: Namespace
Everything a template can see for one target.
Built by Pixie.make_context, never constructed directly: it carries the
target, its image and zone, the repositories, and its own renderer.
Source code in src/netboot/_context.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | |
target
instance-attribute
target: PixieTarget
image
instance-attribute
image: PixieImage
dhcpzone
instance-attribute
dhcpzone: DHCPZone
repos
instance-attribute
repos: dict[str, Repository]
generated
instance-attribute
generated: datetime = datetime.datetime.now()
resources
instance-attribute
resources: dict[str, Resource]
version
instance-attribute
version: str
searchpaths
property
searchpaths: list[Path]
Template directories for this context: target first, then image.
These extend the engine-wide template roots rather than replacing them; a relative entry is resolved inside each root.
resource
resource(
name: Union[str, Resource], service: str | None = None
) -> URIPath | None
Resolve a resource to a fetchable URI through its repository.
Takes a resource id (looked up in .resources) or a Resource directly.
None if the repo or the resource is unknown.
Source code in src/netboot/_context.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
resource_repo
resource_repo(name: str) -> Repository | None
The Repository backing resource name, or None.
Source code in src/netboot/_context.py
71 72 73 74 75 76 | |
pxe_init
pxe_init(config: Pixie) -> PixieContext
Arm every DHCP backend for this target, succeeding if any one does.
Every backend is tried. A backend that fails is logged as a warning and
skipped, so one server being offline does not block the others. When
none could be armed the first error is raised: as itself when netboot
or dhcpctl raised it on purpose, else as a PixieError chained to it.
Source code in src/netboot/_context.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
pxe_complete
pxe_complete(config: Pixie) -> PixieContext
Disarm every DHCP backend; a failure is a warning, never an error.
Every backend is tried, and one that fails is logged and skipped, so the rest are still disarmed.
Source code in src/netboot/_context.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
render
render(
filename: str, strict: bool = True
) -> str | bytes | None
Render filename against this context and return the result.
The name is resolved by the template search (MAC, hostname, IP, then the
bare name), through tplx, and so are the includes inside it. The
template sees ctx and each of the context's fields (target, image,
...). Text, or bytes for a file the copy engine claims, which is
every suffix no other engine owns -- it is a byte-exact copy, so it is
never decoded. strict=False logs the failure at DEBUG and returns
None instead of raising.
Source code in src/netboot/_context.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | |
Targets and images
netboot.PixieTarget
Bases: Namespace, OpaqueMerge
One machine to provision, as configured under targets:.
Gaps are filled at construction: a MAC-shaped id becomes the MAC, an
IP-shaped id the IP, anything else the hostname. An unknown IP is looked
up only by resolve_ip, which the engine calls for a target it acts on,
so building the engine does no DNS.
Source code in src/netboot/_objects.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
hostname
instance-attribute
hostname: str = self.hostname.lower()
ip
instance-attribute
ip: Union[IPAddress, str] = (
netimps.parse(self.ip, IPAddress) if self.ip else ""
)
mac
instance-attribute
mac: MACAddress
image
instance-attribute
image: str
dhcpzone
instance-attribute
dhcpzone: str
globals
instance-attribute
globals: dict
template_path
instance-attribute
template_path: list[Union[str, Path]]
resolve_ip
resolve_ip() -> PixieTarget
Fill an unknown ip from hostname: one forward lookup, ever.
Never retried: a name that does not resolve answers the same next
time, so it leaves ip unset with a warning, and never raises.
Source code in src/netboot/_objects.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
netboot.PixieImage
Bases: Resource
What a target boots, as configured under images:.
Also a content.Resource, so it carries src/path addressing its
artifacts in a repository. Those play no part in template lookup.
Source code in src/netboot/_objects.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
template_path
instance-attribute
template_path: list[Path]
globals
instance-attribute
globals: dict
match
match(name: str, check: str) -> object
Does image name serve check? Override point for image selection.
Return a bool, or a comparable score so lookup_image can prefer the best
of several matches. Anything falsy means "not this one".
Source code in src/netboot/_objects.py
126 127 128 129 130 131 132 | |
Events
netboot.PixieEvent
Bases: StrEnum
The points in the engine where hooks run.
The string value carries the PixieEvent. prefix (PixieEvent.LookupTarget),
which hooks comparing against raw strings rely on.
Source code in src/netboot/engine.py
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
NewPixieObject
class-attribute
instance-attribute
NewPixieObject = 'PixieEvent.NewPixieObject'
StartPixieInit
class-attribute
instance-attribute
StartPixieInit = 'PixieEvent.StartPixieInit'
SetPixieProperty
class-attribute
instance-attribute
SetPixieProperty = 'PixieEvent.SetPixieProperty'
PixieInitiated
class-attribute
instance-attribute
PixieInitiated = 'PixieEvent.PixieInitiated'
LookupTarget
class-attribute
instance-attribute
LookupTarget = 'PixieEvent.LookupTarget'
FoundTarget
class-attribute
instance-attribute
FoundTarget = 'PixieEvent.FoundTarget'
FoundTargetImage
class-attribute
instance-attribute
FoundTargetImage = 'PixieEvent.FoundTargetImage'
FoundTargetDhcpzone
class-attribute
instance-attribute
FoundTargetDhcpzone = 'PixieEvent.FoundTargetDhcpzone'
PixieContextForTarget
class-attribute
instance-attribute
PixieContextForTarget = 'PixieEvent.PixieContextForTarget'
BuildDhcpOptions
class-attribute
instance-attribute
BuildDhcpOptions = 'PixieEvent.BuildDhcpOptions'
StartPixieInitialize
class-attribute
instance-attribute
StartPixieInitialize = 'PixieEvent.StartPixieInitialize'
EndPixieInitialize
class-attribute
instance-attribute
EndPixieInitialize = 'PixieEvent.EndPixieInitialize'
StartPixieComplete
class-attribute
instance-attribute
StartPixieComplete = 'PixieEvent.StartPixieComplete'
EndPixieComplete
class-attribute
instance-attribute
EndPixieComplete = 'PixieEvent.EndPixieComplete'
DHCP
The servers are dhcpctl's; this module builds each target's reservation for them.
netboot.dhcp
DHCP zones, and what a target's reservation is on each of their servers.
The servers are dhcpctl's: a zone's dhcpservers are URIs, built with
dhcpctl.connect, and a backend for a new scheme is registered with
dhcpctl.register_backend (or the dhcpctl.backends entry point). What stays
here is what is about targets: the zone -> image -> target layering of
dhcp_options, dhcp_when and dhcp_complete, the BuildDhcpOptions hook,
and each server's own secrets from its dhcpservers entry.
OWNER
module-attribute
OWNER = 'netboot'
LEGACY_OPTION_NAMES
module-attribute
LEGACY_OPTION_NAMES = {
"domain-name-servers": "dns",
"boot-file-name": "file",
"tftp-server-name": "tftp-server",
"host-name": "hostname",
"lease-time": "ip-address-lease-time",
}
NETBOOT_CODES
module-attribute
NETBOOT_CODES = dhcpctl.option_codes(LEGACY_OPTION_NAMES)
DHCPZone
Bases: Namespace, OpaqueMerge
A network netboot can provision into, as configured under dhcpzones:.
Derives network from a CIDR gateway, coerces nameservers/search to
lists, and builds dhcpservers URIs into dhcpctl servers.
Source code in src/netboot/dhcp.py
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
gateway
instance-attribute
gateway: '_ty.Optional[IPAddress]'
domain
instance-attribute
domain: '_ty.Optional[str]'
search
instance-attribute
search: 'list[str]'
nameservers
instance-attribute
nameservers: 'list[IPAddress]'
globals
instance-attribute
globals: dict
nameserver
property
nameserver: 'IPAddress | str'
The first nameserver, or "" when none is configured.
dhcpservers
instance-attribute
dhcpservers: "list[dhcpctl.DHCPServer]" = [
server_from(server, codes)
for server in self.dhcpservers or []
]
network
instance-attribute
network: IPNetwork = (
netimps.parse(network, IPNetwork) if network else None
)
get_local_server
get_local_server(
servers: "list[IPAddress]", default: IPAddress
) -> IPAddress
The first server that lives inside this zone's network, else default.
Accepts the strings config and globals actually hold, not just parsed
addresses: "10.0.0.5" in network would otherwise raise.
Source code in src/netboot/dhcp.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | |
codes_for
codes_for(
dhcp: "dict|None" = None,
) -> "type[dhcpctl.OptionCodes]"
The codemap a config's dhcp: section declares, over netboot's.
dhcp.options maps a name to {code: <n>, type: <pydhcp codec>} or to a
code or another name (see dhcpctl.option_codes).
:raises PixieConfigError: the section cannot be used.
Source code in src/netboot/dhcp.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
connect
connect(
uri: str,
codes: "type[dhcpctl.OptionCodes]|None" = None,
secrets: "_abc.Mapping[str, str]|None" = None,
) -> dhcpctl.DHCPServer
The dhcpctl server for uri, with the secrets its config entry gives.
A secret given here overrides the one the URI carries (its user or
password). Option names are read with codes (netboot's by default).
:raises PixieConfigError: the URI cannot be used.
Source code in src/netboot/dhcp.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
server_from
server_from(
entry: "str | _abc.Mapping[str, object] | dhcpctl.DHCPServer",
codes: "type[dhcpctl.OptionCodes] | None" = None,
) -> dhcpctl.DHCPServer
A dhcpservers entry as a server: a URI, or a mapping of uri: and the
secrets that backend takes (windhcp and kea user/password, dhcpd
keyname/omapi_key), each written in the config or produced by it
(password: "{{ env.WINDHCP_PASSWORD }}").
:raises PixieConfigError: the entry cannot be used.
Source code in src/netboot/dhcp.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
scope_for
scope_for(zone: DHCPZone) -> dhcpctl.Scope
A zone as the scope a reservation lives in: subnet_id/scope if set.
Source code in src/netboot/dhcp.py
260 261 262 263 264 265 266 267 268 | |
zone_defaults
zone_defaults(
zone: DHCPZone,
codes: "type[dhcpctl.OptionCodes] | None" = None,
) -> dhcpctl.DHCPOptions
What the zone already knows, before anyone configures an option.
The bag reads its options with codes (netboot's by default), the codemap
every layer merged onto it keeps.
Source code in src/netboot/dhcp.py
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
build_options
build_options(
ctx: PixieContext, server: DHCPServer
) -> dhcpctl.DHCPOptions
The options for this target on this server, in merge order.
Later wins: zone defaults, the image's dhcp_options, the target's
dhcp_options, then the BuildDhcpOptions hook, which receives pydhcp
DHCPOptions and returns them, or any mapping of option names.
Source code in src/netboot/dhcp.py
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | |
build_lease
build_lease(
ctx: PixieContext, server: DHCPServer
) -> dhcpctl.DHCPLease
What this target is served on this server: its address, build_options,
and the header fields the image or the target sets, the target's first.
Source code in src/netboot/dhcp.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | |
build_conditions
build_conditions(
ctx: PixieContext,
) -> "dict[str, dhcpctl.Condition]"
Every dhcp_when condition that applies to this target, layered by name.
Zone, then image, then target -- later wins, by name, so a target
redeclaring ipxe replaces the image's rather than adding a second one.
Source code in src/netboot/dhcp.py
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | |
build_completion
build_completion(ctx: PixieContext) -> dhcpctl.Completion
How this target completes: zone, then image, then target -- later wins.
Source code in src/netboot/dhcp.py
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | |
condition_recipe
condition_recipe(
ctx: "PixieContext",
server: DHCPServer,
condition: Condition,
) -> str
What server needs set up once for condition, in its own syntax.
Source code in src/netboot/dhcp.py
443 444 445 446 447 | |
reservation_for
reservation_for(
ctx: "PixieContext", server: DHCPServer
) -> dhcpctl.Reservation
This target's reservation on server, with ctx as its context.
Source code in src/netboot/dhcp.py
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | |
arm
arm(ctx: 'PixieContext', server: DHCPServer) -> None
Arm server for this target.
Source code in src/netboot/dhcp.py
472 473 474 475 | |
disarm
disarm(ctx: 'PixieContext', server: DHCPServer) -> None
Disarm server for this target, honouring dhcp_complete:.
Source code in src/netboot/dhcp.py
478 479 480 481 | |
Content repositories
netboot.content.Repository
Bases: Namespace
Where artifacts are served from.
services maps a scheme name to a base path or full URI; local is the
filesystem view. address fills in the authority for a relative service
path.
Source code in src/netboot/content/__init__.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
address
instance-attribute
address: Host
local
instance-attribute
local: Optional[URIPath]
services
instance-attribute
services: dict[str, URIPath] = {}
joinpath
joinpath(subpath: str | None = None) -> Repository
A copy of this repository with subpath appended to every service.
subpath is always relative: repo / "/abs" extends the base like
repo / "abs" does, rather than replacing it -- a leading slash in a
config value is a typo, not a request to discard the repository root.
Source code in src/netboot/content/__init__.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | |
get
get(
*path: Union[PosixPathname, str], service: str = None
) -> URIPath
Join path onto a service's base URI, or None if undefined.
Source code in src/netboot/content/__init__.py
84 85 86 87 88 89 90 91 92 93 | |
service
service(name: str | None) -> URIPath | None
The base URI for a service name, None for .local when unset.
A relative service path gets its authority from .address: resolved to an
IP for every scheme except https, which keeps the configured name.
Source code in src/netboot/content/__init__.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
netboot.content.Resource
Bases: Namespace
A file in a repository: path within it, src naming the repo.
Source code in src/netboot/content/__init__.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
path
instance-attribute
path: Pathname
src
instance-attribute
src: str
Templates
Rendering is tplx's; its API reference covers the loader, the engines and the engine contract.
Utilities
netboot.utils.misc
T
module-attribute
T = TypeVar('T')
import_
import_(name: str) -> Any
Import "pkg.mod.attr" and return attr (splits on the last dot).
Source code in src/netboot/utils/misc.py
14 15 16 17 | |
parse_path
parse_path(path: str | Path) -> Path
Parse a configured path: a bare path is local, scheme: is a URI.
A single-letter scheme is a Windows drive, not a URI: C:\srv\tftp and
C:/srv/tftp are local paths. Real URI schemes are at least two
characters, so this costs nothing and stops every absolute Windows path
from being parsed as a URI (and then failing with NotImplementedError
when something tries to read it).
Source code in src/netboot/utils/misc.py
24 25 26 27 28 29 30 31 32 33 34 35 36 | |
shell_quote
shell_quote(value: Any) -> Union[str, List[str]]
shlex.quote for a template: a POSIX shell reads the result as literal text.
A list or tuple is quoted element-wise and comes back as a list; anything
else gives a str. A value that is not a string is stringified first, and
None is the empty string (''). A value with nothing special to the
shell comes back as it is.
Source code in src/netboot/utils/misc.py
39 40 41 42 43 44 45 46 47 48 49 | |
CLI entry point
netboot.cli
The pixie command line, built on duho.
main is the entry point of the pixie console script and of python -m
netboot. Each built-in command is a class in a module of its own; a
--cmdspath plugin may still be a module with run(netboot, args, conf).
Command
Bases: Cmd
A pixie command. The global options arrive from the root parser.
Source code in src/netboot/cli/_common.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
netboot
property
netboot: 'Pixie'
The engine, from --load-module, --config and --baseconfig.
find
find(query: str) -> 'PixieTarget | None'
The target query names, or None after logging why there is none.
An ambiguous query is refused rather than guessed: arming the wrong machine is worse than arming none.
Source code in src/netboot/cli/_common.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
main
main(
argv: "_ty.Sequence[str] | None" = None,
*,
name: "str | None" = None
) -> int
Build the app, parse argv, and run the selected command.
name (default "pixie") is both the prog name and the environment
prefix: settings are read through :class:duho.env.Env, so PIXIE_<KEY>
variables apply. The resolved Env is attached to the dispatched instance
as _env_.
Goes through :func:duho.run with exit="parse": it returns the status,
except that --help, --version and a usage error raise SystemExit.
A configuration or lookup error is reported as a single line and exits 2;
the traceback is logged at DEBUG, so -v still shows it. Other
exceptions propagate untouched.
Source code in src/netboot/cli/__init__.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | |
Errors
netboot.PixieError
Bases: Exception
Base for the errors netboot raises on purpose.
Separates "the operator gave us something unusable" from "netboot has a bug": the CLI reports the former as a one-line message and keeps the traceback for the latter.
Source code in src/netboot/exceptions.py
8 9 10 11 12 13 14 | |
netboot.PixieLookupError
Bases: PixieError, LookupError
A target, image or zone could not be resolved, or the query was ambiguous.
Source code in src/netboot/exceptions.py
17 18 | |
netboot.PixieConfigError
Bases: PixieError, ValueError
The configuration cannot be used as given.
Source code in src/netboot/exceptions.py
21 22 | |