Compare commits
40 Commits
feat_regis
...
fix-emptyB
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
838576c8be | ||
|
|
e8bc723f98 | ||
|
|
8e65ef7dbc | ||
|
|
0c0251082d | ||
|
|
c250cd9b89 | ||
|
|
d6abdb246b | ||
|
|
5769da3ebc | ||
|
|
4f383635ef | ||
|
|
8a7abc2e54 | ||
|
|
af1650bd14 | ||
|
|
c6fdef33c4 | ||
|
|
5f73f09f59 | ||
|
|
1b0fc62e2e | ||
|
|
aa2dc9206d | ||
|
|
2b1562da81 | ||
|
|
25e270edb4 | ||
|
|
51c11c15a8 | ||
|
|
47922dee56 | ||
|
|
3dda4dbaad | ||
|
|
901f7b3fe2 | ||
|
|
774d66512e | ||
|
|
ec1669a32e | ||
|
|
bbcd4184b0 | ||
|
|
85ec26194b | ||
|
|
f0242380ca | ||
|
|
a624330818 | ||
|
|
3892efcca2 | ||
|
|
c1c122d92c | ||
|
|
b7a66e9f73 | ||
|
|
d92d2efc78 | ||
|
|
c2cb51a470 | ||
|
|
5242affdc1 | ||
|
|
71f3be288b | ||
|
|
58769815b0 | ||
|
|
c81c23c0d0 | ||
|
|
f06f89b5b4 | ||
|
|
fa748ed9de | ||
|
|
cd753acff7 | ||
|
|
8ff861e2be | ||
|
|
95ccb2e0ae |
@@ -48,7 +48,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['@xen-orchestra/lite/**/*.{vue,ts}'],
|
||||
files: ['@xen-orchestra/{web-core,lite,web}/**/*.{vue,ts}'],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
},
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -36,3 +36,6 @@ yarn-error.log.*
|
||||
.nyc_output/
|
||||
coverage/
|
||||
.turbo/
|
||||
|
||||
# https://node-tap.org/dot-tap-folder/
|
||||
.tap/
|
||||
|
||||
@@ -62,6 +62,42 @@ decorateClass(Foo, {
|
||||
})
|
||||
```
|
||||
|
||||
### `decorateObject(object, map)`
|
||||
|
||||
Decorates an object the same way `decorateClass()` decorates a class:
|
||||
|
||||
```js
|
||||
import { decorateObject } from '@vates/decorate-with'
|
||||
|
||||
const object = {
|
||||
get bar() {
|
||||
// body
|
||||
},
|
||||
|
||||
set bar(value) {
|
||||
// body
|
||||
},
|
||||
|
||||
baz() {
|
||||
// body
|
||||
},
|
||||
}
|
||||
|
||||
decorateObject(object, {
|
||||
// getter and/or setter
|
||||
bar: {
|
||||
// without arguments
|
||||
get: lodash.memoize,
|
||||
|
||||
// with arguments
|
||||
set: [lodash.debounce, 150],
|
||||
},
|
||||
|
||||
// method (with or without arguments)
|
||||
baz: lodash.curry,
|
||||
})
|
||||
```
|
||||
|
||||
### `perInstance(fn, ...args)`
|
||||
|
||||
Helper to decorate the method by instance instead of for the whole class.
|
||||
|
||||
@@ -80,6 +80,42 @@ decorateClass(Foo, {
|
||||
})
|
||||
```
|
||||
|
||||
### `decorateObject(object, map)`
|
||||
|
||||
Decorates an object the same way `decorateClass()` decorates a class:
|
||||
|
||||
```js
|
||||
import { decorateObject } from '@vates/decorate-with'
|
||||
|
||||
const object = {
|
||||
get bar() {
|
||||
// body
|
||||
},
|
||||
|
||||
set bar(value) {
|
||||
// body
|
||||
},
|
||||
|
||||
baz() {
|
||||
// body
|
||||
},
|
||||
}
|
||||
|
||||
decorateObject(object, {
|
||||
// getter and/or setter
|
||||
bar: {
|
||||
// without arguments
|
||||
get: lodash.memoize,
|
||||
|
||||
// with arguments
|
||||
set: [lodash.debounce, 150],
|
||||
},
|
||||
|
||||
// method (with or without arguments)
|
||||
baz: lodash.curry,
|
||||
})
|
||||
```
|
||||
|
||||
### `perInstance(fn, ...args)`
|
||||
|
||||
Helper to decorate the method by instance instead of for the whole class.
|
||||
|
||||
@@ -14,10 +14,13 @@ function applyDecorator(decorator, value) {
|
||||
}
|
||||
|
||||
exports.decorateClass = exports.decorateMethodsWith = function decorateClass(klass, map) {
|
||||
const { prototype } = klass
|
||||
return decorateObject(klass.prototype, map)
|
||||
}
|
||||
|
||||
function decorateObject(object, map) {
|
||||
for (const name of Object.keys(map)) {
|
||||
const decorator = map[name]
|
||||
const descriptor = getOwnPropertyDescriptor(prototype, name)
|
||||
const descriptor = getOwnPropertyDescriptor(object, name)
|
||||
if (typeof decorator === 'function' || Array.isArray(decorator)) {
|
||||
descriptor.value = applyDecorator(decorator, descriptor.value)
|
||||
} else {
|
||||
@@ -30,10 +33,11 @@ exports.decorateClass = exports.decorateMethodsWith = function decorateClass(kla
|
||||
}
|
||||
}
|
||||
|
||||
defineProperty(prototype, name, descriptor)
|
||||
defineProperty(object, name, descriptor)
|
||||
}
|
||||
return klass
|
||||
return object
|
||||
}
|
||||
exports.decorateObject = decorateObject
|
||||
|
||||
exports.perInstance = function perInstance(fn, decorator, ...args) {
|
||||
const map = new WeakMap()
|
||||
|
||||
28
@vates/fuse-vhd/.USAGE.md
Normal file
28
@vates/fuse-vhd/.USAGE.md
Normal file
@@ -0,0 +1,28 @@
|
||||
Mount a vhd generated by xen-orchestra to filesystem
|
||||
|
||||
### Library
|
||||
|
||||
```js
|
||||
import { mount } from 'fuse-vhd'
|
||||
|
||||
// return a disposable, see promise-toolbox/Disposable
|
||||
// unmount automatically when disposable is disposed
|
||||
// in case of differencing VHD, it mounts the full chain
|
||||
await mount(handler, diskId, mountPoint)
|
||||
```
|
||||
|
||||
### cli
|
||||
|
||||
From the install folder :
|
||||
|
||||
```
|
||||
cli.mjs <remoteUrl> <vhdPathInRemote> <mountPoint>
|
||||
```
|
||||
|
||||
After installing the package
|
||||
|
||||
```
|
||||
xo-fuse-vhd <remoteUrl> <vhdPathInRemote> <mountPoint>
|
||||
```
|
||||
|
||||
remoteUrl can be found by using cli in `@xen-orchestra/fs` , for example a local remote will have a url like `file:///path/to/remote/root`
|
||||
59
@vates/fuse-vhd/README.md
Normal file
59
@vates/fuse-vhd/README.md
Normal file
@@ -0,0 +1,59 @@
|
||||
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->
|
||||
|
||||
# @vates/fuse-vhd
|
||||
|
||||
[](https://npmjs.org/package/@vates/fuse-vhd)  [](https://bundlephobia.com/result?p=@vates/fuse-vhd) [](https://npmjs.org/package/@vates/fuse-vhd)
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/@vates/fuse-vhd):
|
||||
|
||||
```sh
|
||||
npm install --save @vates/fuse-vhd
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Mount a vhd generated by xen-orchestra to filesystem
|
||||
|
||||
### Library
|
||||
|
||||
```js
|
||||
import { mount } from 'fuse-vhd'
|
||||
|
||||
// return a disposable, see promise-toolbox/Disposable
|
||||
// unmount automatically when disposable is disposed
|
||||
// in case of differencing VHD, it mounts the full chain
|
||||
await mount(handler, diskId, mountPoint)
|
||||
```
|
||||
|
||||
### cli
|
||||
|
||||
From the install folder :
|
||||
|
||||
```
|
||||
cli.mjs <remoteUrl> <vhdPathInRemote> <mountPoint>
|
||||
```
|
||||
|
||||
After installing the package
|
||||
|
||||
```
|
||||
xo-fuse-vhd <remoteUrl> <vhdPathInRemote> <mountPoint>
|
||||
```
|
||||
|
||||
remoteUrl can be found by using cli in `@xen-orchestra/fs` , for example a local remote will have a url like `file:///path/to/remote/root`
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[ISC](https://spdx.org/licenses/ISC) © [Vates SAS](https://vates.fr)
|
||||
26
@vates/fuse-vhd/cli.mjs
Executable file
26
@vates/fuse-vhd/cli.mjs
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import Disposable from 'promise-toolbox/Disposable'
|
||||
import { getSyncedHandler } from '@xen-orchestra/fs'
|
||||
|
||||
import { mount } from './index.mjs'
|
||||
|
||||
async function* main([remoteUrl, vhdPathInRemote, mountPoint]) {
|
||||
if (mountPoint === undefined) {
|
||||
throw new TypeError('missing arg: cli <remoteUrl> <vhdPathInRemote> <mountPoint>')
|
||||
}
|
||||
const handler = yield getSyncedHandler({ url: remoteUrl })
|
||||
const mounted = await mount(handler, vhdPathInRemote, mountPoint)
|
||||
|
||||
let disposePromise
|
||||
process.on('SIGINT', async () => {
|
||||
// ensure single dispose
|
||||
if (!disposePromise) {
|
||||
disposePromise = mounted.dispose()
|
||||
}
|
||||
await disposePromise
|
||||
process.exit()
|
||||
})
|
||||
}
|
||||
|
||||
Disposable.wrap(main)(process.argv.slice(2))
|
||||
@@ -58,7 +58,7 @@ export const mount = Disposable.factory(async function* mount(handler, diskPath,
|
||||
},
|
||||
})
|
||||
return new Disposable(
|
||||
() => fromCallback(() => fuse.unmount()),
|
||||
fromCallback(() => fuse.mount())
|
||||
() => fromCallback(cb => fuse.unmount(cb)),
|
||||
fromCallback(cb => fuse.mount(cb))
|
||||
)
|
||||
})
|
||||
|
||||
@@ -19,11 +19,15 @@
|
||||
},
|
||||
"main": "./index.mjs",
|
||||
"dependencies": {
|
||||
"@xen-orchestra/fs": "^4.1.3",
|
||||
"fuse-native": "^2.2.6",
|
||||
"lru-cache": "^7.14.0",
|
||||
"promise-toolbox": "^0.21.0",
|
||||
"vhd-lib": "^4.9.0"
|
||||
},
|
||||
"bin": {
|
||||
"xo-fuse-vhd": "./cli.mjs"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
}
|
||||
|
||||
@@ -86,7 +86,12 @@ export const VmsRemote = class RemoteVmsBackupRunner extends Abstract {
|
||||
throw new Error(`Job mode ${job.mode} not implemented for mirror backup`)
|
||||
}
|
||||
|
||||
return runTask(taskStart, () => vmBackup.run())
|
||||
return sourceRemoteAdapter
|
||||
.listVmBackups(vmUuid, ({ mode }) => mode === job.mode)
|
||||
.then(vmBackups => {
|
||||
// avoiding to create tasks for empty directories
|
||||
if (vmBackups.length > 0) return runTask(taskStart, () => vmBackup.run())
|
||||
})
|
||||
}
|
||||
const { concurrency } = settings
|
||||
await asyncMapSettled(vmsUuids, !concurrency ? handleVm : limitConcurrency(concurrency)(handleVm))
|
||||
|
||||
@@ -2,8 +2,20 @@ import mapValues from 'lodash/mapValues.js'
|
||||
import { dirname } from 'node:path'
|
||||
|
||||
function formatVmBackup(backup) {
|
||||
const { isVhdDifferencing } = backup
|
||||
const { isVhdDifferencing, vmSnapshot } = backup
|
||||
|
||||
let differencingVhds
|
||||
let dynamicVhds
|
||||
const withMemory = vmSnapshot.suspend_VDI !== 'OpaqueRef:NULL'
|
||||
// isVhdDifferencing is either undefined or an object
|
||||
if (isVhdDifferencing !== undefined) {
|
||||
differencingVhds = Object.values(isVhdDifferencing).filter(t => t).length
|
||||
dynamicVhds = Object.values(isVhdDifferencing).filter(t => !t).length
|
||||
if (withMemory) {
|
||||
// the suspend VDI (memory) is always a dynamic
|
||||
dynamicVhds -= 1
|
||||
}
|
||||
}
|
||||
return {
|
||||
disks:
|
||||
backup.vhds === undefined
|
||||
@@ -28,9 +40,9 @@ function formatVmBackup(backup) {
|
||||
name_label: backup.vm.name_label,
|
||||
},
|
||||
|
||||
// isVhdDifferencing is either undefined or an object
|
||||
differencingVhds: isVhdDifferencing && Object.values(isVhdDifferencing).filter(t => t).length,
|
||||
dynamicVhds: isVhdDifferencing && Object.values(isVhdDifferencing).filter(t => !t).length,
|
||||
differencingVhds,
|
||||
dynamicVhds,
|
||||
withMemory,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>XO Lite</title>
|
||||
</head>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"type-check": "vue-tsc --build --force tsconfig.type-check.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@csstools/postcss-global-data": "^2.1.1",
|
||||
"@fontsource/poppins": "^5.0.8",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
@@ -22,16 +23,16 @@
|
||||
"@intlify/unplugin-vue-i18n": "^2.0.0",
|
||||
"@novnc/novnc": "^1.4.0",
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"strip-json-comments": "^5.0.1",
|
||||
"@types/d3-time-format": "^4.0.3",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^18.19.5",
|
||||
"@vitejs/plugin-vue": "^5.0.2",
|
||||
"@types/node": "^18.19.7",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"@vueuse/core": "^10.7.1",
|
||||
"@vueuse/math": "^10.7.1",
|
||||
"@vueuse/shared": "^10.7.1",
|
||||
"@xen-orchestra/web-core": "*",
|
||||
"complex-matcher": "^0.7.1",
|
||||
"d3-time-format": "^4.1.0",
|
||||
"decorator-synchronized": "^0.6.0",
|
||||
@@ -51,15 +52,16 @@
|
||||
"pinia": "^2.1.7",
|
||||
"placement.js": "^1.0.0-beta.5",
|
||||
"postcss": "^8.4.33",
|
||||
"postcss-color-function": "^4.1.0",
|
||||
"postcss-custom-media": "^10.0.2",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"typescript": "^5.3.3",
|
||||
"typescript": "~5.3.3",
|
||||
"vite": "^5.0.11",
|
||||
"vue": "^3.4.7",
|
||||
"vue": "^3.4.13",
|
||||
"vue-echarts": "^6.6.8",
|
||||
"vue-i18n": "^9.9.0",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue-tsc": "^1.8.22",
|
||||
"vue-tsc": "^1.8.27",
|
||||
"zx": "^7.2.3"
|
||||
},
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
export default {
|
||||
plugins: {
|
||||
'@csstools/postcss-global-data': {
|
||||
files: ['../web-core/lib/assets/css/.globals.pcss'],
|
||||
},
|
||||
'postcss-nested': {},
|
||||
'postcss-custom-media': {},
|
||||
'postcss-color-function': {},
|
||||
},
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -16,7 +16,6 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import favicon from '@/assets/favicon.svg'
|
||||
import AppHeader from '@/components/AppHeader.vue'
|
||||
import AppLogin from '@/components/AppLogin.vue'
|
||||
import AppNavigation from '@/components/AppNavigation.vue'
|
||||
@@ -32,14 +31,6 @@ import { logicAnd } from '@vueuse/math'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement | null
|
||||
if (link == null) {
|
||||
link = document.createElement('link')
|
||||
link.rel = 'icon'
|
||||
document.getElementsByTagName('head')[0].appendChild(link)
|
||||
}
|
||||
link.href = favicon
|
||||
|
||||
const xenApiStore = useXenApiStore()
|
||||
|
||||
const { pool } = usePoolCollection()
|
||||
@@ -75,10 +66,6 @@ whenever(
|
||||
useUnreachableHosts()
|
||||
</script>
|
||||
|
||||
<style lang="postcss">
|
||||
@import '@/assets/base.css';
|
||||
</style>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.main {
|
||||
overflow: auto;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
@custom-media --mobile (max-width: 1023px);
|
||||
@custom-media --desktop (min-width: 1024px);
|
||||
@@ -1,100 +0,0 @@
|
||||
@import 'reset.css';
|
||||
@import 'theme.css';
|
||||
@import '@fontsource/poppins/400.css';
|
||||
@import '@fontsource/poppins/500.css';
|
||||
@import '@fontsource/poppins/600.css';
|
||||
@import '@fontsource/poppins/700.css';
|
||||
@import '@fontsource/poppins/900.css';
|
||||
@import '@fontsource/poppins/400-italic.css';
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-size: 1.3rem;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: var(--color-blue-scale-100);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-extra-blue-base);
|
||||
}
|
||||
|
||||
code,
|
||||
code *,
|
||||
pre {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.card-view {
|
||||
padding: 1.2rem;
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.link {
|
||||
text-decoration: underline;
|
||||
color: var(--color-extra-blue-base);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: var(--color-extra-blue-d20);
|
||||
}
|
||||
|
||||
.link:active,
|
||||
.link.router-link-active {
|
||||
color: var(--color-extra-blue-d40);
|
||||
}
|
||||
|
||||
.link.router-link-active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.context-color-success {
|
||||
color: var(--color-green-infra-base);
|
||||
}
|
||||
|
||||
.context-color-error {
|
||||
color: var(--color-red-vates-base);
|
||||
}
|
||||
|
||||
.context-color-warning {
|
||||
color: var(--color-orange-world-base);
|
||||
}
|
||||
|
||||
.context-color-info {
|
||||
color: var(--color-extra-blue-base);
|
||||
}
|
||||
|
||||
.context-background-color-success {
|
||||
background-color: var(--background-color-green-infra);
|
||||
}
|
||||
|
||||
.context-background-color-error {
|
||||
background-color: var(--background-color-red-vates);
|
||||
}
|
||||
|
||||
.context-background-color-warning {
|
||||
background-color: var(--background-color-orange-world);
|
||||
}
|
||||
|
||||
.context-background-color-info {
|
||||
background-color: var(--background-color-extra-blue);
|
||||
}
|
||||
|
||||
.context-border-color-success {
|
||||
border-color: var(--color-green-infra-base);
|
||||
}
|
||||
|
||||
.context-border-color-error {
|
||||
border-color: var(--color-red-vates-base);
|
||||
}
|
||||
|
||||
.context-border-color-warning {
|
||||
border-color: var(--color-orange-world-base);
|
||||
}
|
||||
|
||||
.context-border-color-info {
|
||||
border-color: var(--color-extra-blue-base);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 10 KiB |
@@ -1,87 +0,0 @@
|
||||
:root {
|
||||
--color-logo: #282467;
|
||||
|
||||
--color-blue-scale-000: #000000;
|
||||
--color-blue-scale-100: #1a1b38;
|
||||
--color-blue-scale-200: #595a6f;
|
||||
--color-blue-scale-300: #9899a5;
|
||||
--color-blue-scale-400: #e5e5e7;
|
||||
--color-blue-scale-500: #ffffff;
|
||||
|
||||
--color-extra-blue-l60: #d1cefb;
|
||||
--color-extra-blue-l40: #bbb5f9;
|
||||
--color-extra-blue-l20: #a39df8;
|
||||
--color-extra-blue-base: #8f84ff;
|
||||
--color-extra-blue-d20: #716ac6;
|
||||
--color-extra-blue-d40: #554f94;
|
||||
--color-extra-blue-d60: #383563;
|
||||
|
||||
--color-green-infra-l60: #b5dbca;
|
||||
--color-green-infra-l40: #91c9b0;
|
||||
--color-green-infra-l20: #70b795;
|
||||
--color-green-infra-base: #55a57b;
|
||||
--color-green-infra-d20: #438463;
|
||||
--color-green-infra-d40: #32634a;
|
||||
--color-green-infra-d60: #214231;
|
||||
|
||||
--color-orange-world-l60: #f2cda8;
|
||||
--color-orange-world-l40: #ebb57d;
|
||||
--color-orange-world-l20: #e59d56;
|
||||
--color-orange-world-base: #ef7f18;
|
||||
--color-orange-world-d20: #bf6612;
|
||||
--color-orange-world-d40: #864f1f;
|
||||
--color-orange-world-d60: #5a3514;
|
||||
|
||||
--color-red-vates-l60: #dda5a7;
|
||||
--color-red-vates-l40: #ce787c;
|
||||
--color-red-vates-l20: #bf4f51;
|
||||
--color-red-vates-base: #be1621;
|
||||
--color-red-vates-d20: #8e2221;
|
||||
--color-red-vates-d40: #6a1919;
|
||||
--color-red-vates-d60: #471010;
|
||||
|
||||
--color-grayscale-200: #585757;
|
||||
|
||||
--background-color-primary: #ffffff;
|
||||
--background-color-secondary: #f6f6f7;
|
||||
--background-color-extra-blue: #f4f3fe;
|
||||
--background-color-green-infra: #ecf5f2;
|
||||
--background-color-orange-world: #fbf2e9;
|
||||
--background-color-red-vates: #f5e8e9;
|
||||
|
||||
--shadow-100: 0 0.1rem 0.1rem rgba(20, 20, 30, 0.06);
|
||||
--shadow-200: 0 0.1rem 0.3rem rgba(20, 20, 30, 0.1), 0 0.2rem 0.1rem rgba(20, 20, 30, 0.06),
|
||||
0 0.1rem 0.1rem rgba(20, 20, 30, 0.08);
|
||||
--shadow-300: 0 0.3rem 0.5rem rgba(20, 20, 30, 0.1), 0 0.1rem 1.8rem rgba(20, 20, 30, 0.06),
|
||||
0 0.6rem 1rem rgba(20, 20, 30, 0.08);
|
||||
--shadow-400: 0 1.1rem 1.5rem rgba(20, 20, 30, 0.1), 0 0.9rem 4.6rem rgba(20, 20, 30, 0.06),
|
||||
0 2.4rem 3.8rem rgba(20, 20, 30, 0.04);
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
color-scheme: dark;
|
||||
|
||||
--color-logo: #e5e5e7;
|
||||
|
||||
--color-blue-scale-000: #ffffff;
|
||||
--color-blue-scale-100: #e5e5e7;
|
||||
--color-blue-scale-200: #9899a5;
|
||||
--color-blue-scale-300: #595a6f;
|
||||
--color-blue-scale-400: #1a1b38;
|
||||
--color-blue-scale-500: #000000;
|
||||
|
||||
--background-color-primary: #14141d;
|
||||
--background-color-secondary: #17182a;
|
||||
--background-color-extra-blue: #35335d;
|
||||
--background-color-green-infra: #243b3d;
|
||||
--background-color-orange-world: #493328;
|
||||
--background-color-red-vates: #3c1a28;
|
||||
|
||||
--shadow-100: 0 0.1rem 0.1rem rgba(20, 20, 30, 0.12);
|
||||
--shadow-200: 0 0.1rem 0.3rem rgba(20, 20, 30, 0.2), 0 0.2rem 0.1rem rgba(20, 20, 30, 0.12),
|
||||
0 0.1rem 0.1rem rgba(20, 20, 30, 0.16);
|
||||
--shadow-300: 0 0.3rem 0.5rem rgba(20, 20, 30, 0.2), 0 0.1rem 1.8rem rgba(20, 20, 30, 0.12),
|
||||
0 0.6rem 1rem rgba(20, 20, 30, 0.16);
|
||||
--shadow-400: 0 1.1rem 1.5rem rgba(20, 20, 30, 0.2), 0 0.9rem 4.6rem rgba(20, 20, 30, 0.12),
|
||||
0 2.4rem 3.8rem rgba(20, 20, 30, 0.08);
|
||||
}
|
||||
@@ -51,14 +51,14 @@ const openSettings = () => router.push({ name: 'settings' })
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
border: none;
|
||||
border-radius: 0.8rem;
|
||||
background-color: var(--background-color-secondary);
|
||||
gap: 0.8rem;
|
||||
|
||||
&:disabled {
|
||||
color: var(--color-blue-scale-400);
|
||||
color: var(--color-grey-500);
|
||||
}
|
||||
|
||||
&:not(:disabled) {
|
||||
@@ -72,7 +72,7 @@ const openSettings = () => router.push({ name: 'settings' })
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,6 @@ const openSettings = () => router.push({ name: 'settings' })
|
||||
}
|
||||
|
||||
.menu-item-logout {
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -46,7 +46,7 @@ const { trigger: navigationTrigger } = storeToRefs(navigationStore)
|
||||
justify-content: space-between;
|
||||
height: 5.5rem;
|
||||
padding: 1rem;
|
||||
border-bottom: 0.1rem solid var(--color-blue-scale-400);
|
||||
border-bottom: 0.1rem solid var(--color-grey-500);
|
||||
background-color: var(--background-color-secondary);
|
||||
|
||||
img {
|
||||
|
||||
@@ -135,7 +135,7 @@ form {
|
||||
background-color: var(--background-color-secondary);
|
||||
|
||||
.error {
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ input {
|
||||
max-width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem 1.5rem;
|
||||
border: 1px solid var(--color-blue-scale-400);
|
||||
border: 1px solid var(--color-grey-500);
|
||||
border-radius: 0.8rem;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ useEventListener(
|
||||
}
|
||||
|
||||
code:not(.hljs-code) {
|
||||
background-color: var(--background-color-extra-blue);
|
||||
background-color: var(--background-color-purple-10);
|
||||
padding: 0.3rem 0.6rem;
|
||||
border-radius: 0.6rem;
|
||||
}
|
||||
@@ -81,12 +81,12 @@ useEventListener(
|
||||
}
|
||||
|
||||
thead th {
|
||||
border-bottom: 2px solid var(--color-blue-scale-400);
|
||||
border-bottom: 2px solid var(--color-grey-500);
|
||||
background-color: var(--background-color-secondary);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
border-bottom: 1px solid var(--color-blue-scale-400);
|
||||
border-bottom: 1px solid var(--color-grey-500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,11 +103,11 @@ useEventListener(
|
||||
background-color: transparent;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: var(--color-extra-blue-d20);
|
||||
color: var(--color-purple-d20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ whenever(isOpen, () => {
|
||||
max-width: 37rem;
|
||||
height: calc(100vh - 5.5rem);
|
||||
padding: 0.5rem;
|
||||
border-right: 1px solid var(--color-blue-scale-400);
|
||||
border-right: 1px solid var(--color-grey-500);
|
||||
background-color: var(--background-color-primary);
|
||||
|
||||
&.collapsible {
|
||||
|
||||
@@ -41,9 +41,9 @@ watchEffect(() => {
|
||||
display: inline-flex;
|
||||
padding: 0.3125em 0.5em;
|
||||
pointer-events: none;
|
||||
color: var(--color-blue-scale-500);
|
||||
color: var(--color-grey-600);
|
||||
border-radius: 0.5em;
|
||||
background-color: var(--color-blue-scale-100);
|
||||
background-color: var(--color-grey-100);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@@ -145,6 +145,6 @@ watchEffect(() => {
|
||||
content: '';
|
||||
transform: rotate(45deg) skew(20deg, 20deg);
|
||||
border-radius: 0.3125em;
|
||||
background-color: var(--color-blue-scale-100);
|
||||
background-color: var(--color-grey-100);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -54,14 +54,14 @@ const isIcon = (maybeIcon: any): maybeIcon is IconDefinition => typeof maybeIcon
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
padding: 0 0.7rem;
|
||||
border: 1px solid var(--color-blue-scale-400);
|
||||
border: 1px solid var(--color-grey-500);
|
||||
border-radius: 0.8rem;
|
||||
background-color: var(--color-blue-scale-500);
|
||||
background-color: var(--color-grey-600);
|
||||
box-shadow: var(--shadow-100);
|
||||
gap: 0.1rem;
|
||||
|
||||
&:focus-within {
|
||||
outline: 1px solid var(--color-extra-blue-l40);
|
||||
outline: 1px solid var(--color-purple-l40);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ const isIcon = (maybeIcon: any): maybeIcon is IconDefinition => typeof maybeIcon
|
||||
}
|
||||
|
||||
.form-widget:hover .widget {
|
||||
border-color: var(--color-extra-blue-l60);
|
||||
border-color: var(--color-purple-l60);
|
||||
}
|
||||
|
||||
.element {
|
||||
@@ -93,8 +93,8 @@ const isIcon = (maybeIcon: any): maybeIcon is IconDefinition => typeof maybeIcon
|
||||
font-size: inherit;
|
||||
border: none;
|
||||
outline: none;
|
||||
color: var(--color-blue-scale-100);
|
||||
background-color: var(--color-blue-scale-500);
|
||||
color: var(--color-grey-100);
|
||||
background-color: var(--color-grey-600);
|
||||
flex: 1;
|
||||
|
||||
&:disabled {
|
||||
@@ -134,7 +134,7 @@ const isIcon = (maybeIcon: any): maybeIcon is IconDefinition => typeof maybeIcon
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,7 +25,7 @@ defineProps<{
|
||||
font-size: 1.3rem;
|
||||
line-height: 150%;
|
||||
margin: 0.5rem 0;
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
|
||||
& svg {
|
||||
margin-right: 0.5rem;
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
font-weight: 500;
|
||||
font-size: 1.25em;
|
||||
line-height: 150%;
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
font-weight: 500;
|
||||
font-size: 2rem;
|
||||
line-height: 150%;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -85,7 +85,7 @@ const objectRoute = computed(() => {
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.unknown {
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -33,7 +33,7 @@ const isRecordNotFound = computed(() => props.isReady && !props.uuidChecker(id.v
|
||||
}
|
||||
|
||||
.spinner {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
display: flex;
|
||||
margin: auto;
|
||||
width: 10rem;
|
||||
|
||||
@@ -26,7 +26,7 @@ import UiStatusPanel from '@/components/ui/UiStatusPanel.vue'
|
||||
.contact {
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
|
||||
& a {
|
||||
text-transform: lowercase;
|
||||
|
||||
@@ -44,7 +44,7 @@ const masterSessionStorage = useSessionStorage('master', null)
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.warning-not-current-pool {
|
||||
color: var(--color-orange-world-base);
|
||||
color: var(--color-orange-base);
|
||||
cursor: pointer;
|
||||
|
||||
.wrapper {
|
||||
|
||||
@@ -26,18 +26,18 @@ const className = computed(() => `state-${props.state.toLocaleLowerCase()}`)
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.power-state-icon {
|
||||
color: var(--color-extra-blue-d60);
|
||||
color: var(--color-purple-d60);
|
||||
|
||||
&.state-running {
|
||||
color: var(--color-green-infra-base);
|
||||
color: var(--color-green-base);
|
||||
}
|
||||
|
||||
&.state-paused {
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
}
|
||||
|
||||
&.state-suspended {
|
||||
color: var(--color-extra-blue-d20);
|
||||
color: var(--color-purple-d20);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -37,7 +37,7 @@ const progress = computed(() => {
|
||||
.progress-circle-fill {
|
||||
animation: progress 1s ease-out forwards;
|
||||
fill: none;
|
||||
stroke: var(--color-green-infra-base);
|
||||
stroke: var(--color-green-base);
|
||||
stroke-width: 1.2;
|
||||
stroke-linecap: round;
|
||||
stroke-dasharray: v-bind(progress), 100;
|
||||
@@ -46,13 +46,13 @@ const progress = computed(() => {
|
||||
.progress-circle-background {
|
||||
fill: none;
|
||||
stroke-width: 1.2;
|
||||
stroke: var(--color-blue-scale-400);
|
||||
stroke: var(--color-grey-500);
|
||||
}
|
||||
|
||||
.progress-circle-text {
|
||||
font-size: 0.7rem;
|
||||
font-weight: bold;
|
||||
fill: var(--color-green-infra-base);
|
||||
fill: var(--color-green-base);
|
||||
text-anchor: middle;
|
||||
alignment-baseline: middle;
|
||||
}
|
||||
|
||||
@@ -29,18 +29,18 @@ defineProps<{
|
||||
align-items: center;
|
||||
height: 6rem;
|
||||
padding: 0 1.5rem;
|
||||
border-bottom: 1px solid var(--color-blue-scale-400);
|
||||
border-bottom: 1px solid var(--color-grey-500);
|
||||
background-color: var(--background-color-primary);
|
||||
gap: 0.8rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 2.5rem;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -60,28 +60,28 @@ const computedData = computed(() => {
|
||||
}
|
||||
|
||||
.progress-item:nth-child(1) {
|
||||
--progress-bar-color: var(--color-extra-blue-d60);
|
||||
--progress-bar-color: var(--color-purple-d60);
|
||||
}
|
||||
|
||||
.progress-item:nth-child(2) {
|
||||
--progress-bar-color: var(--color-extra-blue-d40);
|
||||
--progress-bar-color: var(--color-purple-d40);
|
||||
}
|
||||
|
||||
.progress-item:nth-child(3) {
|
||||
--progress-bar-color: var(--color-extra-blue-d20);
|
||||
--progress-bar-color: var(--color-purple-d20);
|
||||
}
|
||||
|
||||
.progress-item {
|
||||
--progress-bar-height: 1.2rem;
|
||||
--progress-bar-color: var(--color-extra-blue-l20);
|
||||
--progress-bar-background-color: var(--color-blue-scale-400);
|
||||
--progress-bar-color: var(--color-purple-l20);
|
||||
--progress-bar-background-color: var(--color-grey-500);
|
||||
|
||||
&.warning {
|
||||
--progress-bar-color: var(--color-orange-world-base);
|
||||
--progress-bar-color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
&.error {
|
||||
--progress-bar-color: var(--color-red-vates-base);
|
||||
--progress-bar-color: var(--color-red-base);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
th,
|
||||
td {
|
||||
padding: 0.3rem 0.6rem;
|
||||
border-bottom: 0.1rem solid var(--color-blue-scale-400);
|
||||
border-bottom: 0.1rem solid var(--color-grey-500);
|
||||
vertical-align: center;
|
||||
}
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: var(--background-color-extra-blue);
|
||||
background-color: var(--background-color-purple-10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,14 +127,14 @@ const openRawValueModal = (code: string) =>
|
||||
align-items: center;
|
||||
padding: 0.4rem 0.6rem;
|
||||
cursor: pointer;
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
border-radius: 0.4rem;
|
||||
gap: 0.6rem;
|
||||
|
||||
&.active {
|
||||
font-weight: 600;
|
||||
cursor: default;
|
||||
color: var(--color-green-infra-l20);
|
||||
color: var(--color-green-l20);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,7 @@ const openRawValueModal = (code: string) =>
|
||||
|
||||
.help {
|
||||
font-style: italic;
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
}
|
||||
|
||||
.default-value {
|
||||
@@ -168,12 +168,12 @@ const openRawValueModal = (code: string) =>
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
opacity: 1;
|
||||
color: var(--color-green-infra-base);
|
||||
color: var(--color-green-base);
|
||||
}
|
||||
}
|
||||
|
||||
.v-model-indicator,
|
||||
.context-indicator {
|
||||
color: var(--color-green-infra-base);
|
||||
color: var(--color-green-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -81,7 +81,7 @@ const isIndeterminate = computed(() => (type === 'checkbox' || type === 'toggle'
|
||||
|
||||
.input.indeterminate + .fake-checkbox > .icon {
|
||||
opacity: 1;
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ const isIndeterminate = computed(() => (type === 'checkbox' || type === 'toggle'
|
||||
|
||||
.fake-checkbox {
|
||||
width: 2.5em;
|
||||
--background-color: var(--color-blue-scale-400);
|
||||
--background-color: var(--color-grey-500);
|
||||
}
|
||||
|
||||
.icon {
|
||||
@@ -128,7 +128,7 @@ const isIndeterminate = computed(() => (type === 'checkbox' || type === 'toggle'
|
||||
|
||||
.input.indeterminate + .fake-checkbox > .icon {
|
||||
opacity: 1;
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,7 @@ const isIndeterminate = computed(() => (type === 'checkbox' || type === 'toggle'
|
||||
.icon {
|
||||
font-size: var(--checkbox-icon-size);
|
||||
position: absolute;
|
||||
color: var(--color-blue-scale-500);
|
||||
color: var(--color-grey-600);
|
||||
|
||||
filter: drop-shadow(0 0.0625em 0.5em rgba(0, 0, 0, 0.1)) drop-shadow(0 0.1875em 0.1875em rgba(0, 0, 0, 0.06))
|
||||
drop-shadow(0 0.1875em 0.25em rgba(0, 0, 0, 0.08));
|
||||
@@ -162,44 +162,44 @@ const isIndeterminate = computed(() => (type === 'checkbox' || type === 'toggle'
|
||||
background-color: var(--background-color);
|
||||
box-shadow: var(--shadow-100);
|
||||
|
||||
--border-color: var(--color-blue-scale-400);
|
||||
--border-color: var(--color-grey-500);
|
||||
}
|
||||
|
||||
.input:disabled {
|
||||
& + .fake-checkbox {
|
||||
cursor: not-allowed;
|
||||
--background-color: var(--background-color-secondary);
|
||||
--border-color: var(--color-blue-scale-400);
|
||||
--border-color: var(--color-grey-500);
|
||||
}
|
||||
|
||||
&:checked + .fake-checkbox {
|
||||
--border-color: transparent;
|
||||
--background-color: var(--color-extra-blue-l60);
|
||||
--background-color: var(--color-purple-l60);
|
||||
}
|
||||
}
|
||||
|
||||
.input:not(:disabled) {
|
||||
&:hover + .fake-checkbox,
|
||||
&:focus + .fake-checkbox {
|
||||
--border-color: var(--color-extra-blue-l40);
|
||||
--border-color: var(--color-purple-l40);
|
||||
}
|
||||
|
||||
&:active + .fake-checkbox {
|
||||
--border-color: var(--color-extra-blue-l20);
|
||||
--border-color: var(--color-purple-l20);
|
||||
}
|
||||
|
||||
&:checked + .fake-checkbox {
|
||||
--border-color: transparent;
|
||||
--background-color: var(--color-extra-blue-base);
|
||||
--background-color: var(--color-purple-base);
|
||||
}
|
||||
|
||||
&:checked:hover + .fake-checkbox,
|
||||
&:checked:focus + .fake-checkbox {
|
||||
--background-color: var(--color-extra-blue-d20);
|
||||
--background-color: var(--color-purple-d20);
|
||||
}
|
||||
|
||||
&:checked:active + .fake-checkbox {
|
||||
--background-color: var(--color-extra-blue-d40);
|
||||
--background-color: var(--color-purple-d40);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -144,14 +144,14 @@ defineExpose({
|
||||
--after-width: v-bind('afterWidth || "1.625em"');
|
||||
--caret-width: 1.5em;
|
||||
|
||||
--text-color: var(--color-blue-scale-100);
|
||||
--text-color: var(--color-grey-100);
|
||||
|
||||
&.empty {
|
||||
--text-color: var(--color-blue-scale-300);
|
||||
--text-color: var(--color-grey-300);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
--text-color: var(--color-blue-scale-400);
|
||||
--text-color: var(--color-grey-500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ defineExpose({
|
||||
}
|
||||
|
||||
--background-color: var(--background-color-primary);
|
||||
--border-color: var(--color-blue-scale-400);
|
||||
--border-color: var(--color-grey-500);
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
@@ -199,63 +199,63 @@ defineExpose({
|
||||
&:not(:disabled) {
|
||||
&.info {
|
||||
&:hover {
|
||||
--border-color: var(--color-extra-blue-l60);
|
||||
--border-color: var(--color-purple-l60);
|
||||
}
|
||||
|
||||
&:active {
|
||||
--border-color: var(--color-extra-blue-l40);
|
||||
--border-color: var(--color-purple-l40);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
--border-color: var(--color-extra-blue-base);
|
||||
--border-color: var(--color-purple-base);
|
||||
}
|
||||
}
|
||||
|
||||
&.success {
|
||||
--border-color: var(--color-green-infra-base);
|
||||
--border-color: var(--color-green-base);
|
||||
|
||||
&:hover {
|
||||
--border-color: var(--color-green-infra-l60);
|
||||
--border-color: var(--color-green-l60);
|
||||
}
|
||||
|
||||
&:active {
|
||||
--border-color: var(--color-green-infra-l40);
|
||||
--border-color: var(--color-green-l40);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
--border-color: var(--color-green-infra-base);
|
||||
--border-color: var(--color-green-base);
|
||||
}
|
||||
}
|
||||
|
||||
&.warning {
|
||||
--border-color: var(--color-orange-world-base);
|
||||
--border-color: var(--color-orange-base);
|
||||
|
||||
&:hover {
|
||||
--border-color: var(--color-orange-world-l60);
|
||||
--border-color: var(--color-orange-l60);
|
||||
}
|
||||
|
||||
&:active {
|
||||
--border-color: var(--color-orange-world-l40);
|
||||
--border-color: var(--color-orange-l40);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
--border-color: var(--color-orange-world-base);
|
||||
--border-color: var(--color-orange-base);
|
||||
}
|
||||
}
|
||||
|
||||
&.error {
|
||||
--border-color: var(--color-red-vates-base);
|
||||
--border-color: var(--color-red-base);
|
||||
|
||||
&:hover {
|
||||
--border-color: var(--color-red-vates-l60);
|
||||
--border-color: var(--color-red-l60);
|
||||
}
|
||||
|
||||
&:active {
|
||||
--border-color: var(--color-red-vates-l40);
|
||||
--border-color: var(--color-red-l40);
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
--border-color: var(--color-red-vates-base);
|
||||
--border-color: var(--color-red-base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ useContext(DisabledContext, () => props.disabled)
|
||||
|
||||
&.light {
|
||||
font-size: 1.6rem;
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ useContext(DisabledContext, () => props.disabled)
|
||||
font-size: 1.4rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ useContext(DisabledContext, () => props.disabled)
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
text-decoration: none;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
|
||||
& > span {
|
||||
text-decoration: underline;
|
||||
@@ -134,14 +134,14 @@ useContext(DisabledContext, () => props.disabled)
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: var(--color-orange-world-base);
|
||||
color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
|
||||
.help {
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -53,7 +53,7 @@ whenever(
|
||||
<style lang="postcss" scoped>
|
||||
.collapsible {
|
||||
padding: 1rem 1.5rem;
|
||||
background-color: var(--background-color-extra-blue);
|
||||
background-color: var(--background-color-purple-10);
|
||||
border-radius: 0.8rem;
|
||||
}
|
||||
|
||||
@@ -67,16 +67,16 @@ whenever(
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--color-extra-blue-base);
|
||||
border-bottom: 1px solid var(--color-purple-base);
|
||||
width: 100%;
|
||||
font-size: 2rem;
|
||||
font-weight: 500;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.collapsible & {
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
padding-bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -87,6 +87,6 @@ whenever(
|
||||
}
|
||||
|
||||
.collapse-icon {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -65,7 +65,7 @@ const vmCount = computed(() => recordsByHostRef.value.get(props.hostOpaqueRef)?.
|
||||
}
|
||||
|
||||
.master-icon {
|
||||
color: var(--color-orange-world-base);
|
||||
color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
.vm-count {
|
||||
@@ -76,9 +76,9 @@ const vmCount = computed(() => recordsByHostRef.value.get(props.hostOpaqueRef)?.
|
||||
justify-content: center;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
color: var(--color-blue-scale-500);
|
||||
color: var(--color-grey-600);
|
||||
border-radius: calc(var(--size) / 2);
|
||||
background-color: var(--color-extra-blue-base);
|
||||
background-color: var(--color-purple-base);
|
||||
--size: 2.3rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,6 +23,6 @@ const { records: hosts, isReady, hasError } = useHostCollection()
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -40,27 +40,27 @@ const hasTooltip = computed(() => hasEllipsis(textElement.value))
|
||||
.infra-item-label {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
border-radius: 0.8rem;
|
||||
background-color: var(--background-color-primary);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
background-color: var(--background-color-secondary);
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
background-color: var(--background-color-primary);
|
||||
}
|
||||
|
||||
&.exact-active {
|
||||
color: var(--color-blue-scale-100);
|
||||
background-color: var(--background-color-extra-blue);
|
||||
color: var(--color-grey-100);
|
||||
background-color: var(--background-color-purple-10);
|
||||
|
||||
.icon {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ defineProps<{
|
||||
}
|
||||
|
||||
.icon {
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
}
|
||||
|
||||
.link-placeholder {
|
||||
@@ -41,7 +41,7 @@ defineProps<{
|
||||
.loader {
|
||||
flex: 1;
|
||||
animation: pulse alternate 1s infinite;
|
||||
background-color: var(--background-color-extra-blue);
|
||||
background-color: var(--background-color-purple-10);
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
|
||||
@@ -43,6 +43,6 @@ const { isReady, hasError, pool } = usePoolCollection()
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -40,18 +40,18 @@ const { stop } = useIntersectionObserver(rootElement, ([entry]) => {
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.infra-action {
|
||||
color: var(--color-extra-blue-d60);
|
||||
color: var(--color-purple-d60);
|
||||
|
||||
&.running {
|
||||
color: var(--color-green-infra-base);
|
||||
color: var(--color-green-base);
|
||||
}
|
||||
|
||||
&.paused {
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
}
|
||||
|
||||
&.suspended {
|
||||
color: var(--color-extra-blue-d20);
|
||||
color: var(--color-purple-d20);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -31,6 +31,6 @@ const vms = computed(() => recordsByHostRef.value.get(props.hostOpaqueRef ?? ('O
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -87,9 +87,9 @@ const open = (event: MouseEvent) => {
|
||||
flex-direction: column;
|
||||
padding: 0.5rem;
|
||||
cursor: default;
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
border-radius: 0.8rem;
|
||||
background-color: var(--color-blue-scale-500);
|
||||
background-color: var(--color-grey-600);
|
||||
gap: 0.5rem;
|
||||
|
||||
&.horizontal {
|
||||
|
||||
@@ -72,7 +72,7 @@ const handleClick = async () => {
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.menu-item {
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
}
|
||||
|
||||
.submenu-icon {
|
||||
|
||||
@@ -16,11 +16,11 @@ const horizontal = inject(
|
||||
.ui-menu-separator {
|
||||
&.horizontal {
|
||||
margin: 0 0.5rem;
|
||||
border-right: 1px solid var(--color-blue-scale-400);
|
||||
border-right: 1px solid var(--color-grey-500);
|
||||
}
|
||||
|
||||
&:not(.horizontal) {
|
||||
border-bottom: 1px solid var(--color-blue-scale-400);
|
||||
border-bottom: 1px solid var(--color-grey-500);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -29,10 +29,10 @@ defineProps<{
|
||||
white-space: nowrap;
|
||||
border-radius: 0.8rem;
|
||||
gap: 1rem;
|
||||
background-color: var(--color-blue-scale-500);
|
||||
background-color: var(--color-grey-600);
|
||||
|
||||
&.disabled {
|
||||
color: var(--color-blue-scale-400);
|
||||
color: var(--color-grey-500);
|
||||
}
|
||||
|
||||
&:not(.disabled) {
|
||||
@@ -44,8 +44,8 @@ defineProps<{
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
color: var(--color-extra-blue-base);
|
||||
background-color: var(--background-color-extra-blue);
|
||||
color: var(--color-purple-base);
|
||||
background-color: var(--background-color-purple-10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ const { records: alarms, start, isStarted, isReady, hasError } = useAlarmCollect
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.no-alarm & {
|
||||
color: var(--color-green-infra-base);
|
||||
color: var(--color-green-base);
|
||||
}
|
||||
}
|
||||
.table-container {
|
||||
|
||||
@@ -83,12 +83,12 @@ const hasError = computed(() => hostStoreHasError.value || vmStoreHasError.value
|
||||
.progress-item {
|
||||
margin-top: 2.6rem;
|
||||
--progress-bar-height: 1.2rem;
|
||||
--progress-bar-color: var(--color-extra-blue-base);
|
||||
--progress-bar-background-color: var(--color-blue-scale-400);
|
||||
--progress-bar-color: var(--color-purple-base);
|
||||
--progress-bar-background-color: var(--color-grey-500);
|
||||
|
||||
&.warning {
|
||||
--progress-bar-color: var(--color-orange-world-base);
|
||||
--footer-value-color: var(--color-orange-world-base);
|
||||
--progress-bar-color: var(--color-orange-base);
|
||||
--footer-value-color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
& .footer-value {
|
||||
|
||||
@@ -31,7 +31,7 @@ const { count, patches, areSomeLoaded, areAllLoaded } = useHostPatches(hosts)
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.patches-title {
|
||||
--section-title-right-color: var(--color-red-vates-base);
|
||||
--section-title-right-color: var(--color-red-base);
|
||||
}
|
||||
|
||||
.table-container {
|
||||
|
||||
@@ -52,10 +52,10 @@ const inactive = computed(() => props.total - props.active)
|
||||
width: 1.3rem;
|
||||
height: 1.3rem;
|
||||
border-radius: 0.65rem;
|
||||
background-color: var(--color-green-infra-base);
|
||||
background-color: var(--color-green-base);
|
||||
|
||||
&.inactive {
|
||||
background-color: var(--color-blue-scale-400);
|
||||
background-color: var(--color-grey-500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ const hasTooltip = computed(() => hasEllipsis(descriptionElement.value))
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.level {
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
font-size: 1.4rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ const hasTasks = computed(() => props.pendingTasks.length > 0 || (props.finished
|
||||
|
||||
.no-tasks {
|
||||
text-align: center;
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ td[colspan='5'] {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 150%;
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
|
||||
.loader {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
display: block;
|
||||
font-size: 4rem;
|
||||
margin: 2rem auto 0;
|
||||
|
||||
@@ -40,12 +40,12 @@ const isDisplayed = computed(() => !isNaN(percentUsed.value) && !isNaN(percentFr
|
||||
justify-content: space-between;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
display: flex;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ const isDisabled = useContext(DisabledContext, () => props.disabled)
|
||||
background-color: var(--background-color-primary);
|
||||
|
||||
&.disabled {
|
||||
color: var(--color-blue-scale-400);
|
||||
color: var(--color-grey-500);
|
||||
}
|
||||
|
||||
&:not(.disabled) {
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--background-color-secondary);
|
||||
@@ -62,8 +62,8 @@ const isDisabled = useContext(DisabledContext, () => props.disabled)
|
||||
&:active,
|
||||
&.active,
|
||||
&.busy {
|
||||
color: var(--color-extra-blue-base);
|
||||
background-color: var(--background-color-extra-blue);
|
||||
color: var(--color-purple-base);
|
||||
background-color: var(--background-color-purple-10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ defineProps<{
|
||||
font-weight: 500;
|
||||
padding: 0 0.8rem;
|
||||
height: 1.8em;
|
||||
color: var(--color-blue-scale-500);
|
||||
color: var(--color-grey-600);
|
||||
border-radius: 9.6rem;
|
||||
background-color: var(--color-blue-scale-300);
|
||||
background-color: var(--color-grey-300);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -86,27 +86,27 @@ const className = computed(() => {
|
||||
}
|
||||
|
||||
&.color-info {
|
||||
--button-accent-color: var(--color-extra-blue-base);
|
||||
--button-accent-color-hover: var(--color-extra-blue-d20);
|
||||
--button-accent-color-active: var(--color-extra-blue-d40);
|
||||
--button-accent-color: var(--color-purple-base);
|
||||
--button-accent-color-hover: var(--color-purple-d20);
|
||||
--button-accent-color-active: var(--color-purple-d40);
|
||||
}
|
||||
|
||||
&.color-success {
|
||||
--button-accent-color: var(--color-green-infra-base);
|
||||
--button-accent-color-hover: var(--color-green-infra-d20);
|
||||
--button-accent-color-active: var(--color-green-infra-d40);
|
||||
--button-accent-color: var(--color-green-base);
|
||||
--button-accent-color-hover: var(--color-green-d20);
|
||||
--button-accent-color-active: var(--color-green-d40);
|
||||
}
|
||||
|
||||
&.color-warning {
|
||||
--button-accent-color: var(--color-orange-world-base);
|
||||
--button-accent-color-hover: var(--color-orange-world-d20);
|
||||
--button-accent-color-active: var(--color-orange-world-d40);
|
||||
--button-accent-color: var(--color-orange-base);
|
||||
--button-accent-color-hover: var(--color-orange-d20);
|
||||
--button-accent-color-active: var(--color-orange-d40);
|
||||
}
|
||||
|
||||
&.color-error {
|
||||
--button-accent-color: var(--color-red-vates-base);
|
||||
--button-accent-color-hover: var(--color-red-vates-d20);
|
||||
--button-accent-color-active: var(--color-red-vates-d40);
|
||||
--button-accent-color: var(--color-red-base);
|
||||
--button-accent-color-hover: var(--color-red-d20);
|
||||
--button-accent-color-active: var(--color-red-d40);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -119,7 +119,7 @@ const className = computed(() => {
|
||||
--button-accent-color: var(--button-accent-color-active);
|
||||
}
|
||||
|
||||
--button-color: var(--color-blue-scale-500);
|
||||
--button-color: var(--color-grey-600);
|
||||
--button-border-color: transparent;
|
||||
--button-background-color: var(--button-accent-color);
|
||||
|
||||
@@ -141,7 +141,7 @@ const className = computed(() => {
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
--button-color: var(--color-blue-scale-400);
|
||||
--button-color: var(--color-grey-500);
|
||||
--button-border-color: transparent;
|
||||
--button-background-color: var(--background-color-secondary);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.footer {
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -17,7 +17,7 @@ import UiSpinner from '@/components/ui/UiSpinner.vue'
|
||||
}
|
||||
|
||||
.spinner {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
font-size: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -44,28 +44,28 @@ const tags = computed(() => {
|
||||
justify-content: space-between;
|
||||
|
||||
--section-title-left-size: 2rem;
|
||||
--section-title-left-color: var(--color-blue-scale-100);
|
||||
--section-title-left-color: var(--color-grey-100);
|
||||
--section-title-left-weight: 500;
|
||||
--section-title-right-size: 1.6rem;
|
||||
--section-title-right-color: var(--color-extra-blue-base);
|
||||
--section-title-right-color: var(--color-purple-base);
|
||||
--section-title-right-weight: 700;
|
||||
|
||||
&.h6 {
|
||||
margin-bottom: 1rem;
|
||||
--section-title-left-size: 1.5rem;
|
||||
--section-title-left-color: var(--color-blue-scale-300);
|
||||
--section-title-left-color: var(--color-grey-300);
|
||||
--section-title-left-weight: 400;
|
||||
}
|
||||
|
||||
&.h5 {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--color-extra-blue-base);
|
||||
border-bottom: 1px solid var(--color-purple-base);
|
||||
--section-title-left-size: 1.6rem;
|
||||
--section-title-left-color: var(--color-extra-blue-base);
|
||||
--section-title-left-color: var(--color-purple-base);
|
||||
--section-title-left-weight: 700;
|
||||
--section-title-right-size: 1.4rem;
|
||||
--section-title-right-color: var(--color-extra-blue-base);
|
||||
--section-title-right-color: var(--color-purple-base);
|
||||
--section-title-right-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ defineProps<{
|
||||
justify-content: center;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
color: var(--color-blue-scale-500);
|
||||
color: var(--color-grey-600);
|
||||
border-radius: calc(var(--size) / 2);
|
||||
background-color: var(--color-blue-scale-300);
|
||||
background-color: var(--color-grey-300);
|
||||
--size: 1.75em;
|
||||
|
||||
.overflow {
|
||||
@@ -33,19 +33,19 @@ defineProps<{
|
||||
}
|
||||
|
||||
&.info {
|
||||
background-color: var(--color-extra-blue-base);
|
||||
background-color: var(--color-purple-base);
|
||||
}
|
||||
|
||||
&.success {
|
||||
background-color: var(--color-green-infra-base);
|
||||
background-color: var(--color-green-base);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background-color: var(--color-orange-world-base);
|
||||
background-color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
&.error {
|
||||
background-color: var(--color-red-vates-base);
|
||||
background-color: var(--color-red-base);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,11 +27,11 @@ const emit = defineEmits<{
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
height: 3.4rem;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
border-radius: 1.7rem;
|
||||
background-color: var(--background-color-extra-blue);
|
||||
background-color: var(--background-color-purple-10);
|
||||
gap: 1rem;
|
||||
border: 1px solid var(--color-extra-blue-base);
|
||||
border: 1px solid var(--color-purple-base);
|
||||
}
|
||||
|
||||
.label,
|
||||
@@ -55,10 +55,10 @@ const emit = defineEmits<{
|
||||
border-radius: 1.4rem;
|
||||
width: 2.8rem;
|
||||
margin: 0.2rem;
|
||||
background-color: var(--color-extra-blue-l40);
|
||||
background-color: var(--color-purple-l40);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-red-vates-l20);
|
||||
background-color: var(--color-red-l20);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
@import '@/assets/_responsive.pcss';
|
||||
|
||||
.key,
|
||||
.value {
|
||||
padding-top: 0.5rem;
|
||||
@@ -24,7 +22,7 @@
|
||||
.key {
|
||||
padding-right: 2rem;
|
||||
text-align: left;
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
|
||||
@media (--desktop) {
|
||||
min-width: 20rem;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.ui-raw {
|
||||
background-color: var(--color-blue-scale-400);
|
||||
background-color: var(--color-grey-500);
|
||||
text-align: left;
|
||||
overflow: auto;
|
||||
max-width: 100%;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<style lang="postcss" scoped>
|
||||
.ui-separator {
|
||||
border: none;
|
||||
border-top: 1px solid var(--color-blue-scale-400);
|
||||
border-top: 1px solid var(--color-grey-500);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,7 +24,7 @@ defineProps<{
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
|
||||
.title {
|
||||
|
||||
@@ -29,12 +29,12 @@ const isTabBarDisabled = useContext(DisabledContext, () => props.disabled)
|
||||
padding: 0 1.5rem;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
border-bottom: 2px solid transparent;
|
||||
|
||||
&.disabled {
|
||||
pointer-events: none;
|
||||
color: var(--color-blue-scale-400);
|
||||
color: var(--color-grey-500);
|
||||
}
|
||||
|
||||
&:not(.disabled) {
|
||||
@@ -42,19 +42,19 @@ const isTabBarDisabled = useContext(DisabledContext, () => props.disabled)
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border-bottom-color: var(--color-extra-blue-base);
|
||||
border-bottom-color: var(--color-purple-base);
|
||||
background-color: var(--background-color-secondary);
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: var(--color-extra-blue-base);
|
||||
border-bottom-color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
border-bottom-color: var(--color-purple-base);
|
||||
background-color: var(--background-color-secondary);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--color-extra-blue-base);
|
||||
border-bottom-color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
border-bottom-color: var(--color-purple-base);
|
||||
background-color: var(--background-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ useContext(DisabledContext, () => props.disabled)
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
height: 5rem;
|
||||
border-bottom: 1px solid var(--color-blue-scale-400);
|
||||
border-bottom: 1px solid var(--color-grey-500);
|
||||
background-color: var(--background-color-primary);
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
|
||||
@@ -19,12 +19,12 @@ defineProps<{
|
||||
font-weight: 400;
|
||||
font-size: 1.4rem;
|
||||
line-height: 2.4rem;
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
|
||||
:deep(th),
|
||||
:deep(td) {
|
||||
padding: 1rem;
|
||||
border-top: 1px solid var(--color-blue-scale-400);
|
||||
border-top: 1px solid var(--color-grey-500);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ defineProps<{
|
||||
:deep(thead) {
|
||||
th,
|
||||
td {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
font-size: 1.4rem;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
@@ -45,7 +45,7 @@ defineProps<{
|
||||
&.vertical-border {
|
||||
:deep(th),
|
||||
:deep(td) {
|
||||
border-right: 1px solid var(--color-blue-scale-400);
|
||||
border-right: 1px solid var(--color-grey-500);
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
@@ -55,6 +55,6 @@ defineProps<{
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: var(--background-color-red-vates);
|
||||
background-color: var(--background-color-red-10);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,7 +25,7 @@ const tag = computed(() => {
|
||||
line-height: 150%;
|
||||
align-self: stretch;
|
||||
flex-grow: 0;
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
|
||||
&.display {
|
||||
font-size: 6.4rem;
|
||||
|
||||
@@ -30,16 +30,16 @@ const icon = computed(() => {
|
||||
color: var(--icon-color);
|
||||
|
||||
&.error {
|
||||
--icon-color: var(--color-red-vates-base);
|
||||
--icon-color: var(--color-red-base);
|
||||
}
|
||||
&.warning {
|
||||
--icon-color: var(--color-orange-world-base);
|
||||
--icon-color: var(--color-orange-base);
|
||||
}
|
||||
&.info {
|
||||
--icon-color: var(--color-extra-blue-base);
|
||||
--icon-color: var(--color-purple-base);
|
||||
}
|
||||
&.success {
|
||||
--icon-color: var(--color-green-infra-base);
|
||||
--icon-color: var(--color-green-base);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -72,6 +72,6 @@ defineSlots<{
|
||||
.subtitle {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
color: var(--color-blue-scale-200);
|
||||
color: var(--color-grey-200);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -29,22 +29,22 @@ const progressWithUnit = computed(() => {
|
||||
height: var(--progress-bar-height, 0.4rem);
|
||||
margin: 1rem 0;
|
||||
border-radius: 0.4rem;
|
||||
background-color: var(--progress-bar-background-color, var(--background-color-extra-blue));
|
||||
background-color: var(--progress-bar-background-color, var(--background-color-purple-10));
|
||||
|
||||
&.color-info {
|
||||
--progress-bar-color: var(--color-extra-blue-base);
|
||||
--progress-bar-color: var(--color-purple-base);
|
||||
}
|
||||
|
||||
&.color-success {
|
||||
--progress-bar-color: var(--color-green-infra-base);
|
||||
--progress-bar-color: var(--color-green-base);
|
||||
}
|
||||
|
||||
&.color-warning {
|
||||
--progress-bar-color: var(--color-orange-world-base);
|
||||
--progress-bar-color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
&.color-error {
|
||||
--progress-bar-color: var(--color-red-vates-base);
|
||||
--progress-bar-color: var(--color-red-base);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ withDefaults(
|
||||
|
||||
<style lang="postcss">
|
||||
.unit {
|
||||
color: var(--color-blue-scale-300);
|
||||
color: var(--color-grey-300);
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
|
||||
@@ -25,15 +25,15 @@ defineProps<{
|
||||
}
|
||||
|
||||
.icon {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
font-size: 3.2rem;
|
||||
}
|
||||
|
||||
.separator {
|
||||
height: 4.5rem;
|
||||
width: 0;
|
||||
border-left: 0.1rem solid var(--color-extra-blue-base);
|
||||
background-color: var(--color-extra-blue-base);
|
||||
border-left: 0.1rem solid var(--color-purple-base);
|
||||
background-color: var(--color-purple-base);
|
||||
margin: 0 1.5rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,6 @@ const getHostState = (host: XenApiHost) => (isHostRunning(host) ? VM_POWER_STATE
|
||||
|
||||
.star {
|
||||
margin: 0 1rem;
|
||||
color: var(--color-orange-world-base);
|
||||
color: var(--color-orange-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -53,7 +53,7 @@ const { isMobile } = storeToRefs(useUiStore())
|
||||
<style lang="postcss" scoped>
|
||||
.vms-actions-bar {
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--color-blue-scale-400);
|
||||
border-bottom: 1px solid var(--color-grey-500);
|
||||
background-color: var(--background-color-primary);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,10 +10,10 @@ export const useChartTheme = () => {
|
||||
|
||||
const getColors = () => ({
|
||||
background: style.getPropertyValue('--background-color-primary'),
|
||||
text: style.getPropertyValue('--color-blue-scale-300'),
|
||||
splitLine: style.getPropertyValue('--color-blue-scale-400'),
|
||||
primary: style.getPropertyValue('--color-extra-blue-base'),
|
||||
secondary: style.getPropertyValue('--color-orange-world-base'),
|
||||
text: style.getPropertyValue('--color-grey-300'),
|
||||
splitLine: style.getPropertyValue('--color-grey-500'),
|
||||
primary: style.getPropertyValue('--color-purple-base'),
|
||||
secondary: style.getPropertyValue('--color-orange-base'),
|
||||
})
|
||||
|
||||
const colors = ref(getColors())
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createApp } from 'vue'
|
||||
import App from '@/App.vue'
|
||||
import i18n from '@/i18n'
|
||||
import router from '@/router'
|
||||
import '@xen-orchestra/web-core/assets/css/base.pcss'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ img {
|
||||
}
|
||||
|
||||
.text {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
line-height: 150%;
|
||||
|
||||
@@ -30,7 +30,7 @@ img {
|
||||
width: 30%;
|
||||
}
|
||||
.numeric {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
font-size: 96px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 1em;
|
||||
@@ -40,7 +40,7 @@ img {
|
||||
}
|
||||
|
||||
.text {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
line-height: 150%;
|
||||
|
||||
@@ -145,8 +145,6 @@ const { colorMode } = storeToRefs(useUiStore())
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
@import '@/assets/_responsive.pcss';
|
||||
|
||||
.card-view {
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -176,9 +174,9 @@ h5 {
|
||||
flex-direction: column;
|
||||
gap: 1.6em;
|
||||
&.selected {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
img {
|
||||
outline: solid 2px var(--color-extra-blue-base);
|
||||
outline: solid 2px var(--color-purple-base);
|
||||
}
|
||||
}
|
||||
&:not(.selected) {
|
||||
|
||||
@@ -236,7 +236,7 @@ watch(
|
||||
.warning {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-orange-world-base);
|
||||
color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
.code-highlight {
|
||||
|
||||
@@ -123,7 +123,7 @@ const openInNewTab = () => {
|
||||
}
|
||||
|
||||
.spinner {
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
display: flex;
|
||||
margin: auto;
|
||||
width: 10rem;
|
||||
@@ -143,7 +143,7 @@ const openInNewTab = () => {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 4rem;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
font-size: 3.6rem;
|
||||
}
|
||||
|
||||
@@ -157,8 +157,8 @@ const openInNewTab = () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--color-extra-blue-base);
|
||||
color: var(--color-blue-scale-500);
|
||||
background-color: var(--color-purple-base);
|
||||
color: var(--color-grey-600);
|
||||
text-decoration: none;
|
||||
padding: 1.5rem;
|
||||
font-size: 1.6rem;
|
||||
|
||||
@@ -520,7 +520,7 @@ async function cancel() {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 76.5vh;
|
||||
color: var(--color-extra-blue-base);
|
||||
color: var(--color-purple-base);
|
||||
text-align: center;
|
||||
padding: 5rem;
|
||||
margin: auto;
|
||||
@@ -536,15 +536,15 @@ async function cancel() {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.status {
|
||||
color: var(--color-blue-scale-100);
|
||||
color: var(--color-grey-100);
|
||||
}
|
||||
|
||||
.success {
|
||||
color: var(--color-green-infra-base);
|
||||
color: var(--color-green-base);
|
||||
}
|
||||
|
||||
.danger {
|
||||
color: var(--color-red-vates-base);
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
.success,
|
||||
.danger {
|
||||
@@ -560,6 +560,6 @@ async function cancel() {
|
||||
gap: 0.5em;
|
||||
}
|
||||
.warning {
|
||||
color: var(--color-orange-world-base);
|
||||
color: var(--color-orange-base);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
|
||||
import fse from 'fs-extra'
|
||||
import getopts from 'getopts'
|
||||
import pRetry from 'promise-toolbox/retry'
|
||||
import { catchGlobalErrors } from '@xen-orchestra/log/configure'
|
||||
import { create as createServer } from 'http-server-plus'
|
||||
import { createCachedLookup } from '@vates/cached-dns.lookup'
|
||||
import { createLogger } from '@xen-orchestra/log'
|
||||
import { createSecureServer } from 'http2'
|
||||
import { genSelfSignedCert } from '@xen-orchestra/self-signed'
|
||||
import { load as loadConfig } from 'app-conf'
|
||||
import { readCert } from '@xen-orchestra/self-signed/readCert'
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -79,36 +78,17 @@ ${APP_NAME} v${APP_VERSION}
|
||||
}
|
||||
}
|
||||
|
||||
niceAddress = await pRetry(
|
||||
async () => {
|
||||
try {
|
||||
opts.cert = fse.readFileSync(cert)
|
||||
opts.key = fse.readFileSync(key)
|
||||
} catch (error) {
|
||||
if (!(autoCert && error.code === 'ENOENT')) {
|
||||
throw error
|
||||
}
|
||||
|
||||
const pems = await genSelfSignedCert()
|
||||
fse.outputFileSync(cert, pems.cert, { flag: 'wx', mode: 0o400 })
|
||||
fse.outputFileSync(key, pems.key, { flag: 'wx', mode: 0o400 })
|
||||
info('new certificate generated', { cert, key })
|
||||
opts.cert = pems.cert
|
||||
opts.key = pems.key
|
||||
}
|
||||
niceAddress = await readCert(cert, key, {
|
||||
autoCert,
|
||||
info,
|
||||
warn,
|
||||
use({ cert, key }) {
|
||||
opts.cert = cert
|
||||
opts.key = key
|
||||
|
||||
return httpServer.listen(opts)
|
||||
},
|
||||
{
|
||||
tries: 2,
|
||||
when: e => autoCert && e.code === 'ERR_SSL_EE_KEY_TOO_SMALL',
|
||||
onRetry: () => {
|
||||
warn('deleting invalid certificate')
|
||||
fse.unlinkSync(cert)
|
||||
fse.unlinkSync(key)
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
} else {
|
||||
niceAddress = await httpServer.listen(opts)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
### `genSelfSigned()`
|
||||
|
||||
> Generate a self-signed cert/key pair with OpenSSL.
|
||||
|
||||
```js
|
||||
import { genSelfSigned } from '@xen-orchestra/self-signed'
|
||||
|
||||
@@ -18,3 +22,41 @@ console.log(
|
||||
// '-----END RSA PRIVATE KEY-----\n'
|
||||
// }
|
||||
```
|
||||
|
||||
### `readCert()`
|
||||
|
||||
> Reads a cert/key pair from the filesystem, if missing or invalid, generates a new one and write them to the filesystem.
|
||||
|
||||
```js
|
||||
import { readCert } from '@xen-orchestra/self-signed/readCert'
|
||||
|
||||
const { cert, key } = await readCert('path/to/cert.pem', 'path/to/key.pem', {
|
||||
// if false, do not generate a new one in case of error
|
||||
autoCert: false,
|
||||
|
||||
// this function is called in case a new pair is generated
|
||||
info: console.log,
|
||||
|
||||
// mode used when creating files or directories after generating a new pair
|
||||
mode: 0o400,
|
||||
|
||||
// this function is called when there is a non fatal error (fatal errors are thrown)
|
||||
warn: console.warn,
|
||||
})
|
||||
|
||||
// unfortunately some cert/key issues are detected only when attempting to use them
|
||||
//
|
||||
// that's why you can pass a `use` function to `readCert` that will received the pair
|
||||
// and in case some specific errors are thrown, it will trigger a new generation
|
||||
await readCert('path/to/cert.pem', 'path/to/key.pem', {
|
||||
autoCert: true,
|
||||
|
||||
async use({ cert, key }) {
|
||||
const server = https.createServer({ cert, key })
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
server.once('error', reject).listen(443, resolve)
|
||||
})
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -16,6 +16,10 @@ npm install --save @xen-orchestra/self-signed
|
||||
|
||||
## Usage
|
||||
|
||||
### `genSelfSigned()`
|
||||
|
||||
> Generate a self-signed cert/key pair with OpenSSL.
|
||||
|
||||
```js
|
||||
import { genSelfSigned } from '@xen-orchestra/self-signed'
|
||||
|
||||
@@ -37,6 +41,44 @@ console.log(
|
||||
// }
|
||||
```
|
||||
|
||||
### `readCert()`
|
||||
|
||||
> Reads a cert/key pair from the filesystem, if missing or invalid, generates a new one and write them to the filesystem.
|
||||
|
||||
```js
|
||||
import { readCert } from '@xen-orchestra/self-signed/readCert'
|
||||
|
||||
const { cert, key } = await readCert('path/to/cert.pem', 'path/to/key.pem', {
|
||||
// if false, do not generate a new one in case of error
|
||||
autoCert: false,
|
||||
|
||||
// this function is called in case a new pair is generated
|
||||
info: console.log,
|
||||
|
||||
// mode used when creating files or directories after generating a new pair
|
||||
mode: 0o400,
|
||||
|
||||
// this function is called when there is a non fatal error (fatal errors are thrown)
|
||||
warn: console.warn,
|
||||
})
|
||||
|
||||
// unfortunately some cert/key issues are detected only when attempting to use them
|
||||
//
|
||||
// that's why you can pass a `use` function to `readCert` that will received the pair
|
||||
// and in case some specific errors are thrown, it will trigger a new generation
|
||||
await readCert('path/to/cert.pem', 'path/to/key.pem', {
|
||||
autoCert: true,
|
||||
|
||||
async use({ cert, key }) {
|
||||
const server = https.createServer({ cert, key })
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
server.once('error', reject).listen(443, resolve)
|
||||
})
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are _very_ welcomed, either on the documentation or on
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"version": "0.1.3",
|
||||
"engines": {
|
||||
"node": ">=8.10"
|
||||
"node": ">=15.6"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "npm publish --access public"
|
||||
@@ -20,5 +20,9 @@
|
||||
"author": {
|
||||
"name": "Vates SAS",
|
||||
"url": "https://vates.fr"
|
||||
},
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./readCert": "./readCert.js"
|
||||
}
|
||||
}
|
||||
|
||||
81
@xen-orchestra/self-signed/readCert.js
Normal file
81
@xen-orchestra/self-signed/readCert.js
Normal file
@@ -0,0 +1,81 @@
|
||||
'use strict'
|
||||
|
||||
const { dirname } = require('node:path')
|
||||
const { mkdir, readFile, writeFile, unlink } = require('node:fs/promises')
|
||||
const { X509Certificate } = require('node:crypto')
|
||||
|
||||
const { genSelfSignedCert } = require('./index.js')
|
||||
|
||||
const identity = value => value
|
||||
|
||||
const noop = Function.prototype
|
||||
|
||||
async function outputFile(path, content, mode) {
|
||||
for (let attempt = 0; attempt < 5; ++attempt) {
|
||||
try {
|
||||
return await writeFile(path, content, { mode })
|
||||
} catch (error) {
|
||||
const { code } = error
|
||||
if (code === 'ENOENT') {
|
||||
await mkdir(dirname(path), { mode, recursive: true })
|
||||
} else if (code === 'EACCES') {
|
||||
await unlink(path)
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.readCert = async function readCert(
|
||||
certPath,
|
||||
keyPath,
|
||||
{
|
||||
autoCert = false,
|
||||
use = identity,
|
||||
info = noop,
|
||||
mode = 0o400,
|
||||
warn = noop,
|
||||
|
||||
...opts
|
||||
}
|
||||
) {
|
||||
let readingDone = false
|
||||
|
||||
try {
|
||||
const cert = await readFile(certPath)
|
||||
|
||||
if (autoCert) {
|
||||
const x509 = new X509Certificate(cert)
|
||||
|
||||
const now = Date.now()
|
||||
if (now < Date.parse(x509.validFrom) || now > Date.parse(x509.validTo)) {
|
||||
const e = new Error('certificate is not valid')
|
||||
|
||||
// same code used when attempting to connect to a server with an expired certificate
|
||||
e.code = 'CERT_HAS_EXPIRED'
|
||||
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const key = await readFile(keyPath)
|
||||
|
||||
readingDone = true
|
||||
return await use({ cert, key })
|
||||
} catch (error) {
|
||||
// only regen if a reading error or if the use error was ERR_SSL_EE_KEY_TOO_SMALL
|
||||
if (!(autoCert && (!readingDone || error.code === 'ERR_SSL_EE_KEY_TOO_SMALL'))) {
|
||||
throw error
|
||||
}
|
||||
warn(error)
|
||||
|
||||
const { cert, key } = await genSelfSignedCert(opts)
|
||||
|
||||
info('new certificate generated', { cert, key })
|
||||
|
||||
await Promise.all([outputFile(certPath, cert, mode).catch(warn), outputFile(keyPath, key, mode).catch(warn)])
|
||||
|
||||
return use({ cert, key })
|
||||
}
|
||||
}
|
||||
1
@xen-orchestra/web-core/.npmignore
Symbolic link
1
@xen-orchestra/web-core/.npmignore
Symbolic link
@@ -0,0 +1 @@
|
||||
../../scripts/npmignore
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user