From 49cc960703bb8d3d9c0ad10f38fa1972dee1805c Mon Sep 17 00:00:00 2001 From: Artur Gurgul Date: Mon, 11 Aug 2025 14:18:59 +0200 Subject: [PATCH] creating raw images for QEMU --- bin/admin/install-gui | 7 +++++ bin/vm | 8 ++--- install | 6 ++-- lib/certbot.rb | 2 -- lib/downloader.rb | 26 ++++++++++++----- lib/local-user/single-user.rb | 10 +++++++ lib/system.rb | 8 +++++ lib/system/architecture.rb | 55 +++++++++++++++++++++++++++++++++++ lib/system/debian.rb | 5 ++++ lib/system/macos.rb | 5 ++++ lib/system/utils.rb | 6 ++++ lib/user.rb | 4 +++ lib/virtual-machine.rb | 39 +++++++++++++++++++++++-- 13 files changed, 164 insertions(+), 17 deletions(-) create mode 100755 bin/admin/install-gui create mode 100644 lib/local-user/single-user.rb create mode 100644 lib/system/architecture.rb create mode 100644 lib/system/utils.rb diff --git a/bin/admin/install-gui b/bin/admin/install-gui new file mode 100755 index 0000000..3043f9d --- /dev/null +++ b/bin/admin/install-gui @@ -0,0 +1,7 @@ + +## missing in the install script +apt install zsh curl + +apt install sway libgtk-3-0 libasound2 + +wget https://github.com/zen-browser/desktop/releases/download/1.14.11b/zen.linux-x86_64.tar.xz \ No newline at end of file diff --git a/bin/vm b/bin/vm index eb6eee3..0675205 100755 --- a/bin/vm +++ b/bin/vm @@ -8,15 +8,15 @@ require 'virtual-machine' options = OpenStruct.new subcommand = ARGV.shift&.to_sym -options.parameter = ARGV[0] && ARGV[0] !~ /^-/ ? ARGV.shift : nil +parameter = ARGV[0] && ARGV[0] !~ /^-/ ? ARGV.shift : nil OptionParser.new do |opt| opt.on('--arch ARCH', 'Architecture arm64 or x86_64') do |arch| options.arch = arch end - opt.on('--name NAME', 'Virtaul Machine name') do |arch| - options.arch = arch + opt.on('--name NAME', 'Virtaul Machine name') do |name| + options.name = name end end.parse! @@ -27,7 +27,7 @@ when :create puts "Creating image...." when :setup - options[:distro] = subcommand + options[:distro] = parameter VirtualMachine.setup(options) else puts "Error not found #{options.type}" diff --git a/install b/install index 1b8b6c8..7dcfed1 100755 --- a/install +++ b/install @@ -79,7 +79,7 @@ export DAT_ROOT=$(echo "$DAT_ROOT" | envsubst) debian_install_packages() { # List of required packages - local packages=("git" "ruby") + local packages=("git" "ruby" "zsh") local to_install=() # Determine if we need to use sudo @@ -105,11 +105,13 @@ debian_install_packages() { else echo "All required packages are already installed." fi + + chsh -s $(which zsh) } macos_install_packages() { # List of required packages - local packages=("git" "ruby") + local packages=("git" "ruby" "zsh") local to_install=() # Check for Homebrew diff --git a/lib/certbot.rb b/lib/certbot.rb index 32c3b39..836495b 100644 --- a/lib/certbot.rb +++ b/lib/certbot.rb @@ -1,6 +1,5 @@ module Certbot - def self.create_certificate(domain, wildcard = false) command = "/home/artur/.dat/bin/certbot" if wildcard @@ -9,5 +8,4 @@ module Certbot system "sudo #{command} --nginx -d #{domain}" end end - end diff --git a/lib/downloader.rb b/lib/downloader.rb index 6fa1e67..462be6e 100644 --- a/lib/downloader.rb +++ b/lib/downloader.rb @@ -1,21 +1,33 @@ require 'uri' require 'addressable/uri' - +require 'user' +require 'fileutils' +require 'open-uri' module Downloader # use_cache => save in the home and return path to it # forced => download even if the file exists in the cache, saves to chace if use_cache == true def self.get(url, use_cache = true, forced = false) - puts "downloading..." - puts url - - uri = Addressable::URI.parse(url) - path = File.join("#{ENV["HOME"]}/.cache/dat/downloads/", uri.domain, uri.path) + path = File.join(User.cache_path, "downloads", uri.domain, uri.path) #uri = URI.parse(url) #file_name = File.basename(uri.path) - puts "Download path: #{path}" + + + # Ensure the directory exists + dir = File.dirname(path) + FileUtils.mkdir_p(dir) unless Dir.exist?(dir) + + unless File.exist?(path) + puts "File does not exist, downloading..." + URI.open(uri) do |input| + File.open(path, 'wb') do |output| + IO.copy_stream(input, output) + end + end + end + yield path end end \ No newline at end of file diff --git a/lib/local-user/single-user.rb b/lib/local-user/single-user.rb new file mode 100644 index 0000000..d055093 --- /dev/null +++ b/lib/local-user/single-user.rb @@ -0,0 +1,10 @@ + + +module User + + # Make user to be trusted when he use + # the computer locally + def make_local_trusted(user) + File.mkdir_p("/etc/systemd/system/getty@tty1.service.d") + end +end \ No newline at end of file diff --git a/lib/system.rb b/lib/system.rb index 14aee45..28d7f38 100644 --- a/lib/system.rb +++ b/lib/system.rb @@ -1,5 +1,7 @@ +require_relative('system/architecture') module System + def self.detect_os case RUBY_PLATFORM when /darwin/ @@ -29,7 +31,13 @@ module System raise "Operating system not supported" end + ARCH = normalize_architecture_string(arch) + def self.os_info puts os_name end + + def self.arch_to_symbol(arch) + normalize_architecture_string(arch) + end end diff --git a/lib/system/architecture.rb b/lib/system/architecture.rb new file mode 100644 index 0000000..657ac23 --- /dev/null +++ b/lib/system/architecture.rb @@ -0,0 +1,55 @@ +module System + def self.normalize_architecture_string(s) + str = s.to_s.strip.downcase + exact = { + "x86_64" => :x86_64, "amd64" => :x86_64, + "i386" => :x86_32, "i486" => :x86_32, "i586" => :x86_32, "i686" => :x86_32, + + "arm64" => :arm64, "aarch64" => :arm64, + "armhf" => :armv7, "armel" => :armv5, "armv7l" => :armv7, "armv6l" => :armv6, "armv5tel" => :armv5, + + "riscv64" => :riscv64, + + "ppc64el" => :ppc64le, "ppc64le" => :ppc64le, + "ppc64" => :ppc64, "powerpc64" => :ppc64, + "ppc" => :ppc32, "powerpc" => :ppc32, + + "s390x" => :s390x, + + "mips64el" => :mips64el, "mips64" => :mips64, + "mipsel" => :mipsel, "mips" => :mips, + + "loong64" => :loongarch64, "loongarch64" => :loongarch64, + + "sparc64" => :sparc64, + + "alpha" => :alpha, + "hppa" => :hppa, + "ia64" => :ia64, + } + return exact[str] if exact.key?(str) + + return :x86_64 if str.include?("x64") || str.include?("amd64") + return :x86_32 if str =~ /\Ai[3-6]86\z/ || str.include?("x86") + return :arm64 if str.include?("aarch64") || str.include?("arm64") + return :armv7 if str.include?("armv7") + return :armv6 if str.include?("armv6") + return :armv5 if str.include?("armv5") + return :riscv64 if str.include?("riscv64") + return :ppc64le if str.include?("ppc64el") || str.include?("ppc64le") + return :ppc64 if str.include?("ppc64") + return :ppc32 if str.include?("ppc") || str.include?("powerpc") + return :s390x if str.include?("s390x") + return :mips64el if str.include?("mips64el") + return :mips64 if str.include?("mips64") + return :mipsel if str.include?("mipsel") + return :mips if str.start_with?("mips") + return :loongarch64 if str.include?("loong") || str.include?("loongarch") + return :sparc64 if str.include?("sparc64") + return :alpha if str.include?("alpha") + return :hppa if str.include?("hppa") + return :ia64 if str.include?("ia64") + + :unknown + end +end \ No newline at end of file diff --git a/lib/system/debian.rb b/lib/system/debian.rb index 6504a2f..c7803df 100644 --- a/lib/system/debian.rb +++ b/lib/system/debian.rb @@ -1,4 +1,5 @@ require 'open3' +require_relative "utils" module DebianSystem def os_name @@ -10,6 +11,10 @@ module DebianSystem stdout.strip.to_i end + def arch + sh("dpkg --print-architecture") + end + def install(packages) missing_packages = packages.reject { |pkg| package_installed?(pkg) } diff --git a/lib/system/macos.rb b/lib/system/macos.rb index b2a6a22..cc3c9ff 100644 --- a/lib/system/macos.rb +++ b/lib/system/macos.rb @@ -1,10 +1,15 @@ require 'open3' +require_relative "utils" module MacOSSystem def os_name "macOS" end + def arch + sh("sysctl -n hw.machine") + end + def cpus stdout, stderr, status = Open3.capture3("sysctl -n hw.ncpu") stdout.strip.to_i diff --git a/lib/system/utils.rb b/lib/system/utils.rb new file mode 100644 index 0000000..70d98c8 --- /dev/null +++ b/lib/system/utils.rb @@ -0,0 +1,6 @@ +def sh(cmd) + out = `#{cmd} 2>/dev/null`.to_s.strip + out.empty? ? "" : out + rescue + "" +end \ No newline at end of file diff --git a/lib/user.rb b/lib/user.rb index b084396..724436b 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -34,4 +34,8 @@ module User end end + + def self.cache_path + "#{ENV["HOME"]}/.cache/dat/" + end end diff --git a/lib/virtual-machine.rb b/lib/virtual-machine.rb index b27bbcb..44dae19 100644 --- a/lib/virtual-machine.rb +++ b/lib/virtual-machine.rb @@ -1,4 +1,5 @@ require 'downloader' +require 'system' require_relative 'data/resources/iso-images' module VirtualMachine @@ -7,10 +8,44 @@ module VirtualMachine end def self.setup(options) + if options[:name] == nil + options[:name] = options[:distro] + end + + if options[:arch] == nil + options[:arch] = System::ARCH + else + options[:arch] = System.arch_to_symbol(options[:arch]) + end + + puts options + distro = options[:distro] - arch = :arm64 type = :install + arch = options[:arch] url = distro(name, arch, type) - Downloader.get(url) + + 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, 500) + + puts path + puts disk_img_path + end + end + + # size in MB + def self.create_disk_image(path, size) + size_in_bytes = 1024 * 1024 * size + + # Ensure the directory exists + dir = File.dirname(path) + FileUtils.mkdir_p(dir) unless Dir.exist?(dir) + + File.open(path, "wb") do |f| + f.truncate(size_in_bytes) + # f.seek(size_in_bytes - 1) + # f.write("\0") + end end end \ No newline at end of file