@@ -62,7 +62,21 @@ fn validate_label(label: &str) -> Result<()> {
6262 Ok ( ( ) )
6363}
6464
65- fn resolve_gpus ( gpu_cfg : & rpc:: GpuConfig ) -> Result < GpuConfig > {
65+ pub fn resolve_gpus_with_config (
66+ gpu_cfg : & rpc:: GpuConfig ,
67+ cvm_config : & crate :: config:: CvmConfig ,
68+ ) -> Result < GpuConfig > {
69+ if !cvm_config. gpu . enabled {
70+ bail ! ( "GPU is not enabled" ) ;
71+ }
72+ let gpus = resolve_gpus ( gpu_cfg) ?;
73+ if !cvm_config. gpu . allow_attach_all && gpus. attach_mode . is_all ( ) {
74+ bail ! ( "Attaching all GPUs is not allowed" ) ;
75+ }
76+ Ok ( gpus)
77+ }
78+
79+ pub fn resolve_gpus ( gpu_cfg : & rpc:: GpuConfig ) -> Result < GpuConfig > {
6680 // Check the attach mode to determine how to handle GPUs
6781 match gpu_cfg. attach_mode . as_str ( ) {
6882 "listed" => {
@@ -110,80 +124,84 @@ fn resolve_gpus(gpu_cfg: &rpc::GpuConfig) -> Result<GpuConfig> {
110124 }
111125}
112126
127+ // Shared function to create manifest from VM configuration
128+ pub fn create_manifest_from_vm_config (
129+ request : VmConfiguration ,
130+ cvm_config : & crate :: config:: CvmConfig ,
131+ ) -> Result < Manifest > {
132+ validate_label ( & request. name ) ?;
133+
134+ let pm_cfg = & cvm_config. port_mapping ;
135+ if !( request. ports . is_empty ( ) || pm_cfg. enabled ) {
136+ bail ! ( "Port mapping is disabled" ) ;
137+ }
138+ let port_map = request
139+ . ports
140+ . iter ( )
141+ . map ( |p| {
142+ let from = p. host_port . try_into ( ) . context ( "Invalid host port" ) ?;
143+ let to = p. vm_port . try_into ( ) . context ( "Invalid vm port" ) ?;
144+ if !pm_cfg. is_allowed ( & p. protocol , from) {
145+ bail ! ( "Port mapping is not allowed for {}:{}" , p. protocol, from) ;
146+ }
147+ let protocol = p. protocol . parse ( ) . context ( "Invalid protocol" ) ?;
148+ let address = if !p. host_address . is_empty ( ) {
149+ p. host_address . parse ( ) . context ( "Invalid host address" ) ?
150+ } else {
151+ pm_cfg. address
152+ } ;
153+ Ok ( PortMapping {
154+ address,
155+ protocol,
156+ from,
157+ to,
158+ } )
159+ } )
160+ . collect :: < Result < Vec < _ > > > ( ) ?;
161+
162+ let app_id = match & request. app_id {
163+ Some ( id) => id. strip_prefix ( "0x" ) . unwrap_or ( id) . to_lowercase ( ) ,
164+ None => app_id_of ( & request. compose_file ) ,
165+ } ;
166+ let id = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
167+ let now = SystemTime :: now ( )
168+ . duration_since ( UNIX_EPOCH )
169+ . unwrap_or_default ( )
170+ . as_millis ( ) as u64 ;
171+ let gpus = match & request. gpus {
172+ Some ( gpus) => resolve_gpus_with_config ( gpus, cvm_config) ?,
173+ None => GpuConfig :: default ( ) ,
174+ } ;
175+
176+ Ok ( Manifest :: builder ( )
177+ . id ( id)
178+ . name ( request. name . clone ( ) )
179+ . app_id ( app_id)
180+ . image ( request. image . clone ( ) )
181+ . vcpu ( request. vcpu )
182+ . memory ( request. memory )
183+ . disk_size ( request. disk_size )
184+ . port_map ( port_map)
185+ . created_at_ms ( now)
186+ . hugepages ( request. hugepages )
187+ . pin_numa ( request. pin_numa )
188+ . gpus ( gpus)
189+ . kms_urls ( request. kms_urls . clone ( ) )
190+ . gateway_urls ( request. gateway_urls . clone ( ) )
191+ . build ( ) )
192+ }
193+
113194impl RpcHandler {
114195 fn resolve_gpus ( & self , gpu_cfg : & rpc:: GpuConfig ) -> Result < GpuConfig > {
115- let gpus = resolve_gpus ( gpu_cfg) ?;
116- if !self . app . config . cvm . gpu . enabled {
117- bail ! ( "GPU is not enabled" ) ;
118- }
119- if !self . app . config . cvm . gpu . allow_attach_all && gpus. attach_mode . is_all ( ) {
120- bail ! ( "Attaching all GPUs is not allowed" ) ;
121- }
122- Ok ( gpus)
196+ resolve_gpus_with_config ( gpu_cfg, & self . app . config . cvm )
123197 }
124198}
125199
126200impl VmmRpc for RpcHandler {
127201 async fn create_vm ( self , request : VmConfiguration ) -> Result < Id > {
128- validate_label ( & request. name ) ?;
129-
130- let pm_cfg = & self . app . config . cvm . 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) => self . resolve_gpus ( gpus) ?,
169- None => GpuConfig :: default ( ) ,
170- } ;
171- let manifest = Manifest :: builder ( )
172- . id ( id. clone ( ) )
173- . name ( request. name . clone ( ) )
174- . app_id ( app_id. clone ( ) )
175- . image ( request. image . clone ( ) )
176- . vcpu ( request. vcpu )
177- . memory ( request. memory )
178- . disk_size ( request. disk_size )
179- . port_map ( port_map)
180- . created_at_ms ( now)
181- . hugepages ( request. hugepages )
182- . pin_numa ( request. pin_numa )
183- . gpus ( gpus)
184- . kms_urls ( request. kms_urls . clone ( ) )
185- . gateway_urls ( request. gateway_urls . clone ( ) )
186- . build ( ) ;
202+ let manifest = create_manifest_from_vm_config ( request. clone ( ) , & self . app . config . cvm ) ?;
203+ let id = manifest. id . clone ( ) ;
204+ let app_id = manifest. app_id . clone ( ) ;
187205 let vm_work_dir = self . app . work_dir ( & id) ;
188206 vm_work_dir
189207 . put_manifest ( & manifest)
0 commit comments