...
This commit is contained in:
@@ -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`
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -11,5 +11,4 @@ playcmds.run(
|
||||
heroscript_path: heroscript_path
|
||||
)!
|
||||
|
||||
|
||||
println('Simulation complete!')
|
||||
|
||||
2
examples/tmux/tmux_setup.heroscript
Normal file → Executable file
2
examples/tmux/tmux_setup.heroscript
Normal file → Executable file
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env hero
|
||||
|
||||
// Create development session
|
||||
!!tmux.session_create
|
||||
name:'dev'
|
||||
|
||||
@@ -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')!
|
||||
|
||||
@@ -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()!
|
||||
|
||||
|
||||
@@ -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'))!
|
||||
|
||||
@@ -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}"'
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)!
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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*
|
||||
|
||||
")!
|
||||
')!
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)!
|
||||
|
||||
@@ -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') }
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
module incatokens
|
||||
|
||||
import freeflowuniverse.herolib.biz.spreadsheet
|
||||
import os
|
||||
import incatokens.defaults
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 != '' {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -61,4 +61,3 @@ pub mut:
|
||||
epochs []Epoch
|
||||
final_metrics ScenarioMetrics
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 == '' {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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')
|
||||
}
|
||||
@@ -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 {
|
||||
Reference in New Issue
Block a user