README.md in libvirt_async-0.1.1 vs README.md in libvirt_async-0.2.0

- old
+ new

@@ -1,9 +1,11 @@ # LibvirtAsync -Libvirt event async implementation. -Libvirt event api implementation on Fibers based on [libvirt-ruby](https://github.com/qwe/libvirt-ruby) and [async](https://github.com/socketry/async) +Libvirt event loop asynchronous implementation on Fibers. +Based on [libvirt-ruby](https://github.com/qwe/libvirt-ruby) and [async](https://github.com/socketry/async). +Allows to receive domain events. +Allows to work with streams in asynchronous mode. ## Installation Add this line to your application's Gemfile: @@ -19,24 +21,136 @@ $ gem install libvirt_async ## Usage +`LibvirtAsync.register_implementations!` must be called once per process before connecting to hypervisor. + +### Receiving domain events + +We can subscribe for event from all hypervisor's domains ```ruby require 'libvirt_async' -LibvirtAsync.use_logger! -LibvirtAsync.logger.level = Logger::Severity::DEBUG # optional for debugging LibvirtAsync.register_implementations! + +connection = Libvirt::open('qemu+tcp://127.0.0.1:16509') + +some_object = Object.new + +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_LIFECYCLE, + ->(connection, domain, event, detail, opaque) { + puts "LIFECYCLE event #{domain.uuid} #{event} #{detail}" + }, + nil, # optional domain, can be omitted + some_object # will be an opaque in callback, can be omitted +) ``` -## Development +Or we can subscribe on particular domain -After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. -You can also run `bin/console` for an interactive prompt that will allow you to experiment. +```ruby +require 'libvirt_async' -To install this gem onto your local machine, run `bundle exec rake install`. -To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). +LibvirtAsync.register_implementations! + +connection = Libvirt::open('qemu+tcp://127.0.0.1:16509') +domain = connection.list_all_domains.first + +some_object = Object.new + +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_LIFECYCLE, + ->(connection, domain, event, detail, opaque) { + puts "LIFECYCLE event #{domain.uuid} #{event} #{detail}" + }, + domain, + some_object # will be an opaque in callback, can be omitted +) +``` + +All available domain events: +```ruby +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_REBOOT, + ->(connection, domain, opaque) { + puts "REBOOT event #{domain.uuid}" + } +) + +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_RTC_CHANGE, + ->(connection, domain, utc_offset, opaque) { + puts "RTC_CHANGE event #{domain.uuid} #{utc_offset}" + } +) + +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_WATCHDOG, + ->(connection, domain, action, opaque) { + puts "WATCHDOG event #{domain.uuid} #{action}" + } +) + +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_IO_ERROR, + ->(connection, domain, src_path, dev_alias, action, opaque) { + puts "IO_ERROR event #{domain.uuid} #{src_path} #{dev_alias} #{action}" + } +) + +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_IO_ERROR_REASON, + ->(connection, domain, src_path, dev_alias, action, opaque) { + puts "IO_ERROR_REASON event #{domain.uuid} #{src_path} #{dev_alias} #{action}" + } +) + +connection.domain_event_register_any( + Libvirt::Connect::DOMAIN_EVENT_ID_GRAPHICS, + ->(connection, domain, phase, local, remote, auth_scheme, subject, opaque) { + puts "GRAPHICS event #{domain.uuid} #{phase} #{local} #{remote} #{auth_scheme} #{subject}" + } +) +``` + +### Taking screenshot + +```ruby +require 'libvirt_async' + +LibvirtAsync.register_implementations! + +connection = Libvirt::open('qemu+tcp://127.0.0.1:16509') +domain = connection.list_all_domains.first + +file = File.new("/screenshots/#{domain.uuid}.pnm", 'wb') +stream = LibvirtAsync::StreamRead.new(connection, file) +mime_type = domain.screenshot(stream.stream, 0) +puts "screenshot saving initiated mime_type=#{mime_type}" + +# will start screenshot saving +stream.call do |success, reason, io| + # this block will be called asynchronously on complete or error + io.close + if success + puts "screenshot saved at #{io.path}" + else + puts "screenshot was not saved: #{reason}" + end +end +``` + +Logging. +```ruby +require 'libvirt_async' + +LibvirtAsync.use_logger! +LibvirtAsync.logger.level = Logger::Severity::DEBUG # for debugging +``` + +Look at [ruby-libvirt Documenation](https://libvirt.org/ruby/documentation.html) for further details. ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/senid231/libvirt_async. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/libvirt_async/blob/master/CODE_OF_CONDUCT.md).