libvirt_rpc/
request.rs

1use ::xdr_codec;
2use std::convert::From;
3
4pub mod generated {
5    //! This module is generated from protocol files.
6    //!
7    //! It follows original naming convention
8    #![allow(non_camel_case_types)]
9    #![allow(dead_code)]
10    #![allow(non_snake_case)]
11    #![allow(unused_assignments)]
12    use ::xdr_codec;
13    use super::{ErrorCode,ErrorDomain};
14
15    include!(concat!(env!("OUT_DIR"), "/virnetprotocol_xdr.rs"));
16    include!(concat!(env!("OUT_DIR"), "/remote_protocol_xdr.rs"));
17
18    impl virNetMessageError {
19        pub fn code(&self) -> ErrorCode {
20            ErrorCode::from(self.code)
21        }
22
23        pub fn domain(&self) -> ErrorDomain {
24            ErrorDomain::from(self.domain)
25        }
26    }
27}
28
29pub trait LibvirtRpc<R: ::std::io::Read> where {
30    const PROCEDURE: ::remote_procedure;
31    type Response: Send + ::xdr_codec::Unpack<R>;
32}
33
34pub use self::generated::remote_procedure;
35pub use self::generated::{virNetMessageStatus,virNetMessageHeader,virNetMessageError};
36
37/// VM instance
38#[derive(Debug,Clone)]
39pub struct Domain(generated::remote_nonnull_domain);
40
41impl Domain {
42    /// positive integer, unique amongst running guest domains on a single host. An inactive domain does not have an ID.
43    pub fn id(&self) -> i32 {
44        self.0.id
45    }
46
47    /// short string, unique amongst all guest domains on a single host, both running and inactive.
48    pub fn name(&self) -> String {
49        self.0.name.0.clone()
50    }
51
52    /// guaranteed to be unique amongst all guest domains on any host.
53    pub fn uuid(&self) -> ::uuid::Uuid {
54        let bytes = self.0.uuid.0;
55        ::uuid::Uuid::from_bytes(&bytes).unwrap()
56    }
57}
58
59impl ::std::default::Default for generated::virNetMessageHeader {
60    fn default() -> Self {
61        generated::virNetMessageHeader {
62            prog: 0x20008086,
63            vers: 1,
64            proc_: 0,
65            type_: generated::virNetMessageType::VIR_NET_CALL,
66            serial: 0,
67            status: generated::virNetMessageStatus::VIR_NET_OK,
68        }
69    }
70}
71
72#[derive(Debug)]
73pub struct LibvirtMessage<P> {
74    pub header: generated::virNetMessageHeader,
75    pub payload: P,
76}
77
78impl<P: xdr_codec::Pack<Out>, Out: xdr_codec::Write> xdr_codec::Pack<Out> for LibvirtMessage<P> {
79    fn pack(&self, out: &mut Out) -> xdr_codec::Result<usize> {
80        let mut sz: usize = 0;
81        sz += try!(self.header.pack(out));
82        sz += try!(self.payload.pack(out));
83        Ok(sz)
84    }
85}
86
87macro_rules! delegate_pack_impl {
88    ($t:ty) => {
89        impl<Out: xdr_codec::Write> xdr_codec::Pack<Out> for $t {
90            fn pack(&self, out: &mut Out) -> xdr_codec::Result<usize> {
91                self.0.pack(out)
92            }
93        }
94    }
95}
96
97macro_rules! delegate_unpack_impl {
98    ($t:ty) => {
99        impl<In: xdr_codec::Read> xdr_codec::Unpack<In> for $t {
100            fn unpack(input: &mut In) -> xdr_codec::Result<(Self, usize)> {
101                let (inner, len) = try!(xdr_codec::Unpack::unpack(input));
102                let mut pkt: $t = unsafe { ::std::mem::zeroed() };
103                pkt.0 = inner;
104                Ok((pkt, len))
105            }
106        }
107
108    }
109}
110
111macro_rules! req {
112    ($name: ident) => {
113        #[derive(Debug)]
114        pub struct $name(());
115        delegate_pack_impl!($name);
116
117        impl $name {
118            pub fn new() -> Self {
119                $name(())
120            }
121        }
122    };
123
124    ($name:ident : $inner:ident { $($f:ident : $t:ty => $e: expr),+ }) => {
125        #[derive(Debug)]
126        pub struct $name($inner);
127        delegate_pack_impl!($name);
128
129        impl $name {
130            pub fn new($( $f: $t,)+) -> Self {
131                let inner = $inner {
132                    $(
133                        $f: $e,
134                    )+
135                };
136                $name(inner)
137            }
138        }
139    };
140
141    ($name:ident : $inner:ident { $($f:ident as $arg:ident : $t:ty => $e: expr),+ }) => {
142        #[derive(Debug)]
143        pub struct $name($inner);
144        delegate_pack_impl!($name);
145
146        impl $name {
147            pub fn new($( $arg: $t,)+) -> Self {
148                let inner = $inner {
149                    $(
150                        $f: $e,
151                    )+
152                };
153                $name(inner)
154            }
155        }
156    };
157
158
159
160    ($name:ident : $inner:ident { $($f: ident => $e: expr),+ }) => {
161        #[derive(Debug)]
162        pub struct $name($inner);
163        delegate_pack_impl!($name);
164
165        impl $name {
166            pub fn new() -> Self {
167                let inner = $inner {
168                    $(
169                        $f: $e,
170                    )+
171                };
172                $name(inner)
173            }
174        }
175    };
176
177
178    ($name:ident : $inner:ident { $($f: ident : $t: ty),+ }) => {
179        #[derive(Debug)]
180        pub struct $name($inner);
181        delegate_pack_impl!($name);
182
183        impl $name {
184            pub fn new($( $f: $t,)+) -> Self {
185                let inner = $inner {
186                    $(
187                        $f,
188                    )+
189                };
190                $name(inner)
191            }
192        }
193    };
194
195    // argument renaming
196    ($name:ident : $inner:ident { $($f: ident as $arg: ident : $t: ty),+ }) => {
197        #[derive(Debug)]
198        pub struct $name($inner);
199        delegate_pack_impl!($name);
200
201        impl $name {
202            pub fn new($( $arg: $t,)+) -> Self {
203                let inner = $inner {
204                    $(
205                        $f: $arg,
206                    )+
207                };
208                $name(inner)
209            }
210        }
211    };
212}
213
214macro_rules! resp {
215    ($name: ident) => {
216        #[derive(Debug)]
217        pub struct $name(());
218        delegate_unpack_impl!($name);
219
220        impl Into<()> for $name {
221            fn into(self) -> () {
222                ()
223            }
224        }
225    };
226
227    ($name: ident : $inner: ty) => {
228        #[derive(Debug)]
229        pub struct $name($inner);
230        delegate_unpack_impl!($name);
231    };
232}
233
234macro_rules! rpc {
235    ($id:path, $req:ident => $resp:ident) => {
236        impl<R: ::std::io::Read> LibvirtRpc<R> for $req {
237            const PROCEDURE: ::remote_procedure = $id;
238            type Response = $resp;
239        }
240    }
241}
242
243req!(NodeGetInfoRequest);
244resp!(NodeGetInfoResponse: generated::remote_node_get_info_ret);
245rpc!(remote_procedure::REMOTE_PROC_NODE_GET_INFO, NodeGetInfoRequest => NodeGetInfoResponse);
246
247#[derive(Debug)]
248pub struct NodeInfo(NodeGetInfoResponse);
249
250impl From<NodeGetInfoResponse> for NodeInfo {
251    fn from(resp: NodeGetInfoResponse) -> Self {
252        NodeInfo(resp)
253    }
254}
255
256impl NodeInfo {
257    pub fn get_memory(&self) -> u64 {
258        (self.0).0.memory
259    }
260
261    /// the number of active CPUs
262    pub fn get_cpus(&self) -> i32 {
263        (self.0).0.cpus
264    }
265
266    /// number of cores per socket, total number of processors in case of unusual NUMA topology
267    pub fn get_cores(&self) -> i32 {
268        (self.0).0.cores
269    }
270
271    /// number of CPU sockets per node if nodes > 1, 1 in case of unusual NUMA topology
272    pub fn get_sockets(&self) -> i32 {
273        (self.0).0.sockets
274    }
275
276    /// the number of NUMA cell, 1 for unusual NUMA topologies or uniform memory access;
277    /// check capabilities XML for the actual NUMA topology
278    pub fn get_nodes(&self) -> i32 {
279        (self.0).0.nodes
280    }
281}
282
283/// Auth list request must be the first request
284req!(AuthListRequest);
285resp!(AuthListResponse: generated::remote_auth_list_ret);
286rpc!(remote_procedure::REMOTE_PROC_AUTH_LIST, AuthListRequest => AuthListResponse);
287
288/// Connect open request
289use generated::remote_connect_open_args;
290req!(ConnectOpenRequest: remote_connect_open_args {
291     name => Some(generated::remote_nonnull_string("qemu:///system".to_string())),
292     flags => 0
293});
294resp!(ConnectOpenResponse);
295rpc!(remote_procedure::REMOTE_PROC_CONNECT_OPEN, ConnectOpenRequest => ConnectOpenResponse);
296
297/// Version request
298req!(GetLibVersionRequest);
299resp!(GetLibVersionResponse: generated::remote_connect_get_lib_version_ret);
300rpc!(remote_procedure::REMOTE_PROC_CONNECT_GET_LIB_VERSION, GetLibVersionRequest => GetLibVersionResponse);
301
302impl GetLibVersionResponse {
303    pub fn version(&self) -> (u32, u32, u32) {
304        let mut version = (self.0).lib_ver;
305
306        let major = version / 1000000;
307        version %= 1000000;
308        let minor = version / 1000;
309        version %= 1000;
310        let micro = version;
311
312        (major as u32, minor as u32, micro as u32)
313    }
314}
315
316
317use generated::remote_connect_list_defined_domains_args;
318req!(ListDefinedDomainsRequest: remote_connect_list_defined_domains_args {
319    maxnames => generated::REMOTE_DOMAIN_LIST_MAX as i32
320});
321resp!(ListDefinedDomainsResponse: generated::remote_connect_list_defined_domains_ret);
322rpc!(remote_procedure::REMOTE_PROC_CONNECT_LIST_DEFINED_DOMAINS, ListDefinedDomainsRequest => ListDefinedDomainsResponse);
323
324impl ListDefinedDomainsResponse {
325    pub fn get_domain_names(&self) -> Vec<String> {
326        let mut names = Vec::new();
327        for name in &(self.0).names {
328            names.push(name.0.to_string());
329        }
330        names
331    }
332}
333
334use generated::remote_domain_define_xml_flags_args;
335req!(DomainDefineXMLRequest: remote_domain_define_xml_flags_args {
336    xml: &str => generated::remote_nonnull_string(xml.to_string()),
337    flags: u32 => flags
338});
339
340resp!(DomainDefineXMLResponse: generated::remote_domain_define_xml_flags_ret);
341rpc!(remote_procedure::REMOTE_PROC_DOMAIN_DEFINE_XML_FLAGS, DomainDefineXMLRequest => DomainDefineXMLResponse);
342
343impl ::std::convert::Into<Domain> for DomainDefineXMLResponse {
344    fn into(self) -> Domain {
345        Domain (self.0.dom)
346    }
347}
348
349impl DomainDefineXMLResponse {
350    pub fn get_domain(&self) -> Domain {
351        Domain ((self.0).dom.clone())
352    }
353}
354
355use generated::remote_domain_shutdown_args;
356req!(DomainShutdownRequest: remote_domain_shutdown_args {
357    dom: &Domain => dom.0.to_owned()
358});
359
360resp!(DomainShutdownResponse);
361rpc!(remote_procedure::REMOTE_PROC_DOMAIN_SHUTDOWN, DomainShutdownRequest => DomainShutdownResponse);
362
363use generated::remote_domain_reboot_args;
364req!(DomainRebootRequest: remote_domain_reboot_args {
365    dom: &Domain => dom.0.to_owned(),
366    flags: u32 => flags
367});
368
369resp!(DomainRebootResponse);
370rpc!(remote_procedure::REMOTE_PROC_DOMAIN_REBOOT, DomainRebootRequest => DomainRebootResponse);
371
372use generated::remote_domain_reset_args;
373req!(DomainResetRequest: remote_domain_reset_args {
374    dom: &Domain => dom.0.to_owned(),
375    flags: u32 => flags
376});
377
378resp!(DomainResetResponse);
379rpc!(remote_procedure::REMOTE_PROC_DOMAIN_RESET, DomainResetRequest => DomainResetResponse);
380
381use generated::remote_domain_undefine_flags_args;
382req!(DomainUndefineRequest: remote_domain_undefine_flags_args {
383    dom: Domain => dom.0,
384    flags: u32 => flags
385});
386
387resp!(DomainUndefineResponse);
388rpc!(remote_procedure::REMOTE_PROC_DOMAIN_UNDEFINE, DomainUndefineRequest => DomainUndefineResponse);
389
390#[allow(non_snake_case)]
391pub mod DomainCreateFlags {
392    bitflags! {
393        pub flags DomainCreateFlags: u32 {
394            /// Launch guest in paused state
395            const START_PAUSED = 1,
396            /// Automatically kill guest when virConnectPtr is closed
397            const START_AUTODESTROY = 2,
398            /// Avoid file system cache pollution
399            const START_BYPASS_CACHE = 4,
400            /// Boot, discarding any managed save
401            const START_FORCE_BOOT = 8,
402            /// Validate the XML document against schema
403            const START_VALIDATE = 16,
404        }
405    }
406}
407
408use generated::remote_domain_create_with_flags_args;
409req!(DomainCreateRequest: remote_domain_create_with_flags_args {
410    dom: Domain => dom.0,
411    flags: DomainCreateFlags::DomainCreateFlags => flags.bits()
412});
413
414resp!(DomainCreateResponse: generated::remote_domain_create_with_flags_ret);
415rpc!(remote_procedure::REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS, DomainCreateRequest => DomainCreateResponse);
416
417impl ::std::convert::Into<Domain> for DomainCreateResponse {
418    fn into(self) -> Domain {
419        Domain (self.0.dom)
420    }
421}
422
423impl DomainCreateResponse {
424    pub fn get_domain(&self) -> Domain {
425        Domain ((self.0).dom.clone())
426    }
427}
428
429#[allow(non_snake_case)]
430pub mod DomainDestroyFlags {
431    bitflags! {
432        pub flags DomainDestroyFlags: u32 {
433            /// Default behavior - could lead to data loss!!
434            const DESTROY_DEFAULT = 0,
435            /// Only SIGTERM, no SIGKILL
436            const DESTROY_GRACEFUL = 1,
437        }
438    }
439}
440use generated::remote_domain_destroy_flags_args;
441req!(DomainDestroyRequest: remote_domain_destroy_flags_args {
442    dom: &Domain => dom.0.clone(),
443    flags: DomainDestroyFlags::DomainDestroyFlags => flags.bits()
444});
445
446resp!(DomainDestroyResponse);
447rpc!(remote_procedure::REMOTE_PROC_DOMAIN_DESTROY_FLAGS, DomainDestroyRequest => DomainDestroyResponse);
448
449#[allow(non_snake_case)]
450pub mod ListAllDomainsFlags {
451    bitflags! {
452        pub flags ListAllDomainsFlags: u32 {
453            const DOMAINS_ACTIVE	=	1,
454            const DOMAINS_INACTIVE	=	2,
455            const DOMAINS_PERSISTENT	=	4,
456            const DOMAINS_TRANSIENT	=	8,
457            const DOMAINS_RUNNING	=	16,
458            const DOMAINS_PAUSED	=	32,
459            const DOMAINS_SHUTOFF	=	64,
460            const DOMAINS_OTHER	=	128,
461            const DOMAINS_MANAGEDSAVE	=	256,
462            const DOMAINS_NO_MANAGEDSAVE	=	512,
463            const DOMAINS_AUTOSTART	=	1024,
464            const DOMAINS_NO_AUTOSTART	=	2048,
465            const DOMAINS_HAS_SNAPSHOT	=	4096,
466            const DOMAINS_NO_SNAPSHOT	=	8192,
467        }
468    }
469}
470
471#[derive(Debug)]
472pub struct ListAllDomainsRequest(generated::remote_connect_list_all_domains_args);
473
474impl ListAllDomainsRequest {
475    pub fn new(flags: ListAllDomainsFlags::ListAllDomainsFlags) -> Self {
476        let payload = generated::remote_connect_list_all_domains_args {
477            need_results: 1,
478            flags: flags.bits(),
479        };
480        ListAllDomainsRequest(payload)
481    }
482}
483
484delegate_pack_impl!(ListAllDomainsRequest);
485
486#[derive(Debug)]
487pub struct ListAllDomainsResponse(generated::remote_connect_list_all_domains_ret);
488
489impl ::std::convert::Into<Vec<Domain>> for ListAllDomainsResponse {
490    fn into(self) -> Vec<Domain> {
491        let mut domains = Vec::new();
492        for dom in &(self.0).domains {
493            domains.push(Domain(dom.clone()))
494        }
495        domains
496    }
497}
498
499delegate_unpack_impl!(ListAllDomainsResponse);
500
501impl<R: ::std::io::Read> LibvirtRpc<R> for ListAllDomainsRequest {
502    const PROCEDURE: ::remote_procedure = remote_procedure::REMOTE_PROC_CONNECT_LIST_ALL_DOMAINS;
503    type Response = ListAllDomainsResponse;
504}
505
506/*
507use generated::remote_connect_domain_event_register_any_args;
508req!(DomainEventRegisterAnyRequest: remote_connect_domain_event_register_any_args {
509    eventID as event: i32
510});
511
512resp!(DomainEventRegisterAnyResponse);
513rpc!(DomainEventRegisterAnyRequest => DomainEventRegisterAnyResponse);
514*/
515
516use generated::remote_connect_domain_event_callback_register_any_args;
517req!(DomainEventCallbackRegisterAnyRequest: remote_connect_domain_event_callback_register_any_args {
518    eventID as event: i32 => event,
519    dom as domain: Option<&Domain> => domain.map(|dom| Box::new(dom.0.clone()))
520});
521
522resp!(DomainEventCallbackRegisterAnyResponse: generated::remote_connect_domain_event_callback_register_any_ret);
523rpc!(remote_procedure::REMOTE_PROC_CONNECT_DOMAIN_EVENT_CALLBACK_REGISTER_ANY, DomainEventCallbackRegisterAnyRequest => DomainEventCallbackRegisterAnyResponse);
524
525impl DomainEventCallbackRegisterAnyResponse {
526    pub fn callback_id(&self) -> i32 {
527        self.0.callbackID
528    }
529}
530
531use generated::remote_domain_lookup_by_uuid_args;
532req!(DomainLookupByUuidRequest: remote_domain_lookup_by_uuid_args {
533    uuid: &::uuid::Uuid => generated::remote_uuid(uuid.as_bytes().clone())
534});
535
536resp!(DomainLookupByUuidResponse: generated::remote_domain_lookup_by_uuid_ret);
537rpc!(remote_procedure::REMOTE_PROC_DOMAIN_LOOKUP_BY_UUID, DomainLookupByUuidRequest => DomainLookupByUuidResponse);
538
539impl DomainLookupByUuidResponse {
540    pub fn domain(&self) -> Domain {
541        Domain ((self.0).dom.clone())
542    }
543}
544
545/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventCrashedDetailType */
546#[derive(Debug)]
547#[repr(u8)]
548pub enum EventCrashedDetailType {
549    /// Guest was panicked
550    Panicked = 0,
551}
552
553/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventStartedDetailType */
554#[derive(Debug)]
555#[repr(u8)]
556pub enum EventStartedDetailType {
557    /// Normal startup from boot
558    Booted = 0,
559    /// Incoming migration from another host
560    Migrated = 1,
561    /// Restored from a state file
562    Restored = 2,
563    /// Restored from snapshot
564    FromSnapshot = 3,
565    /// Started due to wakeup event
566    Wakeup = 4,
567}
568
569/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventStoppedDetailType */
570#[derive(Debug)]
571#[repr(u8)]
572pub enum EventStoppedDetailType {
573    /// Normal shutdown
574    Shutdown = 0,
575    /// Forced poweroff from host
576    Destroyed = 1,
577    /// Guest crashed
578    Crashed = 2,
579    /// Migrated off to another host
580    Migrated = 3,
581    /// Saved to a state file
582    Saved = 4,
583    /// Host emulator/mgmt failed
584    Failed = 5,
585    /// Offline snapshot loaded
586    FromSnapshot = 6,
587}
588
589/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventSuspendedDetailType */
590#[derive(Debug)]
591#[repr(u8)]
592pub enum EventSuspendedDetailType {
593    /// Normal suspend due to admin pause
594    Paused = 0,
595    /// Suspended for offline migration
596    Migrated = 1,
597    /// Suspended due to a disk I/O error
598    IoError = 2,
599    /// Suspended due to a watchdog firing
600    Watchdog = 3,
601    /// Restored from paused state file
602    Restored = 4,
603    /// Restored from paused snapshot
604    FromSnapshot = 5,
605    /// Suspended after failure during libvirt API call
606    ApiError = 6,
607    /// Suspended for post-copy migration
608    PostCopy = 7,
609    /// Suspended after failed post-copy
610    PostCopyFailed = 8,
611}
612
613/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventResumedDetailType */
614#[derive(Debug)]
615#[repr(u8)]
616pub enum EventResumedDetailType {
617    /// Normal resume due to admin unpause
618    Unpaused = 0,
619    /// Resumed for completion of migration
620    Migrated = 1,
621    /// Resumed from snapshot
622    FromSnapshot = 2,
623    /// Resumed, but migration is still running in post-copy mode
624    PostCopy = 3,
625}
626
627/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventDefinedDetailType */
628#[derive(Debug)]
629#[repr(u8)]
630pub enum EventDefinedDetailType {
631    /// Newly created config file
632    Added =	0,
633    /// Changed config file	
634    Updated = 1,
635    /// Domain was renamed
636    Renamed = 2,
637    /// Config was restored from a snapshot
638    FromSnapshot = 3,
639}
640
641/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventUndefinedDetailType */
642#[derive(Debug)]
643#[repr(u8)]
644pub enum EventUndefinedDetailType {
645    /// Deleted the config file
646    Removed = 0,
647    /// Domain was renamed
648    Renamed = 1,
649}
650
651/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventShutdownDetailType */
652#[derive(Debug)]
653#[repr(u8)]
654pub enum EventShutdownDetailType {
655    /// Guest finished shutdown sequence
656    Finished = 0, 
657}
658
659/* http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventPMSuspendedDetailType */
660#[derive(Debug)]
661#[repr(u8)]
662pub enum EventPmSuspendedDetailType {
663    /// Guest was PM suspended to memory
664    Memory = 0,
665    /// Guest was PM suspended to disk
666    Disk = 1,
667}
668
669pub trait DomainEvent where Self: Sized {
670    type From: Into<Self> + ::xdr_codec::Unpack<::std::io::Cursor<::bytes::BytesMut>>;
671}
672
673#[derive(Debug)]
674pub enum DomainEventInfo {
675    Defined(EventDefinedDetailType),
676    Undefined(EventUndefinedDetailType),
677    Started(EventStartedDetailType),
678    Suspended(EventSuspendedDetailType),
679    Stopped(EventStoppedDetailType),
680    Shutdown(EventShutdownDetailType),
681    Resumed(EventResumedDetailType),
682    Crashed(EventCrashedDetailType),
683    PmSuspended(EventPmSuspendedDetailType),
684    Other(i32, i32)
685}
686
687#[derive(Debug)]
688pub struct DomainLifecycleEvent {
689    pub domain: Domain,
690    pub info: DomainEventInfo,
691}
692
693/* virDomainEventType: http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventType */
694const VIR_DOMAIN_EVENT_DEFINED: i32	=	0;
695const VIR_DOMAIN_EVENT_UNDEFINED: i32	=	1;
696const VIR_DOMAIN_EVENT_STARTED: i32	=	2;
697const VIR_DOMAIN_EVENT_SUSPENDED: i32	=	3;
698const VIR_DOMAIN_EVENT_RESUMED: i32	=	4;
699const VIR_DOMAIN_EVENT_STOPPED: i32	=	5;
700const VIR_DOMAIN_EVENT_SHUTDOWN: i32	=	6;
701const VIR_DOMAIN_EVENT_PMSUSPENDED: i32	=	7;
702const VIR_DOMAIN_EVENT_CRASHED: i32	=	8;
703
704impl DomainEvent for DomainLifecycleEvent {
705    type From = generated::remote_domain_event_callback_lifecycle_msg;
706}
707
708impl From<generated::remote_domain_event_callback_lifecycle_msg> for DomainLifecycleEvent {
709    fn from(ev: generated::remote_domain_event_callback_lifecycle_msg) -> Self {
710        use ::std::mem;
711        let info = match ev.msg.event {
712            VIR_DOMAIN_EVENT_DEFINED => {
713                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
714                DomainEventInfo::Defined(detail)
715            }
716            VIR_DOMAIN_EVENT_UNDEFINED => {
717                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
718                DomainEventInfo::Undefined(detail)
719            }
720            VIR_DOMAIN_EVENT_STARTED => {
721                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
722                DomainEventInfo::Started(detail)
723            }
724            VIR_DOMAIN_EVENT_SUSPENDED => {
725                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
726                DomainEventInfo::Suspended(detail)
727            }
728            VIR_DOMAIN_EVENT_STOPPED => {
729                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
730                DomainEventInfo::Stopped(detail)
731            }
732            VIR_DOMAIN_EVENT_RESUMED => {
733                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
734                DomainEventInfo::Resumed(detail)
735            }
736            VIR_DOMAIN_EVENT_SHUTDOWN => {
737                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
738                DomainEventInfo::Shutdown(detail)
739            }
740            VIR_DOMAIN_EVENT_CRASHED => {
741                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
742                DomainEventInfo::Crashed(detail)
743            }
744            VIR_DOMAIN_EVENT_PMSUSPENDED => {
745                let detail = unsafe { mem::transmute(ev.msg.detail as u8) };
746                DomainEventInfo::PmSuspended(detail)
747            }
748            i => {
749                DomainEventInfo::Other(i, ev.msg.detail)
750            }
751        };
752        let domain = Domain(ev.msg.dom);
753        DomainLifecycleEvent { domain, info }
754    }
755}
756
757#[derive(Debug)]
758pub struct DomainRebootEvent {
759    pub domain: Domain,
760}
761
762impl DomainEvent for DomainRebootEvent {
763    type From = generated::remote_domain_event_callback_reboot_msg;
764}
765
766impl From<generated::remote_domain_event_callback_reboot_msg> for DomainRebootEvent {
767    fn from(ev: generated::remote_domain_event_callback_reboot_msg) -> Self {
768        let domain = Domain(ev.msg.dom);
769        DomainRebootEvent { domain }
770    }
771}
772
773#[derive(Debug,Copy,Clone)]
774#[repr(i32)]
775pub enum DomainBlockJobType {
776    Unknown = 0,
777    /// Block pull (virDomainBlockPull, or virDomainBlockRebase without flags), job ends on completion
778    Pull = 1,
779    /// Block Copy (virDomainBlockCopy, or virDomainBlockRebase with flags), job exists as long as mirroring is active
780    Copy = 2,
781    /// Block Commit (virDomainBlockCommit without flags), job ends on completion
782    Commit = 3,
783    /// Active Block Commit (virDomainBlockCommit with flags), job exists as long as sync is active
784    ActiveCommit = 4,
785}
786
787#[derive(Debug,Copy,Clone)]
788#[repr(i32)]
789pub enum DomainBlockJobStatus {
790    Completed = 0,
791    Failed = 1,
792    Canceled = 2,
793    Ready = 3,
794}
795
796#[derive(Debug)]
797pub struct DomainBlockJobInfo {
798    type_: DomainBlockJobType,
799    status: DomainBlockJobStatus,
800}
801
802impl DomainBlockJobInfo {
803    pub fn get_type(&self) -> DomainBlockJobType {
804        self.type_
805    }
806
807    pub fn get_status(&self) -> DomainBlockJobStatus {
808        self.status
809    }
810}
811
812#[derive(Debug)]
813pub struct DomainBlockJobEvent {
814    pub domain: Domain,
815    pub info: DomainBlockJobInfo,
816}
817
818impl From<generated::remote_domain_event_callback_block_job_msg> for DomainBlockJobEvent {
819    fn from(msg: generated::remote_domain_event_callback_block_job_msg) -> Self {
820        let msg = msg.msg;
821        let dom = Domain(msg.dom);
822        let type_ = unsafe { ::std::mem::transmute(msg.type_) };
823        let status = unsafe { ::std::mem::transmute(msg.status) };
824        let info = DomainBlockJobInfo { type_, status };
825        DomainBlockJobEvent { domain: dom, info: info }
826    }
827}
828
829impl DomainEvent for DomainBlockJobEvent {
830    type From = generated::remote_domain_event_callback_block_job_msg;
831}
832
833// http://libvirt.org/html/libvirt-libvirt-domain.html#virDomainEventID
834#[derive(Debug,Copy,Clone)]
835pub enum DomainEventId {
836    Lifecycle,
837    Reboot,
838    RtcChange,
839    Watchdog,
840    IoError,
841    Graphics,
842    IoErrorReason,
843    ControlError,
844    BlockJob,
845    DiskChange,
846    TrayChange,
847    PmWakeup,
848    PmSuspend,
849    BalloonChange,
850    PmSuspendDisk,
851    DeviceRemoved,
852    BlockJob2,
853    Tunable,
854    AgentLifecycle,
855    DeviceAdded,
856    MigrationIteration,
857    JobCompleted,
858    DeviceRemovalFailed,
859    MetadataChanged,
860    BlockThreshold,
861}
862
863impl DomainEventId {
864    pub fn to_procedure(&self) -> remote_procedure {
865        use self::DomainEventId::*;
866        use remote_procedure::*;
867        match *self {
868            Lifecycle => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_LIFECYCLE,
869            Reboot => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_REBOOT,
870            RtcChange => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_RTC_CHANGE,
871            Watchdog => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WATCHDOG,
872            IoError => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR,
873            Graphics => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_GRAPHICS,
874            IoErrorReason => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR_REASON,
875            ControlError => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CONTROL_ERROR,
876            BlockJob => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BLOCK_JOB,
877            DiskChange => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DISK_CHANGE,
878            TrayChange => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TRAY_CHANGE,
879            PmWakeup => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMWAKEUP,
880            PmSuspend => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND,
881            BalloonChange => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE,
882            PmSuspendDisk => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK,
883            DeviceRemoved => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED,
884            DeviceAdded => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED,
885            Tunable => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE,
886            AgentLifecycle => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE,
887            BlockJob2 => REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2,
888            MigrationIteration => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION,
889            JobCompleted => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_JOB_COMPLETED,
890            DeviceRemovalFailed => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED,
891            MetadataChanged => REMOTE_PROC_DOMAIN_EVENT_CALLBACK_METADATA_CHANGE,
892            BlockThreshold => REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD,
893        }
894    }
895
896    pub fn from_procedure(proc_: remote_procedure) -> Option<Self> {
897        use self::DomainEventId::*;
898        use remote_procedure::*;
899
900        match proc_ {
901            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_LIFECYCLE => Some(Lifecycle),
902            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_REBOOT => Some(Reboot),
903            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_RTC_CHANGE => Some(RtcChange),
904            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WATCHDOG => Some(Watchdog),
905            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR => Some(IoError),
906            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_GRAPHICS => Some(Graphics),
907            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_IO_ERROR_REASON => Some(IoErrorReason),
908            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CONTROL_ERROR => Some(ControlError),
909            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BLOCK_JOB => Some(BlockJob),
910            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DISK_CHANGE => Some(DiskChange),
911            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TRAY_CHANGE => Some(TrayChange),
912            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMWAKEUP => Some(PmWakeup),
913            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND => Some(PmSuspend),
914            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE => Some(BalloonChange),
915            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK => Some(PmSuspendDisk),
916            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED => Some(DeviceRemoved),
917            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED => Some(DeviceAdded),
918            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_TUNABLE => Some(Tunable),
919            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE => Some(AgentLifecycle),
920            REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2 => Some(BlockJob2),
921            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION => Some(MigrationIteration),
922            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_JOB_COMPLETED => Some(JobCompleted),
923            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVAL_FAILED => Some(DeviceRemovalFailed),
924            REMOTE_PROC_DOMAIN_EVENT_CALLBACK_METADATA_CHANGE => Some(MetadataChanged),
925            REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD => Some(BlockThreshold),
926            /* TODO: add all */
927            _ => None,
928        }
929    }
930}
931
932// http://libvirt.org/html/libvirt-libvirt-storage.html#virConnectListAllStoragePoolsFlags
933#[allow(non_snake_case)]
934pub mod ListAllStoragePoolsFlags {
935    bitflags! {
936        pub flags ListAllStoragePoolsFlags: u32 {
937            const LIST_STORAGE_POOLS_INACTIVE	=	1,
938            const LIST_STORAGE_POOLS_ACTIVE	=	2,
939            const LIST_STORAGE_POOLS_PERSISTENT	=	4,
940            const LIST_STORAGE_POOLS_TRANSIENT	=	8,
941            const LIST_STORAGE_POOLS_AUTOSTART	=	16,
942            const LIST_STORAGE_POOLS_NO_AUTOSTART	=	32,
943            // List pools by type
944            const LIST_STORAGE_POOLS_DIR	=	64,
945            const LIST_STORAGE_POOLS_FS	=	128,
946            const LIST_STORAGE_POOLS_NETFS	=	256,
947            const LIST_STORAGE_POOLS_LOGICAL	=	512,
948            const LIST_STORAGE_POOLS_DISK	=	1024,
949            const LIST_STORAGE_POOLS_ISCSI	=	2048,
950            const LIST_STORAGE_POOLS_SCSI	=	4096,
951            const LIST_STORAGE_POOLS_MPATH	=	8192,
952            const LIST_STORAGE_POOLS_RBD	=	16384,
953            const LIST_STORAGE_POOLS_SHEEPDOG	=	32768,
954            const LIST_STORAGE_POOLS_GLUSTER	=	65536,
955            const LIST_STORAGE_POOLS_ZFS	=	131072,
956            const LIST_STORAGE_POOLS_VSTORAGE = 262144,
957        }
958    }
959}
960
961#[derive(Debug)]
962pub struct StoragePool(generated::remote_nonnull_storage_pool);
963
964impl From<generated::remote_nonnull_storage_pool> for StoragePool {
965    fn from(inner: generated::remote_nonnull_storage_pool) -> Self {
966        StoragePool(inner)
967    }
968}
969
970#[derive(Debug)]
971pub struct ListAllStoragePoolsRequest(generated::remote_connect_list_all_storage_pools_args);
972delegate_pack_impl!(ListAllStoragePoolsRequest);
973
974impl ListAllStoragePoolsRequest {
975    pub fn new(flags: ListAllStoragePoolsFlags::ListAllStoragePoolsFlags) -> Self {
976        let pl = generated::remote_connect_list_all_storage_pools_args {
977            need_results: 1,
978            flags: flags.bits(),
979        };
980        ListAllStoragePoolsRequest(pl)
981    }
982}
983
984#[derive(Debug)]
985pub struct ListAllStoragePoolsResponse(generated::remote_connect_list_all_storage_pools_ret);
986delegate_unpack_impl!(ListAllStoragePoolsResponse);
987
988impl Into<Vec<StoragePool>> for ListAllStoragePoolsResponse {
989    fn into(self) -> Vec<StoragePool> {
990        let mut result = Vec::new();
991        for pool in self.0.pools {
992            result.push(pool.into());
993        }
994        result
995    }
996}
997
998rpc!(remote_procedure::REMOTE_PROC_CONNECT_LIST_ALL_STORAGE_POOLS, ListAllStoragePoolsRequest => ListAllStoragePoolsResponse);
999
1000use generated::remote_storage_pool_define_xml_args;
1001req!(StoragePoolDefineXmlRequest: remote_storage_pool_define_xml_args {
1002    xml: &str => generated::remote_nonnull_string(xml.to_string()),
1003    flags: u32 => flags
1004});
1005
1006resp!(StoragePoolDefineXmlResponse: generated::remote_storage_pool_define_xml_ret);
1007rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_DEFINE_XML, StoragePoolDefineXmlRequest => StoragePoolDefineXmlResponse);
1008
1009impl Into<StoragePool> for StoragePoolDefineXmlResponse {
1010    fn into(self) -> StoragePool {
1011        StoragePool(self.0.pool)
1012    }
1013}
1014
1015use generated::remote_storage_pool_lookup_by_uuid_args;
1016req!(StoragePoolLookupByUuidRequest: remote_storage_pool_lookup_by_uuid_args {
1017    uuid: &::uuid::Uuid => generated::remote_uuid(uuid.as_bytes().clone())
1018});
1019
1020resp!(StoragePoolLookupByUuidResponse: generated::remote_storage_pool_lookup_by_uuid_ret);
1021rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_UUID, StoragePoolLookupByUuidRequest => StoragePoolLookupByUuidResponse);
1022
1023impl Into<StoragePool> for StoragePoolLookupByUuidResponse {
1024    fn into(self) -> StoragePool {
1025        StoragePool(self.0.pool)
1026    }
1027}
1028
1029use generated::remote_storage_pool_lookup_by_name_args;
1030req!(StoragePoolLookupByNameRequest: remote_storage_pool_lookup_by_name_args {
1031    name: &str => generated::remote_nonnull_string(name.to_string())
1032});
1033
1034resp!(StoragePoolLookupByNameResponse: generated::remote_storage_pool_lookup_by_name_ret);
1035rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_NAME, StoragePoolLookupByNameRequest => StoragePoolLookupByNameResponse);
1036
1037impl Into<StoragePool> for StoragePoolLookupByNameResponse {
1038    fn into(self) -> StoragePool {
1039        StoragePool(self.0.pool)
1040    }
1041}
1042
1043use generated::remote_storage_pool_create_args;
1044req!(StoragePoolCreateRequest: remote_storage_pool_create_args {
1045    pool: &StoragePool => pool.0.clone(),
1046    flags: u32 => flags
1047});
1048resp!(StoragePoolCreateResponse);
1049rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_CREATE, StoragePoolCreateRequest => StoragePoolCreateResponse);
1050
1051use generated::remote_storage_pool_destroy_args;
1052req!(StoragePoolDestroyRequest: remote_storage_pool_destroy_args {
1053    pool: &StoragePool => pool.0.clone()
1054});
1055resp!(StoragePoolDestroyResponse);
1056rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_DESTROY, StoragePoolDestroyRequest => StoragePoolDestroyResponse);
1057
1058use generated::remote_storage_pool_undefine_args;
1059req!(StoragePoolUndefineRequest: remote_storage_pool_undefine_args {
1060    pool: StoragePool => pool.0
1061});
1062resp!(StoragePoolUndefineResponse);
1063rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_UNDEFINE, StoragePoolUndefineRequest => StoragePoolUndefineResponse);
1064
1065use generated::remote_storage_pool_get_info_args;
1066req!(StoragePoolGetInfoRequest: remote_storage_pool_get_info_args {
1067    pool: &StoragePool => pool.0.clone()
1068});
1069resp!(StoragePoolGetInfoResponse: generated::remote_storage_pool_get_info_ret);
1070rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_GET_INFO, StoragePoolGetInfoRequest => StoragePoolGetInfoResponse);
1071
1072#[derive(Debug)]
1073pub struct StoragePoolInfo(StoragePoolGetInfoResponse);
1074
1075impl From<StoragePoolGetInfoResponse> for StoragePoolInfo {
1076    fn from(v: StoragePoolGetInfoResponse) -> Self {
1077        StoragePoolInfo(v)
1078    }
1079}
1080
1081impl StoragePoolInfo {
1082    pub fn get_capacity(&self) -> u64 {
1083        (self.0).0.capacity
1084    }
1085
1086    pub fn get_allocation(&self) -> u64 {
1087        (self.0).0.allocation
1088    }
1089
1090    pub fn get_available(&self) -> u64 {
1091        (self.0).0.available
1092    }
1093}
1094
1095use generated::remote_storage_pool_list_volumes_args;
1096req!(StoragePoolListVolumesRequest: remote_storage_pool_list_volumes_args {
1097    pool: &StoragePool => pool.0.clone(),
1098    maxnames: i32 => maxnames
1099});
1100resp!(StoragePoolListVolumesResponse: generated::remote_storage_pool_list_volumes_ret);
1101rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_LIST_VOLUMES, StoragePoolListVolumesRequest => StoragePoolListVolumesResponse);
1102
1103impl Into<Vec<String>> for StoragePoolListVolumesResponse {
1104    fn into(self) -> Vec<String> {
1105        self.0.names.into_iter().map(|nns| nns.0).collect()
1106    }
1107}
1108
1109#[derive(Debug)]
1110pub struct Volume(generated::remote_nonnull_storage_vol);
1111
1112impl Volume {
1113    pub fn name(&self) -> &str {
1114        &self.0.name.0
1115    }
1116
1117    pub fn key(&self) -> &str {
1118        &self.0.key.0
1119    }
1120
1121    pub fn pool_name(&self) -> &str {
1122        &self.0.pool.0
1123    }
1124}
1125
1126impl From<generated::remote_nonnull_storage_vol> for Volume {
1127    fn from(inner: generated::remote_nonnull_storage_vol) -> Self {
1128        Volume(inner)
1129    }
1130}
1131
1132use generated::remote_storage_pool_list_all_volumes_args;
1133req!(StoragePoolListAllVolumesRequest: remote_storage_pool_list_all_volumes_args {
1134    pool: &StoragePool => pool.0.clone(),
1135    need_results: i32 => need_results,
1136    flags: u32 => flags
1137});
1138resp!(StoragePoolListAllVolumesResponse: generated::remote_storage_pool_list_all_volumes_ret);
1139rpc!(remote_procedure::REMOTE_PROC_STORAGE_POOL_LIST_ALL_VOLUMES, StoragePoolListAllVolumesRequest => StoragePoolListAllVolumesResponse);
1140
1141impl Into<Vec<Volume>> for StoragePoolListAllVolumesResponse {
1142    fn into(self) -> Vec<Volume> {
1143        self.0.vols.into_iter().map(|vol| vol.into()).collect()
1144    }
1145}
1146
1147#[allow(non_snake_case)]
1148pub mod StorageVolCreateXmlFlags {
1149    bitflags! {
1150        pub flags StorageVolCreateXmlFlags: u32 {
1151            const VOL_CREATE_PREALLOC_METADATA = 1,
1152            /// perform a btrfs lightweight copy
1153            const VOL_CREATE_REFLINK = 2,
1154        }
1155    }
1156}
1157
1158use generated::remote_storage_vol_create_xml_args;
1159req!(StorageVolCreateXmlRequest: remote_storage_vol_create_xml_args {
1160    pool: &StoragePool => pool.0.clone(),
1161    xml: &str => generated::remote_nonnull_string(xml.to_owned()),
1162    flags: StorageVolCreateXmlFlags::StorageVolCreateXmlFlags => flags.bits()
1163});
1164resp!(StorageVolCreateXmlResponse: generated::remote_storage_vol_create_xml_ret);
1165rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_CREATE_XML, StorageVolCreateXmlRequest => StorageVolCreateXmlResponse);
1166
1167impl Into<Volume> for StorageVolCreateXmlResponse {
1168    fn into(self) -> Volume {
1169        self.0.vol.into()
1170    }
1171}
1172
1173use generated::remote_storage_vol_create_xml_from_args;
1174req!(StorageVolCreateXmlFromRequest: remote_storage_vol_create_xml_from_args {
1175    pool: &StoragePool => pool.0.clone(),
1176    xml: &str => generated::remote_nonnull_string(xml.to_owned()),
1177    clonevol: &Volume => clonevol.0.clone(),
1178    flags: StorageVolCreateXmlFlags::StorageVolCreateXmlFlags => flags.bits()
1179});
1180resp!(StorageVolCreateXmlFromResponse: generated::remote_storage_vol_create_xml_from_ret);
1181rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_CREATE_XML_FROM, StorageVolCreateXmlFromRequest => StorageVolCreateXmlFromResponse);
1182
1183impl Into<Volume> for StorageVolCreateXmlFromResponse {
1184    fn into(self) -> Volume {
1185        self.0.vol.into()
1186    }
1187}
1188
1189use generated::remote_storage_vol_delete_args;
1190req!(StorageVolDeleteRequest: remote_storage_vol_delete_args {
1191    vol: Volume => vol.0.clone(),
1192    flags: u32 => flags
1193});
1194resp!(StorageVolDeleteResponse);
1195rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_DELETE, StorageVolDeleteRequest => StorageVolDeleteResponse);
1196
1197use generated::remote_storage_vol_wipe_args;
1198req!(StorageVolWipeRequest: remote_storage_vol_wipe_args {
1199    vol: &Volume => vol.0.clone(),
1200    flags: u32 => flags
1201});
1202resp!(StorageVolWipeResponse);
1203rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_WIPE, StorageVolWipeRequest => StorageVolWipeResponse);
1204
1205use generated::remote_storage_vol_lookup_by_name_args;
1206req!(StorageVolLookupByNameRequest: remote_storage_vol_lookup_by_name_args {
1207    pool: &StoragePool => pool.0.clone(),
1208    name: &str => generated::remote_nonnull_string(name.to_owned())
1209});
1210resp!(StorageVolLookupByNameResponse: generated::remote_storage_vol_lookup_by_name_ret);
1211rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_LOOKUP_BY_NAME, StorageVolLookupByNameRequest => StorageVolLookupByNameResponse);
1212
1213impl Into<Volume> for StorageVolLookupByNameResponse {
1214    fn into(self) -> Volume {
1215        Volume(self.0.vol)
1216    }
1217}
1218
1219#[allow(non_snake_case)]
1220pub mod StorageVolResizeFlags {
1221    bitflags! {
1222        pub flags StorageVolResizeFlags: u32 {
1223            /// force allocation of new size
1224            const RESIZE_ALLOCATE = 1,
1225            /// size is relative to current
1226            const RESIZE_DELTA = 2,
1227            /// allow decrease in capacity
1228            const RESIZE_SHRINK = 4,
1229        }
1230    }
1231}
1232
1233use generated::remote_storage_vol_resize_args;
1234req!(StorageVolResizeRequest: remote_storage_vol_resize_args {
1235    vol: &Volume => vol.0.clone(),
1236    capacity: u64 => capacity,
1237    flags: StorageVolResizeFlags::StorageVolResizeFlags => flags.bits()
1238});
1239resp!(StorageVolResizeResponse);
1240rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_RESIZE, StorageVolResizeRequest => StorageVolResizeResponse);
1241
1242use generated::remote_storage_vol_get_info_args;
1243req!(StorageVolGetInfoRequest: remote_storage_vol_get_info_args {
1244    vol: &Volume => vol.0.clone()
1245});
1246resp!(StorageVolGetInfoResponse: generated::remote_storage_vol_get_info_ret);
1247rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_GET_INFO, StorageVolGetInfoRequest => StorageVolGetInfoResponse);
1248
1249impl Into<VolumeInfo> for StorageVolGetInfoResponse {
1250    fn into(self) -> VolumeInfo {
1251        VolumeInfo(self.0)
1252    }
1253}
1254
1255#[derive(Debug)]
1256pub struct VolumeInfo(generated::remote_storage_vol_get_info_ret);
1257
1258impl VolumeInfo {
1259    pub fn get_capacity(&self) -> u64 {
1260        (self.0).capacity
1261    }
1262
1263    pub fn get_allocation(&self) -> u64 {
1264        (self.0).allocation
1265    }
1266}
1267
1268use generated::remote_domain_screenshot_args;
1269req!(DomainScreenshotRequest: remote_domain_screenshot_args {
1270    dom: &Domain => dom.0.clone(),
1271    screen: u32 => screen,
1272    flags: u32 => flags
1273});
1274resp!(DomainScreenshotResponse: generated::remote_domain_screenshot_ret);
1275rpc!(remote_procedure::REMOTE_PROC_DOMAIN_SCREENSHOT, DomainScreenshotRequest => DomainScreenshotResponse);
1276
1277impl Into<Option<String>> for DomainScreenshotResponse {
1278    fn into(self) -> Option<String> {
1279        self.0.mime.map(|s| s.0)
1280    }
1281}
1282
1283use generated::remote_storage_vol_download_args;
1284req!(StorageVolDownloadRequest: remote_storage_vol_download_args {
1285    vol: &Volume => vol.0.clone(),
1286    offset: u64 => offset,
1287    length: u64 => length,
1288    flags: u32 => flags
1289});
1290resp!(StorageVolDownloadResponse);
1291rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_DOWNLOAD, StorageVolDownloadRequest => StorageVolDownloadResponse);
1292
1293use generated::remote_storage_vol_upload_args;
1294req!(StorageVolUploadRequest: remote_storage_vol_upload_args {
1295    vol: &Volume => vol.0.clone(),
1296    offset: u64 => offset,
1297    length: u64 => length,
1298    flags: u32 => flags
1299});
1300resp!(StorageVolUploadResponse);
1301rpc!(remote_procedure::REMOTE_PROC_STORAGE_VOL_UPLOAD, StorageVolUploadRequest => StorageVolUploadResponse);
1302
1303use generated::remote_domain_get_info_args;
1304req!(DomainGetInfoRequest: remote_domain_get_info_args {
1305    dom: &Domain => dom.0.clone()
1306});
1307resp!(DomainGetInfoResponse: generated::remote_domain_get_info_ret);
1308rpc!(remote_procedure::REMOTE_PROC_DOMAIN_GET_INFO, DomainGetInfoRequest => DomainGetInfoResponse);
1309
1310use generated::remote_domain_attach_device_flags_args;
1311req!(DomainAttachDeviceRequest: remote_domain_attach_device_flags_args {
1312    dom: &Domain => dom.0.clone(),
1313    xml: &str => generated::remote_nonnull_string(xml.to_owned()),
1314    flags: DomainModificationImpact::DomainModificationImpact => flags.bits()
1315});
1316resp!(DomainAttachDeviceResponse);
1317rpc!(remote_procedure::REMOTE_PROC_DOMAIN_ATTACH_DEVICE_FLAGS, DomainAttachDeviceRequest => DomainAttachDeviceResponse);
1318
1319use generated::remote_domain_detach_device_flags_args;
1320req!(DomainDetachDeviceRequest: remote_domain_detach_device_flags_args {
1321    dom: &Domain => dom.0.clone(),
1322    xml: &str => generated::remote_nonnull_string(xml.to_owned()),
1323    flags: DomainModificationImpact::DomainModificationImpact => flags.bits()
1324});
1325resp!(DomainDetachDeviceResponse);
1326rpc!(remote_procedure::REMOTE_PROC_DOMAIN_DETACH_DEVICE_FLAGS, DomainDetachDeviceRequest => DomainDetachDeviceResponse);
1327
1328use generated::remote_domain_update_device_flags_args;
1329req!(DomainUpdateDeviceRequest: remote_domain_update_device_flags_args {
1330    dom: &Domain => dom.0.clone(),
1331    xml: &str => generated::remote_nonnull_string(xml.to_owned()),
1332    flags: DomainModificationImpact::DomainModificationImpact => flags.bits()
1333});
1334resp!(DomainUpdateDeviceResponse);
1335rpc!(remote_procedure::REMOTE_PROC_DOMAIN_UPDATE_DEVICE_FLAGS, DomainUpdateDeviceRequest => DomainUpdateDeviceResponse);
1336
1337use generated::remote_domain_set_memory_flags_args;
1338req!(DomainSetMemoryRequest: remote_domain_set_memory_flags_args {
1339    dom: &Domain => dom.0.clone(),
1340    memory: u64 => memory,
1341    flags: DomainModificationImpact::MemoryModificationImpact => flags.bits()
1342});
1343resp!(DomainSetMemoryResponse);
1344rpc!(remote_procedure::REMOTE_PROC_DOMAIN_SET_MEMORY_FLAGS, DomainSetMemoryRequest => DomainSetMemoryResponse);
1345
1346/*
1347use generated::remote_domain_get_max_memory_args;
1348req!(DomainGetMaxMemoryRequest: remote_domain_get_max_memory_args {
1349    dom: &Domain => dom.0.clone()
1350});
1351resp!(DomainGetMaxMemoryResponse: generated::remote_domain_get_max_memory_ret);
1352rpc!(DomainGetMaxMemoryRequest => DomainGetMaxMemoryResponse);
1353*/
1354
1355use generated::remote_domain_get_memory_parameters_args;
1356req!(DomainGetMemoryParametersRequest: remote_domain_get_memory_parameters_args {
1357    dom: &Domain => dom.0.clone(),
1358    nparams: u32 => nparams as i32, 
1359    flags: DomainModificationImpact::DomainModificationImpact => flags.bits()
1360});
1361resp!(DomainGetMemoryParametersResponse: generated::remote_domain_get_memory_parameters_ret);
1362rpc!(remote_procedure::REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS, DomainGetMemoryParametersRequest => DomainGetMemoryParametersResponse);
1363
1364impl DomainGetMemoryParametersResponse {
1365    pub fn count(&self) -> u32 {
1366        self.0.nparams as u32
1367    }
1368
1369    pub fn parameters(self) -> Vec<TypedParam> {
1370        self.0.params.into_iter().map(TypedParam::from).collect()
1371    }
1372}
1373
1374use generated::remote_domain_set_vcpus_flags_args;
1375req!(DomainSetVcpusRequest: remote_domain_set_vcpus_flags_args {
1376    dom: &Domain => dom.0.clone(),
1377    nvcpus: u32 => nvcpus,
1378    flags: DomainModificationImpact::VcpuModificationImpact => flags.bits()
1379});
1380resp!(DomainSetVcpusResponse);
1381rpc!(remote_procedure::REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS, DomainSetVcpusRequest => DomainSetVcpusResponse);
1382
1383use generated::remote_domain_get_vcpus_flags_args;
1384req!(DomainGetVcpusRequest: remote_domain_get_vcpus_flags_args {
1385    dom: &Domain => dom.0.clone(),
1386    flags: DomainModificationImpact::VcpuModificationImpact => flags.bits()
1387});
1388resp!(DomainGetVcpusResponse: generated::remote_domain_get_vcpus_flags_ret);
1389rpc!(remote_procedure::REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS, DomainGetVcpusRequest => DomainGetVcpusResponse);
1390
1391impl Into<u32> for DomainGetVcpusResponse {
1392    fn into(self) -> u32 {
1393        (self.0).num as u32
1394    }
1395}
1396
1397use generated::remote_domain_get_autostart_args;
1398req!(DomainGetAutoStartRequest: remote_domain_get_autostart_args {
1399    dom: &Domain => dom.0.clone()
1400});
1401resp!(DomainGetAutoStartResponse: generated::remote_domain_get_autostart_ret);
1402rpc!(remote_procedure::REMOTE_PROC_DOMAIN_GET_AUTOSTART, DomainGetAutoStartRequest => DomainGetAutoStartResponse);
1403
1404impl Into<bool> for DomainGetAutoStartResponse {
1405    fn into(self) -> bool {
1406        (self.0).autostart == 1
1407    }
1408}
1409
1410use generated::remote_domain_set_autostart_args;
1411req!(DomainSetAutoStartRequest: remote_domain_set_autostart_args {
1412    dom: &Domain => dom.0.clone(),
1413    autostart: bool => if autostart { 1 } else { 0 }
1414});
1415resp!(DomainSetAutoStartResponse);
1416rpc!(remote_procedure::REMOTE_PROC_DOMAIN_SET_AUTOSTART, DomainSetAutoStartRequest => DomainSetAutoStartResponse);
1417
1418use generated::remote_domain_send_key_args;
1419req!(DomainSendKeyRequest: remote_domain_send_key_args {
1420    dom: &Domain => dom.0.clone(),
1421    codeset: u32 => codeset,
1422    holdtime: u32 => holdtime,
1423    keycodes: Vec<u32> => keycodes,
1424    flags: u32 => flags
1425});
1426resp!(DomainSendKeyResponse);
1427rpc!(remote_procedure::REMOTE_PROC_DOMAIN_SEND_KEY, DomainSendKeyRequest => DomainSendKeyResponse);
1428
1429use generated::remote_domain_get_xml_desc_args;
1430req!(DomainGetXmlDescRequest: remote_domain_get_xml_desc_args {
1431    dom: &Domain => dom.0.clone(),
1432    flags: DomainXmlFlags::DomainXmlFlags => flags.bits()
1433});
1434resp!(DomainGetXmlDescResponse: generated::remote_domain_get_xml_desc_ret);
1435rpc!(remote_procedure::REMOTE_PROC_DOMAIN_GET_XML_DESC, DomainGetXmlDescRequest => DomainGetXmlDescResponse);
1436
1437impl Into<String> for DomainGetXmlDescResponse {
1438    fn into(self) -> String {
1439        (self.0).xml.0
1440    }
1441}
1442
1443#[allow(non_snake_case)]
1444pub mod DomainXmlFlags {
1445    bitflags! {
1446        pub flags DomainXmlFlags: u32 {
1447            /// dump security sensitive information too
1448            const SECURE	= 1,
1449            /// dump inactive domain information
1450            const INACTIVE	=	2,
1451            /// update guest CPU requirements according to host CPU
1452            const UPDATE_CPU	=	4,
1453            /// dump XML suitable for migration
1454            const MIGRATABLE	=	8,
1455        }
1456    }
1457}
1458
1459#[allow(non_snake_case)]
1460pub mod DomainModificationImpact {
1461    bitflags! {
1462        pub flags DomainModificationImpact: u32 {
1463            /// Affect current domain state.
1464            const AFFECT_CURRENT = 0,
1465
1466            /// Affect running domain state.
1467            const AFFECT_LIVE = 1,
1468
1469            /// Affect persistent domain state.
1470            const AFFECT_CONFIG = 2,
1471        }
1472    }
1473
1474    bitflags! {
1475        pub flags MemoryModificationImpact: u32 {
1476            const MEM_CURRENT = 0, // AFFECT_CURRENT, // as u32,
1477
1478            const MEM_LIVE = 1, // AFFECT_LIVE as u32,
1479
1480            const MEM_CONFIG = 2, // AFFECT_CONFIG as u32,
1481
1482            /// affect max. value
1483            const MEM_MAXIMUM = 4,
1484        }
1485    }
1486
1487    bitflags! {
1488        pub flags VcpuModificationImpact: u32 {
1489            const VCPU_CURRENT = 0, // AFFECT_CURRENT, // as u32,
1490
1491            const VCPU_LIVE = 1, // AFFECT_LIVE as u32,
1492
1493            const VCPU_CONFIG = 2, // AFFECT_CONFIG as u32,
1494
1495            /// affect max. value
1496            const VCPU_MAXIMUM = 4,
1497
1498            // modify state of the cpu in the guest
1499            const VCPU_GUEST = 8,
1500
1501            const VCPU_HOTPLUGGABLE = 16,
1502        }
1503    }
1504}
1505
1506#[allow(non_snake_case)]
1507pub mod DomainMigrateFlags {
1508    bitflags! {
1509        pub flags DomainMigrateFlags: u32 {
1510            /// Do not pause the domain during migration. The domain's memory will
1511            /// be transferred to the destination host while the domain is running.
1512            /// The migration may never converge if the domain is changing its memory
1513            /// faster then it can be transferred. The domain can be manually paused
1514            /// anytime during migration using virDomainSuspend.
1515            const VIR_MIGRATE_LIVE	=	1,
1516            /// Tell the source libvirtd to connect directly to the destination host.
1517            /// Without this flag the client (e.g., virsh) connects to both hosts and controls the migration process.
1518            /// In peer-to-peer mode, the source libvirtd controls the migration by calling the destination daemon directly.
1519            const VIR_MIGRATE_PEER2PEER	=	2,
1520            /// Tunnel migration data over libvirtd connection. Without this flag the source hypervisor sends migration data
1521            /// directly to the destination hypervisor. This flag can only be used when VIR_MIGRATE_PEER2PEER is set as well.
1522            /// Note the less-common spelling that we're stuck with: VIR_MIGRATE_TUNNELLED should be VIR_MIGRATE_TUNNELED.
1523            const VIR_MIGRATE_TUNNELLED	=	4,
1524            /// Define the domain as persistent on the destination host after successful migration.
1525            /// If the domain was persistent on the source host and VIR_MIGRATE_UNDEFINE_SOURCE is not used, it will end up persistent on both hosts.
1526            const VIR_MIGRATE_PERSIST_DEST	=	8,
1527            /// Undefine the domain on the source host once migration successfully finishes.
1528            const VIR_MIGRATE_UNDEFINE_SOURCE	=	16,
1529            /// Leave the domain suspended on the destination host. virDomainResume (on the virDomainPtr returned by the migration API)
1530            /// has to be called explicitly to resume domain's virtual CPUs.
1531            const VIR_MIGRATE_PAUSED	=	32,
1532            /// Migrate full disk images in addition to domain's memory.
1533            /// By default only non-shared non-readonly disk images are transferred.
1534            /// The VIR_MIGRATE_PARAM_MIGRATE_DISKS parameter can be used to specify which disks should be migrated.
1535            /// This flag and VIR_MIGRATE_NON_SHARED_INC are mutually exclusive.
1536            const VIR_MIGRATE_NON_SHARED_DISK	=	64,
1537            /// Migrate disk images in addition to domain's memory.
1538            /// This is similar to VIR_MIGRATE_NON_SHARED_DISK, but only the top level of each disk's backing chain is copied.
1539            /// That is, the rest of the backing chain is expected to be present on the destination and to be exactly the
1540            /// same as on the source host. This flag and VIR_MIGRATE_NON_SHARED_DISK are mutually exclusive.
1541            const VIR_MIGRATE_NON_SHARED_INC	=	128,
1542            /// Protect against domain configuration changes during the migration process.
1543            /// This flag is used automatically when both sides support it.
1544            /// Explicitly setting this flag will cause migration to fail if either the source or the destination does not support it.
1545            const VIR_MIGRATE_CHANGE_PROTECTION	=	256,
1546            /// Force migration even if it is considered unsafe.
1547            /// In some cases libvirt may refuse to migrate the domain because doing so may lead to potential problems
1548            /// such as data corruption, and thus the migration is considered unsafe.
1549            /// For a QEMU domain this may happen if the domain uses disks without explicitly setting cache mode to "none".
1550            /// Migrating such domains is unsafe unless the disk images are stored on coherent clustered filesystem, such as GFS2 or GPFS.
1551            const VIR_MIGRATE_UNSAFE	=	512,
1552            /// Migrate a domain definition without starting the domain on the destination and without stopping it on the source host.
1553            /// Offline migration requires VIR_MIGRATE_PERSIST_DEST to be set. Offline migration may not copy disk storage or any other
1554            /// file based storage (such as UEFI variables).
1555            const VIR_MIGRATE_OFFLINE	=	1024,
1556            /// Compress migration data. The compression methods can be specified using VIR_MIGRATE_PARAM_COMPRESSION.
1557            /// A hypervisor default method will be used if this parameter is omitted.
1558            /// Individual compression methods can be tuned via their specific VIR_MIGRATE_PARAM_COMPRESSION_* parameters.
1559            const VIR_MIGRATE_COMPRESSED	=	2048,
1560            /// Cancel migration if a soft error (such as I/O error) happens during migration.
1561            const VIR_MIGRATE_ABORT_ON_ERROR	=	4096,
1562            /// Enable algorithms that ensure a live migration will eventually converge.
1563            /// This usually means the domain will be slowed down to make sure it does not change its memory faster
1564            /// than a hypervisor can transfer the changed memory to the destination host.
1565            /// VIR_MIGRATE_PARAM_AUTO_CONVERGE_* parameters can be used to tune the algorithm.
1566            const VIR_MIGRATE_AUTO_CONVERGE	=	8192,
1567            /// This flag can be used with RDMA migration (i.e., when VIR_MIGRATE_PARAM_URI starts with "rdma://") to
1568            /// tell the hypervisor to pin all domain's memory at once before migration starts rather then letting it
1569            /// pin memory pages as needed. This means that all memory pages belonging to the domain will be locked in
1570            /// host's memory and the host will not be allowed to swap them out.
1571            /// For QEMU/KVM this requires hard_limit memory tuning element (in the domain XML) to be used and set to
1572            /// the maximum memory configured for the domain plus any memory consumed by the QEMU process itself.
1573            /// Beware of setting the memory limit too high (and thus allowing the domain to lock most of the host's memory).
1574            /// Doing so may be dangerous to both the domain and the host itself since the host's kernel may run out of memory.
1575            const VIR_MIGRATE_RDMA_PIN_ALL	=	16384,
1576            /// Setting the VIR_MIGRATE_POSTCOPY flag tells libvirt to enable post-copy migration.
1577            /// However, the migration will start normally and virDomainMigrateStartPostCopy needs to be called to switch it into the post-copy mode.
1578            /// See virDomainMigrateStartPostCopy for more details.
1579            const VIR_MIGRATE_POSTCOPY	=	32768,
1580            /// Setting the VIR_MIGRATE_TLS flag will cause the migration to attempt to use the TLS environment configured
1581            /// by the hypervisor in order to perform the migration. If incorrectly configured on either source or destination, the migration will fail.
1582            const VIR_MIGRATE_TLS	=	65536,
1583        }
1584    }
1585}
1586
1587use generated::remote_domain_migrate_perform3_params_args;
1588req!(MigratePerformRequest: remote_domain_migrate_perform3_params_args {
1589    dom: &Domain => dom.0.clone(),
1590    dconnuri: Option<&str> => dconnuri.map(|uri| generated::remote_nonnull_string(uri.to_string())),
1591    params: Vec<MigrationParam> => params.into_iter().map(|mp| {
1592        let tp: TypedParam = mp.into();
1593        tp.into()
1594    }).collect(),
1595    cookie_in: Vec<u8> => cookie_in,
1596    flags: DomainMigrateFlags::DomainMigrateFlags => flags.bits()
1597});
1598resp!(MigratePerformResponse: generated::remote_domain_migrate_perform3_params_ret);
1599rpc!(remote_procedure::REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3_PARAMS, MigratePerformRequest => MigratePerformResponse);
1600
1601/*
1602use generated::remote_domain_migrate_begin3_params_args;
1603req!(MigrateBeginRequest: remote_domain_migrate_begin3_params_args {
1604    dom: &Domain => dom.0.clone(),
1605    params: Vec<MigrationParam> => params.into_iter().map(|mp| {
1606        let tp: TypedParam = mp.into();
1607        tp.into()
1608    }).collect(),
1609    flags: DomainMigrateFlags::DomainMigrateFlags => flags.bits()
1610});
1611resp!(MigrateBeginResponse: generated::remote_domain_migrate_begin3_params_ret);
1612rpc!(MigrateBeginRequest => MigrateBeginResponse);
1613*/
1614#[derive(Debug)]
1615pub enum MigrationParam {
1616    /// URI to use for initiating domain migration. It takes a hypervisor specific format. The
1617    /// uri_transports element of the hypervisor capabilities XML includes details
1618    /// of the supported URI schemes. When omitted libvirt will auto-generate
1619    /// suitable default URI. It is typically only necessary to specify this URI if
1620    /// the destination host has multiple interfaces and a specific interface is
1621    /// required to transmit migration data.
1622    /// 
1623    /// This filed may not be used when VIR_MIGRATE_TUNNELLED flag is set.
1624    Uri(String),
1625    /// the name to be used for the domain on the
1626    /// destination host. Omitting this parameter keeps
1627    /// the domain name the same. This field is only allowed to be used with
1628    /// hypervisors that support domain renaming during migration.
1629    DestinationName(String),
1630    /// the new configuration to be used for the
1631    /// domain on the destination host. The configuration
1632    /// must include an identical set of virtual devices, to ensure a stable guest
1633    /// ABI across migration. Only parameters related to host side configuration
1634    /// can be changed in the XML. Hypervisors which support this field will forbid
1635    /// migration if the provided XML would cause a change in the guest ABI. This
1636    /// field cannot be used to rename the domain during migration (use
1637    /// VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). Domain name in the
1638    /// destination XML must match the original domain name.
1639    ///
1640    /// Omitting this parameter keeps the original domain configuration. Using this
1641    /// field with hypervisors that do not support changing domain configuration
1642    /// during migration will result in a failure.
1643    DestinationXml(String),
1644    /// the new persistent configuration to be used
1645    /// for the domain on the destination host.
1646    /// This field cannot be used to rename the domain during migration (use
1647    /// VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). Domain name in the
1648    /// destination XML must match the original domain name.
1649    ///
1650    /// Omitting this parameter keeps the original domain persistent configuration.
1651    /// Using this field with hypervisors that do not support changing domain
1652    /// configuration during migration will result in a failure.
1653    PersistentXml(String),
1654    ///   the maximum bandwidth (in MiB/s) that will
1655    /// be used for migration. If set to 0 or omitted,
1656    /// libvirt will choose a suitable default. Some hypervisors do not support this
1657    /// feature and will return an error if this field is used and is not 0.
1658    Bandwidth(u64),
1659    /// URI to use for migrating client's connection
1660    /// to domain's graphical console. If specified, the
1661    /// client will be asked to automatically reconnect using these parameters
1662    /// instead of the automatically computed ones. This can be useful if, e.g., the
1663    /// client does not have a direct access to the network virtualization hosts are
1664    /// connected to and needs to connect through a proxy. The URI is formed as
1665    /// follows: protocol://hostname[:port]/[?parameters]
1666    /// where protocol is either "spice" or "vnc" and parameters is a list of
1667    /// protocol specific parameters separated by '&'. Currently recognized
1668    /// parameters are "tlsPort" and "tlsSubject". For example, spice://target.host.com:1234/?tlsPort=4567
1669    GraphicsUri(String),
1670    /// The listen address that hypervisor on the
1671    /// destination side should bind to for incoming migration. Both IPv4 and IPv6
1672    /// addresses are accepted as well as hostnames (the resolving is done on
1673    /// destination). Some hypervisors do not support this feature and will return
1674    /// an error if this field is used.
1675    ListenAddress(String),
1676    /// The multiple values that list
1677    /// the block devices to be migrated. At the moment this is only supported
1678    /// by the QEMU driver but not for the tunnelled migration.
1679    MigrateDisks(String),
1680    /// virDomainMigrate* params field: port that destination server should use
1681    /// for incoming disks migration. If set to 0 or
1682    /// omitted, libvirt will choose a suitable default. At the moment this is only
1683    /// supported by the QEMU driver.
1684    DisksPort(i32),
1685    /// virDomainMigrate* params multiple field: name of the method used to
1686    /// compress migration traffic. Supported compression methods: xbzrle, mt.
1687    /// The parameter may be specified multiple times if more than one method
1688    /// should be used.
1689    Compression(String),
1690    /// the level of compression for multithread
1691    /// compression. Accepted values are in range 0-9.
1692    /// 0 is no compression, 1 is maximum speed and 9 is maximum compression.
1693    CompressionLevel(i32),
1694    /// the number of compression threads for
1695    /// multithread compression
1696    CompressionThreads(i32),
1697    /// the number of decompression threads for
1698    /// multithread compression
1699    DecompressionThreads(i32),
1700    /// the size of page cache for xbzrle compression
1701    CompressionXbzrleCache(u64),
1702    /// the initial percentage guest CPUs are
1703    /// throttled to when auto-convergence decides migration is not converging.
1704    AutoConvergeInitial(i32),
1705    /// the increment added to
1706    /// VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL whenever the hypervisor decides
1707    /// the current rate is not enough to ensure convergence of the migration.
1708    AutoConvergeIncrement(i32),
1709}
1710
1711impl Into<TypedParam> for MigrationParam {
1712    fn into(self) -> TypedParam {
1713        match self {
1714            MigrationParam::Uri(ref s) => TypedParam::string("migrate_uri", s),
1715            MigrationParam::DestinationName(ref s) => TypedParam::string("destination_name", s),
1716            MigrationParam::DestinationXml(ref s) => TypedParam::string("destination_xml", s),
1717            MigrationParam::PersistentXml(ref s) => TypedParam::string("persistent_xml", s),
1718            MigrationParam::Bandwidth(ref i) => TypedParam::ulonglong("bandwidth", *i),
1719            MigrationParam::GraphicsUri(ref s) => TypedParam::string("graphics_uri", s),
1720            MigrationParam::ListenAddress(ref s) => TypedParam::string("listen_address", s),
1721            MigrationParam::MigrateDisks(ref s) => TypedParam::string("migrate_disks", s),
1722            MigrationParam::DisksPort(ref i) => TypedParam::int("disks_port", *i),
1723            MigrationParam::Compression(ref s) => TypedParam::string("compression", s),
1724            MigrationParam::CompressionLevel(ref i) => TypedParam::int("compression.mt.level", *i),
1725            MigrationParam::CompressionThreads(ref i) => TypedParam::int("compression.mt.threads", *i),
1726            MigrationParam::DecompressionThreads(ref i) => TypedParam::int("compression.mt.dthreads", *i),
1727            MigrationParam::CompressionXbzrleCache(ref i) => TypedParam::ulonglong("compression.xbzrle.cache", *i),
1728            MigrationParam::AutoConvergeInitial(ref i) => TypedParam::int("auto_converge.initial", *i),
1729            MigrationParam::AutoConvergeIncrement(ref i) => TypedParam::int("auto_converge.increment", *i),
1730        }
1731    }
1732}
1733
1734#[derive(Debug)]
1735pub struct TypedParam(generated::remote_typed_param);
1736
1737impl TypedParam {
1738    fn string(name: &str, value: &str) -> Self {
1739        TypedParam(generated::remote_typed_param {
1740            field: generated::remote_nonnull_string(name.to_string()),
1741            value: generated::remote_typed_param_value::Const7(generated::remote_nonnull_string(value.to_string())),
1742        })
1743    }
1744
1745    fn ulonglong(name: &str, value: u64) -> Self {
1746        TypedParam(generated::remote_typed_param {
1747            field: generated::remote_nonnull_string(name.to_string()),
1748            value: generated::remote_typed_param_value::Const4(value),
1749        })
1750    }
1751
1752    fn int(name: &str, value: i32) -> Self {
1753        TypedParam(generated::remote_typed_param {
1754            field: generated::remote_nonnull_string(name.to_string()),
1755            value: generated::remote_typed_param_value::Const1(value),
1756        })
1757    }
1758    /* TODO: more */
1759}
1760
1761impl Into<generated::remote_typed_param> for TypedParam {
1762    fn into(self) -> generated::remote_typed_param {
1763        self.0
1764    }
1765}
1766
1767impl From<generated::remote_typed_param> for TypedParam {
1768    fn from(p: generated::remote_typed_param) -> Self {
1769        TypedParam(p)
1770    }
1771}
1772
1773#[derive(Debug)]
1774pub struct DomainInfo(DomainGetInfoResponse);
1775
1776impl DomainInfo {
1777    pub fn get_state(&self) -> DomainState {
1778        DomainState::from((self.0).0.state as u8)
1779    }
1780
1781    pub fn get_max_mem(&self) -> u64 {
1782        (self.0).0.maxMem
1783    }
1784
1785    pub fn get_num_cpus(&self) -> u32 {
1786        (self.0).0.nrVirtCpu as u32
1787    }
1788}
1789
1790impl From<DomainGetInfoResponse> for DomainInfo {
1791    fn from(resp: DomainGetInfoResponse) -> Self {
1792        DomainInfo(resp)
1793    }
1794}
1795
1796#[derive(Debug)]
1797#[repr(u8)]
1798pub enum DomainState {
1799    /// no state
1800    NoState = 0,
1801    /// the domain is running
1802    Running = 1,
1803    /// the domain is blocked on resource
1804    Blocked = 2,
1805    /// the domain is paused by user
1806    Paused = 3,
1807    /// the domain is being shut down
1808    Shutdown = 4,
1809    /// the domain is shut off
1810    Shutoff = 5,
1811    /// the domain is crashed
1812    Crashed = 6,
1813    /// the domain is suspended by guest power management
1814    PmSuspended = 7
1815}
1816
1817impl From<u8> for DomainState {
1818    fn from(v: u8) -> Self {
1819        unsafe { ::std::mem::transmute(v) }
1820    }
1821}
1822
1823#[derive(Debug)]
1824#[repr(u32)]
1825pub enum ErrorCode {
1826    OK	=	0,
1827    /// internal error
1828    InternalError	=	1, 
1829    /// memory allocation failure
1830    NoMemory	=	2,
1831	/// no support for this function
1832    NoSupport	=	3,
1833    /// could not resolve hostname
1834    UnknownHost	=	4,
1835    /// can't connect to hypervisor
1836    NoConnect	=	5,
1837    /// invalid connection object
1838    InvalidConn	=	6,
1839    /// invalid domain object
1840    InvalidDomain	=	7,
1841    /// invalid function argument
1842    InvalidArg	=	8,
1843    /// a command to hypervisor failed
1844    OperationFailed	=	9,
1845    /// a HTTP GET command to failed
1846    GetFailed	=	10,
1847    /// a HTTP POST command to failed
1848    PostFailed	=	11,
1849    /// unexpected HTTP error code
1850    HttpError	=	12,
1851    /// failure to serialize an S-Expr
1852    SexprSerial	=	13,
1853    /// could not open Xen hypervisor control
1854    NoXen	=	14,
1855    /// failure doing an hypervisor call
1856    XenCall	=	15,
1857    /// unknown OS type
1858    OsType	=	16,
1859    /// missing kernel information
1860    NoKernel =	17,
1861    /// missing root device information
1862    NoRoot =	18,
1863    /// missing source device information
1864    NoSource	=	19,
1865    /// missing target device information
1866    NoTarget	=	20,
1867    /// missing domain name information
1868    NoName	=	21,
1869    /// missing domain OS information
1870    NoOs	=	22,
1871    /// missing domain devices information
1872    NoDevice	=	23,
1873    /// could not open Xen Store control
1874    NoXenstore	=	24,
1875    /// too many drivers registered
1876    DriverFull	=	25,
1877    /// not supported by the drivers (DEPRECATED)
1878    CallFailed	=	26,
1879    /// an XML description is not well formed or broken
1880    XmlError	=	27,
1881    /// the domain already exist
1882    DomExist	=	28,
1883    /// operation forbidden on read-only connections
1884    OperationDenied	=	29,
1885    /// failed to open a conf file
1886    OpenFailed	=	30,
1887    /// failed to read a conf file
1888    ReadFailed	=	31,
1889    /// failed to parse a conf file
1890    ParseFailed	=	32,
1891    /// failed to parse the syntax of a conf file
1892    ConfSyntax	=	33,
1893    /// failed to write a conf file
1894    WriteFailed	=	34,
1895    /// detail of an XML error
1896    XmlDetail	=	35,
1897    /// invalid network object
1898    InvalidNetwork	=	36,
1899    /// the network already exist
1900    NetworkExist	=	37,
1901    /// general system call failure
1902    SystemError	=	38,
1903    /// some sort of RPC error
1904    Rpc	=	39,
1905    /// error from a GNUTLS call
1906    GnutlsError	=	40,
1907    /// failed to start network
1908    VirWarNoNetwork	=	41,
1909    /// domain not found or unexpectedly disappeared
1910    NoDomain	=	42,
1911    /// network not found
1912    NoNetwork	=	43,
1913    /// invalid MAC address
1914    InvalidMac	=	44,
1915    /// authentication failed
1916    AuthFailed	=	45,
1917    /// invalid storage pool object
1918    InvalidStoragePool	=	46,
1919    /// invalid storage vol object
1920    InvalidStorageVol	=	47,
1921    /// failed to start storage
1922    VirWarNoStorage	=	48,
1923    /// storage pool not found
1924    NoStoragePool	=	49,
1925    /// storage volume not found
1926    NoStorageVol	=	50,
1927    /// failed to start node driver
1928    VirWarNoNode	=	51,
1929    /// invalid node device object
1930    InvalidNodeDevice	=	52,
1931    /// node device not found
1932    NoNodeDevice	=	53,
1933    /// security model not found
1934    NoSecurityModel	=	54,
1935    /// operation is not applicable at this time
1936    OperationInvalid	=	55,
1937    /// failed to start interface driver
1938    VirWarNoInterface	=	56,
1939    /// interface driver not running
1940    NoInterface	=	57,
1941    /// invalid interface object
1942    InvalidInterface	=	58,
1943    /// more than one matching interface found
1944    MultipleInterfaces	=	59,
1945    /// failed to start nwfilter driver
1946    VirWarNoNwfilter	=	60,
1947    /// invalid nwfilter object
1948    InvalidNwfilter	=	61,
1949    /// nw filter pool not found
1950    NoNwfilter	=	62,
1951    /// nw filter pool not found
1952    BuildFirewall	=	63,
1953    /// failed to start secret storage
1954    VirWarNoSecret	=	64,
1955    /// invalid secret
1956    InvalidSecret	=	65,
1957    /// secret not found
1958    NoSecret	=	66,
1959    /// unsupported configuration construct
1960    ConfigUnsupported	=	67,
1961    /// timeout occurred during operation
1962    OperationTimeout	=	68,
1963    /// a migration worked, but making the VM persist on the dest host failed
1964    MigratePersistFailed	=	69,
1965    /// a synchronous hook script failed
1966    HookScriptFailed	=	70,
1967    /// invalid domain snapshot
1968    InvalidDomainSnapshot	=	71,
1969    /// domain snapshot not found
1970    NoDomainSnapshot	=	72,
1971    /// stream pointer not valid
1972    InvalidStream	=	73,
1973    /// valid API use but unsupported by the given driver
1974    ArgumentUnsupported	=	74,
1975    /// storage pool probe failed
1976    StorageProbeFailed	=	75,
1977    /// storage pool already built
1978    StoragePoolBuilt	=	76,
1979    /// force was not requested for a risky domain snapshot revert
1980    SnapshotRevertRisky	=	77,
1981    /// operation on a domain was canceled/aborted by user
1982    OperationAborted	=	78,
1983    /// authentication cancelled
1984    AuthCancelled	=	79,
1985    /// The metadata is not present
1986    NoDomainMetadata	=	80,
1987    /// Migration is not safe
1988    MigrateUnsafe	=	81,
1989    /// integer overflow
1990    Overflow	=	82,
1991    /// action prevented by block copy job
1992    BlockCopyActive	=	83,
1993    /// The requested operation is not supported
1994    OperationUnsupported	=	84,
1995    /// error in ssh transport driver
1996    Ssh	=	85,
1997    /// guest agent is unresponsive, not running or not usable
1998    AgentUnresponsive	=	86,
1999    /// resource is already in use
2000    ResourceBusy	=	87,
2001    /// operation on the object/resource was denied
2002    AccessDenied	=	88,
2003    /// error from a dbus service
2004    DbusService	=	89,
2005    /// the storage vol already exists
2006    StorageVolExist	=	90,
2007    /// given CPU is incompatible with host CP
2008    CpuIncompatible	=	91,
2009    /// XML document doesn't validate against schema
2010    XmlInvalidSchema	=	92,
2011    /// Finish API succeeded but it is expected to return NULL
2012    MigrateFinishOk	=	93,
2013    /// authentication unavailable
2014    AuthUnavailable	=	94,
2015    /// Server was not found
2016    NoServer	=	95,
2017    /// Client was not found
2018    NoClient	=	96,
2019    /// guest agent replies with wrong id to guest-sync command
2020    AgentUnsynced	=	97,
2021    /// error in libssh transport driver
2022    Libssh	=	98,
2023}
2024
2025impl From<i32> for ErrorCode {
2026    fn from(v: i32) -> Self {
2027        unsafe { ::std::mem::transmute(v) }
2028    }
2029}
2030
2031#[derive(Debug)]
2032#[repr(u32)]
2033pub enum ErrorDomain {
2034    None	=	0,
2035    /// Error at Xen hypervisor layer
2036    Xen	=	1,
2037    /// Error at connection with xend daemon
2038    Xend	=	2,	
2039    /// Error at connection with xen store
2040    Xenstore	=	3,
2041    /// Error in the S-Expression code
2042    Sexpr	=	4,
2043    /// Error in the XML code
2044    Xml	=	5,
2045    /// Error when operating on a domain
2046    Dom	=	6,
2047    /// Error in the XML-RPC code
2048    Rpc	=	7,
2049    /// Error in the proxy code; unused since 0.8.6
2050    Proxy	=	8,
2051    /// Error in the configuration file handling
2052    Conf	=	9,
2053    /// Error at the QEMU daemon
2054    Qemu	=	10,
2055    /// Error when operating on a network
2056    Net	=	11,
2057    /// Error from test driver
2058    Test	=	12,	
2059    /// Error from remote driver
2060    Remote	=	13,	
2061    /// Error from OpenVZ driver
2062    Openvz	=	14,
2063    /// Error at Xen XM layer
2064    Xenxm	=	15,
2065    /// Error in the Linux Stats code
2066    StatsLinux	=	16,
2067    /// Error from Linux Container driver
2068    Lxc	=	17,
2069    /// Error from storage driver
2070    Storage	=	18,
2071    /// Error from network config
2072    Network	=	19,
2073    /// Error from domain config
2074    Domain	=	20,
2075    /// Error at the UML driver
2076    Uml	=	21,
2077    /// Error from node device monitor
2078    Nodedev	=	22,
2079    /// Error from xen inotify layer
2080    XenInotify	=	23,
2081    /// Error from security framework
2082    Security	=	24,
2083    /// Error from VirtualBox driver
2084    Vbox	=	25,
2085    /// Error when operating on an interface
2086    Interface	=	26,
2087    /// The OpenNebula driver no longer exists. Retained for ABI/API compat only
2088    One	=	27,
2089    /// Error from ESX driver
2090    Esx	=	28,
2091    /// Error from IBM power hypervisor
2092    Phyp	=	29,
2093    /// Error from secret storage
2094    Secret	=	30,
2095    /// Error from CPU driver
2096    Cpu	=	31,
2097    /// Error from XenAPI
2098    Xenapi	=	32,
2099    /// Error from network filter driver
2100    Nwfilter	=	33,
2101    /// Error from Synchronous hooks
2102    Hook	=	34,
2103    /// Error from domain snapshot
2104    DomainSnapshot	=	35,
2105    /// Error from auditing subsystem
2106    Audit	=	36,
2107    /// Error from sysinfo/SMBIOS
2108    Sysinfo	=	37,
2109    /// Error from I/O streams
2110    Streams	=	38,
2111    /// Error from VMware driver
2112    Vmware	=	39,
2113    /// Error from event loop impl
2114    Event	=	40,
2115    /// Error from libxenlight driver
2116    Libxl	=	41,
2117    /// Error from lock manager
2118    Locking	=	42,
2119    /// Error from Hyper-V driver
2120    Hyperv	=	43,
2121    /// Error from capabilities
2122    Capabilities	=	44,
2123    /// Error from URI handling
2124    Uri	=	45,
2125    /// Error from auth handling
2126    Auth	=	46,
2127    /// Error from DBus
2128    Dbus	=	47,
2129    /// Error from Parallels
2130    Parallels	=	48,
2131    /// Error from Device
2132    Device	=	49,
2133    /// Error from libssh2 connection transport
2134    Ssh	=	50,
2135    /// Error from lockspace
2136    Lockspace	=	51,
2137    /// Error from initctl device communication
2138    Initctl	=	52,
2139    /// Error from identity code
2140    Identity	=	53,
2141    /// Error from cgroups
2142    Cgroup	=	54,
2143    /// Error from access control manager
2144    Access	=	55,
2145    /// Error from systemd code
2146    Systemd	=	56,
2147    /// Error from bhyve driver
2148    Bhyve	=	57,
2149    /// Error from crypto code
2150    Crypto	=	58,	
2151    /// Error from firewall
2152    Firewall	=	59,
2153    /// Error from polkit code
2154    Polkit	=	60,
2155    /// Error from thread utils
2156    Thread	=	61,
2157    /// Error from admin backend
2158    Admin	=	62,
2159    /// Error from log manager
2160    Logging	=	63,
2161    /// Error from Xen xl config code
2162    Xenxl	=	64,
2163    /// Error from perf
2164    Perf	=	65,
2165    /// Error from libssh connection transport
2166    Libssh	=	66,
2167}
2168
2169impl From<i32> for ErrorDomain {
2170    fn from(v: i32) -> Self {
2171        unsafe { ::std::mem::transmute(v) }
2172    }
2173}