Support -f on service redeploy (C and Python SDKs)
Pass input_files to the redeploy API so un service --redeploy $ID -f repo.tar.gz works. Files are base64-encoded and sent in the JSON body, same as service create. C library API signature unchanged (internal static function extended).
This commit is contained in:
parent
de8c816b27
commit
ac50544ac3
2 changed files with 46 additions and 4 deletions
|
|
@ -4643,7 +4643,7 @@ static char* read_env_stdin(void) {
|
||||||
|
|
||||||
// Redeploy a service (re-run bootstrap script)
|
// Redeploy a service (re-run bootstrap script)
|
||||||
// Bootstrap scripts should be idempotent for proper upgrade behavior
|
// Bootstrap scripts should be idempotent for proper upgrade behavior
|
||||||
static int redeploy_service(const UnsandboxCredentials *creds, const char *service_id, const char *bootstrap) {
|
static int redeploy_service(const UnsandboxCredentials *creds, const char *service_id, const char *bootstrap, struct InputFile *input_files, int input_file_count) {
|
||||||
CURL *curl = curl_easy_init();
|
CURL *curl = curl_easy_init();
|
||||||
if (!curl) return 1;
|
if (!curl) return 1;
|
||||||
|
|
||||||
|
|
@ -4692,6 +4692,9 @@ static int redeploy_service(const UnsandboxCredentials *creds, const char *servi
|
||||||
} else if (bootstrap_url) {
|
} else if (bootstrap_url) {
|
||||||
payload_size += strlen(bootstrap_url) * 2 + 100;
|
payload_size += strlen(bootstrap_url) * 2 + 100;
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < input_file_count; i++) {
|
||||||
|
payload_size += strlen(input_files[i].content_base64) + 256;
|
||||||
|
}
|
||||||
|
|
||||||
// Build JSON payload manually (matching create_service pattern)
|
// Build JSON payload manually (matching create_service pattern)
|
||||||
char *payload = malloc(payload_size);
|
char *payload = malloc(payload_size);
|
||||||
|
|
@ -4704,15 +4707,31 @@ static int redeploy_service(const UnsandboxCredentials *creds, const char *servi
|
||||||
char *p = payload;
|
char *p = payload;
|
||||||
p += sprintf(p, "{");
|
p += sprintf(p, "{");
|
||||||
|
|
||||||
|
int has_field = 0;
|
||||||
if (bootstrap_content) {
|
if (bootstrap_content) {
|
||||||
char *esc_content = escape_json_string(bootstrap_content);
|
char *esc_content = escape_json_string(bootstrap_content);
|
||||||
p += sprintf(p, "\"bootstrap_content\":\"%s\"", esc_content);
|
p += sprintf(p, "\"bootstrap_content\":\"%s\"", esc_content);
|
||||||
free(esc_content);
|
free(esc_content);
|
||||||
free(bootstrap_content);
|
free(bootstrap_content);
|
||||||
|
has_field = 1;
|
||||||
} else if (bootstrap_url) {
|
} else if (bootstrap_url) {
|
||||||
char *esc_url = escape_json_string(bootstrap_url);
|
char *esc_url = escape_json_string(bootstrap_url);
|
||||||
p += sprintf(p, "\"bootstrap\":\"%s\"", esc_url);
|
p += sprintf(p, "\"bootstrap\":\"%s\"", esc_url);
|
||||||
free(esc_url);
|
free(esc_url);
|
||||||
|
has_field = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_file_count > 0) {
|
||||||
|
if (has_field) p += sprintf(p, ",");
|
||||||
|
p += sprintf(p, "\"input_files\":[");
|
||||||
|
for (int i = 0; i < input_file_count; i++) {
|
||||||
|
if (i > 0) p += sprintf(p, ",");
|
||||||
|
char *esc_filename = escape_json_string(input_files[i].filename);
|
||||||
|
p += sprintf(p, "{\"filename\":\"%s\",\"content\":\"%s\"}",
|
||||||
|
esc_filename, input_files[i].content_base64);
|
||||||
|
free(esc_filename);
|
||||||
|
}
|
||||||
|
p += sprintf(p, "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
p += sprintf(p, "}");
|
p += sprintf(p, "}");
|
||||||
|
|
@ -7100,7 +7119,7 @@ int unsandbox_service_redeploy(const char *service_id, const char *bootstrap,
|
||||||
const char *public_key, const char *secret_key) {
|
const char *public_key, const char *secret_key) {
|
||||||
UnsandboxCredentials *creds = get_credentials(public_key, secret_key, -1);
|
UnsandboxCredentials *creds = get_credentials(public_key, secret_key, -1);
|
||||||
if (!creds) return -1;
|
if (!creds) return -1;
|
||||||
int result = redeploy_service(creds, service_id, bootstrap);
|
int result = redeploy_service(creds, service_id, bootstrap, NULL, 0);
|
||||||
free_credentials(creds);
|
free_credentials(creds);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -10489,7 +10508,12 @@ int main(int argc, char *argv[]) {
|
||||||
// - If provided via --bootstrap or --bootstrap-file, use it
|
// - If provided via --bootstrap or --bootstrap-file, use it
|
||||||
// - If omitted, API will use the stored encrypted bootstrap
|
// - If omitted, API will use the stored encrypted bootstrap
|
||||||
const char *bootstrap_to_use = bootstrap_file ? bootstrap_file : service_bootstrap;
|
const char *bootstrap_to_use = bootstrap_file ? bootstrap_file : service_bootstrap;
|
||||||
ret = redeploy_service(creds, service_id, bootstrap_to_use);
|
ret = redeploy_service(creds, service_id, bootstrap_to_use, service_input_files, service_input_file_count);
|
||||||
|
// Free input file memory
|
||||||
|
for (int i = 0; i < service_input_file_count; i++) {
|
||||||
|
free(service_input_files[i].filename);
|
||||||
|
free(service_input_files[i].content_base64);
|
||||||
|
}
|
||||||
} else if (do_execute) {
|
} else if (do_execute) {
|
||||||
// Pass input files if provided (written to /tmp/input/ before command runs)
|
// Pass input files if provided (written to /tmp/input/ before command runs)
|
||||||
ret = execute_service(creds, service_id, execute_command, execute_timeout, service_input_files, service_input_file_count);
|
ret = execute_service(creds, service_id, execute_command, execute_timeout, service_input_files, service_input_file_count);
|
||||||
|
|
|
||||||
|
|
@ -1609,6 +1609,7 @@ def redeploy_service(
|
||||||
bootstrap: Optional[str] = None,
|
bootstrap: Optional[str] = None,
|
||||||
public_key: Optional[str] = None,
|
public_key: Optional[str] = None,
|
||||||
secret_key: Optional[str] = None,
|
secret_key: Optional[str] = None,
|
||||||
|
input_files: Optional[List[Dict[str, str]]] = None,
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Redeploy a service (re-run bootstrap script).
|
Redeploy a service (re-run bootstrap script).
|
||||||
|
|
@ -1620,6 +1621,7 @@ def redeploy_service(
|
||||||
bootstrap: Optional new bootstrap script/URL (uses existing if not provided)
|
bootstrap: Optional new bootstrap script/URL (uses existing if not provided)
|
||||||
public_key: Optional API key
|
public_key: Optional API key
|
||||||
secret_key: Optional API secret
|
secret_key: Optional API secret
|
||||||
|
input_files: Optional list of dicts with "filename" and "content" (base64)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Response dict with redeploy confirmation
|
Response dict with redeploy confirmation
|
||||||
|
|
@ -1636,6 +1638,8 @@ def redeploy_service(
|
||||||
data["bootstrap"] = bootstrap
|
data["bootstrap"] = bootstrap
|
||||||
else:
|
else:
|
||||||
data["bootstrap_content"] = bootstrap
|
data["bootstrap_content"] = bootstrap
|
||||||
|
if input_files:
|
||||||
|
data["input_files"] = input_files
|
||||||
|
|
||||||
return _make_request("POST", f"/services/{service_id}/redeploy", public_key, secret_key, data)
|
return _make_request("POST", f"/services/{service_id}/redeploy", public_key, secret_key, data)
|
||||||
|
|
||||||
|
|
@ -2983,7 +2987,21 @@ def _handle_service_command(args, public_key: str, secret_key: str):
|
||||||
bootstrap = f.read()
|
bootstrap = f.read()
|
||||||
elif args.bootstrap:
|
elif args.bootstrap:
|
||||||
bootstrap = args.bootstrap
|
bootstrap = args.bootstrap
|
||||||
result = redeploy_service(args.redeploy, bootstrap=bootstrap, public_key=public_key, secret_key=secret_key)
|
|
||||||
|
# Build input_files from -f args
|
||||||
|
service_input_files = None
|
||||||
|
if getattr(args, 'files', None):
|
||||||
|
import base64 as _b64
|
||||||
|
service_input_files = []
|
||||||
|
for fpath in args.files:
|
||||||
|
with open(fpath, "rb") as ff:
|
||||||
|
encoded = _b64.b64encode(ff.read()).decode("ascii")
|
||||||
|
service_input_files.append({
|
||||||
|
"filename": os.path.basename(fpath),
|
||||||
|
"content": encoded,
|
||||||
|
})
|
||||||
|
|
||||||
|
result = redeploy_service(args.redeploy, bootstrap=bootstrap, input_files=service_input_files, public_key=public_key, secret_key=secret_key)
|
||||||
print(f"Service {args.redeploy} redeployed")
|
print(f"Service {args.redeploy} redeployed")
|
||||||
elif args.execute:
|
elif args.execute:
|
||||||
service_id, command = args.execute
|
service_id, command = args.execute
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue