-
Notifications
You must be signed in to change notification settings - Fork 5
Integration #145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integration #145
Conversation
mlohvynenko
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-by: Mykhailo Lohvynenko <mykhailo_lohvynenko@epam.com>
mykola-kobets-epam
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-by: Mykola Kobets <mykola_kobets@epam.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR updates several components for “integration” behavior changes, including making container runtime start/stop operations idempotent, refactoring SMController blob URL lookups to use an item info provider, and reworking Fileserver URL handling around Poco::URI.
Changes:
- Container runtime:
StartInstance/StopInstancenow return success for “already running” / “not running” cases (idempotent behavior). - Fileserver: store a parsed
Poco::URIand generate output URLs using a root-relative filesystem path. - SMController: replace
BlobInfoProviderItfusage withItemInfoProviderItfforGetBlobsInfos, update app wiring and tests/stubs accordingly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sm/launcher/runtimes/container/container.cpp | Makes start/stop idempotent; adds logic to reuse/stop existing instance before starting |
| src/sm/launcher/runtimes/container/tests/container.cpp | Updates expectations for idempotent start/stop behavior |
| src/common/fileserver/fileserver.cpp | Switches to Poco::URI member; changes URL translation logic and server socket port retrieval |
| src/common/fileserver/fileserver.hpp | Stores Poco::URI instead of host/port; adjusts includes |
| src/common/fileserver/tests/fileserver.cpp | Updates TranslateFilePathURL test input to match new translation logic |
| src/cm/smcontroller/smcontroller.cpp | Implements GetBlobsInfos via ItemInfoProviderItf::GetBlobURL |
| src/cm/smcontroller/smcontroller.hpp | Updates SMController init signature/member from blob info provider to item info provider |
| src/cm/smcontroller/tests/smcontroller.cpp | Updates tests to use the new item info provider stub |
| src/cm/smcontroller/tests/stubs/iteminfoproviderstub.hpp | Adds stub for ItemInfoProviderItf used by tests |
| src/cm/smcontroller/tests/stubs/blobinfoproviderstub.hpp | Removes blob info provider stub |
| src/cm/app/aoscore.cpp | Wires SMController init to pass mImageManager as item info provider |
Comments suppressed due to low confidence (1)
src/sm/launcher/runtimes/container/container.cpp:182
- When an instance already exists but isn’t active, this code stops it but never removes/replaces the existing entry in
mCurrentInstances. BecausemCurrentInstances.insert(...)won’t overwrite an existing key, the newInstancecan fail to be tracked while the map still points to the old (stopped) instance. Useerase(it)before creating the new instance, orinsert_or_assign/operator[]to replace the entry (and ensure the old instance is properly removed).
instance = std::make_shared<Instance>(instanceInfo, mConfig, mNodeInfo, *mFileSystem, *mRunner,
*mMonitoring, *mItemInfoProvider, *mNetworkManager, *mPermHandler, *mResourceInfoProvider, *mOCISpec);
mCurrentInstances.insert({static_cast<const InstanceIdent&>(instanceInfo), instance});
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (instance) { | ||
| if (auto err = instance->Stop(); !err.IsNone()) { | ||
| LOG_ERR() << "Failed to stop instance" | ||
| << Log::Field("instance", static_cast<const InstanceIdent&>(instanceInfo)) | ||
| << Log::Field(err); | ||
| } | ||
|
|
||
| instance->GetStatus(status); | ||
| SendInstanceStatus(status); | ||
| } |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instance->Stop() (and SendInstanceStatus) is executed while holding mMutex. Instance::Stop() performs blocking work (runner stop, FS ops, network cleanup), so doing it under the runtime mutex can stall other operations and risks lock-order deadlocks. Prefer the same pattern as StopInstance: capture+erase under mMutex, release the lock, then stop/send status outside the critical section (and consider propagating stop failures instead of only logging).
| mRootDir = rootDir; | ||
| Poco::URI uri(serverURL); | ||
| mURI = serverURL.c_str(); | ||
|
|
||
| mHost = uri.getHost(); | ||
| mPort = uri.getPort(); | ||
| if (mURI.getScheme().empty()) { | ||
| mURI.setScheme("http"); | ||
| } | ||
|
|
||
| if (mHost.empty()) { | ||
| mHost = "localhost"; | ||
| if (mURI.getHost().empty()) { | ||
| mURI.setHost("localhost"); | ||
| } | ||
|
|
||
| if (mPort == 0) { | ||
| mPort = cDefaultPort; | ||
| if (mURI.getPort() == 0) { | ||
| mURI.setPort(cDefaultPort); |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Poco::URI parsing here can mis-handle config-style values like "localhost:8080" (common in this repo, e.g. cm/config/tests/config.cpp expects fileServerUrl without a scheme). For such inputs Poco treats localhost as the URI scheme, so mURI.getScheme() won’t be empty and you won’t default to http, producing invalid URLs (e.g. localhost://localhost:8080/...). Consider normalizing serverURL by prepending http:// when it lacks ://, or explicitly handling the host:port form before assigning to mURI.
| uri.setPath(fs::relative(fs::path(filePath.CStr()), mRootDir).string()); | ||
|
|
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fs::relative(fs::path(filePath), mRootDir) can yield paths containing .. when filePath is outside mRootDir, and this URL path is later used by the HTTP handler without any traversal checks. This can generate URLs that allow reading files outside the intended root directory. Validate that filePath resolves within mRootDir (e.g., compare canonical/weakly_canonical paths) and reject or sanitize any relative path containing ../absolute components before setting it on the URI.
| uri.setPath(fs::relative(fs::path(filePath.CStr()), mRootDir).string()); | |
| // Canonicalize root and target paths to ensure containment. | |
| const fs::path rootCanonical = fs::weakly_canonical(fs::path(mRootDir)); | |
| const fs::path fileCanonical = fs::weakly_canonical(fs::path(filePath.CStr())); | |
| // Verify that fileCanonical is within rootCanonical. | |
| auto rootIt = rootCanonical.begin(); | |
| auto fileIt = fileCanonical.begin(); | |
| for (; rootIt != rootCanonical.end() && fileIt != fileCanonical.end(); ++rootIt, ++fileIt) { | |
| if (*rootIt != *fileIt) { | |
| break; | |
| } | |
| } | |
| if (rootIt != rootCanonical.end()) { | |
| throw std::runtime_error("filePath is outside of the fileserver root directory"); | |
| } | |
| fs::path relativePath = fs::relative(fileCanonical, rootCanonical); | |
| // Sanity checks: the URL path must not be absolute or contain any ".." components. | |
| if (relativePath.is_absolute()) { | |
| throw std::runtime_error("relative path for URL must not be absolute"); | |
| } | |
| for (const auto& part : relativePath) { | |
| if (part == "..") { | |
| throw std::runtime_error("relative path for URL must not contain '..' components"); | |
| } | |
| } | |
| uri.setPath(relativePath.string()); |
| 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()) { |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
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.
| 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()); | |
| } |
MykolaSuperman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-by: Mykola Solianko <mykola_solianko@epam.com>
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com> Reviewed-by: Mykola Kobets <mykola_kobets@epam.com> Reviewed-by: Mykhailo Lohvynenko <mykhailo_lohvynenko@epam.com> Reviewed-by: Mykola Solianko <mykola_solianko@epam.com>
Poco::URI returns empty host and port if scheme is not present in str uri. Add checking URI scheme and use Poco::URI for creating file URL and file server itself. Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com> Reviewed-by: Mykola Kobets <mykola_kobets@epam.com> Reviewed-by: Mykhailo Lohvynenko <mykhailo_lohvynenko@epam.com> Reviewed-by: Mykola Solianko <mykola_solianko@epam.com>
SM launcher may ask to start/stop already started/stopped instances. Runtime should not return error in this case. Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com> Reviewed-by: Mykola Kobets <mykola_kobets@epam.com> Reviewed-by: Mykhailo Lohvynenko <mykhailo_lohvynenko@epam.com> Reviewed-by: Mykola Solianko <mykola_solianko@epam.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## feature_unification #145 +/- ##
======================================================
Coverage ? 81.98%
======================================================
Files ? 303
Lines ? 28286
Branches ? 3015
======================================================
Hits ? 23189
Misses ? 5097
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|



No description provided.