diff --git a/init/config.info b/init/config.info index 9ed4b0d3b..7f778fa2e 100644 --- a/init/config.info +++ b/init/config.info @@ -1,11 +1,12 @@ line1=Configurable options,11 expert=Allow selection of individual runlevels?,1,1-Yes,0-No desc=Display actions with descriptions,1,2-Yes, and show all runlevels,1-Yes,0-No +systemd_dedicated=Hide systemd services table?,1,-No,1-Yes order=Show boot order of actions?,1,1-Yes,0-No status_check=Show current status of actions,1,2-On index and action pages,1-On action page only,0-No sort_mode=Sort actions by,1,1-Boot order,0-Name line2=System configuration,11 -init_mode=Boot system,4,-Detect automatically,init-SysV init,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-FreeBSD RC scripts,win32-Windows services,local-Single boot script +init_mode=Boot system,4,-Detect automatically,systemd-Systemd,init-SysV init,openrc-OpenRC,upstart-Upstart,local-Single boot script,rc-FreeBSD RC scripts,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Windows services init_base=Directory in which runlevel directories are located,0 init_dir=Directory containing master init scripts,0 order_digits=Number of digits in action order,0 @@ -17,8 +18,8 @@ shutdown_command=Command to shutdown the system,0 inittab_id=inittab ID for bootup runlevel,0 rc_dir=FreeBSD rc scripts directories,3,None rc_conf=FreeBSD configuration files,3,None -line3=OSX system configuration,11 -startup_dirs=Darwin StartupItems directories,0 +line3=macOS StartupItems configuration,11 +startup_dirs=macOS StartupItems directories,0 darwin_setup=Directory for custom StartupItems,0 -hostconfig=Darwin hostconfig file,0 +hostconfig=Legacy hostconfig file,0 plist=Name of plist in a StartupItems directory,0 diff --git a/init/config.info.ca b/init/config.info.ca index 02d2e5360..2388274e4 100644 --- a/init/config.info.ca +++ b/init/config.info.ca @@ -5,7 +5,7 @@ order=Mostra l'ordre d'engegada de les accions,1,1-Sí,0-No status_check=Mostra l'estat actual de les accions,1,2-A les pàgines d'índex i de l'acció,1-Només a la pàgina de l'acció,0-No sort_mode=Ordena les accions per,1,1-Ordre d'engegada,0-Nom line2=Configuració del sistema,11 -init_mode=Engegada del sistema,4,-Detecta-ho automàticament,init-Init de SysV,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-Scripts RC de FreeBSD,win32-Serveis Windows,local-Script únic d'engegada +init_mode=Engegada del sistema,4,-Detecta-ho automàticament,systemd-Systemd,init-Init de SysV,openrc-OpenRC,upstart-Upstart,local-Script únic d'engegada,rc-Scripts RC de FreeBSD,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Serveis Windows init_base=Directori on s'allotgen els directoris de nivells d'execució,0 init_dir=Directori que conté els scripts init mestres,0 order_digits=Nombre de dígits de l'ordre de l'acció,0 diff --git a/init/config.info.de b/init/config.info.de index 4a0b7ffef..a54c5687d 100644 --- a/init/config.info.de +++ b/init/config.info.de @@ -5,7 +5,7 @@ order=Zeige die Aktionen in Reihenfolge des Starts an?,1,1-Ja,0-Nein status_check=Zeige aktuellen Status der Aktionen,1,2-Auf Index- und Aktionen-Seite,1-Nur auf der Aktionen-Seite,0-Nein sort_mode=Sortiere Aktionen nach,1,1-Boot-Reihenfolge,0-Name line2=Systemkonfiguration,11 -init_mode=Boot-System,4,-automatisch erkennen,init-SysV init,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-FreeBSD RC Script,win32-Windows-Dienste,local-Single Bootskript +init_mode=Boot-System,4,-automatisch erkennen,systemd-Systemd,init-SysV init,openrc-OpenRC,upstart-Upstart,local-Single Bootskript,rc-FreeBSD RC Script,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Windows-Dienste init_base=Verzeichnis, in dem die Runlevel-Verzeichnisse liegen,0 init_dir=Verzeichnis, in dem das Haupt-Skript liegt,0 order_digits=Anzahl Ziffern in Aktionsreihenfolge,0 diff --git a/init/config.info.no b/init/config.info.no index 227712c50..c75fcf84e 100644 --- a/init/config.info.no +++ b/init/config.info.no @@ -5,7 +5,7 @@ order=Vis handlingenes oppstartsrekkefølge?1,1-Ja,0-Nei status_check=Vis handlingenes gjeldende status,1,2-På indeks- og handlingssider,1-Bare på handlingssider,0-Nei sort_mode=Sorter handlinger etter,1,1-Oppstartrekkefølge,0-Navn line2=System konfigurasjon,11 -init_mode=Oppstartssystem,4,-Oppdag automatisk,init-SysV init,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-FreeBSD RC scripts,win32-Windows tjenester,local-Enkelt oppstartsscript +init_mode=Oppstartssystem,4,-Oppdag automatisk,systemd-Systemd,init-SysV init,openrc-OpenRC,upstart-Upstart,local-Enkelt oppstartsscript,rc-FreeBSD RC scripts,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Windows tjenester init_base=Katalog hvor kjøretids-kataloger finnes,0 init_dir=Katalog som inneholder master init scripts,0 order_digits=Antall sifre i handlingssortering,0 diff --git a/init/index.cgi b/init/index.cgi index c87868ae9..31cb73e1b 100755 --- a/init/index.cgi +++ b/init/index.cgi @@ -329,70 +329,74 @@ elsif ($init_mode eq "upstart" && $access{'bootup'}) { } elsif ($init_mode eq "systemd" && $access{'bootup'}) { - # Show systemd actions - print &ui_form_start("mass_systemd.cgi", "post"); - @links = ( &select_all_link("d"), - &select_invert_link("d"), - &ui_link("edit_systemd.cgi?new=1", $text{'index_sadd'}) ); - print &ui_links_row(\@links); - print &ui_columns_start([ "", $text{'systemd_name'}, - $config{'desc'} ? $text{'systemd_desc'} : (), - $text{'systemd_type'}, - $text{'systemd_status'}, - $text{'systemd_boot'}, - $text{'index_ustatus'} ]); - my $units_piped = join('|', map { quotemeta } &get_systemd_unit_types()); - foreach $u (&list_systemd_services()) { - if ($u->{'legacy'}) { - $l = "edit_action.cgi?0+".&urlize($u->{'name'}); - } - else { - $l = "edit_systemd.cgi?name=".&urlize($u->{'name'}); - } - my $sname = $u->{'name'}; - my ($type) = $sname =~ /\.([^.]+)$/; - if (defined($type) && $type =~ /^(?:$units_piped)$/) { - $sname =~ s/\.$type$//; - } - else { - $type = ''; - } - my $title = ($u->{'boot'} == -1 ? - &html_escape($sname) : - &ui_link($l, &html_escape($sname))); - my $desc = $config{'desc'} ? &html_escape($u->{'desc'}) : undef; - print &ui_columns_row([ - &ui_checkbox("d", $u->{'name'}, undef), - $title, - $desc // (), - $type, - $u->{'fullstatus'} || "$text{'index_unknown'}", - $u->{'boot'} == 1 ? - &ui_text_color("$text{'yes'}", 'success') : - $u->{'boot'} == 2 ? - &ui_text_color("$text{'index_sboot6'}", 'success') : - $u->{'boot'} == -1 ? - &ui_text_color("$text{'index_sboot5'}", 'warn') : - &ui_text_color("$text{'no'}", 'warn'), - $u->{'status'} == 1 ? &ui_text_color("$text{'yes'}", 'success') : - $u->{'status'} == 0 ? - &ui_text_color("$text{'no'}", 'warn') : - "$text{'index_unknown'}", - ]); + if (!&init_show_systemd_services()) { + my $systemd_link = &ui_tag('a', + $text{'index_systemd_module'}, + { 'href' => '../systemd/' }); + print &ui_alert_box( + &text('index_systemd_dedicated', $systemd_link), + 'info', undef, undef, ""),"\n"; } - print &ui_columns_end(); - print &ui_links_row(\@links); - print &ui_form_end([ [ "start", $text{'index_start'} ], - [ "stop", $text{'index_stop'} ], - [ "restart", $text{'index_restart'} ], - undef, - [ "addboot", $text{'index_addboot'} ], - [ "delboot", $text{'index_delboot'} ], - undef, - [ "addboot_start", $text{'index_addboot_start'} ], - [ "delboot_stop", $text{'index_delboot_stop'} ], - ]); + else { + # Show systemd actions + print &ui_form_start("mass_systemd.cgi", "post"); + @links = ( &select_all_link("d"), + &select_invert_link("d"), + &ui_link("edit_systemd.cgi?new=1", + $text{'index_sadd'}) ); + print &ui_links_row(\@links); + print &ui_columns_start([ "", $text{'systemd_name'}, + $config{'desc'} ? + $text{'systemd_desc'} : (), + $text{'systemd_status'}, + $text{'systemd_boot'}, + $text{'index_ustatus'} ]); + foreach $u (&list_systemd_services()) { + if ($u->{'legacy'}) { + $l = "edit_action.cgi?0+".&urlize($u->{'name'}); + } + else { + $l = "edit_systemd.cgi?name=".&urlize($u->{'name'}); + } + my $sname = $u->{'name'}; + $sname =~ s/\.service$//; + my $title = ($u->{'boot'} == -1 ? + &html_escape($sname) : + &ui_link($l, &html_escape($sname))); + my $desc = $config{'desc'} ? + &html_escape($u->{'desc'}) : undef; + print &ui_columns_row([ + &ui_checkbox("d", $u->{'name'}, undef), + $title, + $desc // (), + $u->{'fullstatus'} || "$text{'index_unknown'}", + $u->{'boot'} == 1 ? + &ui_text_color("$text{'yes'}", 'success') : + $u->{'boot'} == 2 ? + &ui_text_color("$text{'index_sboot6'}", 'success') : + $u->{'boot'} == -1 ? + &ui_text_color("$text{'index_sboot5'}", 'warn') : + &ui_text_color("$text{'no'}", 'warn'), + $u->{'status'} == 1 ? &ui_text_color("$text{'yes'}", 'success') : + $u->{'status'} == 0 ? + &ui_text_color("$text{'no'}", 'warn') : + "$text{'index_unknown'}", + ]); + } + print &ui_columns_end(); + print &ui_links_row(\@links); + print &ui_form_end([ [ "start", $text{'index_start'} ], + [ "stop", $text{'index_stop'} ], + [ "restart", $text{'index_restart'} ], + undef, + [ "addboot", $text{'index_addboot'} ], + [ "delboot", $text{'index_delboot'} ], + undef, + [ "addboot_start", $text{'index_addboot_start'} ], + [ "delboot_stop", $text{'index_delboot_stop'} ], + ]); + } } elsif ($init_mode eq "launchd" && $access{'bootup'}) { # Show launchd agents @@ -449,4 +453,3 @@ if ($access{'shutdown'}) { print &ui_buttons_end(); &ui_print_footer("/", $text{'index'}); - diff --git a/init/init-lib.pl b/init/init-lib.pl index 620f8351d..451047399 100644 --- a/init/init-lib.pl +++ b/init/init-lib.pl @@ -28,9 +28,9 @@ use WebminCore; This variable is set based on the bootup system in use. Possible values are : -=item osx - MacOSX hostconfig files, for older versions +=item osx - Legacy macOS StartupItems and hostconfig files -=item launchd - MacOS Launchd, for newer versions +=item launchd - macOS launchd, for newer versions =item rc - FreeBSD 6+ RC files @@ -2311,16 +2311,15 @@ if (@list_systemd_services_cache && !$noinit) { return @list_systemd_services_cache; } -my $units_piped = join('|', &get_systemd_unit_types()); - # Get all systemd unit names my $out = &backquote_command("systemctl list-units --full --all -t service --no-legend"); my $ex = $?; foreach my $l (split(/\r?\n/, $out)) { $l =~ s/^[^a-z0-9\-\_\.]+//i; my ($unit, $loaded, $active, $sub, $desc) = split(/\s+/, $l, 5); + next if ($unit !~ /\.service$/); my $a = $unit; - $a =~ s/\.($units_piped)$//; + $a =~ s/\.service$//; my $f = &action_filename($a); if ($unit ne "UNIT" && $loaded eq "loaded" && !-r $f) { push(@units, $unit); @@ -2332,29 +2331,26 @@ foreach my $l (split(/\r?\n/, $out)) { # and so don't show up in systemctl list-units my $root = &get_systemd_root(undef, 1); opendir(UNITS, $root); -push(@units, grep { !/\.wants$/ && !/^\./ && !-d "$root/$_" } readdir(UNITS)); +push(@units, grep { /\.service$/ && !-d "$root/$_" } readdir(UNITS)); closedir(UNITS); # Also add units from list-unit-files that also don't show up $out = &backquote_command("systemctl list-unit-files -t service --no-legend"); foreach my $l (split(/\r?\n/, $out)) { - if ($l =~ /^(\S+\.($units_piped))\s+disabled/ || - $l =~ /^(\S+)\s+disabled/) { + if ($l =~ /^(\S+\.service)\s+disabled/) { push(@units, $1); } } # Skip useless units @units = grep { !/^sys-devices-/ && - !/^\-\.mount/ && - !/^\-\.slice/ && !/^dev-/ && !/^systemd-/ } @units; @units = &unique(@units); # Filter out templates -my @templates = grep { /\@$/ || /\@\.($units_piped)$/ } @units; -@units = grep { !/\@$/ && !/\@\.($units_piped)$/ } @units; +my @templates = grep { /\@$/ || /\@\.service$/ } @units; +@units = grep { !/\@$/ && !/\@\.service$/ } @units; # Dump state of all of them, 100 at a time my %info; @@ -3142,11 +3138,90 @@ return $name =~ /\./ ? $name : "com.webmin.".$name; } # config_pre_load(mod-info, [mod-order]) -# Check if some config options are conditional +# Hides config options that do not apply to the detected boot system. sub config_pre_load { my ($modconf_info, $modconf_order) = @_; -$modconf_info->{'desc'} =~ s/2-[^,]+,// if ($init_mode eq "systemd"); +return if (ref($modconf_info) ne 'HASH'); + +if ($init_mode eq "systemd" && $modconf_info->{'desc'}) { + # Systemd has no runlevels, so keep only the plain yes/no choices. + $modconf_info->{'desc'} =~ s/2-[^,]+,//; + } + +my %keep = map { $_, 1 } &init_config_options_for_mode($init_mode); +foreach my $key (keys %$modconf_info) { + delete($modconf_info->{$key}) if (!$keep{$key}); + } +if (ref($modconf_order) eq 'ARRAY') { + @$modconf_order = grep { $keep{$_} } @$modconf_order; + } +&hide_single_init_config_section($modconf_info, $modconf_order); +} + +# init_config_options_for_mode(mode) +# Returns config.info keys that should be visible for a boot system. +sub init_config_options_for_mode +{ +my ($mode) = @_; +my @display = ( 'expert', 'desc', 'order', 'status_check', 'sort_mode' ); +my @common = ( 'init_mode', 'reboot_command', 'shutdown_command' ); +my @sysv = ( @common, 'init_base', 'init_dir', 'order_digits', + 'boot_levels', 'local_script', 'local_down', 'inittab_id' ); +my @systemd_display = ( 'desc' ); +push(@systemd_display, 'systemd_dedicated') + if (&init_dedicated_systemd_module_available()); + +return ( 'line1', @systemd_display, 'line2', @common ) + if ($mode eq 'systemd'); +return ( 'line1', @display, 'line2', @sysv ) + if ($mode eq 'init' || $mode eq 'upstart' || $mode eq 'openrc'); +return ( 'line2', @common, 'local_script', 'local_down', + 'rc_dir', 'rc_conf' ) + if ($mode eq 'rc'); +return ( 'line2', @common, 'local_script', 'local_down' ) + if ($mode eq 'local'); +return ( 'line2', @common, 'line3', 'startup_dirs', 'darwin_setup', + 'hostconfig', 'plist' ) + if ($mode eq 'osx'); +return ( 'line2', @common ) + if ($mode eq 'launchd' || $mode eq 'win32'); +return ( 'line1', @display, 'line2', @sysv, 'rc_dir', 'rc_conf', + 'line3', 'startup_dirs', 'darwin_setup', 'hostconfig', 'plist' ); +} + +# hide_single_init_config_section(&config-info, [&config-order]) +# Removes the lone section header when filtering leaves only one group. +sub hide_single_init_config_section +{ +my ($modconf_info, $modconf_order) = @_; +my @sections = grep { + exists($modconf_info->{$_}) && + (split(/,/, $modconf_info->{$_}))[1] == 11 + } keys %$modconf_info; +return if (@sections != 1); + +delete($modconf_info->{$sections[0]}); +if (ref($modconf_order) eq 'ARRAY') { + @$modconf_order = grep { $_ ne $sections[0] } @$modconf_order; + } +} + +# init_dedicated_systemd_module_available() +# Returns 1 if the standalone Systemd module can be used by this Webmin user. +sub init_dedicated_systemd_module_available +{ +return &foreign_available("systemd") && &foreign_installed("systemd"); +} + +# init_show_systemd_services() +# Returns 1 if this module should show its legacy systemd service table. +sub init_show_systemd_services +{ +return 1 if (!&init_dedicated_systemd_module_available()); +return 0 if ($config{'systemd_dedicated'} && + $config{'systemd_dedicated'} eq '1'); +return 1; } 1; diff --git a/init/lang/en b/init/lang/en index 7844f1c36..1dbd92582 100644 --- a/init/lang/en +++ b/init/lang/en @@ -188,13 +188,14 @@ change_title=Switch Runlevel change_cmd=Switching to runlevel $1 with command $2. This may take some time, and Webmin might not be available anymore after switching. mode_init=SysV init -mode_osx=MacOS +mode_osx=Legacy macOS StartupItems mode_local=Single boot script mode_win32=Windows services mode_rc=FreeBSD RC scripts mode_upstart=Upstart mode_systemd=Systemd -mode_launchd=LaunchD +mode_launchd=macOS launchd +mode_openrc=OpenRC upstart_title1=Create Upstart Service upstart_title2=Edit Upstart Service @@ -246,6 +247,8 @@ systemd_edesc=Missing unit description systemd_return=systemd unit systemd_econf=No systemd unit configuration entered systemd_estart=Missing commands to run on startup +index_systemd_module=Systemd Services and Units +index_systemd_dedicated=Use the dedicated $1 module to manage systemd services and units. This page now shows only system reboot and shutdown controls. launchd_title1=Create Launchd Agent launchd_title2=Edit Launchd Agent