From fbe553657d5d2f17ee9b73917cfc1a5f21562ed0 Mon Sep 17 00:00:00 2001 From: bill Date: Thu, 30 Sep 2021 16:35:29 +0800 Subject: [PATCH] fix read state --- Gemfile.lock | 2 +- README.md | 13 ++++++--- Rakefile | 2 +- VERSION | 2 +- lib/vagrant-qemu/action.rb | 28 ++----------------- lib/vagrant-qemu/action/read_state.rb | 26 ++++++++++------- lib/vagrant-qemu/action/run_instance.rb | 26 +++++++++-------- lib/vagrant-qemu/action/terminate_instance.rb | 5 ++-- lib/vagrant-qemu/config.rb | 12 ++++++-- lib/vagrant-qemu/plugin.rb | 12 ++++---- lib/vagrant-qemu/provider.rb | 11 ++------ 11 files changed, 66 insertions(+), 73 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 88dcc78..0fde270 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - vagrant-qemu (0.2.21) + vagrant-qemu (0.2.22) GEM remote: https://rubygems.org/ diff --git a/README.md b/README.md index c04fe08..cef6f75 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This is a [Vagrant](http://www.vagrantup.com) 2.5+ plugin that adds a qemu provider to Vagrant, allowing Vagrant to control and provision machines using qemu. -## Install +## Environment preparation First make sure `qemu` works in your environment. If qemu is not installed yet, ``` @@ -16,11 +16,16 @@ to enable graphical acceleration: ``` brew install knazarov/qemu-virgl/qemu-virgl ``` +If `vagrant` is not installed yet, you should [install it](https://www.vagrantup.com) -## Demo +## Build and install +``` +rake build && vagrant plugin install pkg/vagrant-qemu-0.2.21.gem +``` + +## Run a demo -### Run a sample -Only tested on m1 macbook: +Below is to load and run an Ubuntu desktop, only tested on m1 macbook: ```shell vagrant init billyan2018/devbox \ --box-version 0.1.0 diff --git a/Rakefile b/Rakefile index ff55df2..96635a6 100644 --- a/Rakefile +++ b/Rakefile @@ -17,4 +17,4 @@ Bundler::GemHelper.install_tasks # Install the `spec` task so that we can run tests. # Default task is to run the unit tests -task :default => :spec \ No newline at end of file +## task :default => :spec \ No newline at end of file diff --git a/VERSION b/VERSION index 599028f..109a20f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.21 +0.2.22 diff --git a/lib/vagrant-qemu/action.rb b/lib/vagrant-qemu/action.rb index f627af0..0e7a3ec 100644 --- a/lib/vagrant-qemu/action.rb +++ b/lib/vagrant-qemu/action.rb @@ -31,15 +31,7 @@ def self.action_provision end end - # This action is called to read the SSH info of the machine. The - # resulting state is expected to be put into the `:machine_ssh_info` - # key. - def self.action_read_ssh_info - Vagrant::Action::Builder.new.tap do |b| - b.use ConfigValidate - b.use ReadSSHInfo - end - end + # This action is called to read the state of the machine. The # resulting state is expected to be put into the `:machine_state_id` @@ -54,29 +46,13 @@ def self.action_read_state # This action is called to SSH into the machine. def self.action_ssh Vagrant::Action::Builder.new.tap do |b| - b.use ConfigValidate - b.use Call, IsCreated do |env, b2| - if !env[:result] - b2.use MessageNotCreated - next - end - b2.use SSHExec - end end end def self.action_ssh_run Vagrant::Action::Builder.new.tap do |b| - b.use ConfigValidate - b.use Call, IsCreated do |env, b2| - if !env[:result] - b2.use MessageNotCreated - next - end - b2.use SSHRun - end end end @@ -101,7 +77,7 @@ def self.action_up autoload :IsCreated, action_root.join("is_created") autoload :MessageAlreadyCreated, action_root.join("message_already_created") autoload :MessageNotCreated, action_root.join("message_not_created") - autoload :ReadSSHInfo, action_root.join("read_ssh_info") + # autoload :ReadSSHInfo, action_root.join("read_ssh_info") autoload :ReadState, action_root.join("read_state") autoload :RunInstance, action_root.join("run_instance") autoload :TimedProvision, action_root.join("timed_provision") diff --git a/lib/vagrant-qemu/action/read_state.rb b/lib/vagrant-qemu/action/read_state.rb index 7d50a81..1dae026 100644 --- a/lib/vagrant-qemu/action/read_state.rb +++ b/lib/vagrant-qemu/action/read_state.rb @@ -1,5 +1,5 @@ require "log4r" - +require "json" module VagrantPlugins module Qemu module Action @@ -9,23 +9,29 @@ class ReadState def initialize(app, env) @app = app @logger = Log4r::Logger.new("vagrant_qemu::action::read_state") + @env end def call(env) - env[:machine_state_id] = read_state(env[:machine]) + env[:machine_state_id] = read_state(env) @app.call(env) end - def read_state(machine) - return :not_created if machine.id.nil? - - # Return the state - output = %x{ #{machine.provider_config.script} read-state #{machine.id} } - if $?.to_i > 0 - raise Errors::QemuError, :message => "Failure: #{env[:machine].provider_config.script} read-state #{machine.id}" + def read_state(env) + machine = env[:machine] + pid = machine.id + env[:ui].info("======= #{pid}") + if pid.nil? || !(pid.is_a? Numeric) + :not_created + else + begin + Process.getpgid( pid ) + :created + rescue Errno::ESRCH + :not_created + end end - output.strip end end end diff --git a/lib/vagrant-qemu/action/run_instance.rb b/lib/vagrant-qemu/action/run_instance.rb index 9e2fe16..96ee3e5 100644 --- a/lib/vagrant-qemu/action/run_instance.rb +++ b/lib/vagrant-qemu/action/run_instance.rb @@ -21,10 +21,13 @@ def disk_file end def firmware_location - "/opt/homebrew/share/qemu" + @provider_config.firmware_location || "/opt/homebrew/share/qemu" end def prepare_shell_command(env) + + firmware_path = firmware_location + env[:ui].info("==Firmware: #{firmware_path}") disk_file_location = self.disk_file env[:ui].info("==Disk: #{disk_file_location}") %{ @@ -39,8 +42,8 @@ def prepare_shell_command(env) -display cocoa,gl=es \ -device e1000,netdev=net0 \ -netdev user,id=net0 \ - -drive "if=pflash,format=raw,file=#{firmware_location}/edk2-aarch64-code.fd,readonly=on" \ - -drive "if=pflash,format=raw,file=#{firmware_location}/edk2-arm-vars.fd,discard=on" \ + -drive "if=pflash,format=raw,file=#{firmware_path}/edk2-aarch64-code.fd,readonly=on" \ + -drive "if=pflash,format=raw,file=#{firmware_path}/edk2-arm-vars.fd,discard=on" \ -drive "if=virtio,format=qcow2,file=#{disk_file_location},discard=on" \ -chardev qemu-vdagent,id=spice,name=vdagent,clipboard=on \ -device virtio-serial-pci \ @@ -56,7 +59,7 @@ def call(env) # Get the configs @provider_config = env[:machine].provider_config # Launch! - env[:ui].info(I18n.t("vagrant_qemu.launching_instance")) + env[:ui].info("vagrant_qemu.launching_instance") env[:ui].info(JSON.pretty_generate (env[:machine])) @@ -64,12 +67,13 @@ def call(env) shell_command = prepare_shell_command(env) - output = `#{shell_command}` - if $?.to_i > 0 - raise Errors::QemuError, :message => "Failure with command: #{shell_command}..." - end - - env[:machine].id = output.split(/\s+/)[0] + + env[:machine].id = spawn(shell_command) + + # output = `#{shell_command}` + ## if $?.to_i > 0 + # raise Errors::QemuError, :message => "Failure with command: #{shell_command}..." + #end # Wait for the instance to be ready first env[:metrics]["instance_ready_time"] = Util::Timer.time do @@ -111,7 +115,7 @@ def call(env) @logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}") # Ready and booted! - env[:ui].info(I18n.t("vagrant_qemu.ready")) + env[:ui].info("vagrant_qemu.ready") end # Terminate the instance if we were interrupted diff --git a/lib/vagrant-qemu/action/terminate_instance.rb b/lib/vagrant-qemu/action/terminate_instance.rb index dbcb7b8..98e3c8c 100644 --- a/lib/vagrant-qemu/action/terminate_instance.rb +++ b/lib/vagrant-qemu/action/terminate_instance.rb @@ -12,10 +12,11 @@ def initialize(app, env) def call(env) # Destroy the server and remove the tracking ID + pid = env[:machine].id env[:ui].info(I18n.t("vagrant_qemu.terminating")) - output = %x{ #{env[:machine].provider_config.script} terminate-instance #{env[:machine].id}} + output = %x{ kill -9 #{pid} } if $?.to_i > 0 - raise Errors::QemuError, :message => "Failure: #{env[:machine].provider_config.script} terminate-instance #{env[:machine].id}" + raise Errors::QemuError, :message => "Failure: terminate-instance #{env[:machine].id}" end puts output diff --git a/lib/vagrant-qemu/config.rb b/lib/vagrant-qemu/config.rb index c5bcf27..21b2029 100644 --- a/lib/vagrant-qemu/config.rb +++ b/lib/vagrant-qemu/config.rb @@ -3,11 +3,16 @@ module VagrantPlugins module Qemu class Config < Vagrant.plugin("2", :config) - # The ID of the disk_file to use. + # The disk_file to use. # # @return [String] attr_accessor :disk_file + # The firmware to use. + # + # @return [String] + attr_accessor :firmware_location + # The timeout to wait for an instance to become ready. # # @return [Fixnum] @@ -29,7 +34,8 @@ class Config < Vagrant.plugin("2", :config) attr_accessor :run_args def initialize - @disk_file = UNSET_VALUE + @disk_file = UNSET_VALUE + @firmware_location = UNSET_VALUE @instance_ready_timeout = UNSET_VALUE @user_data = UNSET_VALUE @script = UNSET_VALUE @@ -53,6 +59,8 @@ def finalize! # disk_filemust be nil, since we can't default that @disk_file= nil if @disk_file== UNSET_VALUE + @firmware_location= nil if @firmware_location == UNSET_VALUE + # Set the default timeout for waiting for an instance to be ready @instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE diff --git a/lib/vagrant-qemu/plugin.rb b/lib/vagrant-qemu/plugin.rb index d5e626c..76763cd 100644 --- a/lib/vagrant-qemu/plugin.rb +++ b/lib/vagrant-qemu/plugin.rb @@ -28,7 +28,7 @@ def self.make_provider nm_provider provider(nm_provider) do # Setup logging and i18n setup_logging - # setup_i18n + setup_i18n # Return the provider require_relative "provider" @@ -37,12 +37,12 @@ def self.make_provider nm_provider end make_provider(:qemu) - + make_provider("libvirt") # This initializes the internationalization strings. - ## def self.setup_i18n - # I18n.load_path << File.expand_path("locales/en.yml", Qemu.source_root) - # I18n.reload! - ## end + def self.setup_i18n + I18n.load_path << File.expand_path("locales/en.yml", Qemu.source_root) + I18n.reload! + end # This sets up our log level to be whatever VAGRANT_LOG is. def self.setup_logging diff --git a/lib/vagrant-qemu/provider.rb b/lib/vagrant-qemu/provider.rb index db87234..07b1b4a 100644 --- a/lib/vagrant-qemu/provider.rb +++ b/lib/vagrant-qemu/provider.rb @@ -17,13 +17,6 @@ def action(name) nil end - def ssh_info - # Run a custom action called "read_ssh_info" which does what it - # says and puts the resulting SSH info into the `:machine_ssh_info` - # key in the environment. - env = @machine.action("read_ssh_info") - env[:machine_ssh_info] - end def state # Run a custom action we define called "read_state" which does @@ -34,8 +27,8 @@ def state state_id = env[:machine_state_id] # Get the short and long description - short = I18n.t("vagrant_qemu.states.short_#{state_id}") - long = I18n.t("vagrant_qemu.states.long_#{state_id}") + short = "vagrant_qemu.states.short_#{state_id}" + long = "vagrant_qemu.states.long_#{state_id}" # Return the MachineState object Vagrant::MachineState.new(state_id, short, long)