Compare commits

...

11 Commits

Author SHA1 Message Date
Scott Yeager
0269277ac8 bump version to 1.0.38 2025-11-26 14:53:40 -08:00
Scott Yeager
ee0e7d44fd Fix release script 2025-11-26 14:53:29 -08:00
Scott Yeager
28f00d3dc6 Add build flow doc 2025-11-26 14:52:09 -08:00
Scott Yeager
a30646e3b1 Remove unused glibc upload 2025-11-26 14:02:39 -08:00
Scott Yeager
c7ae0ed393 Update workflow for single static build on Linux 2025-11-26 13:55:48 -08:00
805c900b02 Merge pull request #213 from Incubaid/development_linuxname
Rename "linux"
2025-11-26 13:51:24 -08: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
Scott Yeager
dd293ce387 Rename "linux" 2025-11-25 21:30:01 -08:00
a6d746319c /// 2025-11-25 20:10:31 +01:00
0e20b9696a ... 2025-11-25 19:19:35 +01:00
22 changed files with 576 additions and 129 deletions

32
.github/workflows/README.md vendored Normal file
View File

@@ -0,0 +1,32 @@
# Building Hero for release
Generally speaking, our scripts and docs for building hero produce non portable binaries for Linux. While that's fine for development purposes, statically linked binaries are much more convenient for releases and distribution.
The release workflow here creates a static binary for Linux using an Alpine container. A few notes follow about how that's done.
## Static builds in vlang
Since V compiles to C in our case, we are really concerned with how to produce static C builds. The V project provides [some guidance](https://github.com/vlang/v?tab=readme-ov-file#docker-with-alpinemusl) on using an Alpine container and passing `-cflags -static` to the V compiler.
That's fine for some projects. Hero has a dependency on the `libpq` C library for Postgres functionality, however, and this creates a complication.
## Static linking libpq
In order to create a static build of hero on Alpine, we need to install some additional packages:
* openssl-libs-static
* postgresql-dev
The full `apk` command to prepare the container for building looks like this:
```bash
apk add --no-cache bash git build-base openssl-dev libpq-dev postgresql-dev openssl-libs-static
```
Then we also need to instruct the C compiler to link against the Postgres static shared libraries. Here's the build command:
```bash
v -w -d use_openssl -enable-globals -cc gcc -cflags -static -ldflags "-lpgcommon_shlib -lpgport_shlib" cli/hero.v
```
Note that gcc is also the preferred compiler for static builds.

View File

@@ -35,9 +35,6 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
# We do the workaround as described here https://github.com/Incubaid/herolib?tab=readme-ov-file#tcc-compiler-error-on-macos
# gcc and clang also don't work on macOS due to https://github.com/vlang/v/issues/25467
# We can change the compiler or remove this when one is fixed
- name: Setup V & Herolib
id: setup
shell: bash
@@ -53,52 +50,34 @@ jobs:
echo "Herolib symlink created to $(pwd)/lib"
timeout-minutes: 10
# We can't make static builds for Linux easily, since we link to libql
# (Postgres) and this has no static version available in the Alpine
# repos. Therefore we build dynamic binaries for both glibc and musl.
#
# Again we work around a bug limiting our choice of C compiler tcc won't
# work on Alpine due to https://github.com/vlang/v/issues/24866
# So always use gcc for Linux
#
# For macOS, we can only use tcc (see above), but then we hit issues using
# the garbage collector, so disable that
# For Linux, we build a static binary linked against musl on Alpine. For
# static linking, gcc is preferred
- name: Build Hero
timeout-minutes: 15
run: |
set -e
set -ex
if [ "${{ runner.os }}" = "Linux" ]; then
sudo apt-get install libpq-dev
# Build for glibc
v -w -d use_openssl -enable-globals -cc gcc cli/hero.v -o cli/hero-${{ matrix.target }}
# Build for musl using Alpine in Docker
docker run --rm \
-v ${{ github.workspace }}/lib:/root/.vmodules/incubaid/herolib \
-v ${{ github.workspace }}:/herolib \
-w /herolib \
alpine \
alpine:3.22 \
sh -c '
apk add --no-cache bash git build-base openssl-dev libpq-dev
set -ex
apk add --no-cache bash git build-base openssl-dev libpq-dev postgresql-dev openssl-libs-static
cd v
make clean
make
./v symlink
cd ..
v -w -d use_openssl -enable-globals -cc gcc cli/hero.v -o cli/hero-${{ matrix.target }}-musl
v -w -d use_openssl -enable-globals -cc gcc -cflags -static -ldflags "-lpgcommon_shlib -lpgport_shlib" cli/hero.v -o cli/hero-${{ matrix.target }}-musl
'
else
v -w -d use_openssl -enable-globals -cc clang cli/hero.v -o cli/hero-${{ matrix.target }}
fi
- name: Upload glibc binary
if: runner.os == 'Linux'
uses: actions/upload-artifact@v4
with:
name: hero-${{ matrix.target }}
path: cli/hero-${{ matrix.target }}
- name: Upload musl binary
if: runner.os == 'Linux'
uses: actions/upload-artifact@v4

View File

@@ -53,7 +53,7 @@ fn do() ! {
mut cmd := Command{
name: 'hero'
description: 'Your HERO toolset.'
version: '1.0.36'
version: '1.0.38'
}
mut toinstall := false

View File

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

View File

@@ -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:

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

@@ -149,19 +149,19 @@ pub fn (mut config CrunConfig) set_hostname(hostname string) &CrunConfig {
}
pub fn (mut config CrunConfig) set_memory_limit(limit_bytes u64) &CrunConfig {
config.spec.linux.resources.memory.limit = limit_bytes
config.spec.linux_config.resources.memory.limit = limit_bytes
return config
}
pub fn (mut config CrunConfig) set_cpu_limits(period u64, quota i64, shares u64) &CrunConfig {
config.spec.linux.resources.cpu.period = period
config.spec.linux.resources.cpu.quota = quota
config.spec.linux.resources.cpu.shares = shares
config.spec.linux_config.resources.cpu.period = period
config.spec.linux_config.resources.cpu.quota = quota
config.spec.linux_config.resources.cpu.shares = shares
return config
}
pub fn (mut config CrunConfig) set_pids_limit(limit i64) &CrunConfig {
config.spec.linux.resources.pids.limit = limit
config.spec.linux_config.resources.pids.limit = limit
return config
}
@@ -222,15 +222,15 @@ pub fn (mut config CrunConfig) set_terminal(value bool) &CrunConfig {
}
pub fn (mut config CrunConfig) add_masked_path(path string) &CrunConfig {
if path !in config.spec.linux.masked_paths {
config.spec.linux.masked_paths << path
if path !in config.spec.linux_config.masked_paths {
config.spec.linux_config.masked_paths << path
}
return config
}
pub fn (mut config CrunConfig) add_readonly_path(path string) &CrunConfig {
if path !in config.spec.linux.readonly_paths {
config.spec.linux.readonly_paths << path
if path !in config.spec.linux_config.readonly_paths {
config.spec.linux_config.readonly_paths << path
}
return config
}
@@ -293,7 +293,7 @@ fn create_default_spec() Spec {
}
hostname: 'container'
mounts: create_default_mounts()
linux: Linux{
linux_config: LinuxConfig{
namespaces: create_default_namespaces()
masked_paths: [
'/proc/acpi',

View File

@@ -3,14 +3,14 @@ module crun
// OCI Runtime Spec structures that can be directly encoded to JSON
pub struct Spec {
pub mut:
oci_version string @[json: 'ociVersion']
platform Platform
process Process
root Root
hostname string
mounts []Mount
linux Linux
hooks Hooks
oci_version string @[json: 'ociVersion']
platform Platform
process Process
root Root
hostname string
mounts []Mount
linux_config LinuxConfig
hooks Hooks
}
pub struct Platform {
@@ -68,7 +68,7 @@ pub mut:
options []string
}
pub struct Linux {
pub struct LinuxConfig {
pub mut:
namespaces []LinuxNamespace
resources LinuxResources

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."

View File

@@ -88,7 +88,7 @@ os.write_file(hero_v_path, lines.join_lines()) or {
os.rm('${hero_v_path}.backup') or { eprintln('Warning: Could not remove backup file: ${err}') }
// Update version in install_hero.sh
install_hero_path := '${ourdir}/install_hero.sh'
install_hero_path := '${ourdir}/scripts/install_hero.sh'
install_hero_content := os.read_file(install_hero_path) or {
eprintln('Error reading ${install_hero_path}: ${err}')
exit(1)

View File

@@ -4,7 +4,7 @@ set -e
os_name="$(uname -s)"
arch_name="$(uname -m)"
version='1.0.36'
version='1.0.38'
# Detect Linux distribution type
linux_type=""
@@ -17,19 +17,11 @@ fi
# Base URL for GitHub releases
base_url="https://github.com/incubaid/herolib/releases/download/v${version}"
# Select the URL based on the platform
# Select the URL based on the platform. For Linux we have a single static binary
if [[ "$os_name" == "Linux" && "$arch_name" == "x86_64" ]]; then
if [[ "$linux_type" == "alpine" ]]; then
url="$base_url/hero-x86_64-linux-musl"
else
url="$base_url/hero-x86_64-linux"
fi
url="$base_url/hero-x86_64-linux-musl"
elif [[ "$os_name" == "Linux" && "$arch_name" == "aarch64" ]]; then
if [[ "$linux_type" == "alpine" ]]; then
url="$base_url/hero-aarch64-linux-musl"
else
url="$base_url/hero-aarch64-linux"
fi
url="$base_url/hero-aarch64-linux-musl"
elif [[ "$os_name" == "Darwin" && "$arch_name" == "arm64" ]]; then
url="$base_url/hero-aarch64-apple-darwin"
# elif [[ "$os_name" == "Darwin" && "$arch_name" == "x86_64" ]]; then