This commit is contained in:
parent
c08e718c95
commit
7b795600c1
@ -297,6 +297,83 @@ bool GetbinClient::getHash(const std::string& toolName, const std::string& arch,
|
||||
cv.wait(lock, [&] { return done; });
|
||||
}
|
||||
|
||||
worker.join();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool GetbinClient::deleteObject(const std::string& hash, const std::string& token) {
|
||||
bool success = false;
|
||||
bool done = false;
|
||||
std::mutex mtx;
|
||||
std::condition_variable cv;
|
||||
|
||||
std::thread worker([&]() {
|
||||
trantor::EventLoop loop;
|
||||
|
||||
auto client = drogon::HttpClient::newHttpClient(
|
||||
"https://" + std::string(SERVER_HOST),
|
||||
&loop
|
||||
);
|
||||
|
||||
// Configure SSL certificates
|
||||
std::string ca_path = find_ca_certificates();
|
||||
if (!ca_path.empty()) {
|
||||
std::cerr << "[GetbinClient] Found CA certificates at: " << ca_path << std::endl;
|
||||
std::vector<std::pair<std::string, std::string>> sslConfigs;
|
||||
sslConfigs.push_back({"VerifyCAFile", ca_path});
|
||||
client->addSSLConfigs(sslConfigs);
|
||||
} else {
|
||||
std::cerr << "[GetbinClient] Warning: No system CA certificates found. SSL verification may fail." << std::endl;
|
||||
}
|
||||
|
||||
client->enableCookies();
|
||||
client->setUserAgent("getpkg/1.0");
|
||||
|
||||
std::string delete_path = "/deleteobject?hash=" + hash;
|
||||
|
||||
auto req = drogon::HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::Get);
|
||||
req->setPath(delete_path);
|
||||
req->addHeader("Authorization", "Bearer " + token);
|
||||
|
||||
client->sendRequest(req, [&](drogon::ReqResult result, const drogon::HttpResponsePtr& response) {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
if (result == drogon::ReqResult::Ok && response) {
|
||||
int status_code = static_cast<int>(response->getStatusCode());
|
||||
std::string response_body(response->getBody());
|
||||
|
||||
if (status_code == 200) {
|
||||
// Check if the response indicates success
|
||||
try {
|
||||
auto resp_json = json::parse(response_body);
|
||||
if (resp_json.contains("result") && resp_json["result"] == "success") {
|
||||
success = true;
|
||||
}
|
||||
} catch (...) {
|
||||
// If not JSON, assume success if 200 OK
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "[GetbinClient::deleteObject] HTTP error: status code " << status_code << std::endl;
|
||||
std::cerr << "[GetbinClient::deleteObject] Response body: " << response_body << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "[GetbinClient::deleteObject] HTTP request failed." << std::endl;
|
||||
}
|
||||
done = true;
|
||||
cv.notify_one();
|
||||
loop.quit();
|
||||
}, 10.0); // 10 second timeout
|
||||
|
||||
loop.loop();
|
||||
});
|
||||
|
||||
// Wait for completion
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
cv.wait(lock, [&] { return done; });
|
||||
}
|
||||
|
||||
worker.join();
|
||||
return success;
|
||||
}
|
@ -7,4 +7,5 @@ public:
|
||||
bool download(const std::string& toolName, const std::string& arch, const std::string& outPath);
|
||||
bool upload(const std::string& archivePath, std::string& outUrl, std::string& outHash, const std::string& token);
|
||||
bool getHash(const std::string& toolName, const std::string& arch, std::string& outHash);
|
||||
bool deleteObject(const std::string& hash, const std::string& token);
|
||||
};
|
@ -403,6 +403,89 @@ int hash_command(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unpublish_tool(int argc, char* argv[]) {
|
||||
if (argc < 3) {
|
||||
std::cerr << "Usage: getpkg unpublish <tool_name[:ARCH]>" << std::endl;
|
||||
std::cerr << " getpkg unpublish <hash>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::string target = argv[2];
|
||||
|
||||
// Get token
|
||||
std::string token;
|
||||
const char* envToken = std::getenv("SOS_WRITE_TOKEN");
|
||||
if (envToken && std::strlen(envToken) > 0) {
|
||||
token = envToken;
|
||||
} else {
|
||||
std::string home = get_home();
|
||||
std::filesystem::path tokenPath = std::filesystem::path(home) / ".config/getpkg.xyz/write_token.txt";
|
||||
if (std::filesystem::exists(tokenPath)) {
|
||||
std::ifstream tfile(tokenPath);
|
||||
std::getline(tfile, token);
|
||||
} else {
|
||||
std::cout << "Enter getpkg.xyz write token: ";
|
||||
std::getline(std::cin, token);
|
||||
std::filesystem::create_directories(tokenPath.parent_path());
|
||||
std::ofstream tfile(tokenPath);
|
||||
tfile << token << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (token.empty()) {
|
||||
std::cerr << "Error: No write token provided" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
GetbinClient getbin;
|
||||
std::string hash = target;
|
||||
|
||||
// Check if target looks like a hash (all digits) or a tool name
|
||||
bool isHash = true;
|
||||
for (char c : target) {
|
||||
if (!std::isdigit(c)) {
|
||||
isHash = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isHash) {
|
||||
// Target is a tool name, need to get hash first
|
||||
std::string toolName = target;
|
||||
std::string arch = "x86_64"; // default
|
||||
|
||||
// Check if arch is specified (contains :)
|
||||
if (target.find(':') != std::string::npos) {
|
||||
toolName = target.substr(0, target.find(':'));
|
||||
arch = target.substr(target.find(':') + 1);
|
||||
}
|
||||
|
||||
if (!getbin.getHash(toolName, arch, hash)) {
|
||||
std::cerr << "Failed to get hash for " << target << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (hash.empty()) {
|
||||
std::cerr << "Tool " << target << " not found" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Found hash " << hash << " for " << target << std::endl;
|
||||
}
|
||||
|
||||
// Delete the object
|
||||
if (getbin.deleteObject(hash, token)) {
|
||||
std::cout << "Successfully unpublished " << target;
|
||||
if (!isHash) {
|
||||
std::cout << " (hash: " << hash << ")";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
} else {
|
||||
std::cerr << "Failed to unpublish " << target << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int uninstall_tool(int argc, char* argv[]) {
|
||||
if (argc < 3) {
|
||||
std::cerr << "Usage: getpkg uninstall <tool_name>" << std::endl;
|
||||
@ -468,6 +551,10 @@ void show_help() {
|
||||
std::cout << " ARCH is optional (defaults to 'universal')" << std::endl;
|
||||
std::cout << " Requires SOS_WRITE_TOKEN environment variable" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << " unpublish <tool_name[:ARCH]> Remove a published tool" << std::endl;
|
||||
std::cout << " unpublish <hash> Remove a published tool by hash" << std::endl;
|
||||
std::cout << " Requires SOS_WRITE_TOKEN environment variable" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << " update Update getpkg and all installed tools" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << " create <tool_name> <directory> Create a new tool project" << std::endl;
|
||||
@ -485,6 +572,7 @@ void show_help() {
|
||||
std::cout << " getpkg install myapp Install myapp (legacy syntax)" << std::endl;
|
||||
std::cout << " getpkg publish myapp:x86_64 ./build Publish architecture-specific build" << std::endl;
|
||||
std::cout << " getpkg publish myapp ./build Publish universal build" << std::endl;
|
||||
std::cout << " getpkg unpublish myapp:x86_64 Remove published myapp" << std::endl;
|
||||
std::cout << " getpkg uninstall myapp Remove myapp from system" << std::endl;
|
||||
std::cout << " getpkg update Update everything" << std::endl;
|
||||
std::cout << std::endl;
|
||||
@ -511,6 +599,8 @@ int main(int argc, char* argv[]) {
|
||||
return uninstall_tool(argc, argv);
|
||||
} else if (command == "publish") {
|
||||
return publish_tool(argc, argv);
|
||||
} else if (command == "unpublish") {
|
||||
return unpublish_tool(argc, argv);
|
||||
} else if (command == "update") {
|
||||
return update_tool(argc, argv);
|
||||
} else if (command == "autocomplete") {
|
||||
@ -518,6 +608,7 @@ int main(int argc, char* argv[]) {
|
||||
if (args.empty()) std::cout << R"(install
|
||||
uninstall
|
||||
publish
|
||||
unpublish
|
||||
update
|
||||
version
|
||||
create
|
||||
|
Loading…
x
Reference in New Issue
Block a user