| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- <template>
- <div>
- <a-form
- class="mt-3"
- :form="form.fc"
- v-bind="formItemLayout"
- @submit="submit"
- hideRequiredMark>
- <a-form-item :label="$t('compute.text_297', [$t('dictionary.project')])" v-show="false">
- <domain-project
- :fc="form.fc"
- :fd="form.fd"
- :decorators="{ project: decorators.project, domain: decorators.domain }"
- @fetchDomainCallback="fetchDomainCallback"
- @fetchProjectCallback="fetchProjectCallback" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_177')" class="mb-0" v-show="false">
- <cloudregion-zone
- :zone-params="zoneParams"
- :cloudregion-params="cloudregionParams"
- :decorator="decorators.cloudregionZone"
- filterBrandResource="compute_engine" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_294')">
- <a-input-number v-decorator="decorators.count" @blur="countBlur" :min="1" :max="100" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_176')" :extra="$t('compute.text_1151')">
- <hypervisor-radio :decorator="decorators.hypervisor" :type="form.fi.createType" :hypervisors="hypervisors" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_1365')" v-if="isKvm && form.fi.capability.host_cpu_archs">
- <os-arch
- v-decorator="decorators.os_arch"
- :form="form"
- :options="archOptions" />
- </a-form-item>
- <a-form-item v-if="form.fd.hypervisor === 'kvm'" :label="$t('compute.text_1152')">
- <gpu :decorators="decorators.gpu" :gpu-options="gpuOptions" @change="gpuChange" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_1058')" class="mb-0">
- <cpu-radio :decorator="decorators.vcpu" :options="form.fi.cpuMem.cpus || []" @change="cpuChange" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_369')" class="mb-0">
- <mem-radio :decorator="decorators.vmem" :options="form.fi.cpuMem.mems_mb || []" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_109')" v-if="showSku">
- <sku
- v-decorator="decorators.sku"
- :type="type"
- :sku-params="skuParam"
- :hypervisor="form.fd.hypervisor" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_49')" class="mb-0">
- <system-disk
- v-if="form.fd.hypervisor"
- :decorator="decorators.systemDisk"
- :isServertemplate="isServertemplate"
- :type="type"
- :form="form"
- :hypervisor="form.fd.hypervisor"
- :sku="form.fd.sku"
- :capability-data="form.fi.capability"
- :image="form.fi.imageMsg"
- :defaultSize="systemdiskDefaultSize"
- :isHostImageType="isHostImageType"
- :disabled="form.fi.sysDiskDisabled"
- :sizeDisabled="systemdiskSizeDisabled"
- :storageParams="storageParams"
- :storageHostParams="storageHostParams"
- :domain="project_domain"
- :isStorageShow="isStorageShow"
- @storageHostChange="storageHostChange" />
- </a-form-item>
- <a-form-item :label="$t('compute.text_50')">
- <data-disk
- v-if="form.fd.hypervisor"
- ref="dataDiskRef"
- :decorator="decorators.dataDisk"
- :form="form"
- :type="type"
- :hypervisor="form.fd.hypervisor"
- :sku="form.fd.sku"
- :capability-data="form.fi.capability"
- :isSnapshotImageType="isSnapshotImageType"
- :isHostImageType="isHostImageType"
- :disabled="form.fi.dataDiskDisabled"
- :defaultType="form.fd.systemDiskType"
- :domain="project_domain"
- :isWindows="isWindows"
- :isStorageShow="isStorageShow"
- :enableMointpoint="false"
- :simplify="true"
- :storageParams="dataDiskStorageParams"
- :storageHostParams="storageHostParams"
- @storageHostChange="storageHostChange" />
- <div slot="extra" class="warning-color" v-if="isStorageShow">{{ $t('compute.select_storage_no_schetag') }}</div>
- </a-form-item>
- <bottom-bar
- ref="bottomBarRef"
- :loading="submiting"
- :form="form"
- :type="type"
- :dataDiskSizes="dataDiskSizes"
- :isOpenWorkflow="isOpenWorkflow"
- :errors.sync="errors"
- :isServertemplate="isServertemplate"
- :hasMeterService="hasMeterService"
- @getOriginPrice="getOriginPrice" />
- </a-form>
- </div>
- </template>
- <script>
- import _ from 'lodash'
- import * as R from 'ramda'
- import { HYPERVISORS_MAP } from '@/constants'
- import { resolveValueChangeField } from '@/utils/common/ant'
- import { IMAGES_TYPE_MAP, STORAGE_TYPES, HOST_CPU_ARCHS } from '@/constants/compute'
- import OsArch from '@/sections/OsArch'
- import { diskSupportTypeMedium, getOriginDiskKey } from '@/utils/common/hypervisor'
- import mixin from './mixin'
- export default {
- name: 'VM_IDCCreate',
- components: {
- OsArch,
- },
- mixins: [mixin],
- data () {
- return {
- isLocalDisk: true,
- storageHosts: {}, // 所有磁盘的storage-host
- storageHostParams: {}, // 第一个选择的块存储
- }
- },
- computed: {
- isKvm () {
- return this.form.fd.hypervisor === HYPERVISORS_MAP.kvm.key
- },
- isIso () {
- return this.form.fd.imageType === IMAGES_TYPE_MAP.iso.key
- },
- isArm () {
- return this.form.fd.os_arch === HOST_CPU_ARCHS.arm.key
- },
- isLoongarch64 () {
- return this.form.fd.os_arch === HOST_CPU_ARCHS.loongarch64.key
- },
- hypervisors () {
- const { hypervisors = [] } = this.form.fi.capability
- return hypervisors
- },
- cloudregionParams () {
- return {
- cloud_env: 'onpremise',
- usable: true,
- show_emulated: true,
- ...this.scopeParams,
- }
- },
- zoneParams () {
- return {
- usable: true,
- show_emulated: true,
- order_by: 'created_at',
- order: 'asc',
- ...this.scopeParams,
- }
- },
- instanceGroupsParams () {
- return {
- ...this.scopeParams,
- enabled: true,
- }
- },
- cacheImageParams () {
- const params = {
- cloudregion_id: _.get(this.form.fd, 'cloudregion.key'),
- os_arch: HOST_CPU_ARCHS.x86.key,
- }
- if (!params.cloudregion_id) return {}
- if (this.form.fd.imageType === 'vmware') params.image_type = 'system'
- if (this.isArm) params.os_arch = HOST_CPU_ARCHS.arm.key
- if (this.isLoongarch64) params.os_arch = HOST_CPU_ARCHS.loongarch64.key
- return params
- },
- showSku () {
- if (this.form.fd.hypervisor && this.form.fd.vcpu && this.form.fd.vmem) {
- return true
- }
- return false
- },
- skuParam () {
- return {
- limit: 0,
- public_cloud: false,
- postpaid_status: 'available',
- cpu_core_count: this.form.fd.vcpu || this.decorators.vcpu[1].initialValue,
- memory_size_mb: this.form.fd.vmem,
- cloudregion: _.get(this.form, 'fd.cloudregion.key'),
- provider: 'OneCloud',
- ...this.scopeParams,
- }
- },
- // policyHostParams () {
- // const zone = _.get(this.form.fd, 'zone.key')
- // if (zone) {
- // const params = {
- // enabled: 1,
- // usable: true,
- // zone,
- // hypervisor: this.form.fd.hypervisor,
- // os_arch: HOST_CPU_ARCHS.x86.key,
- // ...this.scopeParams,
- // }
- // if (params.hypervisor === HYPERVISORS_MAP.esxi.key) {
- // if (this.form.fd[this.decorators.systemDisk.storage[0]]) {
- // params.storage_id = this.form.fd[this.decorators.systemDisk.storage[0]]
- // }
- // params.cloudprovider = this.form.fd.prefer_manager
- // }
- // if (this.isArm) params.os_arch = HOST_CPU_ARCHS.arm.key
- // return params
- // }
- // return {}
- // },
- networkParam () {
- if (!this.cloudregionZoneParams.cloudregion) return {}
- const params = {
- filter: 'server_type.notin(ipmi, pxe)',
- usable: true,
- ...this.cloudregionZoneParams,
- ...this.scopeParams,
- }
- if ([HYPERVISORS_MAP.esxi.key].includes(this.form.fd.hypervisor)) {
- params.host_type = 'esxi'
- }
- if ([HYPERVISORS_MAP.esxi.key, HYPERVISORS_MAP.kvm.key].includes(this.form.fd.hypervisor)) {
- if (this.form.fd[this.decorators.systemDisk.storage[0]]) {
- params.storage_id = this.form.fd[this.decorators.systemDisk.storage[0]]
- }
- if (this.storageHostParams.disk &&
- this.storageHostParams.disk !== 'system' &&
- this.storageHostParams.storageHosts &&
- this.storageHostParams.storageHosts.length &&
- !params.storage_id) {
- if (this.form.fd[`dataDiskStorages[${this.storageHostParams.disk}]`]) {
- params.storage_id = this.form.fd[`dataDiskStorages[${this.storageHostParams.disk}]`]
- }
- }
- }
- return params
- },
- instanceSpecParmas () {
- return {
- usable: true,
- enabled: true,
- cloudregion: _.get(this.form.fd, 'cloudregion.key'),
- }
- },
- showAdvanceConfig () { // 是否展示高级配置
- return this.isKvm || !this.isServertemplate
- },
- uefi () {
- if (this.isKvm && this.form.fd.gpuEnable && this.form.fd.gpu && this.isWindows) {
- return true
- }
- return false
- },
- cloudproviderParamsExtra () {
- const params = {
- ...this.scopeParams,
- }
- if (this.form.fd.hypervisor && this.form.fd.hypervisor) {
- params.provider = HYPERVISORS_MAP[this.form.fd.hypervisor].provider
- }
- return params
- },
- showSchedCloudprovider () { // 创建VMware机器时,镜像类型不是 VMware 平台镜像时调度策略可以选择指定云账号
- let show = false
- if (this.form.fd.hypervisor === HYPERVISORS_MAP.esxi.key) {
- if (this.form.fd.imageType !== IMAGES_TYPE_MAP.vmware.key) {
- show = true
- }
- }
- return show
- },
- systemdiskSizeDisabled () {
- if (this.form.fd.hypervisor === HYPERVISORS_MAP.esxi.key) {
- const vmLocalImageType = [IMAGES_TYPE_MAP.vmware.key]
- if (vmLocalImageType.includes(this.form.fd.imageType)) {
- return true
- }
- }
- return false
- },
- systemdiskDefaultSize () {
- if (this.isIso) {
- return 30
- }
- return null
- },
- availableHostCount () { // 可用的宿主机数量
- if (R.is(Object, this.form.fi.capability)) {
- return this.form.fi.capability.available_host_count || 0
- }
- return 0
- },
- eipParams () {
- if (!this.cloudregionZoneParams.cloudregion) return {}
- return {
- project: this.project,
- region: this.cloudregionZoneParams.cloudregion,
- }
- },
- showEip () {
- const { vpcs } = this.form.fd
- if (R.is(Object, vpcs)) {
- const vpcList = Object.values(vpcs)
- if (vpcList.length && !~vpcList.indexOf('default')) {
- return this.enableEip
- }
- }
- return false
- },
- storageParams () {
- const { systemDiskType = {}, hypervisor } = this.form.fd
- let key = systemDiskType.key || ''
- // 磁盘区分介质
- if (diskSupportTypeMedium(hypervisor)) {
- key = getOriginDiskKey(key)
- }
- const params = {
- ...this.scopeParams,
- usable: true, // 包含了 enable:true, status为online的数据
- brand: HYPERVISORS_MAP[this.form.fd.hypervisor]?.brand, // kvm,vmware支持指定存储
- manager: this.form.fd.prefer_manager,
- }
- if (key) {
- params.filter = [`storage_type.contains("${key}")`]
- }
- return params
- },
- dataDiskStorageParams () {
- const { dataDiskSizes = {}, hypervisor } = this.form.fd
- let dataDiskType = ''
- for (const key in dataDiskSizes) {
- if (this.form.fd[`dataDiskTypes[${key}]`]) {
- dataDiskType = this.form.fd[`dataDiskTypes[${key}]`].key
- // 磁盘区分介质
- if (diskSupportTypeMedium(hypervisor)) {
- dataDiskType = getOriginDiskKey(dataDiskType)
- }
- }
- }
- const params = {
- ...this.scopeParams,
- usable: true, // 包含了 enable:true, status为online的数据
- brand: HYPERVISORS_MAP[this.form.fd.hypervisor]?.brand, // kvm,vmware支持指定存储
- manager: this.form.fd.prefer_manager,
- }
- if (dataDiskType) {
- params.filter = [`storage_type.contains("${dataDiskType}")`]
- }
- return params
- },
- isStorageShow () { // 是否开启了指定存储
- if ([HYPERVISORS_MAP.esxi.key, HYPERVISORS_MAP.kvm.key].includes(this.form.fd.hypervisor)) {
- if (this.form.fd[this.decorators.systemDisk.storage[0]]) {
- return true
- }
- if (this.storageHostParams.disk &&
- this.storageHostParams.disk !== 'system' &&
- this.storageHostParams.storageHosts &&
- this.storageHostParams.storageHosts.length) {
- if (this.form.fd[`dataDiskStorages[${this.storageHostParams.disk}]`]) {
- return true
- }
- }
- }
- return false
- },
- imageParams () {
- const params = {
- ...this.scopeParams,
- os_arch: HOST_CPU_ARCHS.x86.key,
- }
- if (this.isArm) params.os_arch = HOST_CPU_ARCHS.arm.key
- if (this.isLoongarch64) params.os_arch = HOST_CPU_ARCHS.loongarch64.key
- return params
- },
- archOptions () {
- let opts = []
- if (this.form.fi.capability.host_cpu_archs && this.form.fi.capability.host_cpu_archs.length) {
- opts = this.form.fi.capability.host_cpu_archs.map(item => {
- if (item === HOST_CPU_ARCHS.arm.capabilityKey) return HOST_CPU_ARCHS.arm.key
- if (item === HOST_CPU_ARCHS.x86.capabilityKey) return HOST_CPU_ARCHS.x86.key
- if (item === HOST_CPU_ARCHS.loongarch64.capabilityKey) return HOST_CPU_ARCHS.loongarch64.key
- return item
- })
- }
- return opts
- },
- extra () {
- if (this.isIso && this.isWindows) {
- return this.$t('compute.iso_windows_help')
- }
- return this.$t('compute.text_302')
- },
- },
- watch: {
- 'form.fi.imageMsg': {
- deep: true,
- handler (val, oldVal) {
- if (R.equals(val, oldVal)) return
- this.$nextTick(() => {
- this.form.fi.dataDiskDisabled = false
- this.form.fi.sysDiskDisabled = false
- if (this.form.fd.imageType === IMAGES_TYPE_MAP.host.key) {
- const { root_image: rootImage, data_images: dataImages } = this.form.fi.imageMsg
- const systemDiskSize = rootImage.min_disk_mb / 1024
- const systemDiskType = { // 这里写死即可,因为主机镜像仅 kvm 型机器,且和系统盘类型无瓜葛 @郑雨
- key: STORAGE_TYPES[HYPERVISORS_MAP.kvm.key].local.key,
- label: STORAGE_TYPES[HYPERVISORS_MAP.kvm.key].local.label,
- }
- this.form.fc.setFieldsValue({
- systemDiskSize,
- systemDiskType,
- })
- // 重置数据盘数据
- this._resetDataDisk()
- if (dataImages) {
- dataImages.forEach(val => {
- this.$refs.dataDiskRef.add({ size: val.min_disk_mb / 1024, min: val.min_disk_mb / 1024, minusDisabled: true })
- })
- }
- }
- if (this.form.fd.imageType === IMAGES_TYPE_MAP.snapshot.key) {
- // 镜像类型为主机快照的话要回填数据并禁用
- const snapshots = _.cloneDeep(this.form.fi.imageMsg.server_config.disks)
- if (!snapshots) return
- let sysDisk = snapshots.find(val => val.disk_type === 'sys')
- if (!sysDisk) {
- sysDisk = snapshots.shift()
- }
- const dataDisks = snapshots.filter(val => val.disk_type !== 'sys')
- const data = {
- systemDiskType: {
- key: sysDisk.backend,
- label: STORAGE_TYPES[HYPERVISORS_MAP.kvm.key][sysDisk.backend].label,
- },
- systemDiskSize: sysDisk.size / 1024,
- }
- if (val && R.is(Object, val.server_config)) {
- if (val.server_config.vcpu_count) {
- const cpuValue = val.server_config.vcpu_count
- data[this.decorators.vcpu[0]] = cpuValue
- this.cpuChange(cpuValue)
- if (val.server_config.vmem_size) data[this.decorators.vmem[0]] = val.server_config.vmem_size
- }
- }
- this.form.fc.setFieldsValue(data)
- // 重置数据盘数据
- this._resetDataDisk()
- dataDisks.forEach(val => {
- this.$refs.dataDiskRef.add({ diskType: val.backend, size: val.size / 1024, sizeDisabled: true })
- })
- this.form.fi.dataDiskDisabled = true
- this.form.fi.sysDiskDisabled = true
- } else {
- if (oldVal && R.is(Object, oldVal.server_config)) { // 说明是从主机快照切换过去的
- const vcpuDecorator = this.decorators.vcpu
- const vcpuInit = vcpuDecorator[1].initialValue
- this.form.fc.setFieldsValue({
- [vcpuDecorator[0]]: vcpuInit,
- })
- this.cpuChange(vcpuInit)
- }
- }
- })
- },
- },
- uefi (val) {
- this.setBios(val)
- },
- isArm (val, oldV) {
- this.setBios(val)
- },
- },
- methods: {
- vpcResourceMapper (list) {
- if (this.form.fd.hypervisor === HYPERVISORS_MAP.esxi.key) {
- return list.filter(val => val.id === 'default')
- }
- return list
- },
- onValuesChange (vm, changedFields) {
- this.$nextTick(() => {
- const formValue = this.form.fc.getFieldsValue()
- const newField = resolveValueChangeField(changedFields)
- this._setNewFieldToFd(newField, formValue)
- const keys = Object.keys(newField)
- if (keys.includes('zone') || keys.includes('cloudregion')) {
- this.fetchCapability()
- }
- if (keys.includes('cloudregion')) {
- this.$nextTick(this.fetchInstanceSpecs)
- }
- if (changedFields.schedPolicyType === 'host') {
- this.$set(this.form.fd, 'schedPolicyHost', undefined)
- }
- if (changedFields.backupEnable) {
- this.$set(this.form.fd, 'backup', undefined)
- }
- this.setIsLocalDisk()
- })
- },
- setIsLocalDisk () {
- const isSysLocal = _.get(this.form, 'fd.systemDiskType.key') === 'local'
- const fd = this.form.fc.getFieldsValue()
- let isDiskLocal = true
- const { dataDiskTypes } = fd
- if (!R.is(Object, dataDiskTypes)) return
- const diskTypeItem = dataDiskTypes[Object.keys(dataDiskTypes)[0]]
- if (diskTypeItem && diskTypeItem.key) {
- isDiskLocal = diskTypeItem.key === 'local'
- }
- this.isLocalDisk = isSysLocal && isDiskLocal
- },
- fetchCapability () {
- const params = {
- show_emulated: true,
- resource_type: 'shared',
- ...this.scopeParams,
- }
- let id = this.cloudregionZoneParams.cloudregion
- let resource = 'cloudregions'
- if (this.cloudregionZoneParams.zone) {
- id = this.cloudregionZoneParams.zone
- resource = 'zones'
- }
- const capabilityParams = { id, spec: 'capability', params }
- if (!id) return
- if (R.equals(this.capabilityParams, capabilityParams)) return // 和已有的参数一样则不发请求
- this.capabilityParams = capabilityParams
- new this.$Manager(resource).getSpecific(this.capabilityParams)
- .then(({ data }) => {
- let hypervisors = R.is(Object, data) ? (data.hypervisors || []) : []
- if (hypervisors.includes(HYPERVISORS_MAP.kvm.key)) { // kvm 排序为第一个
- hypervisors = [HYPERVISORS_MAP.kvm.key].concat(hypervisors).filter(val => val !== 'baremetal')
- }
- hypervisors = Array.from(new Set(hypervisors))
- this.form.fi.capability = {
- ...data,
- hypervisors,
- }
- this.form.fc.setFieldsValue({
- hypervisor: hypervisors[0], // 赋值默认第一个平台
- })
- })
- },
- fetchInstanceSpecs () {
- if (!this.instanceSpecParmas.cloudregion) return
- this.serverskusM.get({ id: 'instance-specs', params: this.instanceSpecParmas })
- .then(({ data }) => {
- this.form.fi.cpuMem = data
- const vcpuDecorator = this.decorators.vcpu
- const vcpuInit = vcpuDecorator[1].initialValue
- this.cpuChange(vcpuInit)
- })
- },
- setBios (val) {
- if (val) {
- this.form.fc.getFieldDecorator(this.decorators.bios[0], { preserve: true })
- this.form.fc.setFieldsValue({ [this.decorators.bios[0]]: 'UEFI' })
- } else {
- this.form.fc.setFieldsValue({ [this.decorators.bios[0]]: 'BIOS' })
- }
- },
- gpuChange (val) {
- if (!val) {
- this.form.fc.setFieldsValue({ gpu: '' })
- }
- },
- storageHostChange (val) {
- const { disk } = this.storageHostParams
- if (val.disk) {
- this.storageHosts[val.disk] = val
- }
- // 由第一块选择块存储的盘来确定块存储所在的host
- if (!disk || disk === val.disk) { // 第一块盘选
- if (val.storageHosts && val.storageHosts.length) {
- this.storageHostParams = val
- } else { // 清空操作
- let changeNew = false
- for (const key in this.storageHosts) {
- if (this.storageHosts[key].storageHosts && this.storageHosts[key].storageHosts.length) {
- this.storageHostParams = this.storageHosts[key] // 选其他已选的hosts作为新的范围
- changeNew = true
- break
- }
- }
- if (!changeNew) this.storageHostParams = {}
- }
- }
- },
- },
- }
- </script>
|