Commit 39a89073 authored by Benoit Mortier's avatar Benoit Mortier

Merge branch 'argonaut-1.1-fixes'

parents c68c20f1 931b2f10
Argonaut changelog
==================
* Argonaut 1.2
[Fix] Bugs #5461: Error with Ldap2zone slave when using multiple domains with a common reverse zone
[Fix] Bugs #5513: netboot stayed in uninstall state
[Fix] Bugs #5523: Periodical schedule is not repeated
[Fix] Bugs #5541: Errors when trying to schedule actions
[Fix] Bugs #5544: Periodical jobs miss the first launch
[Fix] Bugs #5546: OPSI update software stay in deployement queue with "in progress" status
[Feature] Bugs #5558: Use some trim on argonaut.conf
[Fix] Bugs #5559: Argonaut client and server systemd service definition fails
[Fix] Bugs #5646: changing the library used to send mail in argonaut-user-reminder
* Argonaut 1.1
[Feature] Bugs #5379: Argonaut should support fdMode instead of gotoMode for FD 1.1
......
[Donate to FusionDirectory on Liberapay](https://liberapay.com/fusiondirectory/donate)
# Argonaut
[Argonaut][Argonaut] Manage your systems, services and also Integrate FusionDirectory backend Fonctionnalities
[Argonaut][Argonaut] is an effective tool for managing services, systems, task.
Integrate Argonaut with your own tools or with deployment tools like [FAI], [OPSI], Debconf.
## Features
Argonaut is a modular client/server system based on JSON-RPCprotocol. Both client and server sides can load modules at start. Argonaut has two primary functions.
### Run a given operation on a system through a client
Two basic functions: restart service and switch on/off a system.
Modules can provide some more functionalities :
* argonaut-ldap2zone: update a dns zone, create view, create acls
* argonaut-quota: apply a quota
* argonaut-fai-mirror: create a synchronization script Mirror
* argonaut-fai-monitor: follow FAI installation and report states to FusionDirectory
* argonaut-dovecot: create the mailbox quota and applies it
* argonaut-user-reminder : to manage the accoun reminder plugin of FusionDirectory
* argonaut-clean-audit : to clean the audit branch of FusionDirectory
* argonaut-user-reminder : to send email reminder coordonated with the user-reminder plugin of FusionDirectory
### Allow integration with deployment tools [FAI], [OPSI], Debconf
* FAI integration (argonaut-server-module-fai and argonaut-common-fai) and the complement to integrate into the nfsroot and FAI server (argonaut-fai-nfsroot argonaut-fai-server, argonaut-fai-mirror)
* OPSI integration (argonaut-server-module-opsi)
* Manage the pxelinux.cfg directory using argonaut-fuse (argonaut-fuse-fai-module and argonaut-fuse-opsi-module): get information and create pxelinux.cfg file that matches the type of machine to be deployed, allowing automatic boot during an install by pxe
## Get help
There are a couple ways you can try [to get help][get help].You can also join the `#fusiondirectory` IRC channel at freenode.net.
You can [register on our system][register] and enter your bug [on the forge][issues-forge] or [here at github][issues-github] even if the forge is the prefered way of dealing with bugs
## IRC Etiquette
* If we don't answer right away then just hang out in the channel. Someone will
eventually write back to you as it just means we are away from keyboard,
working on something else, or in a different timezone than you.
* You should treat IRC as what it is: asynchronous chat. Sure the messages can
be instant but in most channels people are in different time zones. At times
chat replies can be in excess of 24hrs.
## Donate
If you like [Argonaut][Argonaut] and would like to [donate][donate-liberapay] even a small amount you can go to our Liberapay account
## License
[Argonaut][Argonaut] is [GPL 2 License](COPYING).
[Argonaut]: https://www.argonaut-project.org/
[FAI]: http://fai-project.org/
[OPSI]: http://opsi.org/en/
[get help]: https://www.fusiondirectory.org/contact-us/
[register]: https://register.fusiondirectory.org
[issues-forge]: https://forge.fusiondirectory.org/projects/argonaut-agents/issues/new
[issues-github]: https://github.com/fusiondirectory/argonaut/issues
[donate-liberapay]: https://liberapay.com/fusiondirectory/donate
[Unit]
Description=Start argonaut-client
ConditionPathExists=/usr/sbin/argonaut-client
Wants=network-online.target
After=network-online.target
[Service]
Type=forking
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-CLIENT 1"
.TH ARGONAUT-CLIENT 1 "2016-01-06" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-CLIENT 1 "2016-01-06" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -605,6 +605,16 @@ sub argonaut_ldap_fsearch {
return( $mesg, ${search_base} );
}
=item trim
trims whitespaces from a given string
=cut
sub trim {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
#------------------------------------------------------------------------------
# function for reading argonaut config
#
......@@ -612,12 +622,12 @@ sub argonaut_read_config {
my %res = ();
my $config = Config::IniFiles->new( -file => $configfile, -allowempty => 1, -nocase => 1);
$res{'server_ip'} = $config->val( server => "server_ip", "");
$res{'client_ip'} = $config->val( client => "client_ip", "");
$res{'ldap_configfile'} = $config->val( ldap => "config", "/etc/ldap/ldap.conf");
$res{'ldap_dn'} = $config->val( ldap => "dn", "");
$res{'ldap_password'} = $config->val( ldap => "password", "");
$res{'ldap_tls'} = $config->val( ldap => "tls", "off");
$res{'server_ip'} = trim($config->val( server => "server_ip", ""));
$res{'client_ip'} = trim($config->val( client => "client_ip", ""));
$res{'ldap_configfile'} = trim($config->val( ldap => "config", "/etc/ldap/ldap.conf"));
$res{'ldap_dn'} = trim($config->val( ldap => "dn", ""));
$res{'ldap_password'} = trim($config->val( ldap => "password", ""));
$res{'ldap_tls'} = trim($config->val( ldap => "tls", "off"));
if ($res{'ldap_tls'} !~ m/^off|on$/i) {
warn "Unknown value for option ldap/tls: ".$res{'ldap_tls'}." (valid values are on/off)\n";
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-DEBCONF-CRAWLER 1"
.TH ARGONAUT-DEBCONF-CRAWLER 1 "2016-01-06" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-DEBCONF-CRAWLER 1 "2016-01-06" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-REPOSITORY 1"
.TH ARGONAUT-REPOSITORY 1 "2017-01-23" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-REPOSITORY 1 "2017-01-23" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
[Unit]
Description=Start argonaut-fai-monitor
ConditionPathExists=/usr/sbin/argonaut-fai-monitor
Wants=network-online.target
After=network-online.target
[Service]
Type=forking
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-FAI-MONITOR 1"
.TH ARGONAUT-FAI-MONITOR 1 "2016-11-13" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-FAI-MONITOR 1 "2016-11-13" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-LDAP2FAI 1"
.TH ARGONAUT-LDAP2FAI 1 "2017-02-16" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-LDAP2FAI 1 "2017-04-06" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "FAI2LDIF 1"
.TH FAI2LDIF 1 "2017-01-23" "Argonaut 1.1" "Argonaut Documentation"
.TH FAI2LDIF 1 "2017-01-23" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "YUMGROUP2YUMI 1"
.TH YUMGROUP2YUMI 1 "2017-01-23" "Argonaut 1.1" "Argonaut Documentation"
.TH YUMGROUP2YUMI 1 "2017-01-23" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
[Unit]
Description=Start argonaut-fuse
ConditionPathExists=/usr/sbin/argonaut-fuse
Wants=network-online.target
After=network-online.target
[Service]
Type=forking
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-FUSE 1"
.TH ARGONAUT-FUSE 1 "2017-01-23" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-FUSE 1 "2017-01-23" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -37,10 +37,11 @@ use Net::LDAP::Constant qw(LDAP_NO_SUCH_OBJECT);
use Net::LDAP::Util qw(generalizedTime_to_time);
# first, create your message
use Email::MIME;
#~ use Email::MIME;
# send the message
use Email::Sender::Simple qw(sendmail);
#~ use Email::Sender::Simple qw(sendmail);
use Mail::Sendmail qw(sendmail);
my $config;
......@@ -287,20 +288,14 @@ sub send_alert_mail
$cc = "$manager_cn<$manager_mail>";
}
print " with token $token\n" if $verbose;
my $message = Email::MIME->create(
header_str => [
From => $config->{'alert_mailaddress'},
To => "$user_cn<$user_mail>",
Cc => $cc,
Subject => $config->{'alert_mailsubject'},
],
attributes => {
encoding => 'quoted-printable',
charset => 'UTF-8',
},
body_str => sprintf($config->{'alert_mailbody'},$user_cn,$uid,$token),
my %message = (
From => $config->{'alert_mailaddress'},
To => "$user_cn<$user_mail>",
Cc => $cc,
Subject => $config->{'alert_mailsubject'},
Message => sprintf($config->{'alert_mailbody'},$user_cn,$uid,$token)
);
sendmail($message);
sendmail(%message) or die $Mail::Sendmail::error;
}
sub get_ldap_token
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-CLEAN-AUDIT 1"
.TH ARGONAUT-CLEAN-AUDIT 1 "2017-01-23" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-CLEAN-AUDIT 1 "2017-01-23" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-USER-REMINDER 1"
.TH ARGONAUT-USER-REMINDER 1 "2017-03-16" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-USER-REMINDER 1 "2017-04-06" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -132,6 +132,7 @@ sub argonaut_ldap2zone
} elsif ($slavefiles) {
print "Updating all slave files\n" if $verbose;
my @zones = @{$settings->{'slavefiles'}};
my $all_reverse_zones = [];
foreach (@zones) {
my ($zoneName, $masterline, $reverse) = split /\|/, $_, 3;
print "Updating slave $zoneName\n" if $verbose;
......@@ -140,7 +141,7 @@ sub argonaut_ldap2zone
if ($zonedn and ($reverse ne 'noreverse')) {
$reverse_zones = get_reverse_zones($ldap,$ldap_base,$zonedn);
}
create_slave_namedconf($zoneName,$masterline,$reverse_zones,$BIND_DIR,$BIND_CACHE_DIR,$output_BIND_DIR,$verbose);
create_slave_namedconf($zoneName,$masterline,$reverse_zones,$BIND_DIR,$BIND_CACHE_DIR,$output_BIND_DIR,$verbose,$all_reverse_zones);
}
} else {
if (substr($zone,-1) ne ".") { # If the end point is not there, add it
......@@ -240,7 +241,7 @@ sub zoneparse
print "Added record $type $name $class $value $ttl\n" if $verbose;
}
}
my $soa = $entry->get_value("soaRecord");
my $soa = $entry->get_value("sOARecord");
if($soa) {
my $soa_record = $zonefile->soa();
my (@soa_fields) = split(' ',$soa);
......@@ -287,16 +288,18 @@ sub zonesearch
my $mesg = $ldap->search( # perform a search
base => $ldap_base,
filter => "zoneName=$zone",
attrs => [ 'soaRecord' ]
attrs => [ 'sOARecord' ]
);
$mesg->code && die "Error while searching DNS Zone '$zone' :".$mesg->error;
foreach my $entry ($mesg->entries()) {
if($entry->get_value("soaRecord")) {
if($entry->get_value("sOARecord")) {
return $entry->dn();
}
}
die "Could not find DNS Zone '$zone'\n";
}
=item viewparse
......@@ -478,7 +481,7 @@ Returns :
=cut
sub create_slave_namedconf
{
my($zone,$masterline,$reverse_zones,$BIND_DIR,$BIND_CACHE_DIR,$output_BIND_DIR,$verbose) = @_;
my($zone,$masterline,$reverse_zones,$BIND_DIR,$BIND_CACHE_DIR,$output_BIND_DIR,$verbose,$all_reverse_zones) = @_;
if (substr($masterline,-1) ne ";") {
# If the end semi-colon is not there, add it
......@@ -498,6 +501,11 @@ zone "$zone" {
};
EOF
foreach my $reverse_zone (@$reverse_zones) {
if (grep {$_ eq $reverse_zone} @$all_reverse_zones) {
# this avoids having twice the same reverse zones in slave conf
next;
}
push @$all_reverse_zones, $reverse_zone;
print "Writing reverse zone '$reverse_zone'\n" if $verbose;
print $namedfile <<EOF;
zone "$reverse_zone" {
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-LDAP2ZONE 1"
.TH ARGONAUT-LDAP2ZONE 1 "2017-03-22" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-LDAP2ZONE 1 "2017-04-06" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ARGONAUT-QUOTA 1"
.TH ARGONAUT-QUOTA 1 "2016-01-06" "Argonaut 1.1" "Argonaut Documentation"
.TH ARGONAUT-QUOTA 1 "2016-01-06" "Argonaut 1.2" "Argonaut Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
......
......@@ -194,14 +194,14 @@ sub update_task {
if ($task->{status} ne 'processing') {
return $task;
}
if ($task->{action} eq 'Deployment.reinstall') {
if (($task->{action} eq 'Deployment.reinstall') || ($task->{action} eq 'Deployment.update')) {
my $attrs = [
'actionResult',
'actionRequest',
'actionProgress',
'installationStatus',
];
$task->{progress} = 0;
$task->{progress} = 10;
$task->{substatus} = "";
if (defined $self->{'netboot'}) {
my $filter = {
......@@ -212,15 +212,16 @@ sub update_task {
my $results = $self->launch('productOnClient_getObjects',[$attrs, $filter]);
my $res = shift @$results;
if ($res->{'actionRequest'} eq 'setup') {
$task->{substatus} = $res->{'actionProgress'};
$task->{progress} = 10;
return;
$task->{substatus} = $res->{'actionProgress'};
$task->{progress} = 20;
return $task;
} elsif ($res->{'installationStatus'} eq 'installed') {
$task->{substatus} = 'netboot installed';
$task->{progress} = 50;
$task->{substatus} = 'netboot installed';
$task->{progress} = 50;
} elsif ($res->{'actionResult'} eq 'failed') {
$task->{status} = "error";
$task->{error} = $res->{'actionProgress'};
$task->{error} = $res->{'actionProgress'};
return $task;
}
}
my $nblocals = 0;
......@@ -246,13 +247,14 @@ sub update_task {
} elsif ($res->{'actionResult'} eq 'failed') {
$task->{status} = "error";
$task->{error} = $res->{'actionProgress'};
return $task;
}
}
}
if ($nblocals eq 0) {
$task->{progress} = 100;
} else {
$task->{progress} += (100 - $task->{progress})*$nbinstalled/$nblocals;
$task->{progress} += (100 - $task->{progress}) * $nbinstalled / $nblocals;
if ($status ne "") {
$task->{substatus} = $status;
}
......@@ -293,7 +295,6 @@ sub update_or_insert {
sub reinstall_or_update {
my ($self, $reinstall,$action,$params) = @_;
my $res;
#1 - fetch the host profile
my ($ldap, $ldap_base) = argonaut_ldap_handle($main::config);
......@@ -324,32 +325,21 @@ sub reinstall_or_update {
$productStates->{$product->{'productId'}} = $product->{'installationStatus'};
$product->{"actionRequest"} = 'none';
}
$res = $self->launch('productOnClient_updateObjects', [$productOnClients]);
$productOnClients = $self->launch('productPropertyState_getObjects',
$self->launch('productOnClient_updateObjects', [$productOnClients]);
my $productPropertyStates = $self->launch('productPropertyState_getObjects',
[[],
{
"objectId" => $self->{'fqdn'},
"type" => "ProductPropertyState",
}]
);
$res = $self->launch('productPropertyState_deleteObjects', [$productOnClients]);
if (scalar(@$productPropertyStates) > 0) {
$self->launch('productPropertyState_deleteObjects', [$productPropertyStates]);
}
#3 - set netboot as the profile specifies
if (!$reinstall && defined $self->{'netboot'}) {
# Check if netboot is correctly installed
my $attrs = [
'actionResult',
'actionRequest',
'actionProgress',
'installationStatus',
];
my $filter = {
"productId" => $self->{'netboot'},
"clientId" => $self->{'fqdn'},
"productType" => "NetbootProduct",
};
my $results = $self->launch('productOnClient_getObjects',[$attrs, $filter]);
my $res = shift @$results;
if ($res->{'installationStatus'} ne 'installed') {
if ((not exists($productStates->{$self->{'netboot'}})) || ($productStates->{$self->{'netboot'}} ne 'installed')) {
$reinstall = 1;
}
}
......@@ -361,24 +351,28 @@ sub reinstall_or_update {
"type" => "ProductOnClient",
"productType" => "NetbootProduct",
};
$res = $self->launch('productOnClient_updateObject',[$infos]);
$self->launch('productOnClient_updateObject',[$infos]);
} else {
#3 bis - set to uninstall product that are not in the profile
$productOnClients = $self->launch('productOnClient_getObjects',
[[],
{
"clientId" => $self->{'fqdn'},
"type" => "ProductOnClient",
"installationStatus" => "installed",
}]
);
# (all products on the client for now - step 4 will cancel uninstall on needed products)
my $infos = [];
foreach my $product (@$productOnClients) {
if (($product->{"productId"} ne 'opsi-client-agent') && ($product->{"productId"} ne 'opsi-winst')) {
$product->{"actionRequest"} = "uninstall";
$main::log->debug("[OPSI] uninstall ".$product->{"productId"});
if (($product->{"productType"} eq "LocalbootProduct") &&
($product->{"installationStatus"} eq "installed") &&
($product->{"productId"} ne 'opsi-client-agent') &&
($product->{"productId"} ne 'opsi-winst')) {
push @$infos, {
"productId" => $product->{"productId"},
"clientId" => $self->{'fqdn'},
"type" => "ProductOnClient",
"productType" => "LocalbootProduct",
"actionRequest" => "uninstall",
};
}
}
$res = $self->launch('productOnClient_updateObjects', [$productOnClients]);
if (scalar(@$infos) > 0) {
$self->launch('productOnClient_updateObjects',[$infos]);
}
}
#4 - set localboot as the profile specifies (maybe remove the old ones that are not in the profile - see 3 bis)
if (defined $self->{'softlists'}) {
......@@ -431,7 +425,9 @@ sub reinstall_or_update {
$self->launch('configState_create',['software-on-demand.show-details', $self->{'fqdn'}, ($showdetails?JSON::true:JSON::false)]);
}
}
$res = $self->launch('productOnClient_updateObjects',[$infos]);
if (scalar(@$infos) > 0) {
$self->launch('productOnClient_updateObjects',[$infos]);
}
}
#5 - set properties as the profile specifies
if (defined $self->{'properties'}) {
......@@ -446,15 +442,22 @@ sub reinstall_or_update {
"type" => "ProductPropertyState",
};
}
$res = $self->launch('productPropertyState_updateObjects',[$infos]);
if (scalar(@$infos) > 0) {
$self->launch('productPropertyState_updateObjects',[$infos]);
}
}
#6 - reboot the host or fire the event
my $res;
if (defined $self->{'netboot'}) {
$res = $self->launch('hostControl_reboot',[$self->{'fqdn'}]);
} else {
$res = $self->launch('hostControl_fireEvent',['on_demand', $self->{'fqdn'}]);
}
# If we did not die until here, all went well
$self->{task}->{'substatus'} = 'Order sent';
$self->{task}->{'progress'} = 10;
return $res;
}
......@@ -524,22 +527,7 @@ sub do_action {
unshift @$params, $self->{'fqdn'};
}
$main::log->info("[OPSI] sending action ".$actions->{$action}." to ".$self->{'fqdn'});
$res = $self->launch($actions->{$action},$params);
if ($hostParam) {
if ((ref $res eq ref {}) && defined $res->{$self->{'fqdn'}}) {
my $result = $res->{$self->{'fqdn'}};
if (JSON::XS::is_bool($result)) {
$res = $result;
} elsif (defined $result->{'error'}) {
$main::log->error("[OPSI] Error : ".$result->{'error'});
die "Error while sending '".$actions->{$action}."' to '".$self->{'fqdn'}."' : ", $result->{'error'}."\n";
} elsif (defined $result->{'result'}) {
$res = $result->{'result'};
} else {
undef $res;
}
}
}
$res = $self->launch($actions->{$action}, $params);
} else {
my $sub = $actions->{$action};
$res = $self->$sub($action, $params);
......@@ -591,7 +579,21 @@ sub launch {
$main::log->error("[OPSI] Error : ".$res->error_message->{'message'});
die "Error : ", $res->error_message->{'message'}."\n";
} else {
return $res->result;
$res = $res->result;
if ((ref $res eq ref {}) && defined $res->{$self->{'fqdn'}}) {
my $result = $res->{$self->{'fqdn'}};
if (JSON::XS::is_bool($result)) {
$res = $result;
} elsif (defined $result->{'error'}) {
$main::log->error("[OPSI] Error : ".$result->{'error'});
die "Error while sending '".$action."' to '".$self->{'fqdn'}."' : ", $result->{'error'}."\n";
} elsif (defined $result->{'result'}) {
$res = $result->{'result'};
} else {
undef $res;
}
}
return $res;
}
} else {
$main::log->info("[OPSI] Status : ".$client->status_line);
......
......@@ -450,50 +450,70 @@ POE::Session->create(
my ($kernel, $heap, $session, $jsonrpc, $id, @params) = @_[KERNEL,HEAP,SESSION, ARG0..$#_ ];
my ($action,$targets,$data) = @params;
if (ref $data ne ref {}) {
#If data is not an hash reference, make it so to avoid errors.
$data = {};
}
$log->info("adding action $action");
if( ((! defined $data->{timestamp}) || ($data->{timestamp} eq "")) &&
(grep {$_ eq $action} @{$heap->{scheduled_only}})) {
# If the action is scheduled_only and there is no timestamp
# We schedule it for now
$data->{timestamp} = time();
}
eval {
if (scalar(@$targets) == 0) {
$log->debug("No targets, refusing action $action");
$kernel->post( $jsonrpc => 'error' => $id, "Empty target list was given");
return;
}
if(defined $data->{timestamp} && ($data->{timestamp} ne "")) {
$kernel->post( $jsonrpc => 'result' => $id, "OK" ); # asynchronous
my $date = DateTime->from_epoch(epoch => $data->{timestamp});
my $datetime;
if (defined $data->{periodic} && ($data->{periodic} =~ /^(\d+)_(\w+)$/)) {
my $periodic_nb = $1;
my $periodic_keyword = $2;
$datetime = DateTime::Set->from_recurrence (
after => $date,
recurrence => sub {
return $_[0]->add( $periodic_keyword => $periodic_nb )
},
);
} else {
$datetime = DateTime::Set->from_datetimes(dates => [ $date ]);
if (ref $data ne ref {}) {
#If data is not an hash reference, make it so to avoid errors.
$data = {};
}
foreach my $target (@{$targets}) {
$kernel->yield(schedule => $datetime->clone, $action, lc($target), $data);
$log->info("adding action $action");
if( ((! defined $data->{timestamp}) || ($data