our
$VERSION
=
'1.16.0'
;
@EXPORT
=
qw(service service_provider_for)
;
sub
service {
my
(
$services
,
$action
,
@_options
) =
@_
;
my
$opt_ref
= {};
if
(
scalar
@_options
>= 1 ) {
$opt_ref
= {
$action
,
@_options
};
}
else
{
$opt_ref
= {
ensure
=>
$action
,
no_boot
=> 1 };
}
if
(
wantarray
) {
return
sub
{
service(
$services
,
$action
);
};
}
my
$is_multiple
= 1;
unless
(
ref
(
$services
) ) {
$services
= [
$services
];
$is_multiple
= 0;
}
my
$srvc
= Rex::Service->get;
my
$changed
= 0;
my
$return
= 1;
for
my
$res_service
(
@$services
) {
my
$service
=
$res_service
;
if
(
exists
$opt_ref
->{name} ) {
$service
=
$opt_ref
->{name};
}
my
$notify
= Rex::get_current_connection()->{notify};
$notify
->add(
type
=>
"service"
,
name
=>
$service
,
postpone
=> 1,
options
=> {},
cb
=>
sub
{
my
(
$option
) =
shift
;
Rex::Logger::debug(
"Restarting notified service: $service"
);
service(
$service
=>
"restart"
);
}
);
Rex::Hook::run_hook(
service
=>
"before_$action"
,
@_
);
if
(
scalar
@_
== 2 ) {
return
old_service(
$service
,
$action
);
}
Rex::get_current_connection()->{reporter}
->report_resource_start(
type
=>
"service"
,
name
=>
$res_service
);
my
$b_status
=
$srvc
->status(
$service
);
my
$return
;
if
(
$opt_ref
->{ensure} =~ m/^(start|run|enable)/ ) {
if
(
exists
$opt_ref
->{no_boot} &&
$opt_ref
->{no_boot} ) {
$return
=
$srvc
->start(
$service
,
$opt_ref
);
}
else
{
$return
=
$srvc
->ensure(
$service
,
$opt_ref
);
}
}
elsif
(
$opt_ref
->{ensure} =~ m/^(stop|disable)/ ) {
if
(
exists
$opt_ref
->{no_boot} &&
$opt_ref
->{no_boot} ) {
$return
=
$srvc
->stop(
$service
,
$opt_ref
);
}
else
{
$return
=
$srvc
->ensure(
$service
,
$opt_ref
);
}
}
else
{
Rex::Logger::info(
"$opt_ref->{ensure} unknown ensure value."
,
"error"
);
confess
"$opt_ref->{ensure} unknown ensure value."
;
}
my
$a_status
=
$srvc
->status(
$service
,
$opt_ref
);
$changed
= 0;
if
(
$a_status
!=
$b_status
) {
$changed
= 1;
}
Rex::Hook::run_hook(
service
=>
"after_$action"
,
@_
, {
changed
=>
$changed
,
ret
=>
$return
}
);
if
(
$changed
) {
Rex::get_current_connection()->{reporter}->report(
changed
=> 1,
message
=>
"Service $service changed status to $opt_ref->{ensure}."
);
}
else
{
Rex::get_current_connection()->{reporter}->report(
changed
=> 0, );
}
Rex::get_current_connection()->{reporter}
->report_resource_end(
type
=>
"service"
,
name
=>
$res_service
);
}
}
sub
old_service {
my
(
$service
,
$action
,
$options
) =
@_
;
my
$srvc
= Rex::Service->get;
my
$changed
;
my
$is_multiple
= 0;
my
$return
;
Rex::get_current_connection()->{reporter}
->report_resource_start(
type
=>
"service"
,
name
=>
$service
);
if
(
$action
eq
"start"
) {
unless
(
$srvc
->status(
$service
) ) {
$changed
= 1;
if
(
$srvc
->start(
$service
) ) {
Rex::Logger::info(
"Service $service started."
);
$return
= 1
if
!
$is_multiple
;
}
else
{
Rex::Logger::info(
"Error starting $service."
,
"warn"
);
$return
= 0
if
!
$is_multiple
;
}
}
}
elsif
(
$action
eq
"restart"
) {
$changed
= 1;
if
(
$srvc
->restart(
$service
) ) {
Rex::Logger::info(
"Service $service restarted."
);
$return
= 1
if
!
$is_multiple
;
}
else
{
Rex::Logger::info(
"Error restarting $service."
,
"warn"
);
$return
= 0
if
!
$is_multiple
;
}
}
elsif
(
$action
eq
"stop"
) {
if
(
$srvc
->status(
$service
) ) {
$changed
= 1;
if
(
$srvc
->stop(
$service
) ) {
Rex::Logger::info(
"Service $service stopped."
);
$return
= 1
if
!
$is_multiple
;
}
else
{
Rex::Logger::info(
"Error stopping $service."
,
"warn"
);
$return
= 0
if
!
$is_multiple
;
}
}
}
elsif
(
$action
eq
"reload"
) {
$changed
= 1;
if
(
$srvc
->reload(
$service
) ) {
Rex::Logger::info(
"Service $service is reloaded."
);
$return
= 1
if
!
$is_multiple
;
}
else
{
Rex::Logger::info(
"Error $service does not support reload"
,
"warn"
);
$return
= 0
if
!
$is_multiple
;
}
}
elsif
(
$action
eq
"status"
) {
$changed
= 100;
if
(
$srvc
->status(
$service
) ) {
Rex::Logger::info(
"Service $service is running."
);
$return
= 1
if
!
$is_multiple
;
}
else
{
Rex::Logger::info(
"$service is stopped"
);
$return
= 0
if
!
$is_multiple
;
}
}
elsif
(
$action
eq
"ensure"
) {
if
(
$srvc
->ensure(
$service
, {
ensure
=>
$options
} ) ) {
$changed
= 0;
$return
= 1
if
!
$is_multiple
;
}
else
{
$return
= 0
if
!
$is_multiple
;
Rex::Logger::info(
"Error ensuring $service to $options"
);
}
}
else
{
Rex::Logger::info(
"Executing action $action on $service."
);
$srvc
->action(
$service
,
$action
);
$changed
= 100;
}
if
(
$changed
) {
Rex::get_current_connection()->{reporter}
->report(
changed
=>
$changed
,
message
=>
"Service executed $action."
);
}
else
{
Rex::get_current_connection()->{reporter}->report(
changed
=> 0, );
}
Rex::get_current_connection()->{reporter}
->report_resource_end(
type
=>
"service"
,
name
=>
$service
);
return
$return
;
}
sub
service_provider_for {
my
(
$os
,
$provider
) =
@_
;
Rex::Logger::debug(
"setting service provider for $os to $provider"
);
Rex::Config->set(
"service_provider"
, {
$os
=>
$provider
} );
}
1;