Utilities#

SPK#

The SPK class handles parsing and introspection of .spk package files.

class spkrepo.utils.SPK(stream)[source]#

SPK utilities

Parameters:

stream (fileobj) – SPK file stream

BOOLEAN_INFO = {'ctl_stop', 'startable', 'support_conf_folder'}#

Boolean INFO keys

REQUIRED_INFO = {'arch', 'description', 'displayname', 'package', 'version'}#

Required keys in the INFO file

SIGNATURE_FILENAME = 'syno_signature.asc'#

Signature filename

calculate_md5()[source]#
conf_filename_re = re.compile('^conf/.+$')#

Regex for files in conf

firmware_type_re = re.compile('^([a-z]){3,}$')#
firmware_version_re = re.compile('^\\d+\\.\\d$')#

Regex for firmware input

icon_filename_re = re.compile('^PACKAGE_ICON(?:_(?P<size>120|256))?\\.PNG$')#

Regex for icons in files

icon_info_re = re.compile('^package_icon(?:_(?P<size>120|256))?$')#

Regex for icons in INFO

info_line_re = re.compile('^(?P<key>\\w+)="(?P<value>.*)"$', re.MULTILINE)#

Regex for a line of the INFO file

package_re = re.compile('^[\\w-]+$')#

Regex for package in INFO file

script_filename_re = re.compile('^scripts/.+$')#

Regex for files in scripts

sign(timestamp_url, gnupghome)[source]#

Sign the package

Parameters:
  • timestamp_url – url for the remote timestamping

  • gnupghome – path to the gnupg home

unsign()[source]#

Remove the signature file of the package

wizard_filename_re = re.compile('^WIZARD_UIFILES/(?P<process>install|upgrade|uninstall)_uifile(?:_[a-z]{3})?(?:\\.sh)?$')#

Regex for a wizard filename

Helpers#

These functions resolve reference data and apply SPK metadata to the database.

spkrepo.utils.resolve_firmware(session, value, allow_none=False)[source]#

Resolve a firmware string like ‘6.2-23739’ to a Firmware.

Parameters:
  • session – SQLAlchemy session

  • value – firmware string from SPK INFO

  • allow_none – if True, a missing/empty value returns None instead of raising

Raises:

ValueError – if the value is missing (and allow_none is False), malformed, or not found in the database

spkrepo.utils.resolve_architectures(session, arch_string)[source]#

Resolve a space-separated architecture string from SPK INFO to a list of Architecture instances.

Parameters:
  • session – SQLAlchemy session

  • arch_string – space-separated arch string e.g. “88f628x x86_64”

Raises:

ValueError – if arch_string is missing or any architecture is unknown

spkrepo.utils.resolve_services(service_string)[source]#

Resolve a space-separated service dependency string from SPK INFO to a list of Service instances.

Parameters:

service_string – space-separated service codes e.g. “apache-web mysql”, or None/empty for no dependencies

Raises:

ValueError – if any service code is not found in the database

spkrepo.utils.extract_version_metadata(spk)[source]#

Extract all version-level fields from an SPK into a plain dict without touching the database. Used to compare builds of the same version for consistency before writing anything.

Parameters:

spk – a parsed SPK instance

Returns:

dict of version-level field values

spkrepo.utils.apply_info_from_spk(session, build, spk, md5_hash)[source]#

Apply all metadata from a parsed SPK onto the given build and its parent version. Used by the resync path (tasks.py’s resync_build_metadata, triggered from admin.py). NOT currently used by the upload path (api.py’s Packages.post), which has its own separate, inline implementation of similar logic for creating new Package/Version/Build records — see that function if you need to keep both in sync.

Version-level fields (shared across all builds of a version) are written unconditionally — callers must ensure consistency has already been checked via assert_version_metadata_matches_db() before calling this.

Note

Icon files are written to disk before the database is flushed. If a subsequent error causes the caller to roll back the session, any newly written icon files will be left on disk. Callers that require strict atomicity should handle cleanup themselves (e.g. via _cleanup_on_failure()).

Note

This function calls session.flush() at the end to push all pending changes to the database within the current transaction. The caller is responsible for committing or rolling back.

Parameters:
  • session – SQLAlchemy session

  • build – the Build to update

  • spk – a parsed SPK instance

  • md5_hash – pre-calculated MD5 hex string of the SPK file

Raises:

ValueError – on any validation failure (package mismatch, bad version, etc.)

spkrepo.utils.apply_sidecar_to_db(session, build, sidecar)[source]#

Apply sidecar metadata to a build and its version without the SPK archive.

spkrepo.utils.populate_db()[source]#

Populate the database