From 8bbf7d31a5d85ee4fe4a38863383fb0b5f16300f Mon Sep 17 00:00:00 2001 From: Artur Gurgul Date: Wed, 13 Aug 2025 07:06:53 +0200 Subject: [PATCH 1/2] add ca service --- bin/admin/certbot-cert | 4 ++++ bin/admin/install-idf | 21 +++++++++++++++++++++ bin/admin/install-idf-enable | 2 ++ bin/services/ca/Gemfile | 6 ++++++ bin/services/ca/Gemfile.lock | 26 ++++++++++++++++++++++++++ bin/services/ca/app.rb | 12 ++++++++++++ bin/services/ca/config.ru | 2 ++ bin/services/ca/make | 0 bin/services/ca/readme.md | 9 +++++++++ bin/ssl | 8 +++++--- 10 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 bin/admin/certbot-cert create mode 100644 bin/admin/install-idf create mode 100644 bin/admin/install-idf-enable create mode 100644 bin/services/ca/Gemfile create mode 100644 bin/services/ca/Gemfile.lock create mode 100644 bin/services/ca/app.rb create mode 100644 bin/services/ca/config.ru create mode 100755 bin/services/ca/make create mode 100644 bin/services/ca/readme.md diff --git a/bin/admin/certbot-cert b/bin/admin/certbot-cert new file mode 100644 index 0000000..e06ff98 --- /dev/null +++ b/bin/admin/certbot-cert @@ -0,0 +1,4 @@ +#/usr/bin/env bash + +certbot certonly --manual --preferred-challenges=dns -d "*.gurgul.org" -d "gurgul.org" + diff --git a/bin/admin/install-idf b/bin/admin/install-idf new file mode 100644 index 0000000..06d9939 --- /dev/null +++ b/bin/admin/install-idf @@ -0,0 +1,21 @@ +if [ -z "$SUDO_USER" ]; then + echo "This script must be run within sudo." + exit 1 +fi + +# from says ~/esp +ESP=/pkg/esp + +apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 + +sudo -u "$SUDO_USER" bash <= 3.0" +gem "roda" +gem "puma" +gem "rackup" \ No newline at end of file diff --git a/bin/services/ca/Gemfile.lock b/bin/services/ca/Gemfile.lock new file mode 100644 index 0000000..d81fe89 --- /dev/null +++ b/bin/services/ca/Gemfile.lock @@ -0,0 +1,26 @@ +GEM + remote: https://rubygems.org/ + specs: + nio4r (2.7.4) + puma (6.6.1) + nio4r (~> 2.0) + rack (3.2.0) + rackup (2.2.1) + rack (>= 3) + roda (3.95.0) + rack + +PLATFORMS + arm64-darwin-24 + ruby + +DEPENDENCIES + puma + rackup + roda + +RUBY VERSION + ruby 3.4.5p51 + +BUNDLED WITH + 2.6.9 diff --git a/bin/services/ca/app.rb b/bin/services/ca/app.rb new file mode 100644 index 0000000..46a803c --- /dev/null +++ b/bin/services/ca/app.rb @@ -0,0 +1,12 @@ +require "roda" + +class App < Roda + # automatically sets application/json and encodes Ruby objects + plugin :json + + route do |r| + r.get "hello" do + { message: "world" } + end + end +end \ No newline at end of file diff --git a/bin/services/ca/config.ru b/bin/services/ca/config.ru new file mode 100644 index 0000000..d829dc7 --- /dev/null +++ b/bin/services/ca/config.ru @@ -0,0 +1,2 @@ +require_relative "app" +run App.freeze.app \ No newline at end of file diff --git a/bin/services/ca/make b/bin/services/ca/make new file mode 100755 index 0000000..e69de29 diff --git a/bin/services/ca/readme.md b/bin/services/ca/readme.md new file mode 100644 index 0000000..211b003 --- /dev/null +++ b/bin/services/ca/readme.md @@ -0,0 +1,9 @@ + +bundle exec rackup -p 9292 -o 0.0.0.0 + + + +RACK_ENV=production bundle exec rackup -p 8080 -o 0.0.0.0 + + +curl http://0.0.0.0:9292/hello --verbose \ No newline at end of file diff --git a/bin/ssl b/bin/ssl index 60ce748..973d60a 100755 --- a/bin/ssl +++ b/bin/ssl @@ -17,9 +17,11 @@ subcommand = ARGV.shift&.to_sym arg1 = ARGV[0] && ARGV[0] !~ /^-/ ? ARGV.shift : nil arg2 = ARGV[0] && ARGV[0] !~ /^-/ ? ARGV.shift : nil -$domains = ["mediacenter.lan"] -$ips = ["192.168.0.94"] - +# $domains = ["mediacenter.lan"] +# $ips = ["192.168.0.94"] +$domains = ["testing.self"] +$ips = ["127.0.0.2"] +$ips = [] ### Setting up for client $cn = $domains.first From 2840b6e221a6febe361333ae94bb8b5b80877033 Mon Sep 17 00:00:00 2001 From: Artur Gurgul Date: Wed, 13 Aug 2025 10:21:46 +0200 Subject: [PATCH 2/2] Add option for archive and restore VMs --- bin/vm | 39 ++++++++++++++++++- lib/virtual-machine.rb | 87 ++++++++++++++++++++++++++++++++++-------- lib/vm/archive.rb | 37 ++++++++++++++++++ 3 files changed, 146 insertions(+), 17 deletions(-) create mode 100644 lib/vm/archive.rb diff --git a/bin/vm b/bin/vm index 983fb1f..969248b 100755 --- a/bin/vm +++ b/bin/vm @@ -4,6 +4,10 @@ require 'optparse' require 'ostruct' require 'virtual-machine' +# Paramteters +# -env: DAT_VM_DATA=~/.cache/vm + + # vm setup debian --arch "" --name "" options = OpenStruct.new @@ -18,6 +22,8 @@ OptionParser.new do |opt| opt.on('--name NAME', 'Virtaul Machine name') do |name| options.name = name end + # --port (ssh port) + # --attached (do not leave the shell process) # new from copy # fetch from the server end.parse! @@ -25,11 +31,40 @@ end.parse! case subcommand when :create - puts "Creating image...." - + puts "vm create debian-copy --name debian" + puts "Creating image base on existing one...." +when :run + # same as setup but fetches image not + puts "Run the image or fetch and run...." + options[:distro] = parameter + VirtualMachine.run(options) + when :setup options[:distro] = parameter VirtualMachine.setup(options) +when :archive + # whole image or files that are not present in the archived + # --type files (zst all files by files) + # by default + #before start if should create index of files that are present on + # the vm, so later we can copy new files or changed + + options[:distro] = parameter + VirtualMachine.archive(options) + +when :appy + puts "appy chnages from VM to the host os" +when :restore + options[:distro] = parameter + VirtualMachine.restore(options) + #puts "download image from remote or if local copy exists then the local copy" +when :daemon + puts "setup a pprocess so i can attach to it" + # paramaters exatly as run/setup +when :status + puts "Print all images and status stopped/daemon(port)/running(port/)" +when :attach + puts "if not paramteres attaches to last used" else puts "Error not found #{options.type}" end \ No newline at end of file diff --git a/lib/virtual-machine.rb b/lib/virtual-machine.rb index 3875625..ef696b9 100644 --- a/lib/virtual-machine.rb +++ b/lib/virtual-machine.rb @@ -2,13 +2,46 @@ require 'downloader' require 'system' require_relative 'data/resources/iso-images' require 'vm/qemu' +require 'vm/archive' module VirtualMachine def self.distro(name, arch, type = :install) - ISO_URLS[:debian][:arm64][:install] + ISO_URLS[name][arch][type] end - def self.setup(options) + def self.vm_root_path + ENV["DAT_VM_DATA"] || File.join(User.cache_path, "vm") + end + + def self.vm_dir(options) + File.join(vm_root_path, "image", "#{options[:distro].to_s}-#{options[:arch].to_s}", options[:name]) + end + + def self.archive_dir(options) + File.join(vm_root_path, "archive", "#{options[:distro].to_s}-#{options[:arch].to_s}", options[:name]) + end + + def self.create_archive_path(options) + File.join(archive_dir(options), "archive.tar.zst") + end + + def self.get_recent_archive_path(options) + File.join(archive_dir(options), "archive.tar.zst") + end + + # https://artur.gurgul.pro/vm/ + # https://artur.gurgul.pro/vm/debian-arm64/debian/archive.tar.zst + + def self.vm_archive_url(options) + return nil unless ENV["DAT_VM_REPO_URL"] + + end + + def self.root_img_path(options) + File.join(vm_dir(options), "root.img") + end + + def self.fill_defaults(options) if options[:name] == nil options[:name] = options[:distro] end @@ -18,27 +51,51 @@ module VirtualMachine else options[:arch] = System.arch_to_symbol(options[:arch]) end + end - puts options + def self.archive(options) + fill_defaults(options) + Archive.create(vm_dir(options), out: create_archive_path(options)) + end - distro = options[:distro] - type = :install - arch = options[:arch] - url = distro(name, arch, type) + def self.restore(options) + fill_defaults(options) + Archive.restore(get_recent_archive_path(options), vm_dir(options)) + end + + def self.run(options) + fill_defaults(options) + + disk_img_path = root_img_path(options) + # TODO: + # - if image path not exists, check the cache + # - if cache do not exists try to download + puts "Starting image: #{disk_img_path}" + + Qemu.launch( + options[:arch], + disk_img_path, + cpus: [1, System.cpus - 2].max, + detach: true + ) + end + + def self.setup(options) + fill_defaults(options) - Downloader.get(url) do |path| - disk_img_path = File.join(User.cache_path, "vm", distro.to_s, arch.to_s, options[:name], "root.img") - create_disk_image(disk_img_path, 15000) - - puts path - puts disk_img_path + url = distro(options[:name], options[:arch], :install) + disk_img_path = root_img_path(options) + Downloader.get(url) do |path| + + create_disk_image(disk_img_path, 64000) + Qemu.launch( - arch, + options[:arch], disk_img_path, cpus: [1, System.cpus - 2].max, cdrom: path, - detach: false + detach: true ) end end diff --git a/lib/vm/archive.rb b/lib/vm/archive.rb new file mode 100644 index 0000000..8554f15 --- /dev/null +++ b/lib/vm/archive.rb @@ -0,0 +1,37 @@ +require "fileutils" + +module Archive + def self.cmd(*cmd) + puts "cmd: #{cmd.join(" ")}" + # return + stdout, stderr, status = Open3.capture3(*cmd) + unless status.success? + warn "Command failed: #{cmd.join(' ')}" + warn stderr + exit status.exitstatus || 1 + end + stdout + end + + # it preserved sparsiveness + # gtar -S --sparse-version=2 -I 'zstd -T0 -19' -cpf test.tar.zst /Volumes/Projs/VM/VM-data/image/debian-arm64/debian/ + # tar --zstd -xpf test.tar.zst -C ./r + + def self.create(path, **options) + out = options[:out] || File.join(Dir.pwd, "archive.tar.zst") + + FileUtils.mkdir_p(File.dirname(out)) + cmd "gtar", "-S", "--sparse-version=2", "-I", + "zstd -T0 -19", "-cpf", out, "-C" , path, "." + end + + def self.restore(file, path, **options) + puts file + puts path + puts options + + FileUtils.mkdir_p(path) + cmd "gtar", "-S", "--sparse-version=2", "-I", "zstd", "-xpf", + file, "-C", path + end +end \ No newline at end of file