Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
73deae9
feat(instances): add StatusPaused and pause/resume to interfaces
poyrazK Apr 28, 2026
77cdfdb
feat(docker): implement PauseInstance and ResumeInstance
poyrazK Apr 28, 2026
f5f81e8
feat(libvirt): implement PauseInstance and ResumeInstance via DomainS…
poyrazK Apr 28, 2026
dccef5d
feat(stubs): add PauseInstance, ResumeInstance, and ResizeInstance to…
poyrazK Apr 28, 2026
fcadfcb
feat(services): implement PauseInstance and ResumeInstance in Instanc…
poyrazK Apr 28, 2026
418e708
feat(handlers): add POST /instances/:id/pause and /resume endpoints
poyrazK Apr 28, 2026
e154d1e
feat(router): wire /instances/:id/pause and /resume routes
poyrazK Apr 28, 2026
2bc8ba9
feat(platform): add Bulkhead concurrency limiter and enhance CircuitB…
poyrazK Apr 28, 2026
7ec9755
feat(platform): add ResilientCompute wrapper with circuit breaker and…
poyrazK Apr 28, 2026
9c3a665
test(mocks): add PauseInstance and ResumeInstance to K8s and libvirt …
poyrazK Apr 28, 2026
308184a
test(workers): add missing interface methods to worker test mocks
poyrazK Apr 28, 2026
b11d04d
fix(code-review): pre-compile regexes, add ErrNotSupported, and add p…
poyrazK Apr 28, 2026
8641b40
fix(libvirt): verify domain state before pause/resume
poyrazK Apr 28, 2026
67f17ea
fix: improve bulkhead context cancellation and resume error logging
poyrazK Apr 28, 2026
2c65645
Merge origin/main into feat/instance-pause-resume
poyrazK Apr 29, 2026
fbd671a
Merge conflict resolution: fix duplicate methods and missing implemen…
poyrazK Apr 29, 2026
64fd5dd
docs: regenerate swagger with pause/resume endpoints
poyrazK Apr 29, 2026
26f1f3c
fix: add missing PauseInstance/ResumeInstance to worker test mocks
poyrazK Apr 29, 2026
4bd1c5d
Merge origin/main into feat/instance-pause-resume
poyrazK Apr 29, 2026
b7ca0d3
fix(instances): improve error handling for pause/resume operations
poyrazK Apr 29, 2026
a999e74
docs: update API reference and feature docs for pause/resume
poyrazK Apr 29, 2026
30ef02a
test(handlers): add pause/resume endpoint tests
poyrazK Apr 29, 2026
5010b8e
fix(instances): address code review findings from PR #320
poyrazK Apr 29, 2026
d71a165
fix: address PR #320 code review findings
poyrazK Apr 30, 2026
a20a805
revert: remove compute-roadmap.md from branch
poyrazK Apr 30, 2026
e3817de
fix: address PR #320 review findings
poyrazK Apr 30, 2026
bd1bb23
fix(tests): add t.Helper() to assert closures in pause/resume test cases
poyrazK Apr 30, 2026
ff89197
fix(tests): add t.Helper() to all pause/resume assert closures
poyrazK Apr 30, 2026
7a94f6c
ci: trigger fresh build
poyrazK Apr 30, 2026
fc4869d
Merge remote-tracking branch 'origin/main' into feat/instance-pause-r…
poyrazK Apr 30, 2026
9922509
fix(tests): add PauseInstance and ResumeInstance to testComputeBackend
poyrazK Apr 30, 2026
a073124
fix(services): clarify resume failure log message
poyrazK Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ This document provides a comprehensive overview of every feature currently imple
- **Networking**: Integrated with Open vSwitch (OVS) for true SDN.

