boxd 0.2.4__tar.gz → 0.2.5.dev47__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boxd-0.2.4/src/boxd.egg-info → boxd-0.2.5.dev47}/PKG-INFO +1 -1
- {boxd-0.2.4 → boxd-0.2.5.dev47}/pyproject.toml +1 -1
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/__init__.py +4 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_generated/api_pb2.py +33 -3
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_generated/api_pb2_grpc.py +313 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_mappers.py +35 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_transport.py +55 -19
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/models.py +29 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/machines.py +114 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47/src/boxd.egg-info}/PKG-INFO +1 -1
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_mappers.py +38 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_transport.py +72 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/LICENSE +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/README.md +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/setup.cfg +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_client.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_credentials.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_generated/__init__.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_requests.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_streaming.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_urls.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/_version_check.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/errors.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/__init__.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/account.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/credentials.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/disks.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/domains.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/orgs.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/snapshots.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd/resources/vars.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd.egg-info/SOURCES.txt +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd.egg-info/dependency_links.txt +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd.egg-info/requires.txt +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/src/boxd.egg-info/top_level.txt +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_credentials.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_namespaces.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_requests.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_streaming.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_urls.py +0 -0
- {boxd-0.2.4 → boxd-0.2.5.dev47}/tests/test_version_check.py +0 -0
|
@@ -33,6 +33,8 @@ from .errors import (
|
|
|
33
33
|
from .models import (
|
|
34
34
|
Account,
|
|
35
35
|
ApiKey,
|
|
36
|
+
Backup,
|
|
37
|
+
BackupSchedule,
|
|
36
38
|
Billing,
|
|
37
39
|
Checkpoint,
|
|
38
40
|
ClusterConfig,
|
|
@@ -89,6 +91,8 @@ __all__ = [
|
|
|
89
91
|
# Models
|
|
90
92
|
"Account",
|
|
91
93
|
"ApiKey",
|
|
94
|
+
"Backup",
|
|
95
|
+
"BackupSchedule",
|
|
92
96
|
"Billing",
|
|
93
97
|
"Checkpoint",
|
|
94
98
|
"ClusterConfig",
|
|
@@ -24,7 +24,7 @@ _sym_db = _symbol_database.Default()
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tapi.proto\x12\x0b\x62oxd.api.v1\"\xbf\x01\n\x08VmConfig\x12\x0c\n\x04vcpu\x18\x01 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x02 \x01(\x04\x12\x12\n\ndisk_bytes\x18\x03 \x01(\x04\x12#\n\x03srf\x18\x04 \x01(\x0b\x32\x16.boxd.api.v1.SrfConfig\x12+\n\x07network\x18\x05 \x01(\x0b\x32\x1a.boxd.api.v1.NetworkConfig\x12)\n\x07volumes\x18\x06 \x03(\x0b\x32\x18.boxd.api.v1.VolumeMount\"t\n\tSrfConfig\x12&\n\x19\x61uto_suspend_timeout_secs\x18\x01 \x01(\rH\x00\x88\x01\x01\x12!\n\x19\x61uto_destroy_timeout_secs\x18\x02 \x01(\rB\x1c\n\x1a_auto_suspend_timeout_secs\"F\n\rNetworkConfig\x12\x0b\n\x03ssh\x18\x01 \x01(\x08\x12(\n\x07proxies\x18\x02 \x03(\x0b\x32\x17.boxd.api.v1.ProxyEntry\"(\n\nProxyEntry\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\"E\n\x0bVolumeMount\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\x12\n\nmount_path\x18\x02 \x01(\t\x12\x11\n\tread_only\x18\x03 \x01(\x08\"\xed\x01\n\x0f\x43reateVmRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\timage_ref\x18\x02 \x01(\t\x12 \n\x03\x65nv\x18\x05 \x03(\x0b\x32\x13.boxd.api.v1.EnvVar\x12\x0b\n\x03\x63md\x18\x06 \x03(\t\x12\x16\n\x0erestart_policy\x18\x07 \x01(\t\x12%\n\x06\x63onfig\x18\x08 \x01(\x0b\x32\x15.boxd.api.v1.VmConfig\x12\x0b\n\x03org\x18\t \x01(\t\x12\x0e\n\x06shared\x18\n \x01(\x08\x12\x10\n\x08networks\x18\x0b \x03(\t\x12\x10\n\x08isolated\x18\x0c \x01(\x08J\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05\"$\n\x06\x45nvVar\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\x84\x01\n\x10\x43reateVmResponse\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\tpublic_ip\x18\x03 \x01(\t\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\r\n\x05image\x18\x05 \x01(\t\x12\x0e\n\x06status\x18\x06 \x01(\t\x12\x14\n\x0c\x62oot_time_ms\x18\x07 \x01(\x04\"!\n\x10\x44\x65stroyVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x13\n\x11\x44\x65stroyVmResponse\"\x16\n\x14SuggestVmNameRequest\"%\n\x15SuggestVmNameResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\"2\n\x0fRenameVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x10\n\x08new_name\x18\x02 \x01(\t\" \n\x10RenameVmResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\"7\n\x14SetVmNetworksRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x10\n\x08networks\x18\x02 \x03(\t\")\n\x15SetVmNetworksResponse\x12\x10\n\x08networks\x18\x01 \x03(\t\"U\n\x11\x45xposePortRequest\x12\x11\n\x05vm_id\x18\x01 \x01(\tB\x02\x18\x01\x12\x0f\n\x07vm_port\x18\x02 \x01(\r\x12\x10\n\x08protocol\x18\x03 \x01(\t\x12\n\n\x02vm\x18\x04 \x01(\t\"y\n\x12\x45xposePortResponse\x12\x0f\n\x07vm_name\x18\x01 \x01(\t\x12\x0b\n\x03\x64ns\x18\x02 \x01(\t\x12\x13\n\x0bpublic_port\x18\x03 \x01(\r\x12\x0f\n\x07vm_port\x18\x04 \x01(\r\x12\x10\n\x08protocol\x18\x05 \x01(\t\x12\r\n\x05vm_id\x18\x06 \x01(\t\"E\n\x13UnexposePortRequest\x12\x11\n\x05vm_id\x18\x01 \x01(\tB\x02\x18\x01\x12\x0f\n\x07vm_port\x18\x02 \x01(\r\x12\n\n\x02vm\x18\x03 \x01(\t\"H\n\x14UnexposePortResponse\x12\x30\n\x07\x66orward\x18\x01 \x01(\x0b\x32\x1f.boxd.api.v1.ExposePortResponse\"%\n\x17ListExposedPortsRequest\x12\n\n\x02vm\x18\x01 \x01(\t\"M\n\x18ListExposedPortsResponse\x12\x31\n\x08\x66orwards\x18\x01 \x03(\x0b\x32\x1f.boxd.api.v1.ExposePortResponse\"\\\n\rSetVarRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\t\x12\r\n\x05scope\x18\x05 \x01(\tJ\x04\x08\x06\x10\x07\"\x1b\n\x08VarReply\x12\x0f\n\x07message\x18\x01 \x01(\t\",\n\x0fListVarsRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\"O\n\x07VarItem\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\r\n\x05scope\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\tJ\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07\"2\n\x0cVarListReply\x12\"\n\x04vars\x18\x01 \x03(\x0b\x32\x14.boxd.api.v1.VarItem\"J\n\x10RemoveVarRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\r\n\x05scope\x18\x04 \x01(\t\"L\n\x15SetSecretScopeRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04\x66rom\x18\x03 \x01(\t\x12\n\n\x02to\x18\x04 \x01(\t\"\x1f\n\x0eStartVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x11\n\x0fStartVmResponse\"\x1e\n\rStopVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x10\n\x0eStopVmResponse\" \n\x0fRebootVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x12\n\x10RebootVmResponse\"!\n\x10SuspendVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\'\n\x11SuspendVmResponse\x12\x12\n\nsuspend_us\x18\x01 \x01(\x04\" \n\x0fResumeVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"%\n\x10ResumeVmResponse\x12\x11\n\tresume_us\x18\x01 \x01(\x04\"#\n\x12HibernateVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x15\n\x13HibernateVmResponse\"\x1e\n\rWakeVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x10\n\x0eWakeVmResponse\"\x1d\n\x0cGetVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x86\x05\n\rGetVmResponse\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\timage_ref\x18\x03 \x01(\t\x12\x11\n\tpublic_ip\x18\x04 \x01(\t\x12\x0e\n\x06status\x18\x05 \x01(\t\x12\x16\n\x0erestart_policy\x18\x06 \x01(\t\x12\x12\n\ndisk_bytes\x18\x07 \x01(\x04\x12!\n\x19\x61uto_suspend_timeout_secs\x18\x08 \x01(\r\x12\x10\n\x08ssh_port\x18\t \x01(\r\x12\x0b\n\x03org\x18\n \x01(\t\x12\x13\n\x0b\x62illing_org\x18\x0b \x01(\t\x12\x15\n\raccess_domain\x18\x0c \x01(\t\x12#\n\x1b\x61uto_hibernate_timeout_secs\x18\r \x01(\r\x12\x0e\n\x06source\x18\x0e \x01(\t\x12\x0c\n\x04vcpu\x18\x0f \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x10 \x01(\x04\x12\x12\n\ncreated_at\x18\x11 \x01(\x03\x12\x18\n\x10hibernated_at_ms\x18\x12 \x01(\x03\x12!\n\x19\x61uto_destroy_timeout_secs\x18\x13 \x01(\r\x12\x14\n\x0c\x62oot_time_ms\x18\x14 \x01(\x03\x12\x19\n\x11last_connected_ms\x18\x15 \x01(\x03\x12\x0e\n\x06org_id\x18\x16 \x01(\t\x12\x16\n\x0e\x62illing_org_id\x18\x17 \x01(\t\x12*\n\x0bsource_info\x18\x18 \x01(\x0b\x32\x15.boxd.api.v1.VmSource\x12\x10\n\x08networks\x18\x19 \x03(\t\x12\x10\n\x08isolated\x18\x1a \x01(\x08\x12\x35\n\x0e\x63ustom_domains\x18\x1b \x03(\x0b\x32\x1d.boxd.api.v1.CustomDomainInfo\"C\n\x08VmSource\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\x04\x12\n\n\x02id\x18\x04 \x01(\t\"3\n\x0eListVmsRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x14\n\x0c\x61ll_contexts\x18\x02 \x01(\x08\"P\n\x0fListVmsResponse\x12\'\n\x03vms\x18\x01 \x03(\x0b\x32\x1a.boxd.api.v1.GetVmResponse\x12\x14\n\x0cssh_host_key\x18\x02 \x01(\t\"2\n\x11StreamLogsRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0e\n\x06\x66ollow\x18\x02 \x01(\x08\"\x18\n\x08LogChunk\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"\xc1\x01\n\tExecChunk\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\r\n\x05stdin\x18\x02 \x01(\x08\x12\x0b\n\x03tty\x18\x03 \x01(\x08\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\t\x12\r\n\x05vm_id\x18\x05 \x01(\t\x12\x11\n\texit_code\x18\x06 \x01(\x05\x12\x0c\n\x04\x63ols\x18\x07 \x01(\r\x12\x0c\n\x04rows\x18\x08 \x01(\r\x12\x15\n\rwindow_change\x18\t \x01(\x08\x12\x11\n\tis_stderr\x18\n \x01(\x08\x12\x11\n\tdevice_id\x18\x0b \x01(\t\"$\n\x14\x43reateNetworkRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"+\n\x15\x43reateNetworkResponse\x12\x12\n\nnetwork_id\x18\x01 \x01(\t\"\x15\n\x13ListNetworksRequest\"B\n\x14ListNetworksResponse\x12*\n\x08networks\x18\x01 \x03(\x0b\x32\x18.boxd.api.v1.NetworkInfo\"A\n\x0bNetworkInfo\x12\x12\n\nnetwork_id\x18\x01 \x01(\t\x12\x0e\n\x06subnet\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\"7\n\x16\x41\x64\x64\x43ustomDomainRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\"H\n\x17\x41\x64\x64\x43ustomDomainResponse\x12-\n\x06\x64omain\x18\x01 \x01(\x0b\x32\x1d.boxd.api.v1.CustomDomainInfo\"\x1a\n\x18ListCustomDomainsRequest\"K\n\x19ListCustomDomainsResponse\x12.\n\x07\x64omains\x18\x01 \x03(\x0b\x32\x1d.boxd.api.v1.CustomDomainInfo\"+\n\x19RemoveCustomDomainRequest\x12\x0e\n\x06\x64omain\x18\x01 \x01(\t\"\x1c\n\x1aRemoveCustomDomainResponse\"f\n\x10\x43ustomDomainInfo\x12\x0e\n\x06\x64omain\x18\x01 \x01(\t\x12\r\n\x05vm_id\x18\x02 \x01(\t\x12\x0f\n\x07vm_name\x18\x03 \x01(\t\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x12\n\nlast_error\x18\x05 \x01(\t\"5\n\x13SetOrgDomainRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\"B\n\x14SetOrgDomainResponse\x12*\n\x06\x64omain\x18\x01 \x01(\x0b\x32\x1a.boxd.api.v1.OrgDomainInfo\"%\n\x13GetOrgDomainRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"B\n\x14GetOrgDomainResponse\x12*\n\x06\x64omain\x18\x01 \x01(\x0b\x32\x1a.boxd.api.v1.OrgDomainInfo\"\'\n\x15\x43learOrgDomainRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"\x18\n\x16\x43learOrgDomainResponse\"S\n\rOrgDomainInfo\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x12\n\nlast_error\x18\x04 \x01(\t\"\x12\n\x10GetConfigRequest\"8\n\x11GetConfigResponse\x12\x15\n\rdefault_image\x18\x01 \x01(\t\x12\x0c\n\x04zone\x18\x02 \x01(\t\"\x0f\n\rWhoamiRequest\"\x99\x01\n\x0eWhoamiResponse\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x1b\n\x13pubkey_fingerprints\x18\x02 \x03(\t\x12)\n\x07\x62illing\x18\x04 \x01(\x0b\x32\x18.boxd.api.v1.BillingInfo\x12\x14\n\x0c\x64isplay_name\x18\x05 \x01(\tJ\x04\x08\x03\x10\x04R\x12\x64\x65\x66\x61ult_network_id\"\xf9\x01\n\x0b\x42illingInfo\x12\x1b\n\x13subscription_status\x18\x03 \x01(\t\x12\x16\n\x0epast_due_since\x18\x06 \x01(\x03\x12\x0f\n\x07max_vms\x18\x07 \x01(\r\x12\x0c\n\x04vcpu\x18\x08 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\t \x01(\x04\x12\x19\n\x11\x62\x61lance_micro_eur\x18\n \x01(\x03\x12\x14\n\x0c\x62illing_mode\x18\x0b \x01(\tJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06R\x04tierR\x05shapeR\x12stripe_customer_idR\x16stripe_subscription_id\"\x12\n\x10ListPlansRequest\"9\n\x11ListPlansResponse\x12$\n\x05plans\x18\x01 \x03(\x0b\x32\x15.boxd.api.v1.PlanInfo\"\x85\x01\n\x08PlanInfo\x12\x13\n\x0bmonthly_eur\x18\x03 \x01(\r\x12\x12\n\nlookup_key\x18\x04 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\x12\x0c\n\x04vcpu\x18\x06 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x07 \x01(\x04J\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03R\x04tierR\x05shape\"\x13\n\x11GetBillingRequest\"?\n\x12GetBillingResponse\x12)\n\x07\x62illing\x18\x01 \x01(\x0b\x32\x18.boxd.api.v1.BillingInfo\"T\n\x1c\x43reateCheckoutSessionRequest\x12\x13\n\x0bsuccess_url\x18\x02 \x01(\t\x12\x12\n\ncancel_url\x18\x03 \x01(\tJ\x04\x08\x01\x10\x02R\x05shape\"5\n\x1d\x43reateCheckoutSessionResponse\x12\x14\n\x0c\x63heckout_url\x18\x01 \x01(\t\"7\n!CreateBillingPortalSessionRequest\x12\x12\n\nreturn_url\x18\x01 \x01(\t\"8\n\"CreateBillingPortalSessionResponse\x12\x12\n\nportal_url\x18\x01 \x01(\t\"-\n\x12\x43reateTokenRequest\x12\x17\n\x0f\x65xpires_in_secs\x18\x01 \x01(\x04\"8\n\x13\x43reateTokenResponse\x12\r\n\x05token\x18\x01 \x01(\t\x12\x12\n\nexpires_at\x18\x02 \x01(\x03\"\x13\n\x11ListTokensRequest\"<\n\x12ListTokensResponse\x12&\n\x06tokens\x18\x01 \x03(\x0b\x32\x16.boxd.api.v1.TokenInfo\"@\n\tTokenInfo\x12\x0b\n\x03jti\x18\x01 \x01(\t\x12\x12\n\ncreated_at\x18\x02 \x01(\x03\x12\x12\n\nexpires_at\x18\x03 \x01(\x03\"!\n\x12RevokeTokenRequest\x12\x0b\n\x03jti\x18\x01 \x01(\t\"\x15\n\x13RevokeTokenResponse\"E\n\x11LinkSshKeyRequest\x12\x0e\n\x06pubkey\x18\x01 \x01(\t\x12\x11\n\tdevice_id\x18\x02 \x01(\t\x12\r\n\x05label\x18\x03 \x01(\t\"\x14\n\x12LinkSshKeyResponse\"\x8e\x01\n\rForkVmRequest\x12\x14\n\x0csource_vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12%\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x15.boxd.api.v1.VmConfig\x12\x0e\n\x06shared\x18\x04 \x01(\x08\x12\x10\n\x08networks\x18\x05 \x03(\t\x12\x10\n\x08isolated\x18\x06 \x01(\x08\"\x97\x01\n\x0e\x46orkVmResponse\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\tpublic_ip\x18\x03 \x01(\t\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\r\n\x05image\x18\x05 \x01(\t\x12\x0e\n\x06status\x18\x06 \x01(\t\x12\x13\n\x0b\x66orked_from\x18\x07 \x01(\t\x12\x14\n\x0c\x62oot_time_ms\x18\x08 \x01(\x04\"5\n\x12ListProxiesRequest\x12\x13\n\x07vm_name\x18\x01 \x01(\tB\x02\x18\x01\x12\n\n\x02vm\x18\x02 \x01(\t\">\n\x13ListProxiesResponse\x12\'\n\x07proxies\x18\x01 \x03(\x0b\x32\x16.boxd.api.v1.ProxyInfo\"\xac\x01\n\tProxyInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07vm_name\x18\x02 \x01(\t\x12\x0e\n\x06\x64omain\x18\x03 \x01(\t\x12\x0c\n\x04port\x18\x04 \x01(\r\x12\x12\n\nis_default\x18\x05 \x01(\x08\x12\x14\n\x0cport_display\x18\x06 \x01(\t\x12\r\n\x05vm_id\x18\x07 \x01(\t\x12\x11\n\tport_mode\x18\x08 \x01(\t\x12\x16\n\x0e\x65\x66\x66\x65\x63tive_port\x18\t \x01(\r\"\x17\n\x15ListProxyNodesRequest\"E\n\x16ListProxyNodesResponse\x12+\n\x07proxies\x18\x01 \x03(\x0b\x32\x1a.boxd.api.v1.ProxyNodeInfo\")\n\rProxyNodeInfo\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04ipv4\x18\x02 \x01(\t\"Q\n\x12\x43reateProxyRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x07vm_name\x18\x02 \x01(\tB\x02\x18\x01\x12\x0c\n\x04port\x18\x03 \x01(\r\x12\n\n\x02vm\x18\x04 \x01(\t\"R\n\x13\x43reateProxyResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07vm_name\x18\x02 \x01(\t\x12\x0e\n\x06\x64omain\x18\x03 \x01(\t\x12\x0c\n\x04port\x18\x04 \x01(\r\"C\n\x12\x44\x65leteProxyRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x07vm_name\x18\x02 \x01(\tB\x02\x18\x01\x12\n\n\x02vm\x18\x03 \x01(\t\"\x15\n\x13\x44\x65leteProxyResponse\"R\n\x13SetProxyPortRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x07vm_name\x18\x02 \x01(\tB\x02\x18\x01\x12\x0c\n\x04port\x18\x03 \x01(\t\x12\n\n\x02vm\x18\x04 \x01(\t\"\x16\n\x14SetProxyPortResponse\">\n\x11UploadFileRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"+\n\x12UploadFileResponse\x12\x15\n\rbytes_written\x18\x01 \x01(\x04\"P\n\x0fUploadFileChunk\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x12\n\ntotal_size\x18\x03 \x01(\x04\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\"2\n\x13\x44ownloadFileRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\"$\n\x14\x44ownloadFileResponse\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"1\n\x15\x43reateSnapshotRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\\\n\x16\x43reateSnapshotResponse\x12\x13\n\x0bsnapshot_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\t\"#\n\x14ListSnapshotsRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\"E\n\x15ListSnapshotsResponse\x12,\n\tsnapshots\x18\x01 \x03(\x0b\x32\x19.boxd.api.v1.SnapshotInfo\"/\n\x12GetSnapshotRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03org\x18\x02 \x01(\t\"B\n\x13GetSnapshotResponse\x12+\n\x08snapshot\x18\x01 \x01(\x0b\x32\x19.boxd.api.v1.SnapshotInfo\"2\n\x15\x44\x65leteSnapshotRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03org\x18\x02 \x01(\t\"\x18\n\x16\x44\x65leteSnapshotResponse\"\x83\x01\n\x1b\x43reateVmFromSnapshotRequest\x12\x10\n\x08snapshot\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12%\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x15.boxd.api.v1.VmConfig\x12\x0b\n\x03org\x18\x04 \x01(\t\x12\x10\n\x08isolated\x18\x05 \x01(\x08\"\xf3\x01\n\x0cSnapshotInfo\x12\x13\n\x0bsnapshot_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x12\n\nsize_bytes\x18\x07 \x01(\x04\x12\x12\n\nupdated_at\x18\x08 \x01(\x03\x12\x0c\n\x04vcpu\x18\t \x01(\r\x12\x14\n\x0cmemory_bytes\x18\n \x01(\x04\x12\x11\n\tuse_count\x18\x0b \x01(\x04\x12\x12\n\ncreated_at\x18\x0c \x01(\x03J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07R\x0eready_replicasR\x10\x64\x65sired_replicas\"3\n\x17\x43reateCheckpointRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"O\n\x18\x43reateCheckpointResponse\x12\x15\n\rcheckpoint_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\"$\n\x16ListCheckpointsRequest\x12\n\n\x02vm\x18\x01 \x01(\t\"K\n\x17ListCheckpointsResponse\x12\x30\n\x0b\x63heckpoints\x18\x01 \x03(\x0b\x32\x1b.boxd.api.v1.CheckpointInfo\"3\n\x17\x44\x65leteCheckpointRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1a\n\x18\x44\x65leteCheckpointResponse\"4\n\x18RestoreCheckpointRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1b\n\x19RestoreCheckpointResponse\"\x94\x01\n\x0e\x43heckpointInfo\x12\x15\n\rcheckpoint_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x12\n\nsize_bytes\x18\x04 \x01(\x04\x12\x12\n\ncreated_at\x18\x05 \x01(\x03\x12\x12\n\ncreated_by\x18\x06 \x01(\t\x12\x11\n\tavailable\x18\x07 \x01(\x08\";\n\x11\x43reateDiskRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\x04J\x04\x08\x03\x10\x04\"]\n\x12\x43reateDiskResponse\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nsize_bytes\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\tJ\x04\x08\x05\x10\x06\"\x12\n\x10ListDisksRequest\"9\n\x11ListDisksResponse\x12$\n\x05\x64isks\x18\x01 \x03(\x0b\x32\x15.boxd.api.v1.DiskInfo\"\xaa\x01\n\x08\x44iskInfo\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nsize_bytes\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x30\n\x0b\x61ttachments\x18\x06 \x03(\x0b\x32\x1b.boxd.api.v1.DiskAttachment\x12\x12\n\ncreated_at\x18\x08 \x01(\x03J\x04\x08\x05\x10\x06J\x04\x08\x07\x10\x08R\tworker_id\"X\n\x0e\x44iskAttachment\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0f\n\x07vm_name\x18\x02 \x01(\t\x12\x12\n\nmount_path\x18\x03 \x01(\t\x12\x12\n\nmount_mode\x18\x04 \x01(\t\"Z\n\x11\x41ttachDiskRequest\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\r\n\x05vm_id\x18\x02 \x01(\t\x12\x12\n\nmount_path\x18\x03 \x01(\t\x12\x11\n\tread_only\x18\x04 \x01(\x08\"\x14\n\x12\x41ttachDiskResponse\"3\n\x11\x44\x65tachDiskRequest\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\r\n\x05vm_id\x18\x02 \x01(\t\"\x14\n\x12\x44\x65tachDiskResponse\"%\n\x12\x44\x65stroyDiskRequest\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\"\x15\n\x13\x44\x65stroyDiskResponse\"C\n\x1cSetAutoSuspendTimeoutRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x14\n\x0ctimeout_secs\x18\x02 \x01(\r\"\x1f\n\x1dSetAutoSuspendTimeoutResponse\"E\n\x1eSetAutoHibernateTimeoutRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x14\n\x0ctimeout_secs\x18\x02 \x01(\r\"!\n\x1fSetAutoHibernateTimeoutResponse\"W\n\x13\x43reateApiKeyRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0f\x65xpires_in_secs\x18\x02 \x01(\x04\x12\x0b\n\x03org\x18\x03 \x01(\t\x12\x0c\n\x04kind\x18\x04 \x01(\t\"G\n\x14\x43reateApiKeyResponse\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0f\n\x07\x61pi_key\x18\x02 \x01(\t\x12\x12\n\nexpires_at\x18\x03 \x01(\x03\"\x14\n\x12ListApiKeysRequest\"<\n\x13ListApiKeysResponse\x12%\n\x04keys\x18\x01 \x03(\x0b\x32\x17.boxd.api.v1.ApiKeyInfo\"\x93\x01\n\nApiKeyInfo\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nkey_prefix\x18\x03 \x01(\t\x12\x12\n\ncreated_at\x18\x04 \x01(\x03\x12\x14\n\x0clast_used_at\x18\x05 \x01(\x03\x12\x12\n\nexpires_at\x18\x06 \x01(\x03\x12\x0b\n\x03org\x18\x07 \x01(\t\x12\x0c\n\x04kind\x18\x08 \x01(\t\"!\n\x13\x44\x65leteApiKeyRequest\x12\n\n\x02id\x18\x01 \x01(\t\"\x16\n\x14\x44\x65leteApiKeyResponse\"\x1f\n\x0eShareVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x11\n\x0fShareVmResponse\"\x11\n\x0fListOrgsRequest\"W\n\x10ListOrgsResponse\x12%\n\x04orgs\x18\x01 \x03(\x0b\x32\x17.boxd.api.v1.OrgSummary\x12\x16\n\x0e\x64\x65\x66\x61ult_org_id\x18\x03 \x01(\tJ\x04\x08\x02\x10\x03\"F\n\nOrgSummary\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08is_admin\x18\x03 \x01(\x08\x12\x0c\n\x04slug\x18\x04 \x01(\t\"#\n\x14GetOrgBillingRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\"\x9a\x02\n\x15GetOrgBillingResponse\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08is_admin\x18\x03 \x01(\x08\x12\x0f\n\x07max_vms\x18\x04 \x01(\r\x12\x0c\n\x04vcpu\x18\x05 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x06 \x01(\x04\x12\x10\n\x08vm_count\x18\x07 \x01(\r\x12%\n\x03vms\x18\x08 \x03(\x0b\x32\x18.boxd.api.v1.OrgBilledVm\x12\x19\n\x11\x62\x61lance_micro_eur\x18\t \x01(\x03\x12\x14\n\x0c\x62illing_mode\x18\n \x01(\t\x12\x1f\n\x12\x61\x63\x63ruing_micro_eur\x18\x0b \x01(\x03H\x00\x88\x01\x01\x42\x15\n\x13_accruing_micro_eur\"l\n\x0bOrgBilledVm\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05owner\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x0f\n\x07\x62illing\x18\x05 \x01(\t\x12\x12\n\nowner_name\x18\x06 \x01(\tJ\x04\x08\x04\x10\x05R\x05shape\"!\n\x10UnshareVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x13\n\x11UnshareVmResponse2\xb0/\n\x07\x42oxdApi\x12G\n\x08\x43reateVm\x12\x1c.boxd.api.v1.CreateVmRequest\x1a\x1d.boxd.api.v1.CreateVmResponse\x12J\n\tDestroyVm\x12\x1d.boxd.api.v1.DestroyVmRequest\x1a\x1e.boxd.api.v1.DestroyVmResponse\x12G\n\x08RenameVm\x12\x1c.boxd.api.v1.RenameVmRequest\x1a\x1d.boxd.api.v1.RenameVmResponse\x12V\n\rSetVmNetworks\x12!.boxd.api.v1.SetVmNetworksRequest\x1a\".boxd.api.v1.SetVmNetworksResponse\x12\x44\n\x07StartVm\x12\x1b.boxd.api.v1.StartVmRequest\x1a\x1c.boxd.api.v1.StartVmResponse\x12\x41\n\x06StopVm\x12\x1a.boxd.api.v1.StopVmRequest\x1a\x1b.boxd.api.v1.StopVmResponse\x12G\n\x08RebootVm\x12\x1c.boxd.api.v1.RebootVmRequest\x1a\x1d.boxd.api.v1.RebootVmResponse\x12>\n\x05GetVm\x12\x19.boxd.api.v1.GetVmRequest\x1a\x1a.boxd.api.v1.GetVmResponse\x12\x44\n\x07ListVms\x12\x1b.boxd.api.v1.ListVmsRequest\x1a\x1c.boxd.api.v1.ListVmsResponse\x12V\n\rSuggestVmName\x12!.boxd.api.v1.SuggestVmNameRequest\x1a\".boxd.api.v1.SuggestVmNameResponse\x12M\n\nExposePort\x12\x1e.boxd.api.v1.ExposePortRequest\x1a\x1f.boxd.api.v1.ExposePortResponse\x12S\n\x0cUnexposePort\x12 .boxd.api.v1.UnexposePortRequest\x1a!.boxd.api.v1.UnexposePortResponse\x12_\n\x10ListExposedPorts\x12$.boxd.api.v1.ListExposedPortsRequest\x1a%.boxd.api.v1.ListExposedPortsResponse\x12;\n\x06SetVar\x12\x1a.boxd.api.v1.SetVarRequest\x1a\x15.boxd.api.v1.VarReply\x12\x43\n\x08ListVars\x12\x1c.boxd.api.v1.ListVarsRequest\x1a\x19.boxd.api.v1.VarListReply\x12\x41\n\tRemoveVar\x12\x1d.boxd.api.v1.RemoveVarRequest\x1a\x15.boxd.api.v1.VarReply\x12K\n\x0eSetSecretScope\x12\".boxd.api.v1.SetSecretScopeRequest\x1a\x15.boxd.api.v1.VarReply\x12\x45\n\nStreamLogs\x12\x1e.boxd.api.v1.StreamLogsRequest\x1a\x15.boxd.api.v1.LogChunk0\x01\x12:\n\x04\x45xec\x12\x16.boxd.api.v1.ExecChunk\x1a\x16.boxd.api.v1.ExecChunk(\x01\x30\x01\x12V\n\rCreateNetwork\x12!.boxd.api.v1.CreateNetworkRequest\x1a\".boxd.api.v1.CreateNetworkResponse\x12S\n\x0cListNetworks\x12 .boxd.api.v1.ListNetworksRequest\x1a!.boxd.api.v1.ListNetworksResponse\x12\\\n\x0f\x41\x64\x64\x43ustomDomain\x12#.boxd.api.v1.AddCustomDomainRequest\x1a$.boxd.api.v1.AddCustomDomainResponse\x12\x62\n\x11ListCustomDomains\x12%.boxd.api.v1.ListCustomDomainsRequest\x1a&.boxd.api.v1.ListCustomDomainsResponse\x12\x65\n\x12RemoveCustomDomain\x12&.boxd.api.v1.RemoveCustomDomainRequest\x1a\'.boxd.api.v1.RemoveCustomDomainResponse\x12S\n\x0cSetOrgDomain\x12 .boxd.api.v1.SetOrgDomainRequest\x1a!.boxd.api.v1.SetOrgDomainResponse\x12S\n\x0cGetOrgDomain\x12 .boxd.api.v1.GetOrgDomainRequest\x1a!.boxd.api.v1.GetOrgDomainResponse\x12Y\n\x0e\x43learOrgDomain\x12\".boxd.api.v1.ClearOrgDomainRequest\x1a#.boxd.api.v1.ClearOrgDomainResponse\x12\x41\n\x06Whoami\x12\x1a.boxd.api.v1.WhoamiRequest\x1a\x1b.boxd.api.v1.WhoamiResponse\x12P\n\x0b\x43reateToken\x12\x1f.boxd.api.v1.CreateTokenRequest\x1a .boxd.api.v1.CreateTokenResponse\x12M\n\nListTokens\x12\x1e.boxd.api.v1.ListTokensRequest\x1a\x1f.boxd.api.v1.ListTokensResponse\x12P\n\x0bRevokeToken\x12\x1f.boxd.api.v1.RevokeTokenRequest\x1a .boxd.api.v1.RevokeTokenResponse\x12M\n\nLinkSshKey\x12\x1e.boxd.api.v1.LinkSshKeyRequest\x1a\x1f.boxd.api.v1.LinkSshKeyResponse\x12J\n\tGetConfig\x12\x1d.boxd.api.v1.GetConfigRequest\x1a\x1e.boxd.api.v1.GetConfigResponse\x12\x41\n\x06\x46orkVm\x12\x1a.boxd.api.v1.ForkVmRequest\x1a\x1b.boxd.api.v1.ForkVmResponse\x12P\n\x0bListProxies\x12\x1f.boxd.api.v1.ListProxiesRequest\x1a .boxd.api.v1.ListProxiesResponse\x12Y\n\x0eListProxyNodes\x12\".boxd.api.v1.ListProxyNodesRequest\x1a#.boxd.api.v1.ListProxyNodesResponse\x12P\n\x0b\x43reateProxy\x12\x1f.boxd.api.v1.CreateProxyRequest\x1a .boxd.api.v1.CreateProxyResponse\x12P\n\x0b\x44\x65leteProxy\x12\x1f.boxd.api.v1.DeleteProxyRequest\x1a .boxd.api.v1.DeleteProxyResponse\x12S\n\x0cSetProxyPort\x12 .boxd.api.v1.SetProxyPortRequest\x1a!.boxd.api.v1.SetProxyPortResponse\x12M\n\nUploadFile\x12\x1e.boxd.api.v1.UploadFileRequest\x1a\x1f.boxd.api.v1.UploadFileResponse\x12S\n\x10UploadFileStream\x12\x1c.boxd.api.v1.UploadFileChunk\x1a\x1f.boxd.api.v1.UploadFileResponse(\x01\x12S\n\x0c\x44ownloadFile\x12 .boxd.api.v1.DownloadFileRequest\x1a!.boxd.api.v1.DownloadFileResponse\x12J\n\tSuspendVm\x12\x1d.boxd.api.v1.SuspendVmRequest\x1a\x1e.boxd.api.v1.SuspendVmResponse\x12G\n\x08ResumeVm\x12\x1c.boxd.api.v1.ResumeVmRequest\x1a\x1d.boxd.api.v1.ResumeVmResponse\x12P\n\x0bHibernateVm\x12\x1f.boxd.api.v1.HibernateVmRequest\x1a .boxd.api.v1.HibernateVmResponse\x12\x41\n\x06WakeVm\x12\x1a.boxd.api.v1.WakeVmRequest\x1a\x1b.boxd.api.v1.WakeVmResponse\x12Y\n\x0e\x43reateSnapshot\x12\".boxd.api.v1.CreateSnapshotRequest\x1a#.boxd.api.v1.CreateSnapshotResponse\x12V\n\rListSnapshots\x12!.boxd.api.v1.ListSnapshotsRequest\x1a\".boxd.api.v1.ListSnapshotsResponse\x12P\n\x0bGetSnapshot\x12\x1f.boxd.api.v1.GetSnapshotRequest\x1a .boxd.api.v1.GetSnapshotResponse\x12Y\n\x0e\x44\x65leteSnapshot\x12\".boxd.api.v1.DeleteSnapshotRequest\x1a#.boxd.api.v1.DeleteSnapshotResponse\x12_\n\x14\x43reateVmFromSnapshot\x12(.boxd.api.v1.CreateVmFromSnapshotRequest\x1a\x1d.boxd.api.v1.CreateVmResponse\x12_\n\x10\x43reateCheckpoint\x12$.boxd.api.v1.CreateCheckpointRequest\x1a%.boxd.api.v1.CreateCheckpointResponse\x12\\\n\x0fListCheckpoints\x12#.boxd.api.v1.ListCheckpointsRequest\x1a$.boxd.api.v1.ListCheckpointsResponse\x12_\n\x10\x44\x65leteCheckpoint\x12$.boxd.api.v1.DeleteCheckpointRequest\x1a%.boxd.api.v1.DeleteCheckpointResponse\x12\x62\n\x11RestoreCheckpoint\x12%.boxd.api.v1.RestoreCheckpointRequest\x1a&.boxd.api.v1.RestoreCheckpointResponse\x12n\n\x15SetAutoSuspendTimeout\x12).boxd.api.v1.SetAutoSuspendTimeoutRequest\x1a*.boxd.api.v1.SetAutoSuspendTimeoutResponse\x12t\n\x17SetAutoHibernateTimeout\x12+.boxd.api.v1.SetAutoHibernateTimeoutRequest\x1a,.boxd.api.v1.SetAutoHibernateTimeoutResponse\x12M\n\nCreateDisk\x12\x1e.boxd.api.v1.CreateDiskRequest\x1a\x1f.boxd.api.v1.CreateDiskResponse\x12J\n\tListDisks\x12\x1d.boxd.api.v1.ListDisksRequest\x1a\x1e.boxd.api.v1.ListDisksResponse\x12M\n\nAttachDisk\x12\x1e.boxd.api.v1.AttachDiskRequest\x1a\x1f.boxd.api.v1.AttachDiskResponse\x12M\n\nDetachDisk\x12\x1e.boxd.api.v1.DetachDiskRequest\x1a\x1f.boxd.api.v1.DetachDiskResponse\x12P\n\x0b\x44\x65stroyDisk\x12\x1f.boxd.api.v1.DestroyDiskRequest\x1a .boxd.api.v1.DestroyDiskResponse\x12S\n\x0c\x43reateApiKey\x12 .boxd.api.v1.CreateApiKeyRequest\x1a!.boxd.api.v1.CreateApiKeyResponse\x12P\n\x0bListApiKeys\x12\x1f.boxd.api.v1.ListApiKeysRequest\x1a .boxd.api.v1.ListApiKeysResponse\x12S\n\x0c\x44\x65leteApiKey\x12 .boxd.api.v1.DeleteApiKeyRequest\x1a!.boxd.api.v1.DeleteApiKeyResponse\x12J\n\tListPlans\x12\x1d.boxd.api.v1.ListPlansRequest\x1a\x1e.boxd.api.v1.ListPlansResponse\x12M\n\nGetBilling\x12\x1e.boxd.api.v1.GetBillingRequest\x1a\x1f.boxd.api.v1.GetBillingResponse\x12n\n\x15\x43reateCheckoutSession\x12).boxd.api.v1.CreateCheckoutSessionRequest\x1a*.boxd.api.v1.CreateCheckoutSessionResponse\x12}\n\x1a\x43reateBillingPortalSession\x12..boxd.api.v1.CreateBillingPortalSessionRequest\x1a/.boxd.api.v1.CreateBillingPortalSessionResponse\x12\x44\n\x07ShareVm\x12\x1b.boxd.api.v1.ShareVmRequest\x1a\x1c.boxd.api.v1.ShareVmResponse\x12J\n\tUnshareVm\x12\x1d.boxd.api.v1.UnshareVmRequest\x1a\x1e.boxd.api.v1.UnshareVmResponse\x12G\n\x08ListOrgs\x12\x1c.boxd.api.v1.ListOrgsRequest\x1a\x1d.boxd.api.v1.ListOrgsResponse\x12V\n\rGetOrgBilling\x12!.boxd.api.v1.GetOrgBillingRequest\x1a\".boxd.api.v1.GetOrgBillingResponseb\x06proto3')
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tapi.proto\x12\x0b\x62oxd.api.v1\"\xbf\x01\n\x08VmConfig\x12\x0c\n\x04vcpu\x18\x01 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x02 \x01(\x04\x12\x12\n\ndisk_bytes\x18\x03 \x01(\x04\x12#\n\x03srf\x18\x04 \x01(\x0b\x32\x16.boxd.api.v1.SrfConfig\x12+\n\x07network\x18\x05 \x01(\x0b\x32\x1a.boxd.api.v1.NetworkConfig\x12)\n\x07volumes\x18\x06 \x03(\x0b\x32\x18.boxd.api.v1.VolumeMount\"t\n\tSrfConfig\x12&\n\x19\x61uto_suspend_timeout_secs\x18\x01 \x01(\rH\x00\x88\x01\x01\x12!\n\x19\x61uto_destroy_timeout_secs\x18\x02 \x01(\rB\x1c\n\x1a_auto_suspend_timeout_secs\"F\n\rNetworkConfig\x12\x0b\n\x03ssh\x18\x01 \x01(\x08\x12(\n\x07proxies\x18\x02 \x03(\x0b\x32\x17.boxd.api.v1.ProxyEntry\"(\n\nProxyEntry\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\"E\n\x0bVolumeMount\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\x12\n\nmount_path\x18\x02 \x01(\t\x12\x11\n\tread_only\x18\x03 \x01(\x08\"\xed\x01\n\x0f\x43reateVmRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\timage_ref\x18\x02 \x01(\t\x12 \n\x03\x65nv\x18\x05 \x03(\x0b\x32\x13.boxd.api.v1.EnvVar\x12\x0b\n\x03\x63md\x18\x06 \x03(\t\x12\x16\n\x0erestart_policy\x18\x07 \x01(\t\x12%\n\x06\x63onfig\x18\x08 \x01(\x0b\x32\x15.boxd.api.v1.VmConfig\x12\x0b\n\x03org\x18\t \x01(\t\x12\x0e\n\x06shared\x18\n \x01(\x08\x12\x10\n\x08networks\x18\x0b \x03(\t\x12\x10\n\x08isolated\x18\x0c \x01(\x08J\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05\"$\n\x06\x45nvVar\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\x84\x01\n\x10\x43reateVmResponse\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\tpublic_ip\x18\x03 \x01(\t\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\r\n\x05image\x18\x05 \x01(\t\x12\x0e\n\x06status\x18\x06 \x01(\t\x12\x14\n\x0c\x62oot_time_ms\x18\x07 \x01(\x04\"!\n\x10\x44\x65stroyVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x13\n\x11\x44\x65stroyVmResponse\"\x16\n\x14SuggestVmNameRequest\"%\n\x15SuggestVmNameResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\"2\n\x0fRenameVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x10\n\x08new_name\x18\x02 \x01(\t\" \n\x10RenameVmResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\"7\n\x14SetVmNetworksRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x10\n\x08networks\x18\x02 \x03(\t\")\n\x15SetVmNetworksResponse\x12\x10\n\x08networks\x18\x01 \x03(\t\"U\n\x11\x45xposePortRequest\x12\x11\n\x05vm_id\x18\x01 \x01(\tB\x02\x18\x01\x12\x0f\n\x07vm_port\x18\x02 \x01(\r\x12\x10\n\x08protocol\x18\x03 \x01(\t\x12\n\n\x02vm\x18\x04 \x01(\t\"y\n\x12\x45xposePortResponse\x12\x0f\n\x07vm_name\x18\x01 \x01(\t\x12\x0b\n\x03\x64ns\x18\x02 \x01(\t\x12\x13\n\x0bpublic_port\x18\x03 \x01(\r\x12\x0f\n\x07vm_port\x18\x04 \x01(\r\x12\x10\n\x08protocol\x18\x05 \x01(\t\x12\r\n\x05vm_id\x18\x06 \x01(\t\"E\n\x13UnexposePortRequest\x12\x11\n\x05vm_id\x18\x01 \x01(\tB\x02\x18\x01\x12\x0f\n\x07vm_port\x18\x02 \x01(\r\x12\n\n\x02vm\x18\x03 \x01(\t\"H\n\x14UnexposePortResponse\x12\x30\n\x07\x66orward\x18\x01 \x01(\x0b\x32\x1f.boxd.api.v1.ExposePortResponse\"%\n\x17ListExposedPortsRequest\x12\n\n\x02vm\x18\x01 \x01(\t\"M\n\x18ListExposedPortsResponse\x12\x31\n\x08\x66orwards\x18\x01 \x03(\x0b\x32\x1f.boxd.api.v1.ExposePortResponse\"\\\n\rSetVarRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\t\x12\r\n\x05scope\x18\x05 \x01(\tJ\x04\x08\x06\x10\x07\"\x1b\n\x08VarReply\x12\x0f\n\x07message\x18\x01 \x01(\t\",\n\x0fListVarsRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\"O\n\x07VarItem\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\r\n\x05scope\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\tJ\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07\"2\n\x0cVarListReply\x12\"\n\x04vars\x18\x01 \x03(\x0b\x32\x14.boxd.api.v1.VarItem\"J\n\x10RemoveVarRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\r\n\x05scope\x18\x04 \x01(\t\"L\n\x15SetSecretScopeRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04\x66rom\x18\x03 \x01(\t\x12\n\n\x02to\x18\x04 \x01(\t\"\x1f\n\x0eStartVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x11\n\x0fStartVmResponse\"\x1e\n\rStopVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x10\n\x0eStopVmResponse\" \n\x0fRebootVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x12\n\x10RebootVmResponse\"!\n\x10SuspendVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\'\n\x11SuspendVmResponse\x12\x12\n\nsuspend_us\x18\x01 \x01(\x04\" \n\x0fResumeVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"%\n\x10ResumeVmResponse\x12\x11\n\tresume_us\x18\x01 \x01(\x04\"#\n\x12HibernateVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x15\n\x13HibernateVmResponse\"\x1e\n\rWakeVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x10\n\x0eWakeVmResponse\"\x1d\n\x0cGetVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x86\x05\n\rGetVmResponse\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\timage_ref\x18\x03 \x01(\t\x12\x11\n\tpublic_ip\x18\x04 \x01(\t\x12\x0e\n\x06status\x18\x05 \x01(\t\x12\x16\n\x0erestart_policy\x18\x06 \x01(\t\x12\x12\n\ndisk_bytes\x18\x07 \x01(\x04\x12!\n\x19\x61uto_suspend_timeout_secs\x18\x08 \x01(\r\x12\x10\n\x08ssh_port\x18\t \x01(\r\x12\x0b\n\x03org\x18\n \x01(\t\x12\x13\n\x0b\x62illing_org\x18\x0b \x01(\t\x12\x15\n\raccess_domain\x18\x0c \x01(\t\x12#\n\x1b\x61uto_hibernate_timeout_secs\x18\r \x01(\r\x12\x0e\n\x06source\x18\x0e \x01(\t\x12\x0c\n\x04vcpu\x18\x0f \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x10 \x01(\x04\x12\x12\n\ncreated_at\x18\x11 \x01(\x03\x12\x18\n\x10hibernated_at_ms\x18\x12 \x01(\x03\x12!\n\x19\x61uto_destroy_timeout_secs\x18\x13 \x01(\r\x12\x14\n\x0c\x62oot_time_ms\x18\x14 \x01(\x03\x12\x19\n\x11last_connected_ms\x18\x15 \x01(\x03\x12\x0e\n\x06org_id\x18\x16 \x01(\t\x12\x16\n\x0e\x62illing_org_id\x18\x17 \x01(\t\x12*\n\x0bsource_info\x18\x18 \x01(\x0b\x32\x15.boxd.api.v1.VmSource\x12\x10\n\x08networks\x18\x19 \x03(\t\x12\x10\n\x08isolated\x18\x1a \x01(\x08\x12\x35\n\x0e\x63ustom_domains\x18\x1b \x03(\x0b\x32\x1d.boxd.api.v1.CustomDomainInfo\"C\n\x08VmSource\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\x04\x12\n\n\x02id\x18\x04 \x01(\t\"3\n\x0eListVmsRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x14\n\x0c\x61ll_contexts\x18\x02 \x01(\x08\"P\n\x0fListVmsResponse\x12\'\n\x03vms\x18\x01 \x03(\x0b\x32\x1a.boxd.api.v1.GetVmResponse\x12\x14\n\x0cssh_host_key\x18\x02 \x01(\t\"2\n\x11StreamLogsRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0e\n\x06\x66ollow\x18\x02 \x01(\x08\"\x18\n\x08LogChunk\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"\xc1\x01\n\tExecChunk\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\r\n\x05stdin\x18\x02 \x01(\x08\x12\x0b\n\x03tty\x18\x03 \x01(\x08\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\t\x12\r\n\x05vm_id\x18\x05 \x01(\t\x12\x11\n\texit_code\x18\x06 \x01(\x05\x12\x0c\n\x04\x63ols\x18\x07 \x01(\r\x12\x0c\n\x04rows\x18\x08 \x01(\r\x12\x15\n\rwindow_change\x18\t \x01(\x08\x12\x11\n\tis_stderr\x18\n \x01(\x08\x12\x11\n\tdevice_id\x18\x0b \x01(\t\"$\n\x14\x43reateNetworkRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"+\n\x15\x43reateNetworkResponse\x12\x12\n\nnetwork_id\x18\x01 \x01(\t\"\x15\n\x13ListNetworksRequest\"B\n\x14ListNetworksResponse\x12*\n\x08networks\x18\x01 \x03(\x0b\x32\x18.boxd.api.v1.NetworkInfo\"A\n\x0bNetworkInfo\x12\x12\n\nnetwork_id\x18\x01 \x01(\t\x12\x0e\n\x06subnet\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\"7\n\x16\x41\x64\x64\x43ustomDomainRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\"H\n\x17\x41\x64\x64\x43ustomDomainResponse\x12-\n\x06\x64omain\x18\x01 \x01(\x0b\x32\x1d.boxd.api.v1.CustomDomainInfo\"\x1a\n\x18ListCustomDomainsRequest\"K\n\x19ListCustomDomainsResponse\x12.\n\x07\x64omains\x18\x01 \x03(\x0b\x32\x1d.boxd.api.v1.CustomDomainInfo\"+\n\x19RemoveCustomDomainRequest\x12\x0e\n\x06\x64omain\x18\x01 \x01(\t\"\x1c\n\x1aRemoveCustomDomainResponse\"f\n\x10\x43ustomDomainInfo\x12\x0e\n\x06\x64omain\x18\x01 \x01(\t\x12\r\n\x05vm_id\x18\x02 \x01(\t\x12\x0f\n\x07vm_name\x18\x03 \x01(\t\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x12\n\nlast_error\x18\x05 \x01(\t\"5\n\x13SetOrgDomainRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\"B\n\x14SetOrgDomainResponse\x12*\n\x06\x64omain\x18\x01 \x01(\x0b\x32\x1a.boxd.api.v1.OrgDomainInfo\"%\n\x13GetOrgDomainRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"B\n\x14GetOrgDomainResponse\x12*\n\x06\x64omain\x18\x01 \x01(\x0b\x32\x1a.boxd.api.v1.OrgDomainInfo\"\'\n\x15\x43learOrgDomainRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"\x18\n\x16\x43learOrgDomainResponse\"S\n\rOrgDomainInfo\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x12\n\nlast_error\x18\x04 \x01(\t\"\x12\n\x10GetConfigRequest\"8\n\x11GetConfigResponse\x12\x15\n\rdefault_image\x18\x01 \x01(\t\x12\x0c\n\x04zone\x18\x02 \x01(\t\"\x0f\n\rWhoamiRequest\"\x99\x01\n\x0eWhoamiResponse\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x1b\n\x13pubkey_fingerprints\x18\x02 \x03(\t\x12)\n\x07\x62illing\x18\x04 \x01(\x0b\x32\x18.boxd.api.v1.BillingInfo\x12\x14\n\x0c\x64isplay_name\x18\x05 \x01(\tJ\x04\x08\x03\x10\x04R\x12\x64\x65\x66\x61ult_network_id\"\xf9\x01\n\x0b\x42illingInfo\x12\x1b\n\x13subscription_status\x18\x03 \x01(\t\x12\x16\n\x0epast_due_since\x18\x06 \x01(\x03\x12\x0f\n\x07max_vms\x18\x07 \x01(\r\x12\x0c\n\x04vcpu\x18\x08 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\t \x01(\x04\x12\x19\n\x11\x62\x61lance_micro_eur\x18\n \x01(\x03\x12\x14\n\x0c\x62illing_mode\x18\x0b \x01(\tJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06R\x04tierR\x05shapeR\x12stripe_customer_idR\x16stripe_subscription_id\"\x12\n\x10ListPlansRequest\"9\n\x11ListPlansResponse\x12$\n\x05plans\x18\x01 \x03(\x0b\x32\x15.boxd.api.v1.PlanInfo\"\x85\x01\n\x08PlanInfo\x12\x13\n\x0bmonthly_eur\x18\x03 \x01(\r\x12\x12\n\nlookup_key\x18\x04 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\x12\x0c\n\x04vcpu\x18\x06 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x07 \x01(\x04J\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03R\x04tierR\x05shape\"\x13\n\x11GetBillingRequest\"?\n\x12GetBillingResponse\x12)\n\x07\x62illing\x18\x01 \x01(\x0b\x32\x18.boxd.api.v1.BillingInfo\"T\n\x1c\x43reateCheckoutSessionRequest\x12\x13\n\x0bsuccess_url\x18\x02 \x01(\t\x12\x12\n\ncancel_url\x18\x03 \x01(\tJ\x04\x08\x01\x10\x02R\x05shape\"5\n\x1d\x43reateCheckoutSessionResponse\x12\x14\n\x0c\x63heckout_url\x18\x01 \x01(\t\"7\n!CreateBillingPortalSessionRequest\x12\x12\n\nreturn_url\x18\x01 \x01(\t\"8\n\"CreateBillingPortalSessionResponse\x12\x12\n\nportal_url\x18\x01 \x01(\t\"-\n\x12\x43reateTokenRequest\x12\x17\n\x0f\x65xpires_in_secs\x18\x01 \x01(\x04\"8\n\x13\x43reateTokenResponse\x12\r\n\x05token\x18\x01 \x01(\t\x12\x12\n\nexpires_at\x18\x02 \x01(\x03\"\x13\n\x11ListTokensRequest\"<\n\x12ListTokensResponse\x12&\n\x06tokens\x18\x01 \x03(\x0b\x32\x16.boxd.api.v1.TokenInfo\"@\n\tTokenInfo\x12\x0b\n\x03jti\x18\x01 \x01(\t\x12\x12\n\ncreated_at\x18\x02 \x01(\x03\x12\x12\n\nexpires_at\x18\x03 \x01(\x03\"!\n\x12RevokeTokenRequest\x12\x0b\n\x03jti\x18\x01 \x01(\t\"\x15\n\x13RevokeTokenResponse\"E\n\x11LinkSshKeyRequest\x12\x0e\n\x06pubkey\x18\x01 \x01(\t\x12\x11\n\tdevice_id\x18\x02 \x01(\t\x12\r\n\x05label\x18\x03 \x01(\t\"\x14\n\x12LinkSshKeyResponse\"\x8e\x01\n\rForkVmRequest\x12\x14\n\x0csource_vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12%\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x15.boxd.api.v1.VmConfig\x12\x0e\n\x06shared\x18\x04 \x01(\x08\x12\x10\n\x08networks\x18\x05 \x03(\t\x12\x10\n\x08isolated\x18\x06 \x01(\x08\"\x97\x01\n\x0e\x46orkVmResponse\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\tpublic_ip\x18\x03 \x01(\t\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\r\n\x05image\x18\x05 \x01(\t\x12\x0e\n\x06status\x18\x06 \x01(\t\x12\x13\n\x0b\x66orked_from\x18\x07 \x01(\t\x12\x14\n\x0c\x62oot_time_ms\x18\x08 \x01(\x04\"5\n\x12ListProxiesRequest\x12\x13\n\x07vm_name\x18\x01 \x01(\tB\x02\x18\x01\x12\n\n\x02vm\x18\x02 \x01(\t\">\n\x13ListProxiesResponse\x12\'\n\x07proxies\x18\x01 \x03(\x0b\x32\x16.boxd.api.v1.ProxyInfo\"\xac\x01\n\tProxyInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07vm_name\x18\x02 \x01(\t\x12\x0e\n\x06\x64omain\x18\x03 \x01(\t\x12\x0c\n\x04port\x18\x04 \x01(\r\x12\x12\n\nis_default\x18\x05 \x01(\x08\x12\x14\n\x0cport_display\x18\x06 \x01(\t\x12\r\n\x05vm_id\x18\x07 \x01(\t\x12\x11\n\tport_mode\x18\x08 \x01(\t\x12\x16\n\x0e\x65\x66\x66\x65\x63tive_port\x18\t \x01(\r\"\x17\n\x15ListProxyNodesRequest\"E\n\x16ListProxyNodesResponse\x12+\n\x07proxies\x18\x01 \x03(\x0b\x32\x1a.boxd.api.v1.ProxyNodeInfo\")\n\rProxyNodeInfo\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04ipv4\x18\x02 \x01(\t\"Q\n\x12\x43reateProxyRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x07vm_name\x18\x02 \x01(\tB\x02\x18\x01\x12\x0c\n\x04port\x18\x03 \x01(\r\x12\n\n\x02vm\x18\x04 \x01(\t\"R\n\x13\x43reateProxyResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07vm_name\x18\x02 \x01(\t\x12\x0e\n\x06\x64omain\x18\x03 \x01(\t\x12\x0c\n\x04port\x18\x04 \x01(\r\"C\n\x12\x44\x65leteProxyRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x07vm_name\x18\x02 \x01(\tB\x02\x18\x01\x12\n\n\x02vm\x18\x03 \x01(\t\"\x15\n\x13\x44\x65leteProxyResponse\"R\n\x13SetProxyPortRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x07vm_name\x18\x02 \x01(\tB\x02\x18\x01\x12\x0c\n\x04port\x18\x03 \x01(\t\x12\n\n\x02vm\x18\x04 \x01(\t\"\x16\n\x14SetProxyPortResponse\">\n\x11UploadFileRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"+\n\x12UploadFileResponse\x12\x15\n\rbytes_written\x18\x01 \x01(\x04\"P\n\x0fUploadFileChunk\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x12\n\ntotal_size\x18\x03 \x01(\x04\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\"2\n\x13\x44ownloadFileRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\"$\n\x14\x44ownloadFileResponse\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"1\n\x15\x43reateSnapshotRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\\\n\x16\x43reateSnapshotResponse\x12\x13\n\x0bsnapshot_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\t\"#\n\x14ListSnapshotsRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\"E\n\x15ListSnapshotsResponse\x12,\n\tsnapshots\x18\x01 \x03(\x0b\x32\x19.boxd.api.v1.SnapshotInfo\"/\n\x12GetSnapshotRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03org\x18\x02 \x01(\t\"B\n\x13GetSnapshotResponse\x12+\n\x08snapshot\x18\x01 \x01(\x0b\x32\x19.boxd.api.v1.SnapshotInfo\"2\n\x15\x44\x65leteSnapshotRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03org\x18\x02 \x01(\t\"\x18\n\x16\x44\x65leteSnapshotResponse\"\x83\x01\n\x1b\x43reateVmFromSnapshotRequest\x12\x10\n\x08snapshot\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12%\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x15.boxd.api.v1.VmConfig\x12\x0b\n\x03org\x18\x04 \x01(\t\x12\x10\n\x08isolated\x18\x05 \x01(\x08\"\xf3\x01\n\x0cSnapshotInfo\x12\x13\n\x0bsnapshot_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x12\n\nsize_bytes\x18\x07 \x01(\x04\x12\x12\n\nupdated_at\x18\x08 \x01(\x03\x12\x0c\n\x04vcpu\x18\t \x01(\r\x12\x14\n\x0cmemory_bytes\x18\n \x01(\x04\x12\x11\n\tuse_count\x18\x0b \x01(\x04\x12\x12\n\ncreated_at\x18\x0c \x01(\x03J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07R\x0eready_replicasR\x10\x64\x65sired_replicas\"3\n\x17\x43reateCheckpointRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"O\n\x18\x43reateCheckpointResponse\x12\x15\n\rcheckpoint_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\"$\n\x16ListCheckpointsRequest\x12\n\n\x02vm\x18\x01 \x01(\t\"K\n\x17ListCheckpointsResponse\x12\x30\n\x0b\x63heckpoints\x18\x01 \x03(\x0b\x32\x1b.boxd.api.v1.CheckpointInfo\"3\n\x17\x44\x65leteCheckpointRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1a\n\x18\x44\x65leteCheckpointResponse\"4\n\x18RestoreCheckpointRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1b\n\x19RestoreCheckpointResponse\"\x94\x01\n\x0e\x43heckpointInfo\x12\x15\n\rcheckpoint_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x12\n\nsize_bytes\x18\x04 \x01(\x04\x12\x12\n\ncreated_at\x18\x05 \x01(\x03\x12\x12\n\ncreated_by\x18\x06 \x01(\t\x12\x11\n\tavailable\x18\x07 \x01(\x08\";\n\x11\x43reateDiskRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\x04J\x04\x08\x03\x10\x04\"]\n\x12\x43reateDiskResponse\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nsize_bytes\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\tJ\x04\x08\x05\x10\x06\"\x12\n\x10ListDisksRequest\"9\n\x11ListDisksResponse\x12$\n\x05\x64isks\x18\x01 \x03(\x0b\x32\x15.boxd.api.v1.DiskInfo\"\xaa\x01\n\x08\x44iskInfo\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nsize_bytes\x18\x03 \x01(\x04\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x30\n\x0b\x61ttachments\x18\x06 \x03(\x0b\x32\x1b.boxd.api.v1.DiskAttachment\x12\x12\n\ncreated_at\x18\x08 \x01(\x03J\x04\x08\x05\x10\x06J\x04\x08\x07\x10\x08R\tworker_id\"X\n\x0e\x44iskAttachment\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x0f\n\x07vm_name\x18\x02 \x01(\t\x12\x12\n\nmount_path\x18\x03 \x01(\t\x12\x12\n\nmount_mode\x18\x04 \x01(\t\"Z\n\x11\x41ttachDiskRequest\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\r\n\x05vm_id\x18\x02 \x01(\t\x12\x12\n\nmount_path\x18\x03 \x01(\t\x12\x11\n\tread_only\x18\x04 \x01(\x08\"\x14\n\x12\x41ttachDiskResponse\"3\n\x11\x44\x65tachDiskRequest\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\x12\r\n\x05vm_id\x18\x02 \x01(\t\"\x14\n\x12\x44\x65tachDiskResponse\"%\n\x12\x44\x65stroyDiskRequest\x12\x0f\n\x07\x64isk_id\x18\x01 \x01(\t\"\x15\n\x13\x44\x65stroyDiskResponse\"C\n\x1cSetAutoSuspendTimeoutRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x14\n\x0ctimeout_secs\x18\x02 \x01(\r\"\x1f\n\x1dSetAutoSuspendTimeoutResponse\"E\n\x1eSetAutoHibernateTimeoutRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\x12\x14\n\x0ctimeout_secs\x18\x02 \x01(\r\"!\n\x1fSetAutoHibernateTimeoutResponse\"W\n\x13\x43reateApiKeyRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0f\x65xpires_in_secs\x18\x02 \x01(\x04\x12\x0b\n\x03org\x18\x03 \x01(\t\x12\x0c\n\x04kind\x18\x04 \x01(\t\"G\n\x14\x43reateApiKeyResponse\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0f\n\x07\x61pi_key\x18\x02 \x01(\t\x12\x12\n\nexpires_at\x18\x03 \x01(\x03\"\x14\n\x12ListApiKeysRequest\"<\n\x13ListApiKeysResponse\x12%\n\x04keys\x18\x01 \x03(\x0b\x32\x17.boxd.api.v1.ApiKeyInfo\"\x93\x01\n\nApiKeyInfo\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nkey_prefix\x18\x03 \x01(\t\x12\x12\n\ncreated_at\x18\x04 \x01(\x03\x12\x14\n\x0clast_used_at\x18\x05 \x01(\x03\x12\x12\n\nexpires_at\x18\x06 \x01(\x03\x12\x0b\n\x03org\x18\x07 \x01(\t\x12\x0c\n\x04kind\x18\x08 \x01(\t\"!\n\x13\x44\x65leteApiKeyRequest\x12\n\n\x02id\x18\x01 \x01(\t\"\x16\n\x14\x44\x65leteApiKeyResponse\"\x1f\n\x0eShareVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x11\n\x0fShareVmResponse\"\x11\n\x0fListOrgsRequest\"W\n\x10ListOrgsResponse\x12%\n\x04orgs\x18\x01 \x03(\x0b\x32\x17.boxd.api.v1.OrgSummary\x12\x16\n\x0e\x64\x65\x66\x61ult_org_id\x18\x03 \x01(\tJ\x04\x08\x02\x10\x03\"F\n\nOrgSummary\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08is_admin\x18\x03 \x01(\x08\x12\x0c\n\x04slug\x18\x04 \x01(\t\"#\n\x14GetOrgBillingRequest\x12\x0b\n\x03org\x18\x01 \x01(\t\"\x9a\x02\n\x15GetOrgBillingResponse\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08is_admin\x18\x03 \x01(\x08\x12\x0f\n\x07max_vms\x18\x04 \x01(\r\x12\x0c\n\x04vcpu\x18\x05 \x01(\r\x12\x14\n\x0cmemory_bytes\x18\x06 \x01(\x04\x12\x10\n\x08vm_count\x18\x07 \x01(\r\x12%\n\x03vms\x18\x08 \x03(\x0b\x32\x18.boxd.api.v1.OrgBilledVm\x12\x19\n\x11\x62\x61lance_micro_eur\x18\t \x01(\x03\x12\x14\n\x0c\x62illing_mode\x18\n \x01(\t\x12\x1f\n\x12\x61\x63\x63ruing_micro_eur\x18\x0b \x01(\x03H\x00\x88\x01\x01\x42\x15\n\x13_accruing_micro_eur\"l\n\x0bOrgBilledVm\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05owner\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x0f\n\x07\x62illing\x18\x05 \x01(\t\x12\x12\n\nowner_name\x18\x06 \x01(\tJ\x04\x08\x04\x10\x05R\x05shape\"!\n\x10UnshareVmRequest\x12\r\n\x05vm_id\x18\x01 \x01(\t\"\x13\n\x11UnshareVmResponse\"m\n\x18SetBackupScheduleRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x15\n\rschedule_kind\x18\x02 \x01(\t\x12\x16\n\x0eschedule_value\x18\x03 \x01(\t\x12\x16\n\x0eretention_secs\x18\x04 \x01(\r\"\x1b\n\x19SetBackupScheduleResponse\"(\n\x1a\x43learBackupScheduleRequest\x12\n\n\x02vm\x18\x01 \x01(\t\"\x1d\n\x1b\x43learBackupScheduleResponse\"&\n\x18GetBackupScheduleRequest\x12\n\n\x02vm\x18\x01 \x01(\t\"\xa3\x01\n\x19GetBackupScheduleResponse\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x15\n\rschedule_kind\x18\x02 \x01(\t\x12\x16\n\x0eschedule_value\x18\x03 \x01(\t\x12\x16\n\x0eretention_secs\x18\x04 \x01(\r\x12\x16\n\x0enext_backup_at\x18\x05 \x01(\x03\x12\x16\n\x0elast_backup_at\x18\x06 \x01(\x03\" \n\x12ListBackupsRequest\x12\n\n\x02vm\x18\x01 \x01(\t\"\x9a\x01\n\nBackupInfo\x12\x11\n\tbackup_id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12\x12\n\nsize_bytes\x18\x03 \x01(\x04\x12\x10\n\x08\x63hecksum\x18\x04 \x01(\t\x12\x1b\n\x13points_to_backup_id\x18\x05 \x01(\t\x12\x12\n\ncreated_at\x18\x06 \x01(\x03\x12\x12\n\nexpires_at\x18\x07 \x01(\x03\"?\n\x13ListBackupsResponse\x12(\n\x07\x62\x61\x63kups\x18\x01 \x03(\x0b\x32\x17.boxd.api.v1.BackupInfo\"5\n\x14RestoreBackupRequest\x12\n\n\x02vm\x18\x01 \x01(\t\x12\x11\n\tbackup_id\x18\x02 \x01(\t\"\x17\n\x15RestoreBackupResponse\"\x87\x01\n\x1bSetOrgBackupsDefaultRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x18\n\x0bperiod_secs\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x1b\n\x0eretention_secs\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x0e\n\x0c_period_secsB\x11\n\x0f_retention_secs\"\\\n\x1cSetOrgBackupsDefaultResponse\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x13\n\x0bperiod_secs\x18\x02 \x01(\r\x12\x16\n\x0eretention_secs\x18\x03 \x01(\r\"-\n\x1bGetOrgBackupsDefaultRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"\\\n\x1cGetOrgBackupsDefaultResponse\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x13\n\x0bperiod_secs\x18\x02 \x01(\r\x12\x16\n\x0eretention_secs\x18\x03 \x01(\r2\xe6\x34\n\x07\x42oxdApi\x12G\n\x08\x43reateVm\x12\x1c.boxd.api.v1.CreateVmRequest\x1a\x1d.boxd.api.v1.CreateVmResponse\x12J\n\tDestroyVm\x12\x1d.boxd.api.v1.DestroyVmRequest\x1a\x1e.boxd.api.v1.DestroyVmResponse\x12G\n\x08RenameVm\x12\x1c.boxd.api.v1.RenameVmRequest\x1a\x1d.boxd.api.v1.RenameVmResponse\x12V\n\rSetVmNetworks\x12!.boxd.api.v1.SetVmNetworksRequest\x1a\".boxd.api.v1.SetVmNetworksResponse\x12\x44\n\x07StartVm\x12\x1b.boxd.api.v1.StartVmRequest\x1a\x1c.boxd.api.v1.StartVmResponse\x12\x41\n\x06StopVm\x12\x1a.boxd.api.v1.StopVmRequest\x1a\x1b.boxd.api.v1.StopVmResponse\x12G\n\x08RebootVm\x12\x1c.boxd.api.v1.RebootVmRequest\x1a\x1d.boxd.api.v1.RebootVmResponse\x12>\n\x05GetVm\x12\x19.boxd.api.v1.GetVmRequest\x1a\x1a.boxd.api.v1.GetVmResponse\x12\x44\n\x07ListVms\x12\x1b.boxd.api.v1.ListVmsRequest\x1a\x1c.boxd.api.v1.ListVmsResponse\x12V\n\rSuggestVmName\x12!.boxd.api.v1.SuggestVmNameRequest\x1a\".boxd.api.v1.SuggestVmNameResponse\x12M\n\nExposePort\x12\x1e.boxd.api.v1.ExposePortRequest\x1a\x1f.boxd.api.v1.ExposePortResponse\x12S\n\x0cUnexposePort\x12 .boxd.api.v1.UnexposePortRequest\x1a!.boxd.api.v1.UnexposePortResponse\x12_\n\x10ListExposedPorts\x12$.boxd.api.v1.ListExposedPortsRequest\x1a%.boxd.api.v1.ListExposedPortsResponse\x12;\n\x06SetVar\x12\x1a.boxd.api.v1.SetVarRequest\x1a\x15.boxd.api.v1.VarReply\x12\x43\n\x08ListVars\x12\x1c.boxd.api.v1.ListVarsRequest\x1a\x19.boxd.api.v1.VarListReply\x12\x41\n\tRemoveVar\x12\x1d.boxd.api.v1.RemoveVarRequest\x1a\x15.boxd.api.v1.VarReply\x12K\n\x0eSetSecretScope\x12\".boxd.api.v1.SetSecretScopeRequest\x1a\x15.boxd.api.v1.VarReply\x12\x45\n\nStreamLogs\x12\x1e.boxd.api.v1.StreamLogsRequest\x1a\x15.boxd.api.v1.LogChunk0\x01\x12:\n\x04\x45xec\x12\x16.boxd.api.v1.ExecChunk\x1a\x16.boxd.api.v1.ExecChunk(\x01\x30\x01\x12V\n\rCreateNetwork\x12!.boxd.api.v1.CreateNetworkRequest\x1a\".boxd.api.v1.CreateNetworkResponse\x12S\n\x0cListNetworks\x12 .boxd.api.v1.ListNetworksRequest\x1a!.boxd.api.v1.ListNetworksResponse\x12\\\n\x0f\x41\x64\x64\x43ustomDomain\x12#.boxd.api.v1.AddCustomDomainRequest\x1a$.boxd.api.v1.AddCustomDomainResponse\x12\x62\n\x11ListCustomDomains\x12%.boxd.api.v1.ListCustomDomainsRequest\x1a&.boxd.api.v1.ListCustomDomainsResponse\x12\x65\n\x12RemoveCustomDomain\x12&.boxd.api.v1.RemoveCustomDomainRequest\x1a\'.boxd.api.v1.RemoveCustomDomainResponse\x12S\n\x0cSetOrgDomain\x12 .boxd.api.v1.SetOrgDomainRequest\x1a!.boxd.api.v1.SetOrgDomainResponse\x12S\n\x0cGetOrgDomain\x12 .boxd.api.v1.GetOrgDomainRequest\x1a!.boxd.api.v1.GetOrgDomainResponse\x12Y\n\x0e\x43learOrgDomain\x12\".boxd.api.v1.ClearOrgDomainRequest\x1a#.boxd.api.v1.ClearOrgDomainResponse\x12\x41\n\x06Whoami\x12\x1a.boxd.api.v1.WhoamiRequest\x1a\x1b.boxd.api.v1.WhoamiResponse\x12P\n\x0b\x43reateToken\x12\x1f.boxd.api.v1.CreateTokenRequest\x1a .boxd.api.v1.CreateTokenResponse\x12M\n\nListTokens\x12\x1e.boxd.api.v1.ListTokensRequest\x1a\x1f.boxd.api.v1.ListTokensResponse\x12P\n\x0bRevokeToken\x12\x1f.boxd.api.v1.RevokeTokenRequest\x1a .boxd.api.v1.RevokeTokenResponse\x12M\n\nLinkSshKey\x12\x1e.boxd.api.v1.LinkSshKeyRequest\x1a\x1f.boxd.api.v1.LinkSshKeyResponse\x12J\n\tGetConfig\x12\x1d.boxd.api.v1.GetConfigRequest\x1a\x1e.boxd.api.v1.GetConfigResponse\x12\x41\n\x06\x46orkVm\x12\x1a.boxd.api.v1.ForkVmRequest\x1a\x1b.boxd.api.v1.ForkVmResponse\x12P\n\x0bListProxies\x12\x1f.boxd.api.v1.ListProxiesRequest\x1a .boxd.api.v1.ListProxiesResponse\x12Y\n\x0eListProxyNodes\x12\".boxd.api.v1.ListProxyNodesRequest\x1a#.boxd.api.v1.ListProxyNodesResponse\x12P\n\x0b\x43reateProxy\x12\x1f.boxd.api.v1.CreateProxyRequest\x1a .boxd.api.v1.CreateProxyResponse\x12P\n\x0b\x44\x65leteProxy\x12\x1f.boxd.api.v1.DeleteProxyRequest\x1a .boxd.api.v1.DeleteProxyResponse\x12S\n\x0cSetProxyPort\x12 .boxd.api.v1.SetProxyPortRequest\x1a!.boxd.api.v1.SetProxyPortResponse\x12M\n\nUploadFile\x12\x1e.boxd.api.v1.UploadFileRequest\x1a\x1f.boxd.api.v1.UploadFileResponse\x12S\n\x10UploadFileStream\x12\x1c.boxd.api.v1.UploadFileChunk\x1a\x1f.boxd.api.v1.UploadFileResponse(\x01\x12S\n\x0c\x44ownloadFile\x12 .boxd.api.v1.DownloadFileRequest\x1a!.boxd.api.v1.DownloadFileResponse\x12J\n\tSuspendVm\x12\x1d.boxd.api.v1.SuspendVmRequest\x1a\x1e.boxd.api.v1.SuspendVmResponse\x12G\n\x08ResumeVm\x12\x1c.boxd.api.v1.ResumeVmRequest\x1a\x1d.boxd.api.v1.ResumeVmResponse\x12P\n\x0bHibernateVm\x12\x1f.boxd.api.v1.HibernateVmRequest\x1a .boxd.api.v1.HibernateVmResponse\x12\x41\n\x06WakeVm\x12\x1a.boxd.api.v1.WakeVmRequest\x1a\x1b.boxd.api.v1.WakeVmResponse\x12Y\n\x0e\x43reateSnapshot\x12\".boxd.api.v1.CreateSnapshotRequest\x1a#.boxd.api.v1.CreateSnapshotResponse\x12V\n\rListSnapshots\x12!.boxd.api.v1.ListSnapshotsRequest\x1a\".boxd.api.v1.ListSnapshotsResponse\x12P\n\x0bGetSnapshot\x12\x1f.boxd.api.v1.GetSnapshotRequest\x1a .boxd.api.v1.GetSnapshotResponse\x12Y\n\x0e\x44\x65leteSnapshot\x12\".boxd.api.v1.DeleteSnapshotRequest\x1a#.boxd.api.v1.DeleteSnapshotResponse\x12_\n\x14\x43reateVmFromSnapshot\x12(.boxd.api.v1.CreateVmFromSnapshotRequest\x1a\x1d.boxd.api.v1.CreateVmResponse\x12_\n\x10\x43reateCheckpoint\x12$.boxd.api.v1.CreateCheckpointRequest\x1a%.boxd.api.v1.CreateCheckpointResponse\x12\\\n\x0fListCheckpoints\x12#.boxd.api.v1.ListCheckpointsRequest\x1a$.boxd.api.v1.ListCheckpointsResponse\x12_\n\x10\x44\x65leteCheckpoint\x12$.boxd.api.v1.DeleteCheckpointRequest\x1a%.boxd.api.v1.DeleteCheckpointResponse\x12\x62\n\x11RestoreCheckpoint\x12%.boxd.api.v1.RestoreCheckpointRequest\x1a&.boxd.api.v1.RestoreCheckpointResponse\x12n\n\x15SetAutoSuspendTimeout\x12).boxd.api.v1.SetAutoSuspendTimeoutRequest\x1a*.boxd.api.v1.SetAutoSuspendTimeoutResponse\x12t\n\x17SetAutoHibernateTimeout\x12+.boxd.api.v1.SetAutoHibernateTimeoutRequest\x1a,.boxd.api.v1.SetAutoHibernateTimeoutResponse\x12M\n\nCreateDisk\x12\x1e.boxd.api.v1.CreateDiskRequest\x1a\x1f.boxd.api.v1.CreateDiskResponse\x12J\n\tListDisks\x12\x1d.boxd.api.v1.ListDisksRequest\x1a\x1e.boxd.api.v1.ListDisksResponse\x12M\n\nAttachDisk\x12\x1e.boxd.api.v1.AttachDiskRequest\x1a\x1f.boxd.api.v1.AttachDiskResponse\x12M\n\nDetachDisk\x12\x1e.boxd.api.v1.DetachDiskRequest\x1a\x1f.boxd.api.v1.DetachDiskResponse\x12P\n\x0b\x44\x65stroyDisk\x12\x1f.boxd.api.v1.DestroyDiskRequest\x1a .boxd.api.v1.DestroyDiskResponse\x12S\n\x0c\x43reateApiKey\x12 .boxd.api.v1.CreateApiKeyRequest\x1a!.boxd.api.v1.CreateApiKeyResponse\x12P\n\x0bListApiKeys\x12\x1f.boxd.api.v1.ListApiKeysRequest\x1a .boxd.api.v1.ListApiKeysResponse\x12S\n\x0c\x44\x65leteApiKey\x12 .boxd.api.v1.DeleteApiKeyRequest\x1a!.boxd.api.v1.DeleteApiKeyResponse\x12J\n\tListPlans\x12\x1d.boxd.api.v1.ListPlansRequest\x1a\x1e.boxd.api.v1.ListPlansResponse\x12M\n\nGetBilling\x12\x1e.boxd.api.v1.GetBillingRequest\x1a\x1f.boxd.api.v1.GetBillingResponse\x12n\n\x15\x43reateCheckoutSession\x12).boxd.api.v1.CreateCheckoutSessionRequest\x1a*.boxd.api.v1.CreateCheckoutSessionResponse\x12}\n\x1a\x43reateBillingPortalSession\x12..boxd.api.v1.CreateBillingPortalSessionRequest\x1a/.boxd.api.v1.CreateBillingPortalSessionResponse\x12\x44\n\x07ShareVm\x12\x1b.boxd.api.v1.ShareVmRequest\x1a\x1c.boxd.api.v1.ShareVmResponse\x12J\n\tUnshareVm\x12\x1d.boxd.api.v1.UnshareVmRequest\x1a\x1e.boxd.api.v1.UnshareVmResponse\x12G\n\x08ListOrgs\x12\x1c.boxd.api.v1.ListOrgsRequest\x1a\x1d.boxd.api.v1.ListOrgsResponse\x12V\n\rGetOrgBilling\x12!.boxd.api.v1.GetOrgBillingRequest\x1a\".boxd.api.v1.GetOrgBillingResponse\x12\x62\n\x11SetBackupSchedule\x12%.boxd.api.v1.SetBackupScheduleRequest\x1a&.boxd.api.v1.SetBackupScheduleResponse\x12h\n\x13\x43learBackupSchedule\x12\'.boxd.api.v1.ClearBackupScheduleRequest\x1a(.boxd.api.v1.ClearBackupScheduleResponse\x12\x62\n\x11GetBackupSchedule\x12%.boxd.api.v1.GetBackupScheduleRequest\x1a&.boxd.api.v1.GetBackupScheduleResponse\x12P\n\x0bListBackups\x12\x1f.boxd.api.v1.ListBackupsRequest\x1a .boxd.api.v1.ListBackupsResponse\x12V\n\rRestoreBackup\x12!.boxd.api.v1.RestoreBackupRequest\x1a\".boxd.api.v1.RestoreBackupResponse\x12k\n\x14SetOrgBackupsDefault\x12(.boxd.api.v1.SetOrgBackupsDefaultRequest\x1a).boxd.api.v1.SetOrgBackupsDefaultResponse\x12k\n\x14GetOrgBackupsDefault\x12(.boxd.api.v1.GetOrgBackupsDefaultRequest\x1a).boxd.api.v1.GetOrgBackupsDefaultResponseb\x06proto3')
|
|
28
28
|
|
|
29
29
|
_globals = globals()
|
|
30
30
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -371,6 +371,36 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
371
371
|
_globals['_UNSHAREVMREQUEST']._serialized_end=11127
|
|
372
372
|
_globals['_UNSHAREVMRESPONSE']._serialized_start=11129
|
|
373
373
|
_globals['_UNSHAREVMRESPONSE']._serialized_end=11148
|
|
374
|
-
_globals['
|
|
375
|
-
_globals['
|
|
374
|
+
_globals['_SETBACKUPSCHEDULEREQUEST']._serialized_start=11150
|
|
375
|
+
_globals['_SETBACKUPSCHEDULEREQUEST']._serialized_end=11259
|
|
376
|
+
_globals['_SETBACKUPSCHEDULERESPONSE']._serialized_start=11261
|
|
377
|
+
_globals['_SETBACKUPSCHEDULERESPONSE']._serialized_end=11288
|
|
378
|
+
_globals['_CLEARBACKUPSCHEDULEREQUEST']._serialized_start=11290
|
|
379
|
+
_globals['_CLEARBACKUPSCHEDULEREQUEST']._serialized_end=11330
|
|
380
|
+
_globals['_CLEARBACKUPSCHEDULERESPONSE']._serialized_start=11332
|
|
381
|
+
_globals['_CLEARBACKUPSCHEDULERESPONSE']._serialized_end=11361
|
|
382
|
+
_globals['_GETBACKUPSCHEDULEREQUEST']._serialized_start=11363
|
|
383
|
+
_globals['_GETBACKUPSCHEDULEREQUEST']._serialized_end=11401
|
|
384
|
+
_globals['_GETBACKUPSCHEDULERESPONSE']._serialized_start=11404
|
|
385
|
+
_globals['_GETBACKUPSCHEDULERESPONSE']._serialized_end=11567
|
|
386
|
+
_globals['_LISTBACKUPSREQUEST']._serialized_start=11569
|
|
387
|
+
_globals['_LISTBACKUPSREQUEST']._serialized_end=11601
|
|
388
|
+
_globals['_BACKUPINFO']._serialized_start=11604
|
|
389
|
+
_globals['_BACKUPINFO']._serialized_end=11758
|
|
390
|
+
_globals['_LISTBACKUPSRESPONSE']._serialized_start=11760
|
|
391
|
+
_globals['_LISTBACKUPSRESPONSE']._serialized_end=11823
|
|
392
|
+
_globals['_RESTOREBACKUPREQUEST']._serialized_start=11825
|
|
393
|
+
_globals['_RESTOREBACKUPREQUEST']._serialized_end=11878
|
|
394
|
+
_globals['_RESTOREBACKUPRESPONSE']._serialized_start=11880
|
|
395
|
+
_globals['_RESTOREBACKUPRESPONSE']._serialized_end=11903
|
|
396
|
+
_globals['_SETORGBACKUPSDEFAULTREQUEST']._serialized_start=11906
|
|
397
|
+
_globals['_SETORGBACKUPSDEFAULTREQUEST']._serialized_end=12041
|
|
398
|
+
_globals['_SETORGBACKUPSDEFAULTRESPONSE']._serialized_start=12043
|
|
399
|
+
_globals['_SETORGBACKUPSDEFAULTRESPONSE']._serialized_end=12135
|
|
400
|
+
_globals['_GETORGBACKUPSDEFAULTREQUEST']._serialized_start=12137
|
|
401
|
+
_globals['_GETORGBACKUPSDEFAULTREQUEST']._serialized_end=12182
|
|
402
|
+
_globals['_GETORGBACKUPSDEFAULTRESPONSE']._serialized_start=12184
|
|
403
|
+
_globals['_GETORGBACKUPSDEFAULTRESPONSE']._serialized_end=12276
|
|
404
|
+
_globals['_BOXDAPI']._serialized_start=12279
|
|
405
|
+
_globals['_BOXDAPI']._serialized_end=19037
|
|
376
406
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -399,6 +399,41 @@ class BoxdApiStub(object):
|
|
|
399
399
|
request_serializer=api__pb2.GetOrgBillingRequest.SerializeToString,
|
|
400
400
|
response_deserializer=api__pb2.GetOrgBillingResponse.FromString,
|
|
401
401
|
_registered_method=True)
|
|
402
|
+
self.SetBackupSchedule = channel.unary_unary(
|
|
403
|
+
'/boxd.api.v1.BoxdApi/SetBackupSchedule',
|
|
404
|
+
request_serializer=api__pb2.SetBackupScheduleRequest.SerializeToString,
|
|
405
|
+
response_deserializer=api__pb2.SetBackupScheduleResponse.FromString,
|
|
406
|
+
_registered_method=True)
|
|
407
|
+
self.ClearBackupSchedule = channel.unary_unary(
|
|
408
|
+
'/boxd.api.v1.BoxdApi/ClearBackupSchedule',
|
|
409
|
+
request_serializer=api__pb2.ClearBackupScheduleRequest.SerializeToString,
|
|
410
|
+
response_deserializer=api__pb2.ClearBackupScheduleResponse.FromString,
|
|
411
|
+
_registered_method=True)
|
|
412
|
+
self.GetBackupSchedule = channel.unary_unary(
|
|
413
|
+
'/boxd.api.v1.BoxdApi/GetBackupSchedule',
|
|
414
|
+
request_serializer=api__pb2.GetBackupScheduleRequest.SerializeToString,
|
|
415
|
+
response_deserializer=api__pb2.GetBackupScheduleResponse.FromString,
|
|
416
|
+
_registered_method=True)
|
|
417
|
+
self.ListBackups = channel.unary_unary(
|
|
418
|
+
'/boxd.api.v1.BoxdApi/ListBackups',
|
|
419
|
+
request_serializer=api__pb2.ListBackupsRequest.SerializeToString,
|
|
420
|
+
response_deserializer=api__pb2.ListBackupsResponse.FromString,
|
|
421
|
+
_registered_method=True)
|
|
422
|
+
self.RestoreBackup = channel.unary_unary(
|
|
423
|
+
'/boxd.api.v1.BoxdApi/RestoreBackup',
|
|
424
|
+
request_serializer=api__pb2.RestoreBackupRequest.SerializeToString,
|
|
425
|
+
response_deserializer=api__pb2.RestoreBackupResponse.FromString,
|
|
426
|
+
_registered_method=True)
|
|
427
|
+
self.SetOrgBackupsDefault = channel.unary_unary(
|
|
428
|
+
'/boxd.api.v1.BoxdApi/SetOrgBackupsDefault',
|
|
429
|
+
request_serializer=api__pb2.SetOrgBackupsDefaultRequest.SerializeToString,
|
|
430
|
+
response_deserializer=api__pb2.SetOrgBackupsDefaultResponse.FromString,
|
|
431
|
+
_registered_method=True)
|
|
432
|
+
self.GetOrgBackupsDefault = channel.unary_unary(
|
|
433
|
+
'/boxd.api.v1.BoxdApi/GetOrgBackupsDefault',
|
|
434
|
+
request_serializer=api__pb2.GetOrgBackupsDefaultRequest.SerializeToString,
|
|
435
|
+
response_deserializer=api__pb2.GetOrgBackupsDefaultResponse.FromString,
|
|
436
|
+
_registered_method=True)
|
|
402
437
|
|
|
403
438
|
|
|
404
439
|
class BoxdApiServicer(object):
|
|
@@ -891,6 +926,60 @@ class BoxdApiServicer(object):
|
|
|
891
926
|
context.set_details('Method not implemented!')
|
|
892
927
|
raise NotImplementedError('Method not implemented!')
|
|
893
928
|
|
|
929
|
+
def SetBackupSchedule(self, request, context):
|
|
930
|
+
"""Disaster recovery: scheduled VM disk backups to object storage
|
|
931
|
+
(plans/2026-08-10-dr-vm-backups.md). Off by default — SetBackupSchedule
|
|
932
|
+
is refused server-side if the cluster has no [backups] object store
|
|
933
|
+
configured.
|
|
934
|
+
"""
|
|
935
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
936
|
+
context.set_details('Method not implemented!')
|
|
937
|
+
raise NotImplementedError('Method not implemented!')
|
|
938
|
+
|
|
939
|
+
def ClearBackupSchedule(self, request, context):
|
|
940
|
+
"""Missing associated documentation comment in .proto file."""
|
|
941
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
942
|
+
context.set_details('Method not implemented!')
|
|
943
|
+
raise NotImplementedError('Method not implemented!')
|
|
944
|
+
|
|
945
|
+
def GetBackupSchedule(self, request, context):
|
|
946
|
+
"""Missing associated documentation comment in .proto file."""
|
|
947
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
948
|
+
context.set_details('Method not implemented!')
|
|
949
|
+
raise NotImplementedError('Method not implemented!')
|
|
950
|
+
|
|
951
|
+
def ListBackups(self, request, context):
|
|
952
|
+
"""Missing associated documentation comment in .proto file."""
|
|
953
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
954
|
+
context.set_details('Method not implemented!')
|
|
955
|
+
raise NotImplementedError('Method not implemented!')
|
|
956
|
+
|
|
957
|
+
def RestoreBackup(self, request, context):
|
|
958
|
+
"""Restore is IN-PLACE and DESTRUCTIVE (Q1: full disk rewrite, no
|
|
959
|
+
fork-from-backup) — callers must get explicit user confirmation first.
|
|
960
|
+
"""
|
|
961
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
962
|
+
context.set_details('Method not implemented!')
|
|
963
|
+
raise NotImplementedError('Method not implemented!')
|
|
964
|
+
|
|
965
|
+
def SetOrgBackupsDefault(self, request, context):
|
|
966
|
+
"""The org's default backup schedule for NEW VMs (existing VMs are
|
|
967
|
+
unchanged; a fork always copies its own source's schedule instead of
|
|
968
|
+
this default — see plans/2026-08-10-dr-vm-backups.md Q3). Self-service
|
|
969
|
+
counterpart to the operator-only `boxd-ctl org set-backups-default`.
|
|
970
|
+
Set/Clear require org admin; Get is readable by any member — same shape
|
|
971
|
+
as SetOrgDomain/GetOrgDomain above.
|
|
972
|
+
"""
|
|
973
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
974
|
+
context.set_details('Method not implemented!')
|
|
975
|
+
raise NotImplementedError('Method not implemented!')
|
|
976
|
+
|
|
977
|
+
def GetOrgBackupsDefault(self, request, context):
|
|
978
|
+
"""Missing associated documentation comment in .proto file."""
|
|
979
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
980
|
+
context.set_details('Method not implemented!')
|
|
981
|
+
raise NotImplementedError('Method not implemented!')
|
|
982
|
+
|
|
894
983
|
|
|
895
984
|
def add_BoxdApiServicer_to_server(servicer, server):
|
|
896
985
|
rpc_method_handlers = {
|
|
@@ -1259,6 +1348,41 @@ def add_BoxdApiServicer_to_server(servicer, server):
|
|
|
1259
1348
|
request_deserializer=api__pb2.GetOrgBillingRequest.FromString,
|
|
1260
1349
|
response_serializer=api__pb2.GetOrgBillingResponse.SerializeToString,
|
|
1261
1350
|
),
|
|
1351
|
+
'SetBackupSchedule': grpc.unary_unary_rpc_method_handler(
|
|
1352
|
+
servicer.SetBackupSchedule,
|
|
1353
|
+
request_deserializer=api__pb2.SetBackupScheduleRequest.FromString,
|
|
1354
|
+
response_serializer=api__pb2.SetBackupScheduleResponse.SerializeToString,
|
|
1355
|
+
),
|
|
1356
|
+
'ClearBackupSchedule': grpc.unary_unary_rpc_method_handler(
|
|
1357
|
+
servicer.ClearBackupSchedule,
|
|
1358
|
+
request_deserializer=api__pb2.ClearBackupScheduleRequest.FromString,
|
|
1359
|
+
response_serializer=api__pb2.ClearBackupScheduleResponse.SerializeToString,
|
|
1360
|
+
),
|
|
1361
|
+
'GetBackupSchedule': grpc.unary_unary_rpc_method_handler(
|
|
1362
|
+
servicer.GetBackupSchedule,
|
|
1363
|
+
request_deserializer=api__pb2.GetBackupScheduleRequest.FromString,
|
|
1364
|
+
response_serializer=api__pb2.GetBackupScheduleResponse.SerializeToString,
|
|
1365
|
+
),
|
|
1366
|
+
'ListBackups': grpc.unary_unary_rpc_method_handler(
|
|
1367
|
+
servicer.ListBackups,
|
|
1368
|
+
request_deserializer=api__pb2.ListBackupsRequest.FromString,
|
|
1369
|
+
response_serializer=api__pb2.ListBackupsResponse.SerializeToString,
|
|
1370
|
+
),
|
|
1371
|
+
'RestoreBackup': grpc.unary_unary_rpc_method_handler(
|
|
1372
|
+
servicer.RestoreBackup,
|
|
1373
|
+
request_deserializer=api__pb2.RestoreBackupRequest.FromString,
|
|
1374
|
+
response_serializer=api__pb2.RestoreBackupResponse.SerializeToString,
|
|
1375
|
+
),
|
|
1376
|
+
'SetOrgBackupsDefault': grpc.unary_unary_rpc_method_handler(
|
|
1377
|
+
servicer.SetOrgBackupsDefault,
|
|
1378
|
+
request_deserializer=api__pb2.SetOrgBackupsDefaultRequest.FromString,
|
|
1379
|
+
response_serializer=api__pb2.SetOrgBackupsDefaultResponse.SerializeToString,
|
|
1380
|
+
),
|
|
1381
|
+
'GetOrgBackupsDefault': grpc.unary_unary_rpc_method_handler(
|
|
1382
|
+
servicer.GetOrgBackupsDefault,
|
|
1383
|
+
request_deserializer=api__pb2.GetOrgBackupsDefaultRequest.FromString,
|
|
1384
|
+
response_serializer=api__pb2.GetOrgBackupsDefaultResponse.SerializeToString,
|
|
1385
|
+
),
|
|
1262
1386
|
}
|
|
1263
1387
|
generic_handler = grpc.method_handlers_generic_handler(
|
|
1264
1388
|
'boxd.api.v1.BoxdApi', rpc_method_handlers)
|
|
@@ -3240,3 +3364,192 @@ class BoxdApi(object):
|
|
|
3240
3364
|
timeout,
|
|
3241
3365
|
metadata,
|
|
3242
3366
|
_registered_method=True)
|
|
3367
|
+
|
|
3368
|
+
@staticmethod
|
|
3369
|
+
def SetBackupSchedule(request,
|
|
3370
|
+
target,
|
|
3371
|
+
options=(),
|
|
3372
|
+
channel_credentials=None,
|
|
3373
|
+
call_credentials=None,
|
|
3374
|
+
insecure=False,
|
|
3375
|
+
compression=None,
|
|
3376
|
+
wait_for_ready=None,
|
|
3377
|
+
timeout=None,
|
|
3378
|
+
metadata=None):
|
|
3379
|
+
return grpc.experimental.unary_unary(
|
|
3380
|
+
request,
|
|
3381
|
+
target,
|
|
3382
|
+
'/boxd.api.v1.BoxdApi/SetBackupSchedule',
|
|
3383
|
+
api__pb2.SetBackupScheduleRequest.SerializeToString,
|
|
3384
|
+
api__pb2.SetBackupScheduleResponse.FromString,
|
|
3385
|
+
options,
|
|
3386
|
+
channel_credentials,
|
|
3387
|
+
insecure,
|
|
3388
|
+
call_credentials,
|
|
3389
|
+
compression,
|
|
3390
|
+
wait_for_ready,
|
|
3391
|
+
timeout,
|
|
3392
|
+
metadata,
|
|
3393
|
+
_registered_method=True)
|
|
3394
|
+
|
|
3395
|
+
@staticmethod
|
|
3396
|
+
def ClearBackupSchedule(request,
|
|
3397
|
+
target,
|
|
3398
|
+
options=(),
|
|
3399
|
+
channel_credentials=None,
|
|
3400
|
+
call_credentials=None,
|
|
3401
|
+
insecure=False,
|
|
3402
|
+
compression=None,
|
|
3403
|
+
wait_for_ready=None,
|
|
3404
|
+
timeout=None,
|
|
3405
|
+
metadata=None):
|
|
3406
|
+
return grpc.experimental.unary_unary(
|
|
3407
|
+
request,
|
|
3408
|
+
target,
|
|
3409
|
+
'/boxd.api.v1.BoxdApi/ClearBackupSchedule',
|
|
3410
|
+
api__pb2.ClearBackupScheduleRequest.SerializeToString,
|
|
3411
|
+
api__pb2.ClearBackupScheduleResponse.FromString,
|
|
3412
|
+
options,
|
|
3413
|
+
channel_credentials,
|
|
3414
|
+
insecure,
|
|
3415
|
+
call_credentials,
|
|
3416
|
+
compression,
|
|
3417
|
+
wait_for_ready,
|
|
3418
|
+
timeout,
|
|
3419
|
+
metadata,
|
|
3420
|
+
_registered_method=True)
|
|
3421
|
+
|
|
3422
|
+
@staticmethod
|
|
3423
|
+
def GetBackupSchedule(request,
|
|
3424
|
+
target,
|
|
3425
|
+
options=(),
|
|
3426
|
+
channel_credentials=None,
|
|
3427
|
+
call_credentials=None,
|
|
3428
|
+
insecure=False,
|
|
3429
|
+
compression=None,
|
|
3430
|
+
wait_for_ready=None,
|
|
3431
|
+
timeout=None,
|
|
3432
|
+
metadata=None):
|
|
3433
|
+
return grpc.experimental.unary_unary(
|
|
3434
|
+
request,
|
|
3435
|
+
target,
|
|
3436
|
+
'/boxd.api.v1.BoxdApi/GetBackupSchedule',
|
|
3437
|
+
api__pb2.GetBackupScheduleRequest.SerializeToString,
|
|
3438
|
+
api__pb2.GetBackupScheduleResponse.FromString,
|
|
3439
|
+
options,
|
|
3440
|
+
channel_credentials,
|
|
3441
|
+
insecure,
|
|
3442
|
+
call_credentials,
|
|
3443
|
+
compression,
|
|
3444
|
+
wait_for_ready,
|
|
3445
|
+
timeout,
|
|
3446
|
+
metadata,
|
|
3447
|
+
_registered_method=True)
|
|
3448
|
+
|
|
3449
|
+
@staticmethod
|
|
3450
|
+
def ListBackups(request,
|
|
3451
|
+
target,
|
|
3452
|
+
options=(),
|
|
3453
|
+
channel_credentials=None,
|
|
3454
|
+
call_credentials=None,
|
|
3455
|
+
insecure=False,
|
|
3456
|
+
compression=None,
|
|
3457
|
+
wait_for_ready=None,
|
|
3458
|
+
timeout=None,
|
|
3459
|
+
metadata=None):
|
|
3460
|
+
return grpc.experimental.unary_unary(
|
|
3461
|
+
request,
|
|
3462
|
+
target,
|
|
3463
|
+
'/boxd.api.v1.BoxdApi/ListBackups',
|
|
3464
|
+
api__pb2.ListBackupsRequest.SerializeToString,
|
|
3465
|
+
api__pb2.ListBackupsResponse.FromString,
|
|
3466
|
+
options,
|
|
3467
|
+
channel_credentials,
|
|
3468
|
+
insecure,
|
|
3469
|
+
call_credentials,
|
|
3470
|
+
compression,
|
|
3471
|
+
wait_for_ready,
|
|
3472
|
+
timeout,
|
|
3473
|
+
metadata,
|
|
3474
|
+
_registered_method=True)
|
|
3475
|
+
|
|
3476
|
+
@staticmethod
|
|
3477
|
+
def RestoreBackup(request,
|
|
3478
|
+
target,
|
|
3479
|
+
options=(),
|
|
3480
|
+
channel_credentials=None,
|
|
3481
|
+
call_credentials=None,
|
|
3482
|
+
insecure=False,
|
|
3483
|
+
compression=None,
|
|
3484
|
+
wait_for_ready=None,
|
|
3485
|
+
timeout=None,
|
|
3486
|
+
metadata=None):
|
|
3487
|
+
return grpc.experimental.unary_unary(
|
|
3488
|
+
request,
|
|
3489
|
+
target,
|
|
3490
|
+
'/boxd.api.v1.BoxdApi/RestoreBackup',
|
|
3491
|
+
api__pb2.RestoreBackupRequest.SerializeToString,
|
|
3492
|
+
api__pb2.RestoreBackupResponse.FromString,
|
|
3493
|
+
options,
|
|
3494
|
+
channel_credentials,
|
|
3495
|
+
insecure,
|
|
3496
|
+
call_credentials,
|
|
3497
|
+
compression,
|
|
3498
|
+
wait_for_ready,
|
|
3499
|
+
timeout,
|
|
3500
|
+
metadata,
|
|
3501
|
+
_registered_method=True)
|
|
3502
|
+
|
|
3503
|
+
@staticmethod
|
|
3504
|
+
def SetOrgBackupsDefault(request,
|
|
3505
|
+
target,
|
|
3506
|
+
options=(),
|
|
3507
|
+
channel_credentials=None,
|
|
3508
|
+
call_credentials=None,
|
|
3509
|
+
insecure=False,
|
|
3510
|
+
compression=None,
|
|
3511
|
+
wait_for_ready=None,
|
|
3512
|
+
timeout=None,
|
|
3513
|
+
metadata=None):
|
|
3514
|
+
return grpc.experimental.unary_unary(
|
|
3515
|
+
request,
|
|
3516
|
+
target,
|
|
3517
|
+
'/boxd.api.v1.BoxdApi/SetOrgBackupsDefault',
|
|
3518
|
+
api__pb2.SetOrgBackupsDefaultRequest.SerializeToString,
|
|
3519
|
+
api__pb2.SetOrgBackupsDefaultResponse.FromString,
|
|
3520
|
+
options,
|
|
3521
|
+
channel_credentials,
|
|
3522
|
+
insecure,
|
|
3523
|
+
call_credentials,
|
|
3524
|
+
compression,
|
|
3525
|
+
wait_for_ready,
|
|
3526
|
+
timeout,
|
|
3527
|
+
metadata,
|
|
3528
|
+
_registered_method=True)
|
|
3529
|
+
|
|
3530
|
+
@staticmethod
|
|
3531
|
+
def GetOrgBackupsDefault(request,
|
|
3532
|
+
target,
|
|
3533
|
+
options=(),
|
|
3534
|
+
channel_credentials=None,
|
|
3535
|
+
call_credentials=None,
|
|
3536
|
+
insecure=False,
|
|
3537
|
+
compression=None,
|
|
3538
|
+
wait_for_ready=None,
|
|
3539
|
+
timeout=None,
|
|
3540
|
+
metadata=None):
|
|
3541
|
+
return grpc.experimental.unary_unary(
|
|
3542
|
+
request,
|
|
3543
|
+
target,
|
|
3544
|
+
'/boxd.api.v1.BoxdApi/GetOrgBackupsDefault',
|
|
3545
|
+
api__pb2.GetOrgBackupsDefaultRequest.SerializeToString,
|
|
3546
|
+
api__pb2.GetOrgBackupsDefaultResponse.FromString,
|
|
3547
|
+
options,
|
|
3548
|
+
channel_credentials,
|
|
3549
|
+
insecure,
|
|
3550
|
+
call_credentials,
|
|
3551
|
+
compression,
|
|
3552
|
+
wait_for_ready,
|
|
3553
|
+
timeout,
|
|
3554
|
+
metadata,
|
|
3555
|
+
_registered_method=True)
|
|
@@ -16,6 +16,8 @@ from datetime import datetime, timezone
|
|
|
16
16
|
from .models import (
|
|
17
17
|
Account,
|
|
18
18
|
ApiKey,
|
|
19
|
+
Backup,
|
|
20
|
+
BackupSchedule,
|
|
19
21
|
Billing,
|
|
20
22
|
Checkpoint,
|
|
21
23
|
ClusterConfig,
|
|
@@ -68,6 +70,11 @@ def _epoch_ms(millis: int) -> datetime | None:
|
|
|
68
70
|
return datetime.fromtimestamp(millis / 1000, tz=timezone.utc)
|
|
69
71
|
|
|
70
72
|
|
|
73
|
+
def _epoch_ms_always(millis: int) -> datetime:
|
|
74
|
+
"""Epoch MILLISECONDS → aware datetime, for fields the server always sets."""
|
|
75
|
+
return datetime.fromtimestamp(millis / 1000, tz=timezone.utc)
|
|
76
|
+
|
|
77
|
+
|
|
71
78
|
# ── Machines ─────────────────────────────────────────────────────────
|
|
72
79
|
|
|
73
80
|
|
|
@@ -213,6 +220,34 @@ def created_checkpoint(msg) -> CreatedCheckpoint:
|
|
|
213
220
|
return CreatedCheckpoint(id=msg.checkpoint_id, name=msg.name, status=msg.status)
|
|
214
221
|
|
|
215
222
|
|
|
223
|
+
# ── Backups (disaster recovery) ─────────────────────────────────────────
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def backup_schedule(msg) -> BackupSchedule | None:
|
|
227
|
+
"""`GetBackupScheduleResponse` — `enabled=False` means no schedule (off)."""
|
|
228
|
+
if not msg.enabled:
|
|
229
|
+
return None
|
|
230
|
+
return BackupSchedule(
|
|
231
|
+
schedule_kind=msg.schedule_kind,
|
|
232
|
+
schedule_value=msg.schedule_value,
|
|
233
|
+
retention_secs=msg.retention_secs,
|
|
234
|
+
next_backup_at=_epoch_ms_always(msg.next_backup_at),
|
|
235
|
+
last_backup_at=_epoch_ms(msg.last_backup_at),
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def backup(msg) -> Backup:
|
|
240
|
+
return Backup(
|
|
241
|
+
id=msg.backup_id,
|
|
242
|
+
status=msg.status,
|
|
243
|
+
size_bytes=msg.size_bytes,
|
|
244
|
+
checksum=_text(msg.checksum),
|
|
245
|
+
points_to_backup_id=_text(msg.points_to_backup_id),
|
|
246
|
+
created_at=_epoch_ms_always(msg.created_at),
|
|
247
|
+
expires_at=_epoch_ms_always(msg.expires_at),
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
|
|
216
251
|
# ── Snapshots ────────────────────────────────────────────────────────
|
|
217
252
|
|
|
218
253
|
|
|
@@ -110,7 +110,7 @@ class SyncTransport(_TransportBase):
|
|
|
110
110
|
"""Server-streaming call. Never retried — a partial stream can't be replayed."""
|
|
111
111
|
token = self._credentials.token()
|
|
112
112
|
stub = self._ensure_stub()
|
|
113
|
-
return
|
|
113
|
+
return _StreamCall(getattr(stub, method)(request, metadata=self._metadata(token)))
|
|
114
114
|
|
|
115
115
|
def bidi(
|
|
116
116
|
self, method: str, requests: Iterable, *, timeout: float | None = None
|
|
@@ -123,7 +123,7 @@ class SyncTransport(_TransportBase):
|
|
|
123
123
|
"""
|
|
124
124
|
token = self._credentials.token()
|
|
125
125
|
stub = self._ensure_stub()
|
|
126
|
-
return
|
|
126
|
+
return _StreamCall(
|
|
127
127
|
getattr(stub, method)(
|
|
128
128
|
requests, timeout=timeout, metadata=self._metadata(token)
|
|
129
129
|
)
|
|
@@ -171,13 +171,15 @@ class AsyncTransport(_TransportBase):
|
|
|
171
171
|
async def server_stream(self, method: str, request):
|
|
172
172
|
token = await self._credentials.token()
|
|
173
173
|
stub = await self._ensure_stub()
|
|
174
|
-
return
|
|
174
|
+
return _AsyncStreamCall(getattr(stub, method)(request, metadata=self._metadata(token)))
|
|
175
175
|
|
|
176
176
|
async def bidi(self, method: str, requests, *, timeout: float | None = None):
|
|
177
177
|
token = await self._credentials.token()
|
|
178
178
|
stub = await self._ensure_stub()
|
|
179
|
-
return
|
|
180
|
-
|
|
179
|
+
return _AsyncStreamCall(
|
|
180
|
+
getattr(stub, method)(
|
|
181
|
+
requests, timeout=timeout, metadata=self._metadata(token)
|
|
182
|
+
)
|
|
181
183
|
)
|
|
182
184
|
|
|
183
185
|
async def close(self) -> None:
|
|
@@ -187,22 +189,56 @@ class AsyncTransport(_TransportBase):
|
|
|
187
189
|
self._stub = None
|
|
188
190
|
|
|
189
191
|
|
|
190
|
-
|
|
191
|
-
"""
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
class _StreamCall:
|
|
193
|
+
"""A streaming call that re-raises gRPC errors as BoxdErrors, lazily.
|
|
194
|
+
|
|
195
|
+
A class rather than a bare generator so `cancel()` stays reachable —
|
|
196
|
+
`ExecStream.close()` uses it to tear down an abandoned RPC.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
def __init__(self, call):
|
|
200
|
+
self._call = call
|
|
201
|
+
self._iter = self._translate()
|
|
202
|
+
|
|
203
|
+
def _translate(self):
|
|
204
|
+
try:
|
|
205
|
+
for item in self._call:
|
|
206
|
+
yield item
|
|
207
|
+
except grpc.RpcError as e:
|
|
208
|
+
raise from_grpc_error(e) from e
|
|
209
|
+
|
|
210
|
+
def __iter__(self) -> Iterator:
|
|
211
|
+
return self
|
|
212
|
+
|
|
213
|
+
def __next__(self):
|
|
214
|
+
return next(self._iter)
|
|
215
|
+
|
|
216
|
+
def cancel(self):
|
|
217
|
+
return self._call.cancel()
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class _AsyncStreamCall:
|
|
221
|
+
"""Async twin of :class:`_StreamCall`."""
|
|
222
|
+
|
|
223
|
+
def __init__(self, call):
|
|
224
|
+
self._call = call
|
|
225
|
+
self._iter = self._translate()
|
|
226
|
+
|
|
227
|
+
async def _translate(self):
|
|
228
|
+
try:
|
|
229
|
+
async for item in self._call:
|
|
230
|
+
yield item
|
|
231
|
+
except grpc.aio.AioRpcError as e:
|
|
232
|
+
raise from_grpc_error(e) from e
|
|
233
|
+
|
|
234
|
+
def __aiter__(self):
|
|
235
|
+
return self
|
|
197
236
|
|
|
237
|
+
async def __anext__(self):
|
|
238
|
+
return await self._iter.__anext__()
|
|
198
239
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
try:
|
|
202
|
-
async for item in call:
|
|
203
|
-
yield item
|
|
204
|
-
except grpc.aio.AioRpcError as e:
|
|
205
|
-
raise from_grpc_error(e) from e
|
|
240
|
+
def cancel(self):
|
|
241
|
+
return self._call.cancel()
|
|
206
242
|
|
|
207
243
|
|
|
208
244
|
__all__ = ["AsyncTransport", "BoxdError", "SyncTransport"]
|
|
@@ -234,6 +234,35 @@ class CreatedCheckpoint(BaseModel):
|
|
|
234
234
|
status: str
|
|
235
235
|
|
|
236
236
|
|
|
237
|
+
class BackupSchedule(BaseModel):
|
|
238
|
+
"""A machine's disaster-recovery backup schedule. `None` from
|
|
239
|
+
`backups.schedule.get()` means backups are off (no separate flag)."""
|
|
240
|
+
|
|
241
|
+
schedule_kind: Literal["cron", "interval"] | str
|
|
242
|
+
schedule_value: str
|
|
243
|
+
"""A cron expression, or an interval in seconds as text, per `schedule_kind`."""
|
|
244
|
+
retention_secs: int
|
|
245
|
+
next_backup_at: datetime
|
|
246
|
+
last_backup_at: datetime | None
|
|
247
|
+
"""None until the first tick resolves."""
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class Backup(BaseModel):
|
|
251
|
+
"""A single disaster-recovery backup of a machine's disk."""
|
|
252
|
+
|
|
253
|
+
id: str
|
|
254
|
+
status: str
|
|
255
|
+
""""pending" | "ready" | "dedup" | "failed"."""
|
|
256
|
+
size_bytes: int
|
|
257
|
+
"""0 for pending/dedup/failed."""
|
|
258
|
+
checksum: str | None
|
|
259
|
+
"""sha256, hex. None for pending/dedup/failed."""
|
|
260
|
+
points_to_backup_id: str | None
|
|
261
|
+
"""Set iff `status == "dedup"` — the backup this one is a cheap pointer to."""
|
|
262
|
+
created_at: datetime
|
|
263
|
+
expires_at: datetime
|
|
264
|
+
|
|
265
|
+
|
|
237
266
|
class PauseResult(BaseModel):
|
|
238
267
|
suspend_us: int
|
|
239
268
|
"""How long the suspend took, in microseconds."""
|
|
@@ -17,6 +17,8 @@ from .._generated import api_pb2
|
|
|
17
17
|
from .._streaming import AsyncExecStream, ExecStream
|
|
18
18
|
from ..errors import BoxdError
|
|
19
19
|
from ..models import (
|
|
20
|
+
Backup,
|
|
21
|
+
BackupSchedule,
|
|
20
22
|
Checkpoint,
|
|
21
23
|
CreatedCheckpoint,
|
|
22
24
|
ExecResult,
|
|
@@ -187,6 +189,7 @@ class Machines(Namespace):
|
|
|
187
189
|
self.ports = Ports(transport)
|
|
188
190
|
self.proxies = Proxies(transport)
|
|
189
191
|
self.checkpoints = Checkpoints(transport)
|
|
192
|
+
self.backups = Backups(transport)
|
|
190
193
|
|
|
191
194
|
def create(
|
|
192
195
|
self,
|
|
@@ -661,6 +664,67 @@ class Checkpoints(Namespace):
|
|
|
661
664
|
)
|
|
662
665
|
|
|
663
666
|
|
|
667
|
+
class Backups(Namespace):
|
|
668
|
+
"""`boxd.machines.backups` — scheduled disaster-recovery disk backups.
|
|
669
|
+
|
|
670
|
+
Off by default. Enabling copies the disk to object storage on an
|
|
671
|
+
interval; restoring is a full, destructive disk rewrite (unlike a
|
|
672
|
+
checkpoint restore, running/memory state is not restored — the machine
|
|
673
|
+
cold-boots into the restored disk).
|
|
674
|
+
"""
|
|
675
|
+
|
|
676
|
+
def schedule_get(self, machine_id: str) -> BackupSchedule | None:
|
|
677
|
+
"""`None` means backups are off."""
|
|
678
|
+
resp = self._transport.call(
|
|
679
|
+
"GetBackupSchedule", api_pb2.GetBackupScheduleRequest(vm=machine_id)
|
|
680
|
+
)
|
|
681
|
+
return m.backup_schedule(resp)
|
|
682
|
+
|
|
683
|
+
def schedule_set(
|
|
684
|
+
self,
|
|
685
|
+
machine_id: str,
|
|
686
|
+
*,
|
|
687
|
+
interval_secs: int | None = None,
|
|
688
|
+
cron: str | None = None,
|
|
689
|
+
retention_secs: int,
|
|
690
|
+
) -> None:
|
|
691
|
+
"""Enable or update the schedule. Pass exactly one of `interval_secs`
|
|
692
|
+
(relative to the last backup) or `cron` (wall-clock, standard 5-field
|
|
693
|
+
cron syntax)."""
|
|
694
|
+
if (interval_secs is None) == (cron is None):
|
|
695
|
+
raise ValueError("pass exactly one of interval_secs or cron")
|
|
696
|
+
kind, value = ("interval", str(interval_secs)) if interval_secs is not None else ("cron", cron)
|
|
697
|
+
self._transport.call(
|
|
698
|
+
"SetBackupSchedule",
|
|
699
|
+
api_pb2.SetBackupScheduleRequest(
|
|
700
|
+
vm=machine_id,
|
|
701
|
+
schedule_kind=kind,
|
|
702
|
+
schedule_value=value,
|
|
703
|
+
retention_secs=retention_secs,
|
|
704
|
+
),
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
def schedule_clear(self, machine_id: str) -> None:
|
|
708
|
+
"""Disable backups for this machine."""
|
|
709
|
+
self._transport.call(
|
|
710
|
+
"ClearBackupSchedule", api_pb2.ClearBackupScheduleRequest(vm=machine_id)
|
|
711
|
+
)
|
|
712
|
+
|
|
713
|
+
def list(self, machine_id: str) -> list[Backup]:
|
|
714
|
+
resp = self._transport.call(
|
|
715
|
+
"ListBackups", api_pb2.ListBackupsRequest(vm=machine_id)
|
|
716
|
+
)
|
|
717
|
+
return [m.backup(b) for b in resp.backups]
|
|
718
|
+
|
|
719
|
+
def restore(self, machine_id: str, backup_id: str) -> None:
|
|
720
|
+
"""Restore the machine's disk from a backup IN PLACE. Destructive:
|
|
721
|
+
overwrites the machine's current disk; anything since is lost."""
|
|
722
|
+
self._transport.call(
|
|
723
|
+
"RestoreBackup",
|
|
724
|
+
api_pb2.RestoreBackupRequest(vm=machine_id, backup_id=backup_id),
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
|
|
664
728
|
# ── Async ────────────────────────────────────────────────────────────
|
|
665
729
|
|
|
666
730
|
|
|
@@ -673,6 +737,7 @@ class AsyncMachines(Namespace):
|
|
|
673
737
|
self.ports = AsyncPorts(transport)
|
|
674
738
|
self.proxies = AsyncProxies(transport)
|
|
675
739
|
self.checkpoints = AsyncCheckpoints(transport)
|
|
740
|
+
self.backups = AsyncBackups(transport)
|
|
676
741
|
|
|
677
742
|
async def create(
|
|
678
743
|
self,
|
|
@@ -1133,3 +1198,52 @@ class AsyncCheckpoints(Namespace):
|
|
|
1133
1198
|
"RestoreCheckpoint",
|
|
1134
1199
|
api_pb2.RestoreCheckpointRequest(vm=machine_id, name=name),
|
|
1135
1200
|
)
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
class AsyncBackups(Namespace):
|
|
1204
|
+
"""Async twin of :class:`Backups`."""
|
|
1205
|
+
|
|
1206
|
+
async def schedule_get(self, machine_id: str) -> BackupSchedule | None:
|
|
1207
|
+
resp = await self._transport.call(
|
|
1208
|
+
"GetBackupSchedule", api_pb2.GetBackupScheduleRequest(vm=machine_id)
|
|
1209
|
+
)
|
|
1210
|
+
return m.backup_schedule(resp)
|
|
1211
|
+
|
|
1212
|
+
async def schedule_set(
|
|
1213
|
+
self,
|
|
1214
|
+
machine_id: str,
|
|
1215
|
+
*,
|
|
1216
|
+
interval_secs: int | None = None,
|
|
1217
|
+
cron: str | None = None,
|
|
1218
|
+
retention_secs: int,
|
|
1219
|
+
) -> None:
|
|
1220
|
+
if (interval_secs is None) == (cron is None):
|
|
1221
|
+
raise ValueError("pass exactly one of interval_secs or cron")
|
|
1222
|
+
kind, value = ("interval", str(interval_secs)) if interval_secs is not None else ("cron", cron)
|
|
1223
|
+
await self._transport.call(
|
|
1224
|
+
"SetBackupSchedule",
|
|
1225
|
+
api_pb2.SetBackupScheduleRequest(
|
|
1226
|
+
vm=machine_id,
|
|
1227
|
+
schedule_kind=kind,
|
|
1228
|
+
schedule_value=value,
|
|
1229
|
+
retention_secs=retention_secs,
|
|
1230
|
+
),
|
|
1231
|
+
)
|
|
1232
|
+
|
|
1233
|
+
async def schedule_clear(self, machine_id: str) -> None:
|
|
1234
|
+
await self._transport.call(
|
|
1235
|
+
"ClearBackupSchedule", api_pb2.ClearBackupScheduleRequest(vm=machine_id)
|
|
1236
|
+
)
|
|
1237
|
+
|
|
1238
|
+
async def list(self, machine_id: str) -> list[Backup]:
|
|
1239
|
+
resp = await self._transport.call(
|
|
1240
|
+
"ListBackups", api_pb2.ListBackupsRequest(vm=machine_id)
|
|
1241
|
+
)
|
|
1242
|
+
return [m.backup(b) for b in resp.backups]
|
|
1243
|
+
|
|
1244
|
+
async def restore(self, machine_id: str, backup_id: str) -> None:
|
|
1245
|
+
"""Restore the machine's disk from a backup IN PLACE. Destructive."""
|
|
1246
|
+
await self._transport.call(
|
|
1247
|
+
"RestoreBackup",
|
|
1248
|
+
api_pb2.RestoreBackupRequest(vm=machine_id, backup_id=backup_id),
|
|
1249
|
+
)
|
|
@@ -480,3 +480,41 @@ def test_the_create_response_fallback_reports_networking_as_unset():
|
|
|
480
480
|
)
|
|
481
481
|
assert created.networking.networks == []
|
|
482
482
|
assert created.networking.isolated is False
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def test_backup_schedule_disabled_maps_to_none():
|
|
486
|
+
assert m.backup_schedule(api_pb2.GetBackupScheduleResponse(enabled=False)) is None
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def test_backup_schedule_enabled_maps_fields_and_last_backup_at_can_be_unset():
|
|
490
|
+
sched = m.backup_schedule(
|
|
491
|
+
api_pb2.GetBackupScheduleResponse(
|
|
492
|
+
enabled=True,
|
|
493
|
+
schedule_kind="interval",
|
|
494
|
+
schedule_value="3600",
|
|
495
|
+
retention_secs=604800,
|
|
496
|
+
next_backup_at=1_700_000_000_000,
|
|
497
|
+
last_backup_at=0,
|
|
498
|
+
)
|
|
499
|
+
)
|
|
500
|
+
assert sched is not None
|
|
501
|
+
assert sched.schedule_kind == "interval"
|
|
502
|
+
assert sched.retention_secs == 604800
|
|
503
|
+
assert sched.last_backup_at is None
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def test_backup_dedup_pointer_and_checksum_are_absent_on_a_dedup_row():
|
|
507
|
+
backup = m.backup(
|
|
508
|
+
api_pb2.BackupInfo(
|
|
509
|
+
backup_id="bkp-2",
|
|
510
|
+
status="dedup",
|
|
511
|
+
size_bytes=0,
|
|
512
|
+
checksum="",
|
|
513
|
+
points_to_backup_id="bkp-1",
|
|
514
|
+
created_at=1_700_000_000_000,
|
|
515
|
+
expires_at=1_700_600_000_000,
|
|
516
|
+
)
|
|
517
|
+
)
|
|
518
|
+
assert backup.status == "dedup"
|
|
519
|
+
assert backup.checksum is None
|
|
520
|
+
assert backup.points_to_backup_id == "bkp-1"
|
|
@@ -296,3 +296,75 @@ async def test_async_unavailable_is_retried(monkeypatch):
|
|
|
296
296
|
|
|
297
297
|
async def _no_sleep(_seconds):
|
|
298
298
|
return None
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
# --- stream wrapping (BOX-152) ---
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
class FakeStreamCall:
|
|
305
|
+
"""A sync stream call that errors mid-stream and records cancel()."""
|
|
306
|
+
|
|
307
|
+
def __init__(self, items, error=None):
|
|
308
|
+
self._items = list(items)
|
|
309
|
+
self._error = error
|
|
310
|
+
self.cancelled = False
|
|
311
|
+
|
|
312
|
+
def cancel(self):
|
|
313
|
+
self.cancelled = True
|
|
314
|
+
return True
|
|
315
|
+
|
|
316
|
+
def __iter__(self):
|
|
317
|
+
yield from self._items
|
|
318
|
+
if self._error is not None:
|
|
319
|
+
raise self._error
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class FakeAioStreamCall(FakeStreamCall):
|
|
323
|
+
async def __aiter__(self):
|
|
324
|
+
for item in self._items:
|
|
325
|
+
yield item
|
|
326
|
+
if self._error is not None:
|
|
327
|
+
raise self._error
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
async def test_async_bidi_stream_errors_surface_as_boxd_errors():
|
|
331
|
+
# The regression: before the wrap, these escaped as raw AioRpcError and
|
|
332
|
+
# blew through callers' `except BoxdError` retry loops.
|
|
333
|
+
call = FakeAioStreamCall(
|
|
334
|
+
[api_pb2.ExecChunk(data=b"out")], AioError(grpc.StatusCode.NOT_FOUND)
|
|
335
|
+
)
|
|
336
|
+
t = AsyncTransport(
|
|
337
|
+
base_url="http://localhost:9443",
|
|
338
|
+
credentials=FakeAsyncCredentials(),
|
|
339
|
+
timeout=1.0,
|
|
340
|
+
max_retries=2,
|
|
341
|
+
)
|
|
342
|
+
t._stub = FakeStub(Exec=lambda requests, timeout=None, metadata=None: call)
|
|
343
|
+
|
|
344
|
+
async def requests():
|
|
345
|
+
yield api_pb2.ExecChunk(vm_id="vm-1", command="echo hi")
|
|
346
|
+
|
|
347
|
+
stream = await t.bidi("Exec", requests())
|
|
348
|
+
got = []
|
|
349
|
+
with pytest.raises(NotFoundError):
|
|
350
|
+
async for chunk in stream:
|
|
351
|
+
got.append(chunk.data)
|
|
352
|
+
assert got == [b"out"]
|
|
353
|
+
stream.cancel()
|
|
354
|
+
assert call.cancelled
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def test_sync_bidi_cancel_reaches_the_underlying_call():
|
|
358
|
+
# ExecStream.close() cancels via getattr; the wrapper must not hide it.
|
|
359
|
+
call = FakeStreamCall([api_pb2.ExecChunk(data=b"out")])
|
|
360
|
+
t = SyncTransport(
|
|
361
|
+
base_url="http://localhost:9443",
|
|
362
|
+
credentials=FakeCredentials(),
|
|
363
|
+
timeout=1.0,
|
|
364
|
+
max_retries=2,
|
|
365
|
+
)
|
|
366
|
+
t._stub = FakeStub(Exec=lambda requests, timeout=None, metadata=None: call)
|
|
367
|
+
stream = t.bidi("Exec", iter([api_pb2.ExecChunk(vm_id="vm-1")]))
|
|
368
|
+
assert [chunk.data for chunk in stream] == [b"out"]
|
|
369
|
+
stream.cancel()
|
|
370
|
+
assert call.cancelled
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|