diff --git a/README.md b/README.md index c5751715..7b6ac17e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,13 @@ -# Aos meta layer +# AosCore meta layer -This meta layer contains recipes for Aos components such as: +This meta layer contains recipes for AosCore components such as: -* aos-communicationmanager - Aos communication manager; -* aos-iamanager - Aos identity and access manager; -* aos-servicemanager - Aos service manager; -* aos-updatemanager - Aos update manager; -* aos-vis - Aos vehicle information service; -* Aos CNI plugins; -* other tools and utility for AosEdge core part. +* aos-communicationmanager - AosCore communication manager; +* aos-iamanager - AosCore identity and access manager; +* aos-servicemanager - AosCore service manager; +* aos-updatemanager - AosCore update manager; +* aos-vis - AosCore vehicle information service; +* other tools and utility for AosCore operation. ## How to integrate Aos meta layer to custom product @@ -18,5 +17,3 @@ see [Aos Core integration](doc/integration.md) document. ## Misc * Set PREFERRED_PROVIDER_virtual/runc = "runc-opencontainers" to build runc from opencontainers. -* Set AOS_RUNNER to define which runner will be used to run Aos services. Currently supported: runc and crun. -Default is crun. diff --git a/classes/bundle-generator.bbclass b/classes/bundle-generator.bbclass deleted file mode 100644 index 7a9feaac..00000000 --- a/classes/bundle-generator.bbclass +++ /dev/null @@ -1,9 +0,0 @@ -# This class containes functions to generate update bundle - -AOS_BUNDLE_DIR ??= "${DEPLOY_DIR_IMAGE}/update" -AOS_BUNDLE_FILE ??= "${IMAGE_BASENAME}-${MACHINE}-${PV}.bundle.tar" -AOS_BUNDLE_WORK_DIR ??= "${WORKDIR}/update" - -do_pack_bundle() { - tar cf ${AOS_BUNDLE_DIR}/${AOS_BUNDLE_FILE} -C ${AOS_BUNDLE_WORK_DIR}/ . -} diff --git a/classes/layer-generator.bbclass b/classes/layer-generator.bbclass index 98347d5b..feb83fe8 100644 --- a/classes/layer-generator.bbclass +++ b/classes/layer-generator.bbclass @@ -1,17 +1,14 @@ -# This class containes functions to generate layers +# This class contains functions to generate layers # Configuration AOS_BASE_IMAGE ??= "aos-image" AOS_PARENT_LAYER ??= "${AOS_BASE_IMAGE}" AOS_LAYER_FEATURES ??= "" -AOS_LAYER_VERSION ??= "1" -AOS_LAYER_DIGEST_TYPE ??= "sha256" +AOS_LAYER_VERSION ??= "1.0.0" AOS_LAYER_DEPLOY_DIR ??= "${DEPLOY_DIR_IMAGE}/layers" - -# Inherit - -inherit metadata-generator +AOS_LAYER_OS ??= "${AOS_OS}" +AOS_LAYER_ARCH ??= "${AOS_ARCHITECTURE}" # Dependencies @@ -19,19 +16,16 @@ DEPENDS:append = " rsync-native" # Variables -LAYER_MEDIA_TYPE = "application/vnd.aos.image.layer.v1.tar" -LAYER_WORK_DIR = "${WORKDIR}/layer" PARENT_LAYER_ROOTFS = "${TMPDIR}/work-shared/${AOS_PARENT_LAYER}-${MACHINE}/rootfs" ROOTFS_DIFF_DIR = "${WORKDIR}/rootfs_diff" -SHARED_DIGEST_DIR = "${TMPDIR}/work-shared/layers-${AOS_LAYER_DIGEST_TYPE}" IMAGE_INSTALL:append = "${AOS_LAYER_FEATURES}" # Dirs -do_create_layer[cleandirs] += "${LAYER_WORK_DIR} ${ROOTFS_DIFF_DIR}" +do_create_layer[cleandirs] += "${ROOTFS_DIFF_DIR}" do_create_layer[depends] += "${AOS_PARENT_LAYER}:do_create_shared_links" -do_create_layer[dirs] += "${SHARED_DIGEST_DIR} ${AOS_LAYER_DEPLOY_DIR} ${LAYER_WORK_DIR}" +do_create_layer[dirs] += "${AOS_LAYER_DEPLOY_DIR}" # Disable unneeded tasks @@ -44,19 +38,6 @@ do_image_complete[noexec] = "1" do_create_rootfs_archive() { rsync -HXlrvcm --append --progress --delete --compare-dest=${PARENT_LAYER_ROOTFS}/ ${IMAGE_ROOTFS}/* ${ROOTFS_DIFF_DIR} find ${ROOTFS_DIFF_DIR} -type d -empty -delete - - # Create layer rootfs tar - - IMAGE_ROOTFS_TAR=${LAYER_WORK_DIR}/${PN}.tar - - ${IMAGE_CMD_TAR} --numeric-owner -cf ${IMAGE_ROOTFS_TAR} -C ${ROOTFS_DIFF_DIR} . - - # Create layer rootfs digest - - DIGEST="$(${AOS_LAYER_DIGEST_TYPE}sum -b ${IMAGE_ROOTFS_TAR} | cut -d' ' -f1)" - echo "${DIGEST} ${AOS_LAYER_VERSION}" > ${SHARED_DIGEST_DIR}/${PN}.${AOS_LAYER_DIGEST_TYPE} - - mv ${IMAGE_ROOTFS_TAR} ${LAYER_WORK_DIR}/${DIGEST} } python do_create_whiteouts() { @@ -88,43 +69,8 @@ python do_create_whiteouts() { } -python do_create_metadata() { - import os - - # Plarform info - - platform_info = create_layer_platform_info(d.getVar("TARGET_ARCH"), d.getVar("TARGET_OS"), d.getVar("DISTRO_VERSION"), - d.getVar("AOS_LAYER_FEATURES").split()) - - # Annotations - - parent_id = "" - parent_digest = "" - - if d.getVar("AOS_PARENT_LAYER") != d.getVar("AOS_BASE_IMAGE"): - f = open(os.path.join(d.getVar("SHARED_DIGEST_DIR"), - "{}.{}".format(d.getVar("AOS_PARENT_LAYER"), d.getVar("AOS_LAYER_DIGEST_TYPE"))), "r") - - data = f.read().split() - parent_id = "{}:{}".format(d.getVar("AOS_PARENT_LAYER"), data[1]) - parent_digest = "{}:{}".format(d.getVar("AOS_LAYER_DIGEST_TYPE"), data[0]) - - annotations = create_layer_annotations("{}:{}".format(d.getVar("PN"), d.getVar("AOS_LAYER_VERSION")), parent_id, parent_digest) - - # Write metadata - - f = open(os.path.join(d.getVar("SHARED_DIGEST_DIR"), - "{}.{}".format(d.getVar("PN"), d.getVar("AOS_LAYER_DIGEST_TYPE"))), "r") - - data = f.read().split() - digest = "{}:{}".format(d.getVar("AOS_LAYER_DIGEST_TYPE"), data[0]) - - write_layer_metadata(d.getVar("LAYER_WORK_DIR"), d.getVar("LAYER_MEDIA_TYPE"), digest, - os.path.getsize(os.path.join(d.getVar("LAYER_WORK_DIR"), data[0])), platform_info, annotations) -} - do_pack_layer() { - ${IMAGE_CMD_TAR} --numeric-owner -czf ${AOS_LAYER_DEPLOY_DIR}/${PN}-${AOS_LAYER_VERSION}-${MACHINE}.tar.gz -C ${LAYER_WORK_DIR} . + ${IMAGE_CMD_TAR} --numeric-owner -cf - -C ${ROOTFS_DIFF_DIR} . | gzip -n > ${AOS_LAYER_DEPLOY_DIR}/${AOS_LAYER_OS}-${AOS_LAYER_ARCH}-${AOS_LAYER_VERSION}.tar.gz } do_create_layer[nostamp] = "1" @@ -132,7 +78,6 @@ do_create_layer[nostamp] = "1" fakeroot python do_create_layer() { bb.build.exec_func("do_create_whiteouts", d) bb.build.exec_func("do_create_rootfs_archive", d) - bb.build.exec_func("do_create_metadata", d) bb.build.exec_func("do_pack_layer", d) } diff --git a/classes/metadata-generator.bbclass b/classes/metadata-generator.bbclass deleted file mode 100644 index 686a6dbe..00000000 --- a/classes/metadata-generator.bbclass +++ /dev/null @@ -1,169 +0,0 @@ -# This class contains functions to generate uppdate bundle metadata - -# Update bundle metadata - -def create_dep(id, required_version, min_version=None, max_version=None): - FIELD_ID = "id" - FIELD_REQUIRED_VERSION = "requiredVersion" - FIELD_MIN_VERSION = "minVersion" - FIELD_MAX_VERSION = "maxVersion" - - if required_version and (min_version or max_version): - raise RuntimeError( - "{} should not be set along with {} or {}".format(FIELD_REQUIRED_VERSION, FIELD_MIN_VERSION, FIELD_MAX_VERSION)) - - return {FIELD_ID: id, FIELD_REQUIRED_VERSION: required_version, FIELD_MIN_VERSION: min_version, FIELD_MAX_VERSION: max_version} - - -def create_component_metadata(id, file_name, version, description=None, install_dep=None, runtime_deps=None, annotations=None, download_ttl=None): - FIELD_ID = "id" - FIELD_FILE_NAME = "fileName" - FIELD_VERSION = "version" - FIELD_DESCRIPTION = "description" - FIELD_REQUIRED_VERSION = "requiredVersion" - FIELD_MIN_VERSION = "minVersion" - FIELD_MAX_VERSION = "maxVersion" - FIELD_RUNTIME_DEPS = "runtimeDependencies" - FIELD_ANNOTATIONS = "annotations" - FIELD_DOWNLOAD_TTL = "downloadTTL" - - # check mandatory fields - if not id or not file_name or not version: - raise RuntimeError( - "mandatory field ({} or {} or {}) is missing".format(FIELD_ID, FIELD_FILE_NAME, FIELD_VERSION)) - - component = {FIELD_ID: id, FIELD_FILE_NAME: file_name, - FIELD_VERSION: version, FIELD_DESCRIPTION: description, FIELD_ANNOTATIONS: annotations, - FIELD_DOWNLOAD_TTL: download_ttl} - - # install dep - if install_dep: - if not isinstance(install_dep, dict): - raise RuntimeError( - "install_deps should be dictionary") - - if install_dep.get(FIELD_REQUIRED_VERSION) and (install_dep.get(FIELD_MIN_VERSION) or install_dep.get(FIELD_MAX_VERSION)): - raise RuntimeError( - "{} should not be set along with {} or {}".format(FIELD_REQUIRED_VERSION, FIELD_MIN_VERSION, FIELD_MAX_VERSION)) - - install_deps_id = install_dep.get(FIELD_ID) - - if install_deps_id and install_deps_id != id: - raise RuntimeError( - "install deps {} should be equal to item {}".format(FIELD_ID, FIELD_ID)) - - component[FIELD_REQUIRED_VERSION] = install_dep.get( - FIELD_REQUIRED_VERSION) - component[FIELD_MIN_VERSION] = install_dep.get(FIELD_MIN_VERSION) - component[FIELD_MAX_VERSION] = install_dep.get(FIELD_MAX_VERSION) - - # runtime deps - if runtime_deps: - if not isinstance(runtime_deps, list): - raise RuntimeError( - "runtime_deps should be list") - - component[FIELD_RUNTIME_DEPS] = [] - - for dep in runtime_deps: - if not isinstance(dep, dict): - raise RuntimeError( - "runtime_deps item should be dict") - - if not dep.get(FIELD_ID): - raise RuntimeError( - "missing mandatory field {} in runtime deps".format(FIELD_ID)) - - if dep.get(FIELD_REQUIRED_VERSION) and (dep.get(FIELD_MIN_VERSION) or dep.get(FIELD_MAX_VERSION)): - raise RuntimeError( - "{} should not be set along with {} or {}".format(FIELD_REQUIRED_VERSION, FIELD_MIN_VERSION, FIELD_MAX_VERSION)) - - component[FIELD_RUNTIME_DEPS].append( - {FIELD_ID: dep.get(FIELD_ID), FIELD_REQUIRED_VERSION: dep.get(FIELD_REQUIRED_VERSION), - FIELD_MIN_VERSION: dep.get(FIELD_MIN_VERSION), FIELD_MAX_VERSION: dep.get(FIELD_MAX_VERSION)}) - - return component - -def remove_empty_elements(metadata): - def empty(value): - return not value or value == {} or value == [] - - if not isinstance(metadata, (dict, list)): - return metadata - elif isinstance(metadata, list): - return [value for value in (remove_empty_elements(value) for value in metadata) if not empty(value)] - else: - return {key: value for key, value in ((key, remove_empty_elements(value)) for key, value in metadata.items()) if not empty(value)} - -def write_image_metadata(output_dir, components): - import os - import json - - FORMAT_VERSION = 1 - METADATA_FILE_NAME = "metadata.json" - - FIELD_FORMAT_VERSION = "formatVersion" - FIELD_COMPONENTS = "components" - - # check mandatory fields - if not components: - raise RuntimeError( - "mandatory field ({}) is missing".format(FIELD_COMPONENTS)) - - if not isinstance(components, list): - raise RuntimeError( - "components should be list") - - for component in components: - if not isinstance(component, dict): - raise RuntimeError( - "components item should be dict") - - metadata = {FIELD_FORMAT_VERSION: FORMAT_VERSION, FIELD_COMPONENTS: components} - - metadata = remove_empty_elements(metadata) - - with open(os.path.join(output_dir, METADATA_FILE_NAME), 'w') as outfile: - json.dump(metadata, outfile, indent=4) - -# Layer metadata - -def create_layer_platform_info(arch, os, os_version, os_features): - FIELD_ARCH = "architecture" - FIELD_OS = "os" - FIELD_OS_VERSION = "osVersion" - FIELD_OS_FEATURES = "osFeatures" - - return {FIELD_ARCH : arch, FIELD_OS: os, FIELD_OS_VERSION: os_version, FIELD_OS_FEATURES: os_features} - -def create_layer_annotations(layer_id, parent_layer_id=None, parent_layer_digest=None): - FIELD_LAYER_ID = "layerId" - FIELD_PARENT_LAYER_ID = "parrentLayerId" - FIELD_PARENT_LAYER_DIGEST = "parrentLayerDigest" - - return {FIELD_LAYER_ID : layer_id, FIELD_PARENT_LAYER_ID: parent_layer_id, FIELD_PARENT_LAYER_DIGEST: parent_layer_digest} - -def write_layer_metadata(output_dir, media_type, digest, size, platform_info=None, annotations=None): - import os - import json - - FIELD_MEDIATYPE = "mediaType" - FIELD_DIGEST = "digest" - FIELD_SIZE = "size" - FIELD_PLATFORM = "platform" - FIELD_ANNOTATIONS = "annotations" - - METADATA_FILE_NAME = "metadata.json" - - # check mandatory fields - if not media_type or not digest or not size: - raise RuntimeError( - "mandatory field ({} or {} or {}) is missing".format(FIELD_MEDIATYPE, FIELD_DIGEST, FIELD_SIZE)) - - metadata = {FIELD_MEDIATYPE: media_type, FIELD_DIGEST: digest, FIELD_SIZE: size, - FIELD_PLATFORM: platform_info, FIELD_ANNOTATIONS: annotations} - - metadata = remove_empty_elements(metadata) - - with open(os.path.join(output_dir, METADATA_FILE_NAME), 'w') as outfile: - json.dump(metadata, outfile, indent=4) diff --git a/conf/distro/aos-core.conf b/conf/distro/aos-core.conf new file mode 100644 index 00000000..e6d0e4de --- /dev/null +++ b/conf/distro/aos-core.conf @@ -0,0 +1,12 @@ +include conf/distro/poky.conf + +DISTRO = "aos-core" +DISTRO_NAME = "AosCore" +DISTRO_VERSION = "${AOS_ROOTFS_IMAGE_VERSION}" +SDK_VENDOR = "-aossdk" +SDK_VERSION="${AOS_ROOTFS_IMAGE_VERSION}" +SDK_VERSION[vardepvalue] = "${AOS_ROOTFS_IMAGE_VERSION}" +SDK_NAME = "${DISTRO}-${SDKMACHINE}" +SDKPATHINSTALL = "/opt/${DISTRO}-sdk/${MACHINE}/${SDK_VERSION}" +TOOLCHAIN_OUTPUTNAME = "${SDK_NAME}-toolchain-${MACHINE}-${SDK_VERSION}" +TARGET_VENDOR = "-aos" diff --git a/conf/layer.conf b/conf/layer.conf index 17dd2dad..f435ae5a 100644 --- a/conf/layer.conf +++ b/conf/layer.conf @@ -22,12 +22,10 @@ AOS_MAIN_NODE ?= "1" AOS_NODE_TYPE ?= "${AOS_UNIT_MODEL}-${AOS_UNIT_VERSION}-${@'main' \ if bb.utils.to_boolean(d.getVar('AOS_MAIN_NODE')) else 'secondary'}" -AOS_RUNNER ??= "crun" - AOS_NODE_HOSTNAME ?= "${@'main' if bb.utils.to_boolean(d.getVar('AOS_MAIN_NODE')) else 'secondary'}" AOS_MAIN_NODE_HOSTNAME ?= "main" -AOS_UM_COMPONENT_PREFIX ?= "" +AOS_COMPONENT_RUNTIME_PREFIX ?= "" # Overrides diff --git a/doc/integration.md b/doc/integration.md index b3c8c279..e8851a8c 100644 --- a/doc/integration.md +++ b/doc/integration.md @@ -6,8 +6,8 @@ * required additional meta layers: meta-virtualization, meta-security; * init manager: systemd; * required distro features: virtualization, seccomp; -* kernel options (modules or builtin): bridge, nf_conncount, nfnetlink, overlay, squashfs, veth, xt_addrtype, -xt_comment, xt_conntrack, xt_masquerade +* kernel options (modules or builtin): bridge, veth, vxlan, 8021q, ifb, overlay, squashfs, nfnetlink, nf_tables, +nf_conntrack, nf_nat, nft_ct, nft_nat, nft_chain_nat, nft_masq, sch_tbf, sch_ingress, act_mirred, cls_matchall * dedicated RW partition to store Aos services, layers and OTA update artifacts. ## Main components integration @@ -74,12 +74,11 @@ WKS_FILE = "custom.wks.in" Aos main components should be added into the target image by appending `IMAGE_INSTALL` variable in `local.conf`: ```bash -IMAGE_INSTALL:append = " aos-iamanager aos-provfirewall aos-communicationmanager aos-servicemanager aos-updatemanager" +IMAGE_INSTALL:append = " aos-iamanager aos-provfirewall aos-communicationmanager aos-servicemanager" ``` -`aos-iamanager`, `aos-communicationmanager`, `aos-servicemanager` are core Aos components. `aos-updatemanager` is -responsible for Aos OTA updates. If OTA system components update is not needed, `aos-updatemanager` may be removed from -the target image. It also required `umController` section to be removed from `aos-communicationmanager` config as +`aos-iamanager`, `aos-communicationmanager`, `aos-servicemanager` are core Aos components. +It also required `umController` section to be removed from `aos-communicationmanager` config as well as `um` storage to be removed from `aos-iamanager` config. `aos-provfirewall` is helper service that closes provisioning ports after provisioning for security reason. @@ -177,33 +176,7 @@ by other layer recipes. See [aos-vm][aos-vm] layers as example. ## Integrate Aos FOTA update -`aos-updatemanager` performs Aos OTA update of different system components with dedicated plugins. `aos-updatemanager` -has an example implementation of updating disk partitions using dual partition (A/B) approach as well as using overlay -approach. Aos overlay OTA update supports incremental update (delta update) whereas dual partition update supports only -full partition update. - -See reference Aos products as example of boot and roofs partitions update. At these products, rootfs is updated using -overlay approach, boot partition is updated using A/B approach. In [aos-vm][aos-vm] switching between A/B partition is -done by using `efi` boot manager at same time in [aos-rcar-gen3][aos-rcar-gen3] and [aos-rcar-gen4][aos-rcar-gen4] -switching A/B partition is done by using U-Boot environment variables. - -For a custom component update, the appropriate `aos-updatemanager` shall be implemented and integrated. - -Reference Aos FOTA implementation requires readonly rootfs. It can be enabled by setting the following variable in -`local.conf`: - -```bash -IMAGE_FEATURES:append = " read-only-rootfs" -``` - -`meta-aos` provides base Aos image recipe with RO rootfs and generating required for FOTA versioning files. You can -simple use it as your image file or include it in your own image file: - -```bash -require recipes-core/images/aos-image.inc -``` - -See [aos-vm][aos-vm] for reference. +*TBD* ## Integration using moulin meta build system @@ -238,7 +211,7 @@ components: - [DISTRO_FEATURES:append, " virtualization security"] # selinux is optional - [DISTRO_FEATURES:append, " acl xattr pam selinux"] - - [IMAGE_INSTALL:append, " aos-iamanager aos-provfirewall aos-communicationmanager aos-servicemanager aos-updatemanager"] + - [IMAGE_INSTALL:append, " aos-iamanager aos-provfirewall aos-communicationmanager aos-servicemanager"] # AOS VIS is optional - [IMAGE_INSTALL:append, " aos-vis"] # AOS FOTA specific option diff --git a/recipes-aos-layers/aos-kuksa-client-layer/aos-kuksa-client-layer.bb b/recipes-aos-layers/aos-kuksa-client-layer/aos-kuksa-client-layer.bb new file mode 100644 index 00000000..0cbf895c --- /dev/null +++ b/recipes-aos-layers/aos-kuksa-client-layer/aos-kuksa-client-layer.bb @@ -0,0 +1,7 @@ +SUMMARY = "kuksa client layer" + +require recipes-aos-layers/aos-base-layer/aos-base-layer.inc + +AOS_LAYER_FEATURES += " \ + kuksa-client \ +" diff --git a/recipes-aos-layers/aos-libvis-layer/aos-libvis-layer.bb b/recipes-aos-layers/aos-libvis-layer/aos-libvis-layer.bb index e470d0fc..d3b56827 100644 --- a/recipes-aos-layers/aos-libvis-layer/aos-libvis-layer.bb +++ b/recipes-aos-layers/aos-libvis-layer/aos-libvis-layer.bb @@ -7,5 +7,3 @@ require recipes-aos-layers/aos-pylibs-layer/aos-pylibs-layer.bb AOS_LAYER_FEATURES += " \ libvis \ " - -AOS_LAYER_VERSION = "1.0.0" diff --git a/recipes-aos-layers/aos-nodejs-layer/aos-nodejs-layer.bb b/recipes-aos-layers/aos-nodejs-layer/aos-nodejs-layer.bb index 58ad384e..50d47f1c 100644 --- a/recipes-aos-layers/aos-nodejs-layer/aos-nodejs-layer.bb +++ b/recipes-aos-layers/aos-nodejs-layer/aos-nodejs-layer.bb @@ -5,5 +5,3 @@ require recipes-aos-layers/aos-base-layer/aos-base-layer.inc AOS_LAYER_FEATURES += " \ nodejs \ " - -AOS_LAYER_VERSION = "1.0.0" diff --git a/recipes-aos-layers/aos-pylibs-layer/aos-pylibs-layer.bb b/recipes-aos-layers/aos-pylibs-layer/aos-pylibs-layer.bb index fbdd9723..fea8da38 100644 --- a/recipes-aos-layers/aos-pylibs-layer/aos-pylibs-layer.bb +++ b/recipes-aos-layers/aos-pylibs-layer/aos-pylibs-layer.bb @@ -3,15 +3,15 @@ SUMMARY = "python libs layer" require recipes-aos-layers/aos-base-layer/aos-base-layer.inc AOS_LAYER_FEATURES += " \ + python3-aiohttp \ python3-compression \ python3-crypt \ python3-json \ python3-misc \ + python3-requests \ python3-shell \ python3-six \ + python3-socketio \ python3-threading \ python3-websocket-client \ - python3-requests \ " - -AOS_LAYER_VERSION = "1.0.0" diff --git a/recipes-aos-layers/aos-vim-layer/aos-vim-layer.bb b/recipes-aos-layers/aos-vim-layer/aos-vim-layer.bb index 6842f880..602cdb52 100644 --- a/recipes-aos-layers/aos-vim-layer/aos-vim-layer.bb +++ b/recipes-aos-layers/aos-vim-layer/aos-vim-layer.bb @@ -12,5 +12,3 @@ AOS_LAYER_WHITEOUTS += " \ /usr/share/applications/gvim.desktop \ /usr/share/applications/vim.desktop \ " - -AOS_LAYER_VERSION = "1.0.0" diff --git a/recipes-aos/aos-communicationmanager/aos-communicationmanager_git.bb b/recipes-aos/aos-communicationmanager/aos-communicationmanager_git.bb index 41b37195..58a89a08 100644 --- a/recipes-aos/aos-communicationmanager/aos-communicationmanager_git.bb +++ b/recipes-aos/aos-communicationmanager/aos-communicationmanager_git.bb @@ -1,25 +1,25 @@ DESCRIPTION = "AOS Communication Manager" -GO_IMPORT = "github.com/aosedge/aos_communicationmanager" - LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://src/${GO_IMPORT}/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" -BRANCH = "main" -SRCREV = "2c694749d00cbcc0db748a4f71ea7ee216a80d9c" +BRANCH = "develop" +SRCREV = "${AUTOREV}" -SRC_URI = "git://${GO_IMPORT}.git;branch=${BRANCH};protocol=https" +SRC_URI = "git://github.com/aosedge/aos_core_cpp.git;protocol=https;branch=${BRANCH}" SRC_URI += " \ - file://aos_communicationmanager.cfg \ - file://aos-communicationmanager.service \ + file://cm.cfg \ + file://aos-cm.service \ file://aos-target.conf \ file://aos-dirs-service.conf \ " -inherit go goarch systemd +S = "${WORKDIR}/git" + +inherit cmake pkgconfig systemd -SYSTEMD_SERVICE:${PN} = "aos-communicationmanager.service" +SYSTEMD_SERVICE:${PN} = "aos-cm.service" MIGRATION_SCRIPTS_PATH = "${base_prefix}/usr/share/aos/cm/migration" @@ -29,24 +29,27 @@ FILES:${PN} += " \ ${MIGRATION_SCRIPTS_PATH} \ " -DEPENDS = "systemd" - -RDEPENDS:${PN} += " \ - aos-rootca \ - nfs-exports \ -" +DEPENDS = "grpc grpc-native poco protobuf-native systemd curl libnl" -RDEPENDS:${PN}-dev += " bash make" -RDEPENDS:${PN}-staticdev += " bash make" +do_configure[network] = "1" -INSANE_SKIP:${PN} = "textrel" +EXTRA_OECMAKE += " \ + -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \ + -DWITH_CM=ON \ + -DWITH_IAM=OFF \ + -DWITH_MP=OFF \ + -DWITH_SM=OFF \ +" +OECMAKE_GENERATOR = "Unix Makefiles" -# embed version -GO_LDFLAGS += '-ldflags="-X main.GitSummary=`git --git-dir=${S}/src/${GO_IMPORT}/.git describe --tags --always`"' +PACKAGECONFIG ??= "openssl" -# WA to support go install for v 1.18 +PACKAGECONFIG[openssl] = "-DWITH_OPENSSL=ON,-DWITH_OPENSSL=OFF,openssl," +PACKAGECONFIG[mbedtls] = "-DWITH_MBEDTLS=ON,-DWITH_MBEDTLS=OFF,," -GO_LINKSHARED = "" +RDEPENDS:${PN} += " \ + nfs-exports \ +" RRECOMMENDS:${PN} += " \ kernel-module-quota-v1 \ @@ -57,7 +60,7 @@ RRECOMMENDS:${PN} += " \ python do_update_config() { import json - file_name = oe.path.join(d.getVar("D"), d.getVar("sysconfdir"), "aos", "aos_communicationmanager.cfg") + file_name = oe.path.join(d.getVar("D"), d.getVar("sysconfdir"), "aos", "cm.cfg") with open(file_name) as f: data = json.load(f) @@ -65,46 +68,50 @@ python do_update_config() { node_hostname = d.getVar("AOS_NODE_HOSTNAME") # Update IAM servers - - data["IAMProtectedServerURL"]= node_hostname+":8089" - data["IAMPublicServerURL"] = node_hostname+":8090" + + data["iamProtectedServerUrl"]= node_hostname + ":8089" + data["iamPublicServerUrl"] = node_hostname + ":8090" + + # Update DNS IP + + dns_ip = d.getVar("AOS_DNS_IP") + if dns_ip: + data["dnsIp"] = dns_ip main_node_hostname = d.getVar("AOS_MAIN_NODE_HOSTNAME") - # Update SM controller - sm_controller = data["SMController"] - sm_controller["FileServerURL"] = main_node_hostname+":8094" + # Update File Server URL - # Update CM controller - um_controller = data["UMController"] - um_controller["FileServerURL"] = main_node_hostname+":8092" + data["fileServerUrl"] = main_node_hostname + ":8094" with open(file_name, "w") as f: json.dump(data, f, indent=4) } -do_compile:prepend() { - cd ${GOPATH}/src/${GO_IMPORT}/ -} - do_install:append() { install -d ${D}${sysconfdir}/aos - install -m 0644 ${WORKDIR}/aos_communicationmanager.cfg ${D}${sysconfdir}/aos + install -m 0644 ${WORKDIR}/cm.cfg ${D}${sysconfdir}/aos install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/aos-communicationmanager.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/aos-cm.service ${D}${systemd_system_unitdir} install -d ${D}${sysconfdir}/systemd/system/aos.target.d install -m 0644 ${WORKDIR}/aos-target.conf ${D}${sysconfdir}/systemd/system/aos.target.d/${PN}.conf - install -d ${D}${sysconfdir}/systemd/system/aos-communicationmanager.service.d - install -m 0644 ${WORKDIR}/aos-dirs-service.conf ${D}${sysconfdir}/systemd/system/aos-communicationmanager.service.d/10-aos-dirs-service.conf + install -d ${D}${sysconfdir}/systemd/system/aos-cm.service.d + install -m 0644 ${WORKDIR}/aos-dirs-service.conf ${D}${sysconfdir}/systemd/system/aos-cm.service.d/10-aos-dirs-service.conf install -d ${D}${MIGRATION_SCRIPTS_PATH} - source_migration_path="/src/${GO_IMPORT}/database/migration" + source_migration_path="/src/cm/database/migration" if [ -d ${S}${source_migration_path} ]; then install -m 0644 ${S}${source_migration_path}/* ${D}${MIGRATION_SCRIPTS_PATH} fi } +do_install:append() { + # Do not install headers files to prevent SDK build conflicts + rm -rf ${D}${includedir} +} + + addtask update_config after do_install before do_package diff --git a/recipes-aos/aos-communicationmanager/files/aos-communicationmanager.service b/recipes-aos/aos-communicationmanager/files/aos-cm.service similarity index 50% rename from recipes-aos/aos-communicationmanager/files/aos-communicationmanager.service rename to recipes-aos/aos-communicationmanager/files/aos-cm.service index 9a6ef76e..1fc98f52 100644 --- a/recipes-aos/aos-communicationmanager/files/aos-communicationmanager.service +++ b/recipes-aos/aos-communicationmanager/files/aos-cm.service @@ -1,13 +1,13 @@ [Unit] Description=AOS Communication Manager -Wants=network-online.target aos-iamanager.service -After=network-online.target aos-iamanager.service +Wants=network-online.target aos-iam.service +After=network-online.target aos-iam.service ConditionPathExists=/var/aos/.provisionstate PartOf=aos.target [Service] Type=notify -ExecStart=/usr/bin/aos_communicationmanager -c /etc/aos/aos_communicationmanager.cfg -v debug -j +ExecStart=/usr/bin/aos_cm_app -c /etc/aos/cm.cfg -v debug -j Restart=always RestartSec=10 diff --git a/recipes-aos/aos-communicationmanager/files/aos-target.conf b/recipes-aos/aos-communicationmanager/files/aos-target.conf index d9fc3ec2..59102c98 100644 --- a/recipes-aos/aos-communicationmanager/files/aos-target.conf +++ b/recipes-aos/aos-communicationmanager/files/aos-target.conf @@ -1,3 +1,3 @@ [Unit] -Wants=aos-communicationmanager.service -After=aos-communicationmanager.service +Wants=aos-cm.service +After=aos-cm.service diff --git a/recipes-aos/aos-communicationmanager/files/aos_communicationmanager.cfg b/recipes-aos/aos-communicationmanager/files/aos_communicationmanager.cfg deleted file mode 100644 index e7d1e973..00000000 --- a/recipes-aos/aos-communicationmanager/files/aos_communicationmanager.cfg +++ /dev/null @@ -1,28 +0,0 @@ -{ - "Fcrypt": { - "CACert": "/etc/ssl/certs/Aos_Root_CA.pem" - }, - "CertStorage": "cm", - "ServiceDiscoveryURL": "https://aoscloud.io:9000", - "IAMProtectedServerURL": "aosiam:8089", - "IAMPublicServerURL": "aosiam:8090", - "CMServerURL": ":8095", - "WorkingDir": "/var/aos/workdirs/cm", - "StorageDir": "/var/aos/storages", - "StateDir": "/var/aos/states", - "Downloader": { - "DownloadDir": "/var/aos/downloads" - }, - "SMController": { - "CMServerURL": ":8093", - "UpdateTTL": "24h" - }, - "UMController": { - "CMServerURL": ":8091", - "UpdateTTL": "24h" - }, - "Migration": { - "MigrationPath": "/usr/share/aos/cm/migration", - "MergedMigrationPath": "/var/aos/workdirs/cm/migration" - } -} diff --git a/recipes-aos/aos-communicationmanager/files/cm.cfg b/recipes-aos/aos-communicationmanager/files/cm.cfg new file mode 100644 index 00000000..c1af01d0 --- /dev/null +++ b/recipes-aos/aos-communicationmanager/files/cm.cfg @@ -0,0 +1,23 @@ +{ + "caCert": "/usr/share/ca-certificates/aos/AosRootCA.crt", + "certStorage": "cm", + "serviceDiscoveryUrl": "https://aoscloud.io:9000/sd/v7/", + "iamProtectedServerUrl": "main:8089", + "iamPublicServerUrl": "main:8090", + "cmServerUrl": ":8093", + "workingDir": "/var/aos/workdirs/cm", + "storageDir": "/var/aos/storages", + "stateDir": "/var/aos/states", + "dnsIp": "10.0.0.100", + "fileServerUrl": "main:8094", + "imageManager": { + "installPath": "/var/aos/workdirs/cm/imagemanager/install", + "downloadPath": "/var/aos/workdirs/cm/imagemanager/downloads", + "updateItemTTL": "30d", + "removeOutdatedPeriod": "24h" + }, + "migration": { + "migrationPath": "/usr/share/aos/cm/migration", + "mergedMigrationPath": "/var/aos/workdirs/cm/migration" + } +} diff --git a/recipes-aos/aos-deprov/aos-deprov.bb b/recipes-aos/aos-deprov/aos-deprov.bb index c19d9a7c..c5ff1122 100644 --- a/recipes-aos/aos-deprov/aos-deprov.bb +++ b/recipes-aos/aos-deprov/aos-deprov.bb @@ -14,7 +14,7 @@ FILES:${PN} = " \ ${aos_opt_dir} \ " -RDEPENDS:${PN} += "aos-setupdisk" +RDEPENDS:${PN} += "aos-setupdisk nftables" do_install() { install -d ${D}${aos_opt_dir} diff --git a/recipes-aos/aos-deprov/files/deprovision.sh b/recipes-aos/aos-deprov/files/deprovision.sh index 50d31053..d4d272d0 100644 --- a/recipes-aos/aos-deprov/files/deprovision.sh +++ b/recipes-aos/aos-deprov/files/deprovision.sh @@ -13,6 +13,10 @@ clear_disks() { sync } +remove_firewall_rules() { + nft delete table inet aos-provfw 2>/dev/null +} + deprovision_async() { { sleep 1 @@ -21,6 +25,8 @@ deprovision_async() { # all services really stopped. systemctl stop -- $(systemctl show -p Wants aos.target | cut -d= -f2) + remove_firewall_rules + echo "Restore unprovisioned flag" | systemd-cat rm /var/aos/.provisionstate -f diff --git a/recipes-aos/aos-dnsname/aos-dnsname.bb b/recipes-aos/aos-dnsname/aos-dnsname.bb deleted file mode 100644 index e1e4f9b0..00000000 --- a/recipes-aos/aos-dnsname/aos-dnsname.bb +++ /dev/null @@ -1,38 +0,0 @@ -DESCRIPTION = "DNS name CNI plugin" - -GO_IMPORT = "github.com/aosedge/aos_cni_dns" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://src/${GO_IMPORT}/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -BRANCH = "main" -SRCREV = "2b6598aef27f7652c4c26b185dbafa5d1bccaef4" - -SRC_URI = "git://${GO_IMPORT}.git;branch=${BRANCH};protocol=https" - -inherit go -inherit goarch - -# embed version -GO_LDFLAGS += '-ldflags="-X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=`git --git-dir=${S}/src/${GO_IMPORT}/.git describe --tags --always`"' - -FILES:${PN} = "${libexecdir}/cni" - -RDEPENDS:${PN} += "\ - dnsmasq \ -" - -# WA to support go install for v 1.18 - -GO_LINKSHARED = "" - -do_compile:prepend() { - cd ${GOPATH}/src/${GO_IMPORT}/ -} - -do_install() { - localbindir="${libexecdir}/cni" - - install -d ${D}${localbindir} - install -m 755 ${B}/${GO_BUILD_BINDIR}/dnsname ${D}${localbindir} -} diff --git a/recipes-aos/aos-firewall/aos-firewall.bb b/recipes-aos/aos-firewall/aos-firewall.bb deleted file mode 100644 index 8dc38cfb..00000000 --- a/recipes-aos/aos-firewall/aos-firewall.bb +++ /dev/null @@ -1,38 +0,0 @@ -DESCRIPTION = "AOS fierwall CNI plugin" - -GO_IMPORT = "github.com/aosedge/aos_cni_firewall" - -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://src/${GO_IMPORT}/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" - -BRANCH = "main" -SRCREV = "e1f1c51bb069ed8f0150973669cd2d8d62d37516" - -SRC_URI = "git://${GO_IMPORT}.git;branch=${BRANCH};protocol=https" - -inherit go -inherit goarch - -# embed version -GO_LDFLAGS += '-ldflags="-X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=`git --git-dir=${S}/src/${GO_IMPORT}/.git describe --tags --always`"' - -FILES:${PN} = "${libexecdir}/cni" - -RDEPENDS:${PN} += "\ - iptables \ -" - -# WA to support go install for v 1.18 - -GO_LINKSHARED = "" - -do_compile:prepend() { - cd ${GOPATH}/src/${GO_IMPORT}/ -} - -do_install() { - localbindir="${libexecdir}/cni" - - install -d ${D}${localbindir} - install -m 755 ${B}/${GO_BUILD_BINDIR}/aos-firewall ${D}${localbindir} -} diff --git a/recipes-aos/aos-iamanager/aos-iamanager_git.bb b/recipes-aos/aos-iamanager/aos-iamanager_git.bb index eede89c8..e239ed30 100644 --- a/recipes-aos/aos-iamanager/aos-iamanager_git.bb +++ b/recipes-aos/aos-iamanager/aos-iamanager_git.bb @@ -4,29 +4,40 @@ FILESEXTRAPATHS:prepend:aos-secondary-node := "${THISDIR}/files/secondary:" DESCRIPTION = "AOS Identity and Access Manager CPP" LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" -BRANCH = "main" -SRCREV = "85006f422e084e517ae02cfd0395dbad03efcc8a" +BRANCH = "develop" +SRCREV = "${AUTOREV}" -SRC_URI = "gitsm://github.com/aosedge/aos_core_iam_cpp.git;protocol=https;branch=${BRANCH}" +SRC_URI = "git://github.com/aosedge/aos_core_cpp.git;protocol=https;branch=${BRANCH}" SRC_URI += " \ - file://aos_iamanager.cfg \ - file://aos-iamanager.service \ - file://aos-iamanager-provisioning.service \ + file://iam.cfg \ + file://aos-iam.service \ + file://aos-iam-prov.service \ file://aos-target.conf \ file://aos-dirs-service.conf \ " DEPENDS += "poco systemd grpc grpc-native protobuf-native protobuf openssl curl" +EXTRA_OECMAKE += " \ + -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \ + -DWITH_CM=OFF \ + -DWITH_IAM=ON \ + -DWITH_MP=OFF \ + -DWITH_SM=OFF \ +" OECMAKE_GENERATOR = "Unix Makefiles" -EXTRA_OECMAKE += "-DFETCHCONTENT_FULLY_DISCONNECTED=OFF" + +PACKAGECONFIG ??= "openssl" + +PACKAGECONFIG[openssl] = "-DWITH_OPENSSL=ON,-DWITH_OPENSSL=OFF,openssl," +PACKAGECONFIG[mbedtls] = "-DWITH_MBEDTLS=ON,-DWITH_MBEDTLS=OFF,," inherit autotools pkgconfig cmake systemd -SYSTEMD_SERVICE:${PN} = "aos-iamanager.service aos-iamanager-provisioning.service" +SYSTEMD_SERVICE:${PN} = "aos-iam.service aos-iam-prov.service" MIGRATION_SCRIPTS_PATH = "${base_prefix}/usr/share/aos/iam/migration" @@ -36,7 +47,6 @@ FILES:${PN} += " \ " RDEPENDS:${PN} += " \ - aos-rootca \ aos-provfinish \ " @@ -45,40 +55,54 @@ S = "${WORKDIR}/git" do_compile[network] = "1" do_configure[network] = "1" -do_fetch[vardeps] += "AOS_MAIN_NODE AOS_MAIN_NODE_HOSTNAME AOS_NODE_HOSTNAME AOS_NODE_TYPE AOS_RUNNER" +do_fetch[vardeps] += " \ + AOS_MAIN_NODE \ + AOS_MAIN_NODE_HOSTNAME \ + AOS_NODE_HOSTNAME \ + AOS_NODE_TYPE \ + AOS_ARCHITECTURE \ + AOS_ARCHITECTURE_VARIANT \ + AOS_OS \ + AOS_OS_VERSION \ +" python do_update_config() { import json - file_name = oe.path.join(d.getVar("D"), d.getVar("sysconfdir"), "aos", "aos_iamanager.cfg") + file_name = oe.path.join(d.getVar("D"), d.getVar("sysconfdir"), "aos", "iam.cfg") with open(file_name) as f: data = json.load(f) - node_info = data.get("NodeInfo", {}) - node_info["NodeType"] = d.getVar("AOS_NODE_TYPE") + node_info = data.get("nodeInfo", {}) + node_info["nodeType"] = d.getVar("AOS_NODE_TYPE") + + if d.getVar("AOS_ARCHITECTURE"): + node_info["architecture"] = d.getVar("AOS_ARCHITECTURE") + + if d.getVar("AOS_ARCHITECTURE_VARIANT"): + node_info["architectureVariant"] = d.getVar("AOS_ARCHITECTURE_VARIANT") - # Set Node Attributes - aos_runner = d.getVar("AOS_RUNNER") - node_attributes = node_info.get("Attrs", {}) - node_attributes["NodeRunners"] = aos_runner + if d.getVar("AOS_OS"): + node_info["os"] = d.getVar("AOS_OS") - node_info["Attrs"] = node_attributes + if d.getVar("AOS_OS_VERSION"): + node_info["osVersion"] = d.getVar("AOS_OS_VERSION") - data["NodeInfo"] = node_info + data["nodeInfo"] = node_info main_node_host_name = d.getVar("AOS_MAIN_NODE_HOSTNAME") # Set main IAM server URLs for secondary IAM nodes if not d.getVar("AOS_MAIN_NODE") or d.getVar("AOS_MAIN_NODE") == "0": - data["MainIAMPublicServerURL"] = main_node_host_name+":8090" - data["MainIAMProtectedServerURL"] = main_node_host_name+":8089" + data["mainIamPublicServerUrl"] = main_node_host_name + ":8090" + data["mainIamProtectedServerUrl"] = main_node_host_name + ":8089" # Set alternative names for server certificates - for cert_module in data["CertModules"]: - if "ExtendedKeyUsage" in cert_module and "serverAuth" in cert_module["ExtendedKeyUsage"]: - cert_module["AlternativeNames"] = [d.getVar("AOS_NODE_HOSTNAME")] + for cert_module in data["certModules"]: + if "extendedKeyUsage" in cert_module and "serverAuth" in cert_module["extendedKeyUsage"]: + cert_module["alternativeNames"] = [d.getVar("AOS_NODE_HOSTNAME")] with open(file_name, "w") as f: json.dump(data, f, indent=4) @@ -86,20 +110,20 @@ python do_update_config() { do_install:append() { install -d ${D}${sysconfdir}/aos - install -m 0644 ${WORKDIR}/aos_iamanager.cfg ${D}${sysconfdir}/aos + install -m 0644 ${WORKDIR}/iam.cfg ${D}${sysconfdir}/aos install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/aos-iamanager.service ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/aos-iamanager-provisioning.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/aos-iam.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/aos-iam-prov.service ${D}${systemd_system_unitdir} - install -d ${D}${sysconfdir}/systemd/system/aos-iamanager-provisioning.service.d - install -m 0644 ${WORKDIR}/aos-dirs-service.conf ${D}${sysconfdir}/systemd/system/aos-iamanager-provisioning.service.d/20-aos-dirs-service.conf + install -d ${D}${sysconfdir}/systemd/system/aos-iam-prov.service.d + install -m 0644 ${WORKDIR}/aos-dirs-service.conf ${D}${sysconfdir}/systemd/system/aos-iam-prov.service.d/20-aos-dirs-service.conf install -d ${D}${sysconfdir}/systemd/system/aos.target.d install -m 0644 ${WORKDIR}/aos-target.conf ${D}${sysconfdir}/systemd/system/aos.target.d/${PN}.conf install -d ${D}${MIGRATION_SCRIPTS_PATH} - source_migration_path="/src/database/migration" + source_migration_path="/src/iam/database/migration" if [ -d ${S}${source_migration_path} ]; then install -m 0644 ${S}${source_migration_path}/* ${D}${MIGRATION_SCRIPTS_PATH} fi diff --git a/recipes-aos/aos-iamanager/files/aos-iamanager-provisioning.service b/recipes-aos/aos-iamanager/files/aos-iam-prov.service similarity index 77% rename from recipes-aos/aos-iamanager/files/aos-iamanager-provisioning.service rename to recipes-aos/aos-iamanager/files/aos-iam-prov.service index d9d39fb7..79f5e20f 100644 --- a/recipes-aos/aos-iamanager/files/aos-iamanager-provisioning.service +++ b/recipes-aos/aos-iamanager/files/aos-iam-prov.service @@ -8,7 +8,7 @@ PartOf=aos.target [Service] Type=notify ExecStartPre=-/opt/aos/deprovision.sh -ExecStart=/usr/bin/aos_iamanager -c /etc/aos/aos_iamanager.cfg -provisioning -v debug -j +ExecStart=/usr/bin/aos_iam_app -c /etc/aos/iam.cfg -provisioning -v debug -j Restart=always RestartSec=10 diff --git a/recipes-aos/aos-iamanager/files/aos-iamanager.service b/recipes-aos/aos-iamanager/files/aos-iam.service similarity index 78% rename from recipes-aos/aos-iamanager/files/aos-iamanager.service rename to recipes-aos/aos-iamanager/files/aos-iam.service index 2d3ca183..e44e85f7 100644 --- a/recipes-aos/aos-iamanager/files/aos-iamanager.service +++ b/recipes-aos/aos-iamanager/files/aos-iam.service @@ -7,7 +7,7 @@ PartOf=aos.target [Service] Type=notify -ExecStart=/usr/bin/aos_iamanager -c /etc/aos/aos_iamanager.cfg -v debug -j +ExecStart=/usr/bin/aos_iam_app -c /etc/aos/iam.cfg -v debug -j Restart=always RestartSec=10 KillMode=process diff --git a/recipes-aos/aos-iamanager/files/aos-target.conf b/recipes-aos/aos-iamanager/files/aos-target.conf index a582cd4a..2ea51d57 100644 --- a/recipes-aos/aos-iamanager/files/aos-target.conf +++ b/recipes-aos/aos-iamanager/files/aos-target.conf @@ -1,5 +1,5 @@ [Unit] -Wants=aos-iamanager.service -After=aos-iamanager.service -Wants=aos-iamanager-provisioning.service -After=aos-iamanager-provisioning.service +Wants=aos-iam.service +After=aos-iam.service +Wants=aos-iam-prov.service +After=aos-iam-prov.service diff --git a/recipes-aos/aos-iamanager/files/aos_iamanager.cfg b/recipes-aos/aos-iamanager/files/aos_iamanager.cfg deleted file mode 100644 index bf96463e..00000000 --- a/recipes-aos/aos-iamanager/files/aos_iamanager.cfg +++ /dev/null @@ -1,103 +0,0 @@ -{ - "CACert": "/etc/ssl/certs/Aos_Root_CA.pem", - "CertStorage": "iam", - "IAMProtectedServerURL": ":8089", - "IAMPublicServerURL": ":8090", - "WorkingDir": "/var/aos/iam", - "FinishProvisioningCmdArgs": [ - "/opt/aos/provfinish.sh" - ], - "DeprovisionCmdArgs": [ - "/opt/aos/deprovision.sh", "async" - ], - "Identifier": { - "Plugin": "fileidentifier", - "Params": { - "SystemIdPath": "/etc/machine-id", - "BoardModelPath": "/sys/devices/virtual/dmi/id/product_name" - } - }, - "Migration": { - "MigrationPath": "/usr/share/aos/iam/migration", - "MergedMigrationPath": "/var/aos/iam/migration" - }, - "CertModules": [ - { - "ID": "online", - "Plugin": "swmodule", - "Algorithm": "ecc", - "MaxItems": 1, - "Params": { - "StoragePath": "/var/aos/crypt/online" - } - }, - { - "ID": "offline", - "Plugin": "swmodule", - "Algorithm": "rsa", - "MaxItems": 5, - "Params": { - "StoragePath": "/var/aos/crypt/offline" - } - }, - { - "ID": "iam", - "Plugin": "swmodule", - "Algorithm": "ecc", - "MaxItems": 1, - "ExtendedKeyUsage": [ - "serverAuth" - ], - "AlternativeNames": [ - "aosiam" - ], - "Params": { - "StoragePath": "/var/aos/crypt/iam" - } - }, - { - "ID": "sm", - "Plugin": "swmodule", - "Algorithm": "ecc", - "MaxItems": 1, - "ExtendedKeyUsage": [ - "serverAuth", - "clientAuth" - ], - "AlternativeNames": [ - "aossm" - ], - "Params": { - "StoragePath": "/var/aos/crypt/sm" - } - }, - { - "ID": "cm", - "Plugin": "swmodule", - "Algorithm": "ecc", - "MaxItems": 1, - "ExtendedKeyUsage": [ - "serverAuth", - "clientAuth" - ], - "AlternativeNames": [ - "aoscm" - ], - "Params": { - "StoragePath": "/var/aos/crypt/cm" - } - }, - { - "ID": "um", - "Plugin": "swmodule", - "Algorithm": "ecc", - "MaxItems": 1, - "ExtendedKeyUsage": [ - "clientAuth" - ], - "Params": { - "StoragePath": "/var/aos/crypt/um" - } - } - ] -} diff --git a/recipes-aos/aos-iamanager/files/iam.cfg b/recipes-aos/aos-iamanager/files/iam.cfg new file mode 100644 index 00000000..88181856 --- /dev/null +++ b/recipes-aos/aos-iamanager/files/iam.cfg @@ -0,0 +1,160 @@ +{ + "caCert": "/usr/share/ca-certificates/aos/AosRootCA.crt", + "certStorage": "iam", + "iamProtectedServerUrl": ":8089", + "iamPublicServerUrl": ":8090", + "workingDir": "/var/aos/iam", + "nodeInfo": { + "nodeIdPath": "/etc/machine-id", + "nodeName": "main", + "maxDmips": 10000, + "attrs": { + "MainNode": "", + "AosComponents": "cm,iam,sm" + }, + "partitions": [ + { + "name": "storages", + "types": [ + "storages" + ], + "path": "/var/aos/storages" + }, + { + "name": "states", + "types": [ + "states" + ], + "path": "/var/aos/states" + }, + { + "name": "workdirs", + "types": [ + "services", + "layers", + "generic" + ], + "path": "/var/aos/workdirs" + }, + { + "name": "var", + "types": [ + "generic" + ], + "path": "/var" + } + ] + }, + "diskEncryptionCmdArgs": [ + "/bin/sh", + "-c", + "/opt/aos/setupdisk.sh create $(cat /proc/cmdline | sed -e 's/^.*opendisk.target=//' -e 's/ .*$//') -m /usr/lib/softhsm/libsofthsm2.so -p $(cat /var/aos/iam/.usrpin) 2>&1 | systemd-cat; systemctl restart nfs-server.service || true" + ], + "finishProvisioningCmdArgs": [ + "/opt/aos/provfinish.sh" + ], + "deprovisionCmdArgs": [ + "/opt/aos/deprovision.sh", + "async" + ], + "identifier": { + "plugin": "fileidentifier", + "params": { + "systemIdPath": "/etc/machine-id", + "unitModelPath": "/etc/aos/unit_model", + "subjectsPath": "/etc/aos/subjects" + } + }, + "certModules": [ + { + "id": "online", + "plugin": "pkcs11module", + "algorithm": "ecc", + "maxItems": 2, + "params": { + "library": "/usr/lib/softhsm/libsofthsm2.so", + "tokenLabel": "aoscloud", + "userPinPath": "/var/aos/iam/.usrpin", + "modulePathInUrl": true + } + }, + { + "id": "offline", + "plugin": "pkcs11module", + "algorithm": "rsa", + "maxItems": 5, + "params": { + "library": "/usr/lib/softhsm/libsofthsm2.so", + "tokenLabel": "aoscloud", + "userPinPath": "/var/aos/iam/.usrpin", + "modulePathInUrl": true + } + }, + { + "id": "iam", + "plugin": "pkcs11module", + "algorithm": "ecc", + "maxItems": 2, + "extendedKeyUsage": [ + "serverAuth", + "clientAuth" + ], + "params": { + "library": "/usr/lib/softhsm/libsofthsm2.so", + "tokenLabel": "aoscore", + "userPinPath": "/var/aos/iam/.usrpin", + "modulePathInUrl": true + } + }, + { + "id": "sm", + "plugin": "pkcs11module", + "algorithm": "ecc", + "maxItems": 2, + "extendedKeyUsage": [ + "serverAuth", + "clientAuth" + ], + "params": { + "library": "/usr/lib/softhsm/libsofthsm2.so", + "tokenLabel": "aoscore", + "userPinPath": "/var/aos/iam/.usrpin", + "modulePathInUrl": true + } + }, + { + "id": "cm", + "plugin": "pkcs11module", + "algorithm": "ecc", + "maxItems": 2, + "extendedKeyUsage": [ + "serverAuth", + "clientAuth" + ], + "params": { + "library": "/usr/lib/softhsm/libsofthsm2.so", + "tokenLabel": "aoscore", + "userPinPath": "/var/aos/iam/.usrpin", + "modulePathInUrl": true + } + }, + { + "id": "diskencryption", + "plugin": "pkcs11module", + "algorithm": "rsa", + "maxItems": 1, + "disabled": false, + "selfSigned": true, + "params": { + "library": "/usr/lib/softhsm/libsofthsm2.so", + "tokenLabel": "aoscore", + "userPinPath": "/var/aos/iam/.usrpin", + "modulePathInUrl": true + } + } + ], + "migration": { + "migrationPath": "/usr/share/aos/iam/migration", + "mergedMigrationPath": "/var/aos/iam/migration" + } +} diff --git a/recipes-aos/aos-messageproxy/aos-messageproxy_git.bb b/recipes-aos/aos-messageproxy/aos-messageproxy_git.bb index ea6ac974..03779984 100644 --- a/recipes-aos/aos-messageproxy/aos-messageproxy_git.bb +++ b/recipes-aos/aos-messageproxy/aos-messageproxy_git.bb @@ -2,15 +2,15 @@ DESCRIPTION = "AOS Message Proxy" LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" -BRANCH = "main" -SRCREV = "9a3190834a2543e38b600c57bac31e7bf7503ff8" +BRANCH = "develop" +SRCREV = "${AUTOREV}" -SRC_URI = "gitsm://github.com/aosedge/aos_core_mp_cpp.git;protocol=https;branch=${BRANCH}" +SRC_URI = "git://github.com/aosedge/aos_core_cpp.git;protocol=https;branch=${BRANCH}" SRC_URI += " \ - file://aos_messageproxy.cfg \ - file://aos-messageproxy.service \ - file://aos-messageproxy-provisioning.service \ + file://mp.cfg \ + file://aos-mp.service \ + file://aos-mp-provisioning.service \ file://aos-target.conf \ file://aos-cm-service.conf \ " @@ -19,15 +19,24 @@ S = "${WORKDIR}/git" inherit autotools pkgconfig cmake systemd -DEPENDS += "poco systemd grpc grpc-native protobuf-native protobuf curl" +DEPENDS += "poco systemd grpc grpc-native protobuf-native protobuf curl libnl nftables" -PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'xen', 'vchan', '', d)}" +PACKAGECONFIG ??= "openssl ${@bb.utils.contains('DISTRO_FEATURES', 'xen', 'vchan', '', d)}" PACKAGECONFIG[vchan] = "-DWITH_VCHAN=ON,-DWITH_VCHAN=OFF,xen-tools,xen-tools-libxenvchan" +PACKAGECONFIG[openssl] = "-DWITH_OPENSSL=ON,-DWITH_OPENSSL=OFF,openssl," +PACKAGECONFIG[mbedtls] = "-DWITH_MBEDTLS=ON,-DWITH_MBEDTLS=OFF,," OECMAKE_GENERATOR = "Unix Makefiles" -EXTRA_OECMAKE += "-DFETCHCONTENT_FULLY_DISCONNECTED=OFF" -SYSTEMD_SERVICE:${PN} = "aos-messageproxy.service aos-messageproxy-provisioning.service" +EXTRA_OECMAKE += " \ + -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \ + -DWITH_CM=OFF \ + -DWITH_IAM=OFF \ + -DWITH_MP=ON \ + -DWITH_SM=OFF \ +" + +SYSTEMD_SERVICE:${PN} = "aos-mp.service aos-mp-provisioning.service" FILES:${PN} += " \ ${sysconfdir} \ @@ -36,19 +45,52 @@ FILES:${PN} += " \ do_compile[network] = "1" do_configure[network] = "1" +do_fetch[vardeps] += "AOS_MAIN_NODE_HOSTNAME AOS_NODE_HOSTNAME" + +python do_update_config() { + import json + + file_name = oe.path.join(d.getVar("D"), d.getVar("sysconfdir"), "aos", "mp.cfg") + + with open(file_name) as f: + data = json.load(f) + + iamConfig = data.get("iamConfig", {}) + iamConfig["iamPublicServerUrl"] = d.getVar("AOS_NODE_HOSTNAME") + ":8090" + iamConfig["iamMainPublicServerUrl"] = d.getVar("AOS_MAIN_NODE_HOSTNAME") + ":8090" + iamConfig["iamMainProtectedServerUrl"] = d.getVar("AOS_MAIN_NODE_HOSTNAME") + ":8089" + + cmConfig = data.get("cmConfig", {}) + cmConfig["cmServerUrl"] = d.getVar("AOS_MAIN_NODE_HOSTNAME") + ":8093" + + data["iamConfig"] = iamConfig + data["cmConfig"] = cmConfig + + with open(file_name, "w") as f: + json.dump(data, f, indent=4) +} + do_install:append() { install -d ${D}${sysconfdir}/aos - install -m 0644 ${WORKDIR}/aos_messageproxy.cfg ${D}${sysconfdir}/aos + install -m 0644 ${WORKDIR}/mp.cfg ${D}${sysconfdir}/aos install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/aos-messageproxy.service ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/aos-messageproxy-provisioning.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/aos-mp.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/aos-mp-provisioning.service ${D}${systemd_system_unitdir} install -d ${D}${sysconfdir}/systemd/system/aos.target.d install -m 0644 ${WORKDIR}/aos-target.conf ${D}${sysconfdir}/systemd/system/aos.target.d/${PN}.conf } do_install:append:aos-main-node() { - install -d ${D}${sysconfdir}/systemd/system/aos-messageproxy.service.d - install -m 0644 ${WORKDIR}/aos-cm-service.conf ${D}${sysconfdir}/systemd/system/aos-messageproxy.service.d/10-aos-cm-service.conf + install -d ${D}${sysconfdir}/systemd/system/aos-mp.service.d + install -m 0644 ${WORKDIR}/aos-cm-service.conf ${D}${sysconfdir}/systemd/system/aos-mp.service.d/10-aos-cm-service.conf +} + +do_install:append() { + # Do not install headers files to prevent SDK build conflicts + rm -rf ${D}${includedir} } + + +addtask update_config after do_install before do_package diff --git a/recipes-aos/aos-messageproxy/files/aos-cm-service.conf b/recipes-aos/aos-messageproxy/files/aos-cm-service.conf index d9fc3ec2..6c070080 100644 --- a/recipes-aos/aos-messageproxy/files/aos-cm-service.conf +++ b/recipes-aos/aos-messageproxy/files/aos-cm-service.conf @@ -1,3 +1,3 @@ [Unit] -Wants=aos-communicationmanager.service -After=aos-communicationmanager.service +Wants=aos-mp.service +After=aos-mp.service diff --git a/recipes-aos/aos-messageproxy/files/aos-messageproxy-provisioning.service b/recipes-aos/aos-messageproxy/files/aos-messageproxy-provisioning.service deleted file mode 100644 index 945ce204..00000000 --- a/recipes-aos/aos-messageproxy/files/aos-messageproxy-provisioning.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=AOS Message Proxy -Wants=network-online.target aos-iamanager.service -After=network-online.target aos-iamanager.service -ConditionPathExists=!/var/aos/.provisionstate -PartOf=aos.target - -[Service] -Type=notify -ExecStart=/usr/bin/aos_messageproxy -c /etc/aos/aos_messageproxy.cfg -provisioning -v debug -j -Restart=always -RestartSec=10 - -[Install] -WantedBy=multi-user.target diff --git a/recipes-aos/aos-messageproxy/files/aos-mp-provisioning.service b/recipes-aos/aos-messageproxy/files/aos-mp-provisioning.service new file mode 100644 index 00000000..097af320 --- /dev/null +++ b/recipes-aos/aos-messageproxy/files/aos-mp-provisioning.service @@ -0,0 +1,15 @@ +[Unit] +Description=AOS Message Proxy +Wants=network-online.target aos-iam.service +After=network-online.target aos-iam.service +ConditionPathExists=!/var/aos/.provisionstate +PartOf=aos.target + +[Service] +Type=notify +ExecStart=/usr/bin/aos_mp_app -c /etc/aos/mp.cfg -provisioning -v debug -j +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target diff --git a/recipes-aos/aos-messageproxy/files/aos-messageproxy.service b/recipes-aos/aos-messageproxy/files/aos-mp.service similarity index 51% rename from recipes-aos/aos-messageproxy/files/aos-messageproxy.service rename to recipes-aos/aos-messageproxy/files/aos-mp.service index b54baa4f..8d1900af 100644 --- a/recipes-aos/aos-messageproxy/files/aos-messageproxy.service +++ b/recipes-aos/aos-messageproxy/files/aos-mp.service @@ -1,13 +1,13 @@ [Unit] Description=AOS Message Proxy -Wants=network-online.target aos-iamanager.service -After=network-online.target aos-iamanager.service +Wants=network-online.target aos-iam.service +After=network-online.target aos-iam.service ConditionPathExists=/var/aos/.provisionstate PartOf=aos.target [Service] Type=notify -ExecStart=/usr/bin/aos_messageproxy -c /etc/aos/aos_messageproxy.cfg -v debug -j +ExecStart=/usr/bin/aos_mp_app -c /etc/aos/mp.cfg -v debug -j Restart=always RestartSec=10 diff --git a/recipes-aos/aos-messageproxy/files/aos-target.conf b/recipes-aos/aos-messageproxy/files/aos-target.conf index 729dd8dd..6c070080 100644 --- a/recipes-aos/aos-messageproxy/files/aos-target.conf +++ b/recipes-aos/aos-messageproxy/files/aos-target.conf @@ -1,3 +1,3 @@ [Unit] -Wants=aos-messageproxy.service -After=aos-messageproxy.service +Wants=aos-mp.service +After=aos-mp.service diff --git a/recipes-aos/aos-messageproxy/files/aos_messageproxy.cfg b/recipes-aos/aos-messageproxy/files/aos_messageproxy.cfg deleted file mode 100644 index a205e209..00000000 --- a/recipes-aos/aos-messageproxy/files/aos_messageproxy.cfg +++ /dev/null @@ -1,28 +0,0 @@ -{ - "CACert": "/etc/ssl/certs/Aos_Root_CA.pem", - "CertStorage": "sm", - "WorkingDir": "/var/aos/workdirs/mp", - "ImageStoreDir": "/var/aos/workdirs/mp/images", - "IAMConfig": { - "IAMPublicServerURL": "main:8090", - "IAMProtectedServerURL": "main:8089", - "CertStorage": "iam", - "OpenPort": 1, - "SecurePort": 2 - }, - "CMConfig": { - "CMServerURL": "main:8093", - "OpenPort": 3, - "SecurePort": 4 - }, - "VChan": { - "XSRXPath": "tmp/vchan/aos/rx", - "XSTXPath": "tmp/vchan/aos/tx", - "IAMCertStorage": "iam", - "SMCertStorage": "sm", - "Domain": 0 - }, - "Downloader": { - "DownloadDir": "/var/aos/workdirs/mp/downloads" - } -} diff --git a/recipes-aos/aos-messageproxy/files/mp.cfg b/recipes-aos/aos-messageproxy/files/mp.cfg new file mode 100644 index 00000000..3ee5c482 --- /dev/null +++ b/recipes-aos/aos-messageproxy/files/mp.cfg @@ -0,0 +1,29 @@ +{ + "caCert": "/usr/share/ca-certificates/aos/AosRootCA.crt", + "certStorage": "sm", + "workingDir": "/var/aos/workdirs/mp", + "imageStoreDir": "/var/aos/workdirs/mp/images", + "iamConfig": { + "iamPublicServerUrl": ":8090", + "iamMainPublicServerUrl": "main:8090", + "iamMainProtectedServerUrl": "main:8089", + "certStorage": "iam", + "openPort": 1, + "securePort": 2 + }, + "cmConfig": { + "cmServerUrl": "main:8093", + "openPort": 3, + "securePort": 4 + }, + "vchan": { + "xsRxPath": "tmp/vchan/aos/rx", + "xsTxPath": "tmp/vchan/aos/tx", + "iamCertStorage": "iam", + "smCertStorage": "sm", + "domain": 0 + }, + "downloader": { + "downloadDir": "/var/aos/workdirs/mp/downloads" + } +} diff --git a/recipes-aos/aos-nftables/aos-nftables.bb b/recipes-aos/aos-nftables/aos-nftables.bb new file mode 100644 index 00000000..ae4ff668 --- /dev/null +++ b/recipes-aos/aos-nftables/aos-nftables.bb @@ -0,0 +1,37 @@ +DESCRIPTION = "Aos base nftables ruleset (fail-closed forward default-drop)" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +SRC_URI = " \ + file://aos.nft \ + file://aos-nftables.service \ +" + +S = "${WORKDIR}" + +inherit systemd + +SYSTEMD_SERVICE:${PN} = "aos-nftables.service" + +FILES:${PN} = " \ + ${sysconfdir} \ + ${systemd_system_unitdir} \ +" + +RDEPENDS:${PN} += " \ + nftables \ +" + +RRECOMMENDS:${PN} += " \ + kernel-module-nf-conntrack \ + kernel-module-nft-ct \ +" + +do_install() { + install -d ${D}${sysconfdir}/nftables + install -m 0644 ${WORKDIR}/aos.nft ${D}${sysconfdir}/nftables/aos.nft + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/aos-nftables.service ${D}${systemd_system_unitdir} +} diff --git a/recipes-aos/aos-nftables/files/aos-nftables.service b/recipes-aos/aos-nftables/files/aos-nftables.service new file mode 100644 index 00000000..a4339ccf --- /dev/null +++ b/recipes-aos/aos-nftables/files/aos-nftables.service @@ -0,0 +1,16 @@ +[Unit] +Description=Aos base nftables ruleset (fail-closed forward default-drop) +Wants=network-pre.target +Before=network-pre.target aos-sm.service +After=sysinit.target +DefaultDependencies=no +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/nft -f /etc/nftables/aos.nft + +[Install] +WantedBy=multi-user.target diff --git a/recipes-aos/aos-nftables/files/aos.nft b/recipes-aos/aos-nftables/files/aos.nft new file mode 100644 index 00000000..af1f9042 --- /dev/null +++ b/recipes-aos/aos-nftables/files/aos.nft @@ -0,0 +1,25 @@ +#!/usr/sbin/nft -f + +# Aos base firewall ruleset - fail-closed forward default-drop (NET-15). +# +# OS-provisioned safety net: the global forward default-drop must survive even +# when the service manager is down. The service manager augments THIS SAME +# table at runtime (per-instance chains, forward jumps, postrouting +# masquerade), so this ruleset is strictly additive: +# * it never runs "flush ruleset" and never deletes "table inet aos", so the +# service manager's live rules are never wiped; +# * "add table"/"add chain" are idempotent, so re-applying re-asserts the +# base chains without removing the service manager's injected rules. +# +# The schema is a shared contract with aos_core_cpp - the table/chain names and +# priorities must match src/sm/networkmanager/firewall.hpp (table inet aos, +# chain forward filter/hook forward/priority 0, chain postrouting nat/hook +# postrouting/priority 100), or the service manager cannot inject into it. + +add table inet aos + +add chain inet aos forward { type filter hook forward priority 0; policy drop; } +add chain inet aos postrouting { type nat hook postrouting priority 100; } + +add rule inet aos forward ct state invalid drop +add rule inet aos forward ct state established,related accept diff --git a/recipes-aos/aos-provfinish/aos-provfinish.bb b/recipes-aos/aos-provfinish/aos-provfinish.bb index be21dbd1..ad552c6d 100644 --- a/recipes-aos/aos-provfinish/aos-provfinish.bb +++ b/recipes-aos/aos-provfinish/aos-provfinish.bb @@ -1,3 +1,6 @@ +FILESEXTRAPATHS:prepend:aos-main-node := "${THISDIR}/files/main:" +FILESEXTRAPATHS:prepend:aos-secondary-node := "${THISDIR}/files/secondary:" + DESCRIPTION = "Aos provisioning finish script" LICENSE = "Apache-2.0" diff --git a/recipes-aos/aos-provfinish/files/main/provfinish.sh b/recipes-aos/aos-provfinish/files/main/provfinish.sh new file mode 100644 index 00000000..3c18a437 --- /dev/null +++ b/recipes-aos/aos-provfinish/files/main/provfinish.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +sync + +# restart aos target +{ + sleep 1 + systemctl restart rpc-rquotad.service + systemctl restart aos.target +} > /dev/null 2>&1 & diff --git a/recipes-aos/aos-provfinish/files/provfinish.sh b/recipes-aos/aos-provfinish/files/secondary/provfinish.sh similarity index 100% rename from recipes-aos/aos-provfinish/files/provfinish.sh rename to recipes-aos/aos-provfinish/files/secondary/provfinish.sh diff --git a/recipes-aos/aos-provfirewall/aos-provfirewall.bb b/recipes-aos/aos-provfirewall/aos-provfirewall.bb index 8e6c3fa4..3a788c13 100644 --- a/recipes-aos/aos-provfirewall/aos-provfirewall.bb +++ b/recipes-aos/aos-provfirewall/aos-provfirewall.bb @@ -22,11 +22,12 @@ FILES:${PN} = " \ " RDEPENDS:${PN} += " \ - iptables \ + nftables \ " RRECOMMENDS:${PN} += " \ - kernel-module-xt-tcpudp \ + kernel-module-nf-conntrack \ + kernel-module-nft-ct \ " do_install() { diff --git a/recipes-aos/aos-provfirewall/files/provfirewall.sh b/recipes-aos/aos-provfirewall/files/provfirewall.sh index a41791d2..0a2e930f 100755 --- a/recipes-aos/aos-provfirewall/files/provfirewall.sh +++ b/recipes-aos/aos-provfirewall/files/provfirewall.sh @@ -7,23 +7,16 @@ if [ -z "$GATEWAY" ]; then exit 1 fi -apply_rules() { - INTERFACE=$1 - SUBNET=$(ip -o -f inet addr show $INTERFACE | awk '{print $4}' | cut -d'/' -f1-2) - - if [ -z "$SUBNET" ]; then - echo "No IP address found for $INTERFACE" - return - fi +# Recreate the table from scratch so re-runs stay idempotent. +nft delete table inet aos-provfw 2>/dev/null - for PROTO in tcp udp; do - iptables -A INPUT -s $GATEWAY/32 -d $SUBNET -i $INTERFACE -p $PROTO -m $PROTO --dport 8089 -j DROP - iptables -A INPUT ! -s $SUBNET -d $SUBNET -i $INTERFACE -p $PROTO -m $PROTO --dport 8089 -j DROP - iptables -A INPUT -s $SUBNET -d $SUBNET -i $INTERFACE -p $PROTO -m $PROTO --dport 8089 -j ACCEPT - done +nft -f - < ${file} - echo 'import (' >> ${file} - - for module in ${AOS_UM_UPDATE_MODULES}; do - echo "\t_ \"${GO_IMPORT}/${module}\"" >> ${file} - done - - echo ')' >> ${file} -} - -python do_update_config() { - import json - - file_name = oe.path.join(d.getVar("D"), d.getVar("sysconfdir"), "aos", "aos_updatemanager.cfg") - - with open(file_name) as f: - data = json.load(f) - - node_hostname = d.getVar("AOS_NODE_HOSTNAME") - main_node_hostname = d.getVar("AOS_MAIN_NODE_HOSTNAME") - - # Update IAM servers - - data["IAMPublicServerURL"] = node_hostname+":8090" - - # Update CM server - - data["CMServerURL"] = main_node_hostname+":8091" - - # Update component Types - - comp_prefix = d.getVar("AOS_UM_COMPONENT_PREFIX") - - for update_module in data["UpdateModules"]: - if not update_module["Type"].startswith(comp_prefix): - update_module["Type"] = comp_prefix+update_module["Type"] - - with open(file_name, "w") as f: - json.dump(data, f, indent=4) -} - -do_fetch[vardeps] += "AOS_UM_COMPONENT_PREFIX" - -do_install:append() { - install -d ${D}${sysconfdir}/aos - install -m 0644 ${WORKDIR}/aos_updatemanager.cfg ${D}${sysconfdir}/aos - - install -d ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/aos-updatemanager.service ${D}${systemd_system_unitdir} - - install -d ${D}${sysconfdir}/systemd/system/aos.target.d - install -m 0644 ${WORKDIR}/aos-target.conf ${D}${sysconfdir}/systemd/system/aos.target.d/${PN}.conf - - install -d ${D}${sysconfdir}/systemd/system/aos-updatemanager.service.d - install -m 0644 ${WORKDIR}/aos-dirs-service.conf ${D}${sysconfdir}/systemd/system/aos-updatemanager.service.d/20-aos-dirs-service.conf - - install -d ${D}${MIGRATION_SCRIPTS_PATH} - source_migration_path="src/${GO_IMPORT}/database/migration" - if [ -d ${S}/${source_migration_path} ]; then - install -m 0644 ${S}/${source_migration_path}/* ${D}${MIGRATION_SCRIPTS_PATH} - fi -} - -do_install:append:aos-main-node() { - install -d ${D}${sysconfdir}/systemd/system/aos-updatemanager.service.d - install -m 0644 ${WORKDIR}/aos-cm-service.conf ${D}${sysconfdir}/systemd/system/aos-updatemanager.service.d/10-aos-cm-service.conf -} - -addtask update_config after do_install before do_package -addtask prepare_modules after do_unpack before do_compile diff --git a/recipes-aos/aos-updatemanager/files/aos-cm-service.conf b/recipes-aos/aos-updatemanager/files/aos-cm-service.conf deleted file mode 100644 index d9fc3ec2..00000000 --- a/recipes-aos/aos-updatemanager/files/aos-cm-service.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Unit] -Wants=aos-communicationmanager.service -After=aos-communicationmanager.service diff --git a/recipes-aos/aos-updatemanager/files/aos-dirs-service.conf b/recipes-aos/aos-updatemanager/files/aos-dirs-service.conf deleted file mode 100644 index c1b4f2aa..00000000 --- a/recipes-aos/aos-updatemanager/files/aos-dirs-service.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Unit] -Requires=var-aos-workdirs.mount -After=var-aos-workdirs.mount diff --git a/recipes-aos/aos-updatemanager/files/aos-target.conf b/recipes-aos/aos-updatemanager/files/aos-target.conf deleted file mode 100644 index 9e8f8b93..00000000 --- a/recipes-aos/aos-updatemanager/files/aos-target.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Unit] -Wants=aos-updatemanager.service -After=aos-updatemanager.service diff --git a/recipes-aos/aos-updatemanager/files/aos-updatemanager.service b/recipes-aos/aos-updatemanager/files/aos-updatemanager.service deleted file mode 100644 index eeec1540..00000000 --- a/recipes-aos/aos-updatemanager/files/aos-updatemanager.service +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=AOS Update Manager -Wants=network-online.target aos-iamanager.service -After=network-online.target aos-iamanager.service -StartLimitInterval=300 -StartLimitBurst=3 -ConditionPathExists=/var/aos/.provisionstate -PartOf=aos.target - -[Service] -Type=notify -ExecStart=/usr/bin/aos_updatemanager -c /etc/aos/aos_updatemanager.cfg -v debug -j -# It is important to do not restart UM on normal exit. This case is used when system -# reboot scheduled: UM returns exit code 0. -Restart=on-failure -RestartSec=30 -TimeoutStartSec=60 - -[Install] -WantedBy=multi-user.target diff --git a/recipes-aos/aos-updatemanager/files/aos_updatemanager.cfg b/recipes-aos/aos-updatemanager/files/aos_updatemanager.cfg deleted file mode 100644 index 5ba4b2d0..00000000 --- a/recipes-aos/aos-updatemanager/files/aos_updatemanager.cfg +++ /dev/null @@ -1,20 +0,0 @@ -{ - "CACert": "/etc/ssl/certs/Aos_Root_CA.pem", - "CertStorage": "um", - "IAMPublicServerURL": "aosiam:8090", - "CMServerURL": "aoscm:8091", - "WorkingDir": "/var/aos/workdirs/um", - "UpdateModules": [ - { - "ID": "test-component", - "Disabled": false, - "UpdatePriority": 0, - "RebootPriority": 0, - "Plugin": "testmodule" - } - ], - "Migration": { - "MigrationPath": "/usr/share/aos/um/migration", - "MergedMigrationPath": "/var/aos/workdirs/um/migration" - } -} \ No newline at end of file diff --git a/recipes-aos/aos-vis/aos-vis_git.bb b/recipes-aos/aos-vis/aos-vis_git.bb index 6b92f5fc..e8c17639 100644 --- a/recipes-aos/aos-vis/aos-vis_git.bb +++ b/recipes-aos/aos-vis/aos-vis_git.bb @@ -44,7 +44,6 @@ FILES:${PN} += " \ " RDEPENDS:${PN} += " \ - aos-rootca \ ${@bb.utils.contains('AOS_VIS_DATA_PROVIDER', 'telemetryemulatoradapter', 'telemetry-emulator', '', d)} \ " diff --git a/recipes-aos/aos-vis/files/aos_vis.cfg b/recipes-aos/aos-vis/files/aos_vis.cfg index f9e46830..605ff5eb 100644 --- a/recipes-aos/aos-vis/files/aos_vis.cfg +++ b/recipes-aos/aos-vis/files/aos_vis.cfg @@ -1,5 +1,5 @@ { - "CACert": "/etc/ssl/certs/Aos_Root_CA.pem", + "CACert": "/usr/share/ca-certificates/aos/AosRootCA.crt", "VISServerURL": ":443", "VISCert": "/usr/share/aos/vis/certs/wwwivi.crt.pem", "VISKey": "/usr/share/aos/vis/certs/wwwivi.key.pem", diff --git a/recipes-connectivity/iproute2/iproute2_%.bbappend b/recipes-connectivity/iproute2/iproute2_%.bbappend new file mode 100644 index 00000000..8c5d0209 --- /dev/null +++ b/recipes-connectivity/iproute2/iproute2_%.bbappend @@ -0,0 +1,13 @@ +# Aos uses nftables exclusively. iproute2 links libxtables only to provide +# tc's "action xt/ipt" modules (which Aos does not use); that linkage is what +# drags the whole iptables package into the image. Drop the iptables build +# dependency so tc is built without libxtables and no longer pulls iptables. +DEPENDS:remove = "iptables" + +# Those xt/ipt action modules were the only shared objects under ${libdir}/tc +# (the rest are linked into the tc binary), so without them the directory is +# installed empty. Drop it so packaging does not flag it as +# installed-but-not-shipped. +do_install:append() { + rmdir "${D}${libdir}/tc" 2>/dev/null || true +} diff --git a/recipes-connectivity/kuksa-client/kuksa-client/0001-kuksa-client-Update-cmd2-completer-usage.patch b/recipes-connectivity/kuksa-client/kuksa-client/0001-kuksa-client-Update-cmd2-completer-usage.patch new file mode 100644 index 00000000..752ff72b --- /dev/null +++ b/recipes-connectivity/kuksa-client/kuksa-client/0001-kuksa-client-Update-cmd2-completer-usage.patch @@ -0,0 +1,160 @@ +From acb2bbff3de6e9f0bafb8b96a339820a9ddfadca Mon Sep 17 00:00:00 2001 +From: Scott Murray +Date: Mon, 27 Nov 2023 15:31:02 -0500 +Subject: [PATCH 1/2] kuksa-client: Update cmd2 completer usage + +Update cmd2 usage to avoid using internal methods and fix breakage +with newer versions of the cmd2 module. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray +--- + kuksa-client/kuksa_client/__main__.py | 33 +++++++++++++-------------- + 1 file changed, 16 insertions(+), 17 deletions(-) + +diff --git a/kuksa-client/kuksa_client/__main__.py b/kuksa-client/kuksa_client/__main__.py +index 2b29623..7061ec1 100755 +--- a/kuksa-client/kuksa_client/__main__.py ++++ b/kuksa-client/kuksa_client/__main__.py +@@ -36,7 +36,6 @@ from cmd2 import CompletionItem + from cmd2 import with_argparser + from cmd2 import with_category + from cmd2 import constants +-from cmd2.utils import basic_complete + from urllib.parse import urlparse + + from kuksa_client import KuksaClientThread +@@ -151,7 +150,7 @@ class TestClient(Cmd): + self.pathCompletionItems = [] + for sub_id in self.subscribeIds: + self.pathCompletionItems.append(CompletionItem(sub_id)) +- return basic_complete(text, line, begidx, endidx, self.pathCompletionItems) ++ return Cmd.basic_complete(self, text, line, begidx, endidx, self.pathCompletionItems) + + COMM_SETUP_COMMANDS = "Communication Set-up Commands" + VSS_COMMANDS = "Kuksa Interaction Commands (Supported by both KUKSA Databroker and KUKSA Server)" +@@ -167,19 +166,19 @@ class TestClient(Cmd): + + ap_disconnect = argparse.ArgumentParser() + ap_authorize = argparse.ArgumentParser() +- tokenfile_completer_method = functools.partial( ++ tokenfile_completer = functools.partial( + Cmd.path_complete, + path_filter=lambda path: (os.path.isdir(path) or path.endswith(".token")), + ) + ap_authorize.add_argument( + "token_or_tokenfile", + help="JWT(or the file storing the token) for authorizing the client.", +- completer_method=tokenfile_completer_method, ++ completer=tokenfile_completer, + ) + + ap_setValue = argparse.ArgumentParser() + ap_setValue.add_argument( +- "Path", help="Path to be set", completer_method=path_completer ++ "Path", help="Path to be set", completer=path_completer + ) + ap_setValue.add_argument("Value", nargs="+", help="Value to be set") + ap_setValue.add_argument( +@@ -199,7 +198,7 @@ class TestClient(Cmd): + + ap_getValue = argparse.ArgumentParser() + ap_getValue.add_argument( +- "Path", help="Path to be read", completer_method=path_completer ++ "Path", help="Path to be read", completer=path_completer + ) + ap_getValue.add_argument( + "-a", "--attribute", help="Attribute to be get", default="value" +@@ -210,7 +209,7 @@ class TestClient(Cmd): + "Path", + help="Path whose value is to be read", + nargs="+", +- completer_method=path_completer, ++ completer=path_completer, + ) + ap_getValues.add_argument( + "-a", "--attribute", help="Attribute to be get", default="value" +@@ -220,7 +219,7 @@ class TestClient(Cmd): + ap_setTargetValue.add_argument( + "Path", + help="Path whose target value to be set", +- completer_method=path_completer, ++ completer=path_completer, + ) + ap_setTargetValue.add_argument("Value", help="Value to be set") + +@@ -236,7 +235,7 @@ class TestClient(Cmd): + ap_getTargetValue.add_argument( + "Path", + help="Path whose target value is to be read", +- completer_method=path_completer, ++ completer=path_completer, + ) + + ap_getTargetValues = argparse.ArgumentParser() +@@ -244,12 +243,12 @@ class TestClient(Cmd): + "Path", + help="Path whose target value is to be read", + nargs="+", +- completer_method=path_completer, ++ completer=path_completer, + ) + + ap_subscribe = argparse.ArgumentParser() + ap_subscribe.add_argument( +- "Path", help="Path to subscribe to", completer_method=path_completer ++ "Path", help="Path to subscribe to", completer=path_completer + ) + ap_subscribe.add_argument( + "-a", "--attribute", help="Attribute to subscribe to", default="value" +@@ -264,7 +263,7 @@ class TestClient(Cmd): + + ap_subscribeMultiple = argparse.ArgumentParser() + ap_subscribeMultiple.add_argument( +- "Path", help="Path to subscribe to", nargs="+", completer_method=path_completer ++ "Path", help="Path to subscribe to", nargs="+", completer=path_completer + ) + ap_subscribeMultiple.add_argument( + "-a", "--attribute", help="Attribute to subscribe to", default="value" +@@ -280,18 +279,18 @@ class TestClient(Cmd): + ap_unsubscribe.add_argument( + "SubscribeId", + help="Corresponding subscription Id", +- completer_method=subscriptionIdCompleter, ++ completer=subscriptionIdCompleter, + ) + + ap_getMetaData = argparse.ArgumentParser() + ap_getMetaData.add_argument( + "Path", + help="Path whose metadata is to be read", +- completer_method=path_completer, ++ completer=path_completer, + ) + ap_updateMetaData = argparse.ArgumentParser() + ap_updateMetaData.add_argument( +- "Path", help="Path whose MetaData is to update", completer_method=path_completer ++ "Path", help="Path whose MetaData is to update", completer=path_completer + ) + ap_updateMetaData.add_argument( + "Json", +@@ -300,14 +299,14 @@ class TestClient(Cmd): + ) + + ap_updateVSSTree = argparse.ArgumentParser() +- jsonfile_completer_method = functools.partial( ++ jsonfile_completer = functools.partial( + Cmd.path_complete, + path_filter=lambda path: (os.path.isdir(path) or path.endswith(".json")), + ) + ap_updateVSSTree.add_argument( + "Json", + help="Json tree to update VSS", +- completer_method=jsonfile_completer_method, ++ completer=jsonfile_completer, + ) + + # Constructor, request names after protocol to avoid errors +-- +2.44.0 diff --git a/recipes-connectivity/kuksa-client/kuksa-client/0002-kuksa-client-Tweak-grpcio-tools-requirement.patch b/recipes-connectivity/kuksa-client/kuksa-client/0002-kuksa-client-Tweak-grpcio-tools-requirement.patch new file mode 100644 index 00000000..0b63b60c --- /dev/null +++ b/recipes-connectivity/kuksa-client/kuksa-client/0002-kuksa-client-Tweak-grpcio-tools-requirement.patch @@ -0,0 +1,30 @@ +From 43823a52a9cb25d906542d15dc207f6516579aa3 Mon Sep 17 00:00:00 2001 +From: Scott Murray +Date: Thu, 5 Jun 2025 16:03:47 -0400 +Subject: [PATCH 2/2] Tweak grpcio-tools requirement + +Lower grpcio-tools requirement to 1.62.0 so building on YP scarthgap +is possible. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray +--- + kuksa-client/pyproject.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kuksa-client/pyproject.toml b/kuksa-client/pyproject.toml +index 46cb1b0..7c8246b 100644 +--- a/kuksa-client/pyproject.toml ++++ b/kuksa-client/pyproject.toml +@@ -1,7 +1,7 @@ + [build-system] + requires = [ + # Make sure to use the same exact version criteria in setup.cfg and update requirements.txt after changing +- "grpcio-tools==1.68.0", ++ "grpcio-tools>=1.62.0", + "setuptools>=42", + "setuptools-git-versioning", + "wheel", +-- +2.49.0 diff --git a/recipes-connectivity/kuksa-client/kuksa-client/0003-kuksa-client-Fix-AIO-version-of-gRPC-subscribe_target_values.patch b/recipes-connectivity/kuksa-client/kuksa-client/0003-kuksa-client-Fix-AIO-version-of-gRPC-subscribe_target_values.patch new file mode 100644 index 00000000..738fcea8 --- /dev/null +++ b/recipes-connectivity/kuksa-client/kuksa-client/0003-kuksa-client-Fix-AIO-version-of-gRPC-subscribe_target_values.patch @@ -0,0 +1,30 @@ +From 68fb6dec3e25be3aa0c2b339a3951911e93230ac Mon Sep 17 00:00:00 2001 +From: Scott Murray +Date: Thu, 5 Jun 2025 16:04:44 -0400 +Subject: [PATCH 3/3] Fix AIO version of gRPC subscribe_target_values + +The AIO version of subscribe_target_values was still setting the +try_v2 flag when calling subscribe, which fails since that is +not supported with VAL v2. Update it to match the non-AIO version +and restore working behavior. + +Upstream-Status: Pending +Signed-off-by: Scott Murray +--- + kuksa-client/kuksa_client/grpc/aio.py | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/kuksa-client/kuksa_client/grpc/aio.py b/kuksa-client/kuksa_client/grpc/aio.py +index 2571b2c..02b9e48 100644 +--- a/kuksa-client/kuksa_client/grpc/aio.py ++++ b/kuksa-client/kuksa_client/grpc/aio.py +@@ -327,7 +327,6 @@ class VSSClient(BaseVSSClient): + SubscribeEntry(path, View.TARGET_VALUE, (Field.ACTUATOR_TARGET,)) + for path in paths + ), +- try_v2=True, + **rpc_kwargs, + ): + yield { +-- +2.49.0 diff --git a/recipes-connectivity/kuksa-client/kuksa-client_git.bb b/recipes-connectivity/kuksa-client/kuksa-client_git.bb new file mode 100644 index 00000000..412db9b5 --- /dev/null +++ b/recipes-connectivity/kuksa-client/kuksa-client_git.bb @@ -0,0 +1,39 @@ +DESCRIPTION = "KUKSA.val client" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +BRANCH = "main" +SRCREV = "cdf8f8215043b56cad3deaacb59322926b70418a" + +SRC_URI = "gitsm://github.com/eclipse-kuksa/kuksa-python-sdk.git;protocol=https;branch=${BRANCH}" + +SRC_URI += " \ + file://0001-kuksa-client-Update-cmd2-completer-usage.patch;patchdir=.. \ + file://0002-kuksa-client-Tweak-grpcio-tools-requirement.patch;patchdir=.. \ + file://0003-kuksa-client-Fix-AIO-version-of-gRPC-subscribe_target_values.patch;patchdir=.. \ +" + +S = "${WORKDIR}/git/kuksa-client" + +inherit python_setuptools_build_meta + +do_compile:prepend() { + nativepython3 -m proto +} + +DEPENDS = " \ + python3-setuptools-git-versioning-native \ + python3-grpcio-tools-native \ + python3-grpcio \ +" + +RDEPENDS:${PN} += " \ + python3-cmd2 \ + python3-importlib-metadata \ + python3-pkg-resources \ + python3-pygments \ + python3-websockets \ + python3-grpcio \ + python3-grpcio-tools \ + python3-jsonpath-ng \ +" diff --git a/recipes-connectivity/kuksa-databroker/files/CA.pem b/recipes-connectivity/kuksa-databroker/files/CA.pem new file mode 100644 index 00000000..b3fa17d6 --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/CA.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3zCCAscCFDixxnLKOE9pr9sDQynjRqX7u+TlMA0GCSqGSIb3DQEBCwUAMIGr +MQswCQYDVQQGEwJVUzEWMBQGA1UECAwNU2FuIEZyYW5jaXNjbzETMBEGA1UEBwwK +Q2FsaWZvcm5pYTEcMBoGA1UECgwTYXV0b21vdGl2ZWxpbnV4Lm9yZzEVMBMGA1UE +AwwMbG9jYWxob3N0LWNhMTowOAYJKoZIhvcNAQkBFithZ2wtZGV2LWNvbW11bml0 +eUBsaXN0cy5hdXRvbW90aXZlbGludXgub3JnMB4XDTIzMDcyMDIwMzg1NVoXDTMz +MDcxNzIwMzg1NVowgasxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1TYW4gRnJhbmNp +c2NvMRMwEQYDVQQHDApDYWxpZm9ybmlhMRwwGgYDVQQKDBNhdXRvbW90aXZlbGlu +dXgub3JnMRUwEwYDVQQDDAxsb2NhbGhvc3QtY2ExOjA4BgkqhkiG9w0BCQEWK2Fn +bC1kZXYtY29tbXVuaXR5QGxpc3RzLmF1dG9tb3RpdmVsaW51eC5vcmcwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDJZvopAg03G1TuyukI2QdVTzHQxnG +iPePMVIBAQ8M5tBWBOZxxkOgwRBTqZ1GJRvgPPediPHb3+/j+k5/+NE8TT2smDfk +4u9+NBNFXGhC9jqoEe0nkxca85RHP1Jx1iIp8SJ1TTtzEu4q/O/9bCnA+05NPLWQ +YbDZr++lR4Bwhpz0ZVD69uZE/7aXPKVoVQPyeiwNgP7sfn5XOx+THpYz2Lwl2ew/ +490Mm5Wrw5pQkq49s5On5tR7cdms3CWnVKe+qpeJo/ShZg8mJesMusZRLZ3slSPp +GMVBbdFPhIv0L4HFzoJcnEzo1j6+h7fhu4v5T2qNkCkBlxehqvsy3DwfAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBALNHiz8a86sZv6Pii/rtrlctD2x1qIobOAjQID55 +/ylAVPc0JuzGEpc8Hcl9jQXBFz2ZBBYTEn0iAB+nn9BnxWYpF/G9LQsz61uzdJJs +0WlR3FyjN8PwCysMwzGEmG2BH43vfg9oltAKxY4rZ3l5c8eL/a9o2vDzNjKNibll +NdLB+8NkZz33pjyru1sG2lw6Y1gxhcOMSU7MuHgW1YI06slBu56e92OQt5atRc6l +rY9faELSJpLhtKYF9spsS/LsITJrKdVkMZRgqrhoWAIB9qyehtBGk+Agk8MvBba8 +nRAF332SyeLeN/ytJTbjOmcYVh9daGADdyRb5d+5ALBuutU= +-----END CERTIFICATE----- diff --git a/recipes-connectivity/kuksa-databroker/files/Client.key b/recipes-connectivity/kuksa-databroker/files/Client.key new file mode 100644 index 00000000..73b67f5c --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/Client.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyISsHMGwy8dvhx+tPQOGtgtb9YDWS0kRMPcOou3QlUjAcXmz +vT2dLIwOnnRYBS9nENDqI4x52yECUBwVNIvoeiZlQqjKhSr2BOpwJIgJgqeKr4he +sU9M9s3ODqR2sdUhv7e54sRYSFv5Hs35Horr3guSRh12FtWh+iLT2PI75jbi3KjP +mK4yZGJmoSQWh+q/vhB5CQtdAcA/08aoZnhyMOGqBMzmhr1PDm7UbzZIcp2Lxs3x +q3PBJq5eMF6N3S8ssETz7WOqX0vnBdgl4DhMYCVgrjppXzmcYYbkm4uluKVf8sR7 +cAbSaoUUft2G4mLXNBE1RJVpYrzHIQW7OphjqQIDAQABAoIBAGfnl+gu1hZCeiBi +4bpEIYIj0Lsez+yjKC1fWE5FPVieIlqq3eCqFNAIo2qojxPgxF+KYkmZeWt7Z19r +rfFUrlrdmos4O/lVkbZqZUII3CS//LWIzMjEdvVNIAGmZ3svHhXidohzheu4/RZh +VT3mbuLYzCtZCOA8Q3sCoRRCMZfQ3jrTEvak4xrgotihL3bEUOIrA8Tyv8AaAhmP +nIKV+0pS/d8xCkpIBmkNxVtNRAGvsQK5i7DsQYFEDKzbFjhXz7jRapfesAQACEgJ +0yLYKSoiHktuyHIPspj37BdTZva6vNkabJVcDKXMIuRd5xnypiygv7vo+onHJ5Rw +T9TzryECgYEA6oe9qYdiXsKygUji9W6rqYGPAl6o56nyAX6QrKnKhCQBmyVYgBB5 +YmehULzjK1Xvno5ophiBkojnCE8y99liEWZWnE9p2pr8O028ZfQficfbjWgkqmL5 +awmUTON40wK7QkpWj81YwbARYAQuC611R4MfzLWlnxxHacvBZc8x2j8CgYEA2t/a +s6dW2XuqfEgfS/oKI/9i1/CXnPFVAueAPCCl/Ee/QAGJMdmSf4yonnbnOycGMdSh +QGYUHb/PT7i04U+92T+rniprXn3QFz6iwF6X6nCkdlw9RxcWAOmg5l0yIoo9bp7J +LmVnbn2Y2TOy8/Djq47gypTH8H0VSVg5BjKgOBcCgYAG3giosSUpPyw46uhyZVYz +dW65lAoAFpLWhl04IRSj/+XoJBTOUy0qu3wWwCEqwK5uhx77VhZdMxMIxEDqzvu3 +JLb+hrjDxOwD1IfiuF5AC5EbN+Ry9Mj24GXuRm7gRuEy1LhqJ4okycIIfLbYcrDP +ckB5HwyFdy+EIoo8L+/2wwKBgQDallPJteaTvuCtzC2NaEK2XritZjdUYuR+yQqV +ghmjEVhcKOyGX37iaWyBDciyl6+lFnCQayHN8CCvwozKtCOrEt5nUH/4V3f5rvFF +Y3MejK6DEm2UUOcFtE2foxWNzze5AVV0Q4t/mmmLCgm/fCUz0baIOvxPHeyjWjth +CDBgswKBgQDj5QlFkdlgJvdJweHUSWm0vssFCgCucWEPgy5iOo4MDxEHq0r1AZWU +K5j1xabtD73K6JmO3ElvSELGAd1MlvRzeZMsSP8goCk3e8a85js2sRPwDxGHa0Dd +Ef7DoyFp6UIDOUAX6R2ylPyZYqM7bowoLdGIwh9jo8fZnvHn/UCw0w== +-----END RSA PRIVATE KEY----- diff --git a/recipes-connectivity/kuksa-databroker/files/Client.pem b/recipes-connectivity/kuksa-databroker/files/Client.pem new file mode 100644 index 00000000..fcd92b6e --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/Client.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIUeUuog3JmZGhkE0nRcATDuclsVvkwDQYJKoZIhvcNAQEL +BQAwgasxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1TYW4gRnJhbmNpc2NvMRMwEQYD +VQQHDApDYWxpZm9ybmlhMRwwGgYDVQQKDBNhdXRvbW90aXZlbGludXgub3JnMRUw +EwYDVQQDDAxsb2NhbGhvc3QtY2ExOjA4BgkqhkiG9w0BCQEWK2FnbC1kZXYtY29t +bXVuaXR5QGxpc3RzLmF1dG9tb3RpdmVsaW51eC5vcmcwHhcNMjMwNzIwMjAzODU1 +WhcNMjcwNzE5MjAzODU1WjCBpTELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDVNhbiBG +cmFuY2lzY28xEzARBgNVBAcMCkNhbGlmb3JuaWExHDAaBgNVBAoME2F1dG9tb3Rp +dmVsaW51eC5vcmcxDzANBgNVBAMMBkNsaWVudDE6MDgGCSqGSIb3DQEJARYrYWds +LWRldi1jb21tdW5pdHlAbGlzdHMuYXV0b21vdGl2ZWxpbnV4Lm9yZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMiErBzBsMvHb4cfrT0DhrYLW/WA1ktJ +ETD3DqLt0JVIwHF5s709nSyMDp50WAUvZxDQ6iOMedshAlAcFTSL6HomZUKoyoUq +9gTqcCSICYKniq+IXrFPTPbNzg6kdrHVIb+3ueLEWEhb+R7N+R6K694LkkYddhbV +ofoi09jyO+Y24tyoz5iuMmRiZqEkFofqv74QeQkLXQHAP9PGqGZ4cjDhqgTM5oa9 +Tw5u1G82SHKdi8bN8atzwSauXjBejd0vLLBE8+1jql9L5wXYJeA4TGAlYK46aV85 +nGGG5JuLpbilX/LEe3AG0mqFFH7dhuJi1zQRNUSVaWK8xyEFuzqYY6kCAwEAAaMm +MCQwIgYDVR0RBBswGYIGQ2xpZW50gglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcN +AQELBQADggEBAGtM7LGk4PhEgrjLXr7tdRn/VSwUv+HLDmtgkMFsAqYolTwtK7eK +1XgNF2j6Yo4ma/efd8Td9wjKkrfkxQRCpM5gjNLhiZsBRO/HW4GiC3GKz0ELijE2 +7JU7xikawSE6Zvvj1t33KJ5uGDowv2tvDbCB76ecGohTb5O7mpe+fxMlt+d4vPku +uTfAaNfl8+oSo7suy3842ANpxteoxfVHZgG0FjdMKjSKxCyxI3buLltlQ7G+39QS +/cwuRTOp0UNPpiHWDKVOXL8qW/ZHpocGFlErstEQjUz+3/WglMlTK07ocRVQjQc6 +mAo4aKRaaHi5Khn+KPrRDnS+Rl8xEzSsBeo= +-----END CERTIFICATE----- diff --git a/recipes-connectivity/kuksa-databroker/files/Server.key b/recipes-connectivity/kuksa-databroker/files/Server.key new file mode 100644 index 00000000..8b9c6ac6 --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/Server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAzGvmH7adlcMVdfblKg56EkgiSkR45IrRaIMH/AKUcK/4EJdk +Jx3NoHuYuiTTreiovt9b5FjqV8txuJ579e4O9GyDELN1r9stR5y8zEbFQuf8afxK +Bl0JPnhXOxi7nUq92rn0H7jpm0a9WQvmbdRsFVfafNoeC4Dz1PeGMN4tHYtHHCnq +Ye5Sr7yT/eZ8RMUoXB560akRctA/pQWEwYbNps02HJs+jeNsJuXTgXpsirTy2RR5 +TKLmZjQMovxW85zYpSS9fRprwpzqeHhWbJBWWNeP8Y20nkRbAaAktc8IrlmhFMLh +4n0L1B0s0+Xn/9kt98pNSDCJPzH6Ar4LoDPDfwIDAQABAoIBAAyG0CNBXYa/3aDM +8F4TZQeZxAApEf9vQkXVQbf/sHj3T4w0ur5q5R7gdAt0FkSh7TVFGqxzhmi63s0h +aRc471GrFJ0BYkTUeYHZ6PfbnlrrPFyCSUb6jIZ3eWD1swmAewHcQ0luW2JYg2Hh +iM1SJw1nxMvB0fWCgW6bfG2iL8GPmyrVyhyrfebZdEaUUnjvfqLWroIoBZ2B0roa +dZ/VDlXzN8wspyziCqlumiq+R3b9+abBtHLyG13DQAhVYGksbX+5W4s1Yy6nwG0S +yyRh2cK5c2MPrjqHmJr1GqlXItmEnqkjiVlg/qZDEyalWHcKFNGNaURSz7RWNwo2 +cWZv8AECgYEA/h76+2yjvYfDeZRiKRfN9imfT9F6T4VoGgfoZODIe6uLsOQOeiKR +lqjj6bdIP8CDsfcHhb38FblYsgm6GFZiROQafRjVfj2yWiasQszFTOzLDRqR8LNs +nZSUv7zlPziJ28VBs1DF5lZSNbzFXEKxAWdGAINC1POdKZOi2UCUwYECgYEAze7X +7ML1QV+ZipnszLiRvccQ7kMUw51g/hi0Fw//tkCC8FnsbR489GDb8l+V/IR9tNov +7y5cd/NRziGVUhXH67ZnXa2k5yRYxhFWQxpgEEUWUhsfYVqppMj7vMjcxVa85A0R +2hzI/kWWWWcowwuHSmuoU8xRZlNdA2cbefeBBP8CgYEArm8hpRhLxTu+CGS8hKyc +ak7j1mxaYt+WN9gZw7UwqQN2HfRNo7S67wn7eGChLXG+dJi3By0ELv1NTtiybyZM +yjExpZE4azF6jbtiH3BkNouMTfBhITJoajqlaIAHdMAgkUTz9lyJm7TBNbXgW5ZD +3ky/lnaDl52p0fJPpIVaFwECgYEAyhsRYTUJPGqVpxhf9Z9isY0wCZZeR4kqStZ1 +0HiMLxLrLvYh+gmGKxTwZ9P1wIlLUfYcuzGV4Mc1TwdYo+HqfmRa1+52e78JPQKA +1YSKKQ2U1Wn3BzXSbn4tyd6cBTSWV36YOaasgBhNcVqz/5BN6/Tyk6Nfc/x2ucM0 +jSQiRIMCgYADss1PeYdANwbw8n29mXEGkk6qfVh54MU/AoS2v6kk6fqAHNFsb9vJ +m3JkRYSh3kSKwKgD97oGMpbxLr0wVj69s4s8wPjhNo4RZALCB/sj9hra7rsoRzmQ +apSPbfLaWVZEqg3fj0gCamSq8PGjY4fA9RNHOB751M2oszpQb8bdpA== +-----END RSA PRIVATE KEY----- diff --git a/recipes-connectivity/kuksa-databroker/files/Server.pem b/recipes-connectivity/kuksa-databroker/files/Server.pem new file mode 100644 index 00000000..4b181e9a --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/Server.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBjCCAu6gAwIBAgIUeUuog3JmZGhkE0nRcATDuclsVvgwDQYJKoZIhvcNAQEL +BQAwgasxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1TYW4gRnJhbmNpc2NvMRMwEQYD +VQQHDApDYWxpZm9ybmlhMRwwGgYDVQQKDBNhdXRvbW90aXZlbGludXgub3JnMRUw +EwYDVQQDDAxsb2NhbGhvc3QtY2ExOjA4BgkqhkiG9w0BCQEWK2FnbC1kZXYtY29t +bXVuaXR5QGxpc3RzLmF1dG9tb3RpdmVsaW51eC5vcmcwHhcNMjMwNzIwMjAzODU1 +WhcNMjcwNzE5MjAzODU1WjCBpTELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDVNhbiBG +cmFuY2lzY28xEzARBgNVBAcMCkNhbGlmb3JuaWExHDAaBgNVBAoME2F1dG9tb3Rp +dmVsaW51eC5vcmcxDzANBgNVBAMMBlNlcnZlcjE6MDgGCSqGSIb3DQEJARYrYWds +LWRldi1jb21tdW5pdHlAbGlzdHMuYXV0b21vdGl2ZWxpbnV4Lm9yZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMxr5h+2nZXDFXX25SoOehJIIkpEeOSK +0WiDB/wClHCv+BCXZCcdzaB7mLok063oqL7fW+RY6lfLcbiee/XuDvRsgxCzda/b +LUecvMxGxULn/Gn8SgZdCT54VzsYu51Kvdq59B+46ZtGvVkL5m3UbBVX2nzaHguA +89T3hjDeLR2LRxwp6mHuUq+8k/3mfETFKFweetGpEXLQP6UFhMGGzabNNhybPo3j +bCbl04F6bIq08tkUeUyi5mY0DKL8VvOc2KUkvX0aa8Kc6nh4VmyQVljXj/GNtJ5E +WwGgJLXPCK5ZoRTC4eJ9C9QdLNPl5//ZLffKTUgwiT8x+gK+C6Azw38CAwEAAaMm +MCQwIgYDVR0RBBswGYIGU2VydmVygglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcN +AQELBQADggEBAKLnUuIYKU7kX6hw2kWziAzvucZCwkKDnMK1/xqakcgfnFw+z8nu +XSqNsXX0KNBfy0xhZ66Uc9rL37RG+smidxJxy+QmDi3c/Ooqj7DxbZwVXzstnbBp ++iqgfqjadC8Glfci7cfCnl7X4O3oQqo99BJDo7JH3S39fe98mG4mXa1WblKiWnkc +yDtUnf7eFbFeNbVkL94HGzOtghShHokGyt9vZKyGf+szCPPWiIDldLq/CUpPFEnD +AqUhTYBXbHZNZJHAEJ0waJqLxmytt19mAv03aaIMYUpBR0CMvjfDNn5x2Bp86v3A +YW544bNsyHfbvK0ZqwvOaV3sIKG7Bzm2pOA= +-----END CERTIFICATE----- diff --git a/recipes-connectivity/kuksa-databroker/files/genCertsAGL.sh b/recipes-connectivity/kuksa-databroker/files/genCertsAGL.sh new file mode 100755 index 00000000..b078fd1b --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/genCertsAGL.sh @@ -0,0 +1,58 @@ +#!/bin/bash + + +genCAKey() { + openssl genrsa -out CA.key 2048 +} + + +genCACert() { + openssl req -key CA.key -new -out CA.csr -subj "/C=US/ST=San Francisco/L=California/O=automotivelinux.org/CN=localhost-ca/emailAddress=agl-dev-community@lists.automotivelinux.org" + openssl x509 -signkey CA.key -in CA.csr -req -days 3650 -out CA.pem +} + +genKey() { + openssl genrsa -out $1.key 2048 +} + +genCert() { + openssl req -new -key $1.key -out $1.csr -passin pass:"temp" -subj "/C=US/ST=San Francisco/L=California/O=automotivelinux.org/CN=$1/emailAddress=agl-dev-community@lists.automotivelinux.org" + openssl x509 -req -in $1.csr -extfile <(printf "subjectAltName=DNS:$1,DNS:localhost,IP:127.0.0.1") -CA CA.pem -CAkey CA.key -CAcreateserial -days 1460 -out $1.pem + openssl verify -CAfile CA.pem $1.pem +} + +set -e +# Check if the CA is available, else make CA certificates +if [ -f "CA.key" ]; then + echo "Existing CA.key will be used" +else + echo "No CA.key found, will generate new key" + genCAKey + rm -f CA.pem + echo "" +fi + +# Check if the CA.pem is available, else generate a new CA.pem +if [ -f "CA.pem" ]; then + echo "CA.pem will not be regenerated" +else + echo "No CA.pem found, will generate new CA.pem" + genCACert + echo "" +fi + + +for i in Server Client; +do + if [ -f $i.key ]; then + echo "Existing $i.key will be used" + else + echo "No $i.key found, will generate new key" + genKey $i + fi + echo "" + echo "Generating $i.pem" + genCert $i + echo "" +done + diff --git a/recipes-connectivity/kuksa-databroker/files/jwt.key.pub b/recipes-connectivity/kuksa-databroker/files/jwt.key.pub new file mode 100644 index 00000000..d9f78534 --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/jwt.key.pub @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6ScE9EKXEWVyYhzfhfvg ++LC8NseiuEjfrdFx3HKkb31bRw/SeS0Rye0KDP7uzffwreKf6wWYGxVUPYmyKC7j +Pji5MpDBGM9r3pIZSvPUFdpTE5TiRHFBxWbqPSYt954BTLq4rMu/W+oq5Pdfnugb +voYpLf0dclBl1g9KyszkDnItz3TYbWhGMbsUSfyeSPzH0IADzLoifxbc5mgiR73N +CA/4yNSpfLoqWgQ2vdTM1182sMSmxfqSgMzIMUX/tiaXGdkoKITF1sULlLyWfTo9 +79XRZ0hmUwvfzr3OjMZNoClpYSVbKY+vtxHyux9KOOtv9lPMsgYIaPXvisrsneDZ +fCS0afOfjgR96uHIe2UPSGAXru3yGziqEfpRZoxsgXaOe905ordLD5bSX14xkN7N +Cz7rxDLlxPQyxp4Vhog7p/QeUyydBpZjq2bAE5GAJtiu+XGvG8RypzJFKFQwMNsw +g1BoZVD0mb0MtU8KQmHcZIfY0FVer/CR0mUjfl1rHbtoJB+RY03lQvYNAD04ibAG +NI1RhlTziu35Xo6NDEgs9hVs9k3WrtF+ZUxhivWmP2VXhWruRakVkC1NzKGh54e5 +/KlluFbBNpWgvWZqzWo9Jr7/fzHtR0Q0IZwkxh+Vd/bUZya1uLKqP+sTcc+aTHbn +AEiqOjPq0D6X45wCzIwjILUCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/recipes-connectivity/kuksa-databroker/files/kuksa-databroker.env b/recipes-connectivity/kuksa-databroker/files/kuksa-databroker.env new file mode 100644 index 00000000..4f918ced --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/kuksa-databroker.env @@ -0,0 +1 @@ +EXTRA_ARGS="--vss /usr/share/vss/vss.json --tls-cert /etc/kuksa-val/Server.pem --tls-private-key /etc/kuksa-val/Server.key --jwt-public-key /etc/kuksa-val/jwt.key.pub --address=0.0.0.0" diff --git a/recipes-connectivity/kuksa-databroker/files/kuksa-databroker.service b/recipes-connectivity/kuksa-databroker/files/kuksa-databroker.service new file mode 100644 index 00000000..95ee3fd1 --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/files/kuksa-databroker.service @@ -0,0 +1,11 @@ +[Unit] +Description=Eclipse KUKSA.val databroker +After=network.target + +[Service] +EnvironmentFile=-/etc/default/kuksa-databroker +ExecStart=/usr/bin/databroker $EXTRA_ARGS +Restart=on-abort + +[Install] +WantedBy=multi-user.target diff --git a/recipes-connectivity/kuksa-databroker/kuksa-databroker-crates.inc b/recipes-connectivity/kuksa-databroker/kuksa-databroker-crates.inc new file mode 100644 index 00000000..aa665528 --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/kuksa-databroker-crates.inc @@ -0,0 +1,1252 @@ +# Autogenerated with 'bitbake -c update_crates kuksa-databroker' + +# from Cargo.lock +SRC_URI += " \ + crate://crates.io/adler2/2.0.1 \ + crate://crates.io/ahash/0.8.12 \ + crate://crates.io/aho-corasick/1.1.4 \ + crate://crates.io/allocator-api2/0.2.21 \ + crate://crates.io/android_system_properties/0.1.5 \ + crate://crates.io/ansi_term/0.12.1 \ + crate://crates.io/anstream/1.0.0 \ + crate://crates.io/anstyle/1.0.14 \ + crate://crates.io/anstyle-parse/1.0.0 \ + crate://crates.io/anstyle-query/1.1.5 \ + crate://crates.io/anstyle-wincon/3.0.11 \ + crate://crates.io/anyhow/1.0.102 \ + crate://crates.io/arc-swap/1.9.0 \ + crate://crates.io/arrayref/0.3.9 \ + crate://crates.io/arrayvec/0.5.2 \ + crate://crates.io/async-stream/0.3.6 \ + crate://crates.io/async-stream-impl/0.3.6 \ + crate://crates.io/async-trait/0.1.89 \ + crate://crates.io/atomic-waker/1.1.2 \ + crate://crates.io/autocfg/1.5.0 \ + crate://crates.io/axum/0.6.20 \ + crate://crates.io/axum/0.8.8 \ + crate://crates.io/axum-core/0.3.4 \ + crate://crates.io/axum-core/0.5.6 \ + crate://crates.io/base16ct/0.2.0 \ + crate://crates.io/base64/0.13.1 \ + crate://crates.io/base64/0.21.7 \ + crate://crates.io/base64/0.22.1 \ + crate://crates.io/base64ct/1.8.3 \ + crate://crates.io/bitflags/1.3.2 \ + crate://crates.io/bitflags/2.11.0 \ + crate://crates.io/blake2b_simd/0.5.11 \ + crate://crates.io/block-buffer/0.10.4 \ + crate://crates.io/bstr/1.12.1 \ + crate://crates.io/bumpalo/3.20.2 \ + crate://crates.io/bytecount/0.6.9 \ + crate://crates.io/byteorder/1.5.0 \ + crate://crates.io/bytes/1.11.1 \ + crate://crates.io/camino/1.2.2 \ + crate://crates.io/cargo-platform/0.1.9 \ + crate://crates.io/cargo_metadata/0.18.1 \ + crate://crates.io/cc/1.2.58 \ + crate://crates.io/cfg-if/1.0.4 \ + crate://crates.io/chrono/0.4.44 \ + crate://crates.io/clap/4.6.0 \ + crate://crates.io/clap_builder/4.6.0 \ + crate://crates.io/clap_derive/4.6.0 \ + crate://crates.io/clap_lex/1.1.0 \ + crate://crates.io/clru/0.6.3 \ + crate://crates.io/colorchoice/1.0.5 \ + crate://crates.io/console/0.15.11 \ + crate://crates.io/const-oid/0.9.6 \ + crate://crates.io/constant_time_eq/0.1.5 \ + crate://crates.io/core-foundation-sys/0.8.7 \ + crate://crates.io/cpufeatures/0.2.17 \ + crate://crates.io/crc32fast/1.5.0 \ + crate://crates.io/crossbeam-channel/0.5.15 \ + crate://crates.io/crossbeam-deque/0.8.6 \ + crate://crates.io/crossbeam-epoch/0.9.18 \ + crate://crates.io/crossbeam-utils/0.8.21 \ + crate://crates.io/crypto-bigint/0.5.5 \ + crate://crates.io/crypto-common/0.1.6 \ + crate://crates.io/cucumber/0.20.2 \ + crate://crates.io/cucumber-codegen/0.20.2 \ + crate://crates.io/cucumber-expressions/0.3.0 \ + crate://crates.io/curve25519-dalek/4.1.3 \ + crate://crates.io/curve25519-dalek-derive/0.1.1 \ + crate://crates.io/dashmap/5.5.3 \ + crate://crates.io/data-encoding/2.10.0 \ + crate://crates.io/der/0.7.10 \ + crate://crates.io/deranged/0.5.8 \ + crate://crates.io/derive_more/0.99.20 \ + crate://crates.io/digest/0.10.7 \ + crate://crates.io/dirs/1.0.5 \ + crate://crates.io/dirs/4.0.0 \ + crate://crates.io/dirs-sys/0.3.7 \ + crate://crates.io/displaydoc/0.2.5 \ + crate://crates.io/drain_filter_polyfill/0.1.3 \ + crate://crates.io/dunce/1.0.5 \ + crate://crates.io/ecdsa/0.16.9 \ + crate://crates.io/ed25519/2.2.3 \ + crate://crates.io/ed25519-dalek/2.2.0 \ + crate://crates.io/either/1.15.0 \ + crate://crates.io/elliptic-curve/0.13.8 \ + crate://crates.io/encode_unicode/1.0.0 \ + crate://crates.io/env_filter/1.0.1 \ + crate://crates.io/env_logger/0.11.10 \ + crate://crates.io/equivalent/1.0.2 \ + crate://crates.io/errno/0.3.14 \ + crate://crates.io/faster-hex/0.9.0 \ + crate://crates.io/fastrand/2.3.0 \ + crate://crates.io/ff/0.13.1 \ + crate://crates.io/fiat-crypto/0.2.9 \ + crate://crates.io/filetime/0.2.27 \ + crate://crates.io/find-msvc-tools/0.1.9 \ + crate://crates.io/fixedbitset/0.5.7 \ + crate://crates.io/flate2/1.1.9 \ + crate://crates.io/fnv/1.0.7 \ + crate://crates.io/foldhash/0.1.5 \ + crate://crates.io/foldhash/0.2.0 \ + crate://crates.io/form_urlencoded/1.2.2 \ + crate://crates.io/futures/0.3.32 \ + crate://crates.io/futures-channel/0.3.32 \ + crate://crates.io/futures-core/0.3.32 \ + crate://crates.io/futures-executor/0.3.32 \ + crate://crates.io/futures-io/0.3.32 \ + crate://crates.io/futures-macro/0.3.32 \ + crate://crates.io/futures-sink/0.3.32 \ + crate://crates.io/futures-task/0.3.32 \ + crate://crates.io/futures-util/0.3.32 \ + crate://crates.io/generic-array/0.14.9 \ + crate://crates.io/getrandom/0.1.16 \ + crate://crates.io/getrandom/0.2.17 \ + crate://crates.io/getrandom/0.4.2 \ + crate://crates.io/gherkin/0.14.0 \ + crate://crates.io/gix/0.63.0 \ + crate://crates.io/gix-actor/0.31.5 \ + crate://crates.io/gix-bitmap/0.2.16 \ + crate://crates.io/gix-chunk/0.4.12 \ + crate://crates.io/gix-commitgraph/0.24.3 \ + crate://crates.io/gix-config/0.37.0 \ + crate://crates.io/gix-config-value/0.14.12 \ + crate://crates.io/gix-date/0.8.7 \ + crate://crates.io/gix-diff/0.44.1 \ + crate://crates.io/gix-discover/0.32.0 \ + crate://crates.io/gix-features/0.38.2 \ + crate://crates.io/gix-fs/0.11.3 \ + crate://crates.io/gix-glob/0.16.5 \ + crate://crates.io/gix-hash/0.14.2 \ + crate://crates.io/gix-hashtable/0.5.2 \ + crate://crates.io/gix-index/0.33.1 \ + crate://crates.io/gix-lock/14.0.0 \ + crate://crates.io/gix-macros/0.1.5 \ + crate://crates.io/gix-object/0.42.3 \ + crate://crates.io/gix-odb/0.61.1 \ + crate://crates.io/gix-pack/0.51.1 \ + crate://crates.io/gix-path/0.10.22 \ + crate://crates.io/gix-quote/0.4.15 \ + crate://crates.io/gix-ref/0.44.1 \ + crate://crates.io/gix-refspec/0.23.1 \ + crate://crates.io/gix-revision/0.27.2 \ + crate://crates.io/gix-revwalk/0.13.2 \ + crate://crates.io/gix-sec/0.10.12 \ + crate://crates.io/gix-tempfile/14.0.2 \ + crate://crates.io/gix-trace/0.1.18 \ + crate://crates.io/gix-traverse/0.39.2 \ + crate://crates.io/gix-url/0.27.5 \ + crate://crates.io/gix-utils/0.1.14 \ + crate://crates.io/gix-validate/0.8.5 \ + crate://crates.io/gix-validate/0.10.1 \ + crate://crates.io/glob-match/0.2.1 \ + crate://crates.io/globset/0.4.18 \ + crate://crates.io/globwalk/0.8.1 \ + crate://crates.io/group/0.13.0 \ + crate://crates.io/h2/0.3.27 \ + crate://crates.io/h2/0.4.13 \ + crate://crates.io/hashbrown/0.12.3 \ + crate://crates.io/hashbrown/0.14.5 \ + crate://crates.io/hashbrown/0.15.5 \ + crate://crates.io/hashbrown/0.16.1 \ + crate://crates.io/heck/0.4.1 \ + crate://crates.io/heck/0.5.0 \ + crate://crates.io/hkdf/0.12.4 \ + crate://crates.io/hmac/0.12.1 \ + crate://crates.io/home/0.5.12 \ + crate://crates.io/http/0.2.12 \ + crate://crates.io/http/1.4.0 \ + crate://crates.io/http-body/0.4.6 \ + crate://crates.io/http-body/1.0.1 \ + crate://crates.io/http-body-util/0.1.3 \ + crate://crates.io/httparse/1.10.1 \ + crate://crates.io/httpdate/1.0.3 \ + crate://crates.io/humantime/2.3.0 \ + crate://crates.io/hyper/0.14.32 \ + crate://crates.io/hyper/1.9.0 \ + crate://crates.io/hyper-timeout/0.4.1 \ + crate://crates.io/hyper-timeout/0.5.2 \ + crate://crates.io/hyper-util/0.1.20 \ + crate://crates.io/iana-time-zone/0.1.65 \ + crate://crates.io/iana-time-zone-haiku/0.1.2 \ + crate://crates.io/icu_collections/2.1.1 \ + crate://crates.io/icu_locale_core/2.1.1 \ + crate://crates.io/icu_normalizer/2.1.1 \ + crate://crates.io/icu_normalizer_data/2.1.1 \ + crate://crates.io/icu_properties/2.1.2 \ + crate://crates.io/icu_properties_data/2.1.2 \ + crate://crates.io/icu_provider/2.1.1 \ + crate://crates.io/id-arena/2.3.0 \ + crate://crates.io/idna/1.1.0 \ + crate://crates.io/idna_adapter/1.2.1 \ + crate://crates.io/ignore/0.4.25 \ + crate://crates.io/indexmap/1.9.3 \ + crate://crates.io/indexmap/2.13.0 \ + crate://crates.io/inflections/1.1.1 \ + crate://crates.io/inventory/0.3.24 \ + crate://crates.io/is_terminal_polyfill/1.70.2 \ + crate://crates.io/itertools/0.10.5 \ + crate://crates.io/itertools/0.12.1 \ + crate://crates.io/itertools/0.14.0 \ + crate://crates.io/itoa/1.0.18 \ + crate://crates.io/jemalloc-sys/0.5.4+5.3.0-patched \ + crate://crates.io/jemallocator/0.5.4 \ + crate://crates.io/jiff/0.2.23 \ + crate://crates.io/jiff-static/0.2.23 \ + crate://crates.io/js-sys/0.3.94 \ + crate://crates.io/jsonwebtoken/10.3.0 \ + crate://crates.io/lazy-regex/3.6.0 \ + crate://crates.io/lazy-regex-proc_macros/3.6.0 \ + crate://crates.io/lazy_static/1.5.0 \ + crate://crates.io/leb128fmt/0.1.0 \ + crate://crates.io/libc/0.2.183 \ + crate://crates.io/libm/0.2.16 \ + crate://crates.io/libredox/0.1.15 \ + crate://crates.io/linefeed/0.6.0 \ + crate://crates.io/linked-hash-map/0.5.6 \ + crate://crates.io/linux-raw-sys/0.4.15 \ + crate://crates.io/linux-raw-sys/0.12.1 \ + crate://crates.io/litemap/0.8.1 \ + crate://crates.io/lock_api/0.4.14 \ + crate://crates.io/log/0.4.29 \ + crate://crates.io/matchers/0.2.0 \ + crate://crates.io/matchit/0.7.3 \ + crate://crates.io/matchit/0.8.4 \ + crate://crates.io/memchr/2.8.0 \ + crate://crates.io/memmap2/0.9.10 \ + crate://crates.io/mime/0.3.17 \ + crate://crates.io/minimal-lexical/0.2.1 \ + crate://crates.io/miniz_oxide/0.8.9 \ + crate://crates.io/mio/1.2.0 \ + crate://crates.io/mortal/0.2.4 \ + crate://crates.io/multimap/0.10.1 \ + crate://crates.io/nix/0.26.4 \ + crate://crates.io/nom/7.1.3 \ + crate://crates.io/nom_locate/4.2.0 \ + crate://crates.io/nu-ansi-term/0.50.3 \ + crate://crates.io/num-bigint/0.4.6 \ + crate://crates.io/num-bigint-dig/0.8.6 \ + crate://crates.io/num-conv/0.2.1 \ + crate://crates.io/num-integer/0.1.46 \ + crate://crates.io/num-iter/0.1.45 \ + crate://crates.io/num-traits/0.2.19 \ + crate://crates.io/num_threads/0.1.7 \ + crate://crates.io/once_cell/1.21.4 \ + crate://crates.io/once_cell_polyfill/1.70.2 \ + crate://crates.io/opentelemetry/0.19.0 \ + crate://crates.io/opentelemetry-otlp/0.12.0 \ + crate://crates.io/opentelemetry-proto/0.2.0 \ + crate://crates.io/opentelemetry-semantic-conventions/0.11.0 \ + crate://crates.io/opentelemetry_api/0.19.0 \ + crate://crates.io/opentelemetry_sdk/0.19.0 \ + crate://crates.io/p256/0.13.2 \ + crate://crates.io/p384/0.13.1 \ + crate://crates.io/parking_lot/0.12.5 \ + crate://crates.io/parking_lot_core/0.9.12 \ + crate://crates.io/peg/0.6.3 \ + crate://crates.io/peg-macros/0.6.3 \ + crate://crates.io/peg-runtime/0.6.3 \ + crate://crates.io/pem/3.0.6 \ + crate://crates.io/pem-rfc7468/0.7.0 \ + crate://crates.io/percent-encoding/2.3.2 \ + crate://crates.io/petgraph/0.8.3 \ + crate://crates.io/phf/0.11.3 \ + crate://crates.io/phf_codegen/0.11.3 \ + crate://crates.io/phf_generator/0.11.3 \ + crate://crates.io/phf_shared/0.11.3 \ + crate://crates.io/pin-project/1.1.11 \ + crate://crates.io/pin-project-internal/1.1.11 \ + crate://crates.io/pin-project-lite/0.2.17 \ + crate://crates.io/pkcs1/0.7.5 \ + crate://crates.io/pkcs8/0.10.2 \ + crate://crates.io/plain/0.2.3 \ + crate://crates.io/portable-atomic/1.13.1 \ + crate://crates.io/portable-atomic-util/0.2.6 \ + crate://crates.io/potential_utf/0.1.4 \ + crate://crates.io/powerfmt/0.2.0 \ + crate://crates.io/ppv-lite86/0.2.21 \ + crate://crates.io/prettyplease/0.2.37 \ + crate://crates.io/primeorder/0.13.6 \ + crate://crates.io/proc-macro2/1.0.106 \ + crate://crates.io/prodash/28.0.0 \ + crate://crates.io/prost/0.11.9 \ + crate://crates.io/prost/0.14.3 \ + crate://crates.io/prost-build/0.14.3 \ + crate://crates.io/prost-derive/0.11.9 \ + crate://crates.io/prost-derive/0.14.3 \ + crate://crates.io/prost-types/0.14.3 \ + crate://crates.io/quote/1.0.45 \ + crate://crates.io/r-efi/6.0.0 \ + crate://crates.io/rand/0.8.5 \ + crate://crates.io/rand_chacha/0.3.1 \ + crate://crates.io/rand_core/0.6.4 \ + crate://crates.io/redox_syscall/0.1.57 \ + crate://crates.io/redox_syscall/0.5.18 \ + crate://crates.io/redox_syscall/0.7.3 \ + crate://crates.io/redox_users/0.3.5 \ + crate://crates.io/redox_users/0.4.6 \ + crate://crates.io/regex/1.12.3 \ + crate://crates.io/regex-automata/0.4.14 \ + crate://crates.io/regex-syntax/0.7.5 \ + crate://crates.io/regex-syntax/0.8.10 \ + crate://crates.io/rfc6979/0.4.0 \ + crate://crates.io/ring/0.17.14 \ + crate://crates.io/rsa/0.9.10 \ + crate://crates.io/rust-argon2/0.8.3 \ + crate://crates.io/rustc_version/0.4.1 \ + crate://crates.io/rustix/0.38.44 \ + crate://crates.io/rustix/1.1.4 \ + crate://crates.io/rustls/0.23.37 \ + crate://crates.io/rustls-pki-types/1.14.0 \ + crate://crates.io/rustls-webpki/0.103.10 \ + crate://crates.io/rustversion/1.0.22 \ + crate://crates.io/ryu/1.0.23 \ + crate://crates.io/same-file/1.0.6 \ + crate://crates.io/scopeguard/1.2.0 \ + crate://crates.io/sd-notify/0.4.5 \ + crate://crates.io/sealed/0.5.0 \ + crate://crates.io/sec1/0.7.3 \ + crate://crates.io/semver/1.0.27 \ + crate://crates.io/serde/1.0.228 \ + crate://crates.io/serde_core/1.0.228 \ + crate://crates.io/serde_derive/1.0.228 \ + crate://crates.io/serde_json/1.0.149 \ + crate://crates.io/serde_path_to_error/0.1.20 \ + crate://crates.io/serde_urlencoded/0.7.1 \ + crate://crates.io/sha1/0.10.6 \ + crate://crates.io/sha1_smol/1.0.1 \ + crate://crates.io/sha2/0.10.9 \ + crate://crates.io/sharded-slab/0.1.7 \ + crate://crates.io/shlex/1.3.0 \ + crate://crates.io/signal-hook/0.3.18 \ + crate://crates.io/signal-hook-registry/1.4.8 \ + crate://crates.io/signature/2.2.0 \ + crate://crates.io/simd-adler32/0.3.9 \ + crate://crates.io/simple_asn1/0.6.4 \ + crate://crates.io/siphasher/1.0.2 \ + crate://crates.io/slab/0.4.12 \ + crate://crates.io/smallstr/0.2.0 \ + crate://crates.io/smallvec/1.15.1 \ + crate://crates.io/smart-default/0.7.1 \ + crate://crates.io/smawk/0.3.2 \ + crate://crates.io/socket2/0.5.10 \ + crate://crates.io/socket2/0.6.3 \ + crate://crates.io/spin/0.9.8 \ + crate://crates.io/spki/0.7.3 \ + crate://crates.io/sqlparser/0.16.0 \ + crate://crates.io/stable_deref_trait/1.2.1 \ + crate://crates.io/strsim/0.11.1 \ + crate://crates.io/subtle/2.6.1 \ + crate://crates.io/syn/1.0.109 \ + crate://crates.io/syn/2.0.117 \ + crate://crates.io/sync_wrapper/0.1.2 \ + crate://crates.io/sync_wrapper/1.0.2 \ + crate://crates.io/synstructure/0.13.2 \ + crate://crates.io/synthez/0.3.1 \ + crate://crates.io/synthez-codegen/0.3.1 \ + crate://crates.io/synthez-core/0.3.1 \ + crate://crates.io/tempfile/3.27.0 \ + crate://crates.io/terminal_size/0.4.4 \ + crate://crates.io/terminfo/0.8.0 \ + crate://crates.io/textwrap/0.16.2 \ + crate://crates.io/thiserror/1.0.69 \ + crate://crates.io/thiserror/2.0.18 \ + crate://crates.io/thiserror-impl/1.0.69 \ + crate://crates.io/thiserror-impl/2.0.18 \ + crate://crates.io/thread_local/1.1.9 \ + crate://crates.io/time/0.3.47 \ + crate://crates.io/time-core/0.1.8 \ + crate://crates.io/time-macros/0.2.27 \ + crate://crates.io/tinystr/0.8.2 \ + crate://crates.io/tinyvec/1.11.0 \ + crate://crates.io/tinyvec_macros/0.1.1 \ + crate://crates.io/tokio/1.50.0 \ + crate://crates.io/tokio-io-timeout/1.2.1 \ + crate://crates.io/tokio-macros/2.6.1 \ + crate://crates.io/tokio-rustls/0.26.4 \ + crate://crates.io/tokio-stream/0.1.18 \ + crate://crates.io/tokio-tungstenite/0.20.1 \ + crate://crates.io/tokio-util/0.7.18 \ + crate://crates.io/tonic/0.8.3 \ + crate://crates.io/tonic/0.14.5 \ + crate://crates.io/tonic-build/0.14.5 \ + crate://crates.io/tonic-prost/0.14.5 \ + crate://crates.io/tonic-prost-build/0.14.5 \ + crate://crates.io/tonic-reflection/0.14.5 \ + crate://crates.io/tower/0.4.13 \ + crate://crates.io/tower/0.5.3 \ + crate://crates.io/tower-layer/0.3.3 \ + crate://crates.io/tower-service/0.3.3 \ + crate://crates.io/tracing/0.1.44 \ + crate://crates.io/tracing-attributes/0.1.31 \ + crate://crates.io/tracing-core/0.1.36 \ + crate://crates.io/tracing-futures/0.2.5 \ + crate://crates.io/tracing-log/0.1.4 \ + crate://crates.io/tracing-opentelemetry/0.19.0 \ + crate://crates.io/tracing-subscriber/0.3.23 \ + crate://crates.io/try-lock/0.2.5 \ + crate://crates.io/tungstenite/0.20.1 \ + crate://crates.io/typed-builder/0.15.2 \ + crate://crates.io/typed-builder-macro/0.15.2 \ + crate://crates.io/typenum/1.19.0 \ + crate://crates.io/unicode-bom/2.0.3 \ + crate://crates.io/unicode-ident/1.0.24 \ + crate://crates.io/unicode-linebreak/0.1.5 \ + crate://crates.io/unicode-normalization/0.1.25 \ + crate://crates.io/unicode-width/0.1.14 \ + crate://crates.io/unicode-width/0.2.2 \ + crate://crates.io/unicode-xid/0.2.6 \ + crate://crates.io/untrusted/0.9.0 \ + crate://crates.io/url/2.5.8 \ + crate://crates.io/urlencoding/2.1.3 \ + crate://crates.io/utf-8/0.7.6 \ + crate://crates.io/utf8_iter/1.0.4 \ + crate://crates.io/utf8parse/0.2.2 \ + crate://crates.io/uuid/1.23.0 \ + crate://crates.io/valuable/0.1.1 \ + crate://crates.io/vergen/8.3.2 \ + crate://crates.io/version_check/0.9.5 \ + crate://crates.io/walkdir/2.5.0 \ + crate://crates.io/want/0.3.1 \ + crate://crates.io/wasi/0.9.0+wasi-snapshot-preview1 \ + crate://crates.io/wasi/0.11.1+wasi-snapshot-preview1 \ + crate://crates.io/wasip2/1.0.2+wasi-0.2.9 \ + crate://crates.io/wasip3/0.4.0+wasi-0.3.0-rc-2026-01-06 \ + crate://crates.io/wasm-bindgen/0.2.117 \ + crate://crates.io/wasm-bindgen-macro/0.2.117 \ + crate://crates.io/wasm-bindgen-macro-support/0.2.117 \ + crate://crates.io/wasm-bindgen-shared/0.2.117 \ + crate://crates.io/wasm-encoder/0.244.0 \ + crate://crates.io/wasm-metadata/0.244.0 \ + crate://crates.io/wasmparser/0.244.0 \ + crate://crates.io/winapi/0.3.9 \ + crate://crates.io/winapi-i686-pc-windows-gnu/0.4.0 \ + crate://crates.io/winapi-util/0.1.11 \ + crate://crates.io/winapi-x86_64-pc-windows-gnu/0.4.0 \ + crate://crates.io/windows-core/0.62.2 \ + crate://crates.io/windows-implement/0.60.2 \ + crate://crates.io/windows-interface/0.59.3 \ + crate://crates.io/windows-link/0.2.1 \ + crate://crates.io/windows-result/0.4.1 \ + crate://crates.io/windows-strings/0.5.1 \ + crate://crates.io/windows-sys/0.52.0 \ + crate://crates.io/windows-sys/0.59.0 \ + crate://crates.io/windows-sys/0.61.2 \ + crate://crates.io/windows-targets/0.52.6 \ + crate://crates.io/windows_aarch64_gnullvm/0.52.6 \ + crate://crates.io/windows_aarch64_msvc/0.52.6 \ + crate://crates.io/windows_i686_gnu/0.52.6 \ + crate://crates.io/windows_i686_gnullvm/0.52.6 \ + crate://crates.io/windows_i686_msvc/0.52.6 \ + crate://crates.io/windows_x86_64_gnu/0.52.6 \ + crate://crates.io/windows_x86_64_gnullvm/0.52.6 \ + crate://crates.io/windows_x86_64_msvc/0.52.6 \ + crate://crates.io/winnow/0.6.26 \ + crate://crates.io/wit-bindgen/0.51.0 \ + crate://crates.io/wit-bindgen-core/0.51.0 \ + crate://crates.io/wit-bindgen-rust/0.51.0 \ + crate://crates.io/wit-bindgen-rust-macro/0.51.0 \ + crate://crates.io/wit-component/0.244.0 \ + crate://crates.io/wit-parser/0.244.0 \ + crate://crates.io/writeable/0.6.2 \ + crate://crates.io/yoke/0.8.1 \ + crate://crates.io/yoke-derive/0.8.1 \ + crate://crates.io/zerocopy/0.8.48 \ + crate://crates.io/zerocopy-derive/0.8.48 \ + crate://crates.io/zerofrom/0.1.6 \ + crate://crates.io/zerofrom-derive/0.1.6 \ + crate://crates.io/zeroize/1.8.2 \ + crate://crates.io/zerotrie/0.2.3 \ + crate://crates.io/zerovec/0.11.5 \ + crate://crates.io/zerovec-derive/0.11.2 \ + crate://crates.io/zmij/1.0.21 \ +" + +SRC_URI[adler2-2.0.1.sha256sum] = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +SRC_URI[ahash-0.8.12.sha256sum] = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +SRC_URI[aho-corasick-1.1.4.sha256sum] = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +SRC_URI[allocator-api2-0.2.21.sha256sum] = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +SRC_URI[android_system_properties-0.1.5.sha256sum] = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +SRC_URI[ansi_term-0.12.1.sha256sum] = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +SRC_URI[anstream-1.0.0.sha256sum] = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +SRC_URI[anstyle-1.0.14.sha256sum] = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" +SRC_URI[anstyle-parse-1.0.0.sha256sum] = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +SRC_URI[anstyle-query-1.1.5.sha256sum] = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +SRC_URI[anstyle-wincon-3.0.11.sha256sum] = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +SRC_URI[anyhow-1.0.102.sha256sum] = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +SRC_URI[arc-swap-1.9.0.sha256sum] = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" +SRC_URI[arrayref-0.3.9.sha256sum] = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +SRC_URI[arrayvec-0.5.2.sha256sum] = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +SRC_URI[async-stream-0.3.6.sha256sum] = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +SRC_URI[async-stream-impl-0.3.6.sha256sum] = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +SRC_URI[async-trait-0.1.89.sha256sum] = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +SRC_URI[atomic-waker-1.1.2.sha256sum] = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +SRC_URI[autocfg-1.5.0.sha256sum] = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +SRC_URI[axum-0.6.20.sha256sum] = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +SRC_URI[axum-0.8.8.sha256sum] = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +SRC_URI[axum-core-0.3.4.sha256sum] = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +SRC_URI[axum-core-0.5.6.sha256sum] = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +SRC_URI[base16ct-0.2.0.sha256sum] = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +SRC_URI[base64-0.13.1.sha256sum] = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +SRC_URI[base64-0.21.7.sha256sum] = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +SRC_URI[base64-0.22.1.sha256sum] = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +SRC_URI[base64ct-1.8.3.sha256sum] = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +SRC_URI[bitflags-1.3.2.sha256sum] = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +SRC_URI[bitflags-2.11.0.sha256sum] = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +SRC_URI[blake2b_simd-0.5.11.sha256sum] = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +SRC_URI[block-buffer-0.10.4.sha256sum] = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +SRC_URI[bstr-1.12.1.sha256sum] = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +SRC_URI[bumpalo-3.20.2.sha256sum] = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +SRC_URI[bytecount-0.6.9.sha256sum] = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" +SRC_URI[byteorder-1.5.0.sha256sum] = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +SRC_URI[bytes-1.11.1.sha256sum] = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +SRC_URI[camino-1.2.2.sha256sum] = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +SRC_URI[cargo-platform-0.1.9.sha256sum] = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +SRC_URI[cargo_metadata-0.18.1.sha256sum] = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +SRC_URI[cc-1.2.58.sha256sum] = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +SRC_URI[cfg-if-1.0.4.sha256sum] = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +SRC_URI[chrono-0.4.44.sha256sum] = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +SRC_URI[clap-4.6.0.sha256sum] = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +SRC_URI[clap_builder-4.6.0.sha256sum] = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +SRC_URI[clap_derive-4.6.0.sha256sum] = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +SRC_URI[clap_lex-1.1.0.sha256sum] = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +SRC_URI[clru-0.6.3.sha256sum] = "197fd99cb113a8d5d9b6376f3aa817f32c1078f2343b714fff7d2ca44fdf67d5" +SRC_URI[colorchoice-1.0.5.sha256sum] = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +SRC_URI[console-0.15.11.sha256sum] = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +SRC_URI[const-oid-0.9.6.sha256sum] = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +SRC_URI[constant_time_eq-0.1.5.sha256sum] = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +SRC_URI[core-foundation-sys-0.8.7.sha256sum] = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +SRC_URI[cpufeatures-0.2.17.sha256sum] = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +SRC_URI[crc32fast-1.5.0.sha256sum] = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +SRC_URI[crossbeam-channel-0.5.15.sha256sum] = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +SRC_URI[crossbeam-deque-0.8.6.sha256sum] = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +SRC_URI[crossbeam-epoch-0.9.18.sha256sum] = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +SRC_URI[crossbeam-utils-0.8.21.sha256sum] = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +SRC_URI[crypto-bigint-0.5.5.sha256sum] = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +SRC_URI[crypto-common-0.1.6.sha256sum] = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +SRC_URI[cucumber-0.20.2.sha256sum] = "8e5063d8cf24f4998ad01cac265da468a15ca682a8f4f826d50e661964e8d9b8" +SRC_URI[cucumber-codegen-0.20.2.sha256sum] = "01091e28d1f566c8b31b67948399d2efd6c0a8f6228a9785519ed7b73f7f0aef" +SRC_URI[cucumber-expressions-0.3.0.sha256sum] = "d794fed319eea24246fb5f57632f7ae38d61195817b7eb659455aa5bdd7c1810" +SRC_URI[curve25519-dalek-4.1.3.sha256sum] = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +SRC_URI[curve25519-dalek-derive-0.1.1.sha256sum] = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +SRC_URI[dashmap-5.5.3.sha256sum] = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +SRC_URI[data-encoding-2.10.0.sha256sum] = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +SRC_URI[der-0.7.10.sha256sum] = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +SRC_URI[deranged-0.5.8.sha256sum] = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +SRC_URI[derive_more-0.99.20.sha256sum] = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +SRC_URI[digest-0.10.7.sha256sum] = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +SRC_URI[dirs-1.0.5.sha256sum] = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +SRC_URI[dirs-4.0.0.sha256sum] = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +SRC_URI[dirs-sys-0.3.7.sha256sum] = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +SRC_URI[displaydoc-0.2.5.sha256sum] = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +SRC_URI[drain_filter_polyfill-0.1.3.sha256sum] = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" +SRC_URI[dunce-1.0.5.sha256sum] = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +SRC_URI[ecdsa-0.16.9.sha256sum] = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +SRC_URI[ed25519-2.2.3.sha256sum] = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +SRC_URI[ed25519-dalek-2.2.0.sha256sum] = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +SRC_URI[either-1.15.0.sha256sum] = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +SRC_URI[elliptic-curve-0.13.8.sha256sum] = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +SRC_URI[encode_unicode-1.0.0.sha256sum] = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +SRC_URI[env_filter-1.0.1.sha256sum] = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +SRC_URI[env_logger-0.11.10.sha256sum] = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +SRC_URI[equivalent-1.0.2.sha256sum] = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +SRC_URI[errno-0.3.14.sha256sum] = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +SRC_URI[faster-hex-0.9.0.sha256sum] = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" +SRC_URI[fastrand-2.3.0.sha256sum] = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +SRC_URI[ff-0.13.1.sha256sum] = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +SRC_URI[fiat-crypto-0.2.9.sha256sum] = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +SRC_URI[filetime-0.2.27.sha256sum] = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +SRC_URI[find-msvc-tools-0.1.9.sha256sum] = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +SRC_URI[fixedbitset-0.5.7.sha256sum] = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +SRC_URI[flate2-1.1.9.sha256sum] = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +SRC_URI[fnv-1.0.7.sha256sum] = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +SRC_URI[foldhash-0.1.5.sha256sum] = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +SRC_URI[foldhash-0.2.0.sha256sum] = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +SRC_URI[form_urlencoded-1.2.2.sha256sum] = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +SRC_URI[futures-0.3.32.sha256sum] = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +SRC_URI[futures-channel-0.3.32.sha256sum] = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +SRC_URI[futures-core-0.3.32.sha256sum] = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +SRC_URI[futures-executor-0.3.32.sha256sum] = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +SRC_URI[futures-io-0.3.32.sha256sum] = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +SRC_URI[futures-macro-0.3.32.sha256sum] = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +SRC_URI[futures-sink-0.3.32.sha256sum] = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +SRC_URI[futures-task-0.3.32.sha256sum] = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +SRC_URI[futures-util-0.3.32.sha256sum] = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +SRC_URI[generic-array-0.14.9.sha256sum] = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +SRC_URI[getrandom-0.1.16.sha256sum] = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +SRC_URI[getrandom-0.2.17.sha256sum] = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +SRC_URI[getrandom-0.4.2.sha256sum] = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +SRC_URI[gherkin-0.14.0.sha256sum] = "20b79820c0df536d1f3a089a2fa958f61cb96ce9e0f3f8f507f5a31179567755" +SRC_URI[gix-0.63.0.sha256sum] = "984c5018adfa7a4536ade67990b3ebc6e11ab57b3d6cd9968de0947ca99b4b06" +SRC_URI[gix-actor-0.31.5.sha256sum] = "a0e454357e34b833cc3a00b6efbbd3dd4d18b24b9fb0c023876ec2645e8aa3f2" +SRC_URI[gix-bitmap-0.2.16.sha256sum] = "d982fc7ef0608e669851d0d2a6141dae74c60d5a27e8daa451f2a4857bbf41e2" +SRC_URI[gix-chunk-0.4.12.sha256sum] = "5c356b3825677cb6ff579551bb8311a81821e184453cbd105e2fc5311b288eeb" +SRC_URI[gix-commitgraph-0.24.3.sha256sum] = "133b06f67f565836ec0c473e2116a60fb74f80b6435e21d88013ac0e3c60fc78" +SRC_URI[gix-config-0.37.0.sha256sum] = "53fafe42957e11d98e354a66b6bd70aeea00faf2f62dd11164188224a507c840" +SRC_URI[gix-config-value-0.14.12.sha256sum] = "8dc2c844c4cf141884678cabef736fd91dd73068b9146e6f004ba1a0457944b6" +SRC_URI[gix-date-0.8.7.sha256sum] = "9eed6931f21491ee0aeb922751bd7ec97b4b2fe8fbfedcb678e2a2dce5f3b8c0" +SRC_URI[gix-diff-0.44.1.sha256sum] = "1996d5c8a305b59709467d80617c9fde48d9d75fd1f4179ea970912630886c9d" +SRC_URI[gix-discover-0.32.0.sha256sum] = "fc27c699b63da66b50d50c00668bc0b7e90c3a382ef302865e891559935f3dbf" +SRC_URI[gix-features-0.38.2.sha256sum] = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" +SRC_URI[gix-fs-0.11.3.sha256sum] = "f2bfe6249cfea6d0c0e0990d5226a4cb36f030444ba9e35e0639275db8f98575" +SRC_URI[gix-glob-0.16.5.sha256sum] = "74908b4bbc0a0a40852737e5d7889f676f081e340d5451a16e5b4c50d592f111" +SRC_URI[gix-hash-0.14.2.sha256sum] = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" +SRC_URI[gix-hashtable-0.5.2.sha256sum] = "7ddf80e16f3c19ac06ce415a38b8591993d3f73aede049cb561becb5b3a8e242" +SRC_URI[gix-index-0.33.1.sha256sum] = "9a9a44eb55bd84bb48f8a44980e951968ced21e171b22d115d1cdcef82a7d73f" +SRC_URI[gix-lock-14.0.0.sha256sum] = "e3bc7fe297f1f4614774989c00ec8b1add59571dc9b024b4c00acb7dedd4e19d" +SRC_URI[gix-macros-0.1.5.sha256sum] = "999ce923619f88194171a67fb3e6d613653b8d4d6078b529b15a765da0edcc17" +SRC_URI[gix-object-0.42.3.sha256sum] = "25da2f46b4e7c2fa7b413ce4dffb87f69eaf89c2057e386491f4c55cadbfe386" +SRC_URI[gix-odb-0.61.1.sha256sum] = "20d384fe541d93d8a3bb7d5d5ef210780d6df4f50c4e684ccba32665a5e3bc9b" +SRC_URI[gix-pack-0.51.1.sha256sum] = "3e0594491fffe55df94ba1c111a6566b7f56b3f8d2e1efc750e77d572f5f5229" +SRC_URI[gix-path-0.10.22.sha256sum] = "7cb06c3e4f8eed6e24fd915fa93145e28a511f4ea0e768bae16673e05ed3f366" +SRC_URI[gix-quote-0.4.15.sha256sum] = "e49357fccdb0c85c0d3a3292a9f6db32d9b3535959b5471bb9624908f4a066c6" +SRC_URI[gix-ref-0.44.1.sha256sum] = "3394a2997e5bc6b22ebc1e1a87b41eeefbcfcff3dbfa7c4bd73cb0ac8f1f3e2e" +SRC_URI[gix-refspec-0.23.1.sha256sum] = "6868f8cd2e62555d1f7c78b784bece43ace40dd2a462daf3b588d5416e603f37" +SRC_URI[gix-revision-0.27.2.sha256sum] = "01b13e43c2118c4b0537ddac7d0821ae0dfa90b7b8dbf20c711e153fb749adce" +SRC_URI[gix-revwalk-0.13.2.sha256sum] = "1b030ccaab71af141f537e0225f19b9e74f25fefdba0372246b844491cab43e0" +SRC_URI[gix-sec-0.10.12.sha256sum] = "47aeb0f13de9ef2f3033f5ff218de30f44db827ac9f1286f9ef050aacddd5888" +SRC_URI[gix-tempfile-14.0.2.sha256sum] = "046b4927969fa816a150a0cda2e62c80016fe11fb3c3184e4dddf4e542f108aa" +SRC_URI[gix-trace-0.1.18.sha256sum] = "f69a13643b8437d4ca6845e08143e847a36ca82903eed13303475d0ae8b162e0" +SRC_URI[gix-traverse-0.39.2.sha256sum] = "e499a18c511e71cf4a20413b743b9f5bcf64b3d9e81e9c3c6cd399eae55a8840" +SRC_URI[gix-url-0.27.5.sha256sum] = "fd280c5e84fb22e128ed2a053a0daeacb6379469be6a85e3d518a0636e160c89" +SRC_URI[gix-utils-0.1.14.sha256sum] = "ff08f24e03ac8916c478c8419d7d3c33393da9bb41fa4c24455d5406aeefd35f" +SRC_URI[gix-validate-0.8.5.sha256sum] = "82c27dd34a49b1addf193c92070bcbf3beaf6e10f16a78544de6372e146a0acf" +SRC_URI[gix-validate-0.10.1.sha256sum] = "5b1e63a5b516e970a594f870ed4571a8fdcb8a344e7bd407a20db8bd61dbfde4" +SRC_URI[glob-match-0.2.1.sha256sum] = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" +SRC_URI[globset-0.4.18.sha256sum] = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +SRC_URI[globwalk-0.8.1.sha256sum] = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +SRC_URI[group-0.13.0.sha256sum] = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +SRC_URI[h2-0.3.27.sha256sum] = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +SRC_URI[h2-0.4.13.sha256sum] = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +SRC_URI[hashbrown-0.12.3.sha256sum] = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +SRC_URI[hashbrown-0.14.5.sha256sum] = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +SRC_URI[hashbrown-0.15.5.sha256sum] = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +SRC_URI[hashbrown-0.16.1.sha256sum] = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +SRC_URI[heck-0.4.1.sha256sum] = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +SRC_URI[heck-0.5.0.sha256sum] = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +SRC_URI[hkdf-0.12.4.sha256sum] = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +SRC_URI[hmac-0.12.1.sha256sum] = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +SRC_URI[home-0.5.12.sha256sum] = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +SRC_URI[http-0.2.12.sha256sum] = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +SRC_URI[http-1.4.0.sha256sum] = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +SRC_URI[http-body-0.4.6.sha256sum] = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +SRC_URI[http-body-1.0.1.sha256sum] = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +SRC_URI[http-body-util-0.1.3.sha256sum] = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +SRC_URI[httparse-1.10.1.sha256sum] = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +SRC_URI[httpdate-1.0.3.sha256sum] = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +SRC_URI[humantime-2.3.0.sha256sum] = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +SRC_URI[hyper-0.14.32.sha256sum] = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +SRC_URI[hyper-1.9.0.sha256sum] = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +SRC_URI[hyper-timeout-0.4.1.sha256sum] = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +SRC_URI[hyper-timeout-0.5.2.sha256sum] = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +SRC_URI[hyper-util-0.1.20.sha256sum] = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +SRC_URI[iana-time-zone-0.1.65.sha256sum] = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +SRC_URI[iana-time-zone-haiku-0.1.2.sha256sum] = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +SRC_URI[icu_collections-2.1.1.sha256sum] = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +SRC_URI[icu_locale_core-2.1.1.sha256sum] = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +SRC_URI[icu_normalizer-2.1.1.sha256sum] = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +SRC_URI[icu_normalizer_data-2.1.1.sha256sum] = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +SRC_URI[icu_properties-2.1.2.sha256sum] = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +SRC_URI[icu_properties_data-2.1.2.sha256sum] = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +SRC_URI[icu_provider-2.1.1.sha256sum] = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +SRC_URI[id-arena-2.3.0.sha256sum] = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +SRC_URI[idna-1.1.0.sha256sum] = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +SRC_URI[idna_adapter-1.2.1.sha256sum] = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +SRC_URI[ignore-0.4.25.sha256sum] = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +SRC_URI[indexmap-1.9.3.sha256sum] = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +SRC_URI[indexmap-2.13.0.sha256sum] = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +SRC_URI[inflections-1.1.1.sha256sum] = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" +SRC_URI[inventory-0.3.24.sha256sum] = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" +SRC_URI[is_terminal_polyfill-1.70.2.sha256sum] = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +SRC_URI[itertools-0.10.5.sha256sum] = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +SRC_URI[itertools-0.12.1.sha256sum] = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +SRC_URI[itertools-0.14.0.sha256sum] = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +SRC_URI[itoa-1.0.18.sha256sum] = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +SRC_URI[jemalloc-sys-0.5.4+5.3.0-patched.sha256sum] = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" +SRC_URI[jemallocator-0.5.4.sha256sum] = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" +SRC_URI[jiff-0.2.23.sha256sum] = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +SRC_URI[jiff-static-0.2.23.sha256sum] = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +SRC_URI[js-sys-0.3.94.sha256sum] = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +SRC_URI[jsonwebtoken-10.3.0.sha256sum] = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" +SRC_URI[lazy-regex-3.6.0.sha256sum] = "6bae91019476d3ec7147de9aa291cadb6d870abf2f3015d2da73a90325ac1496" +SRC_URI[lazy-regex-proc_macros-3.6.0.sha256sum] = "4de9c1e1439d8b7b3061b2d209809f447ca33241733d9a3c01eabf2dc8d94358" +SRC_URI[lazy_static-1.5.0.sha256sum] = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +SRC_URI[leb128fmt-0.1.0.sha256sum] = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +SRC_URI[libc-0.2.183.sha256sum] = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +SRC_URI[libm-0.2.16.sha256sum] = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +SRC_URI[libredox-0.1.15.sha256sum] = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" +SRC_URI[linefeed-0.6.0.sha256sum] = "28715d08e35c6c074f9ae6b2e6a2420bac75d050c66ecd669d7d5b98e2caa036" +SRC_URI[linked-hash-map-0.5.6.sha256sum] = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +SRC_URI[linux-raw-sys-0.4.15.sha256sum] = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +SRC_URI[linux-raw-sys-0.12.1.sha256sum] = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +SRC_URI[litemap-0.8.1.sha256sum] = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +SRC_URI[lock_api-0.4.14.sha256sum] = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +SRC_URI[log-0.4.29.sha256sum] = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +SRC_URI[matchers-0.2.0.sha256sum] = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +SRC_URI[matchit-0.7.3.sha256sum] = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +SRC_URI[matchit-0.8.4.sha256sum] = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +SRC_URI[memchr-2.8.0.sha256sum] = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +SRC_URI[memmap2-0.9.10.sha256sum] = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +SRC_URI[mime-0.3.17.sha256sum] = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +SRC_URI[minimal-lexical-0.2.1.sha256sum] = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +SRC_URI[miniz_oxide-0.8.9.sha256sum] = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +SRC_URI[mio-1.2.0.sha256sum] = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +SRC_URI[mortal-0.2.4.sha256sum] = "2c624fa1b7aab6bd2aff6e9b18565cc0363b6d45cbcd7465c9ed5e3740ebf097" +SRC_URI[multimap-0.10.1.sha256sum] = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" +SRC_URI[nix-0.26.4.sha256sum] = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +SRC_URI[nom-7.1.3.sha256sum] = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +SRC_URI[nom_locate-4.2.0.sha256sum] = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" +SRC_URI[nu-ansi-term-0.50.3.sha256sum] = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +SRC_URI[num-bigint-0.4.6.sha256sum] = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +SRC_URI[num-bigint-dig-0.8.6.sha256sum] = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +SRC_URI[num-conv-0.2.1.sha256sum] = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +SRC_URI[num-integer-0.1.46.sha256sum] = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +SRC_URI[num-iter-0.1.45.sha256sum] = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +SRC_URI[num-traits-0.2.19.sha256sum] = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +SRC_URI[num_threads-0.1.7.sha256sum] = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +SRC_URI[once_cell-1.21.4.sha256sum] = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +SRC_URI[once_cell_polyfill-1.70.2.sha256sum] = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +SRC_URI[opentelemetry-0.19.0.sha256sum] = "5f4b8347cc26099d3aeee044065ecc3ae11469796b4d65d065a23a584ed92a6f" +SRC_URI[opentelemetry-otlp-0.12.0.sha256sum] = "8af72d59a4484654ea8eb183fea5ae4eb6a41d7ac3e3bae5f4d2a282a3a7d3ca" +SRC_URI[opentelemetry-proto-0.2.0.sha256sum] = "045f8eea8c0fa19f7d48e7bc3128a39c2e5c533d5c61298c548dfefc1064474c" +SRC_URI[opentelemetry-semantic-conventions-0.11.0.sha256sum] = "24e33428e6bf08c6f7fcea4ddb8e358fab0fe48ab877a87c70c6ebe20f673ce5" +SRC_URI[opentelemetry_api-0.19.0.sha256sum] = "ed41783a5bf567688eb38372f2b7a8530f5a607a4b49d38dd7573236c23ca7e2" +SRC_URI[opentelemetry_sdk-0.19.0.sha256sum] = "8b3a2a91fdbfdd4d212c0dcc2ab540de2c2bcbbd90be17de7a7daf8822d010c1" +SRC_URI[p256-0.13.2.sha256sum] = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +SRC_URI[p384-0.13.1.sha256sum] = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +SRC_URI[parking_lot-0.12.5.sha256sum] = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +SRC_URI[parking_lot_core-0.9.12.sha256sum] = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +SRC_URI[peg-0.6.3.sha256sum] = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367" +SRC_URI[peg-macros-0.6.3.sha256sum] = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d" +SRC_URI[peg-runtime-0.6.3.sha256sum] = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" +SRC_URI[pem-3.0.6.sha256sum] = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +SRC_URI[pem-rfc7468-0.7.0.sha256sum] = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +SRC_URI[percent-encoding-2.3.2.sha256sum] = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +SRC_URI[petgraph-0.8.3.sha256sum] = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +SRC_URI[phf-0.11.3.sha256sum] = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +SRC_URI[phf_codegen-0.11.3.sha256sum] = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +SRC_URI[phf_generator-0.11.3.sha256sum] = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +SRC_URI[phf_shared-0.11.3.sha256sum] = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +SRC_URI[pin-project-1.1.11.sha256sum] = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +SRC_URI[pin-project-internal-1.1.11.sha256sum] = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +SRC_URI[pin-project-lite-0.2.17.sha256sum] = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +SRC_URI[pkcs1-0.7.5.sha256sum] = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +SRC_URI[pkcs8-0.10.2.sha256sum] = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +SRC_URI[plain-0.2.3.sha256sum] = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +SRC_URI[portable-atomic-1.13.1.sha256sum] = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +SRC_URI[portable-atomic-util-0.2.6.sha256sum] = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +SRC_URI[potential_utf-0.1.4.sha256sum] = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +SRC_URI[powerfmt-0.2.0.sha256sum] = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +SRC_URI[ppv-lite86-0.2.21.sha256sum] = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +SRC_URI[prettyplease-0.2.37.sha256sum] = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +SRC_URI[primeorder-0.13.6.sha256sum] = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +SRC_URI[proc-macro2-1.0.106.sha256sum] = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +SRC_URI[prodash-28.0.0.sha256sum] = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" +SRC_URI[prost-0.11.9.sha256sum] = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +SRC_URI[prost-0.14.3.sha256sum] = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +SRC_URI[prost-build-0.14.3.sha256sum] = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +SRC_URI[prost-derive-0.11.9.sha256sum] = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +SRC_URI[prost-derive-0.14.3.sha256sum] = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +SRC_URI[prost-types-0.14.3.sha256sum] = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +SRC_URI[quote-1.0.45.sha256sum] = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +SRC_URI[r-efi-6.0.0.sha256sum] = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +SRC_URI[rand-0.8.5.sha256sum] = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +SRC_URI[rand_chacha-0.3.1.sha256sum] = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +SRC_URI[rand_core-0.6.4.sha256sum] = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +SRC_URI[redox_syscall-0.1.57.sha256sum] = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +SRC_URI[redox_syscall-0.5.18.sha256sum] = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +SRC_URI[redox_syscall-0.7.3.sha256sum] = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +SRC_URI[redox_users-0.3.5.sha256sum] = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +SRC_URI[redox_users-0.4.6.sha256sum] = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +SRC_URI[regex-1.12.3.sha256sum] = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +SRC_URI[regex-automata-0.4.14.sha256sum] = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +SRC_URI[regex-syntax-0.7.5.sha256sum] = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +SRC_URI[regex-syntax-0.8.10.sha256sum] = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +SRC_URI[rfc6979-0.4.0.sha256sum] = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +SRC_URI[ring-0.17.14.sha256sum] = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +SRC_URI[rsa-0.9.10.sha256sum] = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +SRC_URI[rust-argon2-0.8.3.sha256sum] = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +SRC_URI[rustc_version-0.4.1.sha256sum] = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +SRC_URI[rustix-0.38.44.sha256sum] = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +SRC_URI[rustix-1.1.4.sha256sum] = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +SRC_URI[rustls-0.23.37.sha256sum] = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +SRC_URI[rustls-pki-types-1.14.0.sha256sum] = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +SRC_URI[rustls-webpki-0.103.10.sha256sum] = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +SRC_URI[rustversion-1.0.22.sha256sum] = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +SRC_URI[ryu-1.0.23.sha256sum] = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +SRC_URI[same-file-1.0.6.sha256sum] = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +SRC_URI[scopeguard-1.2.0.sha256sum] = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +SRC_URI[sd-notify-0.4.5.sha256sum] = "b943eadf71d8b69e661330cb0e2656e31040acf21ee7708e2c238a0ec6af2bf4" +SRC_URI[sealed-0.5.0.sha256sum] = "f4a8caec23b7800fb97971a1c6ae365b6239aaeddfb934d6265f8505e795699d" +SRC_URI[sec1-0.7.3.sha256sum] = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +SRC_URI[semver-1.0.27.sha256sum] = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +SRC_URI[serde-1.0.228.sha256sum] = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +SRC_URI[serde_core-1.0.228.sha256sum] = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +SRC_URI[serde_derive-1.0.228.sha256sum] = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +SRC_URI[serde_json-1.0.149.sha256sum] = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +SRC_URI[serde_path_to_error-0.1.20.sha256sum] = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +SRC_URI[serde_urlencoded-0.7.1.sha256sum] = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +SRC_URI[sha1-0.10.6.sha256sum] = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +SRC_URI[sha1_smol-1.0.1.sha256sum] = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" +SRC_URI[sha2-0.10.9.sha256sum] = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +SRC_URI[sharded-slab-0.1.7.sha256sum] = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +SRC_URI[shlex-1.3.0.sha256sum] = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +SRC_URI[signal-hook-0.3.18.sha256sum] = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +SRC_URI[signal-hook-registry-1.4.8.sha256sum] = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +SRC_URI[signature-2.2.0.sha256sum] = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +SRC_URI[simd-adler32-0.3.9.sha256sum] = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +SRC_URI[simple_asn1-0.6.4.sha256sum] = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d" +SRC_URI[siphasher-1.0.2.sha256sum] = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +SRC_URI[slab-0.4.12.sha256sum] = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +SRC_URI[smallstr-0.2.0.sha256sum] = "1e922794d168678729ffc7e07182721a14219c65814e66e91b839a272fe5ae4f" +SRC_URI[smallvec-1.15.1.sha256sum] = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +SRC_URI[smart-default-0.7.1.sha256sum] = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" +SRC_URI[smawk-0.3.2.sha256sum] = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +SRC_URI[socket2-0.5.10.sha256sum] = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +SRC_URI[socket2-0.6.3.sha256sum] = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +SRC_URI[spin-0.9.8.sha256sum] = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +SRC_URI[spki-0.7.3.sha256sum] = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +SRC_URI[sqlparser-0.16.0.sha256sum] = "7e9a527b68048eb95495a1508f6c8395c8defcff5ecdbe8ad4106d08a2ef2a3c" +SRC_URI[stable_deref_trait-1.2.1.sha256sum] = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +SRC_URI[strsim-0.11.1.sha256sum] = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +SRC_URI[subtle-2.6.1.sha256sum] = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +SRC_URI[syn-1.0.109.sha256sum] = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +SRC_URI[syn-2.0.117.sha256sum] = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +SRC_URI[sync_wrapper-0.1.2.sha256sum] = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +SRC_URI[sync_wrapper-1.0.2.sha256sum] = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +SRC_URI[synstructure-0.13.2.sha256sum] = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +SRC_URI[synthez-0.3.1.sha256sum] = "a3d2c2202510a1e186e63e596d9318c91a8cbe85cd1a56a7be0c333e5f59ec8d" +SRC_URI[synthez-codegen-0.3.1.sha256sum] = "f724aa6d44b7162f3158a57bccd871a77b39a4aef737e01bcdff41f4772c7746" +SRC_URI[synthez-core-0.3.1.sha256sum] = "78bfa6ec52465e2425fd43ce5bbbe0f0b623964f7c63feb6b10980e816c654ea" +SRC_URI[tempfile-3.27.0.sha256sum] = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +SRC_URI[terminal_size-0.4.4.sha256sum] = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" +SRC_URI[terminfo-0.8.0.sha256sum] = "666cd3a6681775d22b200409aad3b089c5b99fb11ecdd8a204d9d62f8148498f" +SRC_URI[textwrap-0.16.2.sha256sum] = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +SRC_URI[thiserror-1.0.69.sha256sum] = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +SRC_URI[thiserror-2.0.18.sha256sum] = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +SRC_URI[thiserror-impl-1.0.69.sha256sum] = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +SRC_URI[thiserror-impl-2.0.18.sha256sum] = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +SRC_URI[thread_local-1.1.9.sha256sum] = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +SRC_URI[time-0.3.47.sha256sum] = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +SRC_URI[time-core-0.1.8.sha256sum] = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +SRC_URI[time-macros-0.2.27.sha256sum] = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +SRC_URI[tinystr-0.8.2.sha256sum] = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +SRC_URI[tinyvec-1.11.0.sha256sum] = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +SRC_URI[tinyvec_macros-0.1.1.sha256sum] = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +SRC_URI[tokio-1.50.0.sha256sum] = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +SRC_URI[tokio-io-timeout-1.2.1.sha256sum] = "0bd86198d9ee903fedd2f9a2e72014287c0d9167e4ae43b5853007205dda1b76" +SRC_URI[tokio-macros-2.6.1.sha256sum] = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +SRC_URI[tokio-rustls-0.26.4.sha256sum] = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +SRC_URI[tokio-stream-0.1.18.sha256sum] = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +SRC_URI[tokio-tungstenite-0.20.1.sha256sum] = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +SRC_URI[tokio-util-0.7.18.sha256sum] = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +SRC_URI[tonic-0.8.3.sha256sum] = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +SRC_URI[tonic-0.14.5.sha256sum] = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +SRC_URI[tonic-build-0.14.5.sha256sum] = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +SRC_URI[tonic-prost-0.14.5.sha256sum] = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +SRC_URI[tonic-prost-build-0.14.5.sha256sum] = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +SRC_URI[tonic-reflection-0.14.5.sha256sum] = "aaf0685a51e6d02b502ba0764002e766b7f3042aed13d9234925b6ffbfa3fca7" +SRC_URI[tower-0.4.13.sha256sum] = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +SRC_URI[tower-0.5.3.sha256sum] = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +SRC_URI[tower-layer-0.3.3.sha256sum] = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" +SRC_URI[tower-service-0.3.3.sha256sum] = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +SRC_URI[tracing-0.1.44.sha256sum] = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +SRC_URI[tracing-attributes-0.1.31.sha256sum] = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +SRC_URI[tracing-core-0.1.36.sha256sum] = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +SRC_URI[tracing-futures-0.2.5.sha256sum] = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +SRC_URI[tracing-log-0.1.4.sha256sum] = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +SRC_URI[tracing-opentelemetry-0.19.0.sha256sum] = "00a39dcf9bfc1742fa4d6215253b33a6e474be78275884c216fc2a06267b3600" +SRC_URI[tracing-subscriber-0.3.23.sha256sum] = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +SRC_URI[try-lock-0.2.5.sha256sum] = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +SRC_URI[tungstenite-0.20.1.sha256sum] = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +SRC_URI[typed-builder-0.15.2.sha256sum] = "7fe83c85a85875e8c4cb9ce4a890f05b23d38cd0d47647db7895d3d2a79566d2" +SRC_URI[typed-builder-macro-0.15.2.sha256sum] = "29a3151c41d0b13e3d011f98adc24434560ef06673a155a6c7f66b9879eecce2" +SRC_URI[typenum-1.19.0.sha256sum] = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +SRC_URI[unicode-bom-2.0.3.sha256sum] = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" +SRC_URI[unicode-ident-1.0.24.sha256sum] = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +SRC_URI[unicode-linebreak-0.1.5.sha256sum] = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +SRC_URI[unicode-normalization-0.1.25.sha256sum] = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +SRC_URI[unicode-width-0.1.14.sha256sum] = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +SRC_URI[unicode-width-0.2.2.sha256sum] = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +SRC_URI[unicode-xid-0.2.6.sha256sum] = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +SRC_URI[untrusted-0.9.0.sha256sum] = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +SRC_URI[url-2.5.8.sha256sum] = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +SRC_URI[urlencoding-2.1.3.sha256sum] = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +SRC_URI[utf-8-0.7.6.sha256sum] = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +SRC_URI[utf8_iter-1.0.4.sha256sum] = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +SRC_URI[utf8parse-0.2.2.sha256sum] = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +SRC_URI[uuid-1.23.0.sha256sum] = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +SRC_URI[valuable-0.1.1.sha256sum] = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +SRC_URI[vergen-8.3.2.sha256sum] = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" +SRC_URI[version_check-0.9.5.sha256sum] = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +SRC_URI[walkdir-2.5.0.sha256sum] = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +SRC_URI[want-0.3.1.sha256sum] = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +SRC_URI[wasi-0.9.0+wasi-snapshot-preview1.sha256sum] = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +SRC_URI[wasi-0.11.1+wasi-snapshot-preview1.sha256sum] = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +SRC_URI[wasip2-1.0.2+wasi-0.2.9.sha256sum] = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +SRC_URI[wasip3-0.4.0+wasi-0.3.0-rc-2026-01-06.sha256sum] = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +SRC_URI[wasm-bindgen-0.2.117.sha256sum] = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +SRC_URI[wasm-bindgen-macro-0.2.117.sha256sum] = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +SRC_URI[wasm-bindgen-macro-support-0.2.117.sha256sum] = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +SRC_URI[wasm-bindgen-shared-0.2.117.sha256sum] = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +SRC_URI[wasm-encoder-0.244.0.sha256sum] = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +SRC_URI[wasm-metadata-0.244.0.sha256sum] = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +SRC_URI[wasmparser-0.244.0.sha256sum] = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +SRC_URI[winapi-0.3.9.sha256sum] = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +SRC_URI[winapi-i686-pc-windows-gnu-0.4.0.sha256sum] = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +SRC_URI[winapi-util-0.1.11.sha256sum] = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +SRC_URI[winapi-x86_64-pc-windows-gnu-0.4.0.sha256sum] = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +SRC_URI[windows-core-0.62.2.sha256sum] = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +SRC_URI[windows-implement-0.60.2.sha256sum] = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +SRC_URI[windows-interface-0.59.3.sha256sum] = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +SRC_URI[windows-link-0.2.1.sha256sum] = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +SRC_URI[windows-result-0.4.1.sha256sum] = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +SRC_URI[windows-strings-0.5.1.sha256sum] = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +SRC_URI[windows-sys-0.52.0.sha256sum] = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +SRC_URI[windows-sys-0.59.0.sha256sum] = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +SRC_URI[windows-sys-0.61.2.sha256sum] = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +SRC_URI[windows-targets-0.52.6.sha256sum] = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +SRC_URI[windows_aarch64_gnullvm-0.52.6.sha256sum] = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +SRC_URI[windows_aarch64_msvc-0.52.6.sha256sum] = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +SRC_URI[windows_i686_gnu-0.52.6.sha256sum] = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +SRC_URI[windows_i686_gnullvm-0.52.6.sha256sum] = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +SRC_URI[windows_i686_msvc-0.52.6.sha256sum] = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +SRC_URI[windows_x86_64_gnu-0.52.6.sha256sum] = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +SRC_URI[windows_x86_64_gnullvm-0.52.6.sha256sum] = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +SRC_URI[windows_x86_64_msvc-0.52.6.sha256sum] = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +SRC_URI[winnow-0.6.26.sha256sum] = "1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28" +SRC_URI[wit-bindgen-0.51.0.sha256sum] = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +SRC_URI[wit-bindgen-core-0.51.0.sha256sum] = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +SRC_URI[wit-bindgen-rust-0.51.0.sha256sum] = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +SRC_URI[wit-bindgen-rust-macro-0.51.0.sha256sum] = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +SRC_URI[wit-component-0.244.0.sha256sum] = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +SRC_URI[wit-parser-0.244.0.sha256sum] = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +SRC_URI[writeable-0.6.2.sha256sum] = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +SRC_URI[yoke-0.8.1.sha256sum] = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +SRC_URI[yoke-derive-0.8.1.sha256sum] = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +SRC_URI[zerocopy-0.8.48.sha256sum] = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +SRC_URI[zerocopy-derive-0.8.48.sha256sum] = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +SRC_URI[zerofrom-0.1.6.sha256sum] = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +SRC_URI[zerofrom-derive-0.1.6.sha256sum] = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +SRC_URI[zeroize-1.8.2.sha256sum] = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +SRC_URI[zerotrie-0.2.3.sha256sum] = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +SRC_URI[zerovec-0.11.5.sha256sum] = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +SRC_URI[zerovec-derive-0.11.2.sha256sum] = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +SRC_URI[zmij-1.0.21.sha256sum] = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +# from lib/Cargo.lock +SRC_URI += " \ + crate://crates.io/aho-corasick/1.1.4 \ + crate://crates.io/anstream/1.0.0 \ + crate://crates.io/anstyle/1.0.14 \ + crate://crates.io/anstyle-parse/1.0.0 \ + crate://crates.io/anstyle-query/1.1.5 \ + crate://crates.io/anstyle-wincon/3.0.11 \ + crate://crates.io/anyhow/1.0.102 \ + crate://crates.io/async-trait/0.1.89 \ + crate://crates.io/atomic-waker/1.1.2 \ + crate://crates.io/base64/0.22.1 \ + crate://crates.io/bitflags/2.11.0 \ + crate://crates.io/bytes/1.11.1 \ + crate://crates.io/cc/1.2.58 \ + crate://crates.io/cfg-if/1.0.4 \ + crate://crates.io/colorchoice/1.0.5 \ + crate://crates.io/either/1.15.0 \ + crate://crates.io/env_filter/1.0.1 \ + crate://crates.io/env_logger/0.11.10 \ + crate://crates.io/equivalent/1.0.2 \ + crate://crates.io/errno/0.3.14 \ + crate://crates.io/fastrand/2.3.0 \ + crate://crates.io/find-msvc-tools/0.1.9 \ + crate://crates.io/fixedbitset/0.5.7 \ + crate://crates.io/fnv/1.0.7 \ + crate://crates.io/foldhash/0.1.5 \ + crate://crates.io/futures-channel/0.3.32 \ + crate://crates.io/futures-core/0.3.32 \ + crate://crates.io/futures-sink/0.3.32 \ + crate://crates.io/futures-task/0.3.32 \ + crate://crates.io/futures-util/0.3.32 \ + crate://crates.io/getrandom/0.2.17 \ + crate://crates.io/getrandom/0.4.2 \ + crate://crates.io/h2/0.4.13 \ + crate://crates.io/hashbrown/0.15.5 \ + crate://crates.io/hashbrown/0.16.1 \ + crate://crates.io/heck/0.5.0 \ + crate://crates.io/http/1.4.0 \ + crate://crates.io/http-body/1.0.1 \ + crate://crates.io/http-body-util/0.1.3 \ + crate://crates.io/httparse/1.10.1 \ + crate://crates.io/httpdate/1.0.3 \ + crate://crates.io/hyper/1.9.0 \ + crate://crates.io/hyper-timeout/0.5.2 \ + crate://crates.io/hyper-util/0.1.20 \ + crate://crates.io/id-arena/2.3.0 \ + crate://crates.io/indexmap/2.13.0 \ + crate://crates.io/is_terminal_polyfill/1.70.2 \ + crate://crates.io/itertools/0.14.0 \ + crate://crates.io/itoa/1.0.18 \ + crate://crates.io/jiff/0.2.23 \ + crate://crates.io/jiff-static/0.2.23 \ + crate://crates.io/leb128fmt/0.1.0 \ + crate://crates.io/libc/0.2.183 \ + crate://crates.io/linux-raw-sys/0.12.1 \ + crate://crates.io/lock_api/0.4.14 \ + crate://crates.io/log/0.4.29 \ + crate://crates.io/memchr/2.8.0 \ + crate://crates.io/mio/1.2.0 \ + crate://crates.io/multimap/0.10.1 \ + crate://crates.io/once_cell/1.21.4 \ + crate://crates.io/once_cell_polyfill/1.70.2 \ + crate://crates.io/parking_lot/0.12.5 \ + crate://crates.io/parking_lot_core/0.9.12 \ + crate://crates.io/percent-encoding/2.3.2 \ + crate://crates.io/petgraph/0.8.3 \ + crate://crates.io/pin-project/1.1.11 \ + crate://crates.io/pin-project-internal/1.1.11 \ + crate://crates.io/pin-project-lite/0.2.17 \ + crate://crates.io/portable-atomic/1.13.1 \ + crate://crates.io/portable-atomic-util/0.2.6 \ + crate://crates.io/prettyplease/0.2.37 \ + crate://crates.io/proc-macro2/1.0.106 \ + crate://crates.io/prost/0.14.3 \ + crate://crates.io/prost-build/0.14.3 \ + crate://crates.io/prost-derive/0.14.3 \ + crate://crates.io/prost-types/0.14.3 \ + crate://crates.io/quote/1.0.45 \ + crate://crates.io/r-efi/6.0.0 \ + crate://crates.io/redox_syscall/0.5.18 \ + crate://crates.io/regex/1.12.3 \ + crate://crates.io/regex-automata/0.4.14 \ + crate://crates.io/regex-syntax/0.8.10 \ + crate://crates.io/ring/0.17.14 \ + crate://crates.io/rustix/1.1.4 \ + crate://crates.io/rustls/0.23.37 \ + crate://crates.io/rustls-pki-types/1.14.0 \ + crate://crates.io/rustls-webpki/0.103.10 \ + crate://crates.io/scopeguard/1.2.0 \ + crate://crates.io/semver/1.0.27 \ + crate://crates.io/serde/1.0.228 \ + crate://crates.io/serde_core/1.0.228 \ + crate://crates.io/serde_derive/1.0.228 \ + crate://crates.io/serde_json/1.0.149 \ + crate://crates.io/shlex/1.3.0 \ + crate://crates.io/signal-hook-registry/1.4.8 \ + crate://crates.io/slab/0.4.12 \ + crate://crates.io/smallvec/1.15.1 \ + crate://crates.io/socket2/0.6.3 \ + crate://crates.io/subtle/2.6.1 \ + crate://crates.io/syn/2.0.117 \ + crate://crates.io/sync_wrapper/1.0.2 \ + crate://crates.io/tempfile/3.27.0 \ + crate://crates.io/test-tag/0.1.6 \ + crate://crates.io/tokio/1.50.0 \ + crate://crates.io/tokio-macros/2.6.1 \ + crate://crates.io/tokio-rustls/0.26.4 \ + crate://crates.io/tokio-stream/0.1.18 \ + crate://crates.io/tokio-util/0.7.18 \ + crate://crates.io/tonic/0.14.5 \ + crate://crates.io/tonic-build/0.14.5 \ + crate://crates.io/tonic-prost/0.14.5 \ + crate://crates.io/tonic-prost-build/0.14.5 \ + crate://crates.io/tower/0.5.3 \ + crate://crates.io/tower-layer/0.3.3 \ + crate://crates.io/tower-service/0.3.3 \ + crate://crates.io/tracing/0.1.44 \ + crate://crates.io/tracing-attributes/0.1.31 \ + crate://crates.io/tracing-core/0.1.36 \ + crate://crates.io/try-lock/0.2.5 \ + crate://crates.io/unicode-ident/1.0.24 \ + crate://crates.io/unicode-xid/0.2.6 \ + crate://crates.io/untrusted/0.9.0 \ + crate://crates.io/utf8parse/0.2.2 \ + crate://crates.io/want/0.3.1 \ + crate://crates.io/wasi/0.11.1+wasi-snapshot-preview1 \ + crate://crates.io/wasip2/1.0.2+wasi-0.2.9 \ + crate://crates.io/wasip3/0.4.0+wasi-0.3.0-rc-2026-01-06 \ + crate://crates.io/wasm-encoder/0.244.0 \ + crate://crates.io/wasm-metadata/0.244.0 \ + crate://crates.io/wasmparser/0.244.0 \ + crate://crates.io/windows-link/0.2.1 \ + crate://crates.io/windows-sys/0.52.0 \ + crate://crates.io/windows-sys/0.61.2 \ + crate://crates.io/windows-targets/0.52.6 \ + crate://crates.io/windows_aarch64_gnullvm/0.52.6 \ + crate://crates.io/windows_aarch64_msvc/0.52.6 \ + crate://crates.io/windows_i686_gnu/0.52.6 \ + crate://crates.io/windows_i686_gnullvm/0.52.6 \ + crate://crates.io/windows_i686_msvc/0.52.6 \ + crate://crates.io/windows_x86_64_gnu/0.52.6 \ + crate://crates.io/windows_x86_64_gnullvm/0.52.6 \ + crate://crates.io/windows_x86_64_msvc/0.52.6 \ + crate://crates.io/wit-bindgen/0.51.0 \ + crate://crates.io/wit-bindgen-core/0.51.0 \ + crate://crates.io/wit-bindgen-rust/0.51.0 \ + crate://crates.io/wit-bindgen-rust-macro/0.51.0 \ + crate://crates.io/wit-component/0.244.0 \ + crate://crates.io/wit-parser/0.244.0 \ + crate://crates.io/zeroize/1.8.2 \ + crate://crates.io/zmij/1.0.21 \ +" + +SRC_URI[aho-corasick-1.1.4.sha256sum] = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +SRC_URI[anstream-1.0.0.sha256sum] = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +SRC_URI[anstyle-1.0.14.sha256sum] = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" +SRC_URI[anstyle-parse-1.0.0.sha256sum] = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +SRC_URI[anstyle-query-1.1.5.sha256sum] = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +SRC_URI[anstyle-wincon-3.0.11.sha256sum] = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +SRC_URI[anyhow-1.0.102.sha256sum] = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +SRC_URI[async-trait-0.1.89.sha256sum] = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +SRC_URI[atomic-waker-1.1.2.sha256sum] = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +SRC_URI[base64-0.22.1.sha256sum] = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +SRC_URI[bitflags-2.11.0.sha256sum] = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +SRC_URI[bytes-1.11.1.sha256sum] = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +SRC_URI[cc-1.2.58.sha256sum] = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +SRC_URI[cfg-if-1.0.4.sha256sum] = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +SRC_URI[colorchoice-1.0.5.sha256sum] = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +SRC_URI[either-1.15.0.sha256sum] = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +SRC_URI[env_filter-1.0.1.sha256sum] = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +SRC_URI[env_logger-0.11.10.sha256sum] = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +SRC_URI[equivalent-1.0.2.sha256sum] = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +SRC_URI[errno-0.3.14.sha256sum] = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +SRC_URI[fastrand-2.3.0.sha256sum] = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +SRC_URI[find-msvc-tools-0.1.9.sha256sum] = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +SRC_URI[fixedbitset-0.5.7.sha256sum] = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +SRC_URI[fnv-1.0.7.sha256sum] = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +SRC_URI[foldhash-0.1.5.sha256sum] = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +SRC_URI[futures-channel-0.3.32.sha256sum] = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +SRC_URI[futures-core-0.3.32.sha256sum] = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +SRC_URI[futures-sink-0.3.32.sha256sum] = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +SRC_URI[futures-task-0.3.32.sha256sum] = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +SRC_URI[futures-util-0.3.32.sha256sum] = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +SRC_URI[getrandom-0.2.17.sha256sum] = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +SRC_URI[getrandom-0.4.2.sha256sum] = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +SRC_URI[h2-0.4.13.sha256sum] = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +SRC_URI[hashbrown-0.15.5.sha256sum] = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +SRC_URI[hashbrown-0.16.1.sha256sum] = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +SRC_URI[heck-0.5.0.sha256sum] = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +SRC_URI[http-1.4.0.sha256sum] = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +SRC_URI[http-body-1.0.1.sha256sum] = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +SRC_URI[http-body-util-0.1.3.sha256sum] = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +SRC_URI[httparse-1.10.1.sha256sum] = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +SRC_URI[httpdate-1.0.3.sha256sum] = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +SRC_URI[hyper-1.9.0.sha256sum] = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +SRC_URI[hyper-timeout-0.5.2.sha256sum] = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +SRC_URI[hyper-util-0.1.20.sha256sum] = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +SRC_URI[id-arena-2.3.0.sha256sum] = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +SRC_URI[indexmap-2.13.0.sha256sum] = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +SRC_URI[is_terminal_polyfill-1.70.2.sha256sum] = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +SRC_URI[itertools-0.14.0.sha256sum] = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +SRC_URI[itoa-1.0.18.sha256sum] = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +SRC_URI[jiff-0.2.23.sha256sum] = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +SRC_URI[jiff-static-0.2.23.sha256sum] = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +SRC_URI[leb128fmt-0.1.0.sha256sum] = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +SRC_URI[libc-0.2.183.sha256sum] = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +SRC_URI[linux-raw-sys-0.12.1.sha256sum] = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +SRC_URI[lock_api-0.4.14.sha256sum] = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +SRC_URI[log-0.4.29.sha256sum] = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +SRC_URI[memchr-2.8.0.sha256sum] = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +SRC_URI[mio-1.2.0.sha256sum] = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +SRC_URI[multimap-0.10.1.sha256sum] = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" +SRC_URI[once_cell-1.21.4.sha256sum] = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +SRC_URI[once_cell_polyfill-1.70.2.sha256sum] = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +SRC_URI[parking_lot-0.12.5.sha256sum] = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +SRC_URI[parking_lot_core-0.9.12.sha256sum] = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +SRC_URI[percent-encoding-2.3.2.sha256sum] = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +SRC_URI[petgraph-0.8.3.sha256sum] = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +SRC_URI[pin-project-1.1.11.sha256sum] = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +SRC_URI[pin-project-internal-1.1.11.sha256sum] = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +SRC_URI[pin-project-lite-0.2.17.sha256sum] = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +SRC_URI[portable-atomic-1.13.1.sha256sum] = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +SRC_URI[portable-atomic-util-0.2.6.sha256sum] = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +SRC_URI[prettyplease-0.2.37.sha256sum] = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +SRC_URI[proc-macro2-1.0.106.sha256sum] = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +SRC_URI[prost-0.14.3.sha256sum] = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +SRC_URI[prost-build-0.14.3.sha256sum] = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +SRC_URI[prost-derive-0.14.3.sha256sum] = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +SRC_URI[prost-types-0.14.3.sha256sum] = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +SRC_URI[quote-1.0.45.sha256sum] = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +SRC_URI[r-efi-6.0.0.sha256sum] = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +SRC_URI[redox_syscall-0.5.18.sha256sum] = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +SRC_URI[regex-1.12.3.sha256sum] = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +SRC_URI[regex-automata-0.4.14.sha256sum] = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +SRC_URI[regex-syntax-0.8.10.sha256sum] = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +SRC_URI[ring-0.17.14.sha256sum] = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +SRC_URI[rustix-1.1.4.sha256sum] = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +SRC_URI[rustls-0.23.37.sha256sum] = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +SRC_URI[rustls-pki-types-1.14.0.sha256sum] = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +SRC_URI[rustls-webpki-0.103.10.sha256sum] = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +SRC_URI[scopeguard-1.2.0.sha256sum] = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +SRC_URI[semver-1.0.27.sha256sum] = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +SRC_URI[serde-1.0.228.sha256sum] = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +SRC_URI[serde_core-1.0.228.sha256sum] = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +SRC_URI[serde_derive-1.0.228.sha256sum] = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +SRC_URI[serde_json-1.0.149.sha256sum] = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +SRC_URI[shlex-1.3.0.sha256sum] = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +SRC_URI[signal-hook-registry-1.4.8.sha256sum] = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +SRC_URI[slab-0.4.12.sha256sum] = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +SRC_URI[smallvec-1.15.1.sha256sum] = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +SRC_URI[socket2-0.6.3.sha256sum] = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +SRC_URI[subtle-2.6.1.sha256sum] = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +SRC_URI[syn-2.0.117.sha256sum] = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +SRC_URI[sync_wrapper-1.0.2.sha256sum] = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +SRC_URI[tempfile-3.27.0.sha256sum] = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +SRC_URI[test-tag-0.1.6.sha256sum] = "e5a2455608f6a56fc2ce66c89dd005501c169688f29165468e65f0b47e060333" +SRC_URI[tokio-1.50.0.sha256sum] = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +SRC_URI[tokio-macros-2.6.1.sha256sum] = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +SRC_URI[tokio-rustls-0.26.4.sha256sum] = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +SRC_URI[tokio-stream-0.1.18.sha256sum] = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +SRC_URI[tokio-util-0.7.18.sha256sum] = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +SRC_URI[tonic-0.14.5.sha256sum] = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +SRC_URI[tonic-build-0.14.5.sha256sum] = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +SRC_URI[tonic-prost-0.14.5.sha256sum] = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +SRC_URI[tonic-prost-build-0.14.5.sha256sum] = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +SRC_URI[tower-0.5.3.sha256sum] = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +SRC_URI[tower-layer-0.3.3.sha256sum] = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" +SRC_URI[tower-service-0.3.3.sha256sum] = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +SRC_URI[tracing-0.1.44.sha256sum] = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +SRC_URI[tracing-attributes-0.1.31.sha256sum] = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +SRC_URI[tracing-core-0.1.36.sha256sum] = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +SRC_URI[try-lock-0.2.5.sha256sum] = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +SRC_URI[unicode-ident-1.0.24.sha256sum] = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +SRC_URI[unicode-xid-0.2.6.sha256sum] = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +SRC_URI[untrusted-0.9.0.sha256sum] = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +SRC_URI[utf8parse-0.2.2.sha256sum] = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +SRC_URI[want-0.3.1.sha256sum] = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +SRC_URI[wasi-0.11.1+wasi-snapshot-preview1.sha256sum] = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +SRC_URI[wasip2-1.0.2+wasi-0.2.9.sha256sum] = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +SRC_URI[wasip3-0.4.0+wasi-0.3.0-rc-2026-01-06.sha256sum] = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +SRC_URI[wasm-encoder-0.244.0.sha256sum] = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +SRC_URI[wasm-metadata-0.244.0.sha256sum] = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +SRC_URI[wasmparser-0.244.0.sha256sum] = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +SRC_URI[windows-link-0.2.1.sha256sum] = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +SRC_URI[windows-sys-0.52.0.sha256sum] = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +SRC_URI[windows-sys-0.61.2.sha256sum] = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +SRC_URI[windows-targets-0.52.6.sha256sum] = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +SRC_URI[windows_aarch64_gnullvm-0.52.6.sha256sum] = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +SRC_URI[windows_aarch64_msvc-0.52.6.sha256sum] = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +SRC_URI[windows_i686_gnu-0.52.6.sha256sum] = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +SRC_URI[windows_i686_gnullvm-0.52.6.sha256sum] = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +SRC_URI[windows_i686_msvc-0.52.6.sha256sum] = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +SRC_URI[windows_x86_64_gnu-0.52.6.sha256sum] = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +SRC_URI[windows_x86_64_gnullvm-0.52.6.sha256sum] = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +SRC_URI[windows_x86_64_msvc-0.52.6.sha256sum] = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +SRC_URI[wit-bindgen-0.51.0.sha256sum] = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +SRC_URI[wit-bindgen-core-0.51.0.sha256sum] = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +SRC_URI[wit-bindgen-rust-0.51.0.sha256sum] = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +SRC_URI[wit-bindgen-rust-macro-0.51.0.sha256sum] = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +SRC_URI[wit-component-0.244.0.sha256sum] = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +SRC_URI[wit-parser-0.244.0.sha256sum] = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +SRC_URI[zeroize-1.8.2.sha256sum] = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +SRC_URI[zmij-1.0.21.sha256sum] = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/recipes-connectivity/kuksa-databroker/kuksa-databroker/0001-Remove-protobuf-src-usage.patch b/recipes-connectivity/kuksa-databroker/kuksa-databroker/0001-Remove-protobuf-src-usage.patch new file mode 100644 index 00000000..3e52c431 --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/kuksa-databroker/0001-Remove-protobuf-src-usage.patch @@ -0,0 +1,133 @@ +From 26c14a895ebaa68829acdb0e1dc613314c5d9657 Mon Sep 17 00:00:00 2001 +From: Scott Murray +Date: Wed, 4 Dec 2024 09:53:15 -0500 +Subject: [PATCH] Remove protobuf-src usage + +The vendoring of a protoc and libprotobuf build that was added in +commit 890703c9 by using protobuf-src is not really workable with +OpenEmbedded / Yocto Project, and somewhat undesirable for any +distribution package builds when it comes to transparency and +reproducibility. Remove it so that building in OE/YP will work. + +Upstream-Status: Pending + +Signed-off-by: Scott Murray +--- + Cargo.lock | 19 ------------------- + databroker-proto/Cargo.toml | 1 - + databroker-proto/build.rs | 1 - + lib/Cargo.lock | 19 ------------------- + 4 files changed, 40 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index 641dc5a..02d8c36 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -478,15 +478,6 @@ dependencies = [ + "hashbrown 0.16.1", + ] + +-[[package]] +-name = "cmake" +-version = "0.1.58" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +-dependencies = [ +- "cc", +-] +- + [[package]] + name = "colorchoice" + version = "1.0.5" +@@ -778,7 +769,6 @@ version = "0.6.1" + dependencies = [ + "prost 0.14.3", + "prost-types", +- "protobuf-src", + "tonic 0.14.5", + "tonic-prost", + "tonic-prost-build", +@@ -3167,15 +3157,6 @@ dependencies = [ + "prost 0.14.3", + ] + +-[[package]] +-name = "protobuf-src" +-version = "2.1.1+27.1" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "6217c3504da19b85a3a4b2e9a5183d635822d83507ba0986624b5c05b83bfc40" +-dependencies = [ +- "cmake", +-] +- + [[package]] + name = "quote" + version = "1.0.45" +diff --git a/databroker-proto/Cargo.toml b/databroker-proto/Cargo.toml +index 5b6a459..f5e2cbb 100644 +--- a/databroker-proto/Cargo.toml ++++ b/databroker-proto/Cargo.toml +@@ -26,4 +26,3 @@ prost-types = { workspace = true } + + [build-dependencies] + tonic-prost-build = { workspace = true, features = ["transport"] } +-protobuf-src = "2" +diff --git a/databroker-proto/build.rs b/databroker-proto/build.rs +index 9c90f99..ba0f6d9 100644 +--- a/databroker-proto/build.rs ++++ b/databroker-proto/build.rs +@@ -14,7 +14,6 @@ + use std::{env, path::PathBuf}; + + fn main() -> Result<(), Box> { +- std::env::set_var("PROTOC", protobuf_src::protoc()); + tonic_prost_build::configure() + .compile_well_known_types(false) + .protoc_arg("--experimental_allow_proto3_optional") +diff --git a/lib/Cargo.lock b/lib/Cargo.lock +index 039b2ea..22d68c0 100644 +--- a/lib/Cargo.lock ++++ b/lib/Cargo.lock +@@ -118,15 +118,6 @@ version = "1.0.4" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +-[[package]] +-name = "cmake" +-version = "0.1.58" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +-dependencies = [ +- "cc", +-] +- + [[package]] + name = "colorchoice" + version = "1.0.5" +@@ -154,7 +145,6 @@ version = "0.6.1" + dependencies = [ + "prost", + "prost-types", +- "protobuf-src", + "tonic", + "tonic-prost", + "tonic-prost-build", +@@ -774,15 +764,6 @@ dependencies = [ + "prost", + ] + +-[[package]] +-name = "protobuf-src" +-version = "2.1.1+27.1" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "6217c3504da19b85a3a4b2e9a5183d635822d83507ba0986624b5c05b83bfc40" +-dependencies = [ +- "cmake", +-] +- + [[package]] + name = "quote" + version = "1.0.45" +-- +2.53.0 + diff --git a/recipes-connectivity/kuksa-databroker/kuksa-databroker_git.bb b/recipes-connectivity/kuksa-databroker/kuksa-databroker_git.bb new file mode 100644 index 00000000..963ca166 --- /dev/null +++ b/recipes-connectivity/kuksa-databroker/kuksa-databroker_git.bb @@ -0,0 +1,67 @@ +DESCRIPTION = "KUKSA.val databroker, the KUKSA Vehicle Abstraction Layer" + +SUMMARY = "KUKSA.val databroker, the KUKSA Vehicle Abstraction Layer" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +BRANCH = "release/0.6.1" +SRCREV = "dd9cb5d1c2da2543dd3b3aa7e5fb350d07412c66" + +SRC_URI = "git://github.com/eclipse-kuksa/kuksa-databroker.git;protocol=https;branch=${BRANCH}" + +SRC_URI += " \ + file://0001-Remove-protobuf-src-usage.patch \ + file://kuksa-databroker.service \ + file://kuksa-databroker.env \ + file://CA.pem \ + file://Client.key \ + file://Client.pem \ + file://Server.key \ + file://Server.pem \ + file://jwt.key.pub \ +" + +S = "${WORKDIR}/git" + +inherit cargo cargo-update-recipe-crates systemd + +DEPENDS = "protobuf-native grpc-native" + +# Add a user agent to avoid 403 errors from crates.io when fetching dependencies. +FETCHCMD_wget = "wget --user-agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64)'" + +CARGO_BUILD_FLAGS += "--features viss" + +SYSTEMD_SERVICE:${PN} = "kuksa-databroker.service" + +FILES:${PN} += " \ + ${sysconfdir} \ + ${systemd_system_unitdir} \ +" + +require kuksa-databroker-crates.inc + +do_install:append() { + install -d ${D}${sysconfdir}/default + install -m 0644 ${WORKDIR}/kuksa-databroker.env ${D}${sysconfdir}/default/kuksa-databroker + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/kuksa-databroker.service ${D}${systemd_system_unitdir} + + + install -d ${D}${sysconfdir}/kuksa-val + install -m 0644 ${WORKDIR}/CA.pem ${D}${sysconfdir}/kuksa-val + + install -m 0644 ${WORKDIR}/Server.key ${D}${sysconfdir}/kuksa-val + install -m 0644 ${WORKDIR}/Server.pem ${D}${sysconfdir}/kuksa-val + install -m 0644 ${WORKDIR}/jwt.key.pub ${D}${sysconfdir}/kuksa-val + install -m 0644 ${WORKDIR}/Client.key ${D}${sysconfdir}/kuksa-val + install -m 0644 ${WORKDIR}/Client.pem ${D}${sysconfdir}/kuksa-val +} + +# The upstream Cargo.toml builds optimized and stripped binaries, for +# now disable the QA check as opposed to tweaking the configuration. +INSANE_SKIP:${PN} = "already-stripped" +INSANE_SKIP:${PN}-cli = "already-stripped" + +RDEPENDS:${PN} += "vss" diff --git a/recipes-connectivity/openssl/files/openssl-aos.cnf b/recipes-connectivity/openssl/files/openssl-aos.cnf new file mode 100644 index 00000000..1d40283e --- /dev/null +++ b/recipes-connectivity/openssl/files/openssl-aos.cnf @@ -0,0 +1,21 @@ +[provider_sect] +base = base_sect +#default = default_sect +legacy = legacy_sect +pkcs11 = pkcs11_sect + +[base_sect] +activate = 1 + +[default_sect] +activate = 1 + +[legacy_sect] +activate = 1 +module = @LEGACY_PROVIDER_PATH@ + +[pkcs11_sect] +module = @PKCS11_PROVIDER_PATH@ +pkcs11-module-path = @HSM_MODULE_PATH@ +pkcs11-module-cache-keys = false +activate = 1 diff --git a/recipes-connectivity/openssl/files/openssl-engine.conf b/recipes-connectivity/openssl/files/openssl-engine.conf deleted file mode 100644 index 359fed85..00000000 --- a/recipes-connectivity/openssl/files/openssl-engine.conf +++ /dev/null @@ -1,20 +0,0 @@ -[provider_sect] -legacy = legacy_sect - -[default_sect] -activate = 1 - -[legacy_sect] -activate = 1 - -[openssl_init] -engines=engine_section - -[engine_section] -pkcs11 = pkcs11_section - -[pkcs11_section] -engine_id = pkcs11 -dynamic_path = @PKCS11_ENGINE_PATH@ -MODULE_PATH = @HSM_MODULE_PATH@ -init = 0 diff --git a/recipes-connectivity/openssl/openssl_%.bbappend b/recipes-connectivity/openssl/openssl_%.bbappend index 57cdfeab..be78e5b3 100644 --- a/recipes-connectivity/openssl/openssl_%.bbappend +++ b/recipes-connectivity/openssl/openssl_%.bbappend @@ -1,17 +1,22 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:" -SRC_URI += "file://openssl-engine.conf" +SRC_URI += "file://openssl-aos.cnf" +PKCS11_PROVIDER_PATH ?= "${libdir}/ossl-modules/pkcs11.so" +LEGACY_PROVIDER_PATH ?= "${libdir}/ossl-modules/legacy.so" HSM_MODULE_PATH ?= "${libdir}/softhsm/libsofthsm2.so" do_install:append:class-target() { - if ! grep -q "^\[engine_section\]" ${D}${sysconfdir}/ssl/openssl.cnf; then - sed -e 's,@PKCS11_ENGINE_PATH@,${libdir}/engines-3/pkcs11.so,g' \ - -e 's,@HSM_MODULE_PATH@,${HSM_MODULE_PATH},g' \ - ${WORKDIR}/openssl-engine.conf >> ${D}${sysconfdir}/ssl/openssl.cnf - fi + sed -e 's,@PKCS11_PROVIDER_PATH@,${PKCS11_PROVIDER_PATH},g' \ + -e 's,@LEGACY_PROVIDER_PATH@,${LEGACY_PROVIDER_PATH},g' \ + -e 's,@HSM_MODULE_PATH@,${HSM_MODULE_PATH},g' \ + ${WORKDIR}/openssl-aos.cnf > ${D}${sysconfdir}/ssl/openssl-aos.cnf + + echo ".include ${sysconfdir}/ssl/openssl-aos.cnf" >> ${D}${sysconfdir}/ssl/openssl.cnf } +PREFERRED_VERSION_pkcs11-provider = "1.0" + RDEPENDS:${PN}:class-target += " \ - libp11 \ + pkcs11-provider \ " diff --git a/recipes-connectivity/pkcs11-provider/pkcs11-provider_1.0.bb b/recipes-connectivity/pkcs11-provider/pkcs11-provider_1.0.bb new file mode 100644 index 00000000..30240336 --- /dev/null +++ b/recipes-connectivity/pkcs11-provider/pkcs11-provider_1.0.bb @@ -0,0 +1,26 @@ +SUMMARY = "An OpenSSL provider that allows direct interfacing with pkcs11 drivers" +DESCRIPTION = "\ +This is an Openssl 3.x provider to access Hardware or Software Tokens using \ +the PKCS#11 Cryptographic Token Interface\ +\ +This code targets version 3.1 of the interface but should be backwards \ +compatible to previous versions as well.\ +" +HOMEPAGE = "https://github.com/latchset/pkcs11-provider" +SECTION = "libs" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://COPYING;md5=b53b787444a60266932bd270d1cf2d45" +DEPENDS = "\ + openssl \ + p11-kit \ +" + +SRCREV = "8f6b94409d4872265076df310492da1e5f6abdf7" + +SRC_URI = "git://github.com/latchset/${BPN}.git;branch=main;protocol=https" + +S = "${WORKDIR}/git" + +inherit meson pkgconfig + +FILES:${PN} += "${libdir}/ossl-modules/pkcs11.so" diff --git a/recipes-containers/crun/crun_git.bbappend b/recipes-containers/crun/crun_git.bbappend new file mode 100644 index 00000000..6f519442 --- /dev/null +++ b/recipes-containers/crun/crun_git.bbappend @@ -0,0 +1 @@ +EXTRA_OECONF:append = " --enable-shared" diff --git a/recipes-core/base-files/base-files_%.bbappend b/recipes-core/base-files/base-files_%.bbappend index 56e535d6..44d37c9e 100644 --- a/recipes-core/base-files/base-files_%.bbappend +++ b/recipes-core/base-files/base-files_%.bbappend @@ -2,11 +2,6 @@ hostname = "${AOS_NODE_HOSTNAME}" aos_disks_timeout = "30" do_install:append() { - # add Aos related hosts - for host in ${AOS_HOSTS}; do - echo ${host} | sed "s/=/ /g" >> ${D}${sysconfdir}/hosts - done - # remove /run from fstab, run is mounted in initramfs sed -i "\:[[:blank:]]*/run:d" ${D}${sysconfdir}/fstab diff --git a/recipes-core/images/aos-image-initramfs.bb b/recipes-core/images/aos-image-initramfs.bb index fe2b6e8e..a4528981 100644 --- a/recipes-core/images/aos-image-initramfs.bb +++ b/recipes-core/images/aos-image-initramfs.bb @@ -4,6 +4,7 @@ LICENSE = "Apache-2.0" AOS_INITRAMFS_SCRIPTS ?= " \ initramfs-module-aosupdate \ + initramfs-module-kmsglog \ initramfs-module-machineid \ initramfs-module-udev \ initramfs-module-vardir \ diff --git a/recipes-core/images/aos-image.inc b/recipes-core/images/aos-image.inc index 8e74eaf1..85454196 100644 --- a/recipes-core/images/aos-image.inc +++ b/recipes-core/images/aos-image.inc @@ -92,19 +92,20 @@ addtask create_rw_parts after do_image_qa do_image_wic before do_image_complete IMAGE_INSTALL:append = " \ aos-iamanager \ aos-servicemanager \ - aos-updatemanager \ aos-deprov \ + aos-provfirewall \ + aos-nftables \ ${@bb.utils.contains('DISTRO_FEATURES', 'selinux', ' \ packagegroup-selinux-minimal \ packagegroup-selinux-policycoreutils \ selinux-autorelabel \ + auditd \ ', '', d)} \ " IMAGE_INSTALL:append:aos-main-node = " \ aos-communicationmanager \ - aos-provfirewall \ - aos-vis \ + kuksa-databroker \ " TOOLCHAIN_HOST_TASK:append = " \ diff --git a/recipes-core/initrdscripts/initramfs-framework/kmsglog b/recipes-core/initrdscripts/initramfs-framework/kmsglog new file mode 100644 index 00000000..132e2b8b --- /dev/null +++ b/recipes-core/initrdscripts/initramfs-framework/kmsglog @@ -0,0 +1,37 @@ +#!/bin/sh + +# This file contains overridden log methods to redirect initramfs messages to /dev/kmsg + +# Prints information +msg() { + echo "<5>initramfs: $*" >/dev/kmsg +} + +# Prints error +error() { + echo "<3>initramfs: $*" >/dev/kmsg +} + +# Prints information if verbose bootparam is used +info() { + [ -n "$bootparam_verbose" ] && echo "<6>initramfs: $*" >/dev/kmsg +} + +# Prints information if debug bootparam is used +debug() { + [ -n "$bootparam_debug" ] && echo "<7>initramfs: $*" >/dev/kmsg +} + +# Prints a message and start a endless loop +fatal() { + echo "<2>initramfs: $1" >/dev/kmsg + echo "<2>initramfs:" >/dev/kmsg + + if [ -n "$bootparam_init_fatal_sh" ]; then + sh + else + while [ "true" ]; do + sleep 3600 + done + fi +} diff --git a/recipes-core/initrdscripts/initramfs-framework_%.bbappend b/recipes-core/initrdscripts/initramfs-framework_%.bbappend index 686b5b05..dca36484 100644 --- a/recipes-core/initrdscripts/initramfs-framework_%.bbappend +++ b/recipes-core/initrdscripts/initramfs-framework_%.bbappend @@ -2,6 +2,7 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/initramfs-framework:" SRC_URI += " \ file://aosupdate \ + file://kmsglog \ file://machineid \ file://opendisk \ file://rundir \ @@ -10,6 +11,7 @@ SRC_URI += " \ PACKAGES += " \ initramfs-module-aosupdate \ + initramfs-module-kmsglog \ initramfs-module-machineid \ initramfs-module-opendisk \ initramfs-module-rundir \ @@ -30,6 +32,10 @@ RRECOMMENDS:initramfs-module-aosupdate = " \ ', '', d)} \ " +SUMMARY:initramfs-module-kmsglog = "redirect log messages to kmsg" +RDEPENDS:initramfs-module-kmsglog = "${PN}-base" +FILES:initramfs-module-kmsglog = "/init.d/00-kmsglog" + SUMMARY:initramfs-module-machineid = "bind /etc/machine-id to /var/machine-id" RDEPENDS:initramfs-module-machineid = "${PN}-base initramfs-module-vardir" FILES:initramfs-module-machineid = "/init.d/96-machineid" @@ -50,6 +56,9 @@ do_install:append() { # aosupdate install -m 0755 ${WORKDIR}/aosupdate ${D}/init.d/95-aosupdate + # kmsglog + install -m 0755 ${WORKDIR}/kmsglog ${D}/init.d/00-kmsglog + # machineid install -m 0755 ${WORKDIR}/machineid ${D}/init.d/96-machineid diff --git a/recipes-devtools/python/python3-annotated-types_%.bbappend b/recipes-devtools/python/python3-annotated-types_%.bbappend new file mode 100644 index 00000000..d6f58699 --- /dev/null +++ b/recipes-devtools/python/python3-annotated-types_%.bbappend @@ -0,0 +1 @@ +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-anytree_2.9.2.bb b/recipes-devtools/python/python3-anytree_2.9.2.bb new file mode 100644 index 00000000..7965ea8d --- /dev/null +++ b/recipes-devtools/python/python3-anytree_2.9.2.bb @@ -0,0 +1,16 @@ +SUMMARY = "Powerful and Lightweight Python Tree Data Structure" +HOMEPAGE = "https://github.com/c0fec0de/anytree" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +PYPI_PACKAGE = "anytree" + +SRC_URI[sha256sum] = "e02af617d41ede47f922e5deea0e4efc3201c6e7330cfc1265409762e5381283" + +inherit pypi python_poetry_core + +RDEPENDS:${PN} += " \ + python3-six \ +" + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-devtools/python/python3-deprecation_2.1.0.bb b/recipes-devtools/python/python3-deprecation_2.1.0.bb new file mode 100644 index 00000000..c4b3a1cf --- /dev/null +++ b/recipes-devtools/python/python3-deprecation_2.1.0.bb @@ -0,0 +1,12 @@ +SUMMARY = "A library to handle automated deprecations" +HOMEPAGE = "https://github.com/briancurtin/deprecation" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +PYPI_PACKAGE = "deprecation" + +SRC_URI[sha256sum] = "72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff" + +inherit pypi setuptools3 + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-devtools/python/python3-graphql-core_3.2.3.bb b/recipes-devtools/python/python3-graphql-core_3.2.3.bb new file mode 100644 index 00000000..b12957a4 --- /dev/null +++ b/recipes-devtools/python/python3-graphql-core_3.2.3.bb @@ -0,0 +1,12 @@ +SUMMARY = "GraphQL implementation for Python" +HOMEPAGE = "https://github.com/graphql-python/graphql-core" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=73706fb002de2debc52328afd1688817" + +PYPI_PACKAGE = "graphql-core" + +SRC_URI[sha256sum] = "06d2aad0ac723e35b1cb47885d3e5c45e956a53bc1b209a9fc5369007fe46676" + +inherit pypi setuptools3 + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-devtools/python/python3-jsonpath-ng_1.5.3.bb b/recipes-devtools/python/python3-jsonpath-ng_1.5.3.bb new file mode 100644 index 00000000..4c3dfaa9 --- /dev/null +++ b/recipes-devtools/python/python3-jsonpath-ng_1.5.3.bb @@ -0,0 +1,15 @@ +SUMMARY = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +HOMEPAGE = "https://github.com/h2non/jsonpath-ng" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +PYPI_PACKAGE = "jsonpath-ng" + +SRC_URI[sha256sum] = "a273b182a82c1256daab86a313b937059261b5c5f8c4fa3fc38b882b344dd567" + +inherit pypi setuptools3 + +RDEPENDS:${PN} += " \ + python3-ply \ + python3-six \ +" diff --git a/recipes-devtools/python/python3-pydantic-core_%.bbappend b/recipes-devtools/python/python3-pydantic-core_%.bbappend new file mode 100644 index 00000000..d6f58699 --- /dev/null +++ b/recipes-devtools/python/python3-pydantic-core_%.bbappend @@ -0,0 +1 @@ +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-pydantic_%.bbappend b/recipes-devtools/python/python3-pydantic_%.bbappend new file mode 100644 index 00000000..d6f58699 --- /dev/null +++ b/recipes-devtools/python/python3-pydantic_%.bbappend @@ -0,0 +1 @@ +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-rich-click_1.8.4.bb b/recipes-devtools/python/python3-rich-click_1.8.4.bb new file mode 100644 index 00000000..e442774a --- /dev/null +++ b/recipes-devtools/python/python3-rich-click_1.8.4.bb @@ -0,0 +1,17 @@ +SUMMARY = "A shim around Click that renders help output nicely using Rich." +HOMEPAGE = "https://github.com/ewels/rich-click" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=5372b77c3720be60b7eff9a9a5c0000d" + +PYPI_PACKAGE = "rich_click" + +SRC_URI[sha256sum] = "0f49471f04439269d0e66a6f43120f52d11d594869a2a0be600cfb12eb0616b9" + +inherit pypi python_setuptools_build_meta + +RDEPENDS:${PN} += " \ + python3-click \ + python3-rich \ +" + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-devtools/python/python3-rich_%.bbappend b/recipes-devtools/python/python3-rich_%.bbappend new file mode 100644 index 00000000..d6f58699 --- /dev/null +++ b/recipes-devtools/python/python3-rich_%.bbappend @@ -0,0 +1 @@ +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-setuptools-git-versioning_1.7.4.bb b/recipes-devtools/python/python3-setuptools-git-versioning_1.7.4.bb new file mode 100644 index 00000000..698a3bb6 --- /dev/null +++ b/recipes-devtools/python/python3-setuptools-git-versioning_1.7.4.bb @@ -0,0 +1,17 @@ +SUMMARY = "Use git repo data for building a version number according PEP-440" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=f22e7cb81b49604c2450680982bdc067" +PYPI_PACKAGE = "setuptools-git-versioning" + +DEPENDS = "python3-six-native" + +SRC_URI[sha256sum] = "be2901afcb7c865e3b500a38183598657fd029a1a72c8d1dfc7fbffb5c227dac" + +inherit pypi setuptools3 + +RDEPENDS:${PN} += " \ + python3-setuptools \ + python3-six \ +" + +BBCLASSEXTEND = "native" diff --git a/recipes-extended/iptables/files/iptables.rules b/recipes-extended/iptables/files/iptables.rules deleted file mode 100644 index 2ecad559..00000000 --- a/recipes-extended/iptables/files/iptables.rules +++ /dev/null @@ -1,3 +0,0 @@ -*filter -:FORWARD DROP [0:0] -COMMIT diff --git a/recipes-extended/iptables/iptables_%.bbappend b/recipes-extended/iptables/iptables_%.bbappend deleted file mode 100644 index 339cdebc..00000000 --- a/recipes-extended/iptables/iptables_%.bbappend +++ /dev/null @@ -1,5 +0,0 @@ -FILESEXTRAPATHS:prepend := "${THISDIR}/files:" - -SRC_URI += "\ - file://iptables.rules \ -" diff --git a/recipes-extended/quota/files/rpc-rquotad.service b/recipes-extended/quota/files/rpc-rquotad.service new file mode 100644 index 00000000..1df36140 --- /dev/null +++ b/recipes-extended/quota/files/rpc-rquotad.service @@ -0,0 +1,14 @@ +[Unit] +Description=Remote quota server +Documentation=man:rpc.rquotad(8) +Requires=rpcbind.service +PartOf=rpcbind.service +After=rpcbind.service network-online.target + +[Service] +Type=forking +ExecStart=/usr/sbin/rpc.rquotad + +[Install] +WantedBy=multi-user.target +WantedBy=nfs-server.service diff --git a/recipes-extended/quota/quota_%.bbappend b/recipes-extended/quota/quota_%.bbappend new file mode 100644 index 00000000..06c1165b --- /dev/null +++ b/recipes-extended/quota/quota_%.bbappend @@ -0,0 +1,16 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI += " \ + file://rpc-rquotad.service \ +" + +inherit systemd + +SYSTEMD_SERVICE:${PN} = "rpc-rquotad.service" + +FILES:${PN} += "${systemd_system_unitdir}/rpc-rquotad.service" + +do_install:append() { + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/rpc-rquotad.service ${D}${systemd_system_unitdir} +} diff --git a/recipes-networking/cni/cni_git.bbappend b/recipes-networking/cni/cni_git.bbappend deleted file mode 100644 index 25c7dd2d..00000000 --- a/recipes-networking/cni/cni_git.bbappend +++ /dev/null @@ -1 +0,0 @@ -export GO111MODULE = "auto" diff --git a/recipes-security/audit/audit_%.bbappend b/recipes-security/audit/audit_%.bbappend new file mode 100644 index 00000000..8ff20333 --- /dev/null +++ b/recipes-security/audit/audit_%.bbappend @@ -0,0 +1,8 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI:append = " file://audit-rules-append.conf" + +do_install:append() { + # Append custom audit rules to the end of audit.rules + cat ${WORKDIR}/audit-rules-append.conf >> ${D}${sysconfdir}/audit/audit.rules +} diff --git a/recipes-security/audit/files/audit-rules-append.conf b/recipes-security/audit/files/audit-rules-append.conf new file mode 100644 index 00000000..671fdb0b --- /dev/null +++ b/recipes-security/audit/files/audit-rules-append.conf @@ -0,0 +1,8 @@ +## Never audit any syscall from any user +-a never,task + +## Always audit SELinux denials (AVC is type 1400) +-a always,exclude -F msgtype!=AVC + +## Enable auditing +-e 1 diff --git a/recipes-security/refpolicy/refpolicy-aos_git.bb b/recipes-security/refpolicy/refpolicy-aos_git.bb index 22c6067a..a9c15b8c 100644 --- a/recipes-security/refpolicy/refpolicy-aos_git.bb +++ b/recipes-security/refpolicy/refpolicy-aos_git.bb @@ -11,8 +11,8 @@ include recipes-security/refpolicy/refpolicy_common.inc PV = "2_20220106+git${SRCPV}" -BRANCH = "master" -SRCREV = "0c6c742ee214cb242c1ed9119847d64bf093f4fe" +BRANCH = "develop" +SRCREV = "${AUTOREV}" SRC_URI = "git://github.com/aosedge/refpolicy.git;branch=${BRANCH};protocol=https;name=refpolicy;destsuffix=refpolicy" diff --git a/recipes-aos/aos-rootca/files/Aos_Root_CA.pem b/recipes-support/ca-certificates/ca-certificates/AosRootCA.crt similarity index 79% rename from recipes-aos/aos-rootca/files/Aos_Root_CA.pem rename to recipes-support/ca-certificates/ca-certificates/AosRootCA.crt index ef163c2f..543dd61b 100644 --- a/recipes-aos/aos-rootca/files/Aos_Root_CA.pem +++ b/recipes-support/ca-certificates/ca-certificates/AosRootCA.crt @@ -1,17 +1,4 @@ -----BEGIN CERTIFICATE----- -MIIB9jCCAX2gAwIBAgIUJiJIopZeqXR/Sy+S38HCM4R+IA4wCgYIKoZIzj0EAwMw -OzERMA8GA1UECgwIRVBBTSBJbmMxDDAKBgNVBAsMA0FvczEYMBYGA1UEAwwPQW9z -RWRnZSBSb290IENBMB4XDTI0MTIyNjEyMDExM1oXDTQ0MTIyMTEyMDExM1owOzER -MA8GA1UECgwIRVBBTSBJbmMxDDAKBgNVBAsMA0FvczEYMBYGA1UEAwwPQW9zRWRn -ZSBSb290IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEYXvRxDhY0eeJx1KjFAtH -heMLTPKPHviav8XtbZZz/OIj+7xwC3EhDq+Y8cwzuZvqWM9ZmPcD52DNx7hg1oOc -T4WXri1G1ga49iqDJhR9BcdCBhvMUOIKCj2Io0dhJ/r6o0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU+SBVz9bppAZGuUCxj1iJ -+Qgyd38wCgYIKoZIzj0EAwMDZwAwZAIwGo3tCLKyVJL57RAJmQ7+ZO2sRvAAas82 -7cbowyJBTZmR4WVDNcDHrKv5zNvWNZ1XAjA/dbxBlaZKN132ULvkOcNe1IXADtOP -hYQ0VMoHFIo5LOyzsJCdiaUQkksyKPQkxtY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- MIIEAjCCAuqgAwIBAgIJAPwk2NFfSDPjMA0GCSqGSIb3DQEBCwUAMIGNMRcwFQYD VQQDDA5GdXNpb24gUm9vdCBDQTEpMCcGCSqGSIb3DQEJARYadm9sb2R5bXlyX2Jh YmNodWtAZXBhbS5jb20xDTALBgNVBAoMBEVQQU0xHDAaBgNVBAsME05vdnVzIE9y @@ -36,12 +23,15 @@ VHEOzvaGk9miP6nBrDfNv7mIkgEKARrjjSpmJasIEU+mNtzeOIEiMtW1EMRc457o 0PdFI3jseyLVPVhEzUkuC7mwjb7CeQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIBdzCCAR2gAwIBAgIUSWWq88ZtNjcD1qScBtThMuKlk5YwCgYIKoZIzj0EAwIw -GjEYMBYGA1UEAwwPQW9zRWRnZSBSb290IENBMCAXDTI0MTIyMDA5MjkwNloYDzIw -NTQxMjEzMDkyOTA2WjAaMRgwFgYDVQQDDA9Bb3NFZGdlIFJvb3QgQ0EwWTATBgcq -hkjOPQIBBggqhkjOPQMBBwNCAAQgaFpO9TjXW/K3y4GwFTi+y+Rb36nxwWVJqnk3 -IwEihvbssFYp+dwmMX2sGGkJy+dS66LohSTRIR/L6WuC6341oz8wPTAPBgNVHRMB -Af8EBTADAQH/MB0GA1UdDgQWBBRB329EoluTc3waQPwT1ig9zD+zbDALBgNVHQ8E -BAMCAYYwCgYIKoZIzj0EAwIDSAAwRQIgDLJnJy86bVImRIGz4vJ9UfUC/hLc5VpQ -AqrFOYwtG4ICIQCfS6XNFk8BMb/lbzMjyoVnt0ONhvpWuD+bGI/rxCrPLQ== +MIIB9jCCAX2gAwIBAgIUJiJIopZeqXR/Sy+S38HCM4R+IA4wCgYIKoZIzj0EAwMw +OzERMA8GA1UECgwIRVBBTSBJbmMxDDAKBgNVBAsMA0FvczEYMBYGA1UEAwwPQW9z +RWRnZSBSb290IENBMB4XDTI0MTIyNjEyMDExM1oXDTQ0MTIyMTEyMDExM1owOzER +MA8GA1UECgwIRVBBTSBJbmMxDDAKBgNVBAsMA0FvczEYMBYGA1UEAwwPQW9zRWRn +ZSBSb290IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEYXvRxDhY0eeJx1KjFAtH +heMLTPKPHviav8XtbZZz/OIj+7xwC3EhDq+Y8cwzuZvqWM9ZmPcD52DNx7hg1oOc +T4WXri1G1ga49iqDJhR9BcdCBhvMUOIKCj2Io0dhJ/r6o0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU+SBVz9bppAZGuUCxj1iJ ++Qgyd38wCgYIKoZIzj0EAwMDZwAwZAIwGo3tCLKyVJL57RAJmQ7+ZO2sRvAAas82 +7cbowyJBTZmR4WVDNcDHrKv5zNvWNZ1XAjA/dbxBlaZKN132ULvkOcNe1IXADtOP +hYQ0VMoHFIo5LOyzsJCdiaUQkksyKPQkxtY= -----END CERTIFICATE----- diff --git a/recipes-support/ca-certificates/ca-certificates_%.bbappend b/recipes-support/ca-certificates/ca-certificates_%.bbappend new file mode 100644 index 00000000..74a929cd --- /dev/null +++ b/recipes-support/ca-certificates/ca-certificates_%.bbappend @@ -0,0 +1,10 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/ca-certificates:" + +SRC_URI += " \ + file://AosRootCA.crt \ +" + +do_install:prepend() { + install -d ${D}${datadir}/ca-certificates/aos + install -m 0644 ${WORKDIR}/AosRootCA.crt ${D}${datadir}/ca-certificates/aos +} diff --git a/recipes-support/vss/vss-tools_5.0.bb b/recipes-support/vss/vss-tools_5.0.bb new file mode 100644 index 00000000..6b36d5d2 --- /dev/null +++ b/recipes-support/vss/vss-tools_5.0.bb @@ -0,0 +1,32 @@ +DESCRIPTION = "COVESA Vehicle Signal Specification tools" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=9741c346eef56131163e13b9db1241b3" + +BRANCH = "release/5.0" +SRCREV = "9ba7f40c0995358a293aab729d57739c3e9b2829" + +SRC_URI = "git://github.com/COVESA/vss-tools.git;protocol=https;branch=${BRANCH} " + +S = "${WORKDIR}/git" + +inherit python_poetry_core + +RDEPENDS:${PN} += " \ + python3-core \ + python3-ctypes \ + python3-email \ + python3-importlib-metadata \ + python3-json \ + python3-logging \ + python3-netclient \ + python3-pkg-resources \ + python3-anytree \ + python3-deprecation \ + python3-graphql-core \ + python3-pyyaml \ + python3-six \ + python3-pydantic \ + python3-rich-click \ +" + +BBCLASSEXTEND += "native nativesdk" diff --git a/recipes-support/vss/vss_5.0.bb b/recipes-support/vss/vss_5.0.bb new file mode 100644 index 00000000..d293a7e5 --- /dev/null +++ b/recipes-support/vss/vss_5.0.bb @@ -0,0 +1,39 @@ +DESCRIPTION = "Vehicle Signal Specification" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=9741c346eef56131163e13b9db1241b3" + +BRANCH = "release/5.0" +SRCREV = "f23ba53be78a8bf2b8df2496bbfccb2860913892" + +SRC_URI = "git://github.com/COVESA/vehicle_signal_specification.git;branch=${BRANCH};protocol=https" + +S = "${WORKDIR}/git" + +UPSTREAM_CHECK_GITTAGREGEX = "v(?P\d+(\.\d+)+)" + +inherit allarch update-alternatives + +DEPENDS = "vss-tools-native" + +EXTRA_OEMAKE = "TOOLSDIR=${STAGING_BINDIR_NATIVE}" + +FILES:${PN} += " \ + ${datadir} \ +" + +do_configure[noexec] = "1" + +do_compile() { + oe_runmake json +} + +do_install() { + # Cannot use the "install" target in the project Makefile, as it is + # intended for setting the repo up for builds. + # For now, just the generated JSON is installed. It is possible that + # installing the vspec files somewhere as a development package may + # be useful, but for now things will be kept simple. + install -d ${D}${datadir}/vss + install -m 0644 ${S}/vss.json ${D}${datadir}/vss/vss.json + install -m 0644 ${S}/vss.json ${D}${datadir}/vss/vss-test.json +} diff --git a/scripts/bitbake.py b/scripts/bitbake.py index 92a5cfe6..b8509107 100644 --- a/scripts/bitbake.py +++ b/scripts/bitbake.py @@ -1,25 +1,33 @@ #!/usr/bin/env python3 -""" Calls bitbake command line """ +"""Calls bitbake command line""" import os -def call_bitbake(work_dir, yocto_dir, build_dir, target, bbake_conf, do_clean=False): +def call_bitbake( + work_dir, yocto_dir, build_dir, target, bbake_conf=None, task=None, do_clean=False +): """Calls bitbake.""" - print(f"Bitbake target: {target}...\n") - # Create config file + if bbake_conf: + conf_file = os.path.abspath(os.path.join(work_dir, f"{target}.conf")) - conf_file = os.path.abspath(os.path.join(work_dir, f"{target}.conf")) - - create_bbake_conf(conf_file, bbake_conf) + create_bbake_conf(conf_file, bbake_conf) cmd = [f"cd {yocto_dir}", f". ./poky/oe-init-build-env {build_dir}"] if do_clean: + print(f"Cleanup {target} build") + cmd.append(f"bitbake {target} -c cleanall") - cmd.append(f"bitbake {target} --postread {conf_file}") + print(f"Bitbake {target}, task {task}") + + cmd.append( + f"bitbake {target}" + + (f" --postread {conf_file}" if bbake_conf else "") + + (f" -c {task}" if task else "") + ) line = " && ".join(c for c in cmd) @@ -31,6 +39,8 @@ def call_bitbake(work_dir, yocto_dir, build_dir, target, bbake_conf, do_clean=Fa def create_bbake_conf(conf_file, bbake_conf): """Creates yocto conf file.""" + print(f"Create {conf_file} file") + with open(conf_file, "w+", encoding="utf8") as file: for var in bbake_conf: file.write(f'{var[0]} = "{var[1]}"\n') diff --git a/scripts/custom_yocto.py b/scripts/custom_yocto.py deleted file mode 100755 index e289547e..00000000 --- a/scripts/custom_yocto.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 -''' Script for building custom bitbake target ''' -import os -import sys -import argparse -import yaml - - -def call_bitbake(yocto_dir, conf): - ''' Call bitbake ''' - cmd = [ - f"cd {yocto_dir}", - f'. ./poky/oe-init-build-env {conf["dir"]}', - f'bitbake {conf["target"]}', - ] - line = " && ".join(c for c in cmd) - ret = os.system(f'bash -c "{line}"') - return ret >> 8 - - -def _read_layers_file(enabled_file): - layers = [] - for line in enabled_file: - line = line.strip() - if len(line) > 0 and line[0] != "#": - if line not in layers: - layers.append(line) - return layers - - -def main(): - ''' Main function ''' - ret = 0 - parser = argparse.ArgumentParser(description="fota") - parser.add_argument( - "conf", metavar="conf.yaml", type=str, help="YAML file with configuration" - ) - parser.add_argument( - "-v", "--verbose", action="store_true", help="Enable verbose output" - ) - parser.add_argument("-l", "--layers", nargs="*", help="List of enabled layers") - parser.add_argument( - "-f", "--file", action="store", help="Config file with enabled layers" - ) - args = parser.parse_args() - - with open(args.conf, "r", encoding="utf-8") as conf_file: - conf = yaml.load(conf_file, Loader=yaml.CLoader) - if args.layers is not None or args.file is not None: - enabled_layers = [] - if args.layers is not None: - enabled_layers = list(args.layers) - if args.file is not None: - try: - with open(args.file, "r", encoding="utf-8") as enabled_file: - enabled_layers.extend(_read_layers_file(enabled_file)) - except FileNotFoundError: - print(f"File {args.file} can't be opened") - else: - enabled_layers = None - layers = conf["layers"] - yocto_dir = layers["yocto_dir"] - for key in layers["items"]: - if enabled_layers: - enabled = key in enabled_layers - else: - enabled = layers["items"][key].get("enabled", True) - if enabled: - ret = call_bitbake(yocto_dir, layers["items"][key]) - return ret - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/scripts/fota_builder.py b/scripts/fota_builder.py index 103f8933..b02b53c5 100755 --- a/scripts/fota_builder.py +++ b/scripts/fota_builder.py @@ -1,100 +1,72 @@ #!/usr/bin/env python3 -""" Create fota archive """ +"""Script for building AOS components with unified metadata generation.""" + import argparse -import json import os import shutil import subprocess import sys -from pathlib import Path import yaml from bitbake import call_bitbake +from metadata_builder import ( + LAYER_MEDIA_TYPE, + AosArchInfo, + AosDependency, + AosDependencyIdentity, + AosIdentity, + AosImage, + AosOsInfo, + AosUpdateItem, + AosUpdateItemConfiguration, + BundleBuilder, +) from moulin import rouge class FotaError(Exception): - """Exception raised for errors during creating FOTA archive - - Attributes: - error code -- Error code - message -- explanation of the error - """ + """Exception raised for errors during creating FOTA archive.""" def __init__(self, error_code, message="FOTA error"): self.code = error_code self.message = f"{message} ({self.code})" - super().__init__(self.message) -class FotaBuilder: - """Create fota archive class""" +class ComponentBuilder: + """Builder for individual AOS components.""" - def __init__(self, conf, verbose) -> None: + def __init__(self, conf: rouge.YamlValue, output_dir: str) -> None: + self._conf = conf self._work_dir = conf["work_dir"].as_str - self._components = conf["components"] - self._verbose = verbose - self._bundle_name = conf["target_images"][0].as_str - self._metadata = {"formatVersion": 2, "components": []} - self._bundle_dir = os.path.join(self._work_dir, "bundle") - - def create_bundle(self): - """Create bundle from prepared files""" + self._output_dir = output_dir - self._mkdir(os.path.dirname(self._bundle_name)) + def build_component(self, name: str, comp_conf: rouge.YamlValue) -> str: + """Build component and return path to the built file.""" + method = comp_conf["method"].as_str + comp_type = comp_conf.get("componentType", name).as_str + version = comp_conf["version"].as_str - args = ["tar", "-cf", self._bundle_name, "-C", self._bundle_dir, "."] + filename = comp_conf.get("fileName", f"{comp_type}-{version}.img").as_str - self._run_cmd(args) + # Create per-component subdirectory + comp_dir = os.path.join(self._output_dir, name) + os.makedirs(comp_dir, exist_ok=True) - def process_component(self, component, conf): - """Process component "component" """ - metadata = self._create_component_metadata(component, conf) - work_dir = os.path.join(self._work_dir, "components", metadata["type"]) - method = conf["method"].as_str + work_dir = os.path.join(self._work_dir, "components", comp_type) if method == "raw": - self._do_raw_component(work_dir, metadata, conf) + self._do_raw_component(work_dir, comp_dir, filename, comp_conf) elif method == "overlay": - self._do_overlay_component(work_dir, metadata, conf) + self._do_overlay_component( + work_dir, comp_dir, filename, comp_type, version, comp_conf + ) elif method == "custom": - self._do_custom_component(metadata, conf) - - self._metadata["components"].append(metadata) - - def create_metadata(self): - """Create metadata file in bundle directory""" - metadata_file_name = os.path.join(self._bundle_dir, "metadata.json") - - with open(metadata_file_name, "w", encoding="utf-8") as metadata_file: - json.dump(self._metadata, metadata_file, indent=4) - - def get_components(self): - """Get dictionary with components configuration""" - return self._components - - def prepare_bundle_dir(self): - """Prepare empty temporary dir for bundle""" - self._prepare_dir(self._bundle_dir) - - def _run_cmd(self, args): - if self._verbose: - print("Running:", " ".join(args)) - - ret = subprocess.run(args, check=True) - if ret.returncode != 0: - raise FotaError(ret.returncode) + self._do_custom_component(comp_dir, filename, comp_conf) - def _do_copy(self, src, dst): - if self._verbose: - print(f"Copy from {src} to {dst}") + return os.path.join(name, filename) - args = ["cp", "-Lf", src, dst] - - self._run_cmd(args) - - def _prepare_dir(self, wdir): + def _prepare_dir(self, wdir: str) -> None: if os.path.exists(wdir): if os.path.isfile(wdir): os.remove(wdir) @@ -103,61 +75,23 @@ def _prepare_dir(self, wdir): os.makedirs(wdir, exist_ok=True) - def _mkdir(self, new_dir): - Path(new_dir).mkdir(parents=True, exist_ok=True) - - def _update_metadata_var(self, conf, varname, metadata): - var = conf.get(varname, None) - - if var: - metadata[varname] = var.as_str - - def _add_runtime_dependencies(self, conf, metadata): - runtime_deps = conf.get("runtimeDependencies", []) - - if len(runtime_deps) == 0: - return - - meta_dependencies = [] - - for dependency in runtime_deps: - if len(dependency) == 0: - continue - - meta_dependency = { - "type": dependency["componentType"].as_str, - "requiredVersion": dependency.get("requiredVersion", "").as_str, - "minVersion": dependency.get("minVersion", "").as_str, - "maxVersion": dependency.get("maxVersion", "").as_str, - } - - # Add dependency with non-empty values only - meta_dependencies.append({k: v for k, v in meta_dependency.items() if v}) - - metadata["runtimeDependencies"] = meta_dependencies - - def _create_component_metadata(self, component, conf): - metadata = { - "type": conf.get("componentType", component).as_str, - "version": conf["version"].as_str, - } - metadata["fileName"] = conf.get( - "fileName", f'{metadata["type"]}-{metadata["version"]}.img' - ).as_str + def _run_cmd(self, args: list) -> None: + print("Running:", " ".join(args)) - self._update_metadata_var(conf, "requiredVersion", metadata) - self._update_metadata_var(conf, "minVersion", metadata) - self._update_metadata_var(conf, "maxVersion", metadata) - self._update_metadata_var(conf, "description", metadata) - self._update_metadata_var(conf, "annotations", metadata) - self._update_metadata_var(conf, "downloadTTL", metadata) + ret = subprocess.run(args, check=True) + if ret.returncode != 0: + raise FotaError(ret.returncode) - self._add_runtime_dependencies(conf, metadata) + def _do_copy(self, src: str, dst: str) -> None: + print(f"Copy from {src} to {dst}") + args = ["cp", "-Lf", src, dst] + self._run_cmd(args) - return metadata + def _do_raw_component( + self, work_dir: str, comp_dir: str, filename: str, conf: rouge.YamlValue + ) -> None: + """Create archive for raw component.""" - def _do_raw_component(self, work_dir, metadata, conf): - """Create archive for raw component""" self._prepare_dir(work_dir) block_entry = rouge.construct_entry(conf["partition"]) @@ -167,41 +101,44 @@ def _do_raw_component(self, work_dir, metadata, conf): file.truncate(block_entry.size()) block_entry.write(file, 0) - gz_image = os.path.join(self._bundle_dir, metadata["fileName"]) - + gz_image = os.path.join(comp_dir, filename) os.system(f"gzip < {image_file} > {gz_image}") - def _do_overlay_component(self, work_dir, metadata, conf): - component = metadata["type"] - overlay_type = conf["type"].as_str + def _do_overlay_component( + self, + work_dir: str, + comp_dir: str, + filename: str, + comp_type: str, + version: str, + conf: rouge.YamlValue, + ) -> None: + """Create overlay component via bitbake.""" + overlay_type = conf["type"].as_str self._prepare_dir(work_dir) - if self._verbose: - print(f"Creating {overlay_type} overlay image for {component}") - - annotats = metadata.get("annotations", {}) - annotats["type"] = overlay_type - metadata["annotations"] = annotats + print(f"Creating {overlay_type} overlay image for {comp_type}") repo = conf.get( "ostree_repo", - os.path.join(self._work_dir, "ostree_repo", component), + os.path.join(self._work_dir, "ostree_repo", comp_type), ).as_str + required_version = conf.get("requiredVersion", "").as_str + bbake_conf = [ ("AOS_ROOTFS_IMAGE_TYPE", overlay_type), - ("AOS_ROOTFS_IMAGE_VERSION", metadata["version"]), - ("AOS_ROOTFS_REF_VERSION", metadata.get("requiredVersion", "")), + ("AOS_ROOTFS_IMAGE_VERSION", version), + ("AOS_ROOTFS_REF_VERSION", required_version), ("AOS_ROOTFS_OSTREE_REPO", os.path.abspath(repo)), ( "AOS_ROOTFS_IMAGE_FILE", - os.path.join(os.path.abspath(self._bundle_dir), metadata["fileName"]), + os.path.join(os.path.abspath(comp_dir), filename), ), ] exclude_items = conf.get("exclude", None) - if exclude_items: bbake_conf.append( ( @@ -222,63 +159,137 @@ def _do_overlay_component(self, work_dir, metadata, conf): if ret != 0: raise FotaError(ret) - def _do_custom_component(self, metadata, conf): - src = conf["file"] - self._do_copy(src, os.path.join(self._bundle_dir, metadata["fileName"])) - - def _exclude_items(self, rootfs_dir, conf): - exclude = conf.get("exclude", None) - - if not exclude: - return + def _do_custom_component( + self, comp_dir: str, filename: str, conf: rouge.YamlValue + ) -> None: + """Copy custom component file.""" + + src = conf["file"].as_str + self._do_copy(src, os.path.join(comp_dir, filename)) + + +def create_update_item( + name: str, + comp_conf: rouge.YamlValue, + filename: str, + architecture: str, + os_name: str, + media_type: str, +) -> AosUpdateItem: + """Create AosUpdateItem from component config.""" + + comp_type = comp_conf.get("componentType", name).as_str + version = comp_conf["version"].as_str + + configuration = AosUpdateItemConfiguration( + runtimes=[ + AosIdentity( + codename=comp_type, + type="runtime", + ) + ] + ) - for item in exclude: - value = item.as_str + image = AosImage( + mediaType=media_type, + path=os.path.basename(filename), + archInfo=AosArchInfo(architecture=architecture), + osInfo=AosOsInfo(os=os_name), + ) - if self._verbose: - print(f"Exclude item: {value}") + dependencies = None + deps_conf = comp_conf.get("dependencies", None) + if deps_conf: + dependencies = [ + AosDependency( + identity=AosDependencyIdentity( + codename=dep["item"].as_str, + type="component", + ), + versions=dep["versions"].as_str, + ) + for dep in deps_conf + ] - if value[0] == os.sep: - value = value[1:] - os.system(f"rm -rf {os.path.join(rootfs_dir, value)}") + title = None + description = None + if comp_conf.get("title", None): + title = comp_conf["title"].as_str + if comp_conf.get("description", None): + description = comp_conf["description"].as_str + + return AosUpdateItem( + identity=AosIdentity( + codename=comp_type, + type="component", + title=title, + description=description, + ), + version=version, + sourceFolder=os.path.dirname(filename), + images=[image], + dependencies=dependencies if dependencies else None, + configuration=configuration if configuration else None, + ) def main(): - """main procedure""" - parser = argparse.ArgumentParser(description="fota") + """Main function.""" + parser = argparse.ArgumentParser(description="AOS Component builder") parser.add_argument( "conf", metavar="conf.yaml", type=str, help="YAML file with configuration" ) - parser.add_argument( - "-v", "--verbose", action="store_true", help="Enable verbose output" - ) - args = parser.parse_args() - conf = yaml.compose(open(args.conf, "r", encoding="utf-8")) - builder = FotaBuilder(rouge.YamlValue(conf), args.verbose) + with open(args.conf, "r", encoding="utf-8") as f: + conf = rouge.YamlValue(yaml.compose(f)) + + components_conf = conf.get("components", conf) - try: - builder.prepare_bundle_dir() + bundle_builder = BundleBuilder(components_conf, "component") + bundle_builder.prepare() - components = builder.get_components() + if os.path.exists(bundle_builder.output_dir): + shutil.rmtree(bundle_builder.output_dir) - for component in components.keys(): # pylint: disable=consider-using-dict-items - print(f"Processing {component}...") + comp_builder = ComponentBuilder(components_conf, bundle_builder.output_dir) + + items = components_conf["items"] + ret = 0 + + for name in items.keys(): + comp_conf = items[name] + + if not comp_conf.get("enabled", True).as_bool: + print(f"Skipping disabled component: {name}") + continue + + print(f"Building component: {name}") + + try: + filename = comp_builder.build_component(name, comp_conf) + + item = create_update_item( + name, + comp_conf, + filename, + bundle_builder._architecture, + bundle_builder._os, + comp_conf.get("mediaType", LAYER_MEDIA_TYPE ).as_str, + ) + bundle_builder.add_item(item) - if not components[component].get("enabled", True).as_bool: - if args.verbose: - print(f"{component} skipped") + except FotaError as err: + print(f"Failed to build component {name}: {err}") + ret = 1 - continue + if ret != 0: + print("Some components failed to build") - builder.process_component(component, components[component]) + return ret - builder.create_metadata() - builder.create_bundle() - except FotaError as err: - print(err) + bundle_builder.build() return 0 diff --git a/scripts/layer_builder.py b/scripts/layer_builder.py index 41c83998..c029a0f0 100755 --- a/scripts/layer_builder.py +++ b/scripts/layer_builder.py @@ -1,88 +1,170 @@ #!/usr/bin/env python3 -""" Script for building Aos layers """ +"""Script for building AOS layers with unified metadata generation.""" + import argparse import os +import shutil import sys +from typing import Dict, List, Optional import yaml from bitbake import call_bitbake +from metadata_builder import BundleBuilder +from moulin import rouge + + +def resolve_parent_target( + name: str, + item_conf: rouge.YamlValue, + items: rouge.YamlValue, +) -> Optional[str]: + """Return parent layer bitbake target based on item's dependency, or None.""" + + dep_conf = item_conf.get("dependency", None) + if not dep_conf: + return None + + parent_name = dep_conf["item"].as_str + + if parent_name not in items.keys(): + raise ValueError( + f"Layer '{name}' depends on unknown item '{parent_name}'" + ) + + return items[parent_name]["target"].as_str + + +def order_items(items: rouge.YamlValue) -> List[str]: + """Topologically sort items so every parent is built before its children.""" + + graph: Dict[str, Optional[str]] = {} + for name in items.keys(): + item_conf = items[name] + dep_conf = item_conf.get("dependency", None) + parent = dep_conf["item"].as_str if dep_conf else None + + if parent is not None and parent not in items.keys(): + raise ValueError( + f"Layer '{name}' depends on unknown item '{parent}'" + ) + + graph[name] = parent + + ordered: List[str] = [] + visiting: set = set() + visited: set = set() + + def visit(node: str) -> None: + if node in visited: + return + + if node in visiting: + raise ValueError( + f"Cyclic layer dependency detected involving '{node}'" + ) + + visiting.add(node) + parent = graph[node] + + if parent is not None: + visit(parent) + + visiting.remove(node) + visited.add(node) + ordered.append(node) + for name in graph: + visit(name) -def read_layers_file(enabled_file): - """Reads layers file.""" - layers = [] + return ordered - for line in enabled_file: - line = line.strip() - if len(line) > 0 and line[0] != "#": - if line not in layers: - layers.append(line) +def build_layer( + layers_conf: rouge.YamlValue, + layer_conf: rouge.YamlValue, + layer_dir: str, + parent_target: Optional[str] = None, +) -> int: + """Build a single layer using bitbake into its own subdirectory.""" - return layers + if os.path.exists(layer_dir): + shutil.rmtree(layer_dir) + os.makedirs(layer_dir) + + bbake_conf = [ + ("AOS_BASE_IMAGE", layers_conf["base_image"].as_str), + ("AOS_LAYER_DEPLOY_DIR", layer_dir), + ] + + if parent_target: + # Scope to this recipe only; otherwise the parent layer (also + # parsed in the same bitbake invocation) would inherit the same + # AOS_PARENT_LAYER and create a self-dependency loop. + target = layer_conf["target"].as_str + bbake_conf.append((f"AOS_PARENT_LAYER:pn-{target}", parent_target)) + + version = layer_conf.get("version", None) + if version: + bbake_conf.append(("AOS_LAYER_VERSION", version.as_str)) + + return call_bitbake( + layers_conf.get("work_dir", "workdir").as_str, + layers_conf.get("yocto_dir", "yocto").as_str, + layers_conf.get("build_dir", "build").as_str, + layer_conf["target"].as_str, + bbake_conf, + ) def main(): - """Main function""" - ret = 0 - parser = argparse.ArgumentParser(description="fota") + """Main function.""" + parser = argparse.ArgumentParser(description="AOS Layer builder") parser.add_argument( "conf", metavar="conf.yaml", type=str, help="YAML file with configuration" ) - parser.add_argument( - "-v", "--verbose", action="store_true", help="Enable verbose output" - ) - parser.add_argument("-l", "--layers", nargs="*", help="List of enabled layers") - parser.add_argument( - "-f", "--file", action="store", help="Config file with enabled layers" - ) - args = parser.parse_args() - with open(args.conf, "r", encoding="utf-8") as conf_file: - conf = yaml.load(conf_file, Loader=yaml.CLoader) + with open(args.conf, "r", encoding="utf-8") as f: + conf = rouge.YamlValue(yaml.compose(f)) + + layers_conf = conf.get("layers", conf) + + builder = BundleBuilder(layers_conf, "layer") + builder.prepare() + + ret = 0 + items = layers_conf["items"] + build_order = order_items(items) + + for name in build_order: + item_conf = items[name] - if args.layers is not None or args.file is not None: - enabled_layers = [] + if not item_conf.get("enabled", True).as_bool: + continue - if args.layers is not None: - enabled_layers = list(args.layers) + parent_target = resolve_parent_target(name, item_conf, items) - if args.file is not None: - try: - with open(args.file, "r", encoding="utf-8") as enabled_file: - enabled_layers.extend(read_layers_file(enabled_file)) - except FileNotFoundError: - print(f"File {args.file} can't be opened") - else: - enabled_layers = None + print(f"Building layer: {name}") - layers_conf = conf["layers"] + layer_dir = os.path.join(builder._output_dir, name) + result = build_layer(layers_conf, item_conf, layer_dir, parent_target) - for layer in layers_conf["items"]: - layer_conf = layers_conf["items"][layer] + if result != 0: + print(f"Failed to build layer: {name}") - if enabled_layers: - enabled = layer in enabled_layers + ret = result else: - enabled = layer_conf.get("enabled", True) - - bbake_conf = [ - ("AOS_BASE_IMAGE", layers_conf["base_image"]), - ("AOS_LAYER_DEPLOY_DIR", os.path.abspath(layers_conf["output_dir"])), - ] - - if enabled: - ret = call_bitbake( - conf.get("work_dir", "layers"), - layers_conf.get("yocto_dir", "yocto"), - layers_conf.get("build_dir", "build"), - layer_conf["target"], - bbake_conf, - ) + builder.add_item_from_conf(name, item_conf) + + if ret != 0: + print("Some layers failed to build") + + return ret + + builder.build() - return ret + return 0 if __name__ == "__main__": diff --git a/scripts/metadata_builder.py b/scripts/metadata_builder.py new file mode 100644 index 00000000..1831bfed --- /dev/null +++ b/scripts/metadata_builder.py @@ -0,0 +1,281 @@ +#!/usr/bin/env python3 +"""Unified metadata module for AOS update items (layers and components).""" + +import os +from typing import List, Literal, Optional + +import yaml +from moulin import rouge +from pydantic import BaseModel, Field + +LAYER_MEDIA_TYPE = "application/vnd.oci.image.layer.v1.tar+gzip" + +ItemType = Literal["layer", "component", "service", "runtime"] + + +class AosArchInfo(BaseModel): + """CPU architecture information.""" + + architecture: str # amd64, arm64, arm + variant: Optional[str] = None + + +class AosOsInfo(BaseModel): + """Operating system information.""" + + os: str = "linux" + version: Optional[str] = None + features: Optional[List[str]] = None + + +class AosIdentity(BaseModel): + """AOS object identifier.""" + + codename: str + type: ItemType + title: Optional[str] = None + description: Optional[str] = None + + +class AosImage(BaseModel): + """Image information for an update item.""" + + media_type: str = Field(alias="mediaType") + arch_info: AosArchInfo = Field(alias="archInfo") + os_info: AosOsInfo = Field(default_factory=AosOsInfo, alias="osInfo") + source_folder: Optional[str] = Field(default=None, alias="sourceFolder") + path: Optional[str] = None + + class Config: + populate_by_name = True + + +class AosUpdateItemConfiguration(BaseModel): + """Configuration for an update item""" + + runtimes: list[AosIdentity] + + +class AosDependencyIdentity(BaseModel): + """Identity for dependency reference.""" + + codename: str + type: ItemType + + +class AosDependency(BaseModel): + """Dependency on another AOS object.""" + + identity: AosDependencyIdentity + versions: str # semver constraint, e.g., ">=1.0.0", "5.2.1" + + +class AosUpdateItem(BaseModel): + """Single update item (layer, component, or service).""" + + identity: AosIdentity + version: str + source_folder: Optional[str] = Field(default=None, alias="sourceFolder") + images: List[AosImage] + configuration: Optional[AosUpdateItemConfiguration] = None + dependencies: Optional[List[AosDependency]] = None + + +class AosPublisher(BaseModel): + """Publisher information.""" + + company: Optional[str] = None + author: Optional[str] = None + + +class AosPublish(BaseModel): + """Publish configuration.""" + + tls_key: Optional[str] = Field(default=None, alias="tlsKey") + domain: Optional[str] = None + + class Config: + populate_by_name = True + + +class AosUploadMetaConfig(BaseModel): + """Root configuration for update items upload.""" + + schema_version: int = Field(default=2, alias="schemaVersion") + publisher: Optional[AosPublisher] = None + publish: Optional[AosPublish] = None + items: List[AosUpdateItem] + + class Config: + populate_by_name = True + + +def write_config_yaml(config: AosUploadMetaConfig, output_path: str) -> None: + """Write AosUploadMetaConfig to YAML file.""" + + data = config.model_dump(by_alias=True, exclude_none=True) + + with open(output_path, "w", encoding="utf-8") as f: + yaml.dump( + data, f, default_flow_style=False, sort_keys=False, allow_unicode=True + ) + + +class BundleBuilder: + """Builder for creating update metadata and organizing output artifacts.""" + + def __init__(self, conf: rouge.YamlValue, item_type: ItemType) -> None: + self._item_type = item_type + self._conf = conf + + self._machine = conf.get("machine", "genericx86-64").as_str + self._architecture = conf.get("architecture", "amd64").as_str + self._os = conf.get("os", "linux").as_str + self._output_dir = os.path.abspath(conf.get("output_dir", "../output").as_str) + + publisher_conf = conf.get("publisher", None) + self._publisher = None + if publisher_conf: + company = publisher_conf.get("company", None) + author = publisher_conf.get("author", None) + self._publisher = AosPublisher( + company=company.as_str if company else None, + author=author.as_str if author else None, + ) + + publish_conf = conf.get("publish", None) + self._publish = None + if publish_conf: + tls_key = publish_conf.get("tlsKey", None) + domain = publish_conf.get("domain", None) + self._publish = AosPublish( + tlsKey=tls_key.as_str if tls_key else None, + domain=domain.as_str if domain else None, + ) + + self._items: List[AosUpdateItem] = [] + + def prepare(self) -> None: + """Prepare output directory.""" + + os.makedirs(self._output_dir, exist_ok=True) + + def add_item(self, item: AosUpdateItem) -> None: + """Add update item.""" + + self._items.append(item) + + def add_item_from_conf(self, name: str, item_conf: rouge.YamlValue) -> bool: + """Create and add item from config. Returns True on success.""" + + version = item_conf.get("version", "1.0.0").as_str + codename = item_conf.get("codename", name).as_str + os_name = item_conf.get("os", self._os).as_str + architecture = item_conf.get("architecture", self._architecture).as_str + + archive_path = self._find_archive(name, item_conf) + if not archive_path: + print(f"Warning: Archive not found for: {name}") + + return False + + image = AosImage( + mediaType=item_conf.get("mediaType", LAYER_MEDIA_TYPE).as_str, + path=os.path.relpath(archive_path, self._output_dir), + archInfo=AosArchInfo(architecture=architecture), + osInfo=AosOsInfo(os=os_name), + ) + + title = item_conf.get("title", None) + description = item_conf.get("description", None) + item = AosUpdateItem( + identity=AosIdentity( + codename=codename, + type=self._item_type, + title=title.as_str if title else None, + description=description.as_str if description else None, + ), + version=version, + images=[image], + dependencies=self._create_dependencies(item_conf), + ) + + self._items.append(item) + + return True + + def build(self) -> None: + """Write config.yaml to output_dir/.""" + + if not self._items: + print("No items to bundle") + + return + + config = AosUploadMetaConfig( + items=self._items, + publisher=self._publisher, + publish=self._publish, + ) + config_path = os.path.join(self._output_dir, "config.yaml") + write_config_yaml(config, config_path) + + print(f"Created: {config_path}") + + @property + def output_dir(self) -> str: + """Return output directory path.""" + + return self._output_dir + + def _find_archive(self, name: str, item_conf: rouge.YamlValue) -> Optional[str]: + """Find built archive in item subdirectory.""" + + version = item_conf.get("version", "1.0.0").as_str + os_name = item_conf.get("os", self._os).as_str + architecture = item_conf.get("architecture", self._architecture).as_str + item_dir = os.path.join(self._output_dir, name) + + if not os.path.isdir(item_dir): + return None + + filename = f"{os_name}-{architecture}-{version}.tar.gz" + filepath = os.path.join(item_dir, filename) + + if os.path.exists(filepath): + return filepath + + # Fallback: find any tar.gz in the directory + for fname in os.listdir(item_dir): + if fname.endswith(".tar.gz"): + return os.path.join(item_dir, fname) + + return None + + def _create_dependencies( + self, item_conf: rouge.YamlValue + ) -> Optional[List[AosDependency]]: + """Create dependencies list from a singular `dependency` entry. + + Expected YAML form: + dependency: + item: + versions: + + `item` becomes the codename and the dependency type is the + builder's own item_type (layer or component). + """ + + dep_conf = item_conf.get("dependency", None) + if not dep_conf: + return None + + return [ + AosDependency( + identity=AosDependencyIdentity( + codename=dep_conf["item"].as_str, + type=self._item_type, + ), + versions=dep_conf["versions"].as_str, + ) + ] diff --git a/scripts/sdk_builder.py b/scripts/sdk_builder.py new file mode 100755 index 00000000..e8a35915 --- /dev/null +++ b/scripts/sdk_builder.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +"""Script for building Aos layers""" +import argparse +import os +import shutil +import sys + +import yaml +from bitbake import call_bitbake + + +def main(): + """Main function""" + parser = argparse.ArgumentParser(description="SDK builder") + + parser.add_argument( + "conf", metavar="conf.yaml", type=str, help="YAML file with configuration" + ) + + args = parser.parse_args() + + with open(args.conf, "r", encoding="utf-8") as conf_file: + conf = yaml.load(conf_file, Loader=yaml.CLoader) + + sdk_conf = conf["sdk"] + + yocto_dir = sdk_conf.get("yocto_dir", "yocto") + build_dir = sdk_conf.get("build_dir", "build") + + ret = call_bitbake( + conf.get("work_dir", "workdir"), + yocto_dir, + build_dir, + sdk_conf["base_image"], + task="populate_sdk", + do_clean=True, + ) + + if ret != 0: + return ret + + try: + # Yocto doesn't allow to override SDK_DEPLOY variable, regardless of documentation. + # It is strictly set to ${TOPDIR}/tmp/deploy/sdk in populate_sdk_base.bbclass. + # As WA copy SDK to the output directory manually. + + sdk_dir = os.path.join(yocto_dir, build_dir, "tmp", "deploy", "sdk") + + shutil.copytree( + sdk_dir, + sdk_conf.get("output_dir", "../output/sdk"), + dirs_exist_ok=True, + ) + + shutil.rmtree(sdk_dir, ignore_errors=True) + except OSError as e: + print(f"Failed to copy sdk: {e}") + + return 1 + + return 0 + + +if __name__ == "__main__": + sys.exit(main())