Compare commits
2 Commits
lite/ui-ic
...
fix_openVh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
543f44d1d1 | ||
|
|
b0cb249ae9 |
@@ -3,7 +3,7 @@
|
||||
const sum = require('lodash/sum')
|
||||
const UUID = require('uuid')
|
||||
const { asyncMap } = require('@xen-orchestra/async-map')
|
||||
const { Constants, openVhd, VhdAbstract, VhdFile } = require('vhd-lib')
|
||||
const { Constants, openVhd, VhdAbstract, VhdFile, BrokenVhdError } = require('vhd-lib')
|
||||
const { isVhdAlias, resolveVhdAlias } = require('vhd-lib/aliases')
|
||||
const { dirname, resolve } = require('path')
|
||||
const { DISK_TYPES } = Constants
|
||||
@@ -242,7 +242,7 @@ exports.cleanVm = async function cleanVm(
|
||||
} catch (error) {
|
||||
vhds.delete(path)
|
||||
logWarn('VHD check error', { path, error })
|
||||
if (error?.code === 'ERR_ASSERTION' && remove) {
|
||||
if (error instanceof BrokenVhdError && remove) {
|
||||
logInfo('deleting broken VHD', { path })
|
||||
return VhdAbstract.unlink(handler, path)
|
||||
}
|
||||
|
||||
@@ -91,18 +91,21 @@ const fontSize = ref("2rem");
|
||||
|
||||
This project is using Font Awesome 6 Free.
|
||||
|
||||
Here is how to use an icon in your template.
|
||||
Icons can be displayed with the `UiIcon` component.
|
||||
|
||||
Note: `FontAwesomeIcon` is a global component that does not need to be imported.
|
||||
Passing `undefined` as `icon` prop will disable the component (no need to use an additional `v-if` condition).
|
||||
|
||||
Use the `busy` prop to display a loader icon.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<FontAwesomeIcon :icon="faDisplay" />
|
||||
<UiIcon :icon="faDisplay" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import UiIcon from "@/components/ui/UiIcon.vue"
|
||||
import { faDisplay } from "@fortawesome/free-solid-svg-icons";
|
||||
</script>
|
||||
```
|
||||
@@ -115,8 +118,6 @@ Here is the equivalent between font weight and style name.
|
||||
| ---------- | ----------- |
|
||||
| Solid | 900 |
|
||||
| Regular | 400 |
|
||||
| Light | 300 |
|
||||
| Thin | 100 |
|
||||
|
||||
### CSS
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
@remove="emit('removeSort', property)"
|
||||
>
|
||||
<span class="property">
|
||||
<UiIcon :icon="isAscending ? faCaretUp : faCaretDown" />
|
||||
<FontAwesomeIcon :icon="isAscending ? faCaretUp : faCaretDown" />
|
||||
{{ property }}
|
||||
</span>
|
||||
</UiFilter>
|
||||
@@ -57,11 +57,10 @@ import {
|
||||
faSort,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import FormWidget from "@/components/FormWidget.vue";
|
||||
import UiActionButton from "@/components/ui/UiActionButton.vue";
|
||||
import UiButton from "@/components/ui/UiButton.vue";
|
||||
import UiActionButton from "@/components/ui/UiActionButton.vue";
|
||||
import UiFilter from "@/components/ui/UiFilter.vue";
|
||||
import UiFilterGroup from "@/components/ui/UiFilterGroup.vue";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
import UiModal from "@/components/ui/UiModal.vue";
|
||||
import useModal from "@/composables/modal.composable";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<th>
|
||||
<div class="content">
|
||||
<span class="label">
|
||||
<UiIcon :icon="icon" />
|
||||
<FontAwesomeIcon v-if="icon" :icon="icon" />
|
||||
<slot />
|
||||
</span>
|
||||
</div>
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
|
||||
defineProps<{
|
||||
icon?: IconDefinition;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<span class="widget">
|
||||
<span v-if="before || $slots.before" class="before">
|
||||
<slot name="before">
|
||||
<UiIcon v-if="isIcon(before)" :icon="before" fixed-width />
|
||||
<FontAwesomeIcon v-if="isIcon(before)" :icon="before" fixed-width />
|
||||
<template v-else>{{ before }}</template>
|
||||
</slot>
|
||||
</span>
|
||||
@@ -17,7 +17,7 @@
|
||||
</span>
|
||||
<span v-if="after || $slots.after" class="after">
|
||||
<slot name="after">
|
||||
<UiIcon v-if="isIcon(after)" :icon="after" fixed-width />
|
||||
<FontAwesomeIcon v-if="isIcon(after)" :icon="after" fixed-width />
|
||||
<template v-else>{{ after }}</template>
|
||||
</slot>
|
||||
</span>
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
|
||||
defineProps<{
|
||||
before?: IconDefinition | string | object; // "object" added as workaround
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<UiIcon :class="className" :icon="icon" class="power-state-icon" />
|
||||
<FontAwesomeIcon class="power-state-icon" :class="className" :icon="icon" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
faQuestion,
|
||||
faStop,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
import type { PowerState } from "@/libs/xen-api";
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -30,7 +29,7 @@ const icon = computed(() => icons[props.state] ?? faQuestion);
|
||||
const className = computed(() => `state-${props.state.toLocaleLowerCase()}`);
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
<style scoped lang="postcss">
|
||||
.power-state-icon {
|
||||
color: var(--color-extra-blue-d60);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="title-bar">
|
||||
<UiIcon :icon="icon" class="icon" />
|
||||
<FontAwesomeIcon :icon="icon" class="icon" />
|
||||
<div class="title">
|
||||
<slot />
|
||||
</div>
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
|
||||
defineProps<{
|
||||
icon: IconDefinition;
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<template>
|
||||
<div class="infra-action">
|
||||
<slot>
|
||||
<UiIcon :icon="icon" fixed-width />
|
||||
<FontAwesomeIcon :icon="icon" fixed-width />
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
|
||||
defineProps<{
|
||||
icon?: IconDefinition;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<a :href="href" class="link" @click="navigate">
|
||||
<UiIcon :icon="icon" class="icon" />
|
||||
<FontAwesomeIcon :icon="icon" class="icon" />
|
||||
<div class="text">
|
||||
<slot />
|
||||
</div>
|
||||
@@ -23,7 +23,6 @@
|
||||
<script lang="ts" setup>
|
||||
import type { RouteLocationRaw } from "vue-router";
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
|
||||
defineProps<{
|
||||
icon: IconDefinition;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<li class="infra-loading-item">
|
||||
<div class="infra-item-label-placeholder">
|
||||
<div class="link-placeholder">
|
||||
<UiIcon :icon="icon" class="icon" />
|
||||
<FontAwesomeIcon :icon="icon" class="icon" />
|
||||
<div class="loader"> </div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
|
||||
defineProps<{
|
||||
icon: IconDefinition;
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
<slot />
|
||||
</span>
|
||||
<span class="remove" @click.stop="emit('remove')">
|
||||
<UiIcon :icon="faRemove" class="icon" />
|
||||
<FontAwesomeIcon :icon="faRemove" class="icon" />
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { faRemove } from "@fortawesome/free-solid-svg-icons";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "edit"): void;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<FontAwesomeIcon
|
||||
v-if="icon !== undefined"
|
||||
:fixed-width="fixedWidth"
|
||||
:icon="icon"
|
||||
:spin="busy"
|
||||
class="ui-icon"
|
||||
:fixed-width="fixedWidth"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
import { computed } from "vue";
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import { faSpinner } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
>
|
||||
<div class="container">
|
||||
<span v-if="onClose" class="close-icon" @click="emit('close')">
|
||||
<UiIcon :icon="faXmark" />
|
||||
<FontAwesomeIcon :icon="faXmark" />
|
||||
</span>
|
||||
<div v-if="icon || $slots.icon" class="modal-icon">
|
||||
<slot name="icon">
|
||||
<UiIcon :icon="icon" />
|
||||
<FontAwesomeIcon :icon="icon" />
|
||||
</slot>
|
||||
</div>
|
||||
<UiTitle v-if="$slots.title" type="h4">
|
||||
@@ -38,7 +38,6 @@ import type { IconDefinition } from "@fortawesome/fontawesome-common-types";
|
||||
import { faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useMagicKeys, whenever } from "@vueuse/core";
|
||||
import UiButtonGroup from "@/components/ui/UiButtonGroup.vue";
|
||||
import UiIcon from "@/components/ui/UiIcon.vue";
|
||||
import UiTitle from "@/components/ui/UiTitle.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
|
||||
@@ -3,11 +3,13 @@ import { createApp } from "vue";
|
||||
import App from "@/App.vue";
|
||||
import i18n from "@/i18n";
|
||||
import router from "@/router";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
app.use(i18n);
|
||||
app.use(createPinia());
|
||||
app.use(router);
|
||||
app.component("FontAwesomeIcon", FontAwesomeIcon);
|
||||
|
||||
app.mount("#root");
|
||||
|
||||
10
packages/vhd-lib/BrokenVhdError.js
Normal file
10
packages/vhd-lib/BrokenVhdError.js
Normal file
@@ -0,0 +1,10 @@
|
||||
'use strict'
|
||||
class BrokenVhdError extends Error {
|
||||
constructor(message, baseError) {
|
||||
super(message)
|
||||
this.code = 'BROKEN_VHD'
|
||||
this.cause = baseError
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BrokenVhdError
|
||||
@@ -9,6 +9,7 @@ const assert = require('assert')
|
||||
const { synchronized } = require('decorator-synchronized')
|
||||
const promisify = require('promise-toolbox/promisify')
|
||||
const zlib = require('zlib')
|
||||
const BrokenVhdError = require('../BrokenVhdError')
|
||||
|
||||
const { debug } = createLogger('vhd-lib:VhdDirectory')
|
||||
|
||||
@@ -110,7 +111,14 @@ exports.VhdDirectory = class VhdDirectory extends VhdAbstract {
|
||||
// EISDIR pathname refers to a directory and the access requested
|
||||
// involved writing (that is, O_WRONLY or O_RDWR is set).
|
||||
// reading the header ensure we have a well formed directory immediatly
|
||||
await vhd.readHeaderAndFooter()
|
||||
try {
|
||||
await vhd.readHeaderAndFooter()
|
||||
} catch (error) {
|
||||
if (error.code === 'ERR_ASSERTION') {
|
||||
throw new BrokenVhdError('Invalid header or footer', error)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
return {
|
||||
dispose: () => {},
|
||||
value: vhd,
|
||||
@@ -185,18 +193,8 @@ exports.VhdDirectory = class VhdDirectory extends VhdAbstract {
|
||||
async readHeaderAndFooter() {
|
||||
await this.#readChunkFilters()
|
||||
|
||||
let bufHeader, bufFooter
|
||||
try {
|
||||
bufHeader = (await this._readChunk('header')).buffer
|
||||
bufFooter = (await this._readChunk('footer')).buffer
|
||||
} catch (error) {
|
||||
// emit an AssertionError if the VHD is broken to stay as close as possible to the VhdFile API
|
||||
if (error.code === 'ENOENT') {
|
||||
assert(false, 'Header And Footer should exists')
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
const bufHeader = (await this._readChunk('header')).buffer
|
||||
const bufFooter = (await this._readChunk('footer')).buffer
|
||||
const footer = unpackFooter(bufFooter)
|
||||
const header = unpackHeader(bufHeader, footer)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ const {
|
||||
} = require('../_constants')
|
||||
const { computeBatSize, sectorsToBytes, unpackHeader, unpackFooter, BUF_BLOCK_UNUSED } = require('./_utils')
|
||||
const { createLogger } = require('@xen-orchestra/log')
|
||||
const BrokenVhdError = require('../BrokenVhdError')
|
||||
const { fuFooter, fuHeader, checksumStruct } = require('../_structs')
|
||||
const { set: mapSetBit } = require('../_bitmap')
|
||||
const { VhdAbstract } = require('./VhdAbstract')
|
||||
@@ -93,7 +94,14 @@ exports.VhdFile = class VhdFile extends VhdAbstract {
|
||||
// EISDIR pathname refers to a directory and the access requested
|
||||
// involved writing (that is, O_WRONLY or O_RDWR is set).
|
||||
// reading the header ensure we have a well formed file immediatly
|
||||
await vhd.readHeaderAndFooter(checkSecondFooter)
|
||||
try {
|
||||
await vhd.readHeaderAndFooter(checkSecondFooter)
|
||||
} catch (error) {
|
||||
if (error.code === 'ERR_ASSERTION') {
|
||||
throw new BrokenVhdError('Invalid header or footer', error)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
return {
|
||||
dispose: () => handler.closeFile(fd),
|
||||
value: vhd,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
exports.BrokenVhdError = require('./BrokenVhdError')
|
||||
exports.chainVhd = require('./chain')
|
||||
exports.checkFooter = require('./checkFooter')
|
||||
exports.checkVhdChain = require('./checkChain')
|
||||
|
||||
@@ -1,17 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
const { BrokenVhdError } = require('.')
|
||||
const { resolveVhdAlias } = require('./aliases')
|
||||
const { VhdDirectory } = require('./Vhd/VhdDirectory.js')
|
||||
const { VhdFile } = require('./Vhd/VhdFile.js')
|
||||
|
||||
class AggregateError extends Error {
|
||||
constructor(errors, message) {
|
||||
super(message)
|
||||
this.errors = errors
|
||||
}
|
||||
}
|
||||
|
||||
exports.openVhd = async function openVhd(handler, path, opts) {
|
||||
const resolved = await resolveVhdAlias(handler, path)
|
||||
try {
|
||||
return await VhdFile.open(handler, resolved, opts)
|
||||
} catch (e) {
|
||||
if (e.code !== 'EISDIR') {
|
||||
throw e
|
||||
}
|
||||
return await VhdDirectory.open(handler, resolved, opts)
|
||||
} catch (vhdDirectoryError) {
|
||||
// it's a directory, but it's an invalid vhd
|
||||
if (vhdDirectoryError instanceof BrokenVhdError) {
|
||||
throw vhdDirectoryError
|
||||
}
|
||||
|
||||
// it's not a vhd directory, try to open it as a vhd file
|
||||
try {
|
||||
return await VhdFile.open(handler, resolved, opts)
|
||||
} catch (vhdFileError) {
|
||||
// this is really a file that looks like a vhd but is broken
|
||||
if (vhdFileError instanceof BrokenVhdError) {
|
||||
throw vhdFileError
|
||||
}
|
||||
// the errors are not vhd related, throw both error to keep a trace
|
||||
throw new AggregateError([vhdDirectoryError, vhdFileError])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user