Bug#772555: untested hacky attempt at using systemctl preset

Raphael Hertzog hertzog at debian.org
Tue Mar 8 10:12:45 GMT 2016


Hi,

On Fri, 04 Mar 2016, Felipe Sateler wrote:
> This is only needed when creating links manually. As noted above, when
> invoking via systemctl it does the reload automatically.

Ok. So here's the final patch that I'm now using in Kali. It seems to work
from the quick tests that I did.

And I believe that it does the right thing given the contstraint.

It would be even better if we changed all maintainer scripts to call a true
"preset" action but I believe that's out of scope for now.

Cheers,
-- 
Raphaël Hertzog ◈ Debian Developer

Support Debian LTS: http://www.freexian.com/services/debian-lts.html
Learn to master Debian: http://debian-handbook.info/get/
-------------- next part --------------
diff --git a/script/deb-systemd-helper b/script/deb-systemd-helper
index 2a87cb4..07521a8 100755
--- a/script/deb-systemd-helper
+++ b/script/deb-systemd-helper
@@ -98,6 +98,7 @@ my $masked_state_dir = '/var/lib/systemd/deb-systemd-helper-masked';
 # Globals are bad, but in this specific case, it really makes things much
 # easier to write and understand.
 my $changed_sth;
+my $has_systemctl = -x "/bin/systemctl";
 
 sub error {
     print STDERR "$0: error: @_\n";
@@ -218,8 +219,49 @@ sub get_link_closure {
     return @links;
 }
 
-sub make_systemd_links {
+sub all_links_installed {
+    my ($scriptname, $service_path) = @_;
+
+    my @links = get_link_closure($scriptname, $service_path);
+    my @missing_links = grep { ! -l $_->{src} } @links;
+
+    return (@missing_links == 0);
+}
+
+sub no_link_installed {
+    my ($scriptname, $service_path) = @_;
+
+    my @links = get_link_closure($scriptname, $service_path);
+    my @existing_links = grep { -l $_->{src} } @links;
+
+    return (@existing_links == 0);
+}
+
+sub enable {
     my ($scriptname, $service_path) = @_;
+    if ($has_systemctl) {
+        # We use systemctl preset on the initial installation only
+        # On upgrade, we manually add the missing symlinks only if
+        # the service already has some links installed.
+        my $create_links = 0;
+        if (debian_installed($scriptname)) {
+            $create_links = 1 unless no_link_installed($scriptname, $service_path);
+        } else {
+            debug "Using systemctl preset to enable $scriptname";
+            system("/bin/systemctl", "--preset-mode=enable-only",
+                "preset", $scriptname) == 0 or
+                error("systemctl preset failed on $scriptname: $!");
+        }
+        make_systemd_links($scriptname, $service_path, create_links => $create_links);
+    } else {
+        # We create all the symlinks ourselves
+        make_systemd_links($scriptname, $service_path);
+    }
+}
+
+sub make_systemd_links {
+    my ($scriptname, $service_path, %opts) = @_;
+    $opts{'create_links'} //= 1;
 
     my $dsh_state = dsh_state_path($scriptname);
 
@@ -234,7 +276,7 @@ sub make_systemd_links {
         $statefile =~ s,^/etc/systemd/system/,$enabled_state_dir/,;
         next if -e $statefile;
 
-        if (! -l $service_link) {
+        if ($opts{'create_links'} && ! -l $service_link) {
             make_path(dirname($service_link));
             symlink($service_path, $service_link) or
                 error("unable to link $service_link to $service_path: $!");
@@ -472,9 +514,7 @@ for my $scriptname (@ARGV) {
     debug "action = $action, scriptname = $scriptname, service_path = $service_path";
 
     if ($action eq 'is-enabled') {
-        my @links = get_link_closure($scriptname, $service_path);
-        my @missing_links = grep { ! -l $_->{src} } @links;
-        my $enabled = (@missing_links == 0);
+        my $enabled = all_links_installed($scriptname, $service_path);
         print STDERR ($enabled ? "enabled\n" : "disabled\n") unless $quiet;
         $rc = 0 if $enabled;
     }
@@ -520,7 +560,7 @@ for my $scriptname (@ARGV) {
     }
 
     if ($action eq 'enable') {
-        make_systemd_links($scriptname, $service_path);
+        enable($scriptname, $service_path);
     }
 
     if ($action eq 'mask') {


More information about the Pkg-systemd-maintainers mailing list