llm_sku_base.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package llm
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "yunion.io/x/jsonutils"
  7. "yunion.io/x/onecloud/pkg/apis"
  8. computeapi "yunion.io/x/onecloud/pkg/apis/compute"
  9. api "yunion.io/x/onecloud/pkg/apis/llm"
  10. )
  11. type LLMSkuBaseCreateOptions struct {
  12. apis.SharableVirtualResourceCreateInput
  13. CPU int
  14. MEMORY int `help:"memory size MB"`
  15. DISK_SIZE int `help:"disk size MB"`
  16. Bandwidth int
  17. StorageType string
  18. // DiskOverlay string `help:"disk overlay, e.g. /opt/steam-data/base:/opt/steam-data/games"`
  19. TemplateId string
  20. PortMappings []string `help:"port mapping in the format of protocol:port[:prefix][:first_port_offset][:env_key=env_value], e.g. tcp:5555:192.168.0.0/16:5:WOLF_BASE_PORT=20000"`
  21. Devices []string `help:"device info in the format of model[:path[:dev_type]], e.g. 'GeForce RTX 4060'"`
  22. Env []string `help:"env in format of key=value"`
  23. Property []string `help:"extra properties of key=value, e.g. tango32=true"`
  24. // MountedApps []string `help:"mounted apps, e.g. com.tencent.tmgp.sgame/1.0.0"`
  25. Entrypoint string `help:"entrypoint"`
  26. }
  27. func (o *LLMSkuBaseCreateOptions) Params(dict *jsonutils.JSONDict) error {
  28. vol := api.Volume{
  29. SizeMB: o.DISK_SIZE,
  30. TemplateId: o.TemplateId,
  31. StorageType: o.StorageType,
  32. }
  33. vols := []api.Volume{vol}
  34. dict.Set("volumes", jsonutils.Marshal(vols))
  35. fetchPortmappings(o.PortMappings, dict)
  36. fetchDevices(o.Devices, dict)
  37. fetchEnvs(o.Env, dict)
  38. fetchProperties(o.Property, dict)
  39. return nil
  40. }
  41. type LLMSkuBaseUpdateOptions struct {
  42. apis.SharableVirtualResourceBaseUpdateInput
  43. ID string
  44. Cpu *int
  45. Memory *int `help:"memory size GB"`
  46. DiskSize *int `help:"disk size MB"`
  47. StorageType string
  48. TemplateId string
  49. NoTemplate bool `json:"-" help:"remove template"`
  50. Bandwidth *int
  51. // Dpi *int
  52. // Fps *int
  53. PortMappings []string `help:"port mapping in the format of protocol:port[:prefix][:first_port_offset], e.g. tcp:5555:192.168.0.0/16,10.10.0.0/16:1000"`
  54. Devices []string `help:"device info in the format of model[:path[:dev_type]], e.g. QuadraT2A:/dev/nvme1n1, Device::VASTAITECH_GPU"`
  55. Env []string `help:"env in the format of key=value, e.g. AUTHENTICATION_PATH=/bupt-test/"`
  56. Property []string `help:"extra properties of key=value, e.g. tango32=true"`
  57. // MountedApps []string `help:"mounted apps, e.g. com.tencent.tmgp.sgame/1.0.0"`
  58. SyncImage bool `help:"request sync image" json:"-"`
  59. ClearSyncImage bool `help:"request clear sync image flag" json:"-"`
  60. Entrypoint string `help:"entrypoint"`
  61. }
  62. func (o *LLMSkuBaseUpdateOptions) Params(dict *jsonutils.JSONDict) error {
  63. if o.NoTemplate {
  64. dict.Set("template_id", jsonutils.NewString(""))
  65. }
  66. if o.SyncImage {
  67. dict.Set("request_sync_image", jsonutils.JSONTrue)
  68. } else if o.ClearSyncImage {
  69. dict.Set("request_sync_image", jsonutils.JSONFalse)
  70. }
  71. if o.DiskSize != nil && *o.DiskSize > 0 {
  72. dict.Set("disk_size_mb", jsonutils.NewInt(int64(*o.DiskSize)))
  73. }
  74. fetchPortmappings(o.PortMappings, dict)
  75. fetchDevices(o.Devices, dict)
  76. fetchEnvs(o.Env, dict)
  77. fetchProperties(o.Property, dict)
  78. // fetchMountedApps(o.MountedApps, dict)
  79. return nil
  80. }
  81. func fetchPortmappings(pmStrs []string, dict *jsonutils.JSONDict) {
  82. pms := make([]api.PortMapping, 0)
  83. for _, pm := range pmStrs {
  84. segs := strings.Split(pm, ":")
  85. if len(segs) > 1 {
  86. port, _ := strconv.ParseInt(segs[1], 10, 64)
  87. var remoteIps []string
  88. if len(segs) > 2 {
  89. for _, ip := range strings.Split(segs[2], ",") {
  90. ip = strings.TrimSpace(ip)
  91. if len(ip) > 0 {
  92. remoteIps = append(remoteIps, ip)
  93. }
  94. }
  95. }
  96. firstPortOffset := 0
  97. var err error
  98. if len(segs) > 3 {
  99. firstPortOffset, err = strconv.Atoi(segs[3])
  100. if err != nil {
  101. panic(fmt.Sprintf("parse firstPortOffset: %s", err))
  102. }
  103. }
  104. pm := api.PortMapping{
  105. Protocol: segs[0],
  106. ContainerPort: int(port),
  107. RemoteIps: remoteIps,
  108. }
  109. if firstPortOffset >= 0 {
  110. pm.FirstPortOffset = &firstPortOffset
  111. }
  112. if len(segs) > 4 {
  113. envs := make([]computeapi.GuestPortMappingEnv, 0)
  114. for _, env := range strings.Split(segs[4], ",") {
  115. parts := strings.Split(env, "=")
  116. if len(parts) != 2 {
  117. panic(fmt.Sprintf("parse env: %s", env))
  118. }
  119. key := parts[0]
  120. valType := parts[1]
  121. switch valType {
  122. case "port":
  123. envs = append(envs, computeapi.GuestPortMappingEnv{Key: key, ValueFrom: computeapi.GuestPortMappingEnvValueFromPort})
  124. case "host_port":
  125. envs = append(envs, computeapi.GuestPortMappingEnv{Key: key, ValueFrom: computeapi.GuestPortMappingEnvValueFromHostPort})
  126. default:
  127. panic(fmt.Sprintf("wrong env type: %q", valType))
  128. }
  129. }
  130. pm.Envs = envs
  131. }
  132. pms = append(pms, pm)
  133. }
  134. }
  135. if len(pms) > 0 {
  136. dict.Set("port_mappings", jsonutils.Marshal(pms))
  137. }
  138. }
  139. func fetchDevices(devStrs []string, dict *jsonutils.JSONDict) {
  140. devs := make([]api.Device, 0)
  141. for _, dev := range devStrs {
  142. segs := strings.Split(dev, ":")
  143. if len(segs) > 0 {
  144. devpath := ""
  145. devType := ""
  146. if len(segs) > 1 {
  147. devpath = segs[1]
  148. }
  149. if len(segs) > 2 {
  150. devType = segs[2]
  151. }
  152. devs = append(devs, api.Device{
  153. Model: segs[0],
  154. DevicePath: devpath,
  155. DevType: devType,
  156. })
  157. }
  158. }
  159. if len(devs) > 0 {
  160. dict.Set("devices", jsonutils.Marshal(devs))
  161. }
  162. }
  163. func fetchEnvs(EnvStrs []string, dict *jsonutils.JSONDict) {
  164. envs := make(api.Envs, 0)
  165. for _, env := range EnvStrs {
  166. pos := strings.Index(env, "=")
  167. if pos > 0 {
  168. key := strings.TrimSpace(env[:pos])
  169. val := strings.TrimSpace(env[pos+1:])
  170. envs = append(envs, api.Env{Key: key, Value: val})
  171. }
  172. }
  173. if len(envs) > 0 {
  174. dict.Set("envs", jsonutils.Marshal(envs))
  175. }
  176. }
  177. func fetchProperties(propStrs []string, dict *jsonutils.JSONDict) {
  178. props := make(map[string]string, 0)
  179. for _, env := range propStrs {
  180. pos := strings.Index(env, "=")
  181. if pos > 0 {
  182. key := strings.TrimSpace(env[:pos])
  183. val := strings.TrimSpace(env[pos+1:])
  184. props[key] = val
  185. }
  186. }
  187. if len(props) > 0 {
  188. dict.Set("properties", jsonutils.Marshal(props))
  189. }
  190. }
  191. func fetchMountedModels(mdls []string, dict *jsonutils.JSONDict) {
  192. if len(mdls) > 0 {
  193. dict.Set("mounted_models", jsonutils.Marshal(mdls))
  194. }
  195. }