[system-tools-backends-clone] Base Upstart support (for /etc/init.d scripts only)
- From: Milan Bouchet-Valat <milanbv src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [system-tools-backends-clone] Base Upstart support (for /etc/init.d scripts only)
- Date: Wed, 30 Sep 2009 20:21:32 +0000 (UTC)
commit 24ae335fbd828410cb3e7c082adba18ad068a4a7
Author: Milan Bouchet-Valat <nalimilan club fr>
Date: Mon Sep 28 22:26:05 2009 +0200
Base Upstart support (for /etc/init.d scripts only)
Add a new "upstart" init system type that is for now a modified copy of our SystemV support. Use it under Debian systems. More precisely, we need to discard scripts from /etc/init.d that are also present in /etc/init, because they're only compatibility symlinks we should not play with. We also use "service" to start/stop scripts, instead of running them directly. This way, we don't break under Upstart, but only support traditional scripts for now. Support for Upstart jobs should come later.
Init/Services.pm | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++----
Utils/Report.pm | 8 ++
2 files changed, 252 insertions(+), 17 deletions(-)
---
diff --git a/Init/Services.pm b/Init/Services.pm
index 83ba38c..b598bb7 100644
--- a/Init/Services.pm
+++ b/Init/Services.pm
@@ -6,7 +6,8 @@
#
# Authors: Carlos Garnacho Parro <garparr teleline es>,
# Hans Petter Jansson <hpj ximian com>,
-# Arturo Espinosa <arturo ximian com>
+# Arturo Espinosa <arturo ximian com>,
+# Milan Bouchet-Valat <nalimilan club fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published
@@ -87,6 +88,229 @@ sub get_default_runlevel
return &get_sysv_default_runlevel ();
}
+# Upstart support
+# TODO: Handle Upstart jobs, and not only traditional SystemV scripts inside an upstart system
+sub get_upstart_paths
+{
+ my %dist_map =
+ (
+ # gst_dist => [rc.X dirs location, init.d scripts location, relative path, upstart init jobs location]
+ "debian" => ["$gst_prefix/etc", "$gst_prefix/etc/init.d", "../init.d", "$gst_prefix/etc/init"],
+ );
+ my $res;
+
+ $res = $dist_map{$Utils::Backend::tool{"platform"}};
+ &Utils::Report::do_report ("service_upstart_unsupported", $Utils::Backend::tool{"platform"}) if ($res eq undef);
+ return @$res;
+}
+
+# we are going to extract the name of the script
+sub get_upstart_service_name
+{
+ my ($service) = @_;
+
+ $service =~ s/$initd_path\///;
+
+ return $service;
+}
+
+# This function gets the state of the service along the runlevels,
+# it also returns the average priority
+sub get_upstart_runlevels_status
+{
+ my ($service) = @_;
+ my ($link);
+ my ($runlevel, $action, $priority);
+ my (@arr, @ret);
+
+ foreach $link (<$rcd_path/rc[0-6].d/[SK][0-9][0-9]$service>)
+ {
+ $link =~ s/$rcd_path\///;
+ $link =~ /rc([0-6])\.d\/([SK])([0-9][0-9]).*/;
+ ($runlevel,$action,$priority)=($1,$2,$3);
+
+ if ($action eq "S")
+ {
+ push @arr, [ $runlevel, $SERVICE_START, $priority ];
+ }
+ elsif ($action eq "K")
+ {
+ push @arr, [ $runlevel, $SERVICE_STOP, $priority ];
+ }
+ }
+
+ return \ arr;
+}
+
+# We are going to extract the information of the service
+sub get_upstart_service_info
+{
+ my ($service) = @_;
+ my ($script, @actions, @runlevels, $role);
+
+ # Return if it's a directory
+ return if (-d $service);
+
+ # We have to check if the service is executable
+ return unless (-x $service);
+
+ $script = &get_upstart_service_name ($service);
+ $runlevels = &get_upstart_runlevels_status($script);
+
+ return ($script, $runlevels);
+}
+
+# This function gets an ordered array of the available services from a upstart system
+sub get_upstart_services
+{
+ my ($service);
+ my (@arr);
+
+ ($rcd_path, $initd_path, $relative_path, $init_path) = &get_upstart_paths ();
+ return undef unless ($rcd_path && $initd_path && $init_path);
+
+ foreach $service (<$initd_path/*>)
+ {
+ my (@info, $script);
+
+ @info = &get_upstart_service_info ($service);
+ # Only manage traditional init.d scripts, ignore services with jobs installed
+ $script = $info[0];
+ if (!-e "$init_path/$script.conf")
+ {
+ push @arr, \ info if (scalar (@info));
+ }
+ }
+
+ return \ arr;
+}
+
+# These are the functions for storing the service settings in upstart
+sub remove_upstart_link
+{
+ my ($rcd_path, $runlevel, $script) = @_;
+
+ foreach $link (<$rcd_path/rc$runlevel.d/[SK][0-9][0-9]$script>)
+ {
+ &Utils::Report::enter ();
+ &Utils::Report::do_report ("service_upstart_remove_link", "$link");
+ unlink ($link);
+ &Utils::Report::leave ();
+ }
+}
+
+sub add_upstart_link
+{
+ my ($rcd_path, $relative_path, $runlevel, $action, $priority, $service) = @_;
+ my ($prio) = sprintf ("%0.2d",$priority);
+
+ symlink ("$relative_path/$service", "$rcd_path/rc$runlevel.d/$action$prio$service");
+
+ &Utils::Report::enter ();
+ &Utils::Report::do_report ("service_upstart_add_link", "$rcd_path/rc$runlevel.d/$action$prio$service");
+ &Utils::Report::leave ();
+}
+
+sub run_upstart_initd_script
+{
+ my ($service, $arg) = @_;
+ my ($rc_path, $initd_path);
+ my $str;
+
+ &Utils::Report::enter ();
+
+ if (&Utils::File::run ("service", $service, $arg) == 0)
+ {
+ &Utils::Report::do_report ("service_upstart_op_success", $service, $arg);
+ &Utils::Report::leave ();
+ return 0;
+ }
+
+ &Utils::Report::do_report ("service_upstart_op_failed", $service, $arg);
+ &Utils::Report::leave ();
+ return -1;
+}
+
+sub set_upstart_service
+{
+ my ($service) = @_;
+ my ($script, $priority, $runlevels, $default_runlevel);
+ my ($runlevel, $action, %configured_runlevels);
+
+ ($rcd_path, $initd_path, $relative_path) = &get_upstart_paths ();
+ return unless ($rcd_path && $initd_path && $relative_path);
+
+ $script = $$service[0];
+ $runlevels = $$service[1];
+ $default_runlevel = &get_default_runlevel ();
+
+ foreach $r (@$runlevels)
+ {
+ $runlevel = $$r[0];
+ $action = ($$r[1] == $SERVICE_START) ? "S" : "K";
+ $priority = sprintf ("%0.2d", $$r[2]);
+ $priority = "50" if ($$r[2] <= 0);
+
+ $configured_runlevels{$runlevel} = 1;
+
+ if (!-f "$rcd_path/rc$runlevel.d/$action$priority$script")
+ {
+ &remove_upstart_link ($rcd_path, $runlevel, $script);
+ &add_upstart_link ($rcd_path, $relative_path, $runlevel, $action, $priority, $script);
+
+ if ($runlevel eq $default_runlevel)
+ {
+ &run_upstart_initd_script ($script, ($$r[1] == $SERVICE_START) ? "start" : "stop");
+ }
+ }
+ }
+
+ # remove unneeded links
+ foreach $link (<$rcd_path/rc[0-6].d/[SK][0-9][0-9]$script>)
+ {
+ $link =~ /rc([0-6])\.d/;
+ $runlevel = $1;
+
+ if (!exists $configured_runlevels{$runlevel})
+ {
+ &remove_upstart_link ($rcd_path, $runlevel, $script);
+
+ if ($runlevel eq $default_runlevel)
+ {
+ &run_upstart_initd_script ($script, "stop");
+ }
+ }
+ }
+}
+
+sub set_upstart_services
+{
+ my ($services) = @_;
+
+ foreach $i (@$services)
+ {
+ &set_upstart_service($i);
+ }
+}
+
+# This function gets the runlevel that is in use
+sub get_sysv_default_runlevel
+{
+ my (@arr);
+ @arr = split / /, `/sbin/runlevel` ;
+ chomp $arr[1];
+
+ return $arr[1];
+}
+
+sub get_default_runlevel
+{
+ my $type = &get_init_type ();
+
+ return "default" if ($type eq "gentoo" || $type eq "rcng" || $type eq "bsd" || $type eq "smf");
+ return &get_sysv_default_runlevel ();
+}
+
sub get_sysv_paths
{
my %dist_map =
@@ -1277,9 +1501,9 @@ sub get_init_type
$gst_dist = $Utils::Backend::tool{"platform"};
- if (($gst_dist =~ /debian/) && (Utils::File::exists ("/etc/runlevel.conf")))
+ if (($gst_dist =~ /debian/))
{
- return "file-rc";
+ return "upstart";
}
elsif ($gst_dist =~ /slackware/)
{
@@ -1313,6 +1537,7 @@ sub run_script
my ($proc, $type);
my %map =
(
+ "upstart" => \&run_upstart_initd_script,
"sysv" => \&run_sysv_initd_script,
"file-rc" => \&run_sysv_initd_script,
"bsd" => \&run_bsd_script,
@@ -1331,13 +1556,14 @@ sub get
{
$type = &get_init_type ();
- return &get_sysv_services () if ($type eq "sysv");
- return &get_filerc_services () if ($type eq "file-rc");
- return &get_bsd_services () if ($type eq "bsd");
- return &get_gentoo_services () if ($type eq "gentoo");
- return &get_rcng_services () if ($type eq "rcng");
- return &get_suse_services () if ($type eq "suse");
- return &get_smf_services () if ($type eq "smf");
+ return &get_upstart_services () if ($type eq "upstart");
+ return &get_sysv_services () if ($type eq "sysv");
+ return &get_filerc_services () if ($type eq "file-rc");
+ return &get_bsd_services () if ($type eq "bsd");
+ return &get_gentoo_services () if ($type eq "gentoo");
+ return &get_rcng_services () if ($type eq "rcng");
+ return &get_suse_services () if ($type eq "suse");
+ return &get_smf_services () if ($type eq "smf");
return undef;
}
@@ -1348,13 +1574,14 @@ sub set
$type = &get_init_type ();
- &set_sysv_services ($services) if ($type eq "sysv");
- &set_filerc_services ($services) if ($type eq "file-rc");
- &set_bsd_services ($services) if ($type eq "bsd");
- &set_gentoo_services ($services) if ($type eq "gentoo");
- &set_rcng_services ($services) if ($type eq "rcng");
- &set_suse_services ($services) if ($type eq "suse");
- &set_smf_services ($services) if ($type eq "smf");
+ &set_upstart_services ($services) if ($type eq "upstart");
+ &set_sysv_services ($services) if ($type eq "sysv");
+ &set_filerc_services ($services) if ($type eq "file-rc");
+ &set_bsd_services ($services) if ($type eq "bsd");
+ &set_gentoo_services ($services) if ($type eq "gentoo");
+ &set_rcng_services ($services) if ($type eq "rcng");
+ &set_suse_services ($services) if ($type eq "suse");
+ &set_smf_services ($services) if ($type eq "smf");
}
1;
diff --git a/Utils/Report.pm b/Utils/Report.pm
index 6cb9271..1bf47d5 100644
--- a/Utils/Report.pm
+++ b/Utils/Report.pm
@@ -235,6 +235,14 @@ sub add
"service_sysv_op_unk" => ["error", "Unknown initd operation [%s]."],
"service_sysv_op_success" => ["info", "Service [%s] %s."],
"service_sysv_op_failed" => ["warn", "Service [%s] could not be %s."],
+ "service_upstart_unsupported" => ["info", "No Upstart support for platform [%s]."],
+ "service_upstart_not_found" => ["warn", "Could not find init scripts for service [%s]."],
+ "service_upstart_no_runlevel" => ["warn", "Could not find init runlevel [%s] directory [%s]."],
+ "service_upstart_remove_link" => ["info", "Removed rc.d link [%s]."],
+ "service_upstart_add_link" => ["info", "Created rc.d link [%s]."],
+ "service_upstart_op_unk" => ["error", "Unknown Upstart operation [%s]."],
+ "service_upstart_op_success" => ["info", "Service [%s] %s."],
+ "service_upstart_op_failed" => ["warn", "Service [%s] could not be %s."],
"network_dialing_get" => ["info", "Loading ISP configurations."],
"network_iface_active_get" => ["info", "Finding active interfaces."],
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]