Compare commits

...

5 Commits

Author SHA1 Message Date
Maxime Van Hees
55ebaa4d68 first impl of client lib for herodb 2025-11-26 15:20:46 +01:00
Omdanii
aa434fddee Merge pull request #214 from Incubaid/development_fix_codeparser_tests
refactor: Improve const and param parsing logic
2025-11-26 12:28:52 +02:00
Mahmoud-Emad
deca6387f2 refactor: Improve const and param parsing logic
- Strip 'const ' prefix from const name
- Handle empty string for void param return type
- Handle empty split for void param return type
- Rename test functions to check functions
- Add `!` to functions that can return errors
2025-11-26 10:49:27 +02:00
a6d746319c /// 2025-11-25 20:10:31 +01:00
0e20b9696a ... 2025-11-25 19:19:35 +01:00
18 changed files with 723 additions and 66 deletions

View File

@@ -0,0 +1,34 @@
#!/usr/bin/env -S v -n -w -enable-globals run
import incubaid.herolib.clients.herodb
// Initialize the client
mut client := herodb.new(herodb.Config{
url: 'http://localhost:3000'
})!
println('Connecting to HeroDB at ${client.server_url}...')
// List instances
instances := client.list_instances()!
println('Found ${instances.len} instances:')
for instance in instances {
println('----------------------------------------')
println('Index: ${instance.index}')
println('Name: ${instance.name}')
println('Created At: ${instance.created_at}')
// Parse backend info
backend := instance.get_backend_info() or {
println('Backend: Unknown/Error (${err})')
continue
}
println('Backend Type: ${backend.type_name}')
if backend.path != '' {
println('Backend Path: ${backend.path}')
}
}
println('----------------------------------------')

View File

@@ -1 +1,4 @@
hetzner_example
hetzner_kristof1
hetzner_kristof2
hetzner_kristof3
hetzner_test1

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env hero
#!/usr/bin/env hero
// !!hetznermanager.configure
@@ -33,5 +33,3 @@
server_name: 'kristof2'
wait: true
hero_install: true // Install Herolib on the new OS

View File

