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).