- **Backend Selection**: Set via `COMPUTE_BACKEND` environment variable (`docker` or `libvirt`).
- **Lifecycle**: The `InstanceService` manages the backend API to Create, Start, Stop, Resize, and Remove instances.
- **Lifecycle**: The `InstanceService` manages the backend API to Create, Start, Stop, Pause, Resume, Resize, and Remove instances.
- **Instance States**: Instances transition through states: `INITIALIZING` → `RUNNING` → `STOPPED` / `PAUSED` → `DELETED`. The `PAUSED` state freezes CPU while retaining memory and network connections.
- **Pause/Resume**: RUNNING instances can be paused (via `DomainSuspend` for Libvirt, `ContainerPause` for Docker) and later resumed. State transitions are validated to ensure proper ordering.
- **Instance Metadata & Labels**: Support for arbitrary key-value pairs assigned to instances for organization and filtering.
- **Cloud-Init (Docker Simulation)**: Simulates Cloud-Init configuration injection in containers (SSH keys, script execution).
- **Self-Healing**: Automated background worker that detects instances in `ERROR` state and attempts recovery via restart.
- **Resilient Compute**: Backend operations are wrapped with circuit breaker and bulkhead patterns for fault tolerance.

### 2. Networking (VPC & Elastic IPs)
**What it is**: Isolated virtual networks and static public IP addresses.
Expand Down
34 changes: 34 additions & 0 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,40 @@ Get the VNC console URL for the instance.
}
```

### POST /instances/:id/pause
Pause a running instance (freezes CPU, retains memory/network).

**Prerequisites:** Instance must be in `RUNNING` state.

**Response:**
```json
{
"message": "instance paused"
}
```

**Error Responses:**
- `400` — Instance not in RUNNING state (returned as `CONFLICT`)
- `404` — Instance not found
- `403` — Insufficient permissions

### POST /instances/:id/resume
Resume a paused instance back to running state.

**Prerequisites:** Instance must be in `PAUSED` state.

**Response:**
```json
{
"message": "instance resumed"
}
```

**Error Responses:**
- `400` — Instance not in PAUSED state (returned as `CONFLICT`)
- `404` — Instance not found
- `403` — Insufficient permissions

---

## Images
Expand Down
1 change: 1 addition & 0 deletions docs/guides/libvirt-backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ Always use virtio for best I/O performance:
| **Networking** | Bridge/overlay | NAT/bridge/macvtap |
| **Storage** | Overlay2/volumes | QCOW2/raw images |
| **Volume Attach/Detach** | Stop→recreate→start cycle | True hot-plug via DomainAttachDevice |
| **Pause/Resume** | ContainerPause/Unpause | DomainSuspend/DomainResume |
| **Use Cases** | Microservices, CI/CD | Legacy apps, multi-OS, security |

## Best Practices
Expand Down
142 changes: 142 additions & 0 deletions docs/swagger/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3974,6 +3974,76 @@ const docTemplate = `{
}
}
},
"/instances/{id}/pause": {
"post": {
"security": [
{
"APIKeyAuth": []
}
],
"description": "Freezes a running instance (CPU halted, memory/network retained)",
"produces": [
"application/json"
],
"tags": [
"instances"
],
"summary": "Pause an instance",
"parameters": [
{
"type": "string",
"description": "Instance ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"409": {
"description": "Instance not in RUNNING state",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
}
}
}
},
"/instances/{id}/resize": {
"post": {
"security": [
Expand Down Expand Up @@ -4044,6 +4114,76 @@ const docTemplate = `{
}
}
},
"/instances/{id}/resume": {
"post": {
"security": [
{
"APIKeyAuth": []
}
],
"description": "Resumes a paused instance back to running state",
"produces": [
"application/json"
],
"tags": [
"instances"
],
"summary": "Resume an instance",
"parameters": [
{
"type": "string",
"description": "Instance ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"409": {
"description": "Instance not in PAUSED state",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/httputil.Response"
}
}
}
}
},
"/instances/{id}/stats": {
"get": {
"security": [
Expand Down Expand Up @@ -8934,13 +9074,15 @@ const docTemplate = `{
"RUNNING",
"STOPPED",
"ERROR",
"PAUSED",
"DELETED"
],
"x-enum-varnames": [
"StatusStarting",
"StatusRunning",
"StatusStopped",
"StatusError",
"StatusPaused",
"StatusDeleted"
]
},
Expand Down
Loading
Loading