@@ -8,6 +8,8 @@ import time
import os
import incubaid.herolib.core.playcmds
name := 'kristof1'
user := os.environ()['HETZNER_USER'] or {
println('HETZNER_USER not set')
exit(1)
@@ -20,7 +22,7 @@ passwd := os.environ()['HETZNER_PASSWORD'] or {
hs := '
!!hetznermanager.configure
user:"${user}"
whitelist:"2111181, 2392178, 2545053, 2542166, 2550508, 2550378,2550253"
whitelist:"2521602,2555487,2573047"
password:"${passwd}"
sshkey:"kristof"
'
@@ -40,29 +42,28 @@ mut cl := hetznermanager.get()!
println(cl.servers_list()!)
// mut serverinfo := cl.server_info_get(name: 'kristof2')!
mut serverinfo := cl.server_info_get(name: name)!
// println(serverinfo)
println(serverinfo)
// cl.server_reset(name:"kristof2",wait:true)!
// cl.server_reset(name: 'kristof2', wait: true)!
// don't forget to specify the keyname needed
// cl.server_rescue(name:"kristof2",wait:true, hero_install:true,sshkey_name:"kristof")!
// cl.server_rescue(name: name, wait: true, hero_install: true)!
// mut ks:=cl.keys_get()!
// mut ks := cl.keys_get()!
// println(ks)
// console.print_header('SSH login')
// mut b := builder.new()!
// mut n := b.node_new(ipaddr: serverinfo.server_ip)!
// 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)!
cl.ubuntu_install(name: name, wait: true, hero_install: true)!
// cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)!
cl.ubuntu_install(id: 2550253, name: 'kristof23', wait: true, hero_install: true)!
// cl.ubuntu_install(id: 2550253, name: 'kristof23', wait: true, hero_install: true)!
// this will put hero in debug mode on the system
mut b := builder.new()!
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
n.hero_install(compile: true)!
n.shell('')!

View File

@@ -0,0 +1,69 @@
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import incubaid.herolib.virt.hetznermanager
import incubaid.herolib.ui.console
import incubaid.herolib.core.base
import incubaid.herolib.builder
import time
import os
import incubaid.herolib.core.playcmds
name := 'kristof2'
user := os.environ()['HETZNER_USER'] or {
println('HETZNER_USER not set')
exit(1)
}
passwd := os.environ()['HETZNER_PASSWORD'] or {
println('HETZNER_PASSWORD not set')
exit(1)
}
hs := '
!!hetznermanager.configure
user:"${user}"
whitelist:"2521602,2555487"
password:"${passwd}"
sshkey:"kristof"
'
println(hs)
playcmds.run(heroscript: hs)!
console.print_header('Hetzner Test.')
mut cl := hetznermanager.get()!
// println(cl)
// for i in 0 .. 5 {
// println('test cache, first time slow then fast')
// }
println(cl.servers_list()!)
mut serverinfo := cl.server_info_get(name: name)!
println(serverinfo)
// cl.server_reset(name: 'kristof2', wait: true)!
cl.server_rescue(name: name, wait: true, hero_install: true)!
mut ks := cl.keys_get()!
println(ks)
console.print_header('SSH login')
mut b := builder.new()!
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
// this will put hero in debug mode on the system
// n.hero_install(compile: true)!
n.shell('')!
cl.ubuntu_install(name: name, wait: true, hero_install: true)!
// cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)!
// cl.ubuntu_install(id: 2550253, name: 'kristof23', wait: true, hero_install: true)!

View File

@@ -0,0 +1,69 @@
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import incubaid.herolib.virt.hetznermanager
import incubaid.herolib.ui.console
import incubaid.herolib.core.base
import incubaid.herolib.builder
import time
import os
import incubaid.herolib.core.playcmds
name := 'kristof3'
user := os.environ()['HETZNER_USER'] or {
println('HETZNER_USER not set')
exit(1)
}
passwd := os.environ()['HETZNER_PASSWORD'] or {
println('HETZNER_PASSWORD not set')
exit(1)
}
hs := '
!!hetznermanager.configure
user:"${user}"
whitelist:"2521602,2555487,2573047"
password:"${passwd}"
sshkey:"kristof"
'
println(hs)
playcmds.run(heroscript: hs)!
console.print_header('Hetzner Test.')
mut cl := hetznermanager.get()!
// println(cl)
// for i in 0 .. 5 {
// println('test cache, first time slow then fast')
// }
println(cl.servers_list()!)
mut serverinfo := cl.server_info_get(name: name)!
println(serverinfo)
// cl.server_reset(name: 'kristof2', wait: true)!
// cl.server_rescue(name: name, wait: true, hero_install: true)!
// mut ks := cl.keys_get()!
// println(ks)
// console.print_header('SSH login')
cl.ubuntu_install(name: name, wait: true, hero_install: true)!
// cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)!
// cl.ubuntu_install(id: 2550253, name: 'kristof23', wait: true, hero_install: true)!
// this will put hero in debug mode on the system
mut b := builder.new()!
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
n.hero_install(compile: true)!
n.shell('')!

View File

@@ -0,0 +1,69 @@
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import incubaid.herolib.virt.hetznermanager
import incubaid.herolib.ui.console
import incubaid.herolib.core.base
import incubaid.herolib.builder
import time
import os
import incubaid.herolib.core.playcmds
name := 'test1'
user := os.environ()['HETZNER_USER'] or {
println('HETZNER_USER not set')
exit(1)
}
passwd := os.environ()['HETZNER_PASSWORD'] or {
println('HETZNER_PASSWORD not set')
exit(1)
}
hs := '
!!hetznermanager.configure
user:"${user}"
whitelist:"2575034"
password:"${passwd}"
sshkey:"kristof"
'
println(hs)
playcmds.run(heroscript: hs)!
console.print_header('Hetzner Test.')
mut cl := hetznermanager.get()!
// println(cl)
// for i in 0 .. 5 {
// println('test cache, first time slow then fast')
// }
println(cl.servers_list()!)
mut serverinfo := cl.server_info_get(name: name)!
println(serverinfo)
// cl.server_reset(name: 'kristof2', wait: true)!
// cl.server_rescue(name: name, wait: true, hero_install: true)!
// mut ks := cl.keys_get()!
// println(ks)
// console.print_header('SSH login')
cl.ubuntu_install(name: name, wait: true, hero_install: true)!
// cl.ubuntu_install(name: 'kristof20', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550378, name: 'kristof21', wait: true, hero_install: true)!
// cl.ubuntu_install(id:2550508, name: 'kristof22', wait: true, hero_install: true)!
// cl.ubuntu_install(id: 2550253, name: 'kristof23', wait: true, hero_install: true)!
// this will put hero in debug mode on the system
mut b := builder.new()!
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
n.hero_install(compile: true)!
n.shell('')!

View File

@@ -1,4 +1,28 @@
## to get started
make sure you have hero_secrets loaded
```bash
hero git pull https://git.threefold.info/despiegk/hero_secrets
source ~/code/git.ourworld.tf/despiegk/hero_secrets/mysecrets.sh
```
## to e.g. install test1
```
~/code/github/incubaid/herolib/examples/virt/hetzner/hetzner_test1.vsh
```
keys available:
- hossnys (RSA 2048)
- Jan De Landtsheer (ED25519 256)
- mahmoud (ED25519 256)
- kristof (ED25519 256)
- maxime (ED25519 256)
## hetzner info
get the login passwd from:
@@ -6,4 +30,4 @@ https://robot.hetzner.com/preferences/index
```bash
curl -u "#ws+JdQtGCdL:..." https://robot-ws.your-server.de/server
```
```

View File

@@ -0,0 +1,52 @@
# HeroDB Client
A V client library for interacting with the HeroDB JSON-RPC API.
## Features
- Connects to HeroDB's JSON-RPC server (default port 3000).
- Lists running database instances.
- Parses polymorphic backend types (InMemory, Redb, LanceDb).
## Usage
```v
import incubaid.herolib.clients.herodb
fn main() {
// Initialize the client
mut client := herodb.new(herodb.Config{
url: 'http://localhost:3000'
})!
// List instances
instances := client.list_instances()!
for instance in instances {
println('Index: ${instance.index}')
println('Name: ${instance.name}')
// Parse backend info
backend := instance.get_backend_info()!
println('Backend: ${backend.type_name}')
if backend.path != '' {
println('Path: ${backend.path}')
}
println('---')
}
}
```
## API Reference
### `fn new(cfg Config) !HeroDB`
Creates a new HeroDB client instance.
### `fn (mut self HeroDB) list_instances() ![]InstanceMetadata`
Retrieves a list of all currently loaded database instances.
### `fn (m InstanceMetadata) get_backend_info() !BackendInfo`
Helper method to parse the `backend_type` field from `InstanceMetadata` into a structured `BackendInfo` object.

127
lib/clients/herodb/herodb.v Normal file
View File

@@ -0,0 +1,127 @@
module herodb
import json
import incubaid.herolib.core.httpconnection
// JSON-RPC 2.0 Structures
struct JsonRpcRequest {
jsonrpc string = '2.0'
method string
params []string
id int
}
struct JsonRpcResponse[T] {
jsonrpc string
result T
error ?JsonRpcError
id int
}
struct JsonRpcError {
code int
message string
data string
}
// HeroDB Specific Structures
pub struct InstanceMetadata {
pub:
index int
name string
// backend_type can be a string ("InMemory") or an object ({"Redb": "path"}).
// We use the `raw` attribute to capture the raw JSON and parse it manually.
backend_type string @[raw]
created_at string
}
// Helper struct to represent the parsed backend info in a usable way
pub struct BackendInfo {
pub:
type_name string // "InMemory", "Redb", "LanceDb"
path string // Empty for InMemory
}
pub struct HeroDB {
pub:
server_url string
pub mut:
conn ?&httpconnection.HTTPConnection
}
pub struct Config {
pub:
url string = 'http://localhost:3000'
}
pub fn new(cfg Config) !HeroDB {
return HeroDB{
server_url: cfg.url
}
}
pub fn (mut self HeroDB) connection() !&httpconnection.HTTPConnection {
if mut conn := self.conn {
return conn
}
mut new_conn := httpconnection.new(
name: 'herodb'
url: self.server_url
retry: 3
)!
self.conn = new_conn
return new_conn
}
fn (mut self HeroDB) rpc_call[T](method string) !T {
mut conn := self.connection()!
req := JsonRpcRequest{
method: method
id: 1
params: []
}
response := conn.post_json_generic[JsonRpcResponse[T]](
method: .post
prefix: ''
data: json.encode(req)
dataformat: .json
)!
if err := response.error {
return error('RPC Error ${err.code}: ${err.message}')
}
return response.result
}
pub fn (mut self HeroDB) list_instances() ![]InstanceMetadata {
return self.rpc_call[[]InstanceMetadata]('db_listInstances')!
}
pub fn (m InstanceMetadata) get_backend_info() !BackendInfo {
if m.backend_type.len == 0 {
return error('empty backend_type')
}
if m.backend_type[0] == `"` {
// It's a string
val := json.decode(string, m.backend_type)!
return BackendInfo{
type_name: val
}
} else if m.backend_type[0] == `{` {
// It's an object
val := json.decode(map[string]string, m.backend_type)!
for k, v in val {
return BackendInfo{
type_name: k
path: v
}
}
}
return error('unknown backend_type format: ${m.backend_type}')
}

