feat: Improved the pacman installer, added an example

This commit is contained in:
Mahmoud-Emad
2025-02-11 10:32:15 +00:00
parent 6ecd190de8
commit d0b52f40b7
4 changed files with 147 additions and 86 deletions

11
examples/installers/pacman.vsh Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.installers.virt.pacman as pacman_installer
mut pacman := pacman_installer.get()!
// To install
pacman.install()!
// To remove
pacman.destroy()!

View File

@@ -1,20 +1,26 @@
module pacman
import freeflowuniverse.herolib.osal
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core
import os
// checks if a certain version or above is installed
fn installed_() !bool {
return osal.done_exists('install_pacman')
fn installed() !bool {
console.print_header('checking if pacman is installed')
res := os.execute('pacman -v')
if res.exit_code != 0 {
console.print_header('pacman is not installed')
return false
}
console.print_header('pacman is installed')
return true
}
// use https://archlinux.org/mirrorlist/
fn install_() ! {
console.print_header('install pacman')
fn install() ! {
console.print_header('installing pacman')
if core.platform()! == .arch {
return
@@ -24,78 +30,40 @@ fn install_() ! {
return error('only ubuntu supported for this installer.')
}
cmd := '
mkdir -p /etc/pacman.d/gnupg
'
mut cmd := 'apt update && apt upgrade -y'
osal.execute_stdout(cmd)!
dest := '/etc/pacman.conf'
c := $tmpl('templates/pacman.conf')
os.write_file(dest, c)!
cmd = 'mkdir -p /tmp/pacman'
osal.execute_stdout(cmd)!
dest2 := '/etc/pacman.d/mirrorlist'
c2 := $tmpl('templates/mirrorlist')
pathlib.template_write(c2, dest2, true)!
cmd = 'cd /tmp/pacman && wget https://gitlab.com/trivoxel/utilities/deb-pacman/-/archive/${version}/deb-pacman-${version}.tar'
osal.execute_stdout(cmd)!
osal.package_install('
arch-install-scripts
pacman-package-manager
')!
cmd = 'cd /tmp/pacman && tar -xf deb-pacman-v1.0.tar'
osal.execute_stdout(cmd)!
url := 'https://gist.githubusercontent.com/despiegk/e56403ecba40f6057251c6cc609c4cf2/raw/1822c921e7282c491d8ac35f3719f51e234f1cbf/gistfile1.txt'
mut gpg_dest := osal.download(
url: url
minsize_kb: 1000
reset: true
)!
cmd = 'cd /tmp/pacman/deb-pacman-v1.0 && chmod +x pacman && sudo mv pacman /usr/local/bin'
osal.execute_stdout(cmd)!
cmd2 := '
mkdir -p /tmp/keyrings
cd /tmp/keyrings
wget https://archlinux.org/packages/core/any/archlinux-keyring/download -O archlinux-keyring.tar.zst
tar -xvf archlinux-keyring.tar.zst
mkdir -p /usr/share/keyrings
cp usr/share/pacman/keyrings/archlinux.gpg /usr/share/keyrings/
pacman-key --init
pacman-key --populate archlinux
gpg --import ${gpg_dest.path}
# Clean up
rm -f pacman_keyring.asc
#pacman-key --refresh-keys
pacman-key --update
rm -rf /tmp/keyrings
'
osal.execute_stdout(cmd2)!
// TODO: is not working well, is like it doesn;t write in right location
osal.done_set('install_pacman', 'OK')!
console.print_header('install done')
console.print_header('pacman is installed')
}
fn destroy_() ! {
osal.done_delete('install_pacman')!
fn destroy() ! {
console.print_header('uninstall pacman')
osal.package_remove('
arch-install-scripts
pacman-package-manager
')!
if core.platform()! == .arch {
return
}
// TODO: will need to remove more
osal.rm('
pacman
/etc/pacman.d
/var/cache/pacman
')!
if core.platform()! != .ubuntu {
return error('only ubuntu supported for this installer.')
}
mut cmd := 'rm -rf /tmp/pacman'
osal.execute_stdout(cmd)!
cmd = 'sudo rm -rf /usr/local/bin/pacman'
osal.execute_stdout(cmd)!
console.print_header('pacman is uninstalled')
}

View File

@@ -1,11 +1,9 @@
module pacman
import freeflowuniverse.herolib.core.base
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.sysadmin.startupmanager
import freeflowuniverse.herolib.osal.zinit
import time
__global (
pacman_global map[string]&PacmanInstaller
@@ -14,25 +12,98 @@ __global (
/////////FACTORY
@[params]
pub struct ArgsGet {
pub mut:
name string
}
pub fn get(args_ ArgsGet) !&PacmanInstaller {
return &PacmanInstaller{}
}
@[params]
pub struct PlayArgs {
pub mut:
heroscript string // if filled in then plbook will be made out of it
plbook ?playbook.PlayBook
reset bool
}
pub fn play(args_ PlayArgs) ! {
mut args := args_
mut plbook := args.plbook or { playbook.new(text: args.heroscript)! }
mut other_actions := plbook.find(filter: 'pacman.')!
for other_action in other_actions {
if other_action.name in ['destroy', 'install', 'build'] {
mut p := other_action.params
reset := p.get_default_false('reset')
if other_action.name == 'destroy' || reset {
console.print_debug('install action pacman.destroy')
destroy()!
}
if other_action.name == 'install' {
console.print_debug('install action pacman.install')
install()!
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////# LIVE CYCLE MANAGEMENT FOR INSTALLERS ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
fn startupmanager_get(cat zinit.StartupManagerType) !startupmanager.StartupManager {
// unknown
// screen
// zinit
// tmux
// systemd
match cat {
.zinit {
console.print_debug('startupmanager: zinit')
return startupmanager.get(cat: .zinit)!
}
.systemd {
console.print_debug('startupmanager: systemd')
return startupmanager.get(cat: .systemd)!
}
else {
console.print_debug('startupmanager: auto')
return startupmanager.get()!
}
}
}
@[params]
pub struct InstallArgs {
pub mut:
reset bool
}
pub fn install(args InstallArgs) ! {
if args.reset {
destroy()!
}
if !(installed_()!) {
install_()!
pub fn (mut self PacmanInstaller) install(args InstallArgs) ! {
switch(self.name)
if args.reset || (!installed()!) {
install()!
}
}
pub fn destroy() ! {
destroy_()!
pub fn (mut self PacmanInstaller) destroy() ! {
switch(self.name)
destroy()!
}
// switch instance to be used for pacman
pub fn switch(name string) {
pacman_default = name
}
// helpers
@[params]
pub struct DefaultConfigArgs {
instance string = 'default'
}

View File

@@ -1,25 +1,36 @@
module pacman
import freeflowuniverse.herolib.data.paramsparser
import os
import freeflowuniverse.herolib.data.encoderhero
pub const version = ''
pub const version = 'v1.0'
const singleton = true
const default = true
// THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED
@[heap]
pub struct PacmanInstaller {
pub mut:
name string = 'default'
}
fn obj_init(obj_ PacmanInstaller) !PacmanInstaller {
// never call get here, only thing we can do here is work on object itself
mut obj := obj_
return obj
// your checking & initialization code if needed
fn obj_init(mycfg_ PacmanInstaller) !PacmanInstaller {
mut mycfg := mycfg_
return mycfg
}
// called before start if done
fn configure() ! {
// mut installer := get()!
}
/////////////NORMALLY NO NEED TO TOUCH
pub fn heroscript_dumps(obj PacmanInstaller) !string {
return encoderhero.encode[PacmanInstaller](obj)!
}
pub fn heroscript_loads(heroscript string) !PacmanInstaller {
mut obj := encoderhero.decode[PacmanInstaller](heroscript)!
return obj
}