Work on upstart support in bootup module
authorJamie Cameron <jcameron@webmin.com>
Fri, 15 Apr 2011 01:31:20 +0000 (18:31 -0700)
committerJamie Cameron <jcameron@webmin.com>
Fri, 15 Apr 2011 01:31:20 +0000 (18:31 -0700)
init/index.cgi
init/init-lib.pl
init/lang/en

index 212ec79..5b104e2 100755 (executable)
@@ -5,7 +5,8 @@
 
 require './init-lib.pl';
 require './hostconfig-lib.pl';
-&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
+&ui_print_header(&text('index_mode', $text{'mode_'.$init_mode}),
+                $text{'index_title'}, "", undef, 1, 1);
 
 if ($init_mode eq "osx" && $access{'bootup'}) {
        # This hostconfig if block written by Michael A Peters <mpeters@mac.com>
@@ -60,6 +61,9 @@ elsif ($init_mode eq "init" && $access{'bootup'}) {
                                }
                        }
                }
+
+       # For each action, look at /etc/rc*.d/* files to see if it is 
+       # started at boot
        @boot = &get_inittab_runlevel();
        for($i=0; $i<@acts; $i++) {
                foreach $s (&action_levels('S', $acts[$i])) {
@@ -300,6 +304,46 @@ elsif ($init_mode eq "rc" && $access{'bootup'}) {
                             [ "delboot_stop", $text{'index_delboot_stop'} ],
                            ]);
        }
+elsif ($init_mode eq "upstart" && $access{'bootup'}) {
+       # Show upstart actions
+       print &ui_form_start("mass_upstarts.cgi", "post");
+       @links = ( &select_all_link("d"),
+                  &select_invert_link("d"),
+                  "<a href='edit_upstart.cgi?new=1'>$text{'index_uadd'}</a>" );
+       print &ui_links_row(\@links);
+       print &ui_columns_start([ "", $text{'index_uname'},
+                                 $text{'index_udesc'},
+                                 $text{'index_uboot'},
+                                 $text{'index_ustatus'}, ]);
+       foreach $u (&list_upstart_services()) {
+               print &ui_columns_row([
+                       &ui_checkbox("d", $u->{'name'}, undef),
+                       "<a href='edit_upstart.cgi?name=".
+                         &urlize($u->{'name'})."'>$u->{'name'}</a>",
+                       $u->{'desc'},
+                       $u->{'boot'} eq 'start' ? $text{'yes'} :
+                         $u->{'boot'} eq 'stop' ?
+                         "<font color=#ff0000>$text{'no'}</font>" :
+                         "<i>$text{'index_unknown'}</i>",
+                       $u->{'status'} eq 'running' ? $text{'yes'} :
+                         $u->{'status'} eq 'waiting' ?
+                         "<font color=#ff0000>$text{'no'}</font>" :
+                         "<i>$text{'index_unknown'}</i>",
+                       ]);
+               }
+       print &ui_columns_end();
+       print &ui_links_row(\@links);
+       print &ui_form_end([ [ "start", $text{'index_start'} ],
+                            [ "stop", $text{'index_stop'} ],
+                            undef,
+                            [ "addboot", $text{'index_addboot'} ],
+                            [ "delboot", $text{'index_delboot'} ],
+                            undef,
+                            [ "addboot_start", $text{'index_addboot_start'} ],
+                            [ "delboot_stop", $text{'index_delboot_stop'} ],
+                           ]);
+
+       }
 
 # reboot/shutdown buttons
 print &ui_hr();
index 1d8d3a8..4e19217 100755 (executable)
@@ -45,6 +45,10 @@ if ($config{'hostconfig'}) {
 elsif ($config{'rc_dir'}) {
        $init_mode = "rc";
        }
+elsif ($config{'init_base'} && -d "/etc/init" &&
+       &has_command("insserv") && &has_command("initctl")) {
+       $init_mode = "upstart";
+       }
 elsif ($config{'init_base'}) {
        $init_mode = "init";
        }
@@ -429,17 +433,6 @@ if ($config{'chkconfig'}) {
                        }
                }
        }
