@@ -58,7 +58,21 @@ fn validate_label(label: &str) -> Result<()> {
5858 Ok ( ( ) )
5959}
6060
61- fn resolve_gpus ( gpu_cfg : & rpc:: GpuConfig ) -> Result < GpuConfig > {
61+ pub fn resolve_gpus_with_config (
62+ gpu_cfg : & rpc:: GpuConfig ,
63+ cvm_config : & crate :: config:: CvmConfig ,
64+ ) -> Result < GpuConfig > {
65+ if !cvm_config. gpu . enabled {
66+ bail ! ( "GPU is not enabled" ) ;
67+ }
68+ let gpus = resolve_gpus ( gpu_cfg) ?;
69+ if !cvm_config. gpu . allow_attach_all && gpus. attach_mode . is_all ( ) {
70+ bail ! ( "Attaching all GPUs is not allowed" ) ;
71+ }
72+ Ok ( gpus)
73+ }
74+
75+ pub fn resolve_gpus ( gpu_cfg : & rpc:: GpuConfig ) -> Result < GpuConfig > {
6276 // Check the attach mode to determine how to handle GPUs
6377 match gpu_cfg. attach_mode . as_str ( ) {
6478 "listed" => {
@@ -106,80 +120,84 @@ fn resolve_gpus(gpu_cfg: &rpc::GpuConfig) -> Result<GpuConfig> {
106120 }
107121}
108122
123+ // Shared function to create manifest from VM configuration
124+ pub fn create_manifest_from_vm_config (
125+ request : VmConfiguration ,
126+ cvm_config : & crate :: config:: CvmConfig ,
127+ ) -> Result < Manifest > {
128+ validate_label ( & request. name ) ?;
129+
130+ let pm_cfg = & cvm_config. port_mapping ;
131+ if !( request. ports . is_empty ( ) || pm_cfg. enabled ) {
132+ bail ! ( "Port mapping is disabled" ) ;
133+ }
134+ let port_map = request
135+ . ports
136+ . iter ( )
137+ . map ( |p| {
138+ let from = p. host_port . try_into ( ) . context ( "Invalid host port" ) ?;
139+ let to = p. vm_port . try_into ( ) . context ( "Invalid vm port" ) ?;
140+ if !pm_cfg. is_allowed ( & p. protocol , from) {
141+ bail ! ( "Port mapping is not allowed for {}:{}" , p. protocol, from) ;
142+ }
143+ let protocol = p. protocol . parse ( ) . context ( "Invalid protocol" ) ?;
144+ let address = if !p. host_address . is_empty ( ) {
145+ p. host_address . parse ( ) . context ( "Invalid host address" ) ?
146+ } else {
147+ pm_cfg. address
148+ } ;
149+ Ok ( PortMapping {
150+ address,
151+ protocol,
152+ from,
153+ to,
154+ } )
155+ } )
156+ . collect :: < Result < Vec < _ > > > ( ) ?;
157+
158+ let app_id = match & request. app_id {
159+ Some ( id) => id. strip_prefix ( "0x" ) . unwrap_or ( id) . to_lowercase ( ) ,
160+ None => app_id_of ( & request. compose_file ) ,
161+ } ;
162+ let id = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
163+ let now = SystemTime :: now ( )
164+ . duration_since ( UNIX_EPOCH )
165+ . unwrap_or_default ( )
166+ . as_millis ( ) as u64 ;
167+ let gpus = match & request. gpus {
168+ Some ( gpus) => resolve_gpus_with_config ( gpus, cvm_config) ?,
169+ None => GpuConfig :: default ( ) ,
170+ } ;
171+
172+ Ok ( Manifest :: builder ( )
173+ . id ( id)
174+ . name ( request. name . clone ( ) )
175+ . app_id ( app_id)
176+ . image ( request. image . clone ( ) )
177+ . vcpu ( request. vcpu )
178+ . memory ( request. memory )
179+ . disk_size ( request. disk_size )
180+ . port_map ( port_map)
181+ . created_at_ms ( now)
182+ . hugepages ( request. hugepages )
183+ . pin_numa ( request. pin_numa )
184+ . gpus ( gpus)
185+ . kms_urls ( request. kms_urls . clone ( ) )
186+ . gateway_urls ( request. gateway_urls . clone ( ) )
187+ . build ( ) )
188+ }
189+
109190impl RpcHandler {
110191 fn resolve_gpus ( & self , gpu_cfg : & rpc:: GpuConfig ) -> Result < GpuConfig > {
111- let gpus = resolve_gpus ( gpu_cfg) ?;
112- if !self . app . config . cvm . gpu . enabled {
113- bail ! ( "GPU is not enabled" ) ;
114- }
115- if !self . app . config . cvm . gpu . allow_attach_all && gpus. attach_mode . is_all ( ) {
116- bail ! ( "Attaching all GPUs is not allowed" ) ;
117- }
118- Ok ( gpus)
192+ resolve_gpus_with_config ( gpu_cfg, & self . app . config . cvm )
119193 }
120194}
121195
122196impl VmmRpc for RpcHandler {
123197 async fn create_vm ( self , request : VmConfiguration ) -> Result < Id > {
124- validate_label ( & request. name ) ?;
125-
126- let pm_cfg = & self . app . config . cvm . port_mapping ;
127- if !( request. ports . is_empty ( ) || pm_cfg. enabled ) {
128- bail ! ( "Port mapping is disabled" ) ;
129- }
130- let port_map = request
131- . ports
132- . iter ( )
133- . map ( |p| {
134- let from = p. host_port . try_into ( ) . context ( "Invalid host port" ) ?;
135- let to = p. vm_port . try_into ( ) . context ( "Invalid vm port" ) ?;
136- if !pm_cfg. is_allowed ( & p. protocol , from) {
137- bail ! ( "Port mapping is not allowed for {}:{}" , p. protocol, from) ;
138- }
139- let protocol = p. protocol . parse ( ) . context ( "Invalid protocol" ) ?;
140- let address = if !p. host_address . is_empty ( ) {
141- p. host_address . parse ( ) . context ( "Invalid host address" ) ?
142- } else {
143- pm_cfg. address
144- } ;
145- Ok ( PortMapping {
146- address,
147- protocol,
148- from,
149- to,
150- } )
151- } )
152- . collect :: < Result < Vec < _ > > > ( ) ?;
153-
154- let app_id = match & request. app_id {
155- Some ( id) => id. strip_prefix ( "0x" ) . unwrap_or ( id) . to_lowercase ( ) ,
156- None => app_id_of ( & request. compose_file ) ,
157- } ;
158- let id = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
159- let now = SystemTime :: now ( )
160- . duration_since ( UNIX_EPOCH )
161- . unwrap_or_default ( )
162- . as_millis ( ) as u64 ;
163- let gpus = match & request. gpus {
164- Some ( gpus) => self . resolve_gpus ( gpus) ?,
165- None => GpuConfig :: default ( ) ,
166- } ;
167- let manifest = Manifest :: builder ( )
168- . id ( id. clone ( ) )
169- . name ( request. name . clone ( ) )
170- . app_id ( app_id. clone ( ) )
171- . image ( request. image . clone ( ) )
172- . vcpu ( request. vcpu )
173- . memory ( request. memory )
174- . disk_size ( request. disk_size )
175- . port_map ( port_map)
176- . created_at_ms ( now)
177- . hugepages ( request. hugepages )
178- . pin_numa ( request. pin_numa )
179- . gpus ( gpus)
180- . kms_urls ( request. kms_urls . clone ( ) )
181- . gateway_urls ( request. gateway_urls . clone ( ) )
182- . build ( ) ;
198+ let manifest = create_manifest_from_vm_config ( request. clone ( ) , & self . app . config . cvm ) ?;
199+ let id = manifest. id . clone ( ) ;
200+ let app_id = manifest. app_id . clone ( ) ;
183201 let vm_work_dir = self . app . work_dir ( & id) ;
184202 vm_work_dir
185203 . put_manifest ( & manifest)
0 commit comments