...
This commit is contained in:
1
examples/virt/hetzner/.gitignore
vendored
Normal file
1
examples/virt/hetzner/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
hetzner_example
|
||||
Binary file not shown.
@@ -45,17 +45,20 @@ println(serverinfo)
|
||||
|
||||
// cl.server_reset(name:"kristof2",wait:true)!
|
||||
|
||||
cl.server_rescue(name:"kristof2",wait:true, hero_install:true,sshkey_name:"kristof")!
|
||||
//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()!
|
||||
println(ks)
|
||||
// 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)!
|
||||
// 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.hero_install(compile:true)!
|
||||
|
||||
// n.shell("")!
|
||||
|
||||
cl.ubuntu_install(name:"kristof2",wait:true, hero_install:true,sshkey_name:"kristof")!
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ pub fn (mut node Node) hero_install(args HeroInstallArgs) ! {
|
||||
|
||||
mut todo := []string{}
|
||||
if ! args.compile {
|
||||
todo << "curl https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_herolib.sh > /tmp/install.sh"
|
||||
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"
|
||||
|
||||
@@ -7,6 +7,7 @@ import freeflowuniverse.herolib.osal.rsync
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.data.ipaddress
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
|
||||
@[heap]
|
||||
pub struct ExecutorSSH {
|
||||
@@ -52,7 +53,16 @@ pub fn (mut executor ExecutorSSH) exec(args_ ExecArgs) !string {
|
||||
if executor.ipaddr.port > 10 {
|
||||
port = '-p ${executor.ipaddr.port}'
|
||||
}
|
||||
|
||||
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 = 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${executor.user}@${executor.ipaddr.addr} ${port} "${args.cmd}"'
|
||||
|
||||
res := osal.exec(cmd: args.cmd, stdout: args.stdout, debug: executor.debug)!
|
||||
return res.output
|
||||
}
|
||||
@@ -63,7 +73,15 @@ pub fn (mut executor ExecutorSSH) exec_interactive(args_ ExecArgs) ! {
|
||||
if executor.ipaddr.port > 10 {
|
||||
port = '-p ${executor.ipaddr.port}'
|
||||
}
|
||||
|
||||
if args.cmd.contains("\n"){
|
||||
args.cmd = texttools.dedent(args.cmd)
|
||||
//need to upload the file first
|
||||
executor.file_write('/tmp/toexec.sh', args.cmd)!
|
||||
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}"'
|
||||
|
||||
console.print_debug(args.cmd)
|
||||
osal.execute_interactive(args.cmd)!
|
||||
}
|
||||
|
||||
@@ -70,6 +70,49 @@ pub fn ping(args PingArgs) !PingResult {
|
||||
return .ok
|
||||
}
|
||||
|
||||
|
||||
@[params]
|
||||
pub struct RebootWaitArgs {
|
||||
pub mut:
|
||||
address string @[required] // 192.168.8.8
|
||||
timeout_down i64 = 2 // total time in seconds to wait till its down
|
||||
timeout_up i64 = 60 * 5
|
||||
}
|
||||
|
||||
// test if a tcp port answers
|
||||
//```
|
||||
// address string //192.168.8.8
|
||||
// port int = 22
|
||||
// timeout u16 = 2000 // total time in milliseconds to keep on trying
|
||||
//```
|
||||
pub fn reboot_wait(args RebootWaitArgs) ! {
|
||||
start_time := time.now().unix_milli()
|
||||
mut run_time := 0.0
|
||||
for true {
|
||||
console.print_debug("Waiting for server to go down...")
|
||||
run_time = time.now().unix_milli()
|
||||
if run_time > start_time + args.timeout_down {
|
||||
return error("timeout in waiting for server down")
|
||||
}
|
||||
if ping(address:args.address)! == .timeout {
|
||||
break
|
||||
}
|
||||
time.sleep(1)
|
||||
}
|
||||
for true {
|
||||
console.print_debug("Waiting for server to come back up...")
|
||||
run_time = time.now().unix_milli()
|
||||
if run_time > start_time + args.timeout_up {
|
||||
return error("timeout in waiting for server up")
|
||||
}
|
||||
if ping(address:args.address)! == .ok {
|
||||
break
|
||||
}
|
||||
time.sleep(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@[params]
|
||||
pub struct TcpPortTestArgs {
|
||||
pub mut:
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
module hetznermanager
|
||||
|
||||
// TODO: couldn't get ssh lib to work
|
||||
|
||||
// pub fn (h HetznerManager) server_prepare(name string) !bool {
|
||||
// srvs := h.servers_list()!
|
||||
|
||||
// // console.print_debug(srvs)
|
||||
// mut srvid := 0
|
||||
// mut srvip := ""
|
||||
|
||||
// for s in srvs {
|
||||
// if s.server.server_name == name {
|
||||
// // console.print_debug(s)
|
||||
// srvid = s.server.server_number
|
||||
// srvip = s.server.server_ip
|
||||
// }
|
||||
// }
|
||||
|
||||
// if srvid == 0 {
|
||||
// panic("could not find server")
|
||||
// }
|
||||
|
||||
// console.print_debug("[+] request rescue mode")
|
||||
// resc := h.server_rescue(srvid)!
|
||||
// password := resc.rescue.password
|
||||
// console.print_debug("[+] rescue password: $password")
|
||||
// // console.print_debug(resc)
|
||||
|
||||
// console.print_debug("[+] fetching server information")
|
||||
// boot := h.server_boot(srvid)!
|
||||
// // console.print_debug(boot)
|
||||
|
||||
// console.print_debug("[+] forcing reboot")
|
||||
// reset := h.server_reset(srvid)!
|
||||
// // console.print_debug(reset)
|
||||
|
||||
// time.sleep(30000 * time.millisecond)
|
||||
|
||||
// console.print_debug("[+] waiting for rescue to be ready")
|
||||
// for {
|
||||
// target := vssh.new(srvip, 22) or {
|
||||
// console.print_debug("$err")
|
||||
// time.sleep(30000 * time.millisecond)
|
||||
// continue
|
||||
// }
|
||||
|
||||
// // rescue doesn't support keyboard-interactive, fallback to password
|
||||
// target.authenticate(.password, "root", password)!
|
||||
// check := target.execute("grep 'Hetzner Rescue System.' /etc/motd")!
|
||||
// if check.exitcode == 0 {
|
||||
// console.print_debug("[+] we are logged in on the rescue system !")
|
||||
|
||||
// // executing deployment binary
|
||||
// target.upload(os.args[0], "/tmp/deployment")!
|
||||
// target.stream("stdbuf -i0 -o0 -e0 /tmp/deployment")!
|
||||
|
||||
// exit(0)
|
||||
// }
|
||||
// }
|
||||
|
||||
// return true
|
||||
// }
|
||||
@@ -37,18 +37,27 @@ pub fn (mut h HetznerManager) server_rescue(args_ ServerRescueArgs) !ServerInfoD
|
||||
mut args := args_
|
||||
mut serverinfo := h.server_info_get(id: args.id, name: args.name)!
|
||||
|
||||
console.print_header('server ${serverinfo.server_name} goes into rescue mode')
|
||||
|
||||
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)!
|
||||
|
||||
console.print_debug('server ${serverinfo.server_name} is in rescue mode')
|
||||
res:=n.exec(cmd:"ls /root/.oldroot/nfs/install/installimage") or {
|
||||
"ERROR"
|
||||
}
|
||||
if res.contains("nfs/install/installimage"){
|
||||
console.print_debug('server ${serverinfo.server_name} is in rescue mode')
|
||||
return serverinfo
|
||||
}
|
||||
}
|
||||
serverinfo.rescue = false
|
||||
}
|
||||
// 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
|
||||
@@ -67,9 +76,9 @@ pub fn (mut h HetznerManager) server_rescue(args_ ServerRescueArgs) !ServerInfoD
|
||||
dataformat: .urlencoded
|
||||
)!
|
||||
|
||||
console.print_debug('hetzner rescue\n${rescue}')
|
||||
// console.print_debug('hetzner rescue\n${rescue}')
|
||||
|
||||
h.server_reset(id: args.id, name: args.name, wait: args.wait)!
|
||||
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}")!
|
||||
}
|
||||
@@ -81,6 +90,7 @@ pub fn (mut h HetznerManager) server_rescue(args_ ServerRescueArgs) !ServerInfoD
|
||||
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")!
|
||||
if args.hero_install {
|
||||
n.hero_install()!
|
||||
}
|
||||
@@ -94,8 +104,62 @@ pub fn (mut h HetznerManager) server_rescue(args_ ServerRescueArgs) !ServerInfoD
|
||||
pub fn (mut h HetznerManager) server_rescue_node(args ServerRescueArgs) !&builder.Node {
|
||||
mut serverinfo := h.server_rescue(args)!
|
||||
|
||||
mut b := builder.new()!
|
||||
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
|
||||
mut b := builder.new()!
|
||||
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
pub struct ServerInstallArgs {
|
||||
pub mut:
|
||||
id int
|
||||
name string
|
||||
wait bool = true
|
||||
hero_install bool
|
||||
hero_install_compile bool
|
||||
sshkey_name string @[required]
|
||||
raid bool
|
||||
}
|
||||
|
||||
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 b := builder.new()!
|
||||
mut n := b.node_new(ipaddr: serverinfo.server_ip)!
|
||||
|
||||
// installconfig:=$tmpl("templates/ubuntu_install.sh")
|
||||
// n.file_write("/tmp/installconfig",installconfig)!
|
||||
// n.exec_interactive("installimage -a -c /tmp/installconfig")!
|
||||
|
||||
mut rstr:=""
|
||||
if args.raid {
|
||||
rstr="-r yes -l 1 "
|
||||
}
|
||||
|
||||
n.exec_interactive('
|
||||
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 swap:swap:4G,/boot:ext3:1024M,/:btrfs:all
|
||||
reboot')!
|
||||
|
||||
os.execute_opt("ssh-keygen -R ${serverinfo.server_ip}")!
|
||||
|
||||
console.print_debug('server ${serverinfo.server_name} is installed in ubuntu now, should be restarting.')
|
||||
|
||||
osal.reboot_wait(
|
||||
address: serverinfo.server_ip
|
||||
timeout_down: 60
|
||||
timeout_up: 60 * 5
|
||||
)!
|
||||
|
||||
if args.hero_install {
|
||||
n.hero_install(compile: args.hero_install_compile)!
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ pub mut:
|
||||
id int
|
||||
name string
|
||||
wait bool = true
|
||||
msg string
|
||||
}
|
||||
|
||||
pub fn (mut h HetznerManager) server_reset(args ServerRebootArgs) !ResetInfo {
|
||||
@@ -45,7 +46,6 @@ pub fn (mut h HetznerManager) server_reset(args ServerRebootArgs) !ResetInfo {
|
||||
dataformat: .urlencoded
|
||||
// dict_key:'reset'
|
||||
)!
|
||||
println(o)
|
||||
console.print_debug('server ${serverinfo.server_name} reset done.')
|
||||
// now need to wait till it goes off
|
||||
if serveractive {
|
||||
@@ -64,7 +64,7 @@ pub fn (mut h HetznerManager) server_reset(args ServerRebootArgs) !ResetInfo {
|
||||
if args.wait {
|
||||
for {
|
||||
time.sleep(1000 * time.millisecond)
|
||||
console.print_debug('wait for ${serverinfo.server_name}')
|
||||
console.print_debug('wait for ${serverinfo.server_name} ${args.msg}')
|
||||
if osal.ssh_test(address: serverinfo.server_ip)! == .ok {
|
||||
console.print_debug('ssh test ok')
|
||||
console.print_header('server is rebooted: ${serverinfo.server_name}')
|
||||
@@ -80,19 +80,3 @@ pub fn (mut h HetznerManager) server_reset(args ServerRebootArgs) !ResetInfo {
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
// /////////////////////////////////////BOOT
|
||||
|
||||
// struct BootRoot {
|
||||
// boot Boot
|
||||
// }
|
||||
|
||||
// struct Boot {
|
||||
// rescue RescueInfo
|
||||
// }
|
||||
|
||||
// pub fn (mut h HetznerManager) server_boot(id int) !RescueInfo {
|
||||
// mut conn := h.connection()!
|
||||
// boot := conn.get_json[BootRoot](prefix: 'boot/${id}')!
|
||||
// return boot.boot.rescue
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user