Compare commits
11 Commits
developmen
...
v1.0.38
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0269277ac8 | ||
|
|
ee0e7d44fd | ||
|
|
28f00d3dc6 | ||
|
|
a30646e3b1 | ||
|
|
c7ae0ed393 | ||
| 805c900b02 | |||
|
|
aa434fddee | ||
|
|
deca6387f2 | ||
|
|
dd293ce387 | ||
| a6d746319c | |||
| 0e20b9696a |
32
.github/workflows/README.md
vendored
Normal file
32
.github/workflows/README.md
vendored
Normal 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.
|
||||
35
.github/workflows/hero_build.yml
vendored
35
.github/workflows/hero_build.yml
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
5
examples/virt/hetzner/.gitignore
vendored
5
examples/virt/hetzner/.gitignore
vendored
@@ -1 +1,4 @@
|
||||
hetzner_example
|
||||
hetzner_kristof1
|
||||
hetzner_kristof2
|
||||
hetzner_kristof3
|
||||
hetzner_test1
|
||||
|
||||
@@ -33,5 +33,3 @@
|
||||
server_name: 'kristof2'
|
||||
wait: true
|
||||
hero_install: true // Install Herolib on the new OS
|
||||
|
||||
|
||||
|
||||
@@ -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('')!
|
||||
69
examples/virt/hetzner/hetzner_kristof2.vsh
Executable file
69
examples/virt/hetzner/hetzner_kristof2.vsh
Executable 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)!
|
||||
69
examples/virt/hetzner/hetzner_kristof3.vsh
Executable file
69
examples/virt/hetzner/hetzner_kristof3.vsh
Executable 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('')!
|
||||
69
examples/virt/hetzner/hetzner_test1.vsh
Executable file
69
examples/virt/hetzner/hetzner_test1.vsh
Executable 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('')!
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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')
|
||||
|
||||
217
lib/installers/virt/kubernetes_installer/instructions.md
Normal file
217
lib/installers/virt/kubernetes_installer/instructions.md
Normal 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
|
||||
3
lib/installers/virt/kubernetes_installer/moreinfo.md
Normal file
3
lib/installers/virt/kubernetes_installer/moreinfo.md
Normal file
@@ -0,0 +1,3 @@
|
||||
https://github.com/codescalers/kubecloud/blob/master/k3s/native_guide/k3s_killall.sh
|
||||
|
||||
still need to implement this
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)!
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user