Net-Async-WebService-lxd

 view release on metacpan or  search on metacpan

lib/Net/Async/WebService/lxd.pod  view on Meta::CPAN


=head1 NAME

Net::Async::WebService::lxd - REST client (asynchronous) for lxd Linux containers

=head1 SYNOPSIS

   use IO::Async::Loop;
   my $loop = IO::Async::Loop->new;

   use Net::Async::WebService::lxd;
   my $lxd = Net::Async::WebService::lxd->new( loop            => $loop,
					       endpoint        => 'https://192.168.0.50:8443',
					       SSL_cert_file   => "t/client.crt",
					       SSL_key_file    => "t/client.key",
					       SSL_fingerprint => 'sha1$92:DD:63:F8:99:C4:5F:82:59:52:82:A9:09:C8:57:F0:67:56:B0:1B',
                                               );
   $lxd->create_instance(
	    body => {
		architecture => 'x86_64',
		profiles     => [ 'default'  ],
		name         => 'test1',
		source       => { type        => 'image',
				  fingerprint => '6dc6aa7c8c00' },  # image already exists in image store
		config       => {},
	    } )->get;                                               # wait for it
   # container is still stopped
   $lxd->instance_state( name => 'test1',
            body => {
                action   => "start",
		force    => JSON::false,
		stateful => JSON::false,
		timeout  => 30,
	    } )->get;                                               # wait for it


=head1 INTERFACE

=head2 Constructor

The constructor returns a handle to one LXD server. It's address is specified via an B<endpoint>
parameter, be it of an HTTPS or of a UNIX socket kind.

If you are working with a non-default LXD project in mind, then you should also provide that
project's name with the B<project> parameter. Background operation polling will make use of
that. Note, that when invoking any of the methods here, you will still have to specify that project,
unless it is the C<default> one, of course.

As we are operating under an L<IO::Async> regime here, the handle also needs a B<loop> parameter to
the central event loop. The handle will also regularily poll autonomously the server which
operations are still running or have completed. The optional parameter B<polling_time> controls how
often that will occur; it will default to 1 sec, if not provided.

As LXC can be accessed remotely only via HTTPS, TLS (SSL) parameters must be provided. These will be
forwarded directly to
L<IO::Socket::SSL|https://metacpan.org/pod/IO::Socket::SSL#Description-Of-Methods>. But, specifically,
one should consider to provide:

=over

=item * B<client certificate>, via a proper subset of C<SSL_cert_file>, C<SSL_key_file>, C<SSL_cert> and C<SSL_key>.
(Look at the L</HINTS> section to generate such a certificate for LXD.)

=item * B<server fingerprint>, via C<SSL_fingerprint>
(Look at the L</HINTS> section how to figure this out.)

=back

=head2 Methods

All methods below are automatically generated from the L<LXD REST API Spec|https://raw.githubusercontent.com/lxc/lxd/master/doc/rest-api.yaml>.
They should work with API version 1.0.


Let's dissect method invocations with this example:

   my $f = $lxd->instance_state( name => 'test1' );
   my $r = $f->get;

=over

=item *

All invocations return a L<Future>. Thus they can be combined, sequenced, run in "parallel", etc. If
you need to wait for a definite result, then you will block the flow with C<-E<gt>get>.

Polling is done behind the scenes and will watch for all operations which either succeeded or
failed. Those will mark the associated future as C<done> or C<failed>. Normally, you will never need
to use the methods for 'Operations' yourself; they are still offered as fallback.

=item *

The result of each fully completed invocation is either

=over

=item *

the string C<success>, or

=item *

a Perl HASH ref which reflects the JSON data sent from the LXD server. Note, that Booleans have to
be treated special, by using C<JSON::false> and C<JSON::true>. Otherwise, they follow B<exactly> the
structure in the specification.

=item *

or a HASH ref with keys C<stdin> and C<stdout> if this is a result of the C<execute_in_instance>
method.

=back

=item *

If an operation failed, then the associated future will be failed, together with the reason of the

lib/Net/Async/WebService/lxd.pod  view on Meta::CPAN

Well, I'm not a big fan of objects.


=head1 EXAMPLES

I encourage you to look at the C<02_instances.t> test suite. It will show a complete life cycle for
containers.

=head1 SEE ALSO

=over

=item * L<Linux::LXC>

uses actually the existing lxc client to get the information

=item * L<https://github.com/jipipayo/Linux-REST-LXD>

pretty old, never persued

=back


=head1 HINTS

=over

=item * How to generate an SSL client certificate for LXD

First, I found one client certificate (plus the key) in my installation at:

   /root/snap/lxd/common/config/

Alternatively, L<you can run your own small CA, generate a .crt and .key for a client, and then
add it to lxd to trust it|https://serverfault.com/questions/882880/authenticate-to-lxd-rest-api-over-network-certificate-auth-keeps-failing>.

More on this topic is L<here|https://linuxcontainers.org/lxd/docs/master/authentication/>

=item * How to find the SSL fingerprint for an LXD server

With recent versions of LXD this is fairly easy:

   $ lxc info|grep fingerprint

It is a SHA265 hash, so you will have to prefix it with C<sha256$> (no blanks) when you pass it to C<SSL_fingerprint>.

Alternatively, you can try to find the server certificate and use C<openssl> to derive a fingerprint of your choice.

=back

=head1 ISSUES

Open issues are probably best put onto L<Github|https://github.com/drrrho/net-async-webservice-lxd>

=head1 AUTHOR

Robert Barta, C<< <rho at devc.at> >>

=head1 CREDITS

L<IO::Async>, L<Net::Async::HTTP>, L<IO::Socket::SSL> and friends are amazing.

=head1 LICENSE AND COPYRIGHT

Copyright 2022 Robert Barta.

This program is free software; you can redistribute it and/or modify it
under the terms of the the Artistic License (2.0). You may obtain a
copy of the full license at:

L<http://www.perlfoundation.org/artistic_license_2_0>

Any use, modification, and distribution of the Standard or Modified
Versions is governed by this Artistic License. By using, modifying or
distributing the Package, you accept this license. Do not use, modify,
or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made
by someone other than you, you are nevertheless required to ensure that
your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service
mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge
patent license to make, have made, use, offer to sell, sell, import and
otherwise transfer the Package with respect to any patent claims
licensable by the Copyright Holder that are necessarily infringed by the
Package. If you institute patent litigation (including a cross-claim or
counterclaim) against any party alleging that the Package constitutes
direct or contributory patent infringement, then this Artistic License
to you shall terminate on the date that such litigation is filed.

Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



( run in 0.549 second using v1.01-cache-2.11-cpan-39bf76dae61 )