298 lines
7.9 KiB
Markdown
298 lines
7.9 KiB
Markdown
<h1>Deploying a VM with QSFS</h1>
|
|
|
|
<h2>Table of Contents</h2>
|
|
|
|
- [Prerequisites](#prerequisites)
|
|
- [Code Example](#code-example)
|
|
- [Detailed Explanation](#detailed-explanation)
|
|
- [Getting the Client](#getting-the-client)
|
|
- [Preparing QSFS](#preparing-qsfs)
|
|
- [Deploying a VM with QSFS](#deploying-a-vm-with-qsfs)
|
|
- [Getting the Deployment Information](#getting-the-deployment-information)
|
|
- [Deleting a Deployment](#deleting-a-deployment)
|
|
|
|
***
|
|
|
|
## Prerequisites
|
|
|
|
First, make sure that you have your [client](./grid3_javascript_loadclient.md) prepared.
|
|
|
|
## Code Example
|
|
|
|
```ts
|
|
import { FilterOptions, MachinesModel, QSFSZDBSModel } from "../src";
|
|
import { config, getClient } from "./client_loader";
|
|
import { log } from "./utils";
|
|
|
|
async function main() {
|
|
const grid3 = await getClient();
|
|
|
|
const qsfs_name = "wed2710q1";
|
|
const machines_name = "wed2710t1";
|
|
|
|
const vmQueryOptions: FilterOptions = {
|
|
cru: 1,
|
|
mru: 1, // GB
|
|
sru: 1,
|
|
availableFor: grid3.twinId,
|
|
farmId: 1,
|
|
};
|
|
|
|
const qsfsQueryOptions: FilterOptions = {
|
|
hru: 6,
|
|
availableFor: grid3.twinId,
|
|
farmId: 1,
|
|
};
|
|
|
|
const qsfsNodes = [];
|
|
|
|
const allNodes = await grid3.capacity.filterNodes(qsfsQueryOptions);
|
|
if (allNodes.length >= 2) {
|
|
qsfsNodes.push(+allNodes[0].nodeId, +allNodes[1].nodeId);
|
|
} else {
|
|
throw Error("Couldn't find nodes for qsfs");
|
|
}
|
|
|
|
const vmNode = +(await grid3.capacity.filterNodes(vmQueryOptions))[0].nodeId;
|
|
|
|
const qsfs: QSFSZDBSModel = {
|
|
name: qsfs_name,
|
|
count: 8,
|
|
node_ids: qsfsNodes,
|
|
password: "mypassword",
|
|
disk_size: 1,
|
|
description: "my qsfs test",
|
|
metadata: "",
|
|
};
|
|
|
|
const vms: MachinesModel = {
|
|
name: machines_name,
|
|
network: {
|
|
name: "wed2710n1",
|
|
ip_range: "10.201.0.0/16",
|
|
},
|
|
machines: [
|
|
{
|
|
name: "wed2710v1",
|
|
node_id: vmNode,
|
|
disks: [
|
|
{
|
|
name: "wed2710d1",
|
|
size: 1,
|
|
mountpoint: "/mydisk",
|
|
},
|
|
],
|
|
qsfs_disks: [
|
|
{
|
|
qsfs_zdbs_name: qsfs_name,
|
|
name: "wed2710d2",
|
|
minimal_shards: 2,
|
|
expected_shards: 4,
|
|
encryption_key: "hamada",
|
|
prefix: "hamada",
|
|
cache: 1,
|
|
mountpoint: "/myqsfsdisk",
|
|
},
|
|
],
|
|
public_ip: false,
|
|
public_ip6: false,
|
|
planetary: true,
|
|
cpu: 1,
|
|
memory: 1024,
|
|
rootfs_size: 0,
|
|
flist: "https://hub.grid.tf/tf-official-apps/base:latest.flist",
|
|
entrypoint: "/sbin/zinit init",
|
|
env: {
|
|
SSH_KEY: config.ssh_key,
|
|
},
|
|
},
|
|
],
|
|
metadata: "{'testVMs': true}",
|
|
description: "test deploying VMs via ts grid3 client",
|
|
};
|
|
|
|
async function cancel(grid3) {
|
|
// delete
|
|
const d = await grid3.machines.delete({ name: machines_name });
|
|
log(d);
|
|
const r = await grid3.qsfs_zdbs.delete({ name: qsfs_name });
|
|
log(r);
|
|
}
|
|
//deploy qsfs
|
|
const res = await grid3.qsfs_zdbs.deploy(qsfs);
|
|
log(">>>>>>>>>>>>>>>QSFS backend has been created<<<<<<<<<<<<<<<");
|
|
log(res);
|
|
|
|
const vm_res = await grid3.machines.deploy(vms);
|
|
log(">>>>>>>>>>>>>>>vm has been created<<<<<<<<<<<<<<<");
|
|
log(vm_res);
|
|
|
|
// get the deployment
|
|
const l = await grid3.machines.getObj(vms.name);
|
|
log(">>>>>>>>>>>>>>>Deployment result<<<<<<<<<<<<<<<");
|
|
log(l);
|
|
|
|
// await cancel(grid3);
|
|
|
|
await grid3.disconnect();
|
|
}
|
|
|
|
main();
|
|
```
|
|
|
|
## Detailed Explanation
|
|
|
|
We present a detailed explanation of the example shown above.
|
|
|
|
### Getting the Client
|
|
|
|
```ts
|
|
const grid3 = getClient();
|
|
```
|
|
|
|
### Preparing QSFS
|
|
|
|
```ts
|
|
const qsfs_name = "wed2710q1";
|
|
const machines_name = "wed2710t1";
|
|
```
|
|
|
|
We prepare here some names to use across the client for the QSFS and the machines project
|
|
|
|
```ts
|
|
const qsfsQueryOptions: FilterOptions = {
|
|
hru: 6,
|
|
availableFor: grid3.twinId,
|
|
farmId: 1,
|
|
};
|
|
const qsfsNodes = [];
|
|
|
|
const allNodes = await grid3.capacity.filterNodes(qsfsQueryOptions);
|
|
if (allNodes.length >= 2) {
|
|
qsfsNodes.push(+allNodes[0].nodeId, +allNodes[1].nodeId);
|
|
} else {
|
|
throw Error("Couldn't find nodes for qsfs");
|
|
}
|
|
|
|
const vmNode = +(await grid3.capacity.filterNodes(vmQueryOptions))[0].nodeId;
|
|
|
|
const qsfs: QSFSZDBSModel = {
|
|
name: qsfs_name,
|
|
count: 8,
|
|
node_ids: qsfsNodes,
|
|
password: "mypassword",
|
|
disk_size: 1,
|
|
description: "my qsfs test",
|
|
metadata: "",
|
|
};
|
|
|
|
const res = await grid3.qsfs_zdbs.deploy(qsfs);
|
|
log(">>>>>>>>>>>>>>>QSFS backend has been created<<<<<<<<<<<<<<<");
|
|
log(res);
|
|
```
|
|
|
|
Here we deploy `8` ZDBs on nodes `2,3` with password `mypassword`, all of them having disk size of `10GB`
|
|
|
|
### Deploying a VM with QSFS
|
|
|
|
```ts
|
|
const vmQueryOptions: FilterOptions = {
|
|
cru: 1,
|
|
mru: 1, // GB
|
|
sru: 1,
|
|
availableFor: grid3.twinId,
|
|
farmId: 1,
|
|
};
|
|
|
|
const vmNode = +(await grid3.capacity.filterNodes(vmQueryOptions))[0].nodeId;
|
|
|
|
// deploy vms
|
|
const vms: MachinesModel = {
|
|
name: machines_name,
|
|
network: {
|
|
name: "wed2710n1",
|
|
ip_range: "10.201.0.0/16",
|
|
},
|
|
machines: [
|
|
{
|
|
name: "wed2710v1",
|
|
node_id: vmNode,
|
|
disks: [
|
|
{
|
|
name: "wed2710d1",
|
|
size: 1,
|
|
mountpoint: "/mydisk",
|
|
},
|
|
],
|
|
qsfs_disks: [
|
|
{
|
|
qsfs_zdbs_name: qsfs_name,
|
|
name: "wed2710d2",
|
|
minimal_shards: 2,
|
|
expected_shards: 4,
|
|
encryption_key: "hamada",
|
|
prefix: "hamada",
|
|
cache: 1,
|
|
mountpoint: "/myqsfsdisk",
|
|
},
|
|
],
|
|
public_ip: false,
|
|
public_ip6: false,
|
|
planetary: true,
|
|
cpu: 1,
|
|
memory: 1024,
|
|
rootfs_size: 0,
|
|
flist: "https://hub.grid.tf/tf-official-apps/base:latest.flist",
|
|
entrypoint: "/sbin/zinit init",
|
|
env: {
|
|
SSH_KEY: config.ssh_key,
|
|
},
|
|
},
|
|
],
|
|
metadata: "{'testVMs': true}",
|
|
description: "test deploying VMs via ts grid3 client",
|
|
};
|
|
const vm_res = await grid3.machines.deploy(vms);
|
|
log(">>>>>>>>>>>>>>>vm has been created<<<<<<<<<<<<<<<");
|
|
log(vm_res);
|
|
```
|
|
|
|
So this deployment is almost similiar to what we have in the [vm deployment section](./grid3_javascript_vm.md). We only have a new section `qsfs_disks`
|
|
|
|
```ts
|
|
qsfs_disks: [{
|
|
qsfs_zdbs_name: qsfs_name,
|
|
name: "wed2710d2",
|
|
minimal_shards: 2,
|
|
expected_shards: 4,
|
|
encryption_key: "hamada",
|
|
prefix: "hamada",
|
|
cache: 1,
|
|
mountpoint: "/myqsfsdisk"
|
|
}],
|
|
```
|
|
|
|
`qsfs_disks` is a list, representing all of the QSFS disks used within that VM.
|
|
|
|
- `qsfs_zdbs_name`: that's the backend ZDBs we defined in the beginning
|
|
- `expected_shards`: how many ZDBs that QSFS should be working with
|
|
- `minimal_shards`: the minimal possible amount of ZDBs to recover the data with when losing disks e.g due to failure
|
|
- `mountpoint`: where it will be mounted on the VM `/myqsfsdisk`
|
|
|
|
### Getting the Deployment Information
|
|
|
|
```ts
|
|
const l = await grid3.machines.getObj(vms.name);
|
|
log(l);
|
|
```
|
|
|
|
### Deleting a Deployment
|
|
|
|
```ts
|
|
// delete
|
|
const d = await grid3.machines.delete({ name: machines_name });
|
|
log(d);
|
|
const r = await grid3.qsfs_zdbs.delete({ name: qsfs_name });
|
|
log(r);
|
|
```
|