This commit is contained in:
2025-08-28 16:02:28 +02:00
parent d52aa5dbd4
commit fb87adf87d
44 changed files with 480 additions and 507 deletions

View File

@@ -134,7 +134,7 @@ Returns the current username.
## 2. Network Utilities
### `osal.ping(args: PingArgs) !PingResult`
### `osal.ping(args: PingArgs) ! bool`
Checks host reachability.
* **Parameters**:
### `osal.ipaddr_pub_get_check() !string`

View File

@@ -23,12 +23,12 @@ This document describes the core functionalities of the Operating System Abstrac
## 2. Network Utilities
* **`osal.ping(args: PingArgs) !PingResult`**: Check host reachability.
* **Key Parameters**: `address` (string).
* **Returns**: `PingResult` (`.ok`, `.timeout`, `.unknownhost`).
* **`osal.tcp_port_test(args: TcpPortTestArgs) bool`**: Test if a TCP port is open.
* **Key Parameters**: `address` (string), `port` (int).
* **`osal.ipaddr_pub_get() !string`**: Get public IP address.
* **`osal.ping(args: PingArgs) !bool`**: Check host reachability.
- address string = "8.8.8.8"
- nr_ping u16 = 3 // amount of ping requests we will do
- nr_ok u16 = 3 //how many of them need to be ok
- retry u8 //how many times fo we retry above sequence, basically we ping ourselves with -c 1
**`osal.ipaddr_pub_get() !string`**: Get public IP address.
## 3. File System Operations

View File

@@ -761,9 +761,7 @@ this document has info about the most core functions, more detailed info can be
### 2. Network Utilities
* **`osal.ping(args: PingArgs) !PingResult`**: Check host reachability.
* **Key Parameters**: `address` (string).
* **Returns**: `PingResult` (`.ok`, `.timeout`, `.unknownhost`).
* **`osal.ping(args: PingArgs) !bool`**: Check host reachability.
* **`osal.tcp_port_test(args: TcpPortTestArgs) bool`**: Test if a TCP port is open.
* **Key Parameters**: `address` (string), `port` (int).
* **`osal.ipaddr_pub_get() !string`**: Get public IP address.

View File