View File

@@ -11,8 +11,13 @@ pub fn parse_const(code_ string) !Const {
if !code.contains('=') {
return error('code <${code_}> is not of const')
}
mut name := code.split('=')[0].trim_space()
// Strip 'const ' prefix if present
if name.starts_with('const ') {
name = name.trim_string_left('const ').trim_space()
}
return Const{
name: code.split('=')[0].trim_space()
name: name
value: code.split('=')[1].trim_space()
}
}

View File

@@ -44,6 +44,11 @@ pub fn (p Param) typescript() string {
pub fn parse_param(code_ string) !Param {
mut code := code_.trim_space()
// Handle empty string (void return type)
if code == '' {
return Param{}
}
if code == '!' {
return Param{
is_result: true
@@ -60,6 +65,13 @@ pub fn parse_param(code_ string) !Param {
}
split := code.split(' ').filter(it != '')
// Handle empty split (void return type after mut check)
if split.len == 0 {
return Param{
mutable: is_mut
}
}
if split.len == 1 {
// means anonymous param
return Param{

View File

@@ -15,14 +15,14 @@ fn test_comprehensive_code_parsing() {
console.print_lf(1)
// Run all tests
test_module_parsing()
test_struct_parsing()
test_function_parsing()
test_imports_and_modules()
test_type_system()
test_visibility_modifiers()
test_method_parsing()
test_constants_parsing()
check_module_parsing()!
check_struct_parsing()
check_function_parsing()!
check_imports_and_modules()
check_type_system()
check_visibility_modifiers()
check_method_parsing()!
check_constants_parsing()
console.print_green(' All comprehensive tests passed!')
console.print_lf(1)
@@ -74,7 +74,7 @@ fn copy_directory(src string, dst string) ! {
}
}
fn test_module_parsing() {
fn check_module_parsing() ! {
console.print_header('Test 1: Module and File Parsing')
mut myparser := new(path: '/tmp/codeparsertest', recursive: true)!
@@ -98,7 +98,7 @@ fn test_module_parsing() {
console.print_lf(1)
}
fn test_struct_parsing() {
fn check_struct_parsing() {
console.print_header('Test 2: Struct Parsing')
models_file := os.join_path('/tmp/codeparsertest', 'models.v')
@@ -145,7 +145,7 @@ fn test_struct_parsing() {
console.print_lf(1)
}
fn test_function_parsing() {
fn check_function_parsing() ! {
console.print_header('Test 3: Function Parsing')
mut myparser := new(path: '/tmp/codeparsertest', recursive: true)!
@@ -191,7 +191,7 @@ fn test_function_parsing() {
console.print_lf(1)
}
fn test_imports_and_modules() {
fn check_imports_and_modules() {
console.print_header('Test 4: Imports and Module Names')
models_file := os.join_path('/tmp/codeparsertest', 'models.v')
@@ -222,7 +222,7 @@ fn test_imports_and_modules() {
console.print_lf(1)
}
fn test_type_system() {
fn check_type_system() {
console.print_header('Test 5: Type System')
models_file := os.join_path('/tmp/codeparsertest', 'models.v')
@@ -257,7 +257,7 @@ fn test_type_system() {
console.print_lf(1)
}
fn test_visibility_modifiers() {
fn check_visibility_modifiers() {
console.print_header('Test 6: Visibility Modifiers')
models_file := os.join_path('/tmp/codeparsertest', 'models.v')
@@ -293,7 +293,7 @@ fn test_visibility_modifiers() {
console.print_lf(1)
}
fn test_method_parsing() {
fn check_method_parsing() ! {
console.print_header('Test 7: Method Parsing')
mut myparser := new(path: '/tmp/codeparsertest', recursive: true)!
@@ -327,7 +327,7 @@ fn test_method_parsing() {
console.print_lf(1)
}
fn test_constants_parsing() {
fn check_constants_parsing() {
console.print_header('Test 8: Constants Parsing')
models_file := os.join_path('/tmp/codeparsertest', 'models.v')

View File

@@ -0,0 +1,217 @@
need to install following
#!/bin/bash
set -euo pipefail
EXTRA_ARGS=""
log_info() {
echo '[INFO] ' "$@"
}
log_fatal() {
echo '[ERROR] ' "$@" >&2
exit 1
}
source_env_file() {
local env_file="${1:-}"
if [ ! -f "$env_file" ]; then
log_fatal "Environment file not found: $env_file"
fi
set -a
source "$env_file"
set +a
}
check_root() {
if [ "$EUID" -ne 0 ]; then
log_fatal "This script must be run as root"
fi
}
install_deps() {
log_info "Updating package lists..."
if ! apt-get update -qq > /dev/null 2>&1; then
log_fatal "Failed to update package lists"
fi
if ! command -v curl &> /dev/null; then
log_info "Installing curl..."
apt-get install -y -qq curl > /dev/null 2>&1 || log_fatal "Failed to install curl"
fi
if ! command -v ip &> /dev/null; then
log_info "Installing iproute2 for ip command..."
apt-get install -y -qq iproute2 > /dev/null 2>&1 || log_fatal "Failed to install iproute2"
fi
if ! command -v k3s &> /dev/null; then
log_info "Installing k3s..."
if ! curl -fsSL -o /usr/local/bin/k3s https://github.com/k3s-io/k3s/releases/download/v1.33.1+k3s1/k3s 2>/dev/null; then
log_fatal "Failed to download k3s"
fi
chmod +x /usr/local/bin/k3s
fi
if ! command -v kubectl &> /dev/null; then
log_info "Installing kubectl..."
if ! curl -fsSL -o /usr/local/bin/kubectl https://dl.k8s.io/release/v1.33.1/bin/linux/amd64/kubectl 2>/dev/null; then
log_fatal "Failed to download kubectl"
fi
chmod +x /usr/local/bin/kubectl
fi
}
get_iface_ipv6() {
local iface="$1"
# Step 1: Find the next-hop for 400::/7
local route_line
route_line=$(ip -6 route | grep "^400::/7.*dev ${iface}" || true)
if [ -z "$route_line" ]; then
log_fatal "No 400::/7 route found via interface ${iface}"
fi
# Extract next-hop IPv6
local nexthop
nexthop=$(echo "$route_line" | awk '{for(i=1;i<=NF;i++) if ($i=="via") print $(i+1)}')
local prefix
prefix=$(echo "$nexthop" | cut -d':' -f1-4)
# Step 3: Get global IPv6 addresses and match subnet
local ipv6_list
ipv6_list=$(ip -6 addr show dev "$iface" scope global | awk '/inet6/ {print $2}' | cut -d'/' -f1)
local ip ip_prefix
for ip in $ipv6_list; do
ip_prefix=$(echo "$ip" | cut -d':' -f1-4)
if [ "$ip_prefix" = "$prefix" ]; then
echo "$ip"
return 0
fi
done
log_fatal "No global IPv6 address found on ${iface} matching prefix ${prefix}"
}
prepare_args() {
log_info "Preparing k3s arguments..."
if [ -z "${K3S_FLANNEL_IFACE:-}" ]; then
log_fatal "K3S_FLANNEL_IFACE not set, it should be your mycelium interface"
else
local ipv6
ipv6=$(get_iface_ipv6 "$K3S_FLANNEL_IFACE")
EXTRA_ARGS="$EXTRA_ARGS --node-ip=$ipv6"
fi
if [ -n "${K3S_DATA_DIR:-}" ]; then
log_info "k3s data-dir set to: $K3S_DATA_DIR"
if [ -d "/var/lib/rancher/k3s" ] && [ -n "$(ls -A /var/lib/rancher/k3s 2>/dev/null)" ]; then
cp -r /var/lib/rancher/k3s/* $K3S_DATA_DIR && rm -rf /var/lib/rancher/k3s
fi
EXTRA_ARGS="$EXTRA_ARGS --data-dir $K3S_DATA_DIR --kubelet-arg=root-dir=$K3S_DATA_DIR/kubelet"
fi
if [[ "${MASTER:-}" = "true" ]]; then
EXTRA_ARGS="$EXTRA_ARGS --cluster-cidr=2001:cafe:42::/56"
EXTRA_ARGS="$EXTRA_ARGS --service-cidr=2001:cafe:43::/112"
EXTRA_ARGS="$EXTRA_ARGS --flannel-ipv6-masq"
fi
if [ -z "${K3S_URL:-}" ]; then
# Add additional SANs for planetary network IP, public IPv4, and public IPv6
# https://github.com/threefoldtech/tf-images/issues/98
local ifaces=( "tun0" "eth1" "eth2" )
for iface in "${ifaces[@]}"
do
# Check if interface exists before querying
if ! ip addr show "$iface" &>/dev/null; then
continue
fi
local addrs
addrs=$(ip addr show "$iface" 2>/dev/null | grep -E "inet |inet6 " | grep "global" | cut -d '/' -f1 | awk '{print $2}' || true)
local addr
for addr in $addrs
do
# Validate the IP address by trying to route to it
if ip route get "$addr" &>/dev/null; then
EXTRA_ARGS="$EXTRA_ARGS --tls-san $addr"
fi
done
done
if [ "${HA:-}" = "true" ]; then
EXTRA_ARGS="$EXTRA_ARGS --cluster-init"
fi
else
if [ -z "${K3S_TOKEN:-}" ]; then
log_fatal "K3S_TOKEN must be set when K3S_URL is specified (joining a cluster)"
fi
fi
}
patch_manifests() {
log_info "Patching manifests..."
dir="${K3S_DATA_DIR:-/var/lib/rancher/k3s}"
manifest="$dir/server/manifests/tfgw-crd.yaml"
# If K3S_URL found, remove manifest and exit. it is an agent node
if [[ -n "${K3S_URL:-}" ]]; then
rm -f "$manifest"
log_info "Agent node detected, removed manifest: $manifest"
exit 0
fi
# If K3S_URL not found, patch the manifest. it is a server node
[[ ! -f "$manifest" ]] && echo "Manifest not found: $manifest" >&2 && exit 1
sed -i \
-e "s|\${MNEMONIC}|${MNEMONIC:-}|g" \
-e "s|\${NETWORK}|${NETWORK:-}|g" \
-e "s|\${TOKEN}|${TOKEN:-}|g" \
"$manifest"
}
run_node() {
if [ -z "${K3S_URL:-}" ]; then
log_info "Starting k3s server (initializing new cluster)..."
log_info "Command: k3s server --flannel-iface $K3S_FLANNEL_IFACE $EXTRA_ARGS"
exec k3s server --flannel-iface "$K3S_FLANNEL_IFACE" $EXTRA_ARGS 2>&1
elif [ "${MASTER:-}" = "true" ]; then
log_info "Starting k3s server (joining existing cluster as master)..."
log_info "Command: k3s server --server $K3S_URL --flannel-iface $K3S_FLANNEL_IFACE $EXTRA_ARGS"
exec k3s server --server "$K3S_URL" --flannel-iface "$K3S_FLANNEL_IFACE" $EXTRA_ARGS 2>&1
else
log_info "Starting k3s agent (joining existing cluster as worker)..."
log_info "Command: k3s agent --server $K3S_URL --flannel-iface $K3S_FLANNEL_IFACE $EXTRA_ARGS"
exec k3s agent --server "$K3S_URL" --flannel-iface "$K3S_FLANNEL_IFACE" $EXTRA_ARGS 2>&1
fi
}
main() {
source_env_file "${1:-}"
check_root
install_deps
prepare_args
patch_manifests
run_node
}
main "$@"
INSTRUCTIONS: USE HEROLIB AS MUCH AS POSSIBLE e.g. SAL

View File

@@ -0,0 +1,3 @@
https://github.com/codescalers/kubecloud/blob/master/k3s/native_guide/k3s_killall.sh
still need to implement this

View File

@@ -193,7 +193,7 @@ pub fn (mut h HetznerManager) ubuntu_install(args ServerInstallArgs) !&builder.N
console.print_debug('server ${serverinfo.server_name} is reacheable over ssh, lets now install hero if asked for.')
if args.hero_install {
n.exec_silent('apt update && apt install -y mc redis')!
n.exec_silent('apt update && apt install -y mc redis libpq5 libpq-dev')!
n.hero_install(compile: args.hero_install_compile)!
}

View File

@@ -53,7 +53,7 @@ pub fn (mut h HetznerManager) server_reset(args ServerRebootArgs) !ResetInfo {
console.print_debug('wait for server ${serverinfo.server_name} on ${serverinfo.server_ip} to go down.')
pingresult := osal.ping(address: serverinfo.server_ip)!
if !pingresult {
console.print_debug('server ${serverinfo.server_name} is now down, now waitig for reboot.')
console.print_debug('server ${serverinfo.server_name} is now down, now waiting for reboot.')
break
}
time.sleep(1000 * time.millisecond)

View File

@@ -1,26 +0,0 @@
#!/bin/bash
# Exit on error
set -e
echo "Starting HeroLib Manual Wiki Server..."
# Get the directory of this script (manual directory)
MANUAL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Get the directory of this script (manual directory)
CONFIG_FILE="$MANUAL_DIR/config.json"
# Path to the wiki package
WIKI_DIR="/Users/timurgordon/code/github/incubaid/herolauncher/pkg/ui/wiki"
# Path to the herolib directory
HEROLIB_DIR="/Users/timurgordon/code/github/incubaid/herolib"
cd "$WIKI_DIR"
# Run the wiki server on port 3004
go run . "$MANUAL_DIR" "$CONFIG_FILE" 3004
# The script will not reach this point unless the server is stopped
echo "Wiki server stopped."