simplified documentation
This commit is contained in:
		| @@ -1,104 +0,0 @@ | ||||
| <h1> Deploying Gateways</h1> | ||||
|  | ||||
| <h2>Table of Contents</h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Gateway Name](#gateway-name) | ||||
| - [Example](#example) | ||||
| - [Gateway FQDN](#gateway-fqdn) | ||||
| - [Example](#example-1) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| After [deploying a VM](./grid3_go_vm.md) you can deploy Gateways to further expose your VM. | ||||
|  | ||||
| ## Gateway Name | ||||
|  | ||||
| This generates a FQDN for your VM. | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| import ( | ||||
|     "fmt" | ||||
|  | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types" | ||||
|     "github.com/threefoldtech/zos/pkg/gridtypes/zos" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     // Create Threefold plugin client | ||||
|     tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, "sr25519", network, "", "", true, false) | ||||
|  | ||||
|     // Get a free node to deploy | ||||
|     domain := true | ||||
|     status := "up" | ||||
|     filter := types.NodeFilter{ | ||||
|         Domain: &domain, | ||||
|         Status: &status, | ||||
|     } | ||||
|     nodeIDs, err := deployer.FilterNodes(tfPluginClient.GridProxyClient, filter) | ||||
|     nodeID := uint32(nodeIDs[0].NodeID) | ||||
|  | ||||
|     // Create gateway to deploy | ||||
|     gateway := workloads.GatewayNameProxy{ | ||||
|         NodeID:         nodeID, | ||||
|         Name:           "mydomain", | ||||
|         Backends:       []zos.Backend{"http://[300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f]:8080"}, | ||||
|         TLSPassthrough: true, | ||||
|     } | ||||
|     err = tfPluginClient.GatewayNameDeployer.Deploy(ctx, &gateway) | ||||
|  | ||||
|     gatewayObj, err := tfPluginClient.State.LoadGatewayNameFromGrid(nodeID, gateway.Name, gateway.Name) | ||||
|     fmt.Println(gatewayObj.FQDN) | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| This deploys a Gateway Name Proxy that forwards requests to your VM. You should see an output like this: | ||||
|  | ||||
| ```bash | ||||
| mydomain.gent01.dev.grid.tf | ||||
| ``` | ||||
|  | ||||
| ## Gateway FQDN | ||||
|  | ||||
| In case you have a FQDN already pointing to the node, you can expose your VM using Gateway FQDN. | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| import ( | ||||
|     "fmt" | ||||
|  | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" | ||||
|     "github.com/threefoldtech/zos/pkg/gridtypes/zos" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     // Create Threefold plugin client | ||||
|     tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, "sr25519", network, "", "", "", 0, true) | ||||
|  | ||||
|     // Create gateway to deploy | ||||
|     gateway := workloads.GatewayFQDNProxy{ | ||||
|         NodeID:         14, | ||||
|         Name:           "mydomain", | ||||
|         Backends:       []zos.Backend{"http://[300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f]:8080"}, | ||||
|         FQDN:           "my.domain.com", | ||||
|         TLSPassthrough: true, | ||||
|     } | ||||
|     err = tfPluginClient.GatewayFQDNDeployer.Deploy(ctx, &gateway) | ||||
|  | ||||
|     gatewayObj, err := tfPluginClient.State.LoadGatewayFQDNFromGrid(nodeID, gateway.Name, gateway.Name) | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| This deploys a Gateway FQDN Proxy that forwards requests to from node 14 public IP to your VM. | ||||
| @@ -1,6 +0,0 @@ | ||||
| <h1> GPU and Go </h1> | ||||
|  | ||||
| <h2> Table of Contents </h2> | ||||
|  | ||||
| - [GPU and Go Introduction](grid3_go_gpu_support.md) | ||||
| - [Deploy a VM with GPU](grid3_go_vm_with_gpu.md) | ||||
| @@ -1,116 +0,0 @@ | ||||
| <h1> GPU Support </h1> | ||||
|  | ||||
| <h2> Table of Contents </h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Example](#example) | ||||
| - [More Information](#more-information) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| We present here an example on how to deploy using the Go client. This is part of our integration tests. | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| func TestVMWithGPUDeployment(t *testing.T) { | ||||
|  tfPluginClient, err := setup() | ||||
|  assert.NoError(t, err) | ||||
|  | ||||
|  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) | ||||
|  defer cancel() | ||||
|  | ||||
|  publicKey, privateKey, err := GenerateSSHKeyPair() | ||||
|  assert.NoError(t, err) | ||||
|  | ||||
|  twinID := uint64(tfPluginClient.TwinID) | ||||
|  nodeFilter := types.NodeFilter{ | ||||
|   Status:   &statusUp, | ||||
|   FreeSRU:  convertGBToBytes(20), | ||||
|   FreeMRU:  convertGBToBytes(8), | ||||
|   RentedBy: &twinID, | ||||
|   HasGPU:   &trueVal, | ||||
|  } | ||||
|  | ||||
|  nodes, err := deployer.FilterNodes(ctx, tfPluginClient, nodeFilter) | ||||
|  if err != nil { | ||||
|   t.Skip("no available nodes found") | ||||
|  } | ||||
|  nodeID := uint32(nodes[0].NodeID) | ||||
|  | ||||
|  nodeClient, err := tfPluginClient.NcPool.GetNodeClient(tfPluginClient.SubstrateConn, nodeID) | ||||
|  assert.NoError(t, err) | ||||
|  | ||||
|  gpus, err := nodeClient.GPUs(ctx) | ||||
|  assert.NoError(t, err) | ||||
|  | ||||
|  network := workloads.ZNet{ | ||||
|   Name:        "gpuNetwork", | ||||
|   Description: "network for testing gpu", | ||||
|   Nodes:       []uint32{nodeID}, | ||||
|   IPRange: gridtypes.NewIPNet(net.IPNet{ | ||||
|    IP:   net.IPv4(10, 20, 0, 0), | ||||
|    Mask: net.CIDRMask(16, 32), | ||||
|   }), | ||||
|   AddWGAccess: false, | ||||
|  } | ||||
|  | ||||
|  disk := workloads.Disk{ | ||||
|   Name:   "gpuDisk", | ||||
|   SizeGB: 20, | ||||
|  } | ||||
|  | ||||
|  vm := workloads.VM{ | ||||
|   Name:       "gpu", | ||||
|   Flist:      "https://hub.grid.tf/tf-official-vms/ubuntu-22.04.flist", | ||||
|   CPU:        4, | ||||
|   Planetary:  true, | ||||
|   Memory:     1024 * 8, | ||||
|   GPUs:       ConvertGPUsToStr(gpus), | ||||
|   Entrypoint: "/init.sh", | ||||
|   EnvVars: map[string]string{ | ||||
|    "SSH_KEY": publicKey, | ||||
|   }, | ||||
|   Mounts: []workloads.Mount{ | ||||
|    {DiskName: disk.Name, MountPoint: "/data"}, | ||||
|   }, | ||||
|   NetworkName: network.Name, | ||||
|  } | ||||
|  | ||||
|  err = tfPluginClient.NetworkDeployer.Deploy(ctx, &network) | ||||
|  assert.NoError(t, err) | ||||
|  | ||||
|  defer func() { | ||||
|   err = tfPluginClient.NetworkDeployer.Cancel(ctx, &network) | ||||
|   assert.NoError(t, err) | ||||
|  }() | ||||
|  | ||||
|  dl := workloads.NewDeployment("gpu", nodeID, "", nil, network.Name, []workloads.Disk{disk}, nil, []workloads.VM{vm}, nil) | ||||
|  err = tfPluginClient.DeploymentDeployer.Deploy(ctx, &dl) | ||||
|  assert.NoError(t, err) | ||||
|  | ||||
|  defer func() { | ||||
|   err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl) | ||||
|   assert.NoError(t, err) | ||||
|  }() | ||||
|  | ||||
|  vm, err = tfPluginClient.State.LoadVMFromGrid(nodeID, vm.Name, dl.Name) | ||||
|  assert.NoError(t, err) | ||||
|  assert.Equal(t, vm.GPUs, ConvertGPUsToStr(gpus)) | ||||
|  | ||||
|  time.Sleep(30 * time.Second) | ||||
|  output, err := RemoteRun("root", vm.YggIP, "lspci -v", privateKey) | ||||
|  assert.NoError(t, err) | ||||
|  assert.Contains(t, string(output), gpus[0].Vendor) | ||||
| } | ||||
| ``` | ||||
|  | ||||
|  | ||||
|  | ||||
| ## More Information | ||||
|  | ||||
| For more information on this, you can check this [Client Pull Request](https://github.com/threefoldtech/tfgrid-sdk-go/pull/207/) on how to support the new calls to list GPUs and to deploy a machine with GPU. | ||||
| @@ -1,45 +0,0 @@ | ||||
| <h1>Go Client Installation</h1> | ||||
|  | ||||
| <h2>Table of Contents</h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Requirements](#requirements) | ||||
| - [Steps](#steps) | ||||
| - [References](#references) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| We present the general steps to install the ThreeFold Grid3 Go Client. | ||||
|  | ||||
| ## Requirements | ||||
|  | ||||
| Make sure that you have at least Go 1.19 installed on your machine. | ||||
|  | ||||
| - [Go](https://golang.org/doc/install) >= 1.19 | ||||
|  | ||||
| ## Steps | ||||
|  | ||||
| * Create a new directory | ||||
|   * ```bash | ||||
|     mkdir tf_go_client | ||||
|     ``` | ||||
| * Change directory | ||||
|   * ```bash | ||||
|     cd tf_go_client | ||||
|     ``` | ||||
| * Creates a **go.mod** file to track the code's dependencies | ||||
|   * ```bash | ||||
|     go mod init main | ||||
|     ``` | ||||
| * Install the Grid3 Go Client | ||||
|   * ```bash | ||||
|     go get github.com/threefoldtech/tfgrid-sdk-go/grid-client | ||||
|     ``` | ||||
|  | ||||
| This will make Grid3 Go Client packages available to you. | ||||
|  | ||||
| ## References | ||||
|  | ||||
| For more information, you can read the official [Go documentation](https://go.dev/doc/). | ||||
| @@ -1,120 +0,0 @@ | ||||
| <h1> Deploying Kubernetes Clusters</h1> | ||||
|  | ||||
| <h2>Table of Contents</h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Example](#example) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| We show how to deploy a Kubernetes cluster with the Go client. | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| import ( | ||||
|     "fmt" | ||||
|     "net" | ||||
|  | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types" | ||||
|     "github.com/threefoldtech/zos/pkg/gridtypes" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     // Create Threefold plugin client | ||||
|     tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, "sr25519", network, "", "", "", 0, true) | ||||
|  | ||||
|     // Get a free node to deploy | ||||
|     freeMRU := uint64(1) | ||||
|     freeSRU := uint64(1) | ||||
|     status := "up" | ||||
|     filter := types.NodeFilter{ | ||||
|         FreeMRU: &freeMRU, | ||||
|         FreeSRU: &freeSRU, | ||||
|         Status:  &status, | ||||
|     } | ||||
|     nodeIDs, err := deployer.FilterNodes(tfPluginClient.GridProxyClient, filter) | ||||
|     masterNodeID := uint32(nodeIDs[0].NodeID) | ||||
|     workerNodeID1 := uint32(nodeIDs[1].NodeID) | ||||
|     workerNodeID2 := uint32(nodeIDs[2].NodeID) | ||||
|  | ||||
|     // Create a new network to deploy | ||||
|     network := workloads.ZNet{ | ||||
|         Name:        "newNetwork", | ||||
|         Description: "A network to deploy", | ||||
|         Nodes:       []uint32{masterNodeID, workerNodeID1, workerNodeID2}, | ||||
|         IPRange: gridtypes.NewIPNet(net.IPNet{ | ||||
|             IP:   net.IPv4(10, 1, 0, 0), | ||||
|             Mask: net.CIDRMask(16, 32), | ||||
|         }), | ||||
|         AddWGAccess: true, | ||||
|     } | ||||
|  | ||||
|     // Create master and worker nodes to deploy | ||||
|     master := workloads.K8sNode{ | ||||
|         Name:      "master", | ||||
|         Node:      masterNodeID, | ||||
|         DiskSize:  1, | ||||
|         CPU:       2, | ||||
|         Memory:    1024, | ||||
|         Planetary: true, | ||||
|         Flist:     "https://hub.grid.tf/tf-official-apps/threefoldtech-k3s-latest.flist", | ||||
|     } | ||||
|  | ||||
|     worker1 := workloads.K8sNode{ | ||||
|         Name:     "worker1", | ||||
|         Node:     workerNodeID1, | ||||
|         DiskSize: 1, | ||||
|         CPU:      2, | ||||
|         Memory:   1024, | ||||
|         Flist:    "https://hub.grid.tf/tf-official-apps/threefoldtech-k3s-latest.flist", | ||||
|     } | ||||
|  | ||||
|     worker2 := workloads.K8sNode{ | ||||
|         Name:     "worker2", | ||||
|         Node:     workerNodeID2, | ||||
|         DiskSize: 1, | ||||
|         Flist:    "https://hub.grid.tf/tf-official-apps/threefoldtech-k3s-latest.flist", | ||||
|         CPU:      2, | ||||
|         Memory:   1024, | ||||
|     } | ||||
|    | ||||
|     k8sCluster := workloads.K8sCluster{ | ||||
|         Master:      &master, | ||||
|         Workers:     []workloads.K8sNode{worker1, worker2}, | ||||
|         Token:       "tokens", | ||||
|         SSHKey:      publicKey, | ||||
|         NetworkName: network.Name, | ||||
|     } | ||||
|  | ||||
|     // Deploy the network first | ||||
|     err = tfPluginClient.NetworkDeployer.Deploy(ctx, &network) | ||||
|  | ||||
|     // Deploy the k8s cluster | ||||
|     err = tfPluginClient.K8sDeployer.Deploy(ctx, &k8sCluster) | ||||
|  | ||||
|     // Load the k8s cluster | ||||
|     k8sClusterObj, err := tfPluginClient.State.LoadK8sFromGrid([]uint32{masterNodeID, workerNodeID1, workerNodeID2}, master.Name) | ||||
|  | ||||
|     // Print master node Yggdrasil IP | ||||
|     fmt.Println(k8sClusterObj.Master.YggIP) | ||||
|  | ||||
|     // Cancel the VM deployment | ||||
|     err = tfPluginClient.K8sDeployer.Cancel(ctx, &k8sCluster) | ||||
|  | ||||
|     // Cancel the network deployment | ||||
|     err = tfPluginClient.NetworkDeployer.Cancel(ctx, &network) | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| You should see an output like this: | ||||
|  | ||||
| ```bash | ||||
| 300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f | ||||
| ``` | ||||
| @@ -1,35 +0,0 @@ | ||||
| <h1>Load Client</h1> | ||||
|  | ||||
| <h2>Table of Contents</h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [TFPluginClient Configuration](#tfpluginclient-configuration) | ||||
| - [Creating Client](#creating-client) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| We cover how to load client using the Go client. | ||||
|  | ||||
| ## TFPluginClient Configuration | ||||
|  | ||||
| - mnemonics | ||||
| - keyType: can be `ed25519` or `sr25519` | ||||
| - network: can be `dev`, `qa`, `test` or `main` | ||||
|  | ||||
| ## Creating Client | ||||
|  | ||||
| Import `deployer` package to your project: | ||||
|  | ||||
| ```go | ||||
| import "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
| ``` | ||||
|  | ||||
| Create new Client: | ||||
|  | ||||
| ```go | ||||
| func main() { | ||||
|     client, err := deployer.NewTFPluginClient(mnemonics, keyType, network, "", "", "", 0, true) | ||||
| } | ||||
| ``` | ||||
| @@ -1,186 +0,0 @@ | ||||
| <h1> Deploying QSFS </h1> | ||||
|  | ||||
| <h2>Table of Contents</h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Example](#example) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| We show how to deploy QSFS workloads with the Go client. | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| import ( | ||||
|     "context" | ||||
|     "fmt" | ||||
|     "net" | ||||
|  | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types" | ||||
|     "github.com/threefoldtech/zos/pkg/gridtypes" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     // Create Threefold plugin client | ||||
|     tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, "sr25519", network, "", "", "", 0, true) | ||||
|  | ||||
|     // Get a free node to deploy | ||||
|     freeMRU := uint64(2) | ||||
|     freeSRU := uint64(20) | ||||
|     status := "up" | ||||
|     filter := types.NodeFilter{ | ||||
|         FreeMRU: &freeMRU, | ||||
|         FreeSRU: &freeSRU, | ||||
|         Status:  &status, | ||||
|     } | ||||
|     nodeIDs, err := deployer.FilterNodes(tfPluginClient.GridProxyClient, filter) | ||||
|     nodeID := uint32(nodeIDs[0].NodeID) | ||||
|  | ||||
|     // Create data and meta ZDBs | ||||
|     dataZDBs := []workloads.ZDB{} | ||||
|     metaZDBs := []workloads.ZDB{} | ||||
|     for i := 1; i <= DataZDBNum; i++ { | ||||
|         zdb := workloads.ZDB{ | ||||
|             Name:        "qsfsDataZdb" + strconv.Itoa(i), | ||||
|             Password:    "password", | ||||
|             Public:      true, | ||||
|             Size:        1, | ||||
|             Description: "zdb for testing", | ||||
|             Mode:        zos.ZDBModeSeq, | ||||
|         } | ||||
|         dataZDBs = append(dataZDBs, zdb) | ||||
|     } | ||||
|  | ||||
|     for i := 1; i <= MetaZDBNum; i++ { | ||||
|         zdb := workloads.ZDB{ | ||||
|             Name:        "qsfsMetaZdb" + strconv.Itoa(i), | ||||
|             Password:    "password", | ||||
|             Public:      true, | ||||
|             Size:        1, | ||||
|             Description: "zdb for testing", | ||||
|             Mode:        zos.ZDBModeUser, | ||||
|         } | ||||
|         metaZDBs = append(metaZDBs, zdb) | ||||
|     } | ||||
|  | ||||
|     // Deploy ZDBs | ||||
|     dl1 := workloads.NewDeployment("qsfs", nodeID, "", nil, "", nil, append(dataZDBs, metaZDBs...), nil, nil) | ||||
|     err = tfPluginClient.DeploymentDeployer.Deploy(ctx, &dl1) | ||||
|  | ||||
|     // result ZDBs | ||||
|     resDataZDBs := []workloads.ZDB{} | ||||
|     resMetaZDBs := []workloads.ZDB{} | ||||
|     for i := 1; i <= DataZDBNum; i++ { | ||||
|         res, err := tfPluginClient.State.LoadZdbFromGrid(nodeID, "qsfsDataZdb"+strconv.Itoa(i), dl1.Name) | ||||
|         resDataZDBs = append(resDataZDBs, res) | ||||
|     } | ||||
|     for i := 1; i <= MetaZDBNum; i++ { | ||||
|         res, err := tfPluginClient.State.LoadZdbFromGrid(nodeID, "qsfsMetaZdb"+strconv.Itoa(i), dl1.Name) | ||||
|         resMetaZDBs = append(resMetaZDBs, res) | ||||
|     } | ||||
|  | ||||
|     // backends | ||||
|     dataBackends := []workloads.Backend{} | ||||
|     metaBackends := []workloads.Backend{} | ||||
|     for i := 0; i < DataZDBNum; i++ { | ||||
|         dataBackends = append(dataBackends, workloads.Backend{ | ||||
|             Address:   "[" + resDataZDBs[i].IPs[1] + "]" + ":" + fmt.Sprint(resDataZDBs[i].Port), | ||||
|             Namespace: resDataZDBs[i].Namespace, | ||||
|             Password:  resDataZDBs[i].Password, | ||||
|         }) | ||||
|     } | ||||
|     for i := 0; i < MetaZDBNum; i++ { | ||||
|         metaBackends = append(metaBackends, workloads.Backend{ | ||||
|             Address:   "[" + resMetaZDBs[i].IPs[1] + "]" + ":" + fmt.Sprint(resMetaZDBs[i].Port), | ||||
|             Namespace: resMetaZDBs[i].Namespace, | ||||
|             Password:  resMetaZDBs[i].Password, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     // Create a new qsfs to deploy | ||||
|     qsfs := workloads.QSFS{ | ||||
|         Name:                 "qsfs", | ||||
|         Description:          "qsfs for testing", | ||||
|         Cache:                1024, | ||||
|         MinimalShards:        2, | ||||
|         ExpectedShards:       4, | ||||
|         RedundantGroups:      0, | ||||
|         RedundantNodes:       0, | ||||
|         MaxZDBDataDirSize:    512, | ||||
|         EncryptionAlgorithm:  "AES", | ||||
|         EncryptionKey:        "4d778ba3216e4da4231540c92a55f06157cabba802f9b68fb0f78375d2e825af", | ||||
|         CompressionAlgorithm: "snappy", | ||||
|         Groups:               workloads.Groups{{Backends: dataBackends}}, | ||||
|         Metadata: workloads.Metadata{ | ||||
|             Type:                "zdb", | ||||
|             Prefix:              "test", | ||||
|             EncryptionAlgorithm: "AES", | ||||
|             EncryptionKey:       "4d778ba3216e4da4231540c92a55f06157cabba802f9b68fb0f78375d2e825af", | ||||
|             Backends:            metaBackends, | ||||
|         }, | ||||
|     } | ||||
|  | ||||
|     // Create a new network to deploy | ||||
|     network := workloads.ZNet{ | ||||
|         Name:        "newNetwork", | ||||
|         Description: "A network to deploy", | ||||
|         Nodes:       []uint32{nodeID}, | ||||
|         IPRange: gridtypes.NewIPNet(net.IPNet{ | ||||
|             IP:   net.IPv4(10, 1, 0, 0), | ||||
|             Mask: net.CIDRMask(16, 32), | ||||
|         }), | ||||
|         AddWGAccess: true, | ||||
|     } | ||||
|  | ||||
|     vm := workloads.VM{ | ||||
|         Name:       "vm", | ||||
|         Flist:      "https://hub.grid.tf/tf-official-apps/base:latest.flist", | ||||
|         CPU:        2, | ||||
|         Planetary:  true, | ||||
|         Memory:     1024, | ||||
|         Entrypoint: "/sbin/zinit init", | ||||
|         EnvVars: map[string]string{ | ||||
|             "SSH_KEY": publicKey, | ||||
|         }, | ||||
|         Mounts: []workloads.Mount{ | ||||
|             {DiskName: qsfs.Name, MountPoint: "/qsfs"}, | ||||
|         }, | ||||
|         NetworkName: network.Name, | ||||
|     }     | ||||
|  | ||||
|     // Deploy the network first | ||||
|     err = tfPluginClient.NetworkDeployer.Deploy(ctx, &network) | ||||
|  | ||||
|     // Deploy the VM/QSFS deployment | ||||
|     dl2 := workloads.NewDeployment("qsfs", nodeID, "", nil, network.Name, nil, append(dataZDBs, metaZDBs...), []workloads.VM{vm}, []workloads.QSFS{qsfs}) | ||||
|     err = tfPluginClient.DeploymentDeployer.Deploy(ctx, &dl2) | ||||
|  | ||||
|     // Load the QSFS using the state loader | ||||
|     qsfsObj, err := tfPluginClient.State.LoadQSFSFromGrid(nodeID, qsfs.Name, dl2.Name) | ||||
|  | ||||
|     // Load the VM using the state loader | ||||
|     vmObj, err := tfPluginClient.State.LoadVMFromGrid(nodeID, vm.Name, dl2.Name) | ||||
|  | ||||
|     // Print the VM Yggdrasil IP | ||||
|     fmt.Println(vmObj.YggIP) | ||||
|  | ||||
|     // Cancel the VM,QSFS deployment | ||||
|     err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl1) | ||||
|     err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl2) | ||||
|  | ||||
|     // Cancel the network deployment | ||||
|     err = tfPluginClient.NetworkDeployer.Cancel(ctx, &network) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Running this code should result in a VM with QSFS deployed on an available node and get an output like this: | ||||
|  | ||||
| ```bash | ||||
| Yggdrasil IP: 300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f | ||||
| ``` | ||||
| @@ -1,17 +0,0 @@ | ||||
| # Grid Go Client | ||||
|  | ||||
| Grid Go Client is a Go client created to interact and develop on Threefold Grid using Go language. | ||||
|  | ||||
| Please make sure to check the [basics](../../system_administrators/getstarted/tfgrid3_getstarted.md) before continuing. | ||||
|  | ||||
| <h2> Table of Contents </h2> | ||||
|  | ||||
| - [Installation](../go/grid3_go_installation.md) | ||||
| - [Loading Client](../go/grid3_go_load_client.md) | ||||
| - [Deploy a VM](../go/grid3_go_vm.md) | ||||
| - [Deploy a VM with GPU](../go/grid3_go_vm_with_gpu.md) | ||||
| - [Deploy Multiple VMs](../go/grid3_go_vms.md) | ||||
| - [Deploy Gateways](../go/grid3_go_gateways.md) | ||||
| - [Deploy Kubernetes](../go/grid3_go_kubernetes.md) | ||||
| - [Deploy a QSFS](../go/grid3_go_qsfs.md) | ||||
| - [GPU Support](../go/grid3_go_gpu_support.md) | ||||
| @@ -1,99 +0,0 @@ | ||||
| <h1> Deploying a VM</h1> | ||||
|  | ||||
| <h2>Table of Contents</h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Example](#example) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| We show how to deploy a VM with the Go client. | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| import ( | ||||
|     "context" | ||||
|     "fmt" | ||||
|     "net" | ||||
|  | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types" | ||||
|     "github.com/threefoldtech/zos/pkg/gridtypes" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     // Create Threefold plugin client | ||||
|     tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, keyType, network, "", "", "", 0, true) | ||||
|  | ||||
|     // Get a free node to deploy | ||||
|     freeMRU := uint64(2) | ||||
|     freeSRU := uint64(20) | ||||
|     status := "up" | ||||
|     filter := types.NodeFilter{ | ||||
|         FreeMRU: &freeMRU, | ||||
|         FreeSRU: &freeSRU, | ||||
|         Status:  &status, | ||||
|     } | ||||
|     nodeIDs, err := deployer.FilterNodes(tfPluginClient.GridProxyClient, filter) | ||||
|     nodeID := uint32(nodeIDs[0].NodeID) | ||||
|  | ||||
|     // Create a new network to deploy | ||||
|     network := workloads.ZNet{ | ||||
|         Name:        "newNetwork", | ||||
|         Description: "A network to deploy", | ||||
|         Nodes:       []uint32{nodeID}, | ||||
|         IPRange: gridtypes.NewIPNet(net.IPNet{ | ||||
|             IP:   net.IPv4(10, 1, 0, 0), | ||||
|             Mask: net.CIDRMask(16, 32), | ||||
|         }), | ||||
|         AddWGAccess: true, | ||||
|     } | ||||
|  | ||||
|     // Create a new VM to deploy | ||||
|     vm := workloads.VM{ | ||||
|         Name:       "vm", | ||||
|         Flist:      "https://hub.grid.tf/tf-official-apps/base:latest.flist", | ||||
|         CPU:        2, | ||||
|         PublicIP:   true, | ||||
|         Planetary:  true, | ||||
|         Memory:     1024, | ||||
|         RootfsSize: 20 * 1024, | ||||
|         Entrypoint: "/sbin/zinit init", | ||||
|         EnvVars: map[string]string{ | ||||
|             "SSH_KEY": publicKey, | ||||
|         }, | ||||
|         IP:          "10.20.2.5", | ||||
|         NetworkName: network.Name, | ||||
|     } | ||||
|  | ||||
|     // Deploy the network first | ||||
|     err = tfPluginClient.NetworkDeployer.Deploy(ctx, &network) | ||||
|  | ||||
|     // Deploy the VM deployment | ||||
|     dl := workloads.NewDeployment("vm", nodeID, "", nil, network.Name, nil, nil, []workloads.VM{vm}, nil) | ||||
|     err = tfPluginClient.DeploymentDeployer.Deploy(ctx, &dl) | ||||
|  | ||||
|     // Load the VM using the state loader | ||||
|     vmObj, err := tfPluginClient.State.LoadVMFromGrid(nodeID, vm.Name, dl.Name) | ||||
|  | ||||
|     // Print the VM Yggdrasil IP | ||||
|     fmt.Println(vmObj.YggIP) | ||||
|  | ||||
|     // Cancel the VM deployment | ||||
|     err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl) | ||||
|  | ||||
|     // Cancel the network deployment | ||||
|     err = tfPluginClient.NetworkDeployer.Cancel(ctx, &network) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Running this code should result in a VM deployed on an available node and get an output like this: | ||||
|  | ||||
| ```bash | ||||
| 300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f | ||||
| ``` | ||||
| @@ -1,121 +0,0 @@ | ||||
| <h1> Deploy a VM with GPU </h1> | ||||
|  | ||||
| <h2> Table of Contents </h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Example](#example) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| In this section, we explore how to deploy a virtual machine equipped with GPU. We deploy the VM using Go. The VM will be deployed on a 3Node with an available GPU. | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| import ( | ||||
|     "context" | ||||
|     "fmt" | ||||
|     "net" | ||||
|  | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types" | ||||
|     "github.com/threefoldtech/zos/pkg/gridtypes" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     // Create Threefold plugin client | ||||
|     tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, "sr25519", network, "", "", "", 0, true) | ||||
|  | ||||
|     // Get a free node to deploy | ||||
|     freeMRU := uint64(2) | ||||
|     freeSRU := uint64(20) | ||||
|     status := "up" | ||||
|     trueVal := true | ||||
|  | ||||
|     twinID := uint64(tfPluginClient.TwinID) | ||||
|     filter := types.NodeFilter{ | ||||
|         FreeMRU: &freeMRU, | ||||
|         FreeSRU: &freeSRU, | ||||
|         Status:  &status, | ||||
|         RentedBy: &twinID, | ||||
|         HasGPU:   &trueVal, | ||||
|     } | ||||
|     nodeIDs, err := deployer.FilterNodes(tfPluginClient.GridProxyClient, filter) | ||||
|     nodeID := uint32(nodeIDs[0].NodeID) | ||||
|  | ||||
|     // Get the available gpus on the node | ||||
|     nodeClient, err := tfPluginClient.NcPool.GetNodeClient(tfPluginClient.SubstrateConn, nodeID) | ||||
|     gpus, err := nodeClient.GPUs(ctx) | ||||
|  | ||||
|     // Create a new network to deploy | ||||
|     network := workloads.ZNet{ | ||||
|         Name:        "newNetwork", | ||||
|         Description: "A network to deploy", | ||||
|         Nodes:       []uint32{nodeID}, | ||||
|         IPRange: gridtypes.NewIPNet(net.IPNet{ | ||||
|             IP:   net.IPv4(10, 1, 0, 0), | ||||
|             Mask: net.CIDRMask(16, 32), | ||||
|         }), | ||||
|         AddWGAccess: true, | ||||
|     } | ||||
|  | ||||
|     // Create a new disk to deploy | ||||
|     disk := workloads.Disk{ | ||||
|         Name:   "gpuDisk", | ||||
|         SizeGB: 20, | ||||
|     } | ||||
|  | ||||
|     // Create a new VM to deploy | ||||
|     vm := workloads.VM{ | ||||
|         Name:       "vm", | ||||
|         Flist:      "https://hub.grid.tf/tf-official-apps/base:latest.flist", | ||||
|         CPU:        2, | ||||
|         PublicIP:   true, | ||||
|         Planetary:  true, | ||||
|         // Insert your GPUs' IDs here | ||||
|         GPUs:       []zos.GPU{zos.GPU(gpus[0].ID)}, | ||||
|         Memory:     1024, | ||||
|         RootfsSize: 20 * 1024, | ||||
|         Entrypoint: "/sbin/zinit init", | ||||
|         EnvVars: map[string]string{ | ||||
|             "SSH_KEY": publicKey, | ||||
|         }, | ||||
|         Mounts: []workloads.Mount{ | ||||
|             {DiskName: disk.Name, MountPoint: "/data"}, | ||||
|         }, | ||||
|         IP:          "10.20.2.5", | ||||
|         NetworkName: network.Name, | ||||
|     } | ||||
|  | ||||
|     // Deploy the network first | ||||
|     err = tfPluginClient.NetworkDeployer.Deploy(ctx, &network) | ||||
|  | ||||
|     // Deploy the VM deployment | ||||
|     dl := workloads.NewDeployment("gpu", nodeID, "", nil, network.Name, []workloads.Disk{disk}, nil, []workloads.VM{vm}, nil) | ||||
|     err = tfPluginClient.DeploymentDeployer.Deploy(ctx, &dl) | ||||
|  | ||||
|     // Load the VM using the state loader | ||||
|     vmObj, err := tfPluginClient.State.LoadVMFromGrid(nodeID, vm.Name, dl.Name) | ||||
|  | ||||
|     // Print the VM Yggdrasil IP | ||||
|     fmt.Println(vmObj.YggIP) | ||||
|  | ||||
|     // Cancel the VM deployment | ||||
|     err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl) | ||||
|  | ||||
|     // Cancel the network deployment | ||||
|     err = tfPluginClient.NetworkDeployer.Cancel(ctx, &network) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Running this code should result in a VM with a GPU deployed on an available node. The output should look like this: | ||||
|  | ||||
| ```bash | ||||
| Yggdrasil IP: 300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f | ||||
| ``` | ||||
| @@ -1,125 +0,0 @@ | ||||
| <h1> Deploying Multiple VMs</h1> | ||||
|  | ||||
| <h2>Table of Contents</h2> | ||||
|  | ||||
| - [Introduction](#introduction) | ||||
| - [Example](#example) | ||||
|  | ||||
| *** | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| We show how to deploy multiple VMs with the Go client. | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| ```go | ||||
| import ( | ||||
|     "context" | ||||
|     "fmt" | ||||
|     "net" | ||||
|  | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" | ||||
|     "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types" | ||||
|     "github.com/threefoldtech/zos/pkg/gridtypes" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|  | ||||
|     // Create Threefold plugin client | ||||
|     tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, "sr25519", network, "", "", "", 0, true) | ||||
|  | ||||
|     // Get a free node to deploy | ||||
|     freeMRU := uint64(2) | ||||
|     freeSRU := uint64(2) | ||||
|     status := "up" | ||||
|     filter := types.NodeFilter { | ||||
|         FreeMRU: &freeMRU, | ||||
|         FreeSRU: &freeSRU, | ||||
|         Status: &status, | ||||
|     } | ||||
|     nodeIDs, err := deployer.FilterNodes(tfPluginClient.GridProxyClient, filter) | ||||
|     nodeID1 := uint32(nodeIDs[0].NodeID) | ||||
|     nodeID2 := uint32(nodeIDs[1].NodeID) | ||||
|  | ||||
|     // Create a new network to deploy | ||||
|     network := workloads.ZNet{ | ||||
|         Name:        "newNetwork", | ||||
|         Description: "A network to deploy", | ||||
|         Nodes:       []uint32{nodeID1, nodeID2}, | ||||
|         IPRange: gridtypes.NewIPNet(net.IPNet{ | ||||
|             IP:   net.IPv4(10, 1, 0, 0), | ||||
|             Mask: net.CIDRMask(16, 32), | ||||
|         }), | ||||
|         AddWGAccess: true, | ||||
|     } | ||||
|  | ||||
|     // Create new VMs to deploy | ||||
|     vm1 := workloads.VM{ | ||||
|         Name:       "vm1", | ||||
|         Flist:      "https://hub.grid.tf/tf-official-apps/base:latest.flist", | ||||
|         CPU:        2, | ||||
|         PublicIP:   true, | ||||
|         Planetary:  true, | ||||
|         Memory:     1024, | ||||
|         RootfsSize: 20 * 1024, | ||||
|         Entrypoint: "/sbin/zinit init", | ||||
|         EnvVars: map[string]string{ | ||||
|             "SSH_KEY": publicKey, | ||||
|         }, | ||||
|         IP:          "10.20.2.5", | ||||
|         NetworkName: network.Name, | ||||
|     } | ||||
|     vm2 := workloads.VM{ | ||||
|         Name:       "vm2", | ||||
|         Flist:      "https://hub.grid.tf/tf-official-apps/base:latest.flist", | ||||
|         CPU:        2, | ||||
|         PublicIP:   true, | ||||
|         Planetary:  true, | ||||
|         Memory:     1024, | ||||
|         RootfsSize: 20 * 1024, | ||||
|         Entrypoint: "/sbin/zinit init", | ||||
|         EnvVars: map[string]string{ | ||||
|             "SSH_KEY": publicKey, | ||||
|         }, | ||||
|         IP:          "10.20.2.6", | ||||
|         NetworkName: network.Name, | ||||
|     } | ||||
|  | ||||
|     // Deploy the network first | ||||
|     err = tfPluginClient.NetworkDeployer.Deploy(ctx, &network) | ||||
|  | ||||
|     // Load the network using the state loader | ||||
|     // this loader should load the deployment as json then convert it to a deployment go object with workloads inside it | ||||
|     networkObj, err := tfPluginClient.State.LoadNetworkFromGrid(network.Name) | ||||
|  | ||||
|     // Deploy the VM deployments | ||||
|     dl1 := workloads.NewDeployment("vm1", nodeID1, "", nil, network.Name, nil, nil, []workloads.VM{vm1}, nil) | ||||
|     dl2 := workloads.NewDeployment("vm2", nodeID2, "", nil, network.Name, nil, nil, []workloads.VM{vm2}, nil) | ||||
|     err = tfPluginClient.DeploymentDeployer.BatchDeploy(ctx, []*workloads.Deployment{&dl1, &dl2}) | ||||
|  | ||||
|     // Load the VMs using the state loader | ||||
|     vmObj1, err := tfPluginClient.State.LoadVMFromGrid(nodeID1, vm1.Name, dl1.Name) | ||||
|     vmObj2, err := tfPluginClient.State.LoadVMFromGrid(nodeID2, vm2.Name, dl2.Name) | ||||
|  | ||||
|     // Print the VMs Yggdrasil IP | ||||
|     fmt.Println(vmObj1.YggIP) | ||||
|     fmt.Println(vmObj2.YggIP) | ||||
|  | ||||
|     // Cancel the VM deployments | ||||
|     err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl1) | ||||
|     err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl2) | ||||
|  | ||||
|     // Cancel the network | ||||
|     err = tfPluginClient.NetworkDeployer.Cancel(ctx, &network) | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| Running this code should result in two VMs deployed on two separate nodes while being on the same network and you should see an output like this: | ||||
|  | ||||
| ```bash | ||||
| 300:e9c4:9048:57cf:f4e0:2343:f891:6037 | ||||
| 300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f | ||||
| ``` | ||||
		Reference in New Issue
	
	Block a user