Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cm/app/aoscore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ void AosCore::InitSMController()
config.mCertStorage = mConfig.mCertStorage;
config.mCMServerURL = mConfig.mCMServerURL;

auto err = mSMController.Init(config, mCommunication, mIAMClient, mCertLoader, mCryptoProvider, mCommunication,
auto err = mSMController.Init(config, mCommunication, mIAMClient, mCertLoader, mCryptoProvider, mImageManager,
mAlerts, mCommunication, mCommunication, mMonitoring, mLauncher, mNodeInfoProvider);
AOS_ERROR_CHECK_AND_THROW(err, "can't initialize SM controller");
}
Expand Down
36 changes: 9 additions & 27 deletions src/cm/smcontroller/smcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace aos::cm::smcontroller {

Error SMController::Init(const Config& config, cloudconnection::CloudConnectionItf& cloudConnection,
iamclient::CertProviderItf& certProvider, crypto::CertLoaderItf& certLoader,
crypto::x509::ProviderItf& cryptoProvider, imagemanager::BlobInfoProviderItf& blobInfoProvider,
crypto::x509::ProviderItf& cryptoProvider, imagemanager::ItemInfoProviderItf& itemInfoProvider,
alerts::ReceiverItf& alertsReceiver, SenderItf& logSender, launcher::SenderItf& envVarsStatusSender,
monitoring::ReceiverItf& monitoringReceiver, launcher::InstanceStatusReceiverItf& instanceStatusReceiver,
nodeinfoprovider::SMInfoReceiverItf& smInfoReceiver, bool insecureConn)
Expand All @@ -37,7 +37,7 @@ Error SMController::Init(const Config& config, cloudconnection::CloudConnectionI
mCertProvider = &certProvider;
mCertLoader = &certLoader;
mCryptoProvider = &cryptoProvider;
mBlobInfoProvider = &blobInfoProvider;
mItemInfoProvider = &itemInfoProvider;
mAlertsReceiver = &alertsReceiver;
mLogSender = &logSender;
mEnvVarsStatusSender = &envVarsStatusSender;
Expand Down Expand Up @@ -286,37 +286,19 @@ grpc::Status SMController::RegisterSM(grpc::ServerContext*
return grpc::Status::OK;
}

grpc::Status SMController::GetBlobsInfos(grpc::ServerContext* /*context*/,
const servicemanager::v5::BlobsInfosRequest* request, servicemanager::v5::BlobsInfos* response)
grpc::Status SMController::GetBlobsInfos(grpc::ServerContext*, const servicemanager::v5::BlobsInfosRequest* request,
servicemanager::v5::BlobsInfos* response)
{
LOG_DBG() << "Get blobs info request received: digests count=" << request->digests_size();

std::vector<StaticString<oci::cDigestLen>> digests;
digests.reserve(request->digests_size());
LOG_DBG() << "Get blobs info request received" << Log::Field("digestsCount", request->digests_size());

for (int i = 0; i < request->digests_size(); ++i) {
digests.push_back(request->digests(i).c_str());
}

auto digestsArray = Array<StaticString<oci::cDigestLen>>(digests.data(), digests.size());

std::vector<BlobInfo> blobsInfo(request->digests_size());
auto blobsInfoArray = Array<BlobInfo>(blobsInfo.data(), blobsInfo.size());

if (auto err = mBlobInfoProvider->GetBlobsInfos(digestsArray, blobsInfoArray); !err.IsNone()) {
return grpc::Status(grpc::StatusCode::INTERNAL, err.Message());
}

if (blobsInfoArray.Size() != digestsArray.Size()) {
return grpc::Status(grpc::StatusCode::NOT_FOUND, "some blobs info not found");
}
StaticString<cURLLen> digestURL;

for (const auto& blobInfo : blobsInfo) {
if (blobInfo.mURLs.Size() != 1) {
return grpc::Status(grpc::StatusCode::NOT_FOUND, "blob URL not found");
if (auto err = mItemInfoProvider->GetBlobURL(request->digests(i).c_str(), digestURL); !err.IsNone()) {
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetBlobURL errors are always mapped to grpc::StatusCode::INTERNAL. This changes prior behavior where missing blob info/URL resulted in NOT_FOUND. If GetBlobURL returns ErrorEnum::eNotFound, return grpc::StatusCode::NOT_FOUND (and keep INTERNAL for unexpected failures) so clients can distinguish missing data from server errors.

Suggested change
if (auto err = mItemInfoProvider->GetBlobURL(request->digests(i).c_str(), digestURL); !err.IsNone()) {
if (auto err = mItemInfoProvider->GetBlobURL(request->digests(i).c_str(), digestURL); !err.IsNone()) {
if (err == ErrorEnum::eNotFound) {
return grpc::Status(grpc::StatusCode::NOT_FOUND, err.Message());
}

Copilot uses AI. Check for mistakes.
return grpc::Status(grpc::StatusCode::INTERNAL, err.Message());
}

response->add_urls(blobInfo.mURLs[0].CStr());
response->add_urls(digestURL.CStr());
}

return grpc::Status::OK;
Expand Down
8 changes: 4 additions & 4 deletions src/cm/smcontroller/smcontroller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <grpcpp/server.h>
#include <servicemanager/v5/servicemanager.grpc.pb.h>

#include <core/cm/imagemanager/itf/blobinfoprovider.hpp>
#include <core/cm/imagemanager/itf/iteminfoprovider.hpp>
#include <core/cm/launcher/itf/envvarhandler.hpp>
#include <core/cm/launcher/itf/instancerunner.hpp>
#include <core/cm/launcher/itf/monitoringprovider.hpp>
Expand Down Expand Up @@ -49,7 +49,7 @@ class SMController : public SMControllerItf,
* @param certProvider certificate provider.
* @param certLoader certificate loader.
* @param cryptoProvider crypto provider.
* @param blobInfoProvider blob info provider.
* @param itemInfoProvider item info provider.
* @param alertsReceiver alerts receiver.
* @param logSender log sender.
* @param envVarsStatusSender env vars status sender.
Expand All @@ -61,7 +61,7 @@ class SMController : public SMControllerItf,
*/
Error Init(const Config& config, cloudconnection::CloudConnectionItf& cloudConnection,
aos::iamclient::CertProviderItf& certProvider, crypto::CertLoaderItf& certLoader,
crypto::x509::ProviderItf& cryptoProvider, imagemanager::BlobInfoProviderItf& blobInfoProvider,
crypto::x509::ProviderItf& cryptoProvider, imagemanager::ItemInfoProviderItf& itemInfoProvider,
alerts::ReceiverItf& alertsReceiver, SenderItf& logSender, launcher::SenderItf& envVarsStatusSender,
monitoring::ReceiverItf& monitoringReceiver, launcher::InstanceStatusReceiverItf& instanceStatusReceiver,
nodeinfoprovider::SMInfoReceiverItf& smInfoReceiver, bool insecureConn = false);
Expand Down Expand Up @@ -202,7 +202,7 @@ class SMController : public SMControllerItf,
crypto::CertLoaderItf* mCertLoader {};
crypto::x509::ProviderItf* mCryptoProvider {};
aos::iamclient::CertProviderItf* mCertProvider {};
imagemanager::BlobInfoProviderItf* mBlobInfoProvider {};
imagemanager::ItemInfoProviderItf* mItemInfoProvider {};
alerts::ReceiverItf* mAlertsReceiver {};
SenderItf* mLogSender {};
launcher::SenderItf* mEnvVarsStatusSender {};
Expand Down
16 changes: 5 additions & 11 deletions src/cm/smcontroller/tests/smcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
#include <cm/smcontroller/smcontroller.hpp>

#include "stubs/alertsreceiverstub.hpp"
#include "stubs/blobinfoproviderstub.hpp"
#include "stubs/certloaderstub.hpp"
#include "stubs/certproviderstub.hpp"
#include "stubs/cloudconnectionstub.hpp"
#include "stubs/instancestatusreceiverstub.hpp"
#include "stubs/iteminfoproviderstub.hpp"
#include "stubs/launchersenderstub.hpp"
#include "stubs/monitoringreceiverstub.hpp"
#include "stubs/smclientstub.hpp"
Expand Down Expand Up @@ -43,7 +43,7 @@ class SMControllerTest : public Test {
mConfig.mCMServerURL = "localhost:8094";

auto err = mSMController.Init(mConfig, mCloudConnection, mCertProvider, mCertLoader, mX509Provider,
mBlobInfoProvider, mAlertsReceiver, mSMControllerSender, mLauncherSender, mMonitoringReceiver,
mItemInfoProvider, mAlertsReceiver, mSMControllerSender, mLauncherSender, mMonitoringReceiver,
mInstanceStatusReceiver, mSMInfoReceiver, true);
ASSERT_TRUE(err.IsNone()) << err.Message();

Expand Down Expand Up @@ -94,7 +94,7 @@ class SMControllerTest : public Test {
iamclient::CertProviderStub mCertProvider;
crypto::CertLoaderStub mCertLoader;
crypto::x509::ProviderStub mX509Provider;
BlobInfoProviderStub mBlobInfoProvider;
ItemInfoProviderStub mItemInfoProvider;
alerts::ReceiverStub mAlertsReceiver;
SenderStub mSMControllerSender;
launcher::SenderStub mLauncherSender;
Expand Down Expand Up @@ -727,14 +727,8 @@ TEST_F(SMControllerTest, GetBlobsInfos)
const std::string digest = "sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
const std::string url = "https://example.com/blob.tar";

// 1) Setup blob info in stub
BlobInfo blobInfo;
blobInfo.mDigest.Assign(digest.c_str());
blobInfo.mSize = 1024;
if (auto err = blobInfo.mURLs.EmplaceBack(url.c_str()); !err.IsNone()) {
FAIL() << "Failed to set blob URL: " << err.Message();
}
mBlobInfoProvider.SetBlobInfo(String(digest.c_str()), blobInfo);
// 1) Setup blob URL in stub
mItemInfoProvider.SetBlobURL(digest, url);

// 2) Start client
SMClientStub client;
Expand Down
61 changes: 0 additions & 61 deletions src/cm/smcontroller/tests/stubs/blobinfoproviderstub.hpp

This file was deleted.

102 changes: 102 additions & 0 deletions src/cm/smcontroller/tests/stubs/iteminfoproviderstub.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2025 EPAM Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef AOS_CM_SMCONTROLLER_TESTS_STUBS_ITEMINFOPROVIDERSTUB_HPP_
#define AOS_CM_SMCONTROLLER_TESTS_STUBS_ITEMINFOPROVIDERSTUB_HPP_

#include <string>
#include <unordered_map>

#include <core/cm/imagemanager/itf/iteminfoprovider.hpp>

namespace aos::cm::smcontroller {

/**
* Item info provider stub.
*/
class ItemInfoProviderStub : public imagemanager::ItemInfoProviderItf {
public:
/**
* Sets blob URL by its digest.
*
* @param digest blob digest.
* @param url blob URL.
*/
void SetBlobURL(const std::string& digest, const std::string& url) { mBlobURLMap[digest] = url; }

/**
* Returns update item index digest.
*
* @param itemID update item ID.
* @param version update item version.
* @param[out] digest result item digest.
* @return Error.
*/
Error GetIndexDigest(const String& itemID, const String& version, String& digest) const override
{
(void)itemID;
(void)version;
(void)digest;

return ErrorEnum::eNone;
}

/**
* Returns blob path by its digest.
*
* @param digest blob digest.
* @param[out] path result blob path.
* @return Error.
*/
Error GetBlobPath(const String& digest, String& path) const override
{
(void)digest;
(void)path;

return ErrorEnum::eNone;
}

/**
* Returns blob URL by its digest.
*
* @param digest blob digest.
* @param[out] url result blob URL.
* @return Error.
*/
Error GetBlobURL(const String& digest, String& url) const override
{
auto it = mBlobURLMap.find(digest.CStr());
if (it == mBlobURLMap.end()) {
return Error(ErrorEnum::eNotFound, "blob URL not found");
}

url = it->second.c_str();

return ErrorEnum::eNone;
}

/**
* Returns item current version.
*
* @param itemID update item ID.
* @param[out] version result item version.
* @return Error.
*/
Error GetItemCurrentVersion(const String& itemID, String& version) const override
{
(void)itemID;
(void)version;

return ErrorEnum::eNone;
}

private:
std::unordered_map<std::string, std::string> mBlobURLMap;
};

} // namespace aos::cm::smcontroller

#endif
Loading
Loading