feat: add unfreeze_on_demand support to all SDKs
Updated Python, JavaScript, Go, Rust, Ruby, Java, and TypeScript SDKs: - Add unfreeze_on_demand field to Service struct/class - Add setUnfreezeOnDemand function to toggle setting via PATCH /services/:id - Add unfreeze_on_demand parameter to createService function
This commit is contained in:
parent
04060aa4da
commit
e58adcd5fe
13 changed files with 435 additions and 10 deletions
|
|
@ -1100,9 +1100,10 @@ func ShellSession(creds *Credentials, sessionID, command string) <-chan SessionR
|
|||
|
||||
// ServiceOptions contains optional parameters for service creation.
|
||||
type ServiceOptions struct {
|
||||
NetworkMode string // "zerotrust" (default) or "semitrusted"
|
||||
Shell string // Shell to use for bootstrap
|
||||
VCPU int // Number of virtual CPUs
|
||||
NetworkMode string // "zerotrust" (default) or "semitrusted"
|
||||
Shell string // Shell to use for bootstrap
|
||||
VCPU int // Number of virtual CPUs
|
||||
UnfreezeOnDemand bool // Enable automatic unfreezing on HTTP request
|
||||
}
|
||||
|
||||
// ServiceUpdateOptions contains optional parameters for service updates.
|
||||
|
|
@ -1184,6 +1185,9 @@ func CreateService(creds *Credentials, name string, ports []int, bootstrap strin
|
|||
if opts.VCPU > 0 {
|
||||
data["vcpu"] = opts.VCPU
|
||||
}
|
||||
if opts.UnfreezeOnDemand {
|
||||
data["unfreeze_on_demand"] = true
|
||||
}
|
||||
}
|
||||
|
||||
response, err := makeRequest("POST", "/services", creds, data)
|
||||
|
|
@ -1304,6 +1308,23 @@ func UnlockService(creds *Credentials, serviceID string) <-chan ServiceResult {
|
|||
return resultChan
|
||||
}
|
||||
|
||||
// SetUnfreezeOnDemand enables or disables automatic unfreezing on HTTP request.
|
||||
// Returns a channel that receives exactly one ServiceResult then closes.
|
||||
func SetUnfreezeOnDemand(creds *Credentials, serviceID string, enabled bool) <-chan ServiceResult {
|
||||
resultChan := make(chan ServiceResult, 1)
|
||||
|
||||
go func() {
|
||||
defer close(resultChan)
|
||||
|
||||
response, err := makeRequest("PATCH", fmt.Sprintf("/services/%s", serviceID), creds, map[string]interface{}{
|
||||
"unfreeze_on_demand": enabled,
|
||||
})
|
||||
resultChan <- ServiceResult{Data: response, Err: err}
|
||||
}()
|
||||
|
||||
return resultChan
|
||||
}
|
||||
|
||||
// GetServiceLogs retrieves logs from a service.
|
||||
// Returns a channel that receives exactly one ServiceResult then closes.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -773,9 +773,10 @@ func ShellSession(creds *Credentials, sessionID, command string) (map[string]int
|
|||
|
||||
// ServiceOptions contains optional parameters for service creation.
|
||||
type ServiceOptions struct {
|
||||
NetworkMode string // "zerotrust" (default) or "semitrusted"
|
||||
Shell string // Shell to use for bootstrap
|
||||
VCPU int // Number of virtual CPUs
|
||||
NetworkMode string // "zerotrust" (default) or "semitrusted"
|
||||
Shell string // Shell to use for bootstrap
|
||||
VCPU int // Number of virtual CPUs
|
||||
UnfreezeOnDemand bool // Enable automatic unfreezing on HTTP request
|
||||
}
|
||||
|
||||
// ServiceUpdateOptions contains optional parameters for service updates.
|
||||
|
|
@ -829,6 +830,9 @@ func CreateService(creds *Credentials, name string, ports []int, bootstrap strin
|
|||
if opts.VCPU > 0 {
|
||||
data["vcpu"] = opts.VCPU
|
||||
}
|
||||
if opts.UnfreezeOnDemand {
|
||||
data["unfreeze_on_demand"] = true
|
||||
}
|
||||
}
|
||||
|
||||
return makeRequest("POST", "/services", creds, data)
|
||||
|
|
@ -875,6 +879,13 @@ func UnlockService(creds *Credentials, serviceID string) (map[string]interface{}
|
|||
return makeRequest("POST", fmt.Sprintf("/services/%s/unlock", serviceID), creds, map[string]interface{}{})
|
||||
}
|
||||
|
||||
// SetUnfreezeOnDemand enables or disables automatic unfreezing on HTTP request.
|
||||
func SetUnfreezeOnDemand(creds *Credentials, serviceID string, enabled bool) (map[string]interface{}, error) {
|
||||
return makeRequest("PATCH", fmt.Sprintf("/services/%s", serviceID), creds, map[string]interface{}{
|
||||
"unfreeze_on_demand": enabled,
|
||||
})
|
||||
}
|
||||
|
||||
// GetServiceLogs retrieves logs from a service.
|
||||
//
|
||||
// Args:
|
||||
|
|
|
|||
|
|
@ -1352,6 +1352,54 @@ public class UnsandboxAsync {
|
|||
return makeRequest("POST", "/services", creds[0], creds[1], data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new service (long-running container) with unfreeze-on-demand option.
|
||||
*
|
||||
* @param name Service name (used for hostname)
|
||||
* @param ports Comma-separated list of ports to expose (e.g., "80,443")
|
||||
* @param bootstrap Bootstrap script or URL to run on service creation
|
||||
* @param unfreezeOnDemand If true, frozen service will auto-wake on HTTP request
|
||||
* @param publicKey Optional API key
|
||||
* @param secretKey Optional API secret
|
||||
* @return CompletableFuture containing response map with service_id
|
||||
*/
|
||||
public static CompletableFuture<Map<String, Object>> createService(
|
||||
String name,
|
||||
String ports,
|
||||
String bootstrap,
|
||||
boolean unfreezeOnDemand,
|
||||
String publicKey,
|
||||
String secretKey
|
||||
) {
|
||||
String[] creds = resolveCredentials(publicKey, secretKey);
|
||||
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("name", name);
|
||||
if (ports != null && !ports.isEmpty()) {
|
||||
List<Integer> portList = new ArrayList<>();
|
||||
for (String p : ports.split(",")) {
|
||||
try {
|
||||
portList.add(Integer.parseInt(p.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
// Skip invalid port
|
||||
}
|
||||
}
|
||||
data.put("ports", portList);
|
||||
}
|
||||
if (bootstrap != null && !bootstrap.isEmpty()) {
|
||||
if (bootstrap.startsWith("http://") || bootstrap.startsWith("https://")) {
|
||||
data.put("bootstrap_url", bootstrap);
|
||||
} else {
|
||||
data.put("bootstrap", bootstrap);
|
||||
}
|
||||
}
|
||||
if (unfreezeOnDemand) {
|
||||
data.put("unfreeze_on_demand", true);
|
||||
}
|
||||
|
||||
return makeRequest("POST", "/services", creds[0], creds[1], data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details of a specific service.
|
||||
*
|
||||
|
|
@ -1473,6 +1521,30 @@ public class UnsandboxAsync {
|
|||
return makeRequest("POST", "/services/" + serviceId + "/unlock", creds[0], creds[1], new LinkedHashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set unfreeze-on-demand for a service.
|
||||
*
|
||||
* <p>When enabled, a frozen service will automatically wake up when it receives
|
||||
* an HTTP request, without requiring an explicit unfreeze API call.
|
||||
*
|
||||
* @param serviceId Service ID to configure
|
||||
* @param enabled True to enable unfreeze-on-demand, false to disable
|
||||
* @param publicKey Optional API key
|
||||
* @param secretKey Optional API secret
|
||||
* @return CompletableFuture containing response map with update confirmation
|
||||
*/
|
||||
public static CompletableFuture<Map<String, Object>> setUnfreezeOnDemand(
|
||||
String serviceId,
|
||||
boolean enabled,
|
||||
String publicKey,
|
||||
String secretKey
|
||||
) {
|
||||
String[] creds = resolveCredentials(publicKey, secretKey);
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("unfreeze_on_demand", enabled);
|
||||
return makeRequestWithMethod("PATCH", "/services/" + serviceId, creds[0], creds[1], data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bootstrap logs for a service.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1345,6 +1345,58 @@ public class Un {
|
|||
return makeRequest("POST", "/services", creds[0], creds[1], data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new service (long-running container) with unfreeze-on-demand option.
|
||||
*
|
||||
* @param name Service name (used for hostname)
|
||||
* @param ports Comma-separated list of ports to expose (e.g., "80,443")
|
||||
* @param bootstrap Bootstrap script or URL to run on service creation
|
||||
* @param unfreezeOnDemand If true, frozen service will auto-wake on HTTP request
|
||||
* @param publicKey Optional API key
|
||||
* @param secretKey Optional API secret
|
||||
* @return Response map containing service_id
|
||||
* @throws IOException on network errors
|
||||
* @throws CredentialsException if credentials cannot be found
|
||||
* @throws ApiException if API returns an error
|
||||
*/
|
||||
public static Map<String, Object> createService(
|
||||
String name,
|
||||
String ports,
|
||||
String bootstrap,
|
||||
boolean unfreezeOnDemand,
|
||||
String publicKey,
|
||||
String secretKey
|
||||
) throws IOException {
|
||||
String[] creds = resolveCredentials(publicKey, secretKey);
|
||||
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("name", name);
|
||||
if (ports != null && !ports.isEmpty()) {
|
||||
// Parse ports string into list
|
||||
List<Integer> portList = new ArrayList<>();
|
||||
for (String p : ports.split(",")) {
|
||||
try {
|
||||
portList.add(Integer.parseInt(p.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
// Skip invalid port
|
||||
}
|
||||
}
|
||||
data.put("ports", portList);
|
||||
}
|
||||
if (bootstrap != null && !bootstrap.isEmpty()) {
|
||||
if (bootstrap.startsWith("http://") || bootstrap.startsWith("https://")) {
|
||||
data.put("bootstrap_url", bootstrap);
|
||||
} else {
|
||||
data.put("bootstrap", bootstrap);
|
||||
}
|
||||
}
|
||||
if (unfreezeOnDemand) {
|
||||
data.put("unfreeze_on_demand", true);
|
||||
}
|
||||
|
||||
return makeRequest("POST", "/services", creds[0], creds[1], data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details of a specific service.
|
||||
*
|
||||
|
|
@ -1487,6 +1539,33 @@ public class Un {
|
|||
return makeRequest("POST", "/services/" + serviceId + "/unlock", creds[0], creds[1], new LinkedHashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set unfreeze-on-demand for a service.
|
||||
*
|
||||
* <p>When enabled, a frozen service will automatically wake up when it receives
|
||||
* an HTTP request, without requiring an explicit unfreeze API call.
|
||||
*
|
||||
* @param serviceId Service ID to configure
|
||||
* @param enabled True to enable unfreeze-on-demand, false to disable
|
||||
* @param publicKey Optional API key
|
||||
* @param secretKey Optional API secret
|
||||
* @return Response map with update confirmation
|
||||
* @throws IOException on network errors
|
||||
* @throws CredentialsException if credentials cannot be found
|
||||
* @throws ApiException if API returns an error
|
||||
*/
|
||||
public static Map<String, Object> setUnfreezeOnDemand(
|
||||
String serviceId,
|
||||
boolean enabled,
|
||||
String publicKey,
|
||||
String secretKey
|
||||
) throws IOException {
|
||||
String[] creds = resolveCredentials(publicKey, secretKey);
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("unfreeze_on_demand", enabled);
|
||||
return makeRequestWithMethod("PATCH", "/services/" + serviceId, creds[0], creds[1], data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bootstrap logs for a service.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* freezeSession, unfreezeSession, boostSession, unboostSession, shellSession,
|
||||
* // Service management
|
||||
* listServices, createService, getService, updateService, deleteService,
|
||||
* freezeService, unfreezeService, lockService, unlockService,
|
||||
* freezeService, unfreezeService, lockService, unlockService, setUnfreezeOnDemand,
|
||||
* getServiceLogs, getServiceEnv, setServiceEnv, deleteServiceEnv,
|
||||
* exportServiceEnv, redeployService, executeInService,
|
||||
* // Snapshot management
|
||||
|
|
@ -751,6 +751,7 @@ async function listServices(publicKey, secretKey) {
|
|||
* - vcpu: Number of vCPUs (1-8)
|
||||
* - domains: Array of custom domains
|
||||
* - serviceType: Service type for SRV records (minecraft, mumble, etc.)
|
||||
* - unfreezeOnDemand: If true, frozen services wake automatically on HTTP traffic
|
||||
*
|
||||
* Returns: Promise<Object> (service info with service_id)
|
||||
*/
|
||||
|
|
@ -771,6 +772,7 @@ async function createService(name, ports, bootstrap, opts = {}, publicKey, secre
|
|||
if (opts.vcpu && opts.vcpu > 1) data.vcpu = opts.vcpu;
|
||||
if (opts.domains) data.custom_domains = opts.domains;
|
||||
if (opts.serviceType) data.service_type = opts.serviceType;
|
||||
if (opts.unfreezeOnDemand) data.unfreeze_on_demand = true;
|
||||
|
||||
return makeRequest('POST', '/services', publicKey, secretKey, data);
|
||||
}
|
||||
|
|
@ -870,6 +872,22 @@ async function unlockService(serviceId, publicKey, secretKey) {
|
|||
return makeRequest('POST', `/services/${serviceId}/unlock`, publicKey, secretKey, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set unfreeze-on-demand for a service.
|
||||
*
|
||||
* When enabled, frozen services will automatically wake when HTTP traffic arrives.
|
||||
*
|
||||
* Args:
|
||||
* serviceId: Service ID to update
|
||||
* enabled: true to enable, false to disable
|
||||
*
|
||||
* Returns: Promise<Object> (update confirmation)
|
||||
*/
|
||||
async function setUnfreezeOnDemand(serviceId, enabled, publicKey, secretKey) {
|
||||
[publicKey, secretKey] = resolveCredentials(publicKey, secretKey);
|
||||
return makeRequest('PATCH', `/services/${serviceId}`, publicKey, secretKey, { unfreeze_on_demand: enabled });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service logs.
|
||||
*
|
||||
|
|
@ -1127,6 +1145,7 @@ export {
|
|||
unfreezeService,
|
||||
lockService,
|
||||
unlockService,
|
||||
setUnfreezeOnDemand,
|
||||
getServiceLogs,
|
||||
getServiceEnv,
|
||||
setServiceEnv,
|
||||
|
|
@ -1185,6 +1204,7 @@ export default {
|
|||
unfreezeService,
|
||||
lockService,
|
||||
unlockService,
|
||||
setUnfreezeOnDemand,
|
||||
getServiceLogs,
|
||||
getServiceEnv,
|
||||
setServiceEnv,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* freezeSession, unfreezeSession, boostSession, unboostSession, shellSession,
|
||||
* // Service management
|
||||
* listServices, createService, getService, updateService, deleteService,
|
||||
* freezeService, unfreezeService, lockService, unlockService,
|
||||
* freezeService, unfreezeService, lockService, unlockService, setUnfreezeOnDemand,
|
||||
* getServiceLogs, getServiceEnv, setServiceEnv, deleteServiceEnv,
|
||||
* exportServiceEnv, redeployService, executeInService,
|
||||
* // Snapshot management
|
||||
|
|
@ -735,6 +735,7 @@ async function listServices(publicKey, secretKey) {
|
|||
* - vcpu: Number of vCPUs (1-8)
|
||||
* - domains: Array of custom domains
|
||||
* - serviceType: Service type for SRV records (minecraft, mumble, etc.)
|
||||
* - unfreezeOnDemand: If true, frozen services wake automatically on HTTP traffic
|
||||
*
|
||||
* Returns: Promise<Object> (service info with service_id)
|
||||
*/
|
||||
|
|
@ -755,6 +756,7 @@ async function createService(name, ports, bootstrap, opts = {}, publicKey, secre
|
|||
if (opts.vcpu && opts.vcpu > 1) data.vcpu = opts.vcpu;
|
||||
if (opts.domains) data.custom_domains = opts.domains;
|
||||
if (opts.serviceType) data.service_type = opts.serviceType;
|
||||
if (opts.unfreezeOnDemand) data.unfreeze_on_demand = true;
|
||||
|
||||
return makeRequest('POST', '/services', publicKey, secretKey, data);
|
||||
}
|
||||
|
|
@ -854,6 +856,22 @@ async function unlockService(serviceId, publicKey, secretKey) {
|
|||
return makeRequest('POST', `/services/${serviceId}/unlock`, publicKey, secretKey, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set unfreeze-on-demand for a service.
|
||||
*
|
||||
* When enabled, frozen services will automatically wake when HTTP traffic arrives.
|
||||
*
|
||||
* Args:
|
||||
* serviceId: Service ID to update
|
||||
* enabled: true to enable, false to disable
|
||||
*
|
||||
* Returns: Promise<Object> (update confirmation)
|
||||
*/
|
||||
async function setUnfreezeOnDemand(serviceId, enabled, publicKey, secretKey) {
|
||||
[publicKey, secretKey] = resolveCredentials(publicKey, secretKey);
|
||||
return makeRequest('PATCH', `/services/${serviceId}`, publicKey, secretKey, { unfreeze_on_demand: enabled });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service logs.
|
||||
*
|
||||
|
|
@ -1356,6 +1374,7 @@ module.exports = {
|
|||
unfreezeService,
|
||||
lockService,
|
||||
unlockService,
|
||||
setUnfreezeOnDemand,
|
||||
getServiceLogs,
|
||||
getServiceEnv,
|
||||
setServiceEnv,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ Library Usage:
|
|||
unfreeze_service,
|
||||
lock_service,
|
||||
unlock_service,
|
||||
set_unfreeze_on_demand,
|
||||
get_service_logs,
|
||||
get_service_env,
|
||||
set_service_env,
|
||||
|
|
@ -1046,6 +1047,7 @@ async def create_service(
|
|||
custom_domains: Optional[List[str]] = None,
|
||||
vcpu: int = 1,
|
||||
service_type: Optional[str] = None,
|
||||
unfreeze_on_demand: bool = False,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Create a new persistent service.
|
||||
|
|
@ -1060,6 +1062,7 @@ async def create_service(
|
|||
custom_domains: Optional list of custom domain names
|
||||
vcpu: Number of vCPUs (1-8, default 1)
|
||||
service_type: Optional service type for SRV records (e.g., "minecraft")
|
||||
unfreeze_on_demand: If True, automatically unfreeze service on incoming requests
|
||||
|
||||
Returns:
|
||||
Response dict containing service_id, etc.
|
||||
|
|
@ -1087,6 +1090,8 @@ async def create_service(
|
|||
data["vcpu"] = vcpu
|
||||
if service_type:
|
||||
data["service_type"] = service_type
|
||||
if unfreeze_on_demand:
|
||||
data["unfreeze_on_demand"] = unfreeze_on_demand
|
||||
|
||||
return await _make_request("POST", "/services", public_key, secret_key, data)
|
||||
|
||||
|
|
@ -1275,6 +1280,42 @@ async def unlock_service(
|
|||
return await _make_request("POST", f"/services/{service_id}/unlock", public_key, secret_key, {})
|
||||
|
||||
|
||||
async def set_unfreeze_on_demand(
|
||||
service_id: str,
|
||||
enabled: bool,
|
||||
public_key: Optional[str] = None,
|
||||
secret_key: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Enable or disable automatic unfreezing on incoming requests.
|
||||
|
||||
When enabled, a frozen service will automatically wake up when it
|
||||
receives an incoming HTTP request.
|
||||
|
||||
Args:
|
||||
service_id: Service ID to configure
|
||||
enabled: True to enable auto-unfreeze, False to disable
|
||||
public_key: Optional API key
|
||||
secret_key: Optional API secret
|
||||
|
||||
Returns:
|
||||
Response dict with update confirmation
|
||||
|
||||
Raises:
|
||||
aiohttp.ClientError: Network errors
|
||||
ValueError: Invalid response format
|
||||
CredentialsError: Missing credentials
|
||||
"""
|
||||
public_key, secret_key = _resolve_credentials(public_key, secret_key)
|
||||
return await _make_request(
|
||||
"PATCH",
|
||||
f"/services/{service_id}",
|
||||
public_key,
|
||||
secret_key,
|
||||
{"unfreeze_on_demand": enabled},
|
||||
)
|
||||
|
||||
|
||||
async def get_service_logs(
|
||||
service_id: str,
|
||||
all_logs: bool = False,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ Library Usage:
|
|||
unfreeze_service,
|
||||
lock_service,
|
||||
unlock_service,
|
||||
set_unfreeze_on_demand,
|
||||
get_service_logs,
|
||||
get_service_env,
|
||||
set_service_env,
|
||||
|
|
@ -1060,6 +1061,7 @@ def create_service(
|
|||
custom_domains: Optional[List[str]] = None,
|
||||
vcpu: int = 1,
|
||||
service_type: Optional[str] = None,
|
||||
unfreeze_on_demand: bool = False,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Create a new persistent service.
|
||||
|
|
@ -1074,6 +1076,7 @@ def create_service(
|
|||
custom_domains: Optional list of custom domain names
|
||||
vcpu: Number of vCPUs (1-8, default 1)
|
||||
service_type: Optional service type for SRV records (e.g., "minecraft")
|
||||
unfreeze_on_demand: If True, automatically unfreeze service on incoming requests
|
||||
|
||||
Returns:
|
||||
Response dict containing service_id, etc.
|
||||
|
|
@ -1101,6 +1104,8 @@ def create_service(
|
|||
data["vcpu"] = vcpu
|
||||
if service_type:
|
||||
data["service_type"] = service_type
|
||||
if unfreeze_on_demand:
|
||||
data["unfreeze_on_demand"] = unfreeze_on_demand
|
||||
|
||||
return _make_request("POST", "/services", public_key, secret_key, data)
|
||||
|
||||
|
|
@ -1289,6 +1294,42 @@ def unlock_service(
|
|||
return _make_request("POST", f"/services/{service_id}/unlock", public_key, secret_key, {})
|
||||
|
||||
|
||||
def set_unfreeze_on_demand(
|
||||
service_id: str,
|
||||
enabled: bool,
|
||||
public_key: Optional[str] = None,
|
||||
secret_key: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Enable or disable automatic unfreezing on incoming requests.
|
||||
|
||||
When enabled, a frozen service will automatically wake up when it
|
||||
receives an incoming HTTP request.
|
||||
|
||||
Args:
|
||||
service_id: Service ID to configure
|
||||
enabled: True to enable auto-unfreeze, False to disable
|
||||
public_key: Optional API key
|
||||
secret_key: Optional API secret
|
||||
|
||||
Returns:
|
||||
Response dict with update confirmation
|
||||
|
||||
Raises:
|
||||
requests.RequestException: Network errors
|
||||
ValueError: Invalid response format
|
||||
CredentialsError: Missing credentials
|
||||
"""
|
||||
public_key, secret_key = _resolve_credentials(public_key, secret_key)
|
||||
return _make_request(
|
||||
"PATCH",
|
||||
f"/services/{service_id}",
|
||||
public_key,
|
||||
secret_key,
|
||||
{"unfreeze_on_demand": enabled},
|
||||
)
|
||||
|
||||
|
||||
def get_service_logs(
|
||||
service_id: str,
|
||||
all_logs: bool = False,
|
||||
|
|
|
|||
|
|
@ -765,6 +765,7 @@ module UnAsync
|
|||
# @param vcpu [Integer] Number of vCPUs (1-8)
|
||||
# @param custom_domains [Array<String>, nil] Custom domains for the service
|
||||
# @param service_type [String, nil] Service type for SRV records
|
||||
# @param unfreeze_on_demand [Boolean] If true, service will auto-wake on HTTP request (default: false)
|
||||
# @return [Future<Hash>] Future resolving to response hash with service_id
|
||||
# @raise [CredentialsError] If no credentials found (on .value)
|
||||
# @raise [APIError] If API request fails (on .value)
|
||||
|
|
@ -772,7 +773,7 @@ module UnAsync
|
|||
# @example
|
||||
# result = UnAsync.create_service("web", [80, 443], "apt install -y nginx && nginx").value
|
||||
# puts result["service_id"]
|
||||
def create_service(name, ports, bootstrap, public_key: nil, secret_key: nil, network_mode: 'semitrusted', vcpu: 1, custom_domains: nil, service_type: nil)
|
||||
def create_service(name, ports, bootstrap, public_key: nil, secret_key: nil, network_mode: 'semitrusted', vcpu: 1, custom_domains: nil, service_type: nil, unfreeze_on_demand: false)
|
||||
Future.new do
|
||||
pk, sk = resolve_credentials(public_key, secret_key)
|
||||
data = {
|
||||
|
|
@ -784,6 +785,7 @@ module UnAsync
|
|||
data[:vcpu] = vcpu if vcpu > 1
|
||||
data[:custom_domains] = custom_domains if custom_domains
|
||||
data[:service_type] = service_type if service_type
|
||||
data[:unfreeze_on_demand] = unfreeze_on_demand if unfreeze_on_demand
|
||||
make_request_sync('POST', '/services', pk, sk, data)
|
||||
end
|
||||
end
|
||||
|
|
@ -920,6 +922,27 @@ module UnAsync
|
|||
end
|
||||
end
|
||||
|
||||
# Set unfreeze-on-demand for a service
|
||||
#
|
||||
# When enabled, a frozen service will automatically wake when it receives an HTTP request.
|
||||
#
|
||||
# @param service_id [String] Service ID to update
|
||||
# @param enabled [Boolean] Whether to enable unfreeze-on-demand
|
||||
# @param public_key [String, nil] Optional API key
|
||||
# @param secret_key [String, nil] Optional API secret
|
||||
# @return [Future<Hash>] Future resolving to response hash with update confirmation
|
||||
# @raise [CredentialsError] If no credentials found (on .value)
|
||||
# @raise [APIError] If API request fails (on .value)
|
||||
#
|
||||
# @example
|
||||
# UnAsync.set_unfreeze_on_demand(service_id, true).value
|
||||
def set_unfreeze_on_demand(service_id, enabled, public_key: nil, secret_key: nil)
|
||||
Future.new do
|
||||
pk, sk = resolve_credentials(public_key, secret_key)
|
||||
make_request_sync('PATCH', "/services/#{service_id}", pk, sk, { unfreeze_on_demand: enabled })
|
||||
end
|
||||
end
|
||||
|
||||
# Get service logs (bootstrap output)
|
||||
#
|
||||
# @param service_id [String] Service ID to get logs for
|
||||
|
|
|
|||
|
|
@ -894,6 +894,7 @@ module Un
|
|||
# @param vcpu [Integer] Number of vCPUs (1-8)
|
||||
# @param custom_domains [Array<String>, nil] Custom domains for the service
|
||||
# @param service_type [String, nil] Service type for SRV records (e.g., "minecraft")
|
||||
# @param unfreeze_on_demand [Boolean] If true, service will auto-wake on HTTP request (default: false)
|
||||
# @return [Hash] Response hash with service_id
|
||||
# @raise [CredentialsError] If no credentials found
|
||||
# @raise [APIError] If API request fails
|
||||
|
|
@ -901,7 +902,7 @@ module Un
|
|||
# @example
|
||||
# result = Un.create_service("web", [80, 443], "apt install -y nginx && nginx")
|
||||
# puts result["service_id"]
|
||||
def create_service(name, ports, bootstrap, public_key: nil, secret_key: nil, network_mode: 'semitrusted', vcpu: 1, custom_domains: nil, service_type: nil)
|
||||
def create_service(name, ports, bootstrap, public_key: nil, secret_key: nil, network_mode: 'semitrusted', vcpu: 1, custom_domains: nil, service_type: nil, unfreeze_on_demand: false)
|
||||
pk, sk = resolve_credentials(public_key, secret_key)
|
||||
data = {
|
||||
name: name,
|
||||
|
|
@ -912,6 +913,7 @@ module Un
|
|||
data[:vcpu] = vcpu if vcpu > 1
|
||||
data[:custom_domains] = custom_domains if custom_domains
|
||||
data[:service_type] = service_type if service_type
|
||||
data[:unfreeze_on_demand] = unfreeze_on_demand if unfreeze_on_demand
|
||||
make_request('POST', '/services', pk, sk, data)
|
||||
end
|
||||
|
||||
|
|
@ -1033,6 +1035,25 @@ module Un
|
|||
make_request('POST', "/services/#{service_id}/unlock", pk, sk, {})
|
||||
end
|
||||
|
||||
# Set unfreeze-on-demand for a service
|
||||
#
|
||||
# When enabled, a frozen service will automatically wake when it receives an HTTP request.
|
||||
#
|
||||
# @param service_id [String] Service ID to update
|
||||
# @param enabled [Boolean] Whether to enable unfreeze-on-demand
|
||||
# @param public_key [String, nil] Optional API key
|
||||
# @param secret_key [String, nil] Optional API secret
|
||||
# @return [Hash] Response hash with update confirmation
|
||||
# @raise [CredentialsError] If no credentials found
|
||||
# @raise [APIError] If API request fails
|
||||
#
|
||||
# @example
|
||||
# Un.set_unfreeze_on_demand(service_id, true)
|
||||
def set_unfreeze_on_demand(service_id, enabled, public_key: nil, secret_key: nil)
|
||||
pk, sk = resolve_credentials(public_key, secret_key)
|
||||
make_request('PATCH', "/services/#{service_id}", pk, sk, { unfreeze_on_demand: enabled })
|
||||
end
|
||||
|
||||
# Get service logs (bootstrap output)
|
||||
#
|
||||
# @param service_id [String] Service ID to get logs for
|
||||
|
|
|
|||
|
|
@ -316,6 +316,9 @@ pub struct Service {
|
|||
/// Whether the service is locked (cannot be modified)
|
||||
#[serde(default)]
|
||||
pub locked: bool,
|
||||
/// Whether the service automatically unfreezes on incoming HTTP requests
|
||||
#[serde(default)]
|
||||
pub unfreeze_on_demand: bool,
|
||||
/// Public URL for the service
|
||||
#[serde(default)]
|
||||
pub url: String,
|
||||
|
|
@ -382,6 +385,8 @@ pub struct ServiceCreateOptions {
|
|||
pub bootstrap: Option<String>,
|
||||
/// Bootstrap script URL
|
||||
pub bootstrap_url: Option<String>,
|
||||
/// Whether to enable automatic unfreezing on incoming HTTP requests
|
||||
pub unfreeze_on_demand: Option<bool>,
|
||||
}
|
||||
|
||||
/// Options for updating a service
|
||||
|
|
@ -1500,6 +1505,9 @@ pub async fn create_service(
|
|||
if let Some(bootstrap_url) = opts.bootstrap_url {
|
||||
body["bootstrap_url"] = serde_json::json!(bootstrap_url);
|
||||
}
|
||||
if let Some(unfreeze_on_demand) = opts.unfreeze_on_demand {
|
||||
body["unfreeze_on_demand"] = serde_json::json!(unfreeze_on_demand);
|
||||
}
|
||||
}
|
||||
|
||||
make_request("POST", "/services", creds, Some(&body)).await
|
||||
|
|
@ -1618,6 +1626,26 @@ pub async fn unlock_service(service_id: &str, creds: &Credentials) -> Result<Ser
|
|||
make_request("POST", &path, creds, Some(&body)).await
|
||||
}
|
||||
|
||||
/// Set the unfreeze_on_demand flag for a service.
|
||||
///
|
||||
/// When enabled, the service will automatically unfreeze when it receives
|
||||
/// an incoming HTTP request while frozen.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `service_id` - Service ID to update
|
||||
/// * `enabled` - Whether to enable automatic unfreezing on demand
|
||||
/// * `creds` - API credentials
|
||||
///
|
||||
/// # Returns
|
||||
/// Updated Service information
|
||||
pub async fn set_unfreeze_on_demand(service_id: &str, enabled: bool, creds: &Credentials) -> Result<Service> {
|
||||
let path = format!("/services/{}", service_id);
|
||||
let body = serde_json::json!({
|
||||
"unfreeze_on_demand": enabled
|
||||
});
|
||||
make_request("PATCH", &path, creds, Some(&body)).await
|
||||
}
|
||||
|
||||
/// Get bootstrap logs for a service.
|
||||
///
|
||||
/// # Arguments
|
||||
|
|
|
|||
|
|
@ -311,6 +311,9 @@ pub struct Service {
|
|||
/// Whether the service is locked (cannot be modified)
|
||||
#[serde(default)]
|
||||
pub locked: bool,
|
||||
/// Whether the service automatically unfreezes on incoming HTTP requests
|
||||
#[serde(default)]
|
||||
pub unfreeze_on_demand: bool,
|
||||
/// Public URL for the service
|
||||
#[serde(default)]
|
||||
pub url: String,
|
||||
|
|
@ -377,6 +380,8 @@ pub struct ServiceCreateOptions {
|
|||
pub bootstrap: Option<String>,
|
||||
/// Bootstrap script URL
|
||||
pub bootstrap_url: Option<String>,
|
||||
/// Whether to enable automatic unfreezing on incoming HTTP requests
|
||||
pub unfreeze_on_demand: Option<bool>,
|
||||
}
|
||||
|
||||
/// Options for updating a service
|
||||
|
|
@ -1807,6 +1812,9 @@ pub fn create_service(
|
|||
if let Some(bootstrap_url) = opts.bootstrap_url {
|
||||
body["bootstrap_url"] = serde_json::json!(bootstrap_url);
|
||||
}
|
||||
if let Some(unfreeze_on_demand) = opts.unfreeze_on_demand {
|
||||
body["unfreeze_on_demand"] = serde_json::json!(unfreeze_on_demand);
|
||||
}
|
||||
}
|
||||
|
||||
make_request("POST", "/services", creds, Some(&body))
|
||||
|
|
@ -1925,6 +1933,26 @@ pub fn unlock_service(service_id: &str, creds: &Credentials) -> Result<Service>
|
|||
make_request("POST", &path, creds, Some(&body))
|
||||
}
|
||||
|
||||
/// Set the unfreeze_on_demand flag for a service.
|
||||
///
|
||||
/// When enabled, the service will automatically unfreeze when it receives
|
||||
/// an incoming HTTP request while frozen.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `service_id` - Service ID to update
|
||||
/// * `enabled` - Whether to enable automatic unfreezing on demand
|
||||
/// * `creds` - API credentials
|
||||
///
|
||||
/// # Returns
|
||||
/// Updated Service information
|
||||
pub fn set_unfreeze_on_demand(service_id: &str, enabled: bool, creds: &Credentials) -> Result<Service> {
|
||||
let path = format!("/services/{}", service_id);
|
||||
let body = serde_json::json!({
|
||||
"unfreeze_on_demand": enabled
|
||||
});
|
||||
make_request("PATCH", &path, creds, Some(&body))
|
||||
}
|
||||
|
||||
/// Get bootstrap logs for a service.
|
||||
///
|
||||
/// # Arguments
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ interface Args {
|
|||
visibilityMode: string | null;
|
||||
imageSpawn: string | null;
|
||||
imageClone: string | null;
|
||||
unfreezeOnDemand: boolean | null;
|
||||
setUnfreezeOnDemand: string | null;
|
||||
}
|
||||
|
||||
interface ApiKeys {
|
||||
|
|
@ -687,6 +689,14 @@ async function cmdService(args: Args): Promise<void> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (args.setUnfreezeOnDemand) {
|
||||
const enabled = args.unfreezeOnDemand === true;
|
||||
const payload = { unfreeze_on_demand: enabled };
|
||||
await apiRequest(`/services/${args.setUnfreezeOnDemand}`, "PATCH", payload, keys);
|
||||
console.log(`${GREEN}Unfreeze on demand ${enabled ? 'enabled' : 'disabled'} for service ${args.setUnfreezeOnDemand}${RESET}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.execute) {
|
||||
const payload = { command: args.command_arg };
|
||||
const result = await apiRequest(`/services/${args.execute}/execute`, "POST", payload, keys);
|
||||
|
|
@ -755,6 +765,7 @@ async function cmdService(args: Args): Promise<void> {
|
|||
}
|
||||
if (args.network) payload.network = args.network;
|
||||
if (args.vcpu) payload.vcpu = args.vcpu;
|
||||
if (args.unfreezeOnDemand) payload.unfreeze_on_demand = true;
|
||||
|
||||
const result = await apiRequest("/services", "POST", payload, keys);
|
||||
const serviceId = result.id;
|
||||
|
|
@ -1010,6 +1021,8 @@ function parseArgs(argv: string[]): Args {
|
|||
visibilityMode: null,
|
||||
imageSpawn: null,
|
||||
imageClone: null,
|
||||
unfreezeOnDemand: null,
|
||||
setUnfreezeOnDemand: null,
|
||||
};
|
||||
|
||||
let i = 2;
|
||||
|
|
@ -1170,6 +1183,12 @@ function parseArgs(argv: string[]): Args {
|
|||
args.clone = argv[++i];
|
||||
}
|
||||
i++;
|
||||
} else if (arg === '--unfreeze-on-demand') {
|
||||
args.unfreezeOnDemand = true;
|
||||
i++;
|
||||
} else if (arg === '--set-unfreeze-on-demand' && i + 1 < argv.length) {
|
||||
args.setUnfreezeOnDemand = argv[++i];
|
||||
i++;
|
||||
} else if (!arg.startsWith('-')) {
|
||||
args.sourceFile = arg;
|
||||
i++;
|
||||
|
|
@ -1251,6 +1270,8 @@ Service options:
|
|||
--command CMD Command to execute (with --execute)
|
||||
--dump-bootstrap ID Dump bootstrap script
|
||||
--dump-file FILE File to save bootstrap (with --dump-bootstrap)
|
||||
--unfreeze-on-demand Enable unfreeze on demand (with --name or --set-unfreeze-on-demand)
|
||||
--set-unfreeze-on-demand ID Set unfreeze on demand for service
|
||||
|
||||
Image options:
|
||||
--list List all images
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue