summaryrefslogtreecommitdiffstats
path: root/perl-install/services.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/services.pm')
-rw-r--r--perl-install/services.pm307
1 files changed, 215 insertions, 92 deletions
diff --git a/perl-install/services.pm b/perl-install/services.pm
index 7b122b097..a99ef038e 100644
--- a/perl-install/services.pm
+++ b/perl-install/services.pm
@@ -1,4 +1,4 @@
-package services; # $Id: services.pm 267089 2010-03-28 12:51:44Z tv $
+package services;
@@ -11,8 +11,7 @@ use strict;
use common;
use run_program;
-use common;
-use run_program;
+use File::Basename;
sub description {
my %services = (
@@ -24,6 +23,7 @@ It can also be used for shutting down the machine when the battery is low."),
atd => 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' => N_("Avahi is a ZeroConf daemon which implements an mDNS stack"),
+chronyd => N_("An NTP client/server"),
cpufreq => N_("Set CPU frequency settings"),
crond => 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
@@ -50,8 +50,6 @@ many services, including telnet, ftp, rsh, and rlogin. Disabling inetd disables
all of the services it is responsible for."),
ip6tables => N_("Automates a packet filtering firewall with ip6tables"),
iptables => N_("Automates a packet filtering firewall with iptables"),
-ipchains => N_("Launch packet filtering for Linux kernel 2.2 series, to set
-up a firewall to protect your machine from network attacks."),
irqbalance => N_("Evenly distributes IRQ load across multiple CPUs for enhanced performance"),
keytable => N_("This package loads the selected keyboard map as set in
/etc/sysconfig/keyboard. This can be selected using the kbdconfig utility.
@@ -98,7 +96,7 @@ portreserve => N_("Reserves some TCP ports"),
postfix => N_("Postfix is a Mail Transport Agent, which is the program that moves mail from one machine to another."),
random => N_("Saves and restores system entropy pool for higher quality random
number generation."),
-rawdevices => N_("Assign raw devices to block devices (such as hard drive
+rawdevices => 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 => N_("Nameserver information manager"),
routed => N_("The routed daemon allows for automatic IP router table updated via
@@ -113,6 +111,7 @@ rwhod => 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 => N_("SANE (Scanner Access Now Easy) enables to access scanners, video cameras, ..."),
shorewall => N_("Packet filtering firewall"),
+shorewall6 => N_("Packet filtering firewall for IPv6"),
smb => N_("The SMB/CIFS protocol enables to share access to files & printers and also integrates with a Windows Server domain"),
sound => N_("Launch the sound system on your machine"),
'speech-dispatcherd' => N_("layer for speech analysis"),
@@ -130,14 +129,20 @@ xinetd => N_("Starts other deamons on demand."),
if ($s) {
$s = translate($s);
} else {
- my $file = find { -e $_ } map { "$::prefix$_/$name" } '/etc/rc.d/init.d', '/etc/init.d', '/etc/xinetd.d';
- $s = 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;
+ my $file = "$::prefix/usr/lib/systemd/system/$name.service";
+ if (-e $file) {
+ $s = cat_($file);
+ $s = $s =~ /^Description=(.*)/mg ? $1 : '';
+ } else {
+ $file = find { -e $_ } map { "$::prefix$_/$name" } '/etc/rc.d/init.d', '/etc/init.d', '/etc/xinetd.d';
+ $s = 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;
@@ -146,20 +151,26 @@ xinetd => N_("Starts other deamons on demand."),
sub ask_ {
my ($in) = @_;
my %root_services = (
- N("Printing") => [ qw(cups cupslpd lpr lpd oki4daemon hpoj cups-lpd) ],
- N("Internet") => [ qw(httpd boa tux roxen ftp pftp tftp proftpd wu-ftpd pure-ftpdipsec proftpd-xinetd
- ipchains iptables ip6tables ipvsadm isdn4linux ibod jabber jabber-icq adsl squid
- portsentry prelude nessusd junkbuster radvd cddbp ippl iptoip jail.init) ],
- N("File sharing") => [ qw(nfs-common nfs-server nfslock smb nettalk netfs mcserv autofs amd
- venus.init auth2.init codasrv.init update.init swat) ],
- N("System") => [ qw(usb usbd pcmcia irda xinetd inetd kudzu harddrake apmd sound network xfs
- alsa functions halt kheader killall mageia_everytime mageia_firstime
- random rawdevices single keytable syslog crond medusa-init portmap rpcbind acon
- anacron atd gpm psacct wine acpid numlock jserver sensors mosix bpowerd bpowerfail
- fcron powertweak.init ups syslog-ng cvs apcupsd) ],
- N("Remote Administration") => [ qw(sshd telnetd telnet rsh rlogin rexec webmin cfd heartbeat ldirectord
- iplog mon vncserver netsaint olympusd drakxtools_http) ],
-# N("Network Client") => [ qw(ypbind nscd arpwatch fetchmail dnrd_rc diald rsync) ],
+ N("Printing") => [ qw(cups cupslpd cups-lpd hpoj lpd lpr oki4daemon) ],
+
+ # FIXME: split part of 'Internet' into 'Security' or 'Firewall'?
+ N("Internet") => [ qw(adsl boa cddbp ftp httpd ibod ip6tables ippl iptables iptoip ipvsadm
+ isdn4linux jabber jabber-icq jail.init junkbuster mandi nessusd pftp portsentry
+ prelude proftpd proftpd-xinetd pure-ftpd ipsec radvd roxen shorewall shorewall6 squid
+ tftp) ],
+
+ N("_: Keep these entry short\nNetworking") => [ qw(network network-auth network-up resolvconf) ],
+
+ N("System") => [ qw(acon acpid alsa anacron apcupsd apmd atd bpowerd bpowerfail crond cvs dm fcron functions
+ gpm halt harddrake inetd irda jserver keytable kheader killall mageia_everytime
+ mandrake_firstime mdadm medusa-init messagebus microcode_ctl mosix netconsole numlock partmon
+ pcmcia portmap powertweak.init psacct
+ random rawdevices rpcbind sensors single sound syslog syslog-ng ups usb usbd wine xfs xinetd) ],
+
+ N("Remote Administration") => [ qw(cfd drakxtools_http heartbeat iplog ldirectord mon netsaint olympusd rexec
+ rlogin rsh sshd telnet telnetd vncserver webmin) ],
+
+# N("Network Client") => [ qw(arpwatch diald dnrd_rc fetchmail nscd rsync ypbind) ],
# N("Network Server") => [ qw(named bootparamd ntpd xntpd chronyd postfix sendmail
# imap imaps ipop2 ipop3 pop3s routed yppasswdd ypserv ldap dhcpd dhcrelay
# hylafax innd identd rstatd rusersd rwalld rwhod gated
@@ -200,9 +211,7 @@ sub ask_ {
},
get_info => sub { formatLines(description($_[0])) },
interactive_help => sub {
- interactive::gtk::display_help($in,
- { interactive_help_id =>
- 'misc-params#drakxid-configureServices' }, $::main_window) },
+ interactive::gtk::display_help($in, { interactive_help_id => 'configureServices' }) },
}) or return $l, $on_services; #- no change on cancel.
[ grep { $services{$_} } @$l ];
}
@@ -210,47 +219,34 @@ sub ask_ {
sub ask_standalone_gtk {
my ($_in) = @_;
my ($l, $on_services) = services();
- my @xinetd_services = map { $_->[0] } @{(services_raw())[1]};
-
- require ugtk2;
- ugtk2->import(qw(:wrappers :create));
-
- my $W = ugtk2->new(N("Services"));
- my ($x, $y, $w_popup);
- my $nopop = sub { $w_popup and $w_popup->destroy; undef $w_popup };
- my $display = sub {
- my ($text) = @_;
- $nopop->();
- gtkshow(gtkadd($w_popup = Gtk2::Window->new('popup'),
- gtksignal_connect(gtkadd(Gtk2::EventBox->new,
- gtkadd(gtkset_shadow_type(Gtk2::Frame->new, 'etched_out'),
- gtkset_justify(Gtk2::Label->new($text), 'left'))),
- button_press_event => sub { $nopop->() }
- )))->move($x, $y) if $text;
- };
+ my @xinetd_services = map { $_->[0] } xinetd_services();
+
+ require ugtk3;
+ ugtk3->import(qw(:wrappers :create));
+
+ my $W = ugtk3->new(N("Services"));
my $update_service = sub {
my ($service, $label) = @_;
- my $started = -e "/var/lock/subsys/$service";
+ my $started = is_service_running($service);
$label->set_label($started ? N("running") : N("stopped"));
};
- my $b = Gtk2::EventBox->new;
- $b->set_events('pointer_motion_mask');
+ my $b = Gtk3::EventBox->new;
+ $b->set_events(${ Gtk3::Gdk::EventMask->new("pointer_motion_mask") });
gtkadd($W->{window}, gtkadd($b, gtkpack_($W->create_box_with_title,
- 0, mygtk2::gtknew('Title1', label => N("Services and daemons")),
+ 0, mygtk3::gtknew('Title1', label => N("Services and daemons")),
1, gtkset_size_request(create_scrolled_window(create_packtable({ col_spacings => 10, row_spacings => 3 },
map {
my $service = $_;
my $is_xinetd_service = member($service, @xinetd_services);
my $infos = warp_text(description($_), 40);
$infos ||= N("No additional information\nabout this service, sorry.");
- my $label = gtkset_justify(Gtk2::Label->new, 'left');
+ my $label = gtkset_justify(Gtk3::Label->new, 'left');
$update_service->($service, $label) if !$is_xinetd_service;
- [ gtkpack__(Gtk2::HBox->new(0,0), $_),
- gtkpack__(Gtk2::HBox->new(0,0), $label),
- gtkpack__(Gtk2::HBox->new(0,0), gtksignal_connect(Gtk2::Button->new(N("Info")), clicked => sub { $display->($infos) })),
+ [ gtkpack__(Gtk3::HBox->new(0,0), gtkset_tip(Gtk3::Label->new($_), $infos)),
+ gtkpack__(Gtk3::HBox->new(0,0), $label),
- gtkpack__(Gtk2::HBox->new(0,0), gtkset_active(gtksignal_connect(
- Gtk2::CheckButton->new($is_xinetd_service ? N("Start when requested") : N("On boot")),
+ gtkpack__(Gtk3::HBox->new(0,0), gtkset_active(gtksignal_connect(
+ Gtk3::CheckButton->new($is_xinetd_service ? N("Start when requested") : N("On boot")),
clicked => sub { if ($_[0]->get_active) {
push @$on_services, $service if !member($service, @$on_services);
} else {
@@ -258,7 +254,7 @@ sub ask_standalone_gtk {
} }), member($service, @$on_services))),
map {
my $a = $_;
- gtkpack__(Gtk2::HBox->new(0,0), gtksignal_connect(Gtk2::Button->new(translate($a)),
+ gtkpack__(Gtk3::HBox->new(0,0), gtksignal_connect(Gtk3::Button->new(translate($a)),
clicked => sub {
my $action = $a eq "Start" ? 'restart' : 'stop';
log::explanations(qq(GP_LANG="UTF-8" service $service $action));
@@ -266,19 +262,14 @@ sub ask_standalone_gtk {
local $_ = `GP_LANG="UTF-8" service $service $action 2>&1`; s/\033\[[^mG]*[mG]//g;
c::set_tagged_utf8($_);
$update_service->($service, $label);
- $display->($_);
})) if !$is_xinetd_service;
} (N_("Start"), N_("Stop"))
];
}
@$l), [ $::isEmbedded ? 'automatic' : 'never', 'automatic' ]), -1, $::isEmbedded ? -1 : 400),
- 0, gtkpack(gtkset_border_width(Gtk2::HBox->new(0,0),5), $W->create_okcancel)
+ 0, gtkpack(gtkset_border_width(Gtk3::HBox->new(0,0),5), $W->create_okcancel)
))
);
- $b->signal_connect(motion_notify_event => sub { my ($w, $e) = @_;
- my ($ox, $oy) = $w->window->get_origin;
- $x = $e->x+$ox; $y = $e->y+$oy });
- $b->signal_connect(button_press_event => sub { $nopop->() });
$::isEmbedded and gtkflush();
$W->main or return;
$on_services;
@@ -291,17 +282,39 @@ sub ask {
sub _set_service {
my ($service, $enable) = @_;
- my $script = "/etc/rc.d/init.d/$service";
- run_program::rooted($::prefix, "chkconfig", $enable ? "--add" : "--del", $service);
- #- FIXME: handle services with no chkconfig line and with no Default-Start levels in LSB header
- if ($enable && cat_("$::prefix$script") =~ /^#\s+chkconfig:\s+-/m) {
- run_program::rooted($::prefix, "chkconfig", "--level", "35", $service, "on");
+
+ my @xinetd_services = map { $_->[0] } xinetd_services();
+
+ # General Note: We use --no-reload here as this code is sometimes triggered
+ # from code at boot and reloading systemd during boot is generally a bit
+ # racy just now it seems.
+ if (member($service, @xinetd_services)) {
+ run_program::rooted($::prefix, "chkconfig", "--no-reload", $enable ? "--add" : "--del", $service); # Probably still a bug here as xinet support in chkconfig shells out to /sbin/service....
+ } elsif (running_systemd() || has_systemd()) {
+ # systemctl rejects any symlinked units. You have to enabled the real file
+ if (-l "/lib/systemd/system/$service.service") {
+ $service = basename(readlink("/lib/systemd/system/$service.service"));
+ } else {
+ $service = $service . ".service";
+ }
+ run_program::rooted($::prefix, "/bin/systemctl", $enable ? "enable" : "disable", "--no-reload", $service);
+ } else {
+ my $script = "/etc/rc.d/init.d/$service";
+ run_program::rooted($::prefix, "chkconfig", "--no-reload", $enable ? "--add" : "--del", $service);
+ #- FIXME: handle services with no chkconfig line and with no Default-Start levels in LSB header
+ if ($enable && cat_("$::prefix$script") =~ /^#\s+chkconfig:\s+-/m) {
+ run_program::rooted($::prefix, "chkconfig", "--no-reload", "--level", "35", $service, "on");
+ }
}
}
sub _run_action {
my ($service, $action) = @_;
- run_program::rooted($::prefix, "/etc/rc.d/init.d/$service", $action);
+ if (running_systemd()) {
+ run_program::rooted($::prefix, '/bin/systemctl', '--no-block', $action, "$service.service");
+ } else {
+ run_program::rooted($::prefix, "/etc/rc.d/init.d/$service", $action);
+ }
}
sub doit {
@@ -322,43 +335,149 @@ sub doit {
}
}
-sub services_raw() {
+sub running_systemd() {
+ run_program::rooted($::prefix, '/bin/mountpoint', '-q', '/sys/fs/cgroup/systemd');
+}
+
+sub has_systemd() {
+ run_program::rooted($::prefix, '/bin/rpm', '-q', 'systemd');
+}
+
+sub xinetd_services() {
local $ENV{LANGUAGE} = 'C';
- my (@services, @xinetd_services);
- foreach (run_program::rooted_get_stdout($::prefix, '/sbin/chkconfig', '--list')) {
- if (my ($xinetd_name, $on_off) = m!^\t(\S+):\s*(on|off)!) {
- push @xinetd_services, [ $xinetd_name, $on_off eq 'on' ];
- } elsif (my ($name, $l) = m!^(\S+)\s+(0:(on|off).*)!) {
- push @services, [ $name, [ $l =~ /(\d+):on/g ] ];
- }
+ my @xinetd_services;
+ foreach (run_program::rooted_get_stdout($::prefix, '/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' ];
+ }
}
- \@services, \@xinetd_services;
+ @xinetd_services;
}
-#- returns:
+sub _systemd_services() {
+ local $ENV{LANGUAGE} = 'C';
+ my @services;
+ my %loaded;
+ # Running system using systemd
+ log::explanations("Detected systemd running. Using systemctl introspection.");
+ foreach (run_program::rooted_get_stdout($::prefix, '/bin/systemctl', '--no-legend', '--no-pager', '--full', '--all', 'list-units')) {
+ if (my ($name) = m!^(\S+)\.service\s+loaded!) {
+ # We only look at non-template, non-linked service files in /lib
+ # We also check for any non-masked sysvinit files as these are
+ # also handled by systemd
+ if ($name !~ /.*\@$/g && (-e "$::prefix/lib/systemd/system/$name.service" or -e "$::prefix/etc/rc.d/init.d/$name") && ! -l "$::prefix/lib/systemd/system/$name.service") {
+ push @services, [ $name, !!run_program::rooted($::prefix, '/bin/systemctl', '--quiet', 'is-enabled', "$name.service") ];
+ $loaded{$name} = 1;
+ }
+ }
+ }
+ # list-units will not list disabled units that can be enabled
+ foreach (run_program::rooted_get_stdout($::prefix, '/bin/systemctl', '--no-legend', '--no-pager', '--full', 'list-unit-files')) {
+ if (my ($name) = m!^(\S+)\.service\s+disabled!) {
+ # We only look at non-template, non-linked service files in /lib
+ # We also check for any non-masked sysvinit files as these are
+ # also handled by systemd
+ if (!exists $loaded{$name} && $name !~ /.*\@$/g && (-e "$::prefix/lib/systemd/system/$name.service" or -e "$::prefix/etc/rc.d/init.d/$name") && ! -l "$::prefix/lib/systemd/system/$name.service") {
+ # Limit ourselves to "standard" targets which can be enabled
+ my $wantedby = cat_("$::prefix/lib/systemd/system/$name.service") =~ /^WantedBy=(graphical|multi-user).target$/sm ? $1 : '';
+ if ($wantedby) {
+ push @services, [ $name, 0 ];
+ }
+ }
+ }
+ }
+
+ @services;
+}
+
+sub _legacy_services() {
+ local $ENV{LANGUAGE} = 'C';
+ my @services;
+ my $has_systemd = 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)
+ log::explanations("Detected systemd installed. Using fake service+chkconfig introspection.");
+ foreach (glob_("$::prefix/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 = 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 "$::prefix/lib/systemd/system/$wantedby.target.wants/$name.service") {
+ push @services, [ $name, !!-l "$::prefix/etc/systemd/system/$wantedby.target.wants/$name.service" ];
+ }
+ }
+ }
+ }
+ } else {
+ log::explanations("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 (run_program::rooted_get_stdout($::prefix, '/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 = 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
sub services() {
- my ($services, $xinetd_services) = services_raw();
- my @l = @$xinetd_services;
- if ($::isInstall) {
- push @l, map { [ $_->[0], @{$_->[1]} > 0 ] } @$services;
+ my @services;
+ if (running_systemd()) {
+ @services = _systemd_services();
} else {
- my $runlevel = (split " ", `/sbin/runlevel`)[1];
- push @l, map { [ $_->[0], member($runlevel, @{$_->[1]}) ] } @$services;
+ @services = _legacy_services();
}
+
+ my @l = xinetd_services();
+ push @l, @services;
@l = sort { $a->[0] cmp $b->[0] } @l;
[ map { $_->[0] } @l ], [ map { $_->[0] } grep { $_->[1] } @l ];
}
-
-
+sub systemd_unit_exists {
+ my ($name) = @_;
+ # we test with -l as symlinks are not valid when the system is chrooted:
+ -e "$::prefix/lib/systemd/system/$name.service" or -l "$::prefix/lib/systemd/system/$name.service";
+}
sub service_exists {
my ($service) = @_;
- -x "$::prefix/etc/rc.d/init.d/$service";
+ -x "$::prefix/etc/rc.d/init.d/$service" or systemd_unit_exists($service);
}
sub restart ($) {
@@ -400,7 +519,11 @@ sub is_service_running ($) {
my ($service) = @_;
# Exit silently if the service is not installed
service_exists($service) or return 1;
- run_program::rooted($::prefix, "/etc/rc.d/init.d/$service", '>', '/dev/null', '2>', '/dev/null', "status");
+ if (running_systemd()) {
+ run_program::rooted($::prefix, '/bin/systemctl', '--quiet', 'is-active', "$service.service");
+ } else {
+ run_program::rooted($::prefix, '/sbin/service', $service, 'status');
+ }
}
sub starts_on_boot {