219 lines
6.5 KiB
GLSL
Executable File
219 lines
6.5 KiB
GLSL
Executable File
#!/usr/bin/env -S v -n -w -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
|
|
|
import freeflowuniverse.herolib.threefold.grid.models
|
|
import freeflowuniverse.herolib.threefold.grid as tfgrid
|
|
import freeflowuniverse.herolib.threefold.gridproxy
|
|
import freeflowuniverse.herolib.threefold.gridproxy.model { NodeFilter }
|
|
import rand
|
|
import log
|
|
import os
|
|
import flag
|
|
import json
|
|
|
|
fn get_machine_result(dl models.Deployment) !models.ZmachineResult {
|
|
for _, w in dl.workloads {
|
|
if w.type_ == models.workload_types.zmachine {
|
|
res := json.decode(models.ZmachineResult, w.result.data)!
|
|
return res
|
|
}
|
|
}
|
|
|
|
return error('failed to get zmachine workload')
|
|
}
|
|
|
|
fn get_gateway_name_result(dl models.Deployment) !models.GatewayProxyResult {
|
|
for _, w in dl.workloads {
|
|
if w.type_ == models.workload_types.gateway_name {
|
|
res := json.decode(models.GatewayProxyResult, w.result.data)!
|
|
return res
|
|
}
|
|
}
|
|
|
|
return error('failed to get gateway_name workload')
|
|
}
|
|
|
|
fn get_chain_network(network string) !tfgrid.ChainNetwork {
|
|
chain_net_enum := match network {
|
|
'dev' { tfgrid.ChainNetwork.dev }
|
|
'qa' { tfgrid.ChainNetwork.qa }
|
|
'test' { tfgrid.ChainNetwork.test }
|
|
'main' { tfgrid.ChainNetwork.main }
|
|
else { return error('invalid chain newtork ${network}. must be one of (dev, qa, test, main)') }
|
|
}
|
|
|
|
return chain_net_enum
|
|
}
|
|
|
|
fn get_node_id(network tfgrid.ChainNetwork, memory int, disk int, cpu int, public_ip bool, has_domain bool, available_for u64) !u32 {
|
|
gp_net := match network {
|
|
.dev { gridproxy.TFGridNet.dev }
|
|
.qa { gridproxy.TFGridNet.qa }
|
|
.test { gridproxy.TFGridNet.test }
|
|
.main { gridproxy.TFGridNet.main }
|
|
}
|
|
|
|
mut gridproxy_client := gridproxy.get(gp_net, false)!
|
|
mut free_ips := u64(0)
|
|
if public_ip {
|
|
free_ips = 1
|
|
}
|
|
|
|
mut filter_ := NodeFilter{
|
|
free_ips: free_ips
|
|
free_mru: u64(memory) * (1204 * 1204 * 1204)
|
|
free_sru: u64(disk) * (1204 * 1204 * 1204)
|
|
total_cru: u64(cpu)
|
|
domain: has_domain
|
|
available_for: available_for
|
|
status: 'up'
|
|
randomize: true
|
|
size: u64(1)
|
|
}
|
|
|
|
nodes := gridproxy_client.get_nodes(filter_)!
|
|
if nodes.len != 1 {
|
|
return error('cannot find a suitable node matching your specs')
|
|
}
|
|
|
|
return u32(nodes[0].node_id)
|
|
}
|
|
|
|
mut fp := flag.new_flag_parser(os.args)
|
|
fp.application('VM with gateway deployer tool')
|
|
fp.version('v0.0.1')
|
|
fp.skip_executable()
|
|
|
|
mnemonics := fp.string_opt('mnemonic', `m`, 'Your Mnemonic phrase')!
|
|
chain_network := fp.string('network', `n`, 'main', 'Your desired chain network (main, test, qa, dev). Defaults to main')
|
|
ssh_key := fp.string_opt('ssh_key', `s`, 'Your public ssh key')!
|
|
cpu := fp.int('cpu', `c`, 4, 'Machine CPU provisioning. Defaults to 4')
|
|
memory := fp.int('ram', `r`, 4, 'Machine memory provisioning in GB. Defaults to 4')
|
|
disk := fp.int('disk', `d`, 5, 'Machine Disk space provisioning in GB. Defaults to 5')
|
|
public_ip := fp.bool('public_ip', `i`, false, 'True to allow public ip v4')
|
|
|
|
mut logger := &log.Log{}
|
|
logger.set_level(.debug)
|
|
|
|
chain_net_enum := get_chain_network(chain_network)!
|
|
mut deployer := tfgrid.new_deployer(mnemonics, chain_net_enum, mut logger)!
|
|
|
|
mut workloads := []models.Workload{}
|
|
node_id := get_node_id(chain_net_enum, memory, disk, cpu, public_ip, false, deployer.twin_id)!
|
|
// node_id := u32(150)
|
|
logger.info('deploying on node: ${node_id}')
|
|
|
|
network_name := 'net_${rand.string(5).to_lower()}' // autocreate a network
|
|
wg_port := deployer.assign_wg_port(node_id)!
|
|
mut network := models.Znet{
|
|
ip_range: '10.1.0.0/16' // auto-assign
|
|
subnet: '10.1.1.0/24' // auto-assign
|
|
wireguard_private_key: 'GDU+cjKrHNJS9fodzjFDzNFl5su3kJXTZ3ipPgUjOUE=' // autocreate
|
|
wireguard_listen_port: wg_port
|
|
// mycelium: models.Mycelium{
|
|
// hex_key: rand.string(32).bytes().hex()
|
|
// }
|
|
}
|
|
|
|
workloads << network.to_workload(name: network_name, description: 'test_network1')
|
|
|
|
mut public_ip_name := ''
|
|
if public_ip {
|
|
public_ip_name = rand.string(5).to_lower()
|
|
workloads << models.PublicIP{
|
|
v4: true
|
|
}.to_workload(name: public_ip_name)
|
|
}
|
|
|
|
zmachine := models.Zmachine{
|
|
flist: 'https://hub.grid.tf/tf-official-apps/base:latest.flist'
|
|
network: models.ZmachineNetwork{
|
|
interfaces: [
|
|
models.ZNetworkInterface{
|
|
network: network_name
|
|
ip: '10.1.1.3'
|
|
},
|
|
]
|
|
public_ip: public_ip_name
|
|
planetary: true
|
|
// mycelium: models.MyceliumIP{
|
|
// network: network_name
|
|
// hex_seed: rand.string(6).bytes().hex()
|
|
// }
|
|
}
|
|
entrypoint: '/sbin/zinit init' // from user or default
|
|
compute_capacity: models.ComputeCapacity{
|
|
cpu: u8(cpu)
|
|
memory: i64(memory) * 1024 * 1024 * 1024
|
|
}
|
|
size: u64(disk) * 1024 * 1024 * 1024
|
|
env: {
|
|
'SSH_KEY': ssh_key
|
|
}
|
|
}
|
|
|
|
workloads << zmachine.to_workload(
|
|
name: 'vm_${rand.string(5).to_lower()}'
|
|
description: 'zmachine_test'
|
|
)
|
|
|
|
signature_requirement := models.SignatureRequirement{
|
|
weight_required: 1
|
|
requests: [
|
|
models.SignatureRequest{
|
|
twin_id: deployer.twin_id
|
|
weight: 1
|
|
},
|
|
]
|
|
}
|
|
|
|
mut deployment := models.new_deployment(
|
|
twin_id: deployer.twin_id
|
|
description: 'vm with gateway'
|
|
workloads: workloads
|
|
signature_requirement: signature_requirement
|
|
)
|
|
deployment.add_metadata('vm', 'SimpleVM')
|
|
|
|
contract_id := deployer.deploy(node_id, mut deployment, deployment.metadata, 0) or {
|
|
logger.error('failed to deploy deployment: ${err}')
|
|
exit(1)
|
|
}
|
|
logger.info('deployment contract id: ${contract_id}')
|
|
dl := deployer.get_deployment(contract_id, node_id) or {
|
|
logger.error('failed to get deployment data: ${err}')
|
|
exit(1)
|
|
}
|
|
|
|
machine_res := get_machine_result(dl)!
|
|
logger.info('zmachine result: ${machine_res}')
|
|
|
|
gw_name := rand.string(5).to_lower()
|
|
gw := models.GatewayNameProxy{
|
|
tls_passthrough: false
|
|
backends: ['http://[${machine_res.planetary_ip}]:9000']
|
|
name: gw_name
|
|
}
|
|
|
|
gw_workload := gw.to_workload(name: gw_name)
|
|
|
|
name_contract_id := deployer.client.create_name_contract(gw_name)!
|
|
logger.info('name contract ${gw_workload.name} created with id ${name_contract_id}')
|
|
|
|
mut gw_deployment := models.new_deployment(
|
|
twin_id: deployer.twin_id
|
|
workloads: [gw_workload]
|
|
signature_requirement: signature_requirement
|
|
)
|
|
|
|
gw_node_id := get_node_id(chain_net_enum, 0, 0, 0, false, true, deployer.twin_id)!
|
|
gw_node_contract_id := deployer.deploy(gw_node_id, mut gw_deployment, '', 0)!
|
|
logger.info('gateway node contract created with id ${gw_node_contract_id}')
|
|
|
|
gateway_dl := deployer.get_deployment(gw_node_contract_id, gw_node_id) or {
|
|
logger.error('failed to get deployment data: ${err}')
|
|
exit(1)
|
|
}
|
|
|
|
gw_res := get_gateway_name_result(gateway_dl)!
|
|
logger.info('gateway: ${gw_res}')
|