diff --git a/src/cm/communication/cloudprotocol/common.cpp b/src/cm/communication/cloudprotocol/common.cpp index 6b8b1d66..d120c53e 100644 --- a/src/cm/communication/cloudprotocol/common.cpp +++ b/src/cm/communication/cloudprotocol/common.cpp @@ -86,14 +86,24 @@ Error ToJSON(const InstanceIdent& instanceIdent, Poco::JSON::Object& json) { AosIdentity identity; - identity.mID = instanceIdent.mItemID.CStr(); + if (instanceIdent.mPreinstalled) { + identity.mCodename = instanceIdent.mItemID.CStr(); + } else { + identity.mID = instanceIdent.mItemID.CStr(); + } + json.set("item", CreateAosIdentity(identity)); } { AosIdentity identity; - identity.mID = instanceIdent.mSubjectID.CStr(); + if (instanceIdent.mPreinstalled) { + identity.mCodename = instanceIdent.mSubjectID.CStr(); + } else { + identity.mID = instanceIdent.mSubjectID.CStr(); + } + json.set("subject", CreateAosIdentity(identity)); } diff --git a/src/cm/communication/cloudprotocol/tests/common.cpp b/src/cm/communication/cloudprotocol/tests/common.cpp index 1d98e66f..1525ac60 100644 --- a/src/cm/communication/cloudprotocol/tests/common.cpp +++ b/src/cm/communication/cloudprotocol/tests/common.cpp @@ -119,6 +119,22 @@ TEST_F(CloudProtocolCommon, InstanceIdent) EXPECT_EQ(common::utils::Stringify(json), cJSON); } +TEST_F(CloudProtocolCommon, PreinstalledInstanceIdent) +{ + constexpr auto cJSON = R"({"item":{"codename":"item-id"},"subject":{"codename":"subject-id"},"instance":42})"; + + InstanceIdent instanceIdent; + instanceIdent.mItemID = "item-id"; + instanceIdent.mSubjectID = "subject-id"; + instanceIdent.mInstance = 42; + instanceIdent.mPreinstalled = true; + + auto json = Poco::makeShared(Poco::JSON_PRESERVE_KEY_ORDER); + ASSERT_EQ(ToJSON(instanceIdent, *json), ErrorEnum::eNone); + + EXPECT_EQ(common::utils::Stringify(json), cJSON); +} + TEST_F(CloudProtocolCommon, InstanceFilter) { constexpr auto cJSON = R"({"item":{"id":"item-id"},"subject":{"id":"subject-id"},"instance":42})"; diff --git a/src/cm/communication/cloudprotocol/tests/unitstatus.cpp b/src/cm/communication/cloudprotocol/tests/unitstatus.cpp index 125f9543..5a267c64 100644 --- a/src/cm/communication/cloudprotocol/tests/unitstatus.cpp +++ b/src/cm/communication/cloudprotocol/tests/unitstatus.cpp @@ -311,16 +311,16 @@ TEST_F(CloudProtocolUnitStatus, PreinstalledInstances) unitStatus->mInstances->Back().mInstances.Back().mError = ErrorEnum::eFailed; unitStatus->mInstances->EmplaceBack(); - unitStatus->mInstances->Back().mItemID = "itemID2"; - unitStatus->mInstances->Back().mSubjectID = "subjectID2"; - unitStatus->mInstances->Back().mVersion = "version2"; + unitStatus->mInstances->Back().mItemID = "itemID2"; + unitStatus->mInstances->Back().mSubjectID = "subjectID2"; + unitStatus->mInstances->Back().mVersion = "version2"; + unitStatus->mInstances->Back().mPreinstalled = true; unitStatus->mInstances->Back().mInstances.EmplaceBack(); - unitStatus->mInstances->Back().mInstances.Back().mPreinstalled = true; - unitStatus->mInstances->Back().mInstances.Back().mInstance = 1; - unitStatus->mInstances->Back().mInstances.Back().mNodeID = "nodeID2"; - unitStatus->mInstances->Back().mInstances.Back().mRuntimeID = "runtimeID2"; - unitStatus->mInstances->Back().mInstances.Back().mState = InstanceStateEnum::eActivating; + unitStatus->mInstances->Back().mInstances.Back().mInstance = 1; + unitStatus->mInstances->Back().mInstances.Back().mNodeID = "nodeID2"; + unitStatus->mInstances->Back().mInstances.Back().mRuntimeID = "runtimeID2"; + unitStatus->mInstances->Back().mInstances.Back().mState = InstanceStateEnum::eActivating; auto json = Poco::makeShared(Poco::JSON_PRESERVE_KEY_ORDER); diff --git a/src/cm/communication/cloudprotocol/unitstatus.cpp b/src/cm/communication/cloudprotocol/unitstatus.cpp index 9aa24db5..7e6070c5 100644 --- a/src/cm/communication/cloudprotocol/unitstatus.cpp +++ b/src/cm/communication/cloudprotocol/unitstatus.cpp @@ -240,14 +240,10 @@ Poco::JSON::Object::Ptr InstanceToJSON(const UnitInstancesStatuses& statuses) { auto json = Poco::makeShared(Poco::JSON_PRESERVE_KEY_ORDER); - const auto isPreinstalled = statuses.mInstances.FindIf([](const UnitInstanceStatus& status) { - return status.mPreinstalled; - }) != statuses.mInstances.end(); - { AosIdentity identity; - if (isPreinstalled) { + if (statuses.mPreinstalled) { identity.mCodename = statuses.mItemID.CStr(); } else { identity.mID = statuses.mItemID.CStr(); @@ -259,7 +255,7 @@ Poco::JSON::Object::Ptr InstanceToJSON(const UnitInstancesStatuses& statuses) { AosIdentity identity; - if (isPreinstalled) { + if (statuses.mPreinstalled) { identity.mCodename = statuses.mSubjectID.CStr(); } else { identity.mID = statuses.mSubjectID.CStr(); diff --git a/src/cm/database/database.cpp b/src/cm/database/database.cpp index 46c96abf..149779a4 100644 --- a/src/cm/database/database.cpp +++ b/src/cm/database/database.cpp @@ -168,8 +168,8 @@ Error Database::AddStorageStateInfo(const storagestate::InstanceInfo& info) StorageStateInstanceInfoRow row; FromAos(info, row); - *mSession << "INSERT INTO storagestate (itemID, subjectID, instance, type, storageQuota, " - "stateQuota, stateChecksum) VALUES (?, ?, ?, ?, ?, ?, ?);", + *mSession << "INSERT INTO storagestate (itemID, subjectID, instance, type, preinstalled, storageQuota, " + "stateQuota, stateChecksum) VALUES (?, ?, ?, ?, ?, ?, ?, ?);", bind(row), now; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); @@ -185,9 +185,10 @@ Error Database::RemoveStorageStateInfo(const InstanceIdent& instanceIdent) try { Poco::Data::Statement statement {*mSession}; - statement << "DELETE FROM storagestate WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + statement << "DELETE FROM storagestate " + "WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ? AND preinstalled = ?;", bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), - bind(instanceIdent.mType.ToString().CStr()); + bind(instanceIdent.mType.ToString().CStr()), bind(instanceIdent.mPreinstalled); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -205,8 +206,8 @@ Error Database::GetAllStorageStateInfo(Array& info) try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, type, storageQuota, stateQuota, stateChecksum FROM " - "storagestate;", + *mSession << "SELECT itemID, subjectID, instance, type, preinstalled, storageQuota, stateQuota, stateChecksum " + "FROM storagestate;", into(rows), now; auto instanceInfo = std::make_unique(); @@ -231,10 +232,11 @@ Error Database::GetStorageStateInfo(const InstanceIdent& instanceIdent, storages StorageStateInstanceInfoRow row; Poco::Data::Statement statement {*mSession}; - statement << "SELECT itemID, subjectID, instance, type, storageQuota, stateQuota, stateChecksum FROM " - "storagestate WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + statement << "SELECT itemID, subjectID, instance, type, preinstalled, storageQuota, stateQuota, stateChecksum " + "FROM storagestate " + "WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ? AND preinstalled = ?;", bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), - bind(instanceIdent.mType.ToString().CStr()), into(row); + bind(instanceIdent.mType.ToString().CStr()), bind(instanceIdent.mPreinstalled), into(row); if (statement.execute() == 0) { return ErrorEnum::eNotFound; @@ -257,10 +259,11 @@ Error Database::UpdateStorageStateInfo(const storagestate::InstanceInfo& info) Poco::Data::BLOB checksumBlob(info.mStateChecksum.begin(), info.mStateChecksum.Size()); statement << "UPDATE storagestate SET storageQuota = ?, stateQuota = ?, stateChecksum = ? WHERE " - "itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + "itemID = ? AND subjectID = ? AND instance = ? AND type = ? AND preinstalled = ?;", bind(info.mStorageQuota), bind(info.mStateQuota), bind(checksumBlob), bind(info.mInstanceIdent.mItemID.CStr()), bind(info.mInstanceIdent.mSubjectID.CStr()), - bind(info.mInstanceIdent.mInstance), bind(info.mInstanceIdent.mType.ToString().CStr()); + bind(info.mInstanceIdent.mInstance), bind(info.mInstanceIdent.mType.ToString().CStr()), + bind(info.mInstanceIdent.mPreinstalled); if (statement.execute() == 0) { return ErrorEnum::eNotFound; @@ -316,8 +319,8 @@ Error Database::AddInstance(const networkmanager::Instance& instance) NetworkManagerInstanceRow row; FromAos(instance, row); - *mSession << "INSERT INTO networkmanager_instances (itemID, subjectID, instance, type, networkID, nodeID, ip, " - "exposedPorts, dnsServers) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", + *mSession << "INSERT INTO networkmanager_instances (itemID, subjectID, instance, type, preinstalled, " + "networkID, nodeID, ip, exposedPorts, dnsServers) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", bind(row), now; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); @@ -382,8 +385,8 @@ Error Database::GetInstances(const String& networkID, const String& nodeID, Arra try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, type, networkID, nodeID, ip, exposedPorts, dnsServers FROM " - "networkmanager_instances WHERE networkID = ? AND nodeID = ?;", + *mSession << "SELECT itemID, subjectID, instance, type, preinstalled, networkID, nodeID, ip, exposedPorts, " + "dnsServers FROM networkmanager_instances WHERE networkID = ? AND nodeID = ?;", bind(networkID.CStr()), bind(nodeID.CStr()), into(rows), now; auto instance = std::make_unique(); @@ -447,10 +450,10 @@ Error Database::RemoveNetworkInstance(const InstanceIdent& instanceIdent) try { Poco::Data::Statement statement {*mSession}; - statement - << "DELETE FROM networkmanager_instances WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + statement << "DELETE FROM networkmanager_instances " + "WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ? AND preinstalled = ?;", bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), - bind(instanceIdent.mType.ToString().CStr()); + bind(instanceIdent.mType.ToString().CStr()), bind(instanceIdent.mPreinstalled); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -474,10 +477,10 @@ Error Database::AddInstance(const launcher::InstanceInfo& info) LauncherInstanceInfoRow row; FromAos(info, row); - *mSession << "INSERT INTO launcher_instances (itemID, subjectID, instance, type, manifestDigest, " + *mSession << "INSERT INTO launcher_instances (itemID, subjectID, instance, type, preinstalled, manifestDigest, " "nodeID, prevNodeID, runtimeID, uid, gid, timestamp, state, isUnitSubject, version, ownerID, " "subjectType) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", bind(row), now; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); @@ -493,16 +496,18 @@ Error Database::UpdateInstance(const launcher::InstanceInfo& info) try { Poco::Data::Statement statement {*mSession}; - statement << "UPDATE launcher_instances SET manifestDigest = ?, nodeID = ?, prevNodeID = " - "?, runtimeID = ?, uid = ?, gid = ?, timestamp = ?, state = ?, isUnitSubject = ?, ownerID = ?, " - "subjectType = ? " - "WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ? AND version = ?;", + statement + << "UPDATE launcher_instances SET manifestDigest = ?, nodeID = ?, prevNodeID = ?, runtimeID = ?, uid = ?, " + "gid = ?, timestamp = ?, state = ?, isUnitSubject = ?, ownerID = ?, subjectType = ? " + "WHERE itemID = ? AND subjectID = ? AND instance = ? " + "AND type = ? AND preinstalled = ? AND version = ?;", bind(info.mManifestDigest.CStr()), bind(info.mNodeID.CStr()), bind(info.mPrevNodeID.CStr()), bind(info.mRuntimeID.CStr()), bind(info.mUID), bind(info.mGID), bind(info.mTimestamp.UnixNano()), bind(info.mState.ToString().CStr()), bind(info.mIsUnitSubject), bind(info.mOwnerID.CStr()), bind(info.mSubjectType.ToString().CStr()), bind(info.mInstanceIdent.mItemID.CStr()), bind(info.mInstanceIdent.mSubjectID.CStr()), bind(info.mInstanceIdent.mInstance), - bind(info.mInstanceIdent.mType.ToString().CStr()), bind(info.mVersion.CStr()); + bind(info.mInstanceIdent.mType.ToString().CStr()), bind(info.mInstanceIdent.mPreinstalled), + bind(info.mVersion.CStr()); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -521,11 +526,12 @@ Error Database::GetInstance(const InstanceIdent& instanceID, launcher::InstanceI try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, type, manifestDigest, nodeID, prevNodeID, " + *mSession << "SELECT itemID, subjectID, instance, type, preinstalled, manifestDigest, nodeID, prevNodeID, " "runtimeID, uid, gid, timestamp, state, isUnitSubject, version, ownerID, subjectType " - "FROM launcher_instances WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + "FROM launcher_instances WHERE itemID = ? AND subjectID = ? AND instance = ? " + "AND type = ? AND preinstalled = ?;", bind(instanceID.mItemID.CStr()), bind(instanceID.mSubjectID.CStr()), bind(instanceID.mInstance), - bind(instanceID.mType.ToString().CStr()), into(rows), now; + bind(instanceID.mType.ToString().CStr()), bind(instanceID.mPreinstalled), into(rows), now; if (rows.size() != 1) { return ErrorEnum::eNotFound; @@ -546,7 +552,7 @@ Error Database::GetActiveInstances(Array& instances) con try { std::vector rows; - *mSession << "SELECT itemID, subjectID, instance, type, manifestDigest, nodeID, prevNodeID, " + *mSession << "SELECT itemID, subjectID, instance, type, preinstalled, manifestDigest, nodeID, prevNodeID, " "runtimeID, uid, gid, timestamp, state, isUnitSubject, version, ownerID, subjectType " "FROM launcher_instances;", into(rows), now; @@ -573,9 +579,10 @@ Error Database::RemoveInstance(const InstanceIdent& instanceIdent) Poco::Data::Statement statement {*mSession}; statement.reset(*mSession); - statement << "DELETE FROM launcher_instances WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + statement << "DELETE FROM launcher_instances " + "WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ? AND preinstalled = ?;", bind(instanceIdent.mItemID.CStr()), bind(instanceIdent.mSubjectID.CStr()), bind(instanceIdent.mInstance), - bind(instanceIdent.mType.ToString().CStr()); + bind(instanceIdent.mType.ToString().CStr()), bind(instanceIdent.mPreinstalled); if (statement.execute() != 1) { return ErrorEnum::eNotFound; @@ -711,10 +718,11 @@ void Database::CreateTables() "subjectID TEXT," "instance INTEGER," "type TEXT," + "preinstalled INTEGER," "storageQuota INTEGER," "stateQuota INTEGER," "stateChecksum BLOB," - "PRIMARY KEY(itemID,subjectID,instance,type)" + "PRIMARY KEY(itemID,subjectID,instance,type,preinstalled)" ");", now; @@ -758,12 +766,13 @@ void Database::CreateTables() "subjectID TEXT," "instance INTEGER," "type TEXT," + "preinstalled INTEGER," "networkID TEXT," "nodeID TEXT," "ip TEXT," "exposedPorts TEXT," "dnsServers TEXT," - "PRIMARY KEY(itemID,subjectID,instance,type)," + "PRIMARY KEY(itemID,subjectID,instance,type,preinstalled)," "FOREIGN KEY(networkID) REFERENCES networks(networkID)," "FOREIGN KEY(networkID,nodeID) REFERENCES hosts(networkID,nodeID)" ");", @@ -776,6 +785,7 @@ void Database::CreateTables() "subjectID TEXT," "instance INTEGER," "type TEXT," + "preinstalled INTEGER," "manifestDigest TEXT," "nodeID TEXT," "prevNodeID TEXT," @@ -788,7 +798,7 @@ void Database::CreateTables() "version TEXT," "ownerID TEXT," "subjectType TEXT," - "PRIMARY KEY(itemID,subjectID,instance,type,version)" + "PRIMARY KEY(itemID,subjectID,instance,type,preinstalled,version)" ");", now; } @@ -804,6 +814,7 @@ void Database::FromAos(const storagestate::InstanceInfo& src, StorageStateInstan dst.set(src.mInstanceIdent.mSubjectID.CStr()); dst.set(src.mInstanceIdent.mInstance); dst.set(src.mInstanceIdent.mType.ToString().CStr()); + dst.set(src.mInstanceIdent.mPreinstalled); dst.set(src.mStorageQuota); dst.set(src.mStateQuota); dst.set( @@ -814,11 +825,12 @@ void Database::ToAos(const StorageStateInstanceInfoRow& src, storagestate::Insta { const auto& blob = src.get(); - dst.mInstanceIdent.mItemID = src.get().c_str(); - dst.mInstanceIdent.mSubjectID = src.get().c_str(); - dst.mInstanceIdent.mInstance = src.get(); - dst.mStorageQuota = src.get(); - dst.mStateQuota = src.get(); + dst.mInstanceIdent.mItemID = src.get().c_str(); + dst.mInstanceIdent.mSubjectID = src.get().c_str(); + dst.mInstanceIdent.mInstance = src.get(); + dst.mInstanceIdent.mPreinstalled = src.get(); + dst.mStorageQuota = src.get(); + dst.mStateQuota = src.get(); AOS_ERROR_CHECK_AND_THROW( dst.mInstanceIdent.mType.FromString(src.get().c_str()), "failed to parse instance type"); @@ -858,6 +870,7 @@ void Database::FromAos(const networkmanager::Instance& src, NetworkManagerInstan dst.set(src.mInstanceIdent.mSubjectID.CStr()); dst.set(src.mInstanceIdent.mInstance); dst.set(src.mInstanceIdent.mType.ToString().CStr()); + dst.set(src.mInstanceIdent.mPreinstalled); dst.set(src.mNetworkID.CStr()); dst.set(src.mNodeID.CStr()); dst.set(src.mIP.CStr()); @@ -873,9 +886,10 @@ void Database::ToAos(const NetworkManagerInstanceRow& src, networkmanager::Insta AOS_ERROR_CHECK_AND_THROW( dst.mInstanceIdent.mType.FromString(src.get().c_str()), "failed to parse instance type"); - dst.mNetworkID = src.get().c_str(); - dst.mNodeID = src.get().c_str(); - dst.mIP = src.get().c_str(); + dst.mInstanceIdent.mPreinstalled = src.get(); + dst.mNetworkID = src.get().c_str(); + dst.mNodeID = src.get().c_str(); + dst.mIP = src.get().c_str(); DeserializeExposedPorts(src.get(), dst.mExposedPorts); DeserializeDNSServers(src.get(), dst.mDNSServers); @@ -887,6 +901,7 @@ void Database::FromAos(const launcher::InstanceInfo& src, LauncherInstanceInfoRo dst.set(src.mInstanceIdent.mSubjectID.CStr()); dst.set(src.mInstanceIdent.mInstance); dst.set(src.mInstanceIdent.mType.ToString().CStr()); + dst.set(src.mInstanceIdent.mPreinstalled); dst.set(src.mManifestDigest.CStr()); dst.set(src.mNodeID.CStr()); dst.set(src.mPrevNodeID.CStr()); @@ -909,12 +924,13 @@ void Database::ToAos(const LauncherInstanceInfoRow& src, launcher::InstanceInfo& AOS_ERROR_CHECK_AND_THROW( dst.mInstanceIdent.mType.FromString(src.get().c_str()), "failed to parse instance type"); - dst.mManifestDigest = src.get().c_str(); - dst.mNodeID = src.get().c_str(); - dst.mPrevNodeID = src.get().c_str(); - dst.mRuntimeID = src.get().c_str(); - dst.mUID = src.get(); - dst.mGID = src.get(); + dst.mInstanceIdent.mPreinstalled = src.get(); + dst.mManifestDigest = src.get().c_str(); + dst.mNodeID = src.get().c_str(); + dst.mPrevNodeID = src.get().c_str(); + dst.mRuntimeID = src.get().c_str(); + dst.mUID = src.get(); + dst.mGID = src.get(); auto timestamp = src.get(); dst.mTimestamp = Time::Unix(timestamp / Time::cSeconds.Nanoseconds(), timestamp % Time::cSeconds.Nanoseconds()); diff --git a/src/cm/database/database.hpp b/src/cm/database/database.hpp index 4712f5bc..18428561 100644 --- a/src/cm/database/database.hpp +++ b/src/cm/database/database.hpp @@ -282,12 +282,13 @@ class Database : public storagestate::StorageItf, eSubjectID, eInstance, eType, + ePreinstalled, eStorageQuota, eStateQuota, eStateChecksum }; using StorageStateInstanceInfoRow - = Poco::Tuple; + = Poco::Tuple; enum class NetworkManagerNetworkColumns : int { eNetworkID = 0, eSubnet, eVlanID }; using NetworkManagerNetworkRow = Poco::Tuple; @@ -300,13 +301,14 @@ class Database : public storagestate::StorageItf, eSubjectID, eInstance, eType, + ePreinstalled, eNetworkID, eNodeID, eIP, eExposedPorts, eDNSServers }; - using NetworkManagerInstanceRow = Poco::Tuple; enum class LauncherInstanceInfoColumns : int { @@ -314,6 +316,7 @@ class Database : public storagestate::StorageItf, eSubjectID, eInstance, eType, + ePreinstalled, eManifestDigest, eNodeID, ePrevNodeID, @@ -328,7 +331,7 @@ class Database : public storagestate::StorageItf, eSubjectType }; using LauncherInstanceInfoRow - = Poco::Tuple; enum class ImageManagerItemInfoColumns : int { eItemID = 0, eVersion, eIndexDigest, eState, eTimestamp }; diff --git a/src/cm/database/tests/CMakeLists.txt b/src/cm/database/tests/CMakeLists.txt index 920b516c..9e360bb2 100644 --- a/src/cm/database/tests/CMakeLists.txt +++ b/src/cm/database/tests/CMakeLists.txt @@ -16,7 +16,7 @@ set(SOURCES database.cpp) # Libraries # ###################################################################################################################### -set(LIBRARIES aos::cm::database GTest::gmock_main) +set(LIBRARIES aos::cm::database aos::core::common::tests::utils GTest::gmock_main) # ###################################################################################################################### # Target diff --git a/src/cm/database/tests/database.cpp b/src/cm/database/tests/database.cpp index c42282da..3c3c6a21 100644 --- a/src/cm/database/tests/database.cpp +++ b/src/cm/database/tests/database.cpp @@ -6,6 +6,9 @@ #include +#include +#include + #include #include @@ -26,14 +29,15 @@ std::vector ToVector(const Array& src) } InstanceIdent CreateInstanceIdent(const char* itemID, const char* subjectID, uint64_t instance, - UpdateItemType itemType = UpdateItemTypeEnum::eService) + UpdateItemType itemType = UpdateItemTypeEnum::eService, bool preinstalled = true) { InstanceIdent ident; - ident.mItemID = itemID; - ident.mSubjectID = subjectID; - ident.mInstance = instance; - ident.mType = itemType; + ident.mItemID = itemID; + ident.mSubjectID = subjectID; + ident.mInstance = instance; + ident.mType = itemType; + ident.mPreinstalled = preinstalled; return ident; } @@ -165,6 +169,8 @@ class TestDatabase : public Database { class CMDatabaseTest : public Test { protected: + static void SetUpTestSuite() { tests::utils::InitLog(); } + void SetUp() override { // Clean up on start. diff --git a/src/common/pbconvert/common.cpp b/src/common/pbconvert/common.cpp index e9317c13..2db754dc 100644 --- a/src/common/pbconvert/common.cpp +++ b/src/common/pbconvert/common.cpp @@ -47,6 +47,7 @@ ::common::v2::InstanceIdent ConvertToProto(const InstanceIdent& src) result.set_subject_id(src.mSubjectID.CStr()); result.set_instance(src.mInstance); result.set_type(static_cast<::common::v2::ItemType>(src.mType.GetValue())); + result.set_preinstalled(src.mPreinstalled); return result; } @@ -73,10 +74,11 @@ InstanceIdent ConvertToAos(const ::common::v2::InstanceIdent& val) { InstanceIdent result; - result.mItemID = val.item_id().c_str(); - result.mSubjectID = val.subject_id().c_str(); - result.mInstance = val.instance(); - result.mType = static_cast(val.type()); + result.mItemID = val.item_id().c_str(); + result.mSubjectID = val.subject_id().c_str(); + result.mInstance = val.instance(); + result.mType = static_cast(val.type()); + result.mPreinstalled = val.preinstalled(); return result; } diff --git a/src/common/pbconvert/sm.cpp b/src/common/pbconvert/sm.cpp index c9d0e0f4..edc1c517 100644 --- a/src/common/pbconvert/sm.cpp +++ b/src/common/pbconvert/sm.cpp @@ -1047,8 +1047,6 @@ Error ConvertFromProto(const servicemanager::v5::InstanceStatus& src, const Stri return AOS_ERROR_WRAP(err); } - dst.mPreinstalled = src.preinstalled(); - dst.mError = pbconvert::ConvertFromProto(src.error()); return ErrorEnum::eNone; @@ -1152,7 +1150,6 @@ void ConvertToProto(const InstanceStatus& src, servicemanager::v5::InstanceStatu { dst.mutable_instance()->CopyFrom(ConvertToProto(static_cast(src))); dst.set_version(src.mVersion.CStr()); - dst.set_preinstalled(src.mPreinstalled); dst.set_runtime_id(src.mRuntimeID.CStr()); dst.set_manifest_digest(src.mManifestDigest.CStr()); diff --git a/src/common/pbconvert/tests/common.cpp b/src/common/pbconvert/tests/common.cpp index 249fa611..bc7b8a91 100644 --- a/src/common/pbconvert/tests/common.cpp +++ b/src/common/pbconvert/tests/common.cpp @@ -84,13 +84,14 @@ TEST_F(PBConvertCommon, ConvertAosErrorToGrpcStatus) TEST_F(PBConvertCommon, ConvertInstanceIdentToProto) { - aos::InstanceIdent param {"item-id", "subject-id", 1, aos::UpdateItemTypeEnum::eComponent}; + aos::InstanceIdent param {"item-id", "subject-id", 1, aos::UpdateItemTypeEnum::eComponent, true}; ::common::v2::InstanceIdent result = aos::common::pbconvert::ConvertToProto(param); EXPECT_EQ(result.item_id(), param.mItemID.CStr()); EXPECT_EQ(result.subject_id(), param.mSubjectID.CStr()); EXPECT_EQ(result.instance(), param.mInstance); EXPECT_EQ(result.type(), ::common::v2::ItemType::COMPONENT); + EXPECT_TRUE(result.preinstalled()); } TEST_F(PBConvertCommon, ConvertInstanceIdentToAos) @@ -100,12 +101,16 @@ TEST_F(PBConvertCommon, ConvertInstanceIdentToAos) param.set_item_id("item-id"); param.set_subject_id("subject-id"); param.set_instance(1); + param.set_type(::common::v2::ItemType::COMPONENT); + param.set_preinstalled(true); auto result = aos::common::pbconvert::ConvertToAos(param); EXPECT_EQ(result.mItemID, aos::String(param.item_id().c_str())); EXPECT_EQ(result.mSubjectID, aos::String(param.subject_id().c_str())); EXPECT_EQ(result.mInstance, param.instance()); + EXPECT_EQ(result.mType, aos::UpdateItemTypeEnum::eComponent); + EXPECT_TRUE(result.mPreinstalled); } TEST_F(PBConvertCommon, ConvertTimestampToAos) diff --git a/src/common/pbconvert/tests/sm.cpp b/src/common/pbconvert/tests/sm.cpp index a0c88c57..c0981850 100644 --- a/src/common/pbconvert/tests/sm.cpp +++ b/src/common/pbconvert/tests/sm.cpp @@ -194,10 +194,10 @@ TEST_F(PBConvertSMTest, ConvertInstanceStatusFromProto) grpcStatus.mutable_instance()->set_item_id("service1"); grpcStatus.mutable_instance()->set_subject_id("user1"); grpcStatus.mutable_instance()->set_instance(0); + grpcStatus.mutable_instance()->set_preinstalled(true); grpcStatus.set_version("2.0.0"); grpcStatus.set_runtime_id("runc"); grpcStatus.set_state("active"); - grpcStatus.set_preinstalled(true); grpcStatus.set_manifest_digest("sha256:deadbeef"); auto* envVarStatus1 = grpcStatus.add_env_vars(); diff --git a/src/sm/database/database.cpp b/src/sm/database/database.cpp index db6b09f3..7a30bb52 100644 --- a/src/sm/database/database.cpp +++ b/src/sm/database/database.cpp @@ -367,10 +367,10 @@ Error Database::GetAllInstancesInfos([[maybe_unused]] Array& infos try { std::vector rows; - *mSession - << "SELECT itemID, subjectID, instance, type, version, manifestDigest, runtimeID, ownerID, subjectType, " - "uid, gid, priority, storagePath, statePath, envVars, networkParameters, monitoringParams " - "FROM instances;", + *mSession << "SELECT itemID, subjectID, instance, type, preinstalled, version, manifestDigest, " + "runtimeID, ownerID, subjectType,uid, gid, priority, storagePath, statePath, " + "envVars,networkParameters, monitoringParams " + "FROM instances;", into(rows), now; auto instanceInfo = std::make_unique(); @@ -400,9 +400,10 @@ Error Database::UpdateInstanceInfo(const InstanceInfo& info) FromAos(info, row); - *mSession << "INSERT OR REPLACE INTO instances (itemID, subjectID, instance, type, version, manifestDigest, " - "runtimeID, ownerID, subjectType, uid, gid, priority, storagePath, statePath, envVars, " - "networkParameters, monitoringParams) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + *mSession + << "INSERT OR REPLACE INTO instances (itemID, subjectID, instance, type, preinstalled, version, " + "manifestDigest, runtimeID, ownerID, subjectType, uid, gid, priority, storagePath, statePath, envVars, " + "networkParameters, monitoringParams) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", bind(row), now; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); @@ -420,9 +421,10 @@ Error Database::RemoveInstanceInfo(const InstanceIdent& ident) try { Poco::Data::Statement statement {*mSession}; - statement << "DELETE FROM instances WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ?;", + statement << "DELETE FROM instances WHERE itemID = ? AND subjectID = ? AND instance = ? AND type = ? " + "AND preinstalled = ?;", bind(ident.mItemID.CStr()), bind(ident.mSubjectID.CStr()), bind(ident.mInstance), - bind(ident.mType.ToString().CStr()); + bind(ident.mType.ToString().CStr()), bind(ident.mPreinstalled); if (statement.execute() == 0) { return AOS_ERROR_WRAP(ErrorEnum::eNotFound); @@ -759,6 +761,7 @@ void Database::FromAos(const InstanceInfo& src, InstanceInfoRow& dst) dst.set(src.mSubjectID.CStr()); dst.set(src.mInstance); dst.set(src.mType.ToString().CStr()); + dst.set(src.mPreinstalled); dst.set(src.mVersion.CStr()); dst.set(src.mManifestDigest.CStr()); dst.set(src.mRuntimeID.CStr()); @@ -779,6 +782,7 @@ void Database::ToAos(const InstanceInfoRow& src, InstanceInfo& dst) dst.mItemID = src.get().c_str(); dst.mSubjectID = src.get().c_str(); dst.mInstance = src.get(); + dst.mPreinstalled = src.get(); dst.mVersion = src.get().c_str(); dst.mManifestDigest = src.get().c_str(); dst.mRuntimeID = src.get().c_str(); diff --git a/src/sm/database/database.hpp b/src/sm/database/database.hpp index 810e9d58..ec84367f 100644 --- a/src/sm/database/database.hpp +++ b/src/sm/database/database.hpp @@ -180,6 +180,7 @@ class Database : public sm::launcher::StorageItf, public sm::networkmanager::Sto eSubjectID, eInstance, eType, + ePreinstalled, eVersion, eManifestDigest, eRuntimeID, @@ -194,9 +195,9 @@ class Database : public sm::launcher::StorageItf, public sm::networkmanager::Sto eNetworkParameters, eMonitoringParams }; - using InstanceInfoRow = Poco::Tuple; + using InstanceInfoRow = Poco::Tuple; // Network info columns enum class NetworkInfoColumns : int { eNetworkID = 0, eIP, eSubnet, eVlanID, eVlanIfName, eBridgeIfName }; diff --git a/src/sm/database/migration/3_update.up.sql b/src/sm/database/migration/3_update.up.sql index dad20144..a97d31e6 100644 --- a/src/sm/database/migration/3_update.up.sql +++ b/src/sm/database/migration/3_update.up.sql @@ -11,6 +11,7 @@ CREATE TABLE instances ( subjectID TEXT NOT NULL, instance INTEGER NOT NULL, type TEXT NOT NULL DEFAULT 'service', + preinstalled INTEGER NOT NULL DEFAULT 0, version TEXT, manifestDigest TEXT, runtimeID TEXT, @@ -24,7 +25,7 @@ CREATE TABLE instances ( envVars TEXT, networkParameters TEXT, monitoringParams TEXT, - PRIMARY KEY(itemID, subjectID, instance, type) + PRIMARY KEY(itemID, subjectID, instance, type, preinstalled) ); ALTER TABLE network ADD COLUMN bridgeIfName TEXT; diff --git a/src/sm/database/tests/CMakeLists.txt b/src/sm/database/tests/CMakeLists.txt index 790a8146..64f3d193 100644 --- a/src/sm/database/tests/CMakeLists.txt +++ b/src/sm/database/tests/CMakeLists.txt @@ -16,7 +16,7 @@ set(SOURCES database.cpp) # Libraries # ###################################################################################################################### -set(LIBRARIES aos::sm::database GTest::gmock_main) +set(LIBRARIES aos::sm::database aos::core::common::tests::utils GTest::gmock_main) # ###################################################################################################################### # Target diff --git a/src/sm/database/tests/database.cpp b/src/sm/database/tests/database.cpp index 66580eee..4f788d07 100644 --- a/src/sm/database/tests/database.cpp +++ b/src/sm/database/tests/database.cpp @@ -9,6 +9,7 @@ #include #include +#include #include @@ -103,8 +104,11 @@ TEST_F(DatabaseTest, UpdateInstanceInfo) auto instanceInfo = CreateInstanceInfo("service-1", "subject-1", 1); - ASSERT_TRUE(mDB.UpdateInstanceInfo(instanceInfo).IsNone()); - ASSERT_TRUE(mDB.UpdateInstanceInfo(instanceInfo).IsNone()); + auto err = mDB.UpdateInstanceInfo(instanceInfo); + ASSERT_TRUE(err.IsNone()) << aos::tests::utils::ErrorToStr(err); + + err = mDB.UpdateInstanceInfo(instanceInfo); + ASSERT_TRUE(err.IsNone()) << aos::tests::utils::ErrorToStr(err); } TEST_F(DatabaseTest, RemoveInstanceInfo) @@ -126,16 +130,20 @@ TEST_F(DatabaseTest, RemoveInstanceInfo) TEST_F(DatabaseTest, GetAllInstancesInfos) { - ASSERT_TRUE(mDB.Init(mWorkingDir.string(), mMigrationConfig).IsNone()); + auto err = mDB.Init(mWorkingDir.string(), mMigrationConfig); + ASSERT_TRUE(err.IsNone()) << aos::tests::utils::ErrorToStr(err); - auto instanceInfo = CreateInstanceInfo("service-1", "subject-1", 1); + auto instanceInfo = CreateInstanceInfo("service-1", "subject-1", 1); + instanceInfo.mPreinstalled = true; - ASSERT_TRUE(mDB.UpdateInstanceInfo(instanceInfo).IsNone()); + err = mDB.UpdateInstanceInfo(instanceInfo); + ASSERT_TRUE(err.IsNone()) << aos::tests::utils::ErrorToStr(err); // aos::InstanceInfoArray result; auto result = std::make_unique(); - ASSERT_TRUE(mDB.GetAllInstancesInfos(*result).IsNone()); + err = mDB.GetAllInstancesInfos(*result); + ASSERT_TRUE(err.IsNone()) << aos::tests::utils::ErrorToStr(err); ASSERT_EQ(result->Size(), 1); @@ -145,6 +153,7 @@ TEST_F(DatabaseTest, GetAllInstancesInfos) EXPECT_EQ(resultRef.mSubjectID, instanceInfo.mSubjectID); EXPECT_EQ(resultRef.mInstance, instanceInfo.mInstance); EXPECT_EQ(resultRef.mType, instanceInfo.mType); + EXPECT_TRUE(resultRef.mPreinstalled); EXPECT_EQ(resultRef.mManifestDigest, instanceInfo.mManifestDigest); EXPECT_EQ(resultRef.mRuntimeID, instanceInfo.mRuntimeID); EXPECT_EQ(resultRef.mSubjectType, instanceInfo.mSubjectType); diff --git a/src/sm/launcher/runtimes/boot/boot.cpp b/src/sm/launcher/runtimes/boot/boot.cpp index 34f419ed..c4882dd6 100644 --- a/src/sm/launcher/runtimes/boot/boot.cpp +++ b/src/sm/launcher/runtimes/boot/boot.cpp @@ -314,10 +314,11 @@ Error BootRuntime::CreateRuntimeInfo() mRuntimeInfo.mMaxInstances = 1; - mDefaultInstanceIdent.mType = UpdateItemTypeEnum::eComponent; - mDefaultInstanceIdent.mInstance = 0; - mDefaultInstanceIdent.mItemID = mRuntimeInfo.mRuntimeType; - mDefaultInstanceIdent.mSubjectID = nodeInfo->mNodeType; + mDefaultInstanceIdent.mType = UpdateItemTypeEnum::eComponent; + mDefaultInstanceIdent.mInstance = 0; + mDefaultInstanceIdent.mItemID = mRuntimeInfo.mRuntimeType; + mDefaultInstanceIdent.mSubjectID = nodeInfo->mNodeType; + mDefaultInstanceIdent.mPreinstalled = true; LOG_INF() << "Runtime info" << Log::Field("runtimeID", mRuntimeInfo.mRuntimeID) << Log::Field("runtimeType", mRuntimeInfo.mRuntimeType) @@ -487,7 +488,7 @@ void BootRuntime::ToInstanceStatus(const BootData& data, InstanceStatus& status) status.mVersion = data.mVersion; status.mRuntimeID = mRuntimeInfo.mRuntimeID; status.mType = UpdateItemTypeEnum::eComponent; - status.mPreinstalled = static_cast(data) == mDefaultInstanceIdent; + status.mPreinstalled = data.mPreinstalled; } Error BootRuntime::InstallPendingUpdate() @@ -627,6 +628,7 @@ Error BootRuntime::StoreData(const std::string_view filename, const BootData& da json->set("state", data.mState.ToString().CStr()); json->set("type", data.mType.ToString().CStr()); json->set("version", data.mVersion.CStr()); + json->set("preinstalled", data.mPreinstalled); if (data.mPartitionIndex.HasValue()) { json->set("partitionIndex", data.mPartitionIndex.GetValue()); @@ -678,7 +680,8 @@ Error BootRuntime::LoadData(const std::string_view filename, BootData& data) data.mPartitionIndex.SetValue(object.GetValue("partitionIndex")); } - data.mType = UpdateItemTypeEnum::eComponent; + data.mPreinstalled = object.GetValue("preinstalled"); + data.mType = UpdateItemTypeEnum::eComponent; } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); } diff --git a/src/sm/launcher/runtimes/boot/tests/boot.cpp b/src/sm/launcher/runtimes/boot/tests/boot.cpp index 76a6a912..4321cd33 100644 --- a/src/sm/launcher/runtimes/boot/tests/boot.cpp +++ b/src/sm/launcher/runtimes/boot/tests/boot.cpp @@ -360,7 +360,9 @@ TEST_F(BootRuntimeTest, UpdateSucceededOnStart) "instance": 0, "state": "active", "version": "1.0.0", - "partitionIndex": 0 + "partitionIndex": 0, + "preinstalled": true + })"; constexpr auto cPending = R"({ "itemId": "updateItem1", @@ -451,7 +453,8 @@ TEST_F(BootRuntimeTest, UpdateFailedOnStart) "instance": 0, "state": "active", "version": "1.0.0", - "partitionIndex": 0 + "partitionIndex": 0, + "preinstalled": true })"; constexpr auto cPending = R"({ "itemId": "updateItem1", diff --git a/src/sm/launcher/runtimes/rootfs/rootfs.cpp b/src/sm/launcher/runtimes/rootfs/rootfs.cpp index 72111196..e941c589 100644 --- a/src/sm/launcher/runtimes/rootfs/rootfs.cpp +++ b/src/sm/launcher/runtimes/rootfs/rootfs.cpp @@ -307,10 +307,11 @@ Error RootfsRuntime::CreateRuntimeInfo() mRuntimeInfo.mMaxInstances = 1; - mDefaultInstanceIdent.mType = UpdateItemTypeEnum::eComponent; - mDefaultInstanceIdent.mInstance = 0; - mDefaultInstanceIdent.mItemID = mRuntimeInfo.mRuntimeType; - mDefaultInstanceIdent.mSubjectID = nodeInfo->mNodeType; + mDefaultInstanceIdent.mType = UpdateItemTypeEnum::eComponent; + mDefaultInstanceIdent.mInstance = 0; + mDefaultInstanceIdent.mItemID = mRuntimeInfo.mRuntimeType; + mDefaultInstanceIdent.mSubjectID = nodeInfo->mNodeType; + mDefaultInstanceIdent.mPreinstalled = true; LOG_INF() << "Runtime info" << Log::Field("runtimeID", mRuntimeInfo.mRuntimeID) << Log::Field("runtimeType", mRuntimeInfo.mRuntimeType) @@ -413,7 +414,7 @@ void RootfsRuntime::FillInstanceStatus( status.mRuntimeID = mRuntimeInfo.mRuntimeID; status.mManifestDigest = instanceInfo.mManifestDigest; status.mType = UpdateItemTypeEnum::eComponent; - status.mPreinstalled = static_cast(instanceInfo) == mDefaultInstanceIdent; + status.mPreinstalled = instanceInfo.mPreinstalled; } Error RootfsRuntime::SaveInstanceInfo(const InstanceInfo& instance, const std::filesystem::path& path) const @@ -434,6 +435,7 @@ Error RootfsRuntime::SaveInstanceInfo(const InstanceInfo& instance, const std::f json->set("manifestDigest", instance.mManifestDigest.CStr()); json->set("type", instance.mType.ToString().CStr()); json->set("version", instance.mVersion.CStr()); + json->set("preinstalled", instance.mPreinstalled); json->stringify(file); } catch (const std::exception& e) { @@ -473,7 +475,8 @@ Error RootfsRuntime::LoadInstanceInfo(const std::filesystem::path& path, Instanc err = instance.mVersion.Assign(jsonObject.GetValue("version").c_str()); AOS_ERROR_CHECK_AND_THROW(err); - instance.mType = UpdateItemTypeEnum::eComponent; + instance.mType = UpdateItemTypeEnum::eComponent; + instance.mPreinstalled = jsonObject.GetValue("preinstalled"); } catch (const std::exception& e) { return AOS_ERROR_WRAP(common::utils::ToAosError(e)); } diff --git a/src/sm/launcher/runtimes/rootfs/tests/rootfs.cpp b/src/sm/launcher/runtimes/rootfs/tests/rootfs.cpp index fd0ebde9..7185a32c 100644 --- a/src/sm/launcher/runtimes/rootfs/tests/rootfs.cpp +++ b/src/sm/launcher/runtimes/rootfs/tests/rootfs.cpp @@ -147,7 +147,8 @@ class RootfsRuntimeTest : public Test { "itemId": "itemId", "subjectId": "subjectId", "manifestDigest": "manifestDigest", - "version": "1.0.0" + "version": "1.0.0", + "preinstalled": true })"; } else { throw std::runtime_error("can't create instance file");