Skip to content

Commit

Permalink
Merge pull request #714 from threefoldtech/development_dashboard_dedi…
Browse files Browse the repository at this point in the history
…catedNodeGPU

Development dashboard dedicated node gpu
  • Loading branch information
AhmedHanafy725 authored Jun 26, 2023
2 parents 4cbb56e + 2596775 commit fc9e5b2
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 7 deletions.
157 changes: 152 additions & 5 deletions packages/dashboard/src/portal/components/NodeDetails.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<v-row>
<v-col :cols="4">
<v-row class="ma-2">
<v-col :cols="colSize">
<v-card flat color="transparent" tag="div">
<!-- Title -->
<v-list-item>
Expand Down Expand Up @@ -52,7 +52,7 @@
</v-card>
</v-col>

<v-col :cols="4">
<v-col :cols="colSize">
<v-card flat color="transparent" tag="div">
<!-- Title -->
<v-list-item>
Expand Down Expand Up @@ -103,7 +103,7 @@
</v-row>
</v-card>
</v-col>
<v-col :cols="4">
<v-col :cols="colSize" :class="{ 'mt-n8': colSize === 6 }">
<v-card flat color="transparent" tag="div">
<!-- Title -->
<v-list-item>
Expand Down Expand Up @@ -154,19 +154,166 @@
</v-row>
</v-card>
</v-col>

<v-col v-if="node.resources.gpu > 0" class="mt-n8" style="min-width: 400px">
<v-card flat color="transparent" tag="div">
<!-- Title -->
<v-list-item class="mb-n2">
<v-list-item-icon>
<v-icon size="30" class="mr-2">mdi-expansion-card-variant</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title style="font-size: 20px">
GPU Card{{ node.resources.gpu > 1 ? "s" : "" }} details
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<!-- Details -->
<v-row v-if="!loading && nodeGPUitems != null && gpuItem">
<v-col cols="12">
<v-list>
<v-list-item>
<v-list-item-content>
<v-tooltip top nudge-bottom="30">
<template v-slot:activator="{ on, attrs }">
<v-list-item-title v-bind="attrs" v-on="on"
>Card ID
<v-chip
lose-icon="mdi-delete"
:color="gpuItem.contract ? 'warning' : 'success'"
x-small
class="mb-1 ml-3"
>{{ gpuItem.contract ? "Reserved" : "Available" }}</v-chip
>
</v-list-item-title>
</template>
<span>Card id that's used in a deployment</span>
</v-tooltip>
</v-list-item-content>