-elsif ($_[0] =~ /^\/etc\/init.d\/(\S+)$/ && -r "/etc/init/$1.conf") {
-       # Upstart description file exists
-       open(CONF, "/etc/init/$1.conf");
-       while(<CONF>) {
-               if (/^description\s+"([^"]+)"/) {
-                       $desc = $1;
-                       last;
-                       }
-               }
-       close(CONF);
-       }
 elsif ($config{'init_info'} || $data =~ /BEGIN INIT INFO/) {
        # Find the suse-style Description: line
        foreach (@lines) {
@@ -522,6 +515,22 @@ if ($init_mode eq "init") {
                }
        return !$exists ? 0 : $starting ? 2 : 1;
        }
+elsif ($init_mode eq "upstart") {
+       # Check service status
+       local $out = &backquote_command("initctl ".quotemeta($_[0])." 2>&1");
+       if ($?) {
+               # Upstart doesn't know about it
+               return 0;
+               }
+       elsif (-r "/etc/init/$_[0].conf") {
+               # Config script exists
+               return 2;
+               }
+       else {
+               # Not started
+               return 1;
+               }
+       }
 elsif ($init_mode eq "local") {
        # Look for entry in rc.local
        local $fn = "$module_config_directory/$_[0].sh";
@@ -894,11 +903,6 @@ if ($init_mode eq "init") {
                # Call chkconfig to remove the links
                &system_logged("chkconfig ".quotemeta($_[0])." off");
                }
-       elsif (&has_command("insserv") && !$config{'no_chkconfig'} &&
-              $data =~ /Default-Start:/i) {
-               # Call insserv to remove the links
-               &system_logged("insserv -r ".quotemeta($_[0]));
-               }
        else {
                # Just unlink the S links
                foreach (&action_levels('S', $_[0])) {
@@ -916,6 +920,12 @@ if ($init_mode eq "init") {
                        }
                }
        }
+elsif ($init_mode eq "upstart") {
+       # Just use insserv to disable, and rename away .conf file
+       &system_logged("insserv -r ".quotemeta($_[0]));
+       &rename_logged("/etc/init/$_[0].conf",
+                      "/etc/init/$_[0].conf.disabled");
+       }
 elsif ($init_mode eq "local") {
        # Take out of rc.local file
        local $lref = &read_file_lines($config{'local_script'});
@@ -999,6 +1009,10 @@ elsif ($init_mode eq "win32") {
        local $err = &start_win32_service($name);
        return (!$err, $err);
        }
+elsif ($init_mode eq "upstart") {
+       # Run upstart action
+       return &start_upstart_service($name);
+       }
 else {
        return (0, "Bootup mode $init_mode not supported");
        }
@@ -1039,6 +1053,10 @@ elsif ($init_mode eq "win32") {
        local $err = &stop_win32_service($name);
        return (!$err, $err);
        }
+elsif ($init_mode eq "upstart") {
+       # Stop upstart action
+       return &stop_upstart_service($name);
+       }
 else {
        return (0, "Bootup mode $init_mode not supported");
        }
@@ -1463,6 +1481,65 @@ foreach my $f (split(/\s+/, $config{'rc_conf'})) {
        }
 }
 
+=head2 list_upstart_services
+
+Returns a list of all known upstart services, each of which is a hash ref
+with 'name', 'desc', 'boot', 'status' and 'pid' keys.
+
+=cut
+sub list_upstart_services
+{
+my @rv;
+my $out = &backquote_command("initctl list");
+foreach my $l (split(/\r?\n/, $out)) {
+       if ($l =~ /^(\S+)\s+(start|stop)\/([a-z]+)/) {
+               my $s = { 'name' => $1,
+                         'goal' => $2,
+                         'status' => $3 };
+               if ($l =~ /process\s+(\d+)/) {
+                       $s->{'pid'} = $1;
+                       }
+               open(CONF, "/etc/init/$s->{'name'}.conf") ||
+                  open(CONF, "/etc/init/$s->{'name'}.conf.disabled");
+               while(<CONF>) {
+                       if (/^description\s+"([^"]+)"/) {
+                               $s->{'desc'} = $1;
+                               last;
+                               }
+                       }
+               close(CONF);
+               if (-r "/etc/init/$s->{'name'}.conf") {
+                       $s->{'boot'} = 'start';
+                       }
+               elsif (-r "/etc/init/$s->{'name'}.conf.disabled") {
+                       $s->{'boot'} = 'stop';
+                       }
+               push(@rv, $s);
+               }
+       }
+return sort { $a->{'name'} cmp $b->{'name'} } @rv;
+}
+
+# start_upstart_service(name)
+# Run the upstart service with some name, and return an OK flag and output
+sub start_upstart_service
+{
+my ($name) = @_;
+my $out = &backquote_logged(
+       "service ".quotemeta($name)." start 2>&1 </dev/null");
+return (!$?, $out);
+}
+
+# stop_upstop_service(name)
+# Shut down the upstop service with some name, and return an OK flag and output
+sub stop_upstop_service
+{
+my ($name) = @_;
+my $out = &backquote_logged(
+       "service ".quotemeta($name)." stop 2>&1 </dev/null");
+return (!$?, $out);
+}
+
 =head2 reboot_system
 
 Immediately reboots the system.
index 78c203a..2164138 100644 (file)
@@ -1,4 +1,5 @@
 index_title=Bootup and Shutdown
+index_mode=Boot system : $1
 index_add=Create a new bootup and shutdown action.
 index_reboot=Reboot System
 index_rebootmsg=Click on this button to immediately reboot the system. All currently logged in users will be disconnected and all services will be re-started.
@@ -42,6 +43,11 @@ index_rdesc=Description
 index_rboot=Start at boot?
 index_radd=Create a new action.
 index_unknown=Unknown
+index_uname=Service name
+index_udesc=Service description
+index_uboot=Start at boot?
+index_ustatus=Running now?
+index_uadd=Create a new service.
 
 edit_title=Edit Action
 create_title=Create Action
@@ -164,4 +170,11 @@ change_err=You are not allowed to switch runlevels
 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_local=Single boot script
+mode_win32=Windows services
+mode_rc=FreeBSD RC scripts
+mode_upstart=Upstart
+
 __norefs=1