=head1 NAME

Linux::LXC - Manage your LXC containers.

=head1 VERSION

1.0004

=head1 SYNOPSYS

  use Linux::LXC qw(ALLOW_UNDEF);

  my $c = Linux::LXC->new(
    utsname => 'web',
    template => 'download -- -d debian -r wheezy -a amd64'
  );
  my ($uid_start, $uid_map) =
    $c->get_config('lxc.id_map', qr/^u 0 (\d+) (\d+)$/, ALLOW_UNDEF);
  $c->stop if $c->is_running;
  $c->destroy if $c->is_existing;
  $c->deploy;
  $c->set_config('lxc.network.ipv4', '10.0.3.2');
  $c->start;
  my @cmd = (
    'route add default gw 10.0.0.3 eth0',
    'echo "nameserver 8.8.8.8" > /etc/resolv.conf',
    'apt-get update -y',
    'apt-get install -y lighttpd'
  );
  map {
    my ($res, $stdout, $stderr) = $c->exec($_);
    die $stderr if $stderr ne '';
  } @cmd;
  $c->put('lighttpd.conf', '/etc/lighttpd/lighttpd.conf');
  $c->put('www', '/var/www');

=head1 DESCRIPTION

This module helps you to manage LXC container. Each container will be represented by an object of this module.
Some module subroutine are also usable without any object instance.

=head2 Module subroutines

=head3 get_existing_containers()

Will return an array with the name of all LXC containers existing on the system.

=head3 get_running_containers()

Will return an array with the name of all LXC containers currently running on the system.

=head3 get_stopped_containers()

Will return an array with the name of all LXC containers currently stopped on the system.

=head3 get_version()

Will return the version number of LXC implementation that runs on the host.

=head2 Object methods

=head3 new(%params)

Instanciate a new Linux::LXC object. Params that can be initialized:

=over 15

=item utsname

Mandatory parameter. Set the utsname of the container.

=item template

Mandatory only if you planned to deploy the container. Set the LXC template to use for deploying the container.

=item return

A Linux::LXC object.

=back

=head3 deploy()

Will deploy the container. Concretly, this method will check that the container is not existing, and after execute `lxc-deploy -n <utsname> -t <template>` shell command.

=over 15

=item return

The previous Linux::LXC object.

=back

=head3 del_config($attribute, $filter)

Will delete all LXC configuration container attributes that respect the $filter pattern.

=over 15

=item $attribute

The attribute to delete.

=item $filter

A regex or undef.
It will be compared with all $attribute values. The ones that match will be removed.
If undef, all values will be removed.

=item return

The number of elements deleted.

=back

=head3 destroy()

Will stop the container if it's existing and destroy it with the shell `lxc-destroy -n <utsname>`  shell command.

=over 15

=item return

The previous Linux::LXC object.

=back

=head3 exec($cmd)

Will execute the $cmd command in the container.
This method use the IPC::Run method, that allow us to don't think at all about priorities between shell operators.
Eg: exec('echo "Hello" >> ~/file.txt') will write the file on the container, and not on the instance that actually runs the commnand.

=over 15

=item return (if want array)

($result, $stdout, $stderr); $result true if shell command return 0 (it usually means that the command was a success), false otherwise.
$stdout and $stderr are self-explaining.

=item return (if want scalar)

True if shell command return 0 (it usually means that the command was a success), false otherwise.

=back

=head3 get_config($paramater, $filter, $flag)

Get an array of values corresponding to all data that match the LXC container configuration.

=over 15

=item $parameter

The parameter to match.

=item $filter

An regex, or undef.
Values corresponding of the parameter to keep. If undef, we will keep all of them.

=item $flags

ALLOW_EMPTY: don't croak if the parameter asked was not found.

=item return

An array with all matched results.

=back

=head3 get_lxc_path()

Return the path to the LXC instance of the container. By default it's /var/lib/lxc/<utsname>/.
The path is the folder that contains rootfs and config file.

=head3 get_template()

Get the template of the LXC instance.

=head3 get_utsname()

Will return the utsname of the container.

=head3 is_existing()

Retrun true if the container with the given utsname exists. False otherwise.

=head3 is_running()

Retrun true if the container with the given utsname is running. False otherwise.

=head3 is_stopped()

Return true if the container with the given utsname is stopped. False otherwise.

=head3 put($input, $destination)

Will copy the $input file or folder on the $destination path in the container instance.
This method also takes care of ownership and will chown $destination to the container root uid.
The ownership will also be set for all intermediate folders we have to create.

=over 15

=item $input

String corresponding to a relative or absolute path of a folder or a file we want to copy on the container root fs.
This path should be readable by the user executing this script.

=item $output

Location on the container to put the file or folder. This path has to be absolute.

=back

=head3 set_config($attribute, $value, $flag)

Will set a LXC attribute in container configuration.
The update can occurs in two modes: addition or erasing.
In the first one, a new attribute with the given value will always be created.
In the second case, the first previous value already existing of $attribute will be updated with the new $value. If none is found, the atribute will also be created.

=over 15

=item $attribute

Attribute to set.

=item $value

Value to give to the attribute.

=item $flag

Can be ADDITION_MODE, ERASING_MODE or undef. If undef, ERASING_MODE will occur.

=back

=head3 set_template($template)

Will set the $template name to the given container.
Note that this action should be done before the deployment.

=head3 start()

Start the container.

=head3 stop()

Stop the container.

=head1 AUTHOR

Spydemon <jsaipakoimetr@spyzone.fr>

=head1 BUGS AND INFO

A bug tracker is available for this module at the address: https://dev.spyzone.fr/Perl/Linux-LXC but inscriptions are
closed because of spamming issue.
If you want an account for contributing, report any enhancement suggestion or bug report, please send me an email.

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by Spydemon.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

=cut