From b4e446c21e299af0441ec44db7a86334980b77c2 Mon Sep 17 00:00:00 2001 From: Angelo Naselli Date: Mon, 16 Mar 2015 19:20:40 +0100 Subject: Moved the tree accordingly --- lib/ManaTools/Shared/Services.pm | 955 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 955 insertions(+) create mode 100644 lib/ManaTools/Shared/Services.pm (limited to 'lib/ManaTools/Shared/Services.pm') diff --git a/lib/ManaTools/Shared/Services.pm b/lib/ManaTools/Shared/Services.pm new file mode 100644 index 0000000..abef8c3 --- /dev/null +++ b/lib/ManaTools/Shared/Services.pm @@ -0,0 +1,955 @@ +# vim: set et ts=4 sw=4: +package ManaTools::Shared::Services; +#============================================================= -*-perl-*- + +=head1 NAME + +ManaTools::Shared::Services - shares the API to manage services + +=head1 SYNOPSIS + +use ManaTools::Shared::Services; + +my $serv = ManaTools::Shared::Services->new(); + +my ($l, $on_services) = $serv->services(); + +=head1 DESCRIPTION + + This module aims to share all the API to manage system services, + to be used from GUI applications or console. + + From the original code drakx services. + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command: + +perldoc ManaTools::Shared::Services + +=head1 SEE ALSO + +ManaTools::Shared + +=head1 AUTHOR + +Angelo Naselli + +=head1 COPYRIGHT and LICENSE + +Copyright (C) 2013-2015, Angelo Naselli. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2, as +published by the Free Software Foundation. + +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +=head1 FUNCTIONS + +=cut + + +use Moose; + +use Sys::Syslog; +use Net::DBus; +use Net::DBus::Annotation qw(:auth); +use File::Basename; + +use ManaTools::Shared::Locales; +use MDK::Common::Func qw(find); +use MDK::Common::File; +use MDK::Common::DataStructure qw(member); +use ManaTools::Shared::RunProgram qw(rooted); + +has 'loc' => ( + is => 'rw', + init_arg => undef, + builder => '_localeInitialize' +); + + +sub _localeInitialize { + my $self = shift(); + + # TODO fix domain binding for translation + $self->loc(ManaTools::Shared::Locales->new(domain_name => 'libDrakX') ); + # TODO if we want to give the opportunity to test locally add dir_name => 'path' +} + + +has 'dbus_systemd1_service' => ( + is => 'rw', + init_arg => undef, + lazy => 1, + builder => '_dbusServiceInitialize' +); + +sub _dbusServiceInitialize { + my $self = shift(); + + my $bus = Net::DBus->system; + $self->dbus_systemd1_service($bus->get_service("org.freedesktop.systemd1")); +} + + +has 'dbus_systemd1_object' => ( + is => 'rw', + init_arg => undef, + lazy => 1, + builder => '_dbusObjectInitialize' +); + +sub _dbusObjectInitialize { + my $self = shift(); + + $self->dbus_systemd1_object($self->dbus_systemd1_service->get_object("/org/freedesktop/systemd1")); +} + + +has 'service_info' => ( + is => 'rw', + traits => ['Hash'], + isa => 'HashRef', + handles => { + set_service_info => 'set', + get_service_info => 'get', + service_info_pairs => 'kv', + }, + init_arg => undef, + lazy => 1, + builder => '_serviceInfoInitialization' +); + +sub _serviceInfoInitialization { + my $self = shift(); + + my %services = (); + if ($self->_running_systemd()) { + my $object = $self->dbus_systemd1_object; + my $properties = $object->ListUnits(); + + foreach my $s (@{$properties}) { + my $name = $s->[0]; + if (index($name, ".service") != -1) { + my $st = eval{$object->GetUnitFileState($name)} if $name !~ /.*\@.*$/g; + $name =~ s|.service||; + if (!$st) { + if ($name !~ /.*\@$/g && + (-e "/usr/lib/systemd/system/$name.service" or -e "/etc/rc.d/init.d/$name") && + ! -l "/usr/lib/systemd/system/$name.service") { + $st = 'enabled'; + } + } + if ($st && $st ne 'static') { + $services{$name} = { + 'name' => $s->[0], + 'description' => $s->[1], + 'load_state' => $s->[2], + 'active_state' => $s->[3], + 'sub_state' => $s->[4], + 'unit_path' => $s->[6], + 'enabled' => $st eq 'enabled', + }; + } + } + } + + my $unit_files = $object->ListUnitFiles(); + foreach my $s (@{$unit_files}) { + my $name = $s->[0]; + my $st = $s->[1]; + if (index($name, ".service") != -1) { + $name = File::Basename::basename($name, ".service"); + if (!$services{$name} && + $name !~ /.*\@$/g && + (-e $s->[0] or -e "/etc/rc.d/init.d/$name") && + ! -l $s->[0] && ($st eq "disabled" || $st eq "enabled")) { + my $wantedby = $self->_WantedBy($s->[0]); + if ($wantedby) { + my $descr = $self->getUnitProperty($name, 'Description'); + + $services{$name} = { + 'name' => $name, + 'description' => $descr, + 'enabled' => $st eq "enabled", + }; + } + } + } + } + } + + return \%services; +} + +#============================================================= + +=head2 description + +=head3 INPUT + +name: Service Name + +=head3 OUTPUT + +Description: Service description + +=head3 DESCRIPTION + +THis function return the description for the given service + +=cut + +#============================================================= +sub description { + my ($self, $name) = @_; + + my %services = ( +acpid => $self->loc->N_("Listen and dispatch ACPI events from the kernel"), +alsa => $self->loc->N_("Launch the ALSA (Advanced Linux Sound Architecture) sound system"), +anacron => $self->loc->N_("Anacron is a periodic command scheduler."), +apmd => $self->loc->N_("apmd is used for monitoring battery status and logging it via syslog. +It can also be used for shutting down the machine when the battery is low."), +atd => $self->loc->N_("Runs commands scheduled by the at command at the time specified when +at was run, and runs batch commands when the load average is low enough."), +'avahi-deamon' => $self->loc->N_("Avahi is a ZeroConf daemon which implements an mDNS stack"), +chronyd => $self->loc->N_("An NTP client/server"), +cpufreq => $self->loc->N_("Set CPU frequency settings"), +crond => $self->loc->N_("cron is a standard UNIX program that runs user-specified programs +at periodic scheduled times. vixie cron adds a number of features to the basic +UNIX cron, including better security and more powerful configuration options."), +cups => $self->loc->N_("Common UNIX Printing System (CUPS) is an advanced printer spooling system"), +dm => $self->loc->N_("Launches the graphical display manager"), +fam => $self->loc->N_("FAM is a file monitoring daemon. It is used to get reports when files change. +It is used by GNOME and KDE"), +g15daemon => $self->loc->N_("G15Daemon allows users access to all extra keys by decoding them and +pushing them back into the kernel via the linux UINPUT driver. This driver must be loaded +before g15daemon can be used for keyboard access. The G15 LCD is also supported. By default, +with no other clients active, g15daemon will display a clock. Client applications and +scripts can access the LCD via a simple API."), +gpm => $self->loc->N_("GPM adds mouse support to text-based Linux applications such the +Midnight Commander. It also allows mouse-based console cut-and-paste operations, +and includes support for pop-up menus on the console."), +haldaemon => $self->loc->N_("HAL is a daemon that collects and maintains information about hardware"), +harddrake => $self->loc->N_("HardDrake runs a hardware probe, and optionally configures +new/changed hardware."), +httpd => $self->loc->N_("Apache is a World Wide Web server. It is used to serve HTML files and CGI."), +inet => $self->loc->N_("The internet superserver daemon (commonly called inetd) starts a +variety of other internet services as needed. It is responsible for starting +many services, including telnet, ftp, rsh, and rlogin. Disabling inetd disables +all of the services it is responsible for."), +ip6tables => $self->loc->N_("Automates a packet filtering firewall with ip6tables"), +iptables => $self->loc->N_("Automates a packet filtering firewall with iptables"), +irqbalance => $self->loc->N_("Evenly distributes IRQ load across multiple CPUs for enhanced performance"), +keytable => $self->loc->N_("This package loads the selected keyboard map as set in +/etc/sysconfig/keyboard. This can be selected using the kbdconfig utility. +You should leave this enabled for most machines."), +kheader => $self->loc->N_("Automatic regeneration of kernel header in /boot for +/usr/include/linux/{autoconf,version}.h"), +kudzu => $self->loc->N_("Automatic detection and configuration of hardware at boot."), +'laptop-mode' => $self->loc->N_("Tweaks system behavior to extend battery life"), +linuxconf => $self->loc->N_("Linuxconf will sometimes arrange to perform various tasks +at boot-time to maintain the system configuration."), +lpd => $self->loc->N_("lpd is the print daemon required for lpr to work properly. It is +basically a server that arbitrates print jobs to printer(s)."), +lvs => $self->loc->N_("Linux Virtual Server, used to build a high-performance and highly +available server."), +mandi => $self->loc->N_("Monitors the network (Interactive Firewall and wireless"), +mdadm => $self->loc->N_("Software RAID monitoring and management"), +messagebus => $self->loc->N_("DBUS is a daemon which broadcasts notifications of system events and other messages"), +msec => $self->loc->N_("Enables MSEC security policy on system startup"), +named => $self->loc->N_("named (BIND) is a Domain Name Server (DNS) that is used to resolve host names to IP addresses."), +netconsole => $self->loc->N_("Initializes network console logging"), +netfs => $self->loc->N_("Mounts and unmounts all Network File System (NFS), SMB (Lan +Manager/Windows), and NCP (NetWare) mount points."), +network => $self->loc->N_("Activates/Deactivates all network interfaces configured to start +at boot time."), +'network-auth' => $self->loc->N_("Requires network to be up if enabled"), +'network-up' => $self->loc->N_("Wait for the hotplugged network to be up"), +nfs => $self->loc->N_("NFS is a popular protocol for file sharing across TCP/IP networks. +This service provides NFS server functionality, which is configured via the +/etc/exports file."), +nfslock => $self->loc->N_("NFS is a popular protocol for file sharing across TCP/IP +networks. This service provides NFS file locking functionality."), +ntpd => $self->loc->N_("Synchronizes system time using the Network Time Protocol (NTP)"), +numlock => $self->loc->N_("Automatically switch on numlock key locker under console +and Xorg at boot."), +oki4daemon => $self->loc->N_("Support the OKI 4w and compatible winprinters."), +partmon => $self->loc->N_("Checks if a partition is close to full up"), +pcmcia => $self->loc->N_("PCMCIA support is usually to support things like ethernet and +modems in laptops. It will not get started unless configured so it is safe to have +it installed on machines that do not need it."), +portmap => $self->loc->N_("The portmapper manages RPC connections, which are used by +protocols such as NFS and NIS. The portmap server must be running on machines +which act as servers for protocols which make use of the RPC mechanism."), +portreserve => $self->loc->N_("Reserves some TCP ports"), +postfix => $self->loc->N_("Postfix is a Mail Transport Agent, which is the program that moves mail from one machine to another."), +random => $self->loc->N_("Saves and restores system entropy pool for higher quality random +number generation."), +rawdevices => $self->loc->N_("Assign raw devices to block devices (such as hard disk drive +partitions), for the use of applications such as Oracle or DVD players"), +resolvconf => $self->loc->N_("Nameserver information manager"), +routed => $self->loc->N_("The routed daemon allows for automatic IP router table updated via +the RIP protocol. While RIP is widely used on small networks, more complex +routing protocols are needed for complex networks."), +rstatd => $self->loc->N_("The rstat protocol allows users on a network to retrieve +performance metrics for any machine on that network."), +rsyslog => $self->loc->N_("Syslog is the facility by which many daemons use to log messages to various system log files. It is a good idea to always run rsyslog."), +rusersd => $self->loc->N_("The rusers protocol allows users on a network to identify who is +logged in on other responding machines."), +rwhod => $self->loc->N_("The rwho protocol lets remote users get a list of all of the users +logged into a machine running the rwho daemon (similar to finger)."), +saned => $self->loc->N_("SANE (Scanner Access Now Easy) enables to access scanners, video cameras, ..."), +shorewall => $self->loc->N_("Packet filtering firewall"), +smb => $self->loc->N_("The SMB/CIFS protocol enables to share access to files & printers and also integrates with a Windows Server domain"), +sound => $self->loc->N_("Launch the sound system on your machine"), +'speech-dispatcherd' => $self->loc->N_("layer for speech analysis"), +sshd => $self->loc->N_("Secure Shell is a network protocol that allows data to be exchanged over a secure channel between two computers"), +syslog => $self->loc->N_("Syslog is the facility by which many daemons use to log messages +to various system log files. It is a good idea to always run syslog."), +'udev-post' => $self->loc->N_("Moves the generated persistent udev rules to /etc/udev/rules.d"), +usb => $self->loc->N_("Load the drivers for your usb devices."), +vnStat => $self->loc->N_("A lightweight network traffic monitor"), +xfs => $self->loc->N_("Starts the X Font Server."), +xinetd => $self->loc->N_("Starts other deamons on demand."), + ); + + my $s = $services{$name}; + if ($s) { + $s = $self->loc->N($s); + } + elsif ($self->get_service_info($name)) { + $s = $self->get_service_info($name)->{description}; + } + else { + my $file = "/usr/lib/systemd/system/$name.service"; + if (-e $file) { + $s = MDK::Common::File::cat_($file); + $s = $s =~ /^Description=(.*)/mg ? $1 : ''; + } else { + $file = MDK::Common::Func::find { -e $_ } map { "$_/$name" } '/etc/rc.d/init.d', '/etc/init.d', '/etc/xinetd.d'; + $s = MDK::Common::File::cat_($file); + $s =~ s/\\\s*\n#\s*//mg; + $s = + $s =~ /^#\s+(?:Short-)?[dD]escription:\s+(.*?)^(?:[^#]|# {0,2}\S)/sm ? $1 : + $s =~ /^#\s*(.*?)^[^#]/sm ? $1 : ''; + + $s =~ s/#\s*//mg; + } + } + $s =~ s/\n/ /gm; $s =~ s/\s+$//; + $s; +} + + +#============================================================= + +=head2 set_service + +=head3 INPUT + + $service: Service name + $enable: enable/disable service + +=head3 DESCRIPTION + + This function enable/disable at boot the given service + +=cut + +#============================================================= +sub set_service { + my ($self, $service, $enable) = @_; + + my @xinetd_services = map { $_->[0] } $self->xinetd_services(); + + if (MDK::Common::DataStructure::member($service, @xinetd_services)) { + $ENV{PATH} = "/usr/bin:/usr/sbin"; + ManaTools::Shared::RunProgram::rooted("", "/usr/sbin/chkconfig", $enable ? "--add" : "--del", $service); + } elsif ($self->_running_systemd() || $self->_has_systemd()) { + $service = $service . ".service"; + my $dbus_object = $self->dbus_systemd1_object; + if ($enable) { + $dbus_object->EnableUnitFiles(dbus_auth_interactive, [$service], 0, 1); + } + else { + $dbus_object->DisableUnitFiles(dbus_auth_interactive, [$service], 0); + } + # reload local cache + $self->_systemd_services(1); + } else { + my $script = "/etc/rc.d/init.d/$service"; + $ENV{PATH} = "/usr/bin:/usr/sbin"; + ManaTools::Shared::RunProgram::rooted("", "/usr/sbin/chkconfig", $enable ? "--add" : "--del", $service); + #- FIXME: handle services with no chkconfig line and with no Default-Start levels in LSB header + if ($enable && MDK::Common::File::cat_("$script") =~ /^#\s+chkconfig:\s+-/m) { + $ENV{PATH} = "/usr/bin:/usr/sbin"; + ManaTools::Shared::RunProgram::rooted("", "/usr/sbin/chkconfig", "--level", "35", $service, "on"); + } + } +} + +sub _run_action { + my ($self, $service, $action) = @_; + if ($self->_running_systemd()) { + my $object = $self->dbus_systemd1_object; + if ($action eq 'start') { + $object->StartUnit(dbus_auth_interactive, "$service.service", 'fail'); + } + elsif ($action eq 'stop') { + $object->StopUnit(dbus_auth_interactive, "$service.service", 'fail'); + } + else { + $object->RestartUnit(dbus_auth_interactive, "$service.service", 'fail'); + } + # reload local cache + $self->_systemd_services(1); + } else { + $ENV{PATH} = "/usr/bin:/usr/sbin:/etc/rc.d/init.d/"; + ManaTools::Shared::RunProgram::rooted("", "/etc/rc.d/init.d/$service", $action); + } +} + +sub _running_systemd { + my $self = shift; + + $ENV{PATH} = "/usr/bin:/usr/sbin"; + ManaTools::Shared::RunProgram::rooted("", '/usr/bin/mountpoint', '-q', '/sys/fs/cgroup/systemd'); +} + +sub _has_systemd { + my $self = shift; + + $ENV{PATH} = "/usr/bin:/usr/sbin"; + ManaTools::Shared::RunProgram::rooted("", '/usr/bin/rpm', '-q', 'systemd'); +} + +#============================================================= + +=head2 xinetd_services + +=head3 OUTPUT + + xinetd_services: All the xinetd services + +=head3 DESCRIPTION + + This functions returns all the xinetd services in the system. + NOTE that xinetd *must* be enable at boot to get this info + +=cut + +#============================================================= +sub xinetd_services { + my $self = shift; + + my @xinetd_services = (); + + #avoid warning if xinetd is not installed and either enabled + my $ser_info = $self->get_service_info('xinetd'); + if ($ser_info && $ser_info->{enabled} eq "1") { + local $ENV{LANGUAGE} = 'C'; + $ENV{PATH} = "/usr/bin:/usr/sbin"; + foreach (ManaTools::Shared::RunProgram::rooted_get_stdout("", '/usr/sbin/chkconfig', '--list', '--type', 'xinetd')) { + if (my ($xinetd_name, $on_off) = m!^\t(\S+):\s*(on|off)!) { + push @xinetd_services, [ $xinetd_name, $on_off eq 'on' ]; + } + } + } + return @xinetd_services; +} + +sub _systemd_services { + my ($self, $reload) = @_; + + if ($reload) { + $self->service_info($self->_serviceInfoInitialization()); + } + + my @services; + for my $pair ( $self->service_info_pairs) { + my $name = $pair->[0]; + my $info = $pair->[1]; + push @services, [$name, $info->{'enabled'}]; + } + + return @services; + +} + +sub _legacy_services { + my $self = shift; + + local $ENV{LANGUAGE} = 'C'; + my @services; + my $has_systemd = $self->_has_systemd(); + if ($has_systemd) { + # The system not using systemd but will be at next boot. This is + # is typically the case in the installer. In this mode we must read + # as much as is practicable from the native systemd unit files and + # combine that with information from chkconfig regarding legacy sysvinit + # scripts (which systemd will parse and include when running) + Sys::Syslog::syslog('info|local1', "Detected systemd installed. Using fake service+chkconfig introspection."); + foreach (glob_("/usr/lib/systemd/system/*.service")) { + my ($name) = m!([^/]*).service$!; + + # We only look at non-template, non-symlinked service files + if (!(/.*\@\.service$/g) && ! -l $_) { + # Limit ourselves to "standard" targets + my $wantedby = MDK::Common::File::cat_($_) =~ /^WantedBy=(graphical|multi-user).target$/sm ? $1 : ''; + if ($wantedby) { + # Exclude if enabled statically + # Note DO NOT use -e when testing for files that could + # be symbolic links as this will fail under a chroot + # setup where -e will fail if the symlink target does + # exist which is typically the case when viewed outside + # of the chroot. + if (!-l "/usr/lib/systemd/system/$wantedby.target.wants/$name.service") { + push @services, [ $name, !!-l "/etc/systemd/system/$wantedby.target.wants/$name.service" ]; + } + } + } + } + } else { + Sys::Syslog::syslog('info|local1', "Could not detect systemd. Using chkconfig service introspection."); + } + + # Regardless of whether we expect to use systemd on next boot, we still + # need to instrospect information about non-systemd native services. + my $runlevel; + my $on_off; + if (!$::isInstall) { + $runlevel = (split " ", `/sbin/runlevel`)[1]; + } + foreach (ManaTools::Shared::RunProgram::rooted_get_stdout("", '/sbin/chkconfig', '--list', '--type', 'sysv')) { + if (my ($name, $l) = m!^(\S+)\s+(0:(on|off).*)!) { + # If we expect to use systemd (i.e. installer) only show those + # sysvinit scripts which are not masked by a native systemd unit. + my $has_systemd_unit = $self->_systemd_unit_exists($name); + if (!$has_systemd || !$has_systemd_unit) { + if ($::isInstall) { + $on_off = $l =~ /\d+:on/g; + } else { + $on_off = $l =~ /$runlevel:on/g; + } + push @services, [ $name, $on_off ]; + } + } + } + @services; +} + +#- returns: +#--- the listref of installed services +#--- the listref of "on" services +#============================================================= + +=head2 services + +=head3 INPUT + + $reload: load service again + +=head3 OUTPUT + + @l: all the system services + @on_services: all the services that start at boot + +=head3 DESCRIPTION + + This function returns two lists, all the system service and + all the active ones. + +=cut + +#============================================================= + + +sub services { + my ($self, $reload) = @_; + + my @Services; + if ($self->_running_systemd()) { + @Services = $self->_systemd_services($reload); + } else { + @Services = $self->_legacy_services(); + } + + my @l = $self->xinetd_services(); + push @l, @Services; + @l = sort { $a->[0] cmp $b->[0] } @l; + [ map { $_->[0] } @l ], [ map { $_->[0] } grep { $_->[1] } @l ]; +} + + +# if we loaded service info, then exists +sub _systemd_unit_exists { + my ($self, $name) = @_; + + return defined ($self->get_service_info($name)); +} + +#============================================================= + +=head2 service_exists + +=head3 INPUT + + $service: Service name + +=head3 OUTPUT + + 0/1: if the service exists + +=head3 DESCRIPTION + + This function checks if a service is installed by looking for + its unit or init.d service + +=cut + +#============================================================= + +sub service_exists { + my ($self, $service) = @_; + $self->_systemd_unit_exists($service) or -x "/etc/rc.d/init.d/$service"; +} + +#============================================================= + +=head2 restart + +=head3 INPUT + + $service: Service to restart + +=head3 DESCRIPTION + + This function restarts a given service + +=cut + +#============================================================= + + +sub restart { + my ($self, $service) = @_; + # Exit silently if the service is not installed + $self->service_exists($service) or return 1; + $self->_run_action($service, "restart"); +} + +#============================================================= + +=head2 restart_or_start + +=head3 INPUT + + $service: Service to restart or start + +=head3 DESCRIPTION + + This function starts a given service if it is not running, + it restarts that otherwise + +=cut + +#============================================================= + +sub restart_or_start { + my ($self, $service) = @_; + # Exit silently if the service is not installed + $self->service_exists($service) or return 1; + $self->_run_action($service, $self->is_service_running($service) ? "restart" : "start"); +} + + +#============================================================= + +=head2 startService + +=head3 INPUT + + $service: Service to start + +=head3 DESCRIPTION + + This function starts a given service + +=cut + +#============================================================= + +sub startService { + my ($self, $service) = @_; + # Exit silently if the service is not installed + $self->service_exists($service) or return 1; + $self->_run_action($service, "start"); +} + +#============================================================= + +=head2 start_not_running_service + +=head3 INPUT + + $service: Service to start + +=head3 DESCRIPTION + + This function starts a given service if not running + +=cut + +#============================================================= + +sub start_not_running_service { + my ($self, $service) = @_; + # Exit silently if the service is not installed + $self->service_exists($service) or return 1; + $self->is_service_running($service) || $self->_run_action($service, "start"); +} + +#============================================================= + +=head2 stopService + +=head3 INPUT + + $service: Service to stop + +=head3 DESCRIPTION + + This function stops a given service + +=cut + +#============================================================= +sub stopService { + my ($self, $service) = @_; + # Exit silently if the service is not installed + $self->service_exists($service) or return 1; + $self->_run_action($service, "stop"); +} + +#============================================================= + +=head2 is_service_running + +=head3 INPUT + + $service: Service to check + +=head3 DESCRIPTION + + This function returns if the given service is running + +=cut + +#============================================================= + +sub is_service_running { + my ($self, $service) = @_; + # Exit silently if the service is not installed + $self->service_exists($service) or return 0; + my $out; + if ($self->_running_systemd()) { + my $ser_info = $self->get_service_info($service); + $out = $ser_info->{active_state} eq 'active' if $ser_info->{active_state}; + } else { + $ENV{PATH} = "/usr/bin:/usr/sbin"; + $out = ManaTools::Shared::RunProgram::rooted("", '/usr/sbin/service', $service, 'status'); + } + return $out; +} + +#============================================================= + +=head2 starts_on_boot + +=head3 INPUT + + $service: Service name + + +=head3 DESCRIPTION + + This function returns if the given service starts at boot + +=cut + +#============================================================= +sub starts_on_boot { + my ($self, $service) = @_; + my (undef, $on_services) = $self->services(); + MDK::Common::DataStructure::member($service, @$on_services); +} + +#============================================================= + +=head2 start_service_on_boot + +=head3 INPUT + + $service: Service name + + +=head3 DESCRIPTION + + This function set the given service active at boot + +=cut + +#============================================================= +sub start_service_on_boot { + my ($self, $service) = @_; + $self->set_service($service, 1); +} + +#============================================================= + +=head2 do_not_start_service_on_boot + +=head3 INPUT + + $service: Service name + + +=head3 DESCRIPTION + + This function set the given service disabled at boot + +=cut + +#============================================================= +sub do_not_start_service_on_boot { + my ($self, $service) = @_; + $self->set_service($service, 0); +} + +#============================================================= + +=head2 enable + +=head3 INPUT + + $service: Service name + $o_dont_apply: do not start it now + +=head3 DESCRIPTION + + This function set the given service active at boot + and restarts it if o_dont_apply is not given + +=cut + +#============================================================= +sub enable { + my ($self, $service, $o_dont_apply) = @_; + $self->start_service_on_boot($service); + $self->restart_or_start($service) unless $o_dont_apply; +} + +#============================================================= + +=head2 disable + +=head3 INPUT + + $service: Service name + $o_dont_apply: do not stop it now + +=head3 DESCRIPTION + + This function set the given service disabled at boot + and stops it if o_dont_apply is not given + +=cut + +#============================================================= +sub disable { + my ($self, $service, $o_dont_apply) = @_; + $self->do_not_start_service_on_boot($service); + $self->stopService($service) unless $o_dont_apply; +} + +#============================================================= + +=head2 set_status + +=head3 INPUT + + $service: Service name + $enable: Enable/disable + $o_dont_apply: do not start it now + +=head3 DESCRIPTION + + This function set the given service to enable/disable at boot + and restarts/stops it if o_dont_apply is not given + +=cut + +#============================================================= +sub set_status { + my ($self, $service, $enable, $o_dont_apply) = @_; + if ($enable) { + $self->enable($service, $o_dont_apply); + } else { + $self->disable($service, $o_dont_apply); + } +} + +# NOTE $service->get_object("/org/freedesktop/systemd1/unit/$name_2eservice"); +# has empty WantedBy property if disabled +sub _WantedBy { + my ($self, $path_service) = @_; + + my $wantedby = MDK::Common::File::cat_($path_service) =~ /^WantedBy=(graphical|multi-user).target$/sm ? $1 : ''; + + return $wantedby; +} + +#============================================================= + +=head2 getUnitProperty + +=head3 INPUT + + $unit: unit name + $property: property name + +=head3 OUTPUT + + $property_value: property value + +=head3 DESCRIPTION + + This method returns the requested property value + +=cut + +#============================================================= +sub getUnitProperty { + my ($self, $unit, $property) = @_; + + my $name = $unit . ".service"; + $name =~ s|-|_2d|g; + $name =~ s|\.|_2e|g; + my $service = $self->dbus_systemd1_service; + my $unit_object = $service->get_object("/org/freedesktop/systemd1/unit/" . $name); + my $property_value = eval {$unit_object->Get("org.freedesktop.systemd1.Unit", $property)} || ""; + + return $property_value; +} + +1; -- cgit v1.2.1