diff --git a/aiprompts/ai_core/osal_os_system_tools.md b/aiprompts/ai_core/osal_os_system_tools.md index 6a449a5c..66427a76 100644 --- a/aiprompts/ai_core/osal_os_system_tools.md +++ b/aiprompts/ai_core/osal_os_system_tools.md @@ -133,7 +133,8 @@ fn env_unset_all() Unsets all environment variables fn exec(cmd Command) !Job cmd is the cmd to execute can use ' ' and spaces . if \n in cmd it will write it to ext and then execute with bash . if die==false then will just return returncode,out but not return error . if stdout will show stderr and stdout . . if cmd starts with find or ls, will give to bash -c so it can execute . if cmd has no path, path will be found . . Command argument: . -``` + +```` name string // to give a name to your command, good to see logs... cmd string description string @@ -243,7 +244,7 @@ add the following path to a profile fn profile_path_add_hero() !string fn profile_path_source() string return the source statement if the profile exists -fn profile_path_source_and()! string +fn profile_path_source_and() string return source $path && . or empty if it doesn't exist fn sleep(duration int) sleep in seconds @@ -437,3 +438,4 @@ name string @[required] } - +```` diff --git a/examples/threefold/tfgrid3deployer/vm_gw_caddy/delete.vsh b/examples/threefold/tfgrid3deployer/vm_gw_caddy/delete.vsh index bb78920d..1ff3ae23 100755 --- a/examples/threefold/tfgrid3deployer/vm_gw_caddy/delete.vsh +++ b/examples/threefold/tfgrid3deployer/vm_gw_caddy/delete.vsh @@ -6,8 +6,7 @@ import freeflowuniverse.herolib.installers.threefold.griddriver import os import time -mut installer := griddriver.get()! -installer.install()! +griddriver.install()! v := tfgrid3deployer.get()! println('cred: ${v}') @@ -20,6 +19,6 @@ os.rm('${os.home_dir()}/hero/db/0/session_deployer/${deployment_name}')! deployment_name2 := 'vm_caddy_gw' mut deployment2 := tfgrid3deployer.get_deployment(deployment_name2)! -deployment2.remove_webname('mywebname')! +deployment2.remove_webname('gwnamecaddy')! deployment2.deploy()! os.rm('${os.home_dir()}/hero/db/0/session_deployer/${deployment_name2}')! diff --git a/examples/threefold/tfgrid3deployer/vm_gw_caddy/vm_gw_caddy.vsh b/examples/threefold/tfgrid3deployer/vm_gw_caddy/vm_gw_caddy.vsh index 94b2ef06..ca32512a 100755 --- a/examples/threefold/tfgrid3deployer/vm_gw_caddy/vm_gw_caddy.vsh +++ b/examples/threefold/tfgrid3deployer/vm_gw_caddy/vm_gw_caddy.vsh @@ -7,8 +7,7 @@ import freeflowuniverse.herolib.installers.threefold.griddriver import os import time -mut installer := griddriver.get()! -installer.install()! +griddriver.install()! v := tfgrid3deployer.get()! println('cred: ${v}') @@ -18,7 +17,7 @@ deployment.add_machine( name: 'vm_caddy1' cpu: 1 memory: 2 - planetary: true + planetary: false public_ip4: true size: 10 // 10 gig mycelium: tfgrid3deployer.Mycelium{} @@ -32,10 +31,10 @@ vm1_public_ip4 := vm1.public_ip4.all_before('/') deployment_name2 := 'vm_caddy_gw' mut deployment2 := tfgrid3deployer.new_deployment(deployment_name2)! -deployment2.add_webname(name: 'mywebname', backend: 'http://${vm1_public_ip4}:80') +deployment2.add_webname(name: 'gwnamecaddy', backend: 'http://${vm1_public_ip4}:80') deployment2.deploy()! -gw1 := deployment2.webname_get('mywebname')! +gw1 := deployment2.webname_get('gwnamecaddy')! println('gw info: ${gw1}') // Retry logic to wait for the SSH server to be up diff --git a/lib/data/ipaddress/ipaddress.v b/lib/data/ipaddress/ipaddress.v index c67498e9..fb158848 100644 --- a/lib/data/ipaddress/ipaddress.v +++ b/lib/data/ipaddress/ipaddress.v @@ -2,6 +2,7 @@ module ipaddress import os import freeflowuniverse.herolib.osal +import freeflowuniverse.herolib.core import freeflowuniverse.herolib.ui.console pub struct IPNetwork { @@ -124,7 +125,7 @@ pub mut: // PingArgs: retry & timeout // retry default 1 // timeout default 1000 (msec) -pub fn (mut ipaddr IPAddress) ping(args_ PingArgs) bool { +pub fn (mut ipaddr IPAddress) ping(args_ PingArgs) !bool { mut args := args_ if args.retry == 0 { args.retry = 1 diff --git a/lib/develop/gittools/gitlocation.v b/lib/develop/gittools/gitlocation.v index 60ffb272..3262c66f 100644 --- a/lib/develop/gittools/gitlocation.v +++ b/lib/develop/gittools/gitlocation.v @@ -58,24 +58,28 @@ pub fn (mut gs GitStructure) gitlocation_from_url(url string) !GitLocation { mut path := '' mut branch_or_tag := '' - // Deal with path and anchor - if parts.len > 4 { - path = parts[4..].join('/') - if path.contains('#') { - parts2 := path.split('#') - if parts2.len == 2 { - path = parts2[0] - anchor = parts2[1] - } else { - return error("git: url badly formatted, more than 1 '#' in ${url}") + // Extract branch if available + for i := 0; i < parts.len; i++ { + if parts[i] == 'refs' || parts[i] == 'tree' { + if i + 1 < parts.len { + branch_or_tag = parts[i + 1] } + if i + 2 < parts.len { + path = parts[(i + 2)..].join('/') + } + break } } - // Extract branch if available - if parts.len > 3 { - branch_or_tag = parts[3] - parts[2] = parts[2].replace('.git', '') + // Deal with path and anchor + if path.contains('#') { + parts2 := path.split('#') + if parts2.len == 2 { + path = parts2[0] + anchor = parts2[1] + } else { + return error("git: url badly formatted, more than 1 '#' in ${url}") + } } // Validate parts @@ -98,7 +102,7 @@ pub fn (mut gs GitStructure) gitlocation_from_url(url string) !GitLocation { } } -// Return a herolib path object on the filesystem pointing to the locator +// Return a crystallib path object on the filesystem pointing to the locator pub fn (mut l GitLocation) patho() !pathlib.Path { mut addrpath := pathlib.get_dir(path: '${l.provider}/${l.account}/${l.name}', create: false)! if l.path.len > 0 { diff --git a/lib/develop/gittools/repository.v b/lib/develop/gittools/repository.v index 691ffeac..4480f2af 100644 --- a/lib/develop/gittools/repository.v +++ b/lib/develop/gittools/repository.v @@ -3,7 +3,6 @@ module gittools import freeflowuniverse.herolib.ui.console import freeflowuniverse.herolib.osal import os -import time // GitRepo holds information about a single Git repository. @[heap] @@ -146,7 +145,7 @@ pub fn (mut repo GitRepo) checkout() ! { repo.exec('git checkout tags/${repo.status_wanted.tag}')! } if repo.status_wanted.branch.len > 0 { - repo.exec('git checkout ${repo.status_wanted.tag}')! + repo.exec('git checkout ${repo.status_wanted.branch}')! } } diff --git a/lib/develop/gittools/repository_clone.v b/lib/develop/gittools/repository_clone.v index 084d1870..59dc08a8 100644 --- a/lib/develop/gittools/repository_clone.v +++ b/lib/develop/gittools/repository_clone.v @@ -16,11 +16,13 @@ pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo { if args.url.len == 0 { return error('url needs to be specified when doing a clone.') } + console.print_header('Git clone from the URL: ${args.url}.') git_location := gitstructure.gitlocation_from_url(args.url)! mut repo := gitstructure.repo_new_from_gitlocation(git_location)! repo.status_wanted.url = args.url + repo.status_wanted.branch = git_location.branch_or_tag if args.sshkey.len > 0 { repo.set_sshkey(args.sshkey)! @@ -33,13 +35,16 @@ pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo { extra = '--depth 1 --no-single-branch ' } - cmd := 'cd ${parent_dir} && git clone ${extra} ${repo.get_repo_url()!} ${repo.name}' + cmd := 'cd ${parent_dir} && git clone ${extra} ${repo.get_http_url()!} ${repo.name}' result := os.execute(cmd) if result.exit_code != 0 { return error('Cannot clone the repository due to: \n${result.output}') } repo.load()! + if repo.need_checkout() { + repo.checkout()! + } console.print_green("The repository '${repo.name}' cloned into ${parent_dir}.") diff --git a/lib/installers/infra/livekit/livekit_actions.v b/lib/installers/infra/livekit/livekit_actions.v index 04e6a53d..fff2785d 100644 --- a/lib/installers/infra/livekit/livekit_actions.v +++ b/lib/installers/infra/livekit/livekit_actions.v @@ -9,8 +9,8 @@ import json import os // checks if a certain version or above is installed -fn installed_() !bool { - res := os.execute('${osal.profile_path_source_and()!} livekit-server -v') +fn installed() !bool { + res := os.execute('${osal.profile_path_source_and()} livekit-server -v') if res.exit_code != 0 { return false } @@ -25,7 +25,7 @@ fn installed_() !bool { return true } -fn install_() ! { +fn install() ! { console.print_header('install livekit') mut installer := get()! osal.execute_silent(' @@ -45,7 +45,7 @@ fn startupcmd() ![]zinit.ZProcessNewArgs { return res } -fn running_() !bool { +fn running() !bool { mut installer := get()! myport := installer.nr * 2 + 7880 @@ -90,7 +90,7 @@ fn stop_post() ! { // Post-stop cleanup if needed } -fn destroy_() ! { +fn destroy() ! { mut installer := get()! os.rm(installer.configpath) or {} os.rm('livekit-server') or {} diff --git a/lib/installers/infra/livekit/livekit_factory_.v b/lib/installers/infra/livekit/livekit_factory_.v index 0a2563dd..abc47f3b 100644 --- a/lib/installers/infra/livekit/livekit_factory_.v +++ b/lib/installers/infra/livekit/livekit_factory_.v @@ -2,8 +2,6 @@ module livekit import freeflowuniverse.herolib.core.base import freeflowuniverse.herolib.core.playbook -import freeflowuniverse.herolib.ui.console -import freeflowuniverse.herolib.data.encoderhero import freeflowuniverse.herolib.sysadmin.startupmanager import freeflowuniverse.herolib.osal.zinit import time @@ -18,127 +16,89 @@ __global ( @[params] pub struct ArgsGet { pub mut: - name string + name string = 'default' } fn args_get(args_ ArgsGet) ArgsGet { - mut model := args_ - if model.name == '' { - model.name = livekit_default + mut args := args_ + if args.name == '' { + args.name = livekit_default } - if model.name == '' { - model.name = 'default' + if args.name == '' { + args.name = 'default' } - return model + return args } pub fn get(args_ ArgsGet) !&LivekitServer { mut args := args_get(args_) if args.name !in livekit_global { - if args.name == 'default' { - if !config_exists(args) { - if default { - mut context := base.context() or { panic('bug') } - context.hero_config_set('livekit', model.name, heroscript_default()!)! - } + if !config_exists() { + if default { + config_save()! } - load(args)! } + config_load()! } return livekit_global[args.name] or { println(livekit_global) - panic('could not get config for ${args.name} with name:${model.name}') + panic('bug in get from factory: ') } } -// set the model in mem and the config on the filesystem -pub fn set(o LivekitServer) ! { - mut o2 := obj_init(o)! - livekit_global[o.name] = &o2 - livekit_default = o.name -} - -// check we find the config on the filesystem -pub fn exists(args_ ArgsGet) bool { - mut model := args_get(args_) +fn config_exists(args_ ArgsGet) bool { + mut args := args_get(args_) mut context := base.context() or { panic('bug') } - return context.hero_config_exists('livekit', model.name) + return context.hero_config_exists('livekit', args.name) } -// load the config error if it doesn't exist -pub fn load(args_ ArgsGet) ! { - mut model := args_get(args_) +fn config_load(args_ ArgsGet) ! { + mut args := args_get(args_) mut context := base.context()! - mut heroscript := context.hero_config_get('livekit', model.name)! + mut heroscript := context.hero_config_get('livekit', args.name)! play(heroscript: heroscript)! } -// save the config to the filesystem in the context -pub fn save(o LivekitServer) ! { +fn config_save(args_ ArgsGet) ! { + mut args := args_get(args_) mut context := base.context()! - heroscript := encoderhero.encode[LivekitServer](o)! - context.hero_config_set('livekit', model.name, heroscript)! + context.hero_config_set('livekit', args.name, heroscript_default()!)! +} + +fn set(o LivekitServer) ! { + mut o2 := obj_init(o)! + livekit_global['default'] = &o2 } @[params] pub struct PlayArgs { pub mut: + name string = 'default' heroscript string // if filled in then plbook will be made out of it plbook ?playbook.PlayBook reset bool + + start bool + stop bool + restart bool + delete bool + configure bool // make sure there is at least one installed } pub fn play(args_ PlayArgs) ! { - mut model := args_ + mut args := args_ - if model.heroscript == '' { - model.heroscript = heroscript_default()! + if args.heroscript == '' { + args.heroscript = heroscript_default()! } - mut plbook := model.plbook or { playbook.new(text: model.heroscript)! } + mut plbook := args.plbook or { playbook.new(text: args.heroscript)! } - mut configure_actions := plbook.find(filter: 'livekit.configure')! - if configure_actions.len > 0 { - for config_action in configure_actions { - mut p := config_action.params + mut install_actions := plbook.find(filter: 'livekit.configure')! + if install_actions.len > 0 { + for install_action in install_actions { + mut p := install_action.params mycfg := cfg_play(p)! - console.print_debug('install action livekit.configure\n${mycfg}') set(mycfg)! - save(mycfg)! - } - } - - mut other_actions := plbook.find(filter: 'livekit.')! - for other_action in other_actions { - if other_action.name in ['destroy', 'install', 'build'] { - mut p := other_action.params - reset := p.get_default_false('reset') - if other_action.name == 'destroy' || reset { - console.print_debug('install action livekit.destroy') - destroy_()! - } - if other_action.name == 'install' { - console.print_debug('install action livekit.install') - install_()! - } - } - if other_action.name in ['start', 'stop', 'restart'] { - mut p := other_action.params - name := p.get('name')! - mut livekit_obj := get(name: name)! - console.print_debug('action object:\n${livekit_obj}') - if other_action.name == 'start' { - console.print_debug('install action livekit.${other_action.name}') - livekit_obj.start()! - } - - if other_action.name == 'stop' { - console.print_debug('install action livekit.${other_action.name}') - livekit_obj.stop()! - } - if other_action.name == 'restart' { - console.print_debug('install action livekit.${other_action.name}') - livekit_obj.restart()! - } } } } @@ -153,28 +113,6 @@ pub fn (mut self LivekitServer) reload() ! { self = obj_init(self)! } -fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager { - // unknown - // screen - // zinit - // tmux - // systemd - match cat { - .zinit { - console.print_debug('startupmanager: zinit') - return startupmanager.get(cat: .zinit)! - } - .systemd { - console.print_debug('startupmanager: systemd') - return startupmanager.get(cat: .systemd)! - } - else { - console.print_debug('startupmanager: auto') - return startupmanager.get()! - } - } -} - pub fn (mut self LivekitServer) start() ! { switch(self.name) if self.running()! { @@ -183,21 +121,13 @@ pub fn (mut self LivekitServer) start() ! { console.print_header('livekit start') - if !installed_()! { - install_()! - } - configure()! start_pre()! + mut sm := startupmanager.get()! + for zprocess in startupcmd()! { - mut sm := startupmanager_get(zprocess.startuptype)! - - console.print_debug('starting livekit with ${zprocess.startuptype}...') - - sm.new(zprocess)! - sm.start(zprocess.name)! } @@ -212,17 +142,17 @@ pub fn (mut self LivekitServer) start() ! { return error('livekit did not install properly.') } -pub fn (mut self LivekitServer) install_start(model InstallArgs) ! { +pub fn (mut self LivekitServer) install_start(args RestartArgs) ! { switch(self.name) - self.install(model)! + self.install(args)! self.start()! } pub fn (mut self LivekitServer) stop() ! { switch(self.name) stop_pre()! + mut sm := startupmanager.get()! for zprocess in startupcmd()! { - mut sm := startupmanager_get(zprocess.startuptype)! sm.stop(zprocess.name)! } stop_post()! @@ -236,10 +166,10 @@ pub fn (mut self LivekitServer) restart() ! { pub fn (mut self LivekitServer) running() !bool { switch(self.name) + mut sm := startupmanager.get()! // walk over the generic processes, if not running return for zprocess in startupcmd()! { - mut sm := startupmanager_get(zprocess.startuptype)! r := sm.running(zprocess.name)! if r == false { return false @@ -254,6 +184,20 @@ pub mut: reset bool } +pub fn (mut self LivekitServer) install(args InstallArgs) ! { + switch(self.name) + if args.reset || (!installed()!) { + install()! + } +} + +pub fn (mut self LivekitServer) destroy() ! { + switch(self.name) + + self.stop()! + destroy()! +} + // switch instance to be used for livekit pub fn switch(name string) { livekit_default = name diff --git a/lib/installers/lang/golang/golang_actions.v b/lib/installers/lang/golang/golang_actions.v index e7682231..68ee4164 100644 --- a/lib/installers/lang/golang/golang_actions.v +++ b/lib/installers/lang/golang/golang_actions.v @@ -10,8 +10,7 @@ import os // checks if a certain version or above is installed fn installed_() !bool { - res := os.execute('${osal.profile_path_source_and()!} go version') - + res := os.execute('/bin/bash -c "go version"') if res.exit_code == 0 { r := res.output.split_into_lines() .filter(it.contains('go version')) diff --git a/lib/installers/lang/golang/golang_factory_.v b/lib/installers/lang/golang/golang_factory_.v index ddc0e148..01e1c464 100644 --- a/lib/installers/lang/golang/golang_factory_.v +++ b/lib/installers/lang/golang/golang_factory_.v @@ -1,11 +1,8 @@ module golang -import freeflowuniverse.herolib.core.base -import freeflowuniverse.herolib.core.playbook -import freeflowuniverse.herolib.ui.console import freeflowuniverse.herolib.sysadmin.startupmanager import freeflowuniverse.herolib.osal.zinit -import time +import freeflowuniverse.herolib.ui.console __global ( golang_global map[string]&GolangInstaller @@ -14,29 +11,66 @@ __global ( /////////FACTORY +@[params] +pub struct ArgsGet { +pub mut: + name string +} + +pub fn get(args_ ArgsGet) !&GolangInstaller { + return &GolangInstaller{} +} + //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS /////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// +fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager { + // unknown + // screen + // zinit + // tmux + // systemd + match cat { + .zinit { + console.print_debug('startupmanager: zinit') + return startupmanager.get(cat: .zinit)! + } + .systemd { + console.print_debug('startupmanager: systemd') + return startupmanager.get(cat: .systemd)! + } + else { + console.print_debug('startupmanager: auto') + return startupmanager.get()! + } + } +} + @[params] pub struct InstallArgs { pub mut: reset bool } -pub fn install(args InstallArgs) ! { - if args.reset { - destroy()! - } - if !(installed_()!) { +pub fn (mut self GolangInstaller) install(args InstallArgs) ! { + switch(self.name) + if args.reset || (!installed_()!) { install_()! } } -pub fn destroy() ! { +pub fn (mut self GolangInstaller) build() ! { + switch(self.name) + build_()! +} + +pub fn (mut self GolangInstaller) destroy() ! { + switch(self.name) destroy_()! } -pub fn build() ! { - build_()! +// switch instance to be used for golang +pub fn switch(name string) { + golang_default = name } diff --git a/lib/installers/threefold/griddriver/griddriver_actions.v b/lib/installers/threefold/griddriver/griddriver_actions.v index 4d984bc0..26d5de9e 100644 --- a/lib/installers/threefold/griddriver/griddriver_actions.v +++ b/lib/installers/threefold/griddriver/griddriver_actions.v @@ -10,7 +10,7 @@ import os // checks if a certain version or above is installed fn installed_() !bool { - res := os.execute('${osal.profile_path_source_and()!} griddriver --version') + res := os.execute('/bin/bash -c "griddriver --version"') if res.exit_code != 0 { return false } diff --git a/lib/threefold/tfgrid3deployer/deployment.v b/lib/threefold/tfgrid3deployer/deployment.v index 68954708..57d2b0cc 100644 --- a/lib/threefold/tfgrid3deployer/deployment.v +++ b/lib/threefold/tfgrid3deployer/deployment.v @@ -1,6 +1,7 @@ module tfgrid3deployer import freeflowuniverse.herolib.threefold.grid.models as grid_models +import freeflowuniverse.herolib.threefold.gridproxy.model as gridproxy_models import freeflowuniverse.herolib.threefold.grid import freeflowuniverse.herolib.ui.console import compress.zlib @@ -98,14 +99,16 @@ fn (mut self TFDeployment) set_nodes() ! { } nodes := filter_nodes( - node_ids: node_ids - healthy: true - free_mru: convert_to_gigabytes(u64(vm.requirements.memory)) - total_cru: u64(vm.requirements.cpu) - free_ips: if vm.requirements.public_ip4 { u64(1) } else { none } - has_ipv6: if vm.requirements.public_ip6 { vm.requirements.public_ip6 } else { none } - status: 'up' - features: if vm.requirements.public_ip4 { [] } else { ['zmachine'] } + node_ids: node_ids + healthy: true + free_mru: convert_to_gigabytes(u64(vm.requirements.memory)) + total_cru: u64(vm.requirements.cpu) + free_sru: convert_to_gigabytes(u64(vm.requirements.size)) + available_for: gridproxy_models.OptionU64(u64(self.deployer.twin_id)) + free_ips: if vm.requirements.public_ip4 { u64(1) } else { none } + has_ipv6: if vm.requirements.public_ip6 { vm.requirements.public_ip6 } else { none } + status: 'up' + features: if vm.requirements.public_ip4 { [] } else { ['zmachine'] } )! if nodes.len == 0 { @@ -114,40 +117,42 @@ fn (mut self TFDeployment) set_nodes() ! { } return error('Requested the Grid Proxy and no nodes found.') } - idx := rand.u32() % u32(nodes.len) - // println('chodes node: ${}') - vm.node_id = u32(nodes[idx].node_id) + + vm.node_id = self.pick_node(nodes) or { return error('Failed to pick valid node: ${err}') } } for mut zdb in self.zdbs { - size := convert_to_gigabytes(u64(zdb.requirements.size)) nodes := filter_nodes( - free_sru: size - status: 'up' - healthy: true - node_id: zdb.requirements.node_id + free_sru: convert_to_gigabytes(u64(zdb.requirements.size)) + status: 'up' + healthy: true + node_id: zdb.requirements.node_id + available_for: gridproxy_models.OptionU64(u64(self.deployer.twin_id)) )! if nodes.len == 0 { return error('Requested the Grid Proxy and no nodes found.') } - zdb.node_id = u32(nodes[0].node_id) + zdb.node_id = self.pick_node(nodes) or { return error('Failed to pick valid node: ${err}') } } for mut webname in self.webnames { nodes := filter_nodes( - domain: true - status: 'up' - healthy: true - node_id: webname.requirements.node_id + domain: true + status: 'up' + healthy: true + node_id: webname.requirements.node_id + available_for: gridproxy_models.OptionU64(u64(self.deployer.twin_id)) )! if nodes.len == 0 { return error('Requested the Grid Proxy and no nodes found.') } - webname.node_id = u32(nodes[0].node_id) + webname.node_id = self.pick_node(nodes) or { + return error('Failed to pick valid node: ${err}') + } } } @@ -200,7 +205,7 @@ fn (mut self TFDeployment) finalize_deployment(setup DeploymentSetup) ! { } if create_name_contracts.len > 0 || create_deployments.len > 0 { - console.print_header('Batch deploying the deployment') + console.print_header('Attempting batch deployment') created_name_contracts_map, ret_dls := self.deployer.batch_deploy(create_name_contracts, mut create_deployments, none)! @@ -469,86 +474,35 @@ pub fn (mut self TFDeployment) list_deployments() !map[u32]grid_models.Deploymen return dls } -// fn (mut self TFDeployment) vm_delete(vm_name string) ! { -// // delete myself, check on TFChain that deletion was indeed done -// vm := self.vm_get(vm_name)! +fn (mut self TFDeployment) pick_node(nodes []gridproxy_models.Node) !u32 { + mut node_id := ?u32(none) + mut checked := []bool{len: nodes.len} + mut checked_cnt := 0 + for checked_cnt < nodes.len { + idx := int(rand.u32() % u32(nodes.len)) + if checked[idx] { + continue + } -// // get all deployments -// mut dls := self.list_deployments()! + checked[idx] = true + checked_cnt += 1 + if self.ping_node(u32(nodes[idx].twin_id)) { + node_id = u32(nodes[idx].node_id) + break + } + } -// // load network -// mut network_handler := NetworkHandler{ -// deployer: self.deployer -// } + if v := node_id { + return v + } else { + return error('No node is reachable.') + } +} -// // network_handler.load_network_state(dls)! - -// // remove vm workload -// mut vm_dl := dls[vm.node_id] -// mut public_ip_name := '' -// for idx, workload in vm_dl.workloads { -// if workload.name == vm_name { -// zmachine := json.decode(grid_models.Zmachine, workload.data)! -// public_ip_name = zmachine.network.public_ip -// vm_dl.workloads[idx], vm_dl.workloads[vm_dl.workloads.len - 1] = vm_dl.workloads[vm_dl.workloads.len - 1], vm_dl.workloads[idx] -// vm_dl.workloads.delete_last() -// break -// } -// } - -// for idx, workload in vm_dl.workloads { -// if workload.name == public_ip_name { -// vm_dl.workloads[idx], vm_dl.workloads[vm_dl.workloads.len - 1] = vm_dl.workloads[vm_dl.workloads.len - 1], vm_dl.workloads[idx] -// vm_dl.workloads.delete_last() -// break -// } -// } - -// // decide if we want to remove the node -// if vm_dl.workloads.len == 1 && vm_dl.workloads[0].type_ == grid_models.workload_types.network { -// mut ipv4_nodes := 0 -// for _, endpoint in network_handler.endpoints { -// if endpoint.split('.').len == 4 { -// ipv4_nodes += 1 -// } -// } - -// if network_handler.public_node == vm.node_id && (ipv4_nodes > 1 -// || network_handler.hidden_nodes.len == 0 -// || (network_handler.nodes.len == 2 && network_handler.hidden_nodes.len == 1) -// || (ipv4_nodes == 1 && network_handler.hidden_nodes.len > 0)) { -// // we can remove the node -// dls.delete(vm.node_id) -// network_handler.remove_node(vm.node_id)! -// } -// } - -// // use network handler to prepare network -// network_workloads := network_handler.generate_workloads(self.dl_versions)! - -// // replace deloyments network workloads with the ones coming from network handler -// for node_id, mut dl in dls { -// network_wl := network_workloads[node_id] or { continue } -// for id, _ in dl.workloads { -// if dl.workloads[id].name == network_wl.name { -// dl.workloads[id] = network_wl -// } -// } -// } - -// // TODO: update deployments -// /* -// what issues we face: -// 1. Delete the network workload if not needed -// 2. Remove the vm node peer from the other deployments if contract is deleted -// 3. Deploy an access node if the deleted contract was an access node - -// node1 := dl -> hidden -// node2 := dl -> hidden -// node3 := dl -> public // will delete it, we need to deploy another access node for node1 and node2 - -// node1 := dl -> public // Assign node1 instead of node3 and delete node1 -// node2 := dl -> hidden -// node3 := dl -> public // will delete it, we need to deploy another access node for node1 and node2 -// */ -// } +fn (mut self TFDeployment) ping_node(twin_id u32) bool { + if _ := self.deployer.client.get_zos_version(twin_id) { + return true + } else { + return false + } +}