Repository navigation
v0.4.0
Added
pixie render <target> NAME... [--out DIR]renders a target's artifacts to
standard output or a directory, arming nothing.
Changed
-
Configuration is loaded by
anycfg, the new name of yaconfiglib:
netboot depends onanycfg>=0.14.0,<0.15andtplx>=0.2.0,<0.3instead of
yaconfiglibandjinja2, andnetboot[config]installsanycfg[yaml].
Includes are confined byANYCFG_CONFINE_TO;YACONFIGLIB_CONFINE_TOis
not read, so rename it where you set it. A malformed file is still a
one-line error, now namingfile:line:col.netboot.utils.config.Namespace
and the config classes build onanycfg.TypedNamespace/OpaqueMerge. -
Every public module declares
__all__;netboot.utilsexportsNamespace
too.PixieTarget,PixieImageandPixieContextare defined in private
modules and imported, as before, fromnetbootornetboot.engine. -
netboot.dhcp.DhcpZoneisDHCPZone(also importable fromnetboot), as
every other public name spells DHCP; rename the import. -
Pixie.lookup_imagereturnsNonewhen nothing matches, as
lookup_targetandlookup_dhcpzonedo, rather than{}; a
FoundTargetImagehook seesNonetoo. -
The command line is
netboot.cli, one duho class per command
(Initiate,Complete,Render,DhcpConfig); the console script is
netboot.cli:main, andnetboot.mainre-exportsmain,PixieArgs,
Pixie_andparse_path.main(argv=None, *, name=None):argvis the
first parameter, somain(["--version"])works; passname=by keyword.
netboot.cmdsis gone:netboot.cmds.dhcp_config.recipeis
netboot.dhcp.condition_recipe,conditions_forisbuild_conditions, and
a--cmdspathplugin withrun(netboot, args, conf)works as before. -
pixieno longer imports apixie_envsettings module fromsys.path,
which underpython -m netbootmeant the working directory: running it in
a directory runs no code from there. ExportPIXIE_*variables instead, or
name a module with--load-module. -
Building the engine does no DNS. A hostname-only target's
ipis
looked up byPixieTarget.resolve_ip(), which the engine calls for the
target a command acts on (and for every hostname-only target when an IP
query matches no configured address), so an unresolvable target no longer
slows every command. APixieTargetbuilt directly hasip == ""until
resolve_ip()is called. -
initialize(target, **options)andcomplete(target, **options)hand
optionsto their Start/End hooks as kwargs:initiate --iscsinow reaches
them askwargs["iscsi"]. -
A DHCP server's credentials are its own config entry's. A
dhcpservers
entry is a URI or a mapping ofuri:and that backend's secrets (user,
password; dhcpdkeyname,omapi_key), written in the config or taken
from the environment there with{{ env.NAME }}, which config files can now
use.PIXIE_WINDHCP_PASSWORD,PIXIE_WINDHCP_USERand
PIXIE_DHCPD_OMAPI_KEYare no longer read, and
netboot.dhcp.WINDHCP_PASSWORD_ENV_VAR,WINDHCP_USER_ENV_VARand
DHCPD_OMAPI_KEY_ENV_VARare gone: move each value into the entries of the
servers that use it (password: "{{ env.PIXIE_WINDHCP_PASSWORD }}"keeps a
variable you already set). An entry's secrets override a user or password
in the URI.pixie dhcp-config --aspasses the prompted user and password
to each server directly, overriding the URI's. -
The errors are in
netboot.exceptions(PixieError,PixieConfigError,
PixieLookupError), still re-exported fromnetboot. -
dhcp_options,dhcp_whenanddhcp_completeare read as what a target is
served, a pydhcpDHCPLease:next-serverandboot-file-nameare its
BOOTP header fieldssiaddrandfile, as they always reached the server,
andfile,snameandsiaddrmay be written as such.bootfile-nameis
option 67 itself and is now sent as an option.build_next_serveris
replaced bybuild_lease(ctx, server). A Kea client class fromdhcp_when
carries the boot file as itsboot-file-namefield, not as option 67. -
An option with no type of its own (
option-224, unlessdhcp.options
declares one) takes its octets as hex text or{hex: ...}in
dhcp_options, as pydhcp'sDHCPOptions.from_mappingreads them. -
The DHCP backends are
dhcpctl's. netboot depends on
pydhcpctl>=0.1.0,<0.2(imported asdhcpctl), andnetboot.dhcpis a module that builds each
target's reservation for it:DhcpZone,connect(uri),build_options,
build_conditions,build_completion,reservation_for(ctx, server),
armanddisarm. What a server is sent is unchanged, byte for byte,
including the names netboot writes on it (# >>> netbootregions,
netboot-<mac>Windows policies). Removed, with what to do:DhcpServerand its scheme-by-class-name dispatch: subclass
dhcpctl.DHCPServerand calldhcpctl.register_backend(scheme, cls)from
the--load-moduleplugin, or declare it in thedhcpctl.backendsentry
point. A backend implementsadd(reservation)/remove(reservation)
(wereadd_target(ctx)/remove_target(ctx)),keep(reservation)(was
keep_target(ctx, completion)), andextras(reservation, phase)(was
extras(ctx, phase)); the netboot context isreservation.context.netboot.dhcp.dnsmasq/.kea/.dhcpd/.windhcp: the backends are
dhcpctl.backends.DnsmasqBackend,KeaBackend,DHCPDBackendand
WinDHCPBackend; to override one, register the subclass with
replace=True.netboot.dhcp.options,.conditionsand.completion:GENERIC_OPTIONS,
APPLY_TIME,DhcpOptions,split_query,DhcpCondition,MATCH_KEYS,
DhcpCompletionandBOOT_OPTIONSare dhcpctl's (DHCPOptions,
Condition,Completion, ...);build_options,build_conditions,
build_completionandzone_defaultsare innetboot.dhcp.
ConditionMissing/ConditionUnsupportedare
dhcpctl.ConditionMissingError/ConditionUnsupportedError.windhcp.PASSWORD_ENV_VAR/USER_ENV_VARare
netboot.dhcp.WINDHCP_PASSWORD_ENV_VAR/WINDHCP_USER_ENV_VAR, and
dhcpd.KEY_ENV_VARisDHCPD_OMAPI_KEY_ENV_VAR; the variables are the
samePIXIE_*ones, now read only when the URI has no user or password
of its own:windhcp://admin:pw@hostanddhcpd://keyname:key@hostwork.
Logs, errors andpixie dhcp-configshow a server's URI with the password
masked.netboot.DhcpServeris no longer exported.
Thekea,dhcpd,winrmandsshextras install dhcpctl's of the same
name. An unknown scheme, or a URI a backend cannot use, is a
PixieConfigError; a server refusing is adhcpctl.ServerError, reported by
the CLI as one line with status 2.PixieEvent.BuildDhcpOptionsnow fires
once per server for every backend, including one that never asks for its
options.
-
DHCP options are pydhcp's, through dhcpctl. Every IANA option is named by
its pydhcp name (dns,bootfile-name,interface-mtu, ...) or
option-<n>, and the names netboot already took still work
(LEGACY_OPTION_NAMES). A config declares more in a new top-level
dhcp.optionssection: an option of its own with a code and a pydhcp type,
or an alias of a name or a code;dhcp_options,dhcp_whenand
dhcp_completeall read them. Each value is read by the
option's type when the config is applied, sorouter: gatewayis a
PixieConfigErrornaming the image or target; a list option takes one
address per item, so write several as a YAML list or a repeated URI key,
not one comma-joined string. Kea is sent options by code, so a zone with a
gateway or a lease time no longer sends Kea option names it does not define
(router,lease-time). What to do in aBuildDhcpOptionshook: it
receives pydhcp'sDHCPOptions, keyed by code,
so writeoptions[DHCPOptionCode.ROUTER] = ...oroptions[3]where it
wroteoptions["router"], or return a mapping of option names.
next-serveris no longer an option a hook sees: it is the reservation's
BOOTP field, still set fromdhcp_options: {next-server: ...}. -
A server URI says only how to reach the server. Its query takes the
backend's connection settings and nothing else: DHCP options
(?router=...),options_builder=andraw.<backend>=text are
unknown-key errors. What to do: move options to the zone's settings or an
image's or target'sdhcp_options; replace anoptions_builderwith a hook
onPixieEvent.BuildDhcpOptions, which receives the same options plus the
target and the server; for the iPXE chainload usedhcp_when:, and for other
backend-native text register a backend subclass whose
extras(reservation, phase)returns it. -
Template roots resolve against the config file's directory. Through the
CLI, a relativetemplates:root is joined to the directory of the config
file, as!includeis, and with notemplates:the root istemplates
beside the config file (./config/templatesby default). The working
directory's./templatesis no longer prepended. What to do: a config that
relied on./templatesnames it, relative to the config file (the example
config now saystemplates: ../templates). -
The path layer is
pathapianduripath, notpathlib-next. netboot
depends onpathapi>=0.1.0,<0.2andpathapi-uri>=0.1.0,<0.2(import
packageuripath) and no longer installspathlib-nextoruritools. The
paths netboot returns are their classes:Repository.service(),.get()
and.localareuripath.URIPath(werepathlib_next.uri.UriPath),
parse_path()returnspathapi.LocalPathorURIPath, and a template's
PathandUriglobals arepathapi.Pathanduripath.URIPath. What to
do: import them from there in a command module, hook or template that used
pathlib_next; apathlib_nextpath handed to netboot is not aPath.
The URLs netboot builds are the same, buturipathdiffers in these ways a
hook or template can see:- A join keeps the query and fragment of the service URI it starts from
(http://h/boot?sig=1joined withaishttp://h/boot/a?sig=1); it
dropped both. Queryis no longer astr, andSource.from_str()/as_str()are
Source.parse()/str().file:///xandfile:/xare different URIs. netboot still writes the
service of.localasfile:/srv/tftp.
- A join keeps the query and fragment of the service URI it starts from
-
yaconfiglibfloor moves to>=0.13.1,<0.14, the first release built on
pathapi; 0.13.0 needspathlib-next. Configuration loading,!include
globs and merging behave as before. -
The
httpextra is removed.http/httpsrepository services are sent
on the standard library byuripath, so they need no extra and
Repository.service()no longer raises anImportErrornaming
netboot[http]. What to do: drop[http]from the install line (pip warns
about the unknown extra and installs the rest).netboot[kea]still installs
requests; installpathapi-requestsyourself only to sendhttp/https
services through arequests.Session. -
The
sshextra issftppath[uri,paramiko]>=0.1.0,<0.2(was
pathlib_next[sftp]): remotednsmasq://paths aresftp://paths of
sftppath, over paramiko.SFTPPATH_BACKENDreplaces
PATHLIB_NEXT_SFTP_BACKENDto choose paramiko or asyncssh; the old name is
not read. -
duhofloor moves to>=0.7.5,<0.8(pre-1.0 minor, documented API break;
0.7.4 adds the unsorted multi-source command discovery that--cmdspath
now uses, 0.7.5 theexit="parse"mode ofduho.run).
Thepixiecommand line is unchanged: same flags, exit statuses and output,
with one exception in--help: the commands of one--cmdspathdirectory are
listed by file name, then in the order a file defines them, where they were
sorted by command name. The two differ only for a file that defines several
commands or is named differently from its command. -
pixieruns throughduho.run(..., exit="parse")and reports operator errors
through duho's_errors_/_report_error_: the same one-line log record and
the same status 2 as before. New with it: Ctrl-C ends with status 130 and a
broken pipe with status 1, both without a traceback; a plainrun(args)
command's returned value (notNoneor anint) is printed to standard
output, where it was handed tosys.exit; withDUHO_TRACEBACKset an
operator error also prints its traceback to standard error, and the status
stays 2.--help,--versionand a usage error still raiseSystemExit
frommain, as before. -
netimpsmoves to>=0.4.0,<0.5(pre-1.0 minor, documented API break).
The network values netboot hands out are netimps', so its renames reach
templates:target.mac.as_str("-")is nowtarget.mac.format("-"). -
Templates are rendered by
tplx
(tplx[jinja]>=0.1.0,<0.2), with the same engines, suffixes, search order and
templates_undefinedmodes; themako,liquid,handlebarsand
mustacheextras install tplx's. The same templates render the same, with
these differences:- An include goes through the per-target names and the image's
template_path, and a file of another engine is rendered by that engine
and inserted: a Jinja{% include "net" %}ofnet.shtplworks, where it
failed withAttributeError. mako, Liquid, Handlebars and Mustache
includes and partials search the template roots too. - Every engine sees each context field at the top level (
target,
image, ...) besidectx; Jinja and mako saw onlyctx. - A MAC address in a Liquid, Handlebars or Mustache template renders as
aa:bb:cc:dd:ee:ff, where it rendered asDataView(MACAddress(...)). - An
.epptemplate's output no longer gains a trailing newline the
template did not write. - The shell engine leaves out
_-prefixed context names other than_id. - Errors are tplx's:
tplx.TemplateNotFound(wasjinja2.TemplateNotFound),
tplx.UndefinedError(wasjinja2.UndefinedError, orKeyErrorfrom the
shell engine),tplx.NoEngineError,tplx.EngineUnavailableErrorand
tplx.RenderError(wasnetboot.templates.TemplateEngineError, or an
ImportErrornamingnetboot[mako]).pixiereports every
tplx.TplxErroras one line and exits 2. PIXIE_RUBYandPIXIE_PUPPETare nowTPLX_RUBYandTPLX_PUPPET.
- An include goes through the per-target names and the image's
-
shell_quoteisshlex.quote: a value with nothing special to the shell
is no longer quoted ({{ shell_quote("web01") }}rendersweb01, was
'web01'), and an embedded'is written'"'"'(was'\''). Both read
back as the same word in a POSIX shell. Thequote=argument and its
double-quote form are gone.
Removed
netboot.utils.flatten,netboot.utils.arr_getand the
netboot.utils.dictsmodule;shell_quoteandTare in
netboot.utils.miscand still importable fromnetboot.utils.netboot.templates: usetplx(Loader, the engine classes,
register_engineforregister_template_type,unregister_engine,
registered_enginesforTEMPLATE_TYPES,DataEncoderfor
template_data/jsonable). A plugin engine subclassestplx.Templateand
implementsrender_values(values), wherevaluesholdsctxand the context
fields.PixieContext._rendereris gone; the context'stplx.Loaderis
_loader.netboot.utils.net,netboot.netutilsand the network names
netboot.utilsre-exported (Host,IPAddress,IPInterface,
IPNetwork,MACAddress,parse,try_parse,is_valid,is_wildcard,
resolve,ping,get_interfaces,iter_addresses,normalize_host):
import them fromnetimps. netboot'sHostsubclass goes with them, and
with it.try_ip()(usehost.ip() or str(host)),.address(use
.value, and build a newHostrather than assigning) andHost()with no
argument (Host(None)).Repository.addressis anetimps.Host.
A test that faked DNS throughnetboot.netutils.resolvepatches
netimps.resolve.
Fixed
- A configuration mistake is one line and exit 2, not a traceback: a MAC,
address or network that does not parse (namedtargets.<id>,
dhcpzones.<id>), a collection that is not a mapping, a key that is not
text, a--load-modulethat does not import, and a zone whose only DHCP
servers could not be reached (no DHCP server armed ...). A configuredip
that is not an address is now that error instead of being dropped. - A numeric MAC is refused. YAML reads an unquoted all-digit MAC
(mac: 52:54:00:12:34:56, or such a target id) as a base-60 number, which
netboot armed as a different MAC; quote it. repo / "sub"keeps a service's query string last
(http://h/boot/sub/a?sig=1, not.../a?sig=1/sub), and leaveslocal
unset when the repository had none instead of making itfile:sub.- A full-URI repository service no longer resolves the repository's address
(nor warns that it has none); a relative one resolves it once, through
netimps' shared cache, rather than on every URL. templates: dirgiven toPixiedirectly is one root, not one per
character, andparse_pathreads every RFC 3986 scheme (svn+ssh://).pixie dhcp-configwith no target warns about a target whose zone cannot
be found and covers the rest, where it stopped at the first; a recipe
several targets share is printed once.--ason Windows with standard
input fromNULfails at once instead of waiting on a prompt.- A global named like any member of the render context (
version,
render,searchpaths, ...) is dropped with a warning, astargetand
imagealready were, instead of replacing it or breaking the context. - A zone with no
dhcpserverswarns that nothing was armed. hooks: Nonemeans no hooks;ctx.resource(Resource)for a resource with
nopathisNone.- A configuration key nothing reads (
targetz:, a zone'sgatway:) is
logged as a warning naming it. Data for templates belongs underglobals;
a key starting with_is never warned about. - With
DUHO_TRACEBACKset, a configuration error prints its traceback to
standard error again: duho 0.7.6 leaves that to netboot, which now requires
duho>=0.7.6. dnsmasq://writes reservation and option files dnsmasq can read: each line
is the value of--dhcp-host/--dhcp-optionwithout the key, which
dnsmasq rejected before, so no reservation took effect. A dnsmasq extras
fragment is written the same way (tag:web01,252,http://x).dnsmasq://in directory mode stops serving a completed target: dnsmasq
keeps what--dhcp-hostsdirheld until SIGHUP, so completion now signals
pidfile=(default/run/dnsmasq/dnsmasq.pid), or needsreload=when the
dnsmasq is remote. A dnsmasq target served options with nooptsfile=is
refused rather than armed without its boot file.dhcpd://keeps a completed target (the host is deleted and created again,
as dhcpd refuses to overwrite one), serves aconditions=grouptarget its
conditional boot file (the host's own no longer outranks the group's), and
writes an option dhcpd has no name for in a form dhcpd parses.kea://keeps a completed target withreservation-update(or a delete
and add), where it sent areservation-addKea refuses for an existing
reservation, and finds a zone's subnet inside a Keashared-networksentry.windhcp://completing a target that is removed also removes its own
policies (netboot-<mac>-<condition>,netboot-<mac>), which went on serving
its boot file;conditions=sharedleaves an existing policy untouched;
pixie dhcp-configprints the per-target policies target mode creates, every
value quoted;method=netshkeeps a reservation through netsh and no longer
fails its read-back for an option a condition serves.pixie initiateon a target that is already armed replaces its reservation
on every DHCP server; dhcpd and Kea refused, and the Windows cmdlet threw.kea://conditions are a client class of the target's own, so an iPXE
client is served the chainload and any other client the reservation's boot
file; on a real Kea both were handed the same one.dhcp-configprints the
two classes per target (<name>-<mac>andnetboot-<mac>). A Kea with no
hosts database is armed with?target=memory.- Every DHCP option reaches dnsmasq, dhcpd and Kea in a form it reads: dhcpd
refused the host's statements for most options netboot did not name, and
dnsmasq read flags, number lists and octets as text. windhcp://and a remotednsmasq://reload run through hostctl. ssh is
asyncssh rather than the systemsshclient (it reads~/.ssh/configas
sshdoes), sowindhcp://over ssh now needsnetboot[ssh];?timeout=bounds one
Windows script (default 120 s).windhcp://over its local and ssh transports runs the whole script and
fails when any of it fails. It ran only the first line of each multi-line
block and reported success, so a reservation could be reported armed and not
exist.
Full Changelog: v0.3.2...v0.4.0