This commit is contained in:
@@ -123,14 +123,14 @@ curl -X PUT \
|
|||||||
### Get a File
|
### Get a File
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /object/{hash}
|
GET /{hash}
|
||||||
GET /object/{label}:{tag}
|
GET /{label}:{tag}
|
||||||
```
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:8080/object/abc123
|
curl http://localhost:8080/abc123 > abc123.txt
|
||||||
curl http://localhost:8080/object/test:latest
|
curl http://localhost:8080/test:latest > test.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Check if a File Exists
|
### Check if a File Exists
|
||||||
|
@@ -154,19 +154,19 @@ Database::~Database() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::remove(const std::string& labeltag) {
|
// bool Database::remove(const std::string& labeltag) {
|
||||||
std::string sql = "DELETE FROM objects WHERE labeltag = ?;";
|
// std::string sql = "DELETE FROM objects WHERE labeltag = ?;";
|
||||||
sqlite3_stmt* stmt;
|
// sqlite3_stmt* stmt;
|
||||||
|
|
||||||
if (sqlite3_prepare_v2(db_, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
|
// if (sqlite3_prepare_v2(db_, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
sqlite3_bind_text(stmt, 1, labeltag.c_str(), -1, SQLITE_STATIC);
|
// sqlite3_bind_text(stmt, 1, labeltag.c_str(), -1, SQLITE_STATIC);
|
||||||
bool success = sqlite3_step(stmt) == SQLITE_DONE;
|
// bool success = sqlite3_step(stmt) == SQLITE_DONE;
|
||||||
sqlite3_finalize(stmt);
|
// sqlite3_finalize(stmt);
|
||||||
return success;
|
// return success;
|
||||||
}
|
// }
|
||||||
|
|
||||||
bool Database::remove_by_hash(const std::string& hash) {
|
bool Database::remove_by_hash(const std::string& hash) {
|
||||||
std::string sql = "DELETE FROM objects WHERE hash = ?;";
|
std::string sql = "DELETE FROM objects WHERE hash = ?;";
|
||||||
@@ -182,9 +182,9 @@ bool Database::remove_by_hash(const std::string& hash) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::get(const std::string& key, dbEntry& entry) {
|
bool Database::get(const std::string& hash_or_labeltag, dbEntry& entry) {
|
||||||
std::string sql;
|
std::string sql;
|
||||||
if (key.find(':') != std::string::npos) {
|
if (hash_or_labeltag.find(':') != std::string::npos) {
|
||||||
// Query by label:tag - search for exact match in the JSON array
|
// Query by label:tag - search for exact match in the JSON array
|
||||||
sql = "SELECT hash, labeltags, metadata FROM objects WHERE json_array_length(labeltags) > 0 AND EXISTS (SELECT 1 FROM json_each(labeltags) WHERE value = ?);";
|
sql = "SELECT hash, labeltags, metadata FROM objects WHERE json_array_length(labeltags) > 0 AND EXISTS (SELECT 1 FROM json_each(labeltags) WHERE value = ?);";
|
||||||
} else {
|
} else {
|
||||||
@@ -197,12 +197,7 @@ bool Database::get(const std::string& key, dbEntry& entry) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.find(':') != std::string::npos) {
|
sqlite3_bind_text(stmt, 1, hash_or_labeltag.c_str(), -1, SQLITE_STATIC);
|
||||||
// For label:tag queries, bind the exact label:tag string
|
|
||||||
sqlite3_bind_text(stmt, 1, key.c_str(), -1, SQLITE_STATIC);
|
|
||||||
} else {
|
|
||||||
sqlite3_bind_text(stmt, 1, key.c_str(), -1, SQLITE_STATIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
@@ -22,9 +22,8 @@ class Database {
|
|||||||
|
|
||||||
Database(const std::filesystem::path& path);
|
Database(const std::filesystem::path& path);
|
||||||
~Database();
|
~Database();
|
||||||
bool remove(const std::string& hash);
|
|
||||||
bool remove_by_hash(const std::string& hash);
|
bool remove_by_hash(const std::string& hash);
|
||||||
bool get(const std::string& hash, dbEntry& entry);
|
bool get(const std::string& hash_or_labeltag, dbEntry& entry);
|
||||||
bool list(std::vector<dbEntry>& entries);
|
bool list(std::vector<dbEntry>& entries);
|
||||||
bool update_or_insert(const dbEntry& entry);
|
bool update_or_insert(const dbEntry& entry);
|
||||||
private:
|
private:
|
||||||
|
173
src/server.cpp
173
src/server.cpp
@@ -154,8 +154,13 @@ void Server::setup_routes() {
|
|||||||
|
|
||||||
|
|
||||||
// Welcome page
|
// Welcome page
|
||||||
server_.Get("/", [](const httplib::Request&, httplib::Response& res) {
|
server_.Get("/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
if (req.path == "/") {
|
||||||
res.set_content(welcome_page(), "text/html");
|
res.set_content(welcome_page(), "text/html");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// if the path is not /, then it's a hash or label:tag
|
||||||
|
handle_get_object(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
server_.Get("/index.html", [](const httplib::Request&, httplib::Response& res) {
|
server_.Get("/index.html", [](const httplib::Request&, httplib::Response& res) {
|
||||||
@@ -172,6 +177,12 @@ void Server::setup_routes() {
|
|||||||
handle_get_hash(req, res);
|
handle_get_hash(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get version for label:tag
|
||||||
|
server_.Get("/version/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
handle_get_version(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Check if object exists by hash or label:tag
|
// Check if object exists by hash or label:tag
|
||||||
server_.Get("/exists/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
server_.Get("/exists/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
||||||
handle_exists(req, res);
|
handle_exists(req, res);
|
||||||
@@ -267,45 +278,18 @@ void Server::handle_get_object(const httplib::Request& req, httplib::Response& r
|
|||||||
|
|
||||||
// first check if the key matches.
|
// first check if the key matches.
|
||||||
dbEntry entry;
|
dbEntry entry;
|
||||||
if (db_->get(key, entry)) {
|
if (!db_->get(key, entry)) {
|
||||||
// got it!
|
|
||||||
hash_str = entry.hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hash_str.empty()) {
|
|
||||||
res.status = 404;
|
res.status = 404;
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Object hash could not be determined"}};
|
nlohmann::json response = {{"result", "error"}, {"error", "Couldn't find: " + key}};
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check valid hash.
|
|
||||||
uint64_t hash_value;
|
|
||||||
try {
|
|
||||||
hash_value = std::stoull(hash_str);
|
|
||||||
} catch (const std::invalid_argument& e) {
|
|
||||||
res.status = 404;
|
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Invalid hash: " + hash_str}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream oss;
|
|
||||||
oss << hash_value;
|
|
||||||
if (oss.str() != hash_str) {
|
|
||||||
res.status = 404;
|
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Invalid hash: " + hash_str}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hash is valid, safe to look up!
|
|
||||||
|
|
||||||
// Construct the file path using the hash string
|
// Construct the file path using the hash string
|
||||||
std::filesystem::path file_path = config_.object_store_path / oss.str();
|
std::filesystem::path file_path = config_.object_store_path / entry.hash;
|
||||||
if (!std::filesystem::exists(file_path) || !std::filesystem::is_regular_file(file_path)) {
|
if (!std::filesystem::exists(file_path) || !std::filesystem::is_regular_file(file_path)) {
|
||||||
res.status = 404;
|
res.status = 404;
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Object file not found for hash: " + hash_str}};
|
nlohmann::json response = {{"result", "error"}, {"error", "Hash recognised, but object missing for: " + entry.hash}};
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -357,68 +341,23 @@ void Server::handle_get_metadata(const httplib::Request& req, httplib::Response&
|
|||||||
|
|
||||||
// Check if the key is a label:tag format
|
// Check if the key is a label:tag format
|
||||||
dbEntry entry;
|
dbEntry entry;
|
||||||
|
nlohmann::json response;
|
||||||
|
|
||||||
if (db_->get(key, entry)) {
|
if (db_->get(key, entry)) {
|
||||||
// Got it from label:tag, use the hash
|
// Got it from label:tag, use the hash
|
||||||
hash_str = entry.hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we couldn't determine a hash
|
|
||||||
if (hash_str.empty()) {
|
|
||||||
res.status = 404;
|
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Metadata not found for: " + key}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to interpret the key as a hash directly
|
|
||||||
uint64_t hash_value;
|
|
||||||
try {
|
try {
|
||||||
hash_value = std::stoull(hash_str);
|
response = {{"result", "success"}, {"metadata", entry.metadata}};
|
||||||
} catch (const std::invalid_argument& e) {
|
|
||||||
res.status = 404;
|
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Invalid hash: " + hash_str}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream oss;
|
|
||||||
oss << hash_value;
|
|
||||||
if (oss.str() != hash_str) {
|
|
||||||
res.status = 404;
|
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Invalid hash: " + hash_str}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash is valid, look up the metadata
|
|
||||||
std::vector<dbEntry> entries;
|
|
||||||
if (!db_->list(entries)) {
|
|
||||||
res.status = 500;
|
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Failed to retrieve metadata"}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the entry with matching hash
|
|
||||||
for (const auto& e : entries) {
|
|
||||||
if (e.hash == hash_str) {
|
|
||||||
try {
|
|
||||||
nlohmann::json response = {{"result", "success"}, {"metadata", e.metadata}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
} catch (const nlohmann::json::exception& e) {
|
} catch (const nlohmann::json::exception& e) {
|
||||||
std::cerr << "Error serializing metadata for hash " << hash_str << ": " << e.what() << std::endl;
|
std::cerr << "Error serializing metadata for hash " << hash_str << ": " << e.what() << std::endl;
|
||||||
res.status = 500;
|
res.status = 500;
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Internal server error: Failed to serialize metadata"}};
|
response = {{"result", "error"}, {"error", "Internal server error: Failed to serialize metadata"}};
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
// No entry found with this hash
|
|
||||||
res.status = 404;
|
res.status = 404;
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Metadata not found for hash: " + hash_str}};
|
response = {{"result", "error"}, {"error", "Invalid hash: " + hash_str}};
|
||||||
|
}
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,22 +370,24 @@ std::pair<std::string, std::string> Server::parse_labeltag(const std::string& la
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Server::handle_delete_object(const httplib::Request& req, httplib::Response& res) {
|
void Server::handle_delete_object(const httplib::Request& req, httplib::Response& res) {
|
||||||
|
dbEntry entry;
|
||||||
|
|
||||||
|
{
|
||||||
std::map<std::string, std::string> params;
|
std::map<std::string, std::string> params;
|
||||||
if (!validate_write_request(req, res, {"hash"}, params)) {
|
if (!validate_write_request(req, res, {"hash"}, params)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate that the hash exists as a file
|
if (!db_->get(params["hash"], entry)) {
|
||||||
std::filesystem::path file_path = config_.object_store_path / params["hash"];
|
|
||||||
if (!std::filesystem::exists(file_path) || !std::filesystem::is_regular_file(file_path)) {
|
|
||||||
res.status = 404;
|
res.status = 404;
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Object not found for hash: " + params["hash"]}};
|
nlohmann::json response = {{"result", "error"}, {"error", "Object not found for: " + params["hash"]}};
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} // we only use sanitised data from here on out.
|
||||||
|
|
||||||
// Remove all tags that reference this hash
|
// Remove all tags that reference this hash
|
||||||
if (!db_->remove_by_hash(params["hash"])) {
|
if (!db_->remove_by_hash(entry.hash)) {
|
||||||
res.status = 500;
|
res.status = 500;
|
||||||
nlohmann::json response = {{"result", "error"}, {"error", "Failed to remove some or all associated tags"}};
|
nlohmann::json response = {{"result", "error"}, {"error", "Failed to remove some or all associated tags"}};
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
@@ -454,6 +395,8 @@ void Server::handle_delete_object(const httplib::Request& req, httplib::Response
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove the file
|
// Remove the file
|
||||||
|
std::filesystem::path file_path = config_.object_store_path / entry.hash;
|
||||||
|
if (std::filesystem::exists(file_path) && std::filesystem::is_regular_file(file_path)) {
|
||||||
try {
|
try {
|
||||||
std::filesystem::remove(file_path);
|
std::filesystem::remove(file_path);
|
||||||
} catch (const std::filesystem::filesystem_error& e) {
|
} catch (const std::filesystem::filesystem_error& e) {
|
||||||
@@ -463,52 +406,42 @@ void Server::handle_delete_object(const httplib::Request& req, httplib::Response
|
|||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nlohmann::json response = {{"result", "success"}};
|
nlohmann::json response = {{"result", "success"}};
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::handle_exists(const httplib::Request& req, httplib::Response& res) {
|
void Server::handle_exists(const httplib::Request& req, httplib::Response& res) {
|
||||||
|
const auto& key = req.matches[1].str();
|
||||||
|
nlohmann::json response;
|
||||||
|
dbEntry entry;
|
||||||
|
if (db_->get(key, entry)) {
|
||||||
|
response = {{"result", "success"}, {"exists", true}};
|
||||||
|
} else {
|
||||||
|
response = {{"result", "success"}, {"exists", false}};
|
||||||
|
}
|
||||||
|
res.set_content(response.dump(), "application/json");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::handle_get_version(const httplib::Request& req, httplib::Response& res) {
|
||||||
const auto& key = req.matches[1].str();
|
const auto& key = req.matches[1].str();
|
||||||
std::string hash_str = key;
|
std::string hash_str = key;
|
||||||
|
|
||||||
// Check if the key is a label:tag format
|
// Check if the key is a label:tag format
|
||||||
dbEntry entry;
|
dbEntry entry;
|
||||||
if (db_->get(key, entry)) {
|
if (!db_->get(key, entry)) {
|
||||||
// Got it from label:tag, use the hash
|
nlohmann::json response = {{"result", "failed"}, {"error", "Failed to get version for: " + key}};
|
||||||
hash_str = entry.hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we couldn't determine a hash
|
|
||||||
if (hash_str.empty()) {
|
|
||||||
nlohmann::json response = {{"result", "success"}, {"exists", false}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to interpret the key as a hash directly
|
nlohmann::json response;
|
||||||
uint64_t hash_value;
|
if (entry.metadata.contains("version")) {
|
||||||
try {
|
response = {{"result", "success"}, {"version", entry.metadata["version"]}};
|
||||||
hash_value = std::stoull(hash_str);
|
} else {
|
||||||
} catch (const std::invalid_argument& e) {
|
response = {{"result", "failed"}, {"error", "No version found for: " + key}};
|
||||||
nlohmann::json response = {{"result", "success"}, {"exists", false}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream oss;
|
|
||||||
oss << hash_value;
|
|
||||||
if (oss.str() != hash_str) {
|
|
||||||
nlohmann::json response = {{"result", "success"}, {"exists", false}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash is valid, check if the file exists
|
|
||||||
std::filesystem::path file_path = config_.object_store_path / oss.str();
|
|
||||||
bool exists = std::filesystem::exists(file_path) && std::filesystem::is_regular_file(file_path);
|
|
||||||
|
|
||||||
nlohmann::json response = {{"result", "success"}, {"exists", exists}};
|
|
||||||
res.set_content(response.dump(), "application/json");
|
res.set_content(response.dump(), "application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,6 +27,8 @@ public:
|
|||||||
ServerConfig config_;
|
ServerConfig config_;
|
||||||
std::unique_ptr<Database> db_;
|
std::unique_ptr<Database> db_;
|
||||||
|
|
||||||
|
void handle_get_version(const httplib::Request& req, httplib::Response& res);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup_routes();
|
void setup_routes();
|
||||||
void handle_get_object(const httplib::Request& req, httplib::Response& res);
|
void handle_get_object(const httplib::Request& req, httplib::Response& res);
|
||||||
|
@@ -157,6 +157,11 @@ std::string welcome_page() {
|
|||||||
<div class="endpoint-group">
|
<div class="endpoint-group">
|
||||||
<h3>Operations</h3>
|
<h3>Operations</h3>
|
||||||
<ul class="endpoint-list">
|
<ul class="endpoint-list">
|
||||||
|
<li>
|
||||||
|
<span class="endpoint-method">GET</span>
|
||||||
|
<span class="endpoint-path">/<span class="endpoint-param">{label:tag|hash}</span></span>
|
||||||
|
<span class="endpoint-desc">Retrieve an object</span>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="endpoint-method">GET</span>
|
<span class="endpoint-method">GET</span>
|
||||||
<span class="endpoint-path">/hash/<span class="endpoint-param">label:tag</span></span>
|
<span class="endpoint-path">/hash/<span class="endpoint-param">label:tag</span></span>
|
||||||
@@ -164,13 +169,13 @@ std::string welcome_page() {
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="endpoint-method">GET</span>
|
<span class="endpoint-method">GET</span>
|
||||||
<span class="endpoint-path">/exists/<span class="endpoint-param">{label:tag|hash}</span></span>
|
<span class="endpoint-path">/version/<span class="endpoint-param">label:tag</span></span>
|
||||||
<span class="endpoint-desc">Check if an object exists</span>
|
<span class="endpoint-desc">Get version for a label:tag</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="endpoint-method">GET</span>
|
<span class="endpoint-method">GET</span>
|
||||||
<span class="endpoint-path">/object/<span class="endpoint-param">{label:tag|hash}</span></span>
|
<span class="endpoint-path">/exists/<span class="endpoint-param">{label:tag|hash}</span></span>
|
||||||
<span class="endpoint-desc">Retrieve an object</span>
|
<span class="endpoint-desc">Check if an object exists</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="endpoint-method">GET</span>
|
<span class="endpoint-method">GET</span>
|
||||||
|
8
test.sh
8
test.sh
@@ -117,13 +117,13 @@ echo "md5sum of ${SCRIPT_DIR}/${SCRIPT_NAME} is ${MD5SUM}"
|
|||||||
|
|
||||||
# download the object
|
# download the object
|
||||||
echo "downloading ${OBJECT_HASH} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1"
|
echo "downloading ${OBJECT_HASH} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1"
|
||||||
if ! curl -s "${HOSTURL}/object/${OBJECT_HASH}" -o "${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1"; then
|
if ! curl -s "${HOSTURL}/${OBJECT_HASH}" -o "${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1"; then
|
||||||
die "failed to download ${OBJECT_HASH}"
|
die "failed to download ${OBJECT_HASH}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# download the object again via the label:tag
|
# download the object again via the label:tag
|
||||||
echo "downloading ${BASE_TAG}:test1 to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2"
|
echo "downloading ${BASE_TAG}:test1 to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2"
|
||||||
if ! curl -s "${HOSTURL}/object/${BASE_TAG}:test1" -o "${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2"; then
|
if ! curl -s "${HOSTURL}/${BASE_TAG}:test1" -o "${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2"; then
|
||||||
die "failed to download ${BASE_TAG}:test1"
|
die "failed to download ${BASE_TAG}:test1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ fi
|
|||||||
|
|
||||||
# download via the label:tag
|
# download via the label:tag
|
||||||
echo "downloading ${LABELTAG} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3"
|
echo "downloading ${LABELTAG} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3"
|
||||||
if ! curl -s "${HOSTURL}/object/${LABELTAG}" -o "${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3"; then
|
if ! curl -s "${HOSTURL}/${LABELTAG}" -o "${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3"; then
|
||||||
die "failed to download ${LABELTAG}"
|
die "failed to download ${LABELTAG}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ fi
|
|||||||
|
|
||||||
# verify the object is deleted
|
# verify the object is deleted
|
||||||
echo "verifying ${OBJECT_HASH} is deleted"
|
echo "verifying ${OBJECT_HASH} is deleted"
|
||||||
DELETE_RESPONSE=$(curl -s "${HOSTURL}/object/${OBJECT_HASH}")
|
DELETE_RESPONSE=$(curl -s "${HOSTURL}/${OBJECT_HASH}")
|
||||||
if ! echo "${DELETE_RESPONSE}" | jq -r '.result' | grep -q 'error'; then
|
if ! echo "${DELETE_RESPONSE}" | jq -r '.result' | grep -q 'error'; then
|
||||||
die "failed to verify ${OBJECT_HASH} is deleted"
|
die "failed to verify ${OBJECT_HASH} is deleted"
|
||||||
fi
|
fi
|
||||||
|
Reference in New Issue
Block a user