@@ -8,7 +8,7 @@ use anyhow::{bail, Context, Result};
88use bon:: Builder ;
99use dstack_kms_rpc:: kms_client:: KmsClient ;
1010use dstack_types:: shared_filenames:: {
11- compat_v3 , APP_COMPOSE , ENCRYPTED_ENV , INSTANCE_INFO , SYS_CONFIG , USER_CONFIG ,
11+ APP_COMPOSE , ENCRYPTED_ENV , INSTANCE_INFO , SYS_CONFIG , USER_CONFIG ,
1212} ;
1313use dstack_vmm_rpc:: { self as pb, GpuInfo , StatusRequest , StatusResponse , VmConfiguration } ;
1414use fs_err as fs;
@@ -489,119 +489,9 @@ impl App {
489489 let shared_dir = self . shared_dir ( id) ;
490490 let manifest = work_dir. manifest ( ) . context ( "Failed to read manifest" ) ?;
491491 let cfg = & self . config ;
492- let image_path = cfg. image_path . join ( & manifest. image ) ;
493- let image = Image :: load ( image_path) . context ( "Failed to load image info" ) ?;
494- let img_ver = image. info . version_tuple ( ) . unwrap_or ( ( 0 , 0 , 0 ) ) ;
495- let kms_urls = if manifest. kms_urls . is_empty ( ) {
496- cfg. cvm . kms_urls . clone ( )
497- } else {
498- manifest. kms_urls . clone ( )
499- } ;
500- let gateway_urls = if manifest. gateway_urls . is_empty ( ) {
501- cfg. cvm . gateway_urls . clone ( )
502- } else {
503- manifest. gateway_urls . clone ( )
504- } ;
505- let sys_config = if img_ver >= ( 0 , 5 , 0 ) {
506- let os_image_hash = hex:: decode ( image. digest . unwrap_or_default ( ) )
507- . context ( "Failed to decode image digest" ) ?;
508- let gpus = manifest. gpus . unwrap_or_default ( ) ;
509- let vm_config = serde_json:: to_string ( & dstack_types:: VmConfig {
510- spec_version : 1 ,
511- os_image_hash,
512- cpu_count : manifest. vcpu ,
513- memory_size : manifest. memory as u64 * 1024 * 1024 ,
514- qemu_single_pass_add_pages : cfg. cvm . qemu_single_pass_add_pages ,
515- pic : cfg. cvm . qemu_pic ,
516- qemu_version : cfg. cvm . qemu_version . clone ( ) ,
517- pci_hole64_size : cfg. cvm . qemu_pci_hole64_size ,
518- hugepages : manifest. hugepages ,
519- num_gpus : gpus. gpus . len ( ) as u32 ,
520- num_nvswitches : gpus. bridges . len ( ) as u32 ,
521- hotplug_off : cfg. cvm . qemu_hotplug_off ,
522- image : Some ( manifest. image . clone ( ) ) ,
523- } ) ?;
524- json ! ( {
525- "kms_urls" : kms_urls,
526- "gateway_urls" : gateway_urls,
527- "pccs_url" : cfg. cvm. pccs_url,
528- "docker_registry" : cfg. cvm. docker_registry,
529- "host_api_url" : format!( "vsock://2:{}/api" , cfg. host_api. port) ,
530- "vm_config" : vm_config,
531- } )
532- } else if img_ver >= ( 0 , 4 , 2 ) {
533- json ! ( {
534- "kms_urls" : kms_urls,
535- "gateway_urls" : gateway_urls,
536- "pccs_url" : cfg. cvm. pccs_url,
537- "docker_registry" : cfg. cvm. docker_registry,
538- "host_api_url" : format!( "vsock://2:{}/api" , cfg. host_api. port) ,
539- } )
540- } else if img_ver >= ( 0 , 4 , 0 ) {
541- let rootfs_hash = image
542- . info
543- . rootfs_hash
544- . as_ref ( )
545- . context ( "Rootfs hash not found in image info" ) ?;
546- json ! ( {
547- "rootfs_hash" : rootfs_hash,
548- "kms_urls" : kms_urls,
549- "tproxy_urls" : gateway_urls,
550- "pccs_url" : cfg. cvm. pccs_url,
551- "docker_registry" : cfg. cvm. docker_registry,
552- "host_api_url" : format!( "vsock://2:{}/api" , cfg. host_api. port) ,
553- } )
554- } else {
555- let rootfs_hash = image
556- . info
557- . rootfs_hash
558- . as_ref ( )
559- . context ( "Rootfs hash not found in image info" ) ?;
560- json ! ( {
561- "rootfs_hash" : rootfs_hash,
562- "kms_url" : kms_urls. first( ) ,
563- "tproxy_url" : gateway_urls. first( ) ,
564- "pccs_url" : cfg. cvm. pccs_url,
565- "docker_registry" : cfg. cvm. docker_registry,
566- "host_api_url" : format!( "vsock://2:{}/api" , cfg. host_api. port) ,
567- } )
568- } ;
569- let sys_config_str =
570- serde_json:: to_string ( & sys_config) . context ( "Failed to serialize vm config" ) ?;
571- let config_file = if img_ver >= ( 0 , 4 , 0 ) {
572- SYS_CONFIG
573- } else {
574- compat_v3:: SYS_CONFIG
575- } ;
576- fs:: write ( shared_dir. join ( config_file) , sys_config_str)
492+ let sys_config_str = make_sys_config ( cfg, & manifest) ?;
493+ fs:: write ( shared_dir. join ( SYS_CONFIG ) , sys_config_str)
577494 . context ( "Failed to write vm config" ) ?;
578- if img_ver < ( 0 , 4 , 0 ) {
579- // Sync .encrypted-env to encrypted-env
580- let compat_encrypted_env_path = shared_dir. join ( compat_v3:: ENCRYPTED_ENV ) ;
581- let encrypted_env_path = shared_dir. join ( ENCRYPTED_ENV ) ;
582- if compat_encrypted_env_path. exists ( ) {
583- fs:: remove_file ( & compat_encrypted_env_path) ?;
584- }
585- if encrypted_env_path. exists ( ) {
586- fs:: copy ( & encrypted_env_path, & compat_encrypted_env_path) ?;
587- }
588-
589- // Sync certs
590- let certs_dir = shared_dir. join ( "certs" ) ;
591- fs:: create_dir_all ( & certs_dir) . context ( "Failed to create certs directory" ) ?;
592- if cfg. cvm . ca_cert . is_empty ( )
593- || cfg. cvm . tmp_ca_cert . is_empty ( )
594- || cfg. cvm . tmp_ca_key . is_empty ( )
595- {
596- bail ! ( "Certificates are required for older images" ) ;
597- }
598- fs:: copy ( & cfg. cvm . ca_cert , certs_dir. join ( "ca.cert" ) )
599- . context ( "Failed to copy ca cert" ) ?;
600- fs:: copy ( & cfg. cvm . tmp_ca_cert , certs_dir. join ( "tmp-ca.cert" ) )
601- . context ( "Failed to copy tmp ca cert" ) ?;
602- fs:: copy ( & cfg. cvm . tmp_ca_key , certs_dir. join ( "tmp-ca.key" ) )
603- . context ( "Failed to copy tmp ca key" ) ?;
604- }
605495 Ok ( ( ) )
606496 }
607497
@@ -676,6 +566,61 @@ impl App {
676566 }
677567}
678568
569+ pub ( crate ) fn make_sys_config ( cfg : & Config , manifest : & Manifest ) -> Result < String > {
570+ let image_path = cfg. image_path . join ( & manifest. image ) ;
571+ let image = Image :: load ( image_path) . context ( "Failed to load image info" ) ?;
572+ let img_ver = image. info . version_tuple ( ) . unwrap_or ( ( 0 , 0 , 0 ) ) ;
573+ let kms_urls = if manifest. kms_urls . is_empty ( ) {
574+ cfg. cvm . kms_urls . clone ( )
575+ } else {
576+ manifest. kms_urls . clone ( )
577+ } ;
578+ let gateway_urls = if manifest. gateway_urls . is_empty ( ) {
579+ cfg. cvm . gateway_urls . clone ( )
580+ } else {
581+ manifest. gateway_urls . clone ( )
582+ } ;
583+ if img_ver < ( 0 , 5 , 0 ) {
584+ bail ! ( "Unsupported image version: {img_ver:?}" ) ;
585+ }
586+
587+ let sys_config = json ! ( {
588+ "kms_urls" : kms_urls,
589+ "gateway_urls" : gateway_urls,
590+ "pccs_url" : cfg. cvm. pccs_url,
591+ "docker_registry" : cfg. cvm. docker_registry,
592+ "host_api_url" : format!( "vsock://2:{}/api" , cfg. host_api. port) ,
593+ "vm_config" : serde_json:: to_string( & make_vm_config( cfg, manifest, & image) ) ?,
594+ } ) ;
595+ let sys_config_str =
596+ serde_json:: to_string ( & sys_config) . context ( "Failed to serialize vm config" ) ?;
597+ Ok ( sys_config_str)
598+ }
599+
600+ fn make_vm_config ( cfg : & Config , manifest : & Manifest , image : & Image ) -> dstack_types:: VmConfig {
601+ let os_image_hash = image
602+ . digest
603+ . as_ref ( )
604+ . and_then ( |d| hex:: decode ( d) . ok ( ) )
605+ . unwrap_or_default ( ) ;
606+ let gpus = manifest. gpus . clone ( ) . unwrap_or_default ( ) ;
607+ dstack_types:: VmConfig {
608+ spec_version : 1 ,
609+ os_image_hash,
610+ cpu_count : manifest. vcpu ,
611+ memory_size : manifest. memory as u64 * 1024 * 1024 ,
612+ qemu_single_pass_add_pages : cfg. cvm . qemu_single_pass_add_pages ,
613+ pic : cfg. cvm . qemu_pic ,
614+ qemu_version : cfg. cvm . qemu_version . clone ( ) ,
615+ pci_hole64_size : cfg. cvm . qemu_pci_hole64_size ,
616+ hugepages : manifest. hugepages ,
617+ num_gpus : gpus. gpus . len ( ) as u32 ,
618+ num_nvswitches : gpus. bridges . len ( ) as u32 ,
619+ hotplug_off : cfg. cvm . qemu_hotplug_off ,
620+ image : Some ( manifest. image . clone ( ) ) ,
621+ }
622+ }
623+
679624fn paginate < T > ( items : Vec < T > , page : u32 , page_size : u32 ) -> impl Iterator < Item = T > {
680625 let skip;
681626 let take;
0 commit comments