diff --git a/cmd/api/api/instances.go b/cmd/api/api/instances.go index 1507eb96..84c8970d 100644 --- a/cmd/api/api/instances.go +++ b/cmd/api/api/instances.go @@ -111,6 +111,11 @@ func (s *ApiService) CreateInstance(ctx context.Context, request oapi.CreateInst env = *request.Body.Env } + metadata := make(map[string]string) + if request.Body.Metadata != nil { + metadata = *request.Body.Metadata + } + // Parse network enabled (default: true) networkEnabled := true if request.Body.Network != nil && request.Body.Network.Enabled != nil { @@ -216,6 +221,7 @@ func (s *ApiService) CreateInstance(ctx context.Context, request oapi.CreateInst NetworkBandwidthDownload: networkBandwidthDownload, NetworkBandwidthUpload: networkBandwidthUpload, Env: env, + Metadata: metadata, NetworkEnabled: networkEnabled, Devices: deviceRefs, Volumes: volumes, @@ -666,6 +672,10 @@ func instanceToOAPI(inst instances.Instance) oapi.Instance { oapiInst.Env = &inst.Env } + if len(inst.Metadata) > 0 { + oapiInst.Metadata = &inst.Metadata + } + // Convert volume attachments if len(inst.Volumes) > 0 { oapiVolumes := make([]oapi.VolumeMount, len(inst.Volumes)) diff --git a/lib/instances/create.go b/lib/instances/create.go index 3ae8c719..f778c819 100644 --- a/lib/instances/create.go +++ b/lib/instances/create.go @@ -192,6 +192,9 @@ func (m *manager) createInstance( if req.Env == nil { req.Env = make(map[string]string) } + if req.Metadata == nil { + req.Metadata = make(map[string]string) + } // 7. Determine network based on NetworkEnabled flag networkName := "" @@ -298,6 +301,7 @@ func (m *manager) createInstance( NetworkBandwidthUpload: req.NetworkBandwidthUpload, // Will be set by caller if using resource manager DiskIOBps: req.DiskIOBps, // Will be set by caller if using resource manager Env: req.Env, + Metadata: req.Metadata, NetworkEnabled: req.NetworkEnabled, CreatedAt: time.Now(), StartedAt: nil, diff --git a/lib/instances/types.go b/lib/instances/types.go index 3f5f16ac..04802ee6 100644 --- a/lib/instances/types.go +++ b/lib/instances/types.go @@ -46,9 +46,10 @@ type StoredMetadata struct { // Configuration Env map[string]string - NetworkEnabled bool // Whether instance has networking enabled (uses default network) - IP string // Assigned IP address (empty if NetworkEnabled=false) - MAC string // Assigned MAC address (empty if NetworkEnabled=false) + Metadata map[string]string // User-defined key-value metadata + NetworkEnabled bool // Whether instance has networking enabled (uses default network) + IP string // Assigned IP address (empty if NetworkEnabled=false) + MAC string // Assigned MAC address (empty if NetworkEnabled=false) // Attached volumes Volumes []VolumeAttachment // Volumes attached to this instance @@ -106,6 +107,7 @@ type CreateInstanceRequest struct { NetworkBandwidthUpload int64 // Upload rate limit bytes/sec (0 = auto, proportional to CPU) DiskIOBps int64 // Disk I/O rate limit bytes/sec (0 = auto, proportional to CPU) Env map[string]string // Optional environment variables + Metadata map[string]string // Optional user-defined key-value metadata NetworkEnabled bool // Whether to enable networking (uses default network) Devices []string // Device IDs or names to attach (GPU passthrough) Volumes []VolumeAttachment // Volumes to attach at creation time diff --git a/lib/oapi/oapi.go b/lib/oapi/oapi.go index 4171b96e..964aaad1 100644 --- a/lib/oapi/oapi.go +++ b/lib/oapi/oapi.go @@ -246,6 +246,9 @@ type CreateInstanceRequest struct { // Image OCI image reference Image string `json:"image"` + // Metadata User-defined key-value metadata + Metadata *map[string]string `json:"metadata,omitempty"` + // Name Human-readable name (lowercase letters, digits, and dashes only; cannot start or end with a dash) Name string `json:"name"` @@ -492,6 +495,9 @@ type Instance struct { // Image OCI image reference Image string `json:"image"` + // Metadata User-defined key-value metadata + Metadata *map[string]string `json:"metadata,omitempty"` + // Name Human-readable name Name string `json:"name"` diff --git a/openapi.yaml b/openapi.yaml index bc20590f..cac8491f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -144,6 +144,14 @@ components: example: PORT: "3000" NODE_ENV: production + metadata: + type: object + additionalProperties: + type: string + description: User-defined key-value metadata for the instance + example: + team: backend + purpose: staging network: type: object description: Network configuration for the instance @@ -227,6 +235,11 @@ components: additionalProperties: type: string description: Environment variables + metadata: + type: object + additionalProperties: + type: string + description: User-defined key-value metadata network: type: object description: Network configuration of the instance