@@ -33,7 +33,7 @@ fn main() {
// Test 2: Status check
console.print_header('Test 2: Status Check')
result2 := os.execute('${hero_bin} sshagent status')
if result2.exit_code == 0 && result2.output.contains("- SSH Agent Status") {
if result2.exit_code == 0 && result2.output.contains('- SSH Agent Status') {
console.print_green(' Status check successful')
println(result2.output)
} else {

View File

@@ -11,5 +11,4 @@ playcmds.run(
heroscript_path: heroscript_path
)!
println('Simulation complete!')

2
examples/tmux/tmux_setup.heroscript Normal file → Executable file
View File

@@ -1,3 +1,5 @@
#!/usr/bin/env hero
// Create development session
!!tmux.session_create
name:'dev'

View File

@@ -6,15 +6,13 @@ import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.builder
import time
import os
import freeflowuniverse.herolib.core.playcmds
user:=os.environ()['HETZNER_USER'] or {
user := os.environ()['HETZNER_USER'] or {
println('HETZNER_USER not set')
exit(1)
}
passwd:=os.environ()['HETZNER_PASSWORD'] or {
passwd := os.environ()['HETZNER_PASSWORD'] or {
println('HETZNER_PASSWORD not set')
exit(1)
}
@@ -31,7 +29,7 @@ playcmds.run(
console.print_header('Hetzner Test.')
mut cl := hetznermanager.get(name:'main')!
mut cl := hetznermanager.get(name: 'main')!
// for i in 0 .. 5 {
// println('test cache, first time slow then fast')
@@ -45,7 +43,7 @@ mut cl := hetznermanager.get(name:'main')!
// cl.server_reset(name:"kristof2",wait:true)!
//don't forget to specify the keyname needed
// don't forget to specify the keyname needed
// cl.server_rescue(name:"kristof2",wait:true, hero_install:true,sshkey_name:"kristof")!
// mut ks:=cl.keys_get()!
@@ -55,11 +53,10 @@ mut cl := hetznermanager.get(name:'main')!
// mut b := builder.new()!
// mut n := b.node_new(ipaddr: serverinfo.server_ip)!
//this will put hero in debug mode on the system
// this will put hero in debug mode on the system
// n.hero_install(compile:true)!
// n.shell("")!
cl.ubuntu_install(name:"kristof2",wait:true, hero_install:true,sshkey_name:"kristof")!
cl.ubuntu_install(name:"kristof20",wait:true, hero_install:true,sshkey_name:"kristof")!
cl.ubuntu_install(name: 'kristof2', wait: true, hero_install: true, sshkey_name: 'kristof')!
cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true, sshkey_name: 'kristof')!

View File

@@ -6,8 +6,8 @@ import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.installers.virt.lima as limainstaller
import os
mut i:=limainstaller.get(create:true)!
i.install(reset:true)!
mut i := limainstaller.get(create: true)!
i.install(reset: true)!
// mut virtmanager := lima.new()!

View File

@@ -47,7 +47,7 @@ pub mut:
reset bool
compile bool
v_analyzer bool
debug bool //will go in shell
debug bool // will go in shell
}
pub fn (mut node Node) hero_install(args HeroInstallArgs) ! {
@@ -58,15 +58,15 @@ pub fn (mut node Node) hero_install(args HeroInstallArgs) ! {
homedir := myenv['HOME'] or { return error("can't find HOME in env") }
mut todo := []string{}
if ! args.compile {
todo << "curl https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_hero.sh > /tmp/install.sh"
todo << "bash /tmp/install.sh"
}else{
if !args.compile {
todo << 'curl https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_hero.sh > /tmp/install.sh'
todo << 'bash /tmp/install.sh'
} else {
todo << "curl 'https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_v.sh' > /tmp/install_v.sh"
if args.v_analyzer {
todo << "bash /tmp/install_v.sh --analyzer --herolib "
}else{
todo << "bash /tmp/install_v.sh --herolib "
todo << 'bash /tmp/install_v.sh --analyzer --herolib '
} else {
todo << 'bash /tmp/install_v.sh --herolib '
}
}
node.exec_interactive(todo.join('\n'))!

View File

@@ -54,11 +54,11 @@ pub fn (mut executor ExecutorSSH) exec(args_ ExecArgs) !string {
port = '-p ${executor.ipaddr.port}'
}
if args.cmd.contains("\n"){
//need to upload the file first
if args.cmd.contains('\n') {
// need to upload the file first
args.cmd = texttools.dedent(args.cmd)
executor.file_write('/tmp/toexec.sh', args.cmd)!
args.cmd = "bash /tmp/toexec.sh"
args.cmd = 'bash /tmp/toexec.sh'
}
args.cmd = 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${executor.user}@${executor.ipaddr.addr} ${port} "${args.cmd}"'
@@ -74,11 +74,11 @@ pub fn (mut executor ExecutorSSH) exec_interactive(args_ ExecArgs) ! {
port = '-p ${executor.ipaddr.port}'
}
if args.cmd.contains("\n"){
if args.cmd.contains('\n') {
args.cmd = texttools.dedent(args.cmd)
//need to upload the file first
// need to upload the file first
executor.file_write('/tmp/toexec.sh', args.cmd)!
args.cmd = "bash /tmp/toexec.sh"
args.cmd = 'bash /tmp/toexec.sh'
}
args.cmd = 'ssh -tt -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${executor.user}@${executor.ipaddr.addr} ${port} "${args.cmd}"'

View File

@@ -24,10 +24,8 @@ pub fn check() bool {
// }
// TODO: might be dangerous if that one goes out
ping_result := osal.ping(address: '40a:152c:b85b:9646:5b71:d03a:eb27:2462', retry: 2) or {
return false
}
if ping_result == .ok {
ping_result := osal.ping(address: '40a:152c:b85b:9646:5b71:d03a:eb27:2462') or { panic(err) }
if ping_result {
console.print_debug('could reach 40a:152c:b85b:9646:5b71:d03a:eb27:2462')
return true
}

View File

@@ -55,7 +55,7 @@ pub fn (mut h HTTPConnection) send(req_ Request) !Result {
mut is_cacheable := h.is_cacheable(req)
if req.debug {
//in debug mode should not cache
// in debug mode should not cache
is_cacheable = false
}
@@ -101,7 +101,7 @@ pub fn (mut h HTTPConnection) send(req_ Request) !Result {
}
for counter in 0 .. h.retry {
if req.debug {
console.print_debug("request attempt:${counter}")
console.print_debug('request attempt:${counter}')
}
response = new_req.do() or {
err_message = 'Cannot send request:${req}\nerror:${err}'
@@ -111,7 +111,7 @@ pub fn (mut h HTTPConnection) send(req_ Request) !Result {
break
}
if req.debug {
console.print_debug("request done")
console.print_debug('request done')
console.print_debug(response.str())
}
if response.status_code == 0 {
@@ -216,6 +216,6 @@ pub fn (mut h HTTPConnection) post_multi_part(req Request, form http.PostMultipa
header.set(http.CommonHeader.content_type, 'multipart/form-data')
req_form.header = header
url := h.url(req)
//TODO: should that not be on line with above? seems to be other codepath.
// TODO: should that not be on line with above? seems to be other codepath.
return http.post_multipart_form(url, req_form)!
}

View File

@@ -24,8 +24,7 @@ pub mut:
// is_running checks if the node is operational by pinging its address
fn (node &StreamerNode) is_running() bool {
ping_result := osal.ping(address: node.address, retry: 2) or { return false }
return ping_result == .ok
return osal.ping(address: node.address, retry: 2)!
}
// connect_to_master connects the worker node to its master

View File

@@ -99,7 +99,7 @@ pub fn (mut gs GitStructure) do(args_ ReposActionsArgs) !string {
provider: args.provider
)!
if repos.len<4 || args.cmd in 'pull,push,commit,delete'.split(',') {
if repos.len < 4 || args.cmd in 'pull,push,commit,delete'.split(',') {
args.reload = true
}

View File

@@ -66,7 +66,7 @@ fn installed() !bool {
if !osal.cmd_exists('limactl') {
return false
}
mut res:=os.execute("lima -v");
mut res := os.execute('lima -v')
r := res.output.split_into_lines().filter(it.contains('limactl version'))
if r.len != 1 {
return error("couldn't parse lima version, expected 'lima version' on 1 row.\n${res.output}")
@@ -112,42 +112,38 @@ fn install() ! {
}
console.print_header('download ${url}')
mut e:=osal.download(
mut e := osal.download(
url: url
minsize_kb: 20000
dest: '/tmp/lima.tar.gz'
expand_file: '/tmp/download/lima'
)!
e.copy(dest:dest_on_os)!
e.copy(dest: dest_on_os)!
mut installer := get()!
if installer.extra {
mut e2:=osal.download(
mut e2 := osal.download(
url: url2
minsize_kb: 20000
dest: '/tmp/lima-additional-guestagents.tar.gz'
expand_file: '/tmp/download/lima-additional-guestagents'
)!
e2.copy(dest:dest_on_os)!
e2.copy(dest: dest_on_os)!
}
}
fn destroy() ! {
osal.process_kill_recursive(name:'lima')!
osal.process_kill_recursive(name: 'lima')!
osal.package_remove('
lima
limactl
')!
osal.rm("
osal.rm('
lima
limactl
${os.home_dir()}/bin/*.lima
@@ -156,5 +152,5 @@ fn destroy() ! {
${os.home_dir()}/share/lima
${os.home_dir()}/share/man/lima*
")!
')!
}

View File

@@ -14,8 +14,8 @@ pub struct LimaInstaller {
pub mut:
name string = 'default'
homedir string
extra bool //do we want to extra's
sshkey string //name of the key to use
extra bool // do we want to extra's
sshkey string // name of the key to use
}
// your checking & initialization code if needed

View File

@@ -4,73 +4,47 @@ import net
import time
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core
import math
import os
pub enum PingResult {
ok
timeout // timeout from ping
unknownhost // means we don't know the hostname its a dns issue
}
@[params]
pub struct PingArgs {
pub mut:
address string @[required]
count u8 = 2 // the ping is successful if it got count amount of replies from the other side
timeout u16 = 1 // the time in which the other side should respond in seconds
retry u8
address string = '8.8.8.8'
nr_ping u16 = 2 // amount of ping requests we will do
nr_ok u16 = 2 // how many of them need to be ok
retry u8 // how many times fo we retry above sequence, basically we ping ourselves with -c 1
}
// if reached in timout result will be True
// address is e.g. 8.8.8.8
// ping means we check if the destination responds
pub fn ping(args PingArgs) !PingResult {
platform_ := core.platform()!
// if ping ok, return true
pub fn ping(args PingArgs) !bool {
// platform_ := core.platform()!
mut cmd := 'ping'
if args.address.contains(':') {
cmd = 'ping6'
}
if platform_ == .osx {
cmd += ' -c ${args.count} -i ${args.timeout} ${args.address}'
} else if platform_ == .ubuntu {
cmd += ' -c ${args.count} -w ${args.timeout} ${args.address}'
} else {
return error('Unsupported platform for ping')
cmd += ' -c 1 ${args.address}'
if args.nr_ok > args.nr_ping {
return error('nr_ok must be <= nr_ping')
}
for _ in 0 .. math.max(1, args.retry) {
mut nrerrors := 0
for _ in 0 .. args.nr_ping {
console.print_debug(cmd)
_ := exec(cmd: cmd, retry: args.retry, timeout: 0, stdout: false) or {
// println("ping failed.error.\n${err}")
if err.code() == 9999 {
return .timeout
res := os.execute(cmd)
if res.exit_code > 0 {
nrerrors += 1
}
if platform_ == .osx {
return match err.code() {
2 {
.timeout
println(res)
}
68 {
.unknownhost
}
else {
// println("${err} ${err.code()}")
return error("can't ping on osx (${err.code()})\n${err}")
successes := args.nr_ping - nrerrors
if successes >= args.nr_ok {
return true
}
}
} else if platform_ == .ubuntu {
return match err.code() {
1 { .timeout }
2 { .unknownhost }
else { error("can't ping on ubuntu (${err.code()})\n${err}") }
}
} else {
panic('bug, should never get here')
}
}
return .ok
return false
}
@[params]
pub struct RebootWaitArgs {
pub mut:
@@ -89,26 +63,26 @@ pub fn reboot_wait(args RebootWaitArgs) ! {
start_time := time.now().unix()
mut run_time := 0.0
for true {
console.print_debug("Waiting for server to go down...")
console.print_debug('Waiting for server to go down...')
run_time = time.now().unix()
if run_time > start_time + args.timeout_down {
return error("timeout in waiting for server down")
return error('timeout in waiting for server down')
}
if ping(address:args.address)! == .timeout {
if ping(address: args.address)! == false {
break
}
println(ping(address:args.address)!)
println(ping(address: args.address)!)
$dbg;
time.sleep(1)
}
for true {
console.print_debug("Waiting for server to come back up...")
console.print_debug('Waiting for server to come back up...')
run_time = time.now().unix()
if run_time > start_time + args.timeout_up {
return error("timeout in waiting for server up")
return error('timeout in waiting for server up')
}
if ping(address:args.address)! == .ok {
println(ping(address:args.address)!)
if ping(address: args.address)! == true {
println(ping(address: args.address)!)
$dbg;
break
}
@@ -116,7 +90,6 @@ pub fn reboot_wait(args RebootWaitArgs) ! {
}
}
@[params]
pub struct TcpPortTestArgs {
pub mut:
@@ -190,11 +163,10 @@ pub fn is_ip_on_local_interface(public_ip string) !bool {
return false
}
//will give error if ssh test did not work
// will give error if ssh test did not work
pub fn ssh_check(args TcpPortTestArgs) ! {
errmsg, res := ssh_testrun_internal(args)!
if res != .ok{
if res != .ok {
return error(errmsg)
}
}
@@ -206,15 +178,13 @@ pub enum SSHResult {
ssh
}
pub fn ssh_test(args TcpPortTestArgs) !SSHResult {
_, res := ssh_testrun_internal(args)!
return res
}
//will give error if ssh test did not work
// will give error if ssh test did not work
pub fn ssh_wait(args TcpPortTestArgs) ! {
start_time := time.now().unix_milli()
mut run_time := 0.0
for true {
@@ -227,16 +197,14 @@ pub fn ssh_wait(args TcpPortTestArgs) ! {
return error(errmsg)
}
if res == .ok{
if res == .ok {
return
}
}
}
fn ssh_testrun_internal(args TcpPortTestArgs) !(string,SSHResult) {
cmd:='
fn ssh_testrun_internal(args TcpPortTestArgs) !(string, SSHResult) {
cmd := '
ssh -o BatchMode=yes -o ConnectTimeout=3 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q "${args.address}" exit
if [ $? -eq 0 ]; then
echo "OK: SSH works"
@@ -254,9 +222,9 @@ fn ssh_testrun_internal(args TcpPortTestArgs) !(string,SSHResult) {
fi
echo "ERROR: Host unreachable, over ping and ssh"
exit 3
'
// console.print_debug('ssh test cmd: ${cmd}')
res:=exec(cmd:cmd,ignore_error:true,stdout:false,debug:false)!
' // console.print_debug('ssh test cmd: ${cmd}')
res := exec(cmd: cmd, ignore_error: true, stdout: false, debug: false)!
// console.print_debug('ssh test result: ${res}')
if res.exit_code == 0 {
return res.output, SSHResult.ok

View File

@@ -1,6 +1,5 @@
module incatokens
// AMMPool represents a simple Automated Market Maker pool.
// It uses the constant product formula (x * y = k) to determine prices.
pub struct AMMPool {

View File

@@ -62,7 +62,7 @@ fn test_trade_in_empty_pool() {
pool.trade(100.0) or {
expected_error := 'AMM pool is empty and cannot facilitate trades'
assert err.msg() == expected_error
return // Exit the test function successfully after catching the error.
return
}
// This line should not be reached if the error is caught correctly.
assert false, 'Expected trade to fail, but it succeeded'

View File

@@ -11,7 +11,6 @@ pub mut:
token_supply f64 // The total number of tokens available for sale.
}
// AuctionResult holds the outcome of a simulated Dutch auction.
pub struct AuctionResult {
pub mut:
@@ -21,7 +20,6 @@ pub mut:
fully_subscribed bool // True if all tokens were sold.
}
// simulate_auction performs a simplified Dutch auction simulation.
// It determines the market-clearing price based on total demand and token supply.
pub fn simulate_auction(config AuctionConfig) !AuctionResult {
@@ -64,4 +62,3 @@ pub fn simulate_auction(config AuctionConfig) !AuctionResult {
fully_subscribed: true
}
}

View File

@@ -34,7 +34,9 @@ pub fn (sim Simulation) export_csv(sheet_name string, path string) ! {
// Generate a single scenario section for use in templates
pub fn (sim Simulation) generate_scenario_section(scenario_name string) !string {
scenario := sim.scenarios[scenario_name] or { return error('Scenario not found: ${scenario_name}') }
scenario := sim.scenarios[scenario_name] or {
return error('Scenario not found: ${scenario_name}')
}
mut lines := []string{}
lines << '### ${scenario.name} Scenario'
@@ -59,7 +61,8 @@ pub fn (sim Simulation) generate_scenario_section(scenario_name string) !string
lines << '| ${separator.join('|')} |'
// Create data row
mut row := ['\$${(scenario.final_metrics.treasury_total / 1_000_000):.1f}M', '\$${scenario.final_metrics.final_price:.4f}']
mut row := ['\$${(scenario.final_metrics.treasury_total / 1_000_000):.1f}M',
'\$${scenario.final_metrics.final_price:.4f}']
for round in sim.investor_rounds {
roi := scenario.final_metrics.investor_roi[round.name] or { 0.0 }
row << '${roi:.2f}x'
@@ -79,7 +82,6 @@ fn (sim Simulation) calculate_total_raised() f64 {
return total
}
pub fn (sim Simulation) generate_report(output_dir string) ! {
// Ensure output directory exists
mut output_path := pathlib.get_dir(path: output_dir, create: true)!

View File

@@ -45,7 +45,5 @@ pub fn simulation_new(params SimulationParams) !&Simulation {
pub fn simulation_get(name string) !&Simulation {
name_fixed := texttools.name_fix(name)
return simulations[name_fixed] or {
return error('Simulation "${name_fixed}" not found')
}
return simulations[name_fixed] or { return error('Simulation "${name_fixed}" not found') }
}

View File

@@ -1,4 +1,5 @@
module incatokens
import freeflowuniverse.herolib.biz.spreadsheet
import os
import incatokens.defaults

View File

@@ -1,6 +1,6 @@
module incatokens
import os
import os
// SimulationParams is the main configuration struct containing all parameters
pub struct SimulationParams {
@@ -79,4 +79,3 @@ pub mut:
generate_charts bool = true
generate_report bool = true
}

View File

@@ -6,7 +6,6 @@ import freeflowuniverse.herolib.core.pathlib
import os
pub fn play(mut plbook PlayBook) ! {
if !plbook.exists(filter: 'incatokens.') {
return
}
@@ -45,15 +44,21 @@ pub fn play(mut plbook PlayBook) ! {
params.simulation.currency = p.get_default('currency', 'USD')!
// Configure economics
params.economics.epoch1_floor_uplift = p.get_float_default('epoch1_floor_uplift', 1.20)!
params.economics.epochn_floor_uplift = p.get_float_default('epochn_floor_uplift', 1.20)!
params.economics.amm_liquidity_depth_factor = p.get_float_default('amm_liquidity_depth_factor', 2.0)!
params.economics.epoch1_floor_uplift = p.get_float_default('epoch1_floor_uplift',
1.20)!
params.economics.epochn_floor_uplift = p.get_float_default('epochn_floor_uplift',
1.20)!
params.economics.amm_liquidity_depth_factor = p.get_float_default('amm_liquidity_depth_factor',
2.0)!
// Configure vesting
params.vesting.team.cliff_months = p.get_int_default('team_cliff_months', 12)!
params.vesting.team.vesting_months = p.get_int_default('team_vesting_months', 36)!
params.vesting.treasury.cliff_months = p.get_int_default('treasury_cliff_months', 12)!
params.vesting.treasury.vesting_months = p.get_int_default('treasury_vesting_months', 48)!
params.vesting.team.vesting_months = p.get_int_default('team_vesting_months',
36)!
params.vesting.treasury.cliff_months = p.get_int_default('treasury_cliff_months',
12)!
params.vesting.treasury.vesting_months = p.get_int_default('treasury_vesting_months',
48)!
// Configure output - use export_path if provided, otherwise use param
if export_path != '' {

View File

@@ -68,9 +68,30 @@ pub fn (mut sim Simulation) run_scenario(name string, demands []f64, amm_trades
// Initialize epochs
scenario.epochs = [
Epoch{index: 0, type_: .auction_only, start_month: 0, end_month: 3, auction_share: 1.0, amm_share: 0.0},
Epoch{index: 1, type_: .hybrid, start_month: 3, end_month: 6, auction_share: 0.5, amm_share: 0.5},
Epoch{index: 2, type_: .amm_only, start_month: 6, end_month: 12, auction_share: 0.0, amm_share: 1.0}
Epoch{
index: 0
type_: .auction_only
start_month: 0
end_month: 3
auction_share: 1.0
amm_share: 0.0
},
Epoch{
index: 1
type_: .hybrid
start_month: 3
end_month: 6
auction_share: 0.5
amm_share: 0.5
},
Epoch{
index: 2
type_: .amm_only
start_month: 6
end_month: 12
auction_share: 0.0
amm_share: 1.0
},
]
// Track in spreadsheet

View File

@@ -61,4 +61,3 @@ pub mut:
epochs []Epoch
final_metrics ScenarioMetrics
}

View File

@@ -72,7 +72,8 @@ fn (sim Simulation) apply_vesting_schedule(mut row spreadsheet.Row, total_tokens
} else if month < schedule.cliff_months + schedule.vesting_months {
// During vesting period (after cliff)
months_after_cliff := month - schedule.cliff_months + 1
row.cells[month].val = initial_unlocked_tokens + (monthly_vesting_amount * f64(months_after_cliff))
row.cells[month].val = initial_unlocked_tokens +
(monthly_vesting_amount * f64(months_after_cliff))
} else {
// After vesting complete
row.cells[month].val = total_tokens

View File

@@ -34,9 +34,9 @@ pub mut:
}
pub fn (mut h HetznerManager) server_rescue(args_ ServerRescueArgs) !ServerInfoDetailed {
if args_.retry > 1{
for _ in 0 .. args_.retry-1 {
return h.server_rescue_internal(args_) or {continue}
if args_.retry > 1 {
for _ in 0 .. args_.retry - 1 {
return h.server_rescue_internal(args_) or { continue }
}
}
return h.server_rescue_internal(args_)!
@@ -46,16 +46,16 @@ fn (mut h HetznerManager) server_rescue_internal(args_ ServerRescueArgs) !Server
mut args := args_
mut serverinfo := h.server_info_get(id: args.id, name: args.name)!
if serverinfo.rescue && ! args.reset {
if serverinfo.rescue && !args.reset {
if osal.ssh_test(address: serverinfo.server_ip, port: 22)! == .ok {
console.print_debug('test server ${serverinfo.server_name} is in rescue mode?')
mut b := builder.new()!
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
res:=n.exec(cmd:"ls /root/.oldroot/nfs/install/installimage",stdout:false) or {
"ERROR"
res := n.exec(cmd: 'ls /root/.oldroot/nfs/install/installimage', stdout: false) or {
'ERROR'
}
if res.contains("nfs/install/installimage"){
if res.contains('nfs/install/installimage') {
console.print_debug('server ${serverinfo.server_name} is in rescue mode')
return serverinfo
}
@@ -64,13 +64,12 @@ fn (mut h HetznerManager) server_rescue_internal(args_ ServerRescueArgs) !Server
}
// only do it if its not in rescue yet
if serverinfo.rescue == false || args.reset {
console.print_header('server ${serverinfo.server_name} goes into rescue mode')
mut keyfps := []string{}
if args.sshkey_name != '' {
keyfps << h.key_get(args.sshkey_name)!.fingerprint
}else{
} else {
keyfps = h.keys_get()!.map(it.fingerprint)
}
@@ -87,19 +86,24 @@ fn (mut h HetznerManager) server_rescue_internal(args_ ServerRescueArgs) !Server
// console.print_debug('hetzner rescue\n${rescue}')
h.server_reset(id: args.id, name: args.name, wait: args.wait, msg:" to get up and running in rescue mode.")!
h.server_reset(
id: args.id
name: args.name
wait: args.wait
msg: ' to get up and running in rescue mode.'
)!
os.execute_opt("ssh-keygen -R ${serverinfo.server_ip}")!
os.execute_opt('ssh-keygen -R ${serverinfo.server_ip}')!
}
if args.hero_install{
if args.hero_install {
args.wait = true
}
if args.wait {
mut b := builder.new()!
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
n.exec_silent("apt update && apt install -y mc redis")!
n.exec_silent('apt update && apt install -y mc redis')!
if args.hero_install {
n.hero_install()!
}
@@ -119,7 +123,6 @@ pub fn (mut h HetznerManager) server_rescue_node(args ServerRescueArgs) !&builde
return n
}
pub struct ServerInstallArgs {
pub mut:
id int
@@ -132,8 +135,12 @@ pub mut:
}
pub fn (mut h HetznerManager) ubuntu_install(args ServerInstallArgs) !&builder.Node {
mut serverinfo := h.server_rescue(id:args.id,name:args.name,wait:true,sshkey_name:args.sshkey_name)!
mut serverinfo := h.server_rescue(
id: args.id
name: args.name
wait: true
sshkey_name: args.sshkey_name
)!
mut b := builder.new()!
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
@@ -142,18 +149,20 @@ pub fn (mut h HetznerManager) ubuntu_install(args ServerInstallArgs) !&builder.N
// n.file_write("/tmp/installconfig",installconfig)!
// n.exec_interactive("installimage -a -c /tmp/installconfig")!
mut rstr:=""
mut rstr := ''
if args.raid {
rstr="-r yes -l 1 "
rstr = '-r yes -l 1 '
}
n.exec(cmd:'
n.exec(
cmd: '
set -ex
echo "go into install mode, try to install ubuntu 24.04"
/root/.oldroot/nfs/install/installimage -a -n kristof2 ${rstr} -i /root/.oldroot/nfs/images/Ubuntu-2404-noble-amd64-base.tar.gz -f yes -t yes -p swap:swap:4G,/boot:ext3:1024M,/:btrfs:all
reboot')!
reboot'
)!
os.execute_opt("ssh-keygen -R ${serverinfo.server_ip}")!
os.execute_opt('ssh-keygen -R ${serverinfo.server_ip}')!
console.print_debug('server ${serverinfo.server_name} is installed in ubuntu now, should be restarting.')
@@ -163,12 +172,10 @@ pub fn (mut h HetznerManager) ubuntu_install(args ServerInstallArgs) !&builder.N
timeout_up: 60 * 5
)!
$dbg;
if args.hero_install {
n.hero_install(compile: args.hero_install_compile)!
}
return n
}

View File

@@ -30,7 +30,7 @@ pub fn (mut h HetznerManager) server_reset(args ServerRebootArgs) !ResetInfo {
console.print_header('server ${serverinfo.server_name} goes for reset')
mut serveractive := false
if osal.ping(address: serverinfo.server_ip)! == .ok {
if osal.ping(address: serverinfo.server_ip)! {
serveractive = true
console.print_debug('server ${serverinfo.server_name} is active')
} else {
@@ -52,7 +52,7 @@ pub fn (mut h HetznerManager) server_reset(args ServerRebootArgs) !ResetInfo {
for {
console.print_debug('wait for server ${serverinfo.server_name} to go down.')
pingresult := osal.ping(address: serverinfo.server_ip)!
if pingresult != .ok {
if !pingresult {
console.print_debug('server ${serverinfo.server_name} is now down, now waitig for reboot.')
break
}

View File

@@ -18,7 +18,6 @@ pub mut:
prefix string
}
@[params]
pub struct NewArgs {
pub mut:
@@ -27,12 +26,10 @@ pub mut:
herocompile bool
}
if args.install {
if args.install {
mut podman_installer0 := podman_installer.get()!
podman_installer0.install()!
}
}
fn (mut e PodmanFactory) init() ! {
if e.buildpath == '' {

View File

@@ -7,7 +7,6 @@ import freeflowuniverse.herolib.core.pathlib
import os
import json
pub fn (mut self BuildAHContainer) install_zinit() ! {
// https://github.com/threefoldtech/zinit
self.hero_copy()!
@@ -16,12 +15,11 @@ pub fn (mut self BuildAHContainer) install_zinit() ! {
self.set_entrypoint('/sbin/zinit init --container')!
}
pub fn (mut self BuildAHContainer) install_herodb() ! {
self.install_zinit()!
// the hero database gets installed and put in zinit for automatic start
self.hero_play_execute('!!installer.herodb')
//TODO: the hero_play needs to be implemented
// TODO: the hero_play needs to be implemented
}
// copies the hero from host into guest
@@ -29,5 +27,5 @@ pub fn (mut self BuildAHContainer) install_mycelium() ! {
self.install_zinit()!
// the mycelium database gets installed and put in zinit for automatic start
self.hero_play_execute('!!installer.mycelium')
//TODO: the hero_play needs to be implemented
// TODO: the hero_play needs to be implemented
}

View File

@@ -36,10 +36,9 @@ pub enum RunTime {
v
}
//should use builders underneith
// should use builders underneith
pub fn (mut self BuildAHContainer) exec(cmd Command) !osal.Job {
//make sure we have hero in the hostnode of self
// make sure we have hero in the hostnode of self
self.hero_copy()!
mut rt := RunTime.bash
@@ -61,7 +60,7 @@ pub fn (mut self BuildAHContainer) exec(cmd Command) !osal.Job {
if cmd.runtime == .heroscript || cmd.runtime == .herocmd {
self.hero_copy()!
}
mut j:=osal.exec(
mut j := osal.exec(
name: cmd.name
cmd: cmd_str
description: cmd.description

View File

@@ -11,23 +11,19 @@ pub fn (mut self BuildAHContainer) hero_cmd_execute(cmd string) ! {
// send a hero play command to the buildah container
pub fn (mut self BuildAHContainer) hero_play_execute(cmd string) ! {
self.hero_copy()!
panic("implement")
panic('implement')
}
pub fn (mut self BuildAHContainer) hero_execute_script(cmd string) ! {
self.hero_copy()!
self.exec(cmd: cmd, runtime: .heroscript)!
}
// copies the hero from host into guest
pub fn (mut self BuildAHContainer) hero_copy() ! {
// TODO: check we are on linux, check also the platformtype arm or intel, if not right platform then build hero in container
//TODO: check we are on linux, check also the platformtype arm or intel, if not right platform then build hero in container
panic("implement")
panic('implement')
// if !osal.cmd_exists('hero') {
// herolib.hero_compile()!
@@ -36,9 +32,7 @@ pub fn (mut self BuildAHContainer) hero_copy() ! {
self.copy(heropath, '/usr/local/bin/hero')!
}
// get a container where we build hero and export hero from the container so we can use it for hero_copy
pub fn (mut self BuildAHContainer) hero_build() ! {
panic("implement")
panic('implement')
}

View File

@@ -63,8 +63,7 @@ pub fn builder_base(args GetArgs) !BuildAHContainer {
return builder
}
//TODO: all below are not good, need to use play cmd over hero remotely. see how we did it with core_installers
// TODO: all below are not good, need to use play cmd over hero remotely. see how we did it with core_installers
// // builder machine based on arch and install vlang
// pub fn (mut e CEngine) builder_go_rust(args GetArgs) !BuildAHContainer {