mirror of
https://github.com/AlchemillaHQ/Sylve.git
synced 2026-06-14 00:46:34 +03:00
vm: networks: use isUsed properly, thanks @maxdorx!
docs: add new sponsor network: obj: fix isUsed typos
This commit is contained in:
@@ -27,10 +27,18 @@ We’re proud to be supported by:
|
||||
<img src="./docs/sponsors/Alchemilla-Dark.png" alt="Alchemilla" width="150"/>
|
||||
</picture>
|
||||
</a>
|
||||
   
|
||||
<a href="https://iptechnics.com">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./docs/sponsors/IP-Technics-White.png">
|
||||
<img src="./docs/sponsors/IP-Technics-Dark.png" alt="IPTechnics" width="150"/>
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- [FreeBSD Foundation](https://freebsdfoundation.org)
|
||||
- [FreeBSD Foundation](https://freebsdfoundation.org)
|
||||
- [Alchemilla](https://alchemilla.io)
|
||||
- [IPTechnics](https://iptechnics.com)
|
||||
|
||||
You can also support the project by [sponsoring us on GitHub](https://github.com/sponsors/AlchemillaHQ).
|
||||
|
||||
@@ -112,7 +120,7 @@ cp -rf ../config.example.json config.json # Edit the config.json file to your li
|
||||
|
||||
1. Bhyve doesn't support bootorders yet
|
||||
|
||||
Since Bhyve doesn't support bootorders yet, you'll need to configure the order using the UEFI boot menu. You can download
|
||||
Since Bhyve doesn't support bootorders yet, you'll need to configure the order using the UEFI boot menu. You can download
|
||||
|
||||
2. ARM64 support is still pending for Libvirt so the support is not there yet, for everything else it should just work out of the box.
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -212,8 +212,14 @@ func (s *Service) IsObjectUsed(id uint) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if jn.IPv4GwID != nil {
|
||||
if *jn.IPv4GwID == id {
|
||||
if jn.IPv6GwID != nil {
|
||||
if *jn.IPv6GwID == id {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
if jn.MacID != nil {
|
||||
if *jn.MacID == id {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
|
||||
import type { SwitchList } from '$lib/types/network/switch';
|
||||
import { Label } from '$lib/components/ui/label/index.js';
|
||||
import CustomValueInput from '$lib/components/ui/custom-input/value.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import type { NetworkObject } from '$lib/types/network/object';
|
||||
import type { VM } from '$lib/types/vm/vm';
|
||||
import { generateMACOptions } from '$lib/utils/network/object';
|
||||
|
||||
interface Props {
|
||||
@@ -15,7 +12,6 @@
|
||||
mac: string;
|
||||
emulation: string;
|
||||
switches: SwitchList;
|
||||
vms: VM[];
|
||||
networkObjects: NetworkObject[];
|
||||
}
|
||||
|
||||
@@ -24,19 +20,12 @@
|
||||
mac = $bindable(),
|
||||
emulation = $bindable(),
|
||||
switches,
|
||||
networkObjects,
|
||||
vms
|
||||
networkObjects
|
||||
}: Props = $props();
|
||||
|
||||
let usableMacs = $derived.by(() => {
|
||||
const usedMacIds = new Set<number>(
|
||||
vms
|
||||
.flatMap((vm) => vm.networks.map((net) => net.macId))
|
||||
.filter((id): id is number => id !== undefined)
|
||||
);
|
||||
|
||||
return networkObjects.filter(
|
||||
(obj) => obj.type === 'Mac' && obj.entries?.length === 1 && !usedMacIds.has(obj.id)
|
||||
(obj) => obj.type === 'Mac' && obj.entries?.length === 1 && obj.isUsed === false
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import SimpleSelect from '$lib/components/custom/SimpleSelect.svelte';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import CustomComboBox from '$lib/components/ui/custom-input/combobox.svelte';
|
||||
import CustomValueInput from '$lib/components/ui/custom-input/value.svelte';
|
||||
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||
import type { NetworkObject } from '$lib/types/network/object';
|
||||
import type { SwitchList } from '$lib/types/network/switch';
|
||||
@@ -15,12 +14,11 @@
|
||||
interface Props {
|
||||
open: boolean;
|
||||
switches: SwitchList;
|
||||
vms: VM[];
|
||||
vm: VM | null;
|
||||
networkObjects: NetworkObject[];
|
||||
}
|
||||
|
||||
let { open = $bindable(), switches, vm, networkObjects, vms }: Props = $props();
|
||||
let { open = $bindable(), switches, vm, networkObjects }: Props = $props();
|
||||
let usable = $derived.by(() => {
|
||||
return [
|
||||
...(switches.standard ?? []).map((s) => ({
|
||||
@@ -35,14 +33,8 @@
|
||||
});
|
||||
|
||||
let usableMacs = $derived.by(() => {
|
||||
const usedMacIds = new Set<number>(
|
||||
vms
|
||||
.flatMap((vm) => vm.networks.map((net) => net.macId))
|
||||
.filter((id): id is number => id !== undefined)
|
||||
);
|
||||
|
||||
return networkObjects.filter(
|
||||
(obj) => obj.type === 'Mac' && obj.entries?.length === 1 && !usedMacIds.has(obj.id)
|
||||
(obj) => obj.type === 'Mac' && obj.entries?.length === 1 && obj.isUsed === false
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -4301,7 +4301,7 @@ msgstr "No available/unused switches to attach to"
|
||||
msgid "VM must be shut off to attach storage"
|
||||
msgstr "VM must be shut off to attach storage"
|
||||
|
||||
#. placeholder {0}: vm?.name
|
||||
#. placeholder {0}: vm.current.name
|
||||
#. placeholder {1}: properties.detach.name
|
||||
#: src/routes/[node]/vm/[node]/network/+page.svelte
|
||||
msgid "This will detach the VM <b>{0}</b> from the switch <b>{1}</b>"
|
||||
|
||||
@@ -4279,7 +4279,7 @@ msgstr "जोड़ने के लिए कोई उपलब्ध/अप
|
||||
msgid "VM must be shut off to attach storage"
|
||||
msgstr "संग्रहण जोड़ने के लिए VM को बंद करना आवश्यक है"
|
||||
|
||||
#. placeholder {0}: vm?.name
|
||||
#. placeholder {0}: vm.current.name
|
||||
#. placeholder {1}: properties.detach.name
|
||||
#: src/routes/[node]/vm/[node]/network/+page.svelte
|
||||
msgid "This will detach the VM <b>{0}</b> from the switch <b>{1}</b>"
|
||||
|
||||
@@ -4289,7 +4289,7 @@ msgstr ""
|
||||
msgid "VM must be shut off to attach storage"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: vm?.name
|
||||
#. placeholder {0}: vm.current.name
|
||||
#. placeholder {1}: properties.detach.name
|
||||
#: src/routes/[node]/vm/[node]/network/+page.svelte
|
||||
msgid "This will detach the VM <b>{0}</b> from the switch <b>{1}</b>"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { getNetworkObjects } from '$lib/api/network/object';
|
||||
import { getSwitches } from '$lib/api/network/switch';
|
||||
import { detachNetwork } from '$lib/api/vm/network';
|
||||
import { getVMDomain, getVMs } from '$lib/api/vm/vm';
|
||||
import { getVmById, getVMDomain } from '$lib/api/vm/vm';
|
||||
import AlertDialog from '$lib/components/custom/Dialog/Alert.svelte';
|
||||
import TreeTable from '$lib/components/custom/TreeTable.svelte';
|
||||
import Network from '$lib/components/custom/VM/Hardware/Network.svelte';
|
||||
@@ -16,12 +16,11 @@
|
||||
import { handleAPIError, updateCache } from '$lib/utils/http';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import type { CellComponent } from 'tabulator-tables';
|
||||
import { resource, useInterval } from 'runed';
|
||||
import { resource, useInterval, watch } from 'runed';
|
||||
import { untrack } from 'svelte';
|
||||
import { storage } from '$lib';
|
||||
|
||||
interface Data {
|
||||
vms: VM[];
|
||||
vm: VM;
|
||||
domain: VMDomain;
|
||||
interfaces: Iface[];
|
||||
@@ -58,16 +57,16 @@
|
||||
}
|
||||
);
|
||||
|
||||
const vms = resource(
|
||||
() => 'vms',
|
||||
const vm = resource(
|
||||
() => `vm-${data.rid}`,
|
||||
async (key) => {
|
||||
const result = await getVMs();
|
||||
const result = await getVmById(Number(data.vm.rid), 'rid');
|
||||
updateCache(key, result);
|
||||
return result;
|
||||
},
|
||||
{
|
||||
lazy: true,
|
||||
initialValue: data.vms
|
||||
initialValue: data.vm
|
||||
}
|
||||
);
|
||||
|
||||
@@ -102,26 +101,23 @@
|
||||
if (storage.visible) {
|
||||
interfaces.refetch();
|
||||
switches.refetch();
|
||||
vms.refetch();
|
||||
vm.refetch();
|
||||
domain.refetch();
|
||||
networkObjects.refetch();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (storage.visible) {
|
||||
untrack(() => {
|
||||
interfaces.refetch();
|
||||
switches.refetch();
|
||||
vms.refetch();
|
||||
domain.refetch();
|
||||
networkObjects.refetch();
|
||||
});
|
||||
watch(
|
||||
() => storage.visible,
|
||||
() => {
|
||||
interfaces.refetch();
|
||||
switches.refetch();
|
||||
vm.refetch();
|
||||
domain.refetch();
|
||||
networkObjects.refetch();
|
||||
}
|
||||
});
|
||||
|
||||
let vm = $derived(vms.current.find((vm) => vm.rid === Number(data.rid)));
|
||||
);
|
||||
|
||||
function generateTableData() {
|
||||
const rows: Row[] = [];
|
||||
@@ -145,8 +141,8 @@
|
||||
}
|
||||
];
|
||||
|
||||
if (vm?.networks) {
|
||||
for (const network of vm.networks) {
|
||||
if (vm.current) {
|
||||
for (const network of vm.current.networks) {
|
||||
let sw: StandardSwitch | ManualSwitch | null = null;
|
||||
if (network.switchType === 'standard') {
|
||||
sw = switches.current.standard?.find((s) => s.id === network.switchId) ?? null;
|
||||
@@ -236,7 +232,7 @@
|
||||
<div class="flex h-10 w-full items-center gap-2 border p-2">
|
||||
<Button
|
||||
onclick={() => {
|
||||
if (vm) {
|
||||
if (vm.current) {
|
||||
if (usable?.length === 0) {
|
||||
toast.error('No available/unused switches to attach to', {
|
||||
position: 'bottom-center'
|
||||
@@ -278,10 +274,10 @@
|
||||
|
||||
<AlertDialog
|
||||
open={properties.detach.open}
|
||||
customTitle={`This will detach the VM <b>${vm?.name}</b> from the switch <b>${properties.detach.name}</b>`}
|
||||
customTitle={`This will detach the VM <b>${vm.current.name}</b> from the switch <b>${properties.detach.name}</b>`}
|
||||
actions={{
|
||||
onConfirm: async () => {
|
||||
let response = await detachNetwork(vm?.rid as number, properties.detach.id as number);
|
||||
let response = await detachNetwork(vm.current.rid as number, properties.detach.id as number);
|
||||
if (response.status === 'error') {
|
||||
handleAPIError(response);
|
||||
toast.error('Failed to detach network', {
|
||||
@@ -306,7 +302,6 @@
|
||||
<Network
|
||||
bind:open={properties.attach.open}
|
||||
switches={switches.current}
|
||||
vms={vms.current}
|
||||
networkObjects={networkObjects.current}
|
||||
vm={vm ?? null}
|
||||
vm={vm.current ?? null}
|
||||
/>
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
import { getInterfaces } from '$lib/api/network/iface';
|
||||
import { getNetworkObjects } from '$lib/api/network/object.js';
|
||||
import { getSwitches } from '$lib/api/network/switch';
|
||||
import { getVMDomain, getVMs } from '$lib/api/vm/vm';
|
||||
import { getVmById, getVMDomain, getVMs } from '$lib/api/vm/vm';
|
||||
import { cachedFetch } from '$lib/utils/http';
|
||||
|
||||
export async function load({ params }) {
|
||||
const cacheDuration = 1000 * 60000;
|
||||
const rid = params.node;
|
||||
const cacheDuration = 1000 * 60000;
|
||||
const rid = params.node;
|
||||
|
||||
const [vms, domain, interfaces, switches, networkObjects] = await Promise.all([
|
||||
cachedFetch('vm-list', async () => getVMs(), cacheDuration),
|
||||
cachedFetch(`vm-domain-${rid}`, async () => getVMDomain(Number(rid)), cacheDuration),
|
||||
cachedFetch('networkInterfaces', async () => await getInterfaces(), cacheDuration),
|
||||
cachedFetch('networkSwitches', async () => await getSwitches(), cacheDuration),
|
||||
cachedFetch('networkObjects', async () => await getNetworkObjects(), cacheDuration)
|
||||
]);
|
||||
const [vm, domain, interfaces, switches, networkObjects] = await Promise.all([
|
||||
cachedFetch(`vm-${rid}`, async () => getVmById(Number(rid), "rid"), cacheDuration),
|
||||
cachedFetch(`vm-domain-${rid}`, async () => getVMDomain(Number(rid)), cacheDuration),
|
||||
cachedFetch('networkInterfaces', async () => await getInterfaces(), cacheDuration),
|
||||
cachedFetch('networkSwitches', async () => await getSwitches(), cacheDuration),
|
||||
cachedFetch('networkObjects', async () => await getNetworkObjects(), cacheDuration)
|
||||
]);
|
||||
|
||||
const vm = vms.find((vm) => vm.rid === Number(rid));
|
||||
|
||||
return {
|
||||
rid,
|
||||
domain,
|
||||
interfaces,
|
||||
switches,
|
||||
networkObjects,
|
||||
vms,
|
||||
vm
|
||||
};
|
||||
return {
|
||||
rid,
|
||||
domain,
|
||||
interfaces,
|
||||
switches,
|
||||
networkObjects,
|
||||
vm
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user