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
51 changes: 43 additions & 8 deletions src/sagemaker_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "sagemaker_server.h"

#include <filesystem>

namespace triton { namespace server {

#define HTTP_RESPOND_IF_ERR(REQ, X) \
Expand Down Expand Up @@ -291,6 +294,22 @@ SagemakerAPIServer::ParseSageMakerRequest(
}
}

std::filesystem::path url_path(url_string);
url_path = std::filesystem::absolute(
url_path.lexically_normal()); // Normalize the path to remove any
// redundant components.
auto url_abspath = url_path.string();

if (url_abspath.find("/dev/") == 0 || url_abspath.find("/proc/") == 0 ||
url_abspath.find("/sys/") == 0) {
LOG_ERROR << "Invalid URL: " << url_string
<< ". \"url\" property value cannot start with /dev/, /proc/, or "
"/sys/."
<< std::endl;
evhtp_send_reply(req, EVHTP_RES_BADREQ);
return;
}

if (action == "load") {
(*parse_map)["url"] = url_string.c_str();
}
Expand Down Expand Up @@ -891,11 +910,27 @@ SagemakerAPIServer::SageMakerMMELoadModel(
evhtp_request_t* req,
const std::unordered_map<std::string, std::string> parse_map)
{
std::string repo_path = parse_map.at("url");
std::string url_string = parse_map.at("url");
std::string model_name_hash = parse_map.at("model_name_hash");
std::string target_model = parse_map.at("target_model");

/* Check subdirs for models and find ensemble model within the repo_path
std::filesystem::path url_path(url_string);
url_path = std::filesystem::absolute(
url_path.lexically_normal()); // Normalize the path to remove any
// redundant components.
std::string url_abspath = url_path.string();

if (url_abspath.find("/dev/") == 0 || url_abspath.find("/proc/") == 0 ||
url_abspath.find("/sys/") == 0) {
LOG_ERROR << "Invalid repository path: " << url_string
<< ". \"url\" property of `parse_map`cannot start with /dev/, "
"/proc/, or /sys/."
<< std::endl;
evhtp_send_reply(req, EVHTP_RES_BADREQ);
return;
}

/* Check subdirs for models and find ensemble model within the url_abspath
* If only 1 model, that will be selected as model_subdir
* Else ensemble model directory is set as model_subdir
*/
Expand All @@ -904,7 +939,8 @@ SagemakerAPIServer::SageMakerMMELoadModel(
int dir_count = 0;
std::string model_subdir, ensemble_model_subdir;

if ((dir = opendir(repo_path.c_str())) != NULL) {
if ((dir = opendir(url_abspath.c_str())) != NULL) {
std::shared_ptr<DIR> dir_ptr{dir, closedir};
while ((ent = readdir(dir)) != NULL) {
if ((ent->d_type == DT_DIR) && (!strcmp(ent->d_name, ".") == 0) &&
(!strcmp(ent->d_name, "..") == 0)) {
Expand All @@ -923,7 +959,7 @@ SagemakerAPIServer::SageMakerMMELoadModel(

// Read the config.pbtxt file at each path, if available
std::string ensemble_config_path =
repo_path + "/" + model_subdir + "/" + "config.pbtxt";
url_abspath + "/" + model_subdir + "/config.pbtxt";
std::ifstream config_fstream(ensemble_config_path);
std::stringstream ensemble_config_content;

Expand Down Expand Up @@ -954,7 +990,6 @@ SagemakerAPIServer::SageMakerMMELoadModel(
<< std::endl;
}
}
closedir(dir);
}

if (!strcmp(ensemble_model_subdir.c_str(), "") == 0) {
Expand All @@ -972,10 +1007,10 @@ SagemakerAPIServer::SageMakerMMELoadModel(

std::string repo_parent_path, subdir, customer_subdir;
RE2::FullMatch(
repo_path, model_path_regex_, &repo_parent_path, &subdir,
url_abspath, model_path_regex_, &repo_parent_path, &subdir,
&customer_subdir);

std::string config_path = repo_path + "/config.pbtxt";
std::string config_path = url_abspath + "/config.pbtxt";
struct stat buffer;

/* If config.pbtxt is at repo root,
Expand All @@ -986,7 +1021,7 @@ SagemakerAPIServer::SageMakerMMELoadModel(
if (stat(config_path.c_str(), &buffer) == 0) {
model_subdir = subdir;
} else {
repo_parent_path = repo_path;
repo_parent_path = url_abspath;
}

auto param = TRITONSERVER_ParameterNew(
Expand Down
3 changes: 2 additions & 1 deletion src/sagemaker_server.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
Expand All @@ -23,6 +23,7 @@
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#pragma once

#include <sys/stat.h>
Expand Down
Loading