7.1.8. cobbler.services package
7.1.8.1. Submodules
7.1.8.2. cobbler.services.files module
Direct-disk distro tree file server.
This WSGI app serves the files of a distro’s original, uncopied source tree (repodata/,
Packages/, etc.) straight from disk, so that clients such as anaconda/installer HTTP
clients can fetch package/repo data from $tree URLs of the form:
http://<server>/cblr/svc/tree/<distro_name>/<relative_path>
without cobblerd having to stream every byte through an XML-RPC round trip (XML-RPC is only used
here for a single, briefly-cached metadata lookup: resolving a distro name to its
source_tree_path). This mirrors cobbler.services.svc’s pattern for reaching cobblerd
(same settings file, same xmlrpc_port/xmlrpc_host keys, same unauthenticated
xmlrpc.client.Server construction) but never uses XML-RPC for file bytes themselves.
Security note: the path-resolution logic in this module (is_safe_path() /
resolve_within_root()) is the only thing standing between an unauthenticated client and
arbitrary file disclosure. Both textual traversal (../../etc/passwd) and a symlink inside
the tree pointing outside of it must be rejected; both are defeated by resolving
os.path.realpath on the fully-joined candidate path and requiring it to be the root or a
descendant of the root’s own realpath – never by textual .. rejection alone (which a symlink
trivially bypasses).
- cobbler.services.files.CACHE_TTL_SECONDS = 30.0
How long a resolved
source_tree_path(or a negative “not available” result) is cached for, per distro name, before another XML-RPCget_distrocall is made.
- exception cobbler.services.files.RangeUnsatisfiable[source]
Bases:
ExceptionRaised by
parse_range()when theRangeheader is syntactically a byte-range but requests a start offset beyond the file’s size, i.e. a416 Range Not Satisfiable.
- cobbler.services.files.application(environ: Dict[str, Any], start_response: Callable[[str, List[Any]], None]) Any[source]
WSGI entrypoint for direct-disk distro tree file serving.
Expects to be invoked (via
cobbler.services.application’s dispatch) for request paths of the shape/tree/<distro_name>/<relative_path>– i.e. the client-facing/cblr/svc/tree/...URL with Apache’sProxyPassprefix already stripped, exactly likecobbler.services.svc.applicationsees its own paths viaenviron["RAW_URI"].Only
GETandHEADare supported.HEADruns through the exact same resolution/header-computation logic asGET(so e.g.Content-Length/Content-Typereflect the same values aGETwould have produced) but the response body is discarded before returning, per RFC 7231 section 4.3.2. Any other method (POST,DELETE, …) is rejected outright with405 Method Not Allowedrather than being treated as aGET.- Parameters:
environ – The WSGI environ.
start_response – The WSGI
start_responsecallable.
- cobbler.services.files.healthz_application(environ: Dict[str, Any], start_response: Callable[[str, List[Any]], None]) Any[source]
WSGI entrypoint for
/healthz: reports whether cobblerd’s XML-RPC endpoint is reachable and responsive.Only
GETandHEADare supported, exactly likeapplication(). A successful XML-RPCping()round trip yields200 OK; any failure to reach or get a response from cobblerd (connection refused, timeout, an XML-RPC fault, or a malformed/missing settings file, all of which surface asOSError/xmlrpc.client.Fault/xmlrpc.client.ProtocolError) yields503 Service Unavailablerather than propagating as an unhandled exception/500.- Parameters:
environ – The WSGI environ.
start_response – The WSGI
start_responsecallable.
- cobbler.services.files.httpboot_application(environ: Dict[str, Any], start_response: Callable[[str, List[Any]], None]) Any[source]
WSGI entrypoint for direct-disk serving of
/httpboot(UEFI HTTP(S) boot files), the Gunicorn equivalent of Apache’sAlias /httpboot @@tftproot@@/grub.Only
GETandHEADare supported, exactly likeapplication().- Parameters:
environ – The WSGI environ.
start_response – The WSGI
start_responsecallable.
- cobbler.services.files.images_application(environ: Dict[str, Any], start_response: Callable[[str, List[Any]], None]) Any[source]
WSGI entrypoint for direct-disk serving of
/images(UEFI HTTP(S) boot files), the Gunicorn equivalent of Apache’sAlias /images @@tftproot@@/grub/images.Only
GETandHEADare supported, exactly likeapplication().- Parameters:
environ – The WSGI environ.
start_response – The WSGI
start_responsecallable.
- cobbler.services.files.is_safe_path(root_real: str, candidate_real: str) bool[source]
Check whether an already-
realpath-resolved candidate path is the root itself or a proper descendant of it.Both inputs must already have been passed through
os.path.realpathby the caller – this function itself does no filesystem access, which is what makes it cheaply, deterministically unit-testable on plain strings. The actual security property (catching symlink escapes) comes entirely from the caller having resolvedcandidate_realwithrealpathafter joining in the untrusted relative path, not from anything this function does.- Parameters:
root_real – The realpath of the distro’s
source_tree_pathroot.candidate_real – The realpath of the fully-joined candidate path.
- Returns:
Trueifcandidate_realisroot_realor a descendant of it.
- cobbler.services.files.parse_range(header: str, size: int) Tuple[int, int] | None[source]
Parse an HTTP
Rangeheader of the formbytes=start-end(both bounds optional, per RFC 7233), against a known file size.Suffix ranges (
bytes=-N, meaning “the last N bytes”) and multi-range requests (bytes=0-99,200-299) are treated as unsupported and cause the request to be served in full (Noneis returned, i.e. “no usable range, ignore it”), rather than as an error – this mirrors the permissive behavior most HTTP servers fall back to for Range syntax they don’t implement.- Parameters:
header – The raw
Rangeheader value, e.g.bytes=0-99.size – The total size of the file in bytes.
- Returns:
An inclusive
(start, end)tuple, orNoneif the header should be ignored and the full file served instead.- Raises:
RangeUnsatisfiable – if the requested start offset is beyond
size.
- cobbler.services.files.resolve_source_tree_path(distro_name: str) str | None[source]
Resolve a distro name to its
source_tree_path, via a short-TTL cached XML-RPC lookup.- Parameters:
distro_name – The name of the distro to resolve.
- Returns:
The distro’s
source_tree_path, orNoneif the distro doesn’t exist or has nosource_tree_pathset (both are treated identically by callers: a 404).
- cobbler.services.files.resolve_within_root(root: str, relative_path: str) str | None[source]
Join
relative_pathontorootand validate the result stays withinroot.This is the security-critical traversal guard. It defends against two distinct attacks:
Textual traversal: a
relative_pathcontaining../segments that would lexically escaperoot(e.g.../../etc/passwd).Symlink escape: a symlink that lives inside
root(so it wouldn’t be caught by rejecting..in the URL) but whose target points outside ofroot.
Both are defeated the same way:
os.path.realpathis applied to the final joined candidate path (not just to the root), which fully resolves both..segments and any symlinks encountered anywhere along the path – including a symlink as the last component. The resolved result is then required to be exactlyroot’s own realpath, or a path beginning withroot_real + os.sep. A leading/onrelative_pathis stripped first so an absolute-looking segment (e.g. from a doubled slash in the URL) can’t makeos.path.joindiscardrootoutright.- Parameters:
root – The distro’s
source_tree_path(already validated elsewhere to be an absolute, existing directory).relative_path – The untrusted, already-URL-decoded path requested by the client.
- Returns:
The resolved, validated, absolute realpath if it is safe, or
Noneif the request must be rejected (the caller maps this to403 Forbidden).
7.1.8.3. cobbler.services.svc module
Mod Python service functions for Cobbler’s public interface (aka cool stuff that works with wget/curl)
Changelog:
Schema: From -> To
Current Schema: Please refer to the documentation visible of the individual methods.
- V4.0.0 (unreleased)
No changes
- V3.3.4 (unreleased)
No changes
- V3.3.3
- Removed:
look
- V3.3.2
No changes
- V3.3.1
No changes
- V3.3.0
- Added:
settings
- Changed:
gpxe: Renamed toipxe
- V3.2.2
No changes
- V3.2.1
No changes
- V3.2.0
No changes
- V3.1.2
No changes
- V3.1.1
No changes
- V3.1.0
No changes
- V3.0.1
No changes
- V3.0.0
- Added:
autoinstallfind_autoinstall
- V2.8.5
Inital tracking of changes.
- class cobbler.services.svc.CobblerSvc(server: str = '')[source]
Bases:
objectInteresting mod python functions are all keyed off the parameter mode, which defaults to index. All options are passed as parameters into the function.
- autodetect(**kwargs: str | int | List[str]) str[source]
This tries to autodect the system with the given information. If more than one candidate is found an error message is returned.
- Parameters:
kwargs – The keys “REMOTE_MACS”, “REMOTE_ADDR” or “interfaces”.
- Returns:
The name of the possible object or an error message.
- autoinstall(profile: str | None = None, system: str | None = None, file: str = '', **kwargs: Any) str[source]
Generate automatic installation files.
- Parameters:
profile – The name of the profile to generate the autoinstall for.
system – The name of the system to generate the autoinstall for.
kwargs – This parameter is unused.
- Returns:
TODO
- bootcfg(profile: str | None = None, system: str | None = None, **kwargs: Any) str[source]
Generate a boot.cfg config file. Used primarily for VMware ESXi.
- Parameters:
profile
system
kwargs – This parameter is unused.
- Returns:
- events(user: str = '', **kwargs: Any) str[source]
If no user is given then all events are returned. Otherwise only event associated to a user are returned.
- Parameters:
user – Filter the events for a given user.
kwargs – This parameter is unused.
- Returns:
A JSON object which contains all events.
- find_autoinstall(system: str | None = None, profile: str | None = None, **kwargs: str | int) str[source]
Find an autoinstallation for a system or a profile. If this is not known different parameters can be passed to kwargs to find it automatically. See “autodetect”.
- Parameters:
system – The system to find the autoinstallation for,
profile – The profile to find the autoinstallation for.
kwargs – The metadata to find the autoinstallation automatically.
- Returns:
The autoinstall script or error message.
- index(**kwargs: Any) str[source]
Just a placeholder method as an entry point.
- Parameters:
kwargs – This parameter is unused.
- Returns:
“no mode specified”
- ipxe(profile: str | None = None, image: str | None = None, system: str | None = None, mac: str | None = None, **kwargs: Any)[source]
Generates an iPXE configuration.
- Parameters:
profile – A profile.
image – An image.
system – A system.
mac – A MAC address.
kwargs – This parameter is unused.
- list(what: str = 'systems', **kwargs: Any) str[source]
Return a list of objects of a desired category. Defaults to “systems”.
- Parameters:
what – May be “systems”, “profiles”, “distros”, “images”, “repos” or “menus”
kwargs – This parameter is unused.
- Returns:
The list of object names.
- nopxe(system: str | None = None, **kwargs: Any) str[source]
Disables the network boot for the given system.
- Parameters:
system – The system to disable netboot for.
kwargs – This parameter is unused.
- Returns:
A boolean status if the action succeed or not.
- property remote: ServerProxy
Sets up the connection to the Cobbler XMLRPC server. This is the version that does not require a login.
- script(profile: str | None = None, system: str | None = None, **kwargs: Any) str[source]
Generate a script based on snippets. Useful for post or late-action scripts where it’s difficult to embed the script in the response file.
- Parameters:
profile – The profile to generate the script for.
system – The system to generate the script for.
kwargs – This may contain a parameter with the key “query_string” which has a key “script” which may be an array. The element from position zero is taken.
- Returns:
The generated script.
- template(profile: str | None = None, system: str | None = None, path: str | None = None, **kwargs: Any) str[source]
Generate a templated file for the system. Either specify a profile OR a system.
- Parameters:
profile – The profile to provide for the generation of the template.
system – The system to provide for the generation of the template.
path – The path to the template.
kwargs – This parameter is unused.
- Returns:
The rendered template.
- trig(mode: str = '?', profile: str | None = None, system: str | None = None, REMOTE_ADDR: str | None = None, **kwargs: Any) str[source]
Hook to call install triggers. Only valid for a profile OR a system.
- Parameters:
mode – Can be “pre”, “post” or “firstboot”. Everything else is invalid.
profile – The profile object to run triggers for.
system – The system object to run triggers for.
REMOTE_ADDR – The ip if the remote system/profile.
kwargs – This parameter is unused.
- Returns:
The return code of the action.
- yum(profile: str | None = None, system: str | None = None, **kwargs: Any) str[source]
Generate a repo config. Either specify a profile OR a system.
- Parameters:
profile – The profile to provide for the generation of the template.
system – The system to provide for the generation of the template.
kwargs – This parameter is unused.
- Returns:
The generated repository config.
- cobbler.services.svc.VALUE_KEY = <object object>
Empty instance. A unique marker value used instead of None to differentiate between when a key should be used for a value and when ‘None’ is a valid entry in a dictionary.
7.1.8.4. Module contents
Gunicorn entry point for Cobbler’s WSGI service(s): gunicorn cobbler.services:application.
- cobbler.services.application(environ: Dict[str, Any], start_response: Callable[[str, List[Any]], None]) List[bytes][source]
WSGI entrypoint for Gunicorn.
Dispatches requests for the direct-disk distro tree file server (client-facing
/cblr/svc/tree/..., seen here – after Apache’sProxyPassstrips the/cblr/svc/prefix – as/tree/...inenviron["RAW_URI"]) tocobbler.services.files. Requests for/httpboot/...and/images/...(UEFI HTTP(S) boot files, statically served by Apache’s ownAliasdirectives today – not proxied, so no prefix-stripping happens for them) are likewise dispatched straight tocobbler.services.files./healthz(a liveness check backed by an XML-RPC round trip against cobblerd, for Docker’sHEALTHCHECKand orchestration tooling) is dispatched there too. Everything else falls through to the existing XML-RPC-backedcobbler.services.svcapp, unchanged.- Parameters:
environ
start_response
- Returns: