File Coverage

blib/lib/VM/Virtuozzo.pm
Criterion Covered Total %
statement 25 27 92.5
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 34 36 94.4


line stmt bran cond sub pod time code
1             package VM::Virtuozzo;
2              
3 2     2   332972 use v5.10;
  2         7  
  2         86  
4 2     2   9 use strict;
  2         3  
  2         60  
5 2     2   8 use warnings FATAL => "all";
  2         4  
  2         72  
6 2     2   8 use utf8;
  2         4  
  2         13  
7 2     2   47 use Carp;
  2         3  
  2         115  
8 2     2   1857 use File::ShareDir "dist_dir";
  2         12518  
  2         162  
9 2     2   2007 use File::Spec::Functions qw(catdir catfile);
  2         1786  
  2         232  
10 2     2   2023 use Params::Check "check";
  2         15643  
  2         167  
11 2     2   3289 use XML::Compile::Cache;
  0            
  0            
12             use XML::Compile::Util "pack_type";
13             use VM::Virtuozzo::Response;
14             use Socket qw(inet_aton);
15             use IO "Socket::INET";
16              
17             use constant {
18             Document => "XML::LibXML::Document",
19             Element => "XML::LibXML::Element",
20             Response => "VM::Virtuozzo::Response" };
21              
22             use namespace::clean;
23              
24             our $VERSION = 'v0.0.5'; # VERSION
25             # ABSTRACT: Client implementation of the Parallels Virtuozzo XML API
26              
27             my $schema = XML::Compile::Cache->new(
28             allow_undeclared => 1,
29             opts_rw => { elements_qualified => 0 } );
30             do {
31             my $dist_dir = dist_dir("VM-Virtuozzo");
32             my $xsd_dir = catdir $dist_dir, "v4";
33             my @xsd_files = glob catfile $xsd_dir, "*.xsd";
34             $schema->importDefinitions($_) for @xsd_files; };
35              
36             sub new {
37             my ( $class, %params ) = @_;
38              
39             # Check params:
40             my %tmpl = (
41             xsd_version => {
42             required => 1,
43             allow => [4] }, # Only version supported for now
44             use_ssl => {
45             default => 1,
46             allow => [ 0, 1 ] },
47             hostname => {
48             required => 1,
49             allow => sub { $_[0] && inet_aton($_[0]) } } );
50             check( \%tmpl, \%params, 1 ) or croak "Parameter check failed";
51              
52             # Create self and client attribute:
53             my $client = IO::Socket::INET->new(
54             PeerAddr => $params{hostname},
55             PeerPort => 4433,
56             Proto => "tcp",
57             Timeout => 10 ) or croak "Unable to connect to server";
58             local $/ = "\0";
59              
60             return bless {
61             _client => $client,
62             _schema => $schema }, $class; }
63              
64             my $packet_id = 1;
65             my $doc = Document->new("1.0", "UTF-8");
66             sub _write_packet {
67             my ($self, $namespace, $function, $params) = @_;
68             my $protocol_ns = $namespace;
69             $protocol_ns =~ s/\w+$/protocol/x;
70             $protocol_ns =~ s/\bvza\b/vzl/xg;
71             my $packet_type = pack_type($protocol_ns, "packet");
72             my $op_type = pack_type($namespace, $function);
73             my ($short_ns) = $namespace =~ /(\w+)$/x;
74             my $operator = Element->new($short_ns);
75              
76             $operator->addChild(
77             defined $params
78             ? $self->{_schema}->writer($op_type)->($doc, $params)
79             : Element->new($function) );
80             my $packet = $self->{_schema}->writer($packet_type)->(
81             $doc, {
82             id => $packet_id++,
83             version => "4.0.0",
84             ( $short_ns eq "system" ? () : ( target => $short_ns ) ),
85             data => { cho_operator => [ { $short_ns => $operator } ] } } );
86             return $packet->toString; }
87              
88             # Generate API methods:
89              
90             foreach my $namespace ( $schema->namespaces->list ) {
91             my ($ns_short) = $namespace =~ /(\w+)$/x;
92             no strict "refs";
93             *{__PACKAGE__ . "::" . $ns_short} = sub {
94             use strict "refs";
95             my ($self, $function, $params) = @_;
96             my $operation = $self->_write_packet($namespace, $function, $params);
97             $operation =~ s/(\w+?>.+?==)\n/$1/gx;
98             $self->{_client}->print($operation . "\0");
99             local $/ = "\0";
100             return $self->{_client}->getline; } }
101             # return Response->new(
102             # $client->reader($namespace)->( $self->_client->getline ) ); } }
103              
104             1;
105              
106             __END__