Skip to content

Commit

Permalink
add vm deployment example
Browse files Browse the repository at this point in the history
Signed-off-by: mariobassem <[email protected]>
  • Loading branch information
MarioBassem committed Aug 24, 2023
1 parent 786ad7c commit fe3d227
Show file tree
Hide file tree
Showing 9 changed files with 437 additions and 43 deletions.
124 changes: 124 additions & 0 deletions 3bot/zos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Deployments

## Prerequisites

- redis server
- step by step installation [here](https://developer.redis.com/create/linux/)
- [rmb peer](https://github.com/threefoldtech/rmb-rs)
- grid cli
- this is a helper binary to facilitate tfgrid interactions
- how to install:

```bash
cd 3bot/grid_cli
go build -o grid-cli
sudo mv grid-cli /usr/bin/
```

## How to deploy

- for example to make a deployment with Znet and a Zmachine, do the following:
- create a zmachine workload.

```vlang
zmachine := zos.Zmachine{
flist: 'https://hub.grid.tf/tf-official-apps/base:latest.flist'
network: zos.ZmachineNetwork{
public_ip: ''
interfaces: [
zos.ZNetworkInterface{
network: 'network'
ip: '10.1.1.3'
},
]
planetary: true
}
compute_capacity: zos.ComputeCapacity{
cpu: 1
memory: i64(1024) * 1024 * 1024 * 2
}
env: {
'SSH_KEY': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCs3qtlU13/hHKLE8KUkyt+yAH7z5IKs6PH63dhkeQBBG+VdxlTg/a+6DEXqc5VVL6etKRpKKKpDVqUFKuWIK1x3sE+Q6qZ/FiPN+cAAQZjMyevkr5nmX/ofZbvGUAQGo7erxypB0Ye6PFZZVlkZUQBs31dcbNXc6CqtwunJIgWOjCMLIl/wkKUAiod7r4O2lPvD7M2bl0Y/oYCA/FnY9+3UdxlBIi146GBeAvm3+Lpik9jQPaimriBJvAeb90SYIcrHtSSe86t2/9NXcjjN8O7Fa/FboindB2wt5vG+j4APOSbvbWgpDpSfIDPeBbqreSdsqhjhyE36xWwr1IqktX+B9ZuGRoIlPWfCHPJSw/AisfFGPeVeZVW3woUdbdm6bdhoRmGDIGAqPu5Iy576iYiZJnuRb+z8yDbtsbU2eMjRCXn1jnV2GjQcwtxViqiAtbFbqX0eQ0ZU8Zsf0IcFnH1W5Tra/yp9598KmipKHBa+AtsdVu2RRNRW6S4T3MO5SU= mario@mario-machine'
}
}
mut zmachine_workload := zos.Workload{
version: 0
name: 'vm2'
type_: zos.workload_types.zmachine
data: json.encode(zmachine)
description: 'zmachine test'
}
```

- create a znet workload:

```vlang
mut network := zos.Znet{
ip_range: '10.1.0.0/16'
subnet: '10.1.1.0/24'
wireguard_private_key: 'GDU+cjKrHNJS9fodzjFDzNFl5su3kJXTZ3ipPgUjOUE='
wireguard_listen_port: 8080
peers: [
zos.Peer{
subnet: '10.1.2.0/24'
wireguard_public_key: '4KTvZS2KPWYfMr+GbiUUly0ANVg8jBC7xP9Bl79Z8zM='
allowed_ips: ['10.1.2.0/24', '100.64.1.2/32']
},
]
}
mut znet_workload := zos.Workload{
version: 0
name: 'network'
type_: zos.workload_types.network
data: json.encode_pretty(network)
description: 'test network2'
}
```

- create a deployment containing the two workloads:

```vlang
mut deployment := zos.Deployment{
version: 0
twin_id: deployer.twin_id
metadata: 'zm dep'
description: 'zm kjasdf1nafvbeaf1234t21'
workloads: [znet_workload, zmachine_workload]
signature_requirement: zos.SignatureRequirement{
weight_required: 1
requests: [
zos.SignatureRequest{
twin_id: deployer.twin_id
weight: 1
},
]
}
}
```

- create a deployer instance:

```vlang
mnemonics := '<YOUR MNEMONICS>'
substrate_url := 'wss://tfchain.dev.grid.tf/ws'
mut client := rmb.new(nettype: rmb.TFNetType.dev, tfchain_mnemonic: mnemonics)!
mut deployer := zos.Deployer{
mnemonics: mnemonics
substrate_url: substrate_url
twin_id: 'YOUR TWIN ID'
rmb_cl: client
}
```

- use the deployer to deploy the deployment:

```vlang
contract_id := deployer.deploy(node_id, mut deployment, '', 0) or {
logger.error('failed to deploy deployment: ${err}')
exit(1)
}
```

For more examples, go to [examples](./examples/)
23 changes: 14 additions & 9 deletions 3bot/zos/deploy_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import freeflowuniverse.crystallib.threefold.rmb
import json

fn test_deploy_deployment() {
mnemonics := 'route visual hundred rabbit wet crunch ice castle milk model inherit outside'
mnemonics := '<YOUR MNEMONICS>'
substrate_url := 'wss://tfchain.dev.grid.tf/ws'
mut deployer := Deployer{
mnemonics: mnemonics
substrate_url: substrate_url
}
node_id := u32(11)
node_id := u32(14)
twin_id := u32(49)
node_twin_id := u32(21) // TODO: need to get this from chain
node_twin_id := u32(22) // TODO: need to get this from chain

mut network := Znet{
ip_range: '10.1.0.0/16'
Expand All @@ -31,7 +31,7 @@ fn test_deploy_deployment() {
version: 0
name: 'network'
type_: workload_types.network
data: json.encode(network)
data: json.encode_pretty(network)
description: 'test network2'
}

Expand All @@ -58,7 +58,7 @@ fn test_deploy_deployment() {

mut zmachine_workload := Workload{
version: 0
name: 'vm'
name: 'vm2'
type_: workload_types.zmachine
data: json.encode(zmachine)
description: 'zmachine test'
Expand All @@ -68,7 +68,7 @@ fn test_deploy_deployment() {
version: 0
twin_id: twin_id
metadata: 'zm dep'
description: 'zm test1'
description: 'zm kjasdf1nafvbeaf1234t21'
workloads: [znet_workload, zmachine_workload]
signature_requirement: SignatureRequirement{
weight_required: 1
Expand All @@ -84,15 +84,20 @@ fn test_deploy_deployment() {
hash := deployment.challenge_hash()
hex_hash := hash.hex()

contract_id := deployer.create_node_contract(node_id, '', hex_hash, 0, 0)!
contract_id := deployer.create_node_contract(0, '', hex_hash, 0, 0)!
deployment.contract_id = contract_id

signature := deployer.sign_deployment(hex_hash)!
deployment.add_signature(twin_id, signature)

payload := json.encode(deployment)
payload := deployment.json_encode()!
print('payload: ${payload}')
exit(0)
mut client := rmb.new(nettype: rmb.TFNetType.dev, tfchain_mnemonic: mnemonics)!
response := client.rmb_request('zos.deployment.deploy', node_twin_id)!
response := client.rmb_request('zos.deployment.deploy', node_twin_id, payload) or {
print('error: ${err}')
exit(1)
}
if response.err.code != 0 {
print(response.err.message)
}
Expand Down
45 changes: 28 additions & 17 deletions 3bot/zos/deployer.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ module zos
import os
import strconv
import freeflowuniverse.crystallib.threefold.rmb
import json
import encoding.base64

pub struct Deployer {
pub:
mnemonics string
substrate_url string
twin_id u32
rmb_cl rmb.RMBClient
twin_id u32
pub mut:
rmb_cl rmb.RMBClient
}

pub fn (mut d Deployer) deploy(node_id u32, dl Deployment, body string, solution_provider u64) !u64{
pub fn (mut d Deployer) deploy(node_id u32, mut dl Deployment, body string, solution_provider u64) !u64 {
hash_hex := dl.challenge_hash().hex()
public_ips := dl.count_public_ips()

Expand All @@ -20,37 +24,44 @@ pub fn (mut d Deployer) deploy(node_id u32, dl Deployment, body string, solution

signature := d.sign_deployment(hash_hex)!
dl.add_signature(d.twin_id, signature)
payload := dl.json_encode()!
payload := dl.json_encode()

node_twin_id := d.get_node_twin(node_id)!

res := d.rmb_cl.rmb_request('zos.deployment.deploy', node_twin_id, payload)!
if res.err.code != 0 {
return error("an error occured while trying to deploy to the node: ${res.err.message}")
return error('an error occured while trying to deploy to the node: ${res.err.message}')
}
return contract_id
}

pub fn (mut d Deployer) get_deployment(contract_id u64, node_id u64) !Deployment {
pub fn (mut d Deployer) get_deployment(contract_id u64, node_id u32) !Deployment {
twin_id := d.get_node_twin(node_id)!
payload := {
'contract_id': contract_id
}

res := d.rmb_cl.rmb_request('zos.deployment.get', twin_id, "")!
res := d.rmb_cl.rmb_request('zos.deployment.get', twin_id, json.encode(payload))!
if res.err.code != 0 {
return error("an error occured while trying to deploy to the node: ${res.err.message}")
return error('an error occured while trying to deploy to the node: ${res.err.message}')
}

return json.decode(Deployment, res.data)

decoded_data := base64.decode_str(res.dat)

return json.decode(Deployment, decoded_data)
}

pub fn (mut d Deployer) get_node_twin(node_id u64) !u32 {
res := os.execute("./grid node-twin --substrate ${d.substrate_url} --node_id ${node_id}")
res := os.execute('grid-cli node-twin --substrate ${d.substrate_url} --node_id ${node_id}')
if res.exit_code != 0 {
return error(res.output)
}

return strconv.parse_uint(res.output, 10, 32)!
return u32(strconv.parse_uint(res.output, 10, 32)!)
}

pub fn (mut d Deployer) create_node_contract(node_id u32, body string, hash string, public_ips u32, solution_provider u64) !u64 {
res := os.execute("./grid new-node-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --node_id ${node_id} --hash \"${hash}\" --public_ips ${public_ips} --solution_provider ${solution_provider}")
res := os.execute("grid-cli new-node-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --node_id ${node_id} --hash \"${hash}\" --public_ips ${public_ips} --solution_provider ${solution_provider}")
if res.exit_code != 0 {
return error(res.output)
}
Expand All @@ -59,7 +70,7 @@ pub fn (mut d Deployer) create_node_contract(node_id u32, body string, hash stri
}

pub fn (mut d Deployer) create_name_contract(name string) !u64 {
res := os.execute("./grid new-name-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --name ${name}")
res := os.execute("grid-cli new-name-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --name ${name}")
if res.exit_code != 0 {
return error(res.output)
}
Expand All @@ -68,21 +79,21 @@ pub fn (mut d Deployer) create_name_contract(name string) !u64 {
}

pub fn (mut d Deployer) update_node_contract(contract_id u64, body string, hash string) ! {
res := os.execute("./grid update-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --contract_id ${contract_id} --body \"${body}\" --hash \"${hash}\"")
res := os.execute("grid-cli update-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --contract_id ${contract_id} --body \"${body}\" --hash \"${hash}\"")
if res.exit_code != 0 {
return error(res.output)
}
}

pub fn (mut d Deployer) cancel_contract(contract_id u64) ! {
res := os.execute("./grid cancel-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --contract_id ${contract_id}")
res := os.execute("grid-cli cancel-cn --substrate ${d.substrate_url} --mnemonics \"${d.mnemonics}\" --contract_id ${contract_id}")
if res.exit_code != 0 {
return error(res.output)
}
}

pub fn (mut d Deployer) sign_deployment(hash string) !string {
res := os.execute("./grid sign --mnemonics \"${d.mnemonics}\" --hash ${hash}")
res := os.execute("grid-cli sign --mnemonics \"${d.mnemonics}\" --hash ${hash}")
if res.exit_code != 0 {
return error(res.output)
}
Expand Down
10 changes: 5 additions & 5 deletions 3bot/zos/deployment.v
Original file line number Diff line number Diff line change
Expand Up @@ -114,22 +114,22 @@ pub fn (mut d Deployment) add_signature(twin u32, signature string) {
}
}

pub fn (mut d Deployment) json_encode() !string {
pub fn (mut d Deployment) json_encode() string {
mut encoded_workloads := []string{}
for mut w in d.workloads {
encoded_workloads << w.json_encode()!
encoded_workloads << w.json_encode()
}

workloads := '[${encoded_workloads.join(',')}]'
return '{"version":${d.version},"twin_id":${d.twin_id},"contract_id":${d.contract_id},"expiration":${d.expiration},"metadata":"${d.metadata}","description":"${d.description}","workloads":${workloads},"signature_requirement":${json.encode(d.signature_requirement)}}'
}

fn (mut dl Deployment) count_public_ips() u8{
count := 0
fn (dl Deployment) count_public_ips() u8 {
mut count := u8(0)
for wl in dl.workloads {
if wl.type_ == workload_types.public_ip {
count += 1
}
}
}
return count
}
Loading

0 comments on commit fe3d227

Please sign in to comment.