Repository navigation
Expand file tree
/
Copy pathinstance.go
More file actions
326 lines (267 loc) · 13.9 KB
/
Copy pathinstance.go
File metadata and controls
326 lines (267 loc) · 13.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
package v1alpha1
import (
core "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// Instance is the schema for worker.gpustack.ai.
//
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:crd-gen:resource:scope="Namespaced",subResources=["status"]
type Instance struct {
meta.TypeMeta `json:",inline"`
meta.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Spec InstanceSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
Status InstanceStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
var _ runtime.Object = (*Instance)(nil)
// InstanceSpec defines the desired state of Instance.
type InstanceSpec struct {
// DisplayName is the display name of the Instance.
//
// +k8s:validation:maxLength=64
DisplayName string `json:"displayName,omitempty" protobuf:"bytes,1,opt,name=displayName"`
// Description is the description of the Instance.
//
// +k8s:validation:maxLength=1024
Description string `json:"description,omitempty" protobuf:"bytes,2,opt,name=description"`
// Type is the name of InstanceType that provisions corresponding resources.
//
// Immutable after creation.
//
// +required
Type string `json:"type" protobuf:"bytes,3,name=type"`
// InstanceTemplate is the template for the Instance to run.
//
// Immutable after creation.
InstanceTemplate `json:",inline" protobuf:"bytes,4,name=instanceTemplate"`
// Volume is the volume to mount in the Instance.
//
// Immutable after creation.
//
// +required
Volume InstanceVolume `json:"volume,omitempty" protobuf:"bytes,5,opt,name=volume"`
// SSHPublicKey is the reference to the InstanceSSHPublicKey that contains the SSH public key to access the Instance.
//
// Immutable after creation.
SSHPublicKey *core.LocalObjectReference `json:"sshPublicKey,omitempty" protobuf:"bytes,6,opt,name=sshPublicKey"`
// Stop indicates whether to stop the Instance after it is created.
Stop bool `json:"stop,omitempty" protobuf:"varint,7,opt,name=stop"`
// NodeName pins the Instance to one Kubernetes Node, which must exist when the Instance is
// created. It is rendered as the backing Pod's nodeSelector on kubernetes.io/hostname, never
// as the Pod's own nodeName, so the scheduler and Kueue admission still mediate placement.
// Nothing beyond the node's existence is validated, so a node that cannot serve the referenced
// InstanceType leaves the Pod Pending rather than being refused. Empty means no pinning.
//
// Immutable unless the Instance is stopped.
//
// +k8s:validation:maxLength=253
NodeName string `json:"nodeName,omitempty" protobuf:"bytes,8,opt,name=nodeName"`
}
// InstanceTemplate defines the template for the Instance to run.
type InstanceTemplate struct {
// Image is the container image to run.
//
// +required
Image string `json:"image" protobuf:"bytes,1,name=image"`
// ImagePullPolicy is the image pull policy to use.
//
// +default="IfNotPresent"
// +k8s:validation:enum=["Always","IfNotPresent","Never"]
ImagePullPolicy core.PullPolicy `json:"imagePullPolicy,omitempty" protobuf:"bytes,2,name=imagePullPolicy"`
// Command is the command to run in the Instance,
// which should overwrite the default command in the container image CMD.
//
// +listType=atomic
Command []string `json:"command,omitempty" protobuf:"bytes,3,rep,name=command"`
// Privileged indicates whether the container should run in privileged mode.
//
// +k8s:validation:default=false
Privileged bool `json:"privileged,omitempty" protobuf:"bytes,4,opt,name=privileged"`
// Ports is the list of ports to expose from the Instance.
//
// +patchMergeKey=port
// +patchStrategy=merge
// +listType=map
// +listMapKey=port
// +listMapKey=protocol
Ports []InstancePort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"port" protobuf:"bytes,5,rep,name=ports"`
// Env is the list of environment variables to set in the Instance.
//
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
Env []InstanceEnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=env"`
// Resources is the resource requirements for the Instance.
Resources *InstanceResources `json:"resources,omitempty" protobuf:"bytes,7,opt,name=resources"`
// VolumeMount is a path to mount the volume in the Instance.
//
// +default="/workspace"
// +k8s:validation:pattern="^(/[^/]+)+$"
// +k8s:validation:maxLength=1024
VolumeMount string `json:"volumeMount,omitempty" protobuf:"bytes,8,opt,name=volumeMount"`
// ImagePullSecret is the reference to the InstanceImagePullSecret that contains the credentials to pull the container image.
ImagePullSecret *core.LocalObjectReference `json:"imagePullSecret,omitempty" protobuf:"bytes,9,opt,name=imagePullSecret"`
// AdditionalVolumes is the list of volumes to mount in the Instance besides its workspace,
// each at a path of its own. They are mounted into the Instance's main container only, which
// the SSH server also observes.
//
// Immutable unless the Instance is stopped.
//
// +listType=atomic
AdditionalVolumes []InstanceAdditionalVolume `json:"additionalVolumes,omitempty" protobuf:"bytes,10,rep,name=additionalVolumes"` // nolint: lll
}
// InstanceAdditionalVolume defines one volume to mount in the Instance besides its workspace.
// Exactly one source must be specified.
type InstanceAdditionalVolume struct {
// MountPath is the absolute in-container path to mount the volume at. It must not duplicate
// another entry's path, nor the workspace's VolumeMount.
//
// +required
// +k8s:validation:pattern="^(/[^/]+)+$"
// +k8s:validation:maxLength=1024
MountPath string `json:"mountPath" protobuf:"bytes,1,name=mountPath"`
// ReadOnly mounts the volume read-only.
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,2,opt,name=readOnly"`
// SubPath mounts a relative path inside the volume rather than its root.
// It must not be absolute nor contain a ".." element.
//
// +k8s:validation:maxLength=1024
SubPath string `json:"subPath,omitempty" protobuf:"bytes,3,opt,name=subPath"`
// Persistent is the reference to the InstancePersistentVolume to mount, in the same namespace.
Persistent *core.LocalObjectReference `json:"persistent,omitempty" protobuf:"bytes,4,opt,name=persistent"`
// ConfigMap is the reference to the ConfigMap to mount, in the same namespace.
ConfigMap *core.LocalObjectReference `json:"configMap,omitempty" protobuf:"bytes,5,opt,name=configMap"`
// Secret is the reference to the Secret to mount, in the same namespace.
Secret *core.LocalObjectReference `json:"secret,omitempty" protobuf:"bytes,6,opt,name=secret"`
// HostPath is the path on the Kubernetes Node to mount. It crosses the node boundary, so
// taking it requires the instance-host-path-volume-allowed Setting — at creation, and on any
// later change that adds or widens such a mount. One the Instance already holds is never
// re-judged, so the Setting going off does not strand it.
HostPath *core.HostPathVolumeSource `json:"hostPath,omitempty" protobuf:"bytes,7,opt,name=hostPath"`
// Model mounts the weights of a ModelArtifact in the same namespace. It is always mounted
// read-only, whatever ReadOnly says, and takes no SubPath: the artifact's own path is the
// sub-path. Only an artifact on a PersistentVolumeClaim is accepted in this version; one on a
// model hub needs node delivery, which does not exist yet.
Model *InstanceModelVolumeSource `json:"model,omitempty" protobuf:"bytes,8,opt,name=model"`
}
// InstanceModelVolumeSource references the ModelArtifact an Instance volume mounts.
type InstanceModelVolumeSource struct {
// ArtifactRef names a ModelArtifact in the Instance's namespace.
//
// +required
ArtifactRef core.LocalObjectReference `json:"artifactRef" protobuf:"bytes,1,name=artifactRef"`
}
// InstancePort defines the port to expose from the Instance.
type InstancePort struct {
// Port is the port number to expose on the Instance.
Port int32 `json:"port" protobuf:"varint,1,name=port"`
// Protocol is the protocol to use for the port.
//
// +k8s:validation:enum=["TCP","UDP","SCTP"]
// +k8s:validation:default="TCP"
Protocol core.Protocol `json:"protocol,omitempty" protobuf:"bytes,2,opt,name=protocol"`
// Name is the name of the port.
//
// +k8s:validation:maxLength=16
Name string `json:"name,omitempty" protobuf:"bytes,3,opt,name=name"`
}
// InstanceEnvVar defines the environment variable to set in the Instance.
type InstanceEnvVar struct {
// Name is the name of the environment variable,
// each name in one Instance must be unique.
Name string `json:"name" protobuf:"bytes,1,name=name"`
// Value is the value of the environment variable.
Value string `json:"value" protobuf:"bytes,2,name=value"`
}
// InstanceResources defines the resource requirements for the Instance.
type InstanceResources struct {
// CPU is the CPU resource requirement for the Instance, e.g. "4", "8".
//
// +required
CPU resource.Quantity `json:"cpu" protobuf:"bytes,1,name=cpu"`
// RAM is the RAM resource requirement for the Instance, e.g. "40G", "16G".
//
// +required
RAM resource.Quantity `json:"ram" protobuf:"bytes,2,name=ram"`
// LocalStorage is the local storage resource requirement for the Instance, e.g. "100G", "500G".
//
// +required
LocalStorage resource.Quantity `json:"localStorage" protobuf:"bytes,3,name=localStorage"`
// Accelerator is the accelerator resource requirement for the Instance, e.g. "1", "2".
Accelerator *resource.Quantity `json:"accelerator,omitempty" protobuf:"bytes,4,opt,name=accelerator"`
// AcceleratorSlicedMemoryPercentage is the per-accelerator VRAM budget requested on a
// sliced InstanceType, as a percentage in [0,100]. 0 disables slicing (the request
// becomes an exclusive whole-accelerator request). The Pod webhook folds it into the
// normalized .sliced.units; it is ignored by non-sliced requests.
//
// +optional
AcceleratorSlicedMemoryPercentage int32 `json:"acceleratorSlicedMemoryPercentage,omitempty" protobuf:"varint,5,opt,name=acceleratorSlicedMemoryPercentage"` // nolint: lll
// AcceleratorSlicedCoresPercentage is the per-accelerator compute (SM) budget requested on
// a sliced InstanceType, as a percentage in [0,100]. It is independent of
// AcceleratorSlicedMemoryPercentage; when only one of the two is set the webhook
// copies it to the other. It is ignored by non-sliced requests.
//
// +optional
AcceleratorSlicedCoresPercentage int32 `json:"acceleratorSlicedCoresPercentage,omitempty" protobuf:"varint,6,opt,name=acceleratorSlicedCoresPercentage"` // nolint: lll
// AcceleratorPartitionedProfile is the hardware partition profile requested on a
// partition-offering InstanceType, e.g. "3g.40gb". A non-empty value makes this a
// request for one hardware partition of that shape, which is mutually exclusive with
// the two slice percentages above: hardware partitioning and software slicing cannot
// both apply to one accelerator. It is ignored by InstanceTypes offering no partition.
//
// +optional
AcceleratorPartitionedProfile string `json:"acceleratorPartitionedProfile,omitempty" protobuf:"bytes,7,opt,name=acceleratorPartitionedProfile"` // nolint: lll
}
// InstanceVolume defines the volume to mount in the Instance,
// which can be either ephemeral or persistent.
type InstanceVolume struct {
// Ephemeral is the ephemeral volume to mount in the Instance.
Ephemeral *InstanceEphemeralVolume `json:"ephemeral,omitempty" protobuf:"bytes,1,opt,name=ephemeral"`
// Persistent is the reference to the InstancePersistentVolume to mount in the Instance.
Persistent *core.LocalObjectReference `json:"persistent,omitempty" protobuf:"bytes,2,opt,name=persistent"`
}
// InstanceEphemeralVolume defines the ephemeral volume to mount in the Instance.
type InstanceEphemeralVolume struct {
// Capacity is the size limit of the volume.
//
// +required
Capacity resource.Quantity `json:"capacity" protobuf:"bytes,1,name=capacity"`
}
// InstanceStatus defines the observed state of Instance.
type InstanceStatus struct {
// Phase is the current phase of the Instance.
Phase string `json:"phase,omitempty" protobuf:"bytes,1,name=phase"`
// PhaseMessage is the message to describe the current phase of the Instance.
PhaseMessage string `json:"phaseMessage,omitempty" protobuf:"bytes,2,opt,name=phaseMessage"`
// NodeName is the name of the Kubernetes Node that the Instance is running on.
NodeName string `json:"nodeName,omitempty" protobuf:"bytes,3,opt,name=nodeName"`
// AccessAddresses holds the accessible addresses allocated to the Instance.
AccessAddresses []string `json:"accessAddresses,omitempty" protobuf:"bytes,4,rep,name=accessAddresses"`
// HostIPs holds the IP addresses allocated to the host.
HostIPs []core.HostIP `json:"hostIPs,omitempty" protobuf:"bytes,5,rep,name=hostIPs"`
// PodIPs holds the IP addresses allocated to the Kubernetes Pod that related to the Instance.
PodIPs []core.PodIP `json:"podIPs,omitempty" protobuf:"bytes,6,rep,name=podIPs"`
// Ports is the list of ports to expose from the Instance.
Ports []InstanceServicePort `json:"ports,omitempty" protobuf:"bytes,7,rep,name=ports"`
// Allocations is the list of devices allocated to the Instance.
Allocations []DevicesAllocationGroup `json:"allocations,omitempty" protobuf:"bytes,8,rep,name=allocations"`
}
// InstanceServicePort defines the port to expose from the container and the port to expose on the node.
type InstanceServicePort struct {
InstancePort `json:",inline" protobuf:"bytes,1,name=instancePort"`
// NodePort is the port number to expose on the Kubernetes Node.
NodePort int32 `json:"nodePort,omitempty" protobuf:"varint,2,opt,name=nodePort"`
}
// InstanceList holds the list of Instance.
//
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type InstanceList struct {
meta.TypeMeta `json:",inline"`
meta.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []Instance `json:"items" protobuf:"bytes,2,rep,name=items"`
}
var _ runtime.Object = (*InstanceList)(nil)