<v-col class="pa-0 d-flex justify-end">
<v-select
style="max-width: 270px"
v-if="nodeGPUitems?.length > 1"
append-outer-icon="mdi-content-copy"
hide-details
dense
v-model="gpuItem"
:items="nodeGPUitems"
@input.native="gpuItem = $event.srcElement.value.value"
@click:append-outer="copy(gpuItem.id)"
/>
<v-text-field
v-else
:value="gpuItem?.id"
readonly
hide-details
class="mt-n2"
dense
append-outer-icon="mdi-content-copy"
@click:append-outer="copy(gpuItem.id)"
solo
/>
</v-col>
</v-list-item>
<v-divider />
<v-list-item>
<v-list-item-content>
<v-list-item-title> Vendor </v-list-item-title>
</v-list-item-content>
{{ gpuItem?.vendor }}
</v-list-item>
<v-divider />
<v-list-item>
<v-list-item-content>
<v-list-item-title> Device </v-list-item-title>
</v-list-item-content>
{{ gpuItem?.device }}
</v-list-item>
<v-divider />
<v-list-item class="mb-0" v-if="gpuItem?.contract !== undefined">
<v-tooltip top nudge-bottom="30">
<template v-slot:activator="{ on, attrs }">
<v-list-item-content v-bind="attrs" v-on="on">
<v-list-item-title> Contract ID</v-list-item-title>
</v-list-item-content>
</template>
<span>The contract id that reserves this GPU card</span>
</v-tooltip>
{{ gpuItem?.contract }}
</v-list-item>
</v-list>
</v-col></v-row
>
<!-- Errors and loading -->
<v-sheet v-else class="d-flex justify-center align-center pt-0" height="230">
<div v-if="loading" class="text-center">
<v-progress-circular indeterminate></v-progress-circular>
<p class="pt-2">Loading GPU details</p>
</div>
<div v-else-if="nodeGPUitems === null" class="text-center">
<v-alert class="ma-2" dense outlined type="error">
Failed to receive node GPUs information
<template v-slot:append>
<v-icon class="ml-2 mt-1" @click="loadGPUitems">mdi-reload</v-icon>
</template>
</v-alert>
</div>
</v-sheet>
</v-card>
</v-col>
</v-row>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { getNodeGPUs, INodeGPU } from "../lib/nodes";
@Component({
name: "NodeDetails",
})
export default class NodeDetails extends Vue {
@Prop({ required: true }) node!: {
resources: { cru: string; hru: string; sru: string; mru: string };
nodeId: number;
resources: { cru: string; hru: string; sru: string; mru: string; gpu: number };
location: { country: string; city: string; long: string; lat: string };
farm: { id: string; name: string; farmCertType: string; pubIps: string };
};
get colSize() {
if (this.node.resources.gpu > 0) return 6;
else return 4;
}
loading = false;
nodeGPUitems:
| {
text: string;
value: INodeGPU;
disabled: false;
}[]
| null = null;
gpuItem: INodeGPU | null = null;
async loadGPUitems() {
this.loading = true;
const nodeGPU = await getNodeGPUs(this.node.nodeId);
this.loading = false;
if (!nodeGPU) return;
this.nodeGPUitems = nodeGPU.map((item: INodeGPU) => {
return {
text: item.id,
value: item,
disabled: false,
};
});
this.gpuItem = this.nodeGPUitems[0].value;
}
async mounted() {
await this.loadGPUitems();
}
copy(id: string) {
navigator.clipboard.writeText(id);
this.$toasted.show("GPU ID copied to clipboard");
}
}
</script>
2 changes: 1 addition & 1 deletion packages/dashboard/src/portal/components/NodesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export default class NodesTable extends Vue {
{ text: "MRU", value: "resources.mru", align: "center" },
{ text: "SRU", value: "resources.sru", align: "center" },
{ text: "HRU", value: "resources.hru", align: "center" },
{ text: "GPU", value: "resources.gpu", align: "center" },
{ text: "Price (USD)", value: "discount", align: "center" },
{ text: "Actions", value: "actions", align: "center", sortable: false },
];
Expand Down Expand Up @@ -175,7 +176,6 @@ export default class NodesTable extends Vue {
this.pageNumber,
this.pageSize,
);
this.nodes = dNodes;
this.count = parseInt(count as string);
this.loading = false;
Expand Down
23 changes: 22 additions & 1 deletion packages/dashboard/src/portal/lib/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ export interface ITab {
value: "rentable" | "rented" | "mine";
index: number;
}
export interface INodeGPU {
id: string;
vendor: string;
device: string;
contract?: number;
}

export function generateReceipt(doc: jsPDF, node: nodeInterface) {
doc.setFontSize(15);
Expand Down Expand Up @@ -287,6 +293,20 @@ export async function getNodeMintingFixupReceipts(nodeId: number) {

return nodeReceipts;
}
export async function getNodeGPUs(nodeId: number): Promise<INodeGPU[] | undefined> {
let nodeGPUs: INodeGPU[] | undefined;

try {
nodeGPUs = await (
await axios.get(`${config.gridproxyUrl}/nodes/${nodeId}/gpu`, {
timeout: 5000,
})
).data;
} catch (err) {
nodeGPUs = undefined;
}
return nodeGPUs;
}

export async function getNodeUsedResources(nodeId: string) {
const res = await axios.get(`${config.gridproxyUrl}/nodes/${nodeId}`, {
Expand Down Expand Up @@ -467,7 +487,7 @@ export async function getDNodes(
discount: any;
applyedDiscount: { first: any; second: any };
location: { country: any; city: any; long: any; lat: any };
resources: { cru: any; mru: any; hru: any; sru: any };
resources: { cru: any; mru: any; hru: any; sru: any; gpu: number };
farm: { id: string; name?: string; farmCertType?: string; pubIps?: string };
rentContractId: any;
rentedByTwinId: any;
Expand Down Expand Up @@ -499,6 +519,7 @@ export async function getDNodes(
mru: node.total_resources.mru,
hru: node.total_resources.hru,
sru: node.total_resources.sru,
gpu: node.num_gpu,
},
usedResources: {
cru: node.used_resources.cru,
Expand Down

0 comments on commit fc9e5b2

Please sign in to comment.