mirror of https://github.com/rancher/dashboard.git
HARVESTER: add Node Scheduling to VM edit page
This commit is contained in:
parent
f6264c81b0
commit
6fdc7e974e
|
|
@ -1,11 +1,13 @@
|
|||
<script>
|
||||
import { _VIEW } from '@/config/query-params';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { get, isEmpty, clone } from '@/utils/object';
|
||||
import { NODE } from '@/config/types';
|
||||
import MatchExpressions from '@/components/form/MatchExpressions';
|
||||
import LabeledSelect from '@/components/form/LabeledSelect';
|
||||
import { randomStr } from '@/utils/string';
|
||||
import ArrayListGrouped from '@/components/form/ArrayListGrouped';
|
||||
import { NAME as VIRTUAL } from '@/config/product/virtual';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -55,6 +57,7 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters({ t: 'i18n/t' }),
|
||||
isView() {
|
||||
return this.mode === _VIEW;
|
||||
},
|
||||
|
|
@ -64,6 +67,27 @@ export default {
|
|||
node() {
|
||||
return NODE;
|
||||
},
|
||||
isHarvester() {
|
||||
return this.$store.getters['currentProduct'].inStore === VIRTUAL;
|
||||
},
|
||||
defaultAddValue() {
|
||||
const out = { matchExpressions: [] };
|
||||
|
||||
if (this.isHarvester) {
|
||||
out.weight = 1;
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
affinityOptions() {
|
||||
const out = [this.t('workload.scheduling.affinity.preferred')];
|
||||
|
||||
if (!this.isHarvester) {
|
||||
out.push(this.t('workload.scheduling.affinity.required'));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
@ -102,7 +126,7 @@ export default {
|
|||
},
|
||||
|
||||
priorityDisplay(term) {
|
||||
return term.weight ? this.t('workload.scheduling.affinity.preferred') : this.t('workload.scheduling.affinity.required');
|
||||
return term.weight || this.isHarvester ? this.t('workload.scheduling.affinity.preferred') : this.t('workload.scheduling.affinity.required');
|
||||
},
|
||||
|
||||
get,
|
||||
|
|
@ -116,12 +140,12 @@ export default {
|
|||
<template>
|
||||
<div class="row" @input="update">
|
||||
<div class="col span-12">
|
||||
<ArrayListGrouped v-model="allSelectorTerms" class="mt-20" :default-add-value="{matchExpressions:[]}" :add-label="t('workload.scheduling.affinity.addNodeSelector')">
|
||||
<ArrayListGrouped v-model="allSelectorTerms" class="mt-20" :mode="mode" :default-add-value="defaultAddValue" :add-label="t('workload.scheduling.affinity.addNodeSelector')">
|
||||
<template #default="props">
|
||||
<div class="row">
|
||||
<div class="col span-6">
|
||||
<LabeledSelect
|
||||
:options="[t('workload.scheduling.affinity.preferred'),t('workload.scheduling.affinity.required')]"
|
||||
:options="affinityOptions"
|
||||
:value="priorityDisplay(props.row.value)"
|
||||
:label="t('workload.scheduling.affinity.priority')"
|
||||
:mode="mode"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import RadioGroup from '@/components/form/RadioGroup';
|
||||
import LabeledSelect from '@/components/form/LabeledSelect';
|
||||
import NodeAffinity from '@/components/form/NodeAffinity';
|
||||
import { NAME as VIRTUAL } from '@/config/product/virtual';
|
||||
import { _VIEW } from '@/config/query-params';
|
||||
import { isEmpty } from '@/utils/object';
|
||||
|
||||
|
|
@ -56,10 +58,36 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters({ t: 'i18n/t' }),
|
||||
isView() {
|
||||
return this.mode === _VIEW;
|
||||
},
|
||||
|
||||
isHarvester() {
|
||||
return this.$store.getters['currentProduct'].inStore === VIRTUAL;
|
||||
},
|
||||
|
||||
selectNodeOptions() {
|
||||
const out = [{
|
||||
label: this.t('workload.scheduling.affinity.anyNode'),
|
||||
value: null
|
||||
},
|
||||
{
|
||||
label: this.t('workload.scheduling.affinity.specificNode'),
|
||||
value: 'nodeSelector'
|
||||
},
|
||||
{
|
||||
label: this.t('workload.scheduling.affinity.schedulingRules'),
|
||||
value: 'affinity'
|
||||
}];
|
||||
|
||||
if (this.isHarvester) {
|
||||
out.splice(1, 1);
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
|
|
@ -100,8 +128,7 @@ export default {
|
|||
<RadioGroup
|
||||
v-model="selectNode"
|
||||
name="selectNode"
|
||||
:options="[null, 'nodeSelector', 'affinity']"
|
||||
:labels="[ t('workload.scheduling.affinity.anyNode'), t('workload.scheduling.affinity.specificNode'), t('workload.scheduling.affinity.schedulingRules') ]"
|
||||
:options="selectNodeOptions"
|
||||
:mode="mode"
|
||||
@input="update"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
<script>
|
||||
import Tabbed from '@/components/Tabbed';
|
||||
import Tab from '@/components/Tabbed/Tab';
|
||||
import { EVENT, HCI, SERVICE } from '@/config/types';
|
||||
import { EVENT, HCI, SERVICE, NODE } from '@/config/types';
|
||||
import CreateEditView from '@/mixins/create-edit-view';
|
||||
import HarvesterMetrics from '@/components/HarvesterMetrics';
|
||||
import { allHash } from '@/utils/promise';
|
||||
import NodeScheduling from '@/components/form/NodeScheduling';
|
||||
import OverviewBasics from './tabs/details/basics';
|
||||
import OverviewDisks from './tabs/details/disks';
|
||||
import OverviewNetworks from './tabs/details/networks';
|
||||
|
|
@ -27,6 +28,7 @@ export default {
|
|||
OverviewNetworks,
|
||||
OverviewKeypairs,
|
||||
OverviewCloudConfigs,
|
||||
NodeScheduling,
|
||||
Migration,
|
||||
HarvesterMetrics,
|
||||
},
|
||||
|
|
@ -70,11 +72,19 @@ export default {
|
|||
|
||||
return vmi;
|
||||
},
|
||||
|
||||
nodesIdOptions() {
|
||||
const nodes = this.$store.getters['virtual/all'](NODE) || [];
|
||||
|
||||
return nodes.map(node => node.id);
|
||||
},
|
||||
|
||||
allEvents() {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
|
||||
return this.$store.getters[`${ inStore }/all`](EVENT);
|
||||
},
|
||||
|
||||
events() {
|
||||
return this.allEvents.filter((e) => {
|
||||
const { name, creationTimestamp } = this.value?.metadata || {};
|
||||
|
|
@ -120,14 +130,18 @@ export default {
|
|||
<OverviewBasics v-model="value" :resource="vmi" mode="view" />
|
||||
</Tab>
|
||||
|
||||
<Tab name="disks" :label="t('harvester.tab.volume')" class="bordered-table" :weight="5">
|
||||
<Tab name="disks" :label="t('harvester.tab.volume')" class="bordered-table" :weight="6">
|
||||
<OverviewDisks v-model="value" />
|
||||
</Tab>
|
||||
|
||||
<Tab name="networks" :label="t('harvester.virtualMachine.detail.tabs.networks')" class="bordered-table" :weight="4">
|
||||
<Tab name="networks" :label="t('harvester.virtualMachine.detail.tabs.networks')" class="bordered-table" :weight="5">
|
||||
<OverviewNetworks v-model="value" />
|
||||
</Tab>
|
||||
|
||||
<Tab :label="t('workload.container.titles.nodeScheduling')" name="nodeScheduling" :weight="4">
|
||||
<NodeScheduling :mode="mode" :value="value.spec.template.spec" :nodes="nodesIdOptions" />
|
||||
</Tab>
|
||||
|
||||
<Tab name="keypairs" :label="t('harvester.virtualMachine.detail.tabs.keypairs')" class="bordered-table" :weight="3">
|
||||
<OverviewKeypairs v-model="value" />
|
||||
</Tab>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import Network from '@/edit/kubevirt.io.virtualmachine/network';
|
|||
import ImageSelect from '@/edit/kubevirt.io.virtualmachine/Image';
|
||||
import CpuMemory from '@/edit/kubevirt.io.virtualmachine/CpuMemory';
|
||||
import CloudConfig from '@/edit/kubevirt.io.virtualmachine/CloudConfig';
|
||||
import NodeScheduling from '@/components/form/NodeScheduling';
|
||||
|
||||
import { clone } from '@/utils/object';
|
||||
import { HCI } from '@/config/types';
|
||||
|
|
@ -47,6 +48,7 @@ export default {
|
|||
CpuMemory,
|
||||
ImageSelect,
|
||||
CloudConfig,
|
||||
NodeScheduling,
|
||||
},
|
||||
|
||||
mixins: [CreateEditView, VM_MIXIN],
|
||||
|
|
@ -465,10 +467,14 @@ export default {
|
|||
<Network v-model="networkRows" :mode="mode" />
|
||||
</Tab>
|
||||
|
||||
<Tab :label="t('workload.container.titles.nodeScheduling')" name="nodeScheduling" :weight="-3">
|
||||
<NodeScheduling :mode="mode" :value="spec.template.spec" :nodes="nodesIdOptions" />
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
name="advanced"
|
||||
:label="t('harvester.tab.advanced')"
|
||||
:weight="-3"
|
||||
:weight="-4"
|
||||
>
|
||||
<div class="row mb-20">
|
||||
<div class="col span-6">
|
||||
|
|
|
|||
|
|
@ -132,6 +132,12 @@ export default {
|
|||
return this.$store.getters['virtual/all'](HCI.VM_TEMPLATE) || [];
|
||||
},
|
||||
|
||||
nodesIdOptions() {
|
||||
const nodes = this.$store.getters['virtual/all'](NODE) || [];
|
||||
|
||||
return nodes.map(node => node.id);
|
||||
},
|
||||
|
||||
memory: {
|
||||
get() {
|
||||
return this.spec.template.spec.domain.resources.requests.memory;
|
||||
|
|
|
|||
Loading…
Reference in New Issue