Skip to content

Commit 342c05f

Browse files
committed
feat(lite): add enable and disable actions on host
1 parent 2b3dac1 commit 342c05f

9 files changed

Lines changed: 191 additions & 2 deletions

File tree

‎@xen-orchestra/lite/src/libs/xen-api/operations/host-operations.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export function createHostOperations(xenApi: XenApi) {
3333
}
3434

3535
return {
36+
disable,
37+
enable,
3638
powerOn,
3739
shutdown,
3840
destroy,

‎@xen-orchestra/lite/src/libs/xen-api/xen-api.enums.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export enum ON_NORMAL_EXIT {
9191
}
9292

9393
export enum HOST_OPERATION {
94+
ENABLE = 'enable',
9495
EVACUATE = 'evacuate',
9596
POWER_ON = 'power_on',
9697
REBOOT = 'reboot',

‎@xen-orchestra/lite/src/modules/host/components/actions/HostTreeActions.vue‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,35 @@
55
<HostPowerStateActions :host />
66
</template>
77
</MenuItem>
8+
<HostDisableButton v-if="displayDisableButton" :host />
9+
<HostEnableButton v-else :host />
810
<HostForgetButton :host />
911
<VtsDivider type="stretch" />
1012
<HostDownloadButton :host-opaque-ref="host.$ref" />
1113
</template>
1214

1315
<script setup lang="ts">
1416
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
17+
import HostDisableButton from '@/modules/host/components/actions/disable/HostDisableButton.vue'
1518
import HostDownloadButton from '@/modules/host/components/actions/download/HostDownloadButton.vue'
19+
import HostEnableButton from '@/modules/host/components/actions/enable/HostEnableButton.vue'
1620
import HostForgetButton from '@/modules/host/components/actions/forget/HostForgetButton.vue'
1721
import HostPowerStateActions from '@/modules/host/components/actions/HostPowerStateActions.vue'
22+
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
1823
import VtsDivider from '@core/components/divider/VtsDivider.vue'
1924
import MenuItem from '@core/components/menu/MenuItem.vue'
25+
import { computed } from 'vue'
2026
import { useI18n } from 'vue-i18n'
2127
22-
defineProps<{
28+
const { host } = defineProps<{
2329
host: XenApiHost
2430
}>()
2531
2632
const { t } = useI18n()
33+
34+
const { isHostHalted } = useHostMetricsStore().subscribe()
35+
36+
const displayDisableButton = computed(() => host.enabled || isHostHalted(host))
2737
</script>
2838

2939
<style lang="postcss" scoped>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<template>
2+
<MenuItem
3+
v-tooltip="!canDisableHost && disableHostErrorMessage"
4+
:busy="isDisablingHost"
5+
:disabled="!canDisableHost"
6+
icon="action:disable"
7+
@click="disableHost()"
8+
>
9+
{{ t('action:disable') }}
10+
</MenuItem>
11+
</template>
12+
13+
<script lang="ts" setup>
14+
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
15+
import { useHostDisableJob } from '@/modules/host/jobs/host-disable.job.ts'
16+
import MenuItem from '@core/components/menu/MenuItem.vue'
17+
import { useActionModal } from '@core/composables/modals/use-action-modal.ts'
18+
import { vTooltip } from '@core/directives/tooltip.directive.ts'
19+
import { useI18n } from 'vue-i18n'
20+
21+
const { host } = defineProps<{
22+
host: XenApiHost
23+
}>()
24+
25+
const { t } = useI18n()
26+
27+
const { open: openActionModal } = useActionModal()
28+
29+
const {
30+
run,
31+
canRun: canDisableHost,
32+
isRunning: isDisablingHost,
33+
errorMessage: disableHostErrorMessage,
34+
} = useHostDisableJob(() => host)
35+
36+
function disableHost() {
37+
return openActionModal({
38+
props: {
39+
accent: 'info',
40+
action: 'disable',
41+
object: 'host',
42+
hostName: host.name_label,
43+
icon: 'status:info-picto',
44+
},
45+
events: {
46+
onConfirm: async () => {
47+
void run()
48+
},
49+
},
50+
})
51+
}
52+
</script>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<template>
2+
<MenuItem
3+
v-tooltip="!canEnableHost && enableHostErrorMessage"
4+
:busy="isEnablingHost"
5+
:disabled="!canEnableHost"
6+
icon="status:success-circle"
7+
@click="enableHost()"
8+
>
9+
{{ t('action:enable') }}
10+
</MenuItem>
11+
</template>
12+
13+
<script lang="ts" setup>
14+
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
15+
import { useHostEnableJob } from '@/modules/host/jobs/host-enable.job.ts'
16+
import MenuItem from '@core/components/menu/MenuItem.vue'
17+
import { useActionModal } from '@core/composables/modals/use-action-modal.ts'
18+
import { vTooltip } from '@core/directives/tooltip.directive.ts'
19+
import { useI18n } from 'vue-i18n'
20+
21+
const { host } = defineProps<{
22+
host: XenApiHost
23+
}>()
24+
25+
const { t } = useI18n()
26+
27+
const { open: openActionModal } = useActionModal()
28+
29+
const {
30+
run,
31+
canRun: canEnableHost,
32+
isRunning: isEnablingHost,
33+
errorMessage: enableHostErrorMessage,
34+
} = useHostEnableJob(() => host)
35+
36+
function enableHost() {
37+
return openActionModal({
38+
props: {
39+
accent: 'info',
40+
action: 'enable',
41+
object: 'host',
42+
hostName: host.name_label,
43+
icon: 'status:info-picto',
44+
},
45+
events: {
46+
onConfirm: async () => {
47+
void run()
48+
},
49+
},
50+
})
51+
}
52+
</script>

‎@xen-orchestra/lite/src/modules/host/composables/host-utils.composable.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export function useHostUtils(rawHost: MaybeRefOrGetter<XenApiHost | undefined>)
2727
const currentOperation = useMapper<string, string>(
2828
() => pendingStateOperation.value,
2929
{
30+
[HOST_OPERATION.ENABLE]: t('operation:enable'),
3031
[HOST_OPERATION.EVACUATE]: t('operation:evacuate'),
3132
[HOST_OPERATION.POWER_ON]: t('operation:start'),
3233
[HOST_OPERATION.REBOOT]: t('operation:clean-reboot'),
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { HOST_OPERATION } from '@/libs/xen-api/xen-api.enums.ts'
2+
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
3+
import { hostArg } from '@/modules/host/jobs/host-args.ts'
4+
import { isHostOperationPending } from '@/modules/host/utils/host.util.ts'
5+
import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store.ts'
6+
import { useXenApiStore } from '@/stores/xen-api.store.ts'
7+
import { defineJob, JobError, JobRunningError } from '@core/packages/job'
8+
import { useI18n } from 'vue-i18n'
9+
10+
export const useHostDisableJob = defineJob('host.disable', [hostArg], () => {
11+
const xapi = useXenApiStore().getXapi()
12+
const { t } = useI18n()
13+
const { isHostRunning } = useHostMetricsStore().subscribe()
14+
15+
return {
16+
run: (host: XenApiHost) => xapi.host.disable(host.$ref),
17+
18+
validate: (isRunning, host: XenApiHost | undefined) => {
19+
if (host === undefined) {
20+
throw new JobError(t('job:host-disable:missing-host'))
21+
}
22+
23+
if (isRunning) {
24+
throw new JobRunningError(t('job:disable:in-progress'))
25+
}
26+
27+
if (isHostOperationPending(host, HOST_OPERATION.EVACUATE)) {
28+
throw new JobRunningError(t('job:host-evacuate:in-progress'))
29+
}
30+
31+
if (!isHostRunning(host)) {
32+
throw new JobError(t('job:host-disable:bad-power-state'))
33+
}
34+
},
35+
}
36+
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { HOST_OPERATION } from '@/libs/xen-api/xen-api.enums.ts'
2+
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
3+
import { hostArg } from '@/modules/host/jobs/host-args.ts'
4+
import { isHostOperationPending } from '@/modules/host/utils/host.util.ts'
5+
import { useXenApiStore } from '@/stores/xen-api.store.ts'
6+
import { defineJob, JobError, JobRunningError } from '@core/packages/job'
7+
import { useI18n } from 'vue-i18n'
8+
9+
export const useHostEnableJob = defineJob('host.enable', [hostArg], () => {
10+
const xapi = useXenApiStore().getXapi()
11+
const { t } = useI18n()
12+
13+
return {
14+
run: (host: XenApiHost) => xapi.host.enable(host.$ref),
15+
16+
validate: (isRunning, host: XenApiHost | undefined) => {
17+
if (host === undefined) {
18+
throw new JobError(t('job:host-enable:missing-host'))
19+
}
20+
21+
if (isRunning || isHostOperationPending(host, HOST_OPERATION.ENABLE)) {
22+
throw new JobRunningError(t('job:enable:in-progress'))
23+
}
24+
25+
if (isHostOperationPending(host, HOST_OPERATION.EVACUATE)) {
26+
throw new JobRunningError(t('job:host-evacuate:in-progress'))
27+
}
28+
},
29+
}
30+
})

‎@xen-orchestra/lite/src/modules/host/utils/host.util.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { HOST_OPERATION } from '@/libs/xen-api/xen-api.enums.ts'
22
import type { XenApiHost } from '@/libs/xen-api/xen-api.types.ts'
33
import { castArray } from 'lodash-es'
44

5-
const RUNNING_CHANGING_STATE_OPERATIONS = [HOST_OPERATION.EVACUATE, HOST_OPERATION.REBOOT, HOST_OPERATION.SHUTDOWN]
5+
const RUNNING_CHANGING_STATE_OPERATIONS = [
6+
HOST_OPERATION.ENABLE,
7+
HOST_OPERATION.EVACUATE,
8+
HOST_OPERATION.REBOOT,
9+
HOST_OPERATION.SHUTDOWN,
10+
]
611

712
const NOT_RUNNING_CHANGING_STATE_OPERATIONS = [HOST_OPERATION.POWER_ON]
813

0 commit comments

Comments
 (0)