initial commit of file from CVS for e-smith-base on Thu 26 Oct 11:24:52 BST 2023
This commit is contained in:
		
							
								
								
									
										231
									
								
								root/etc/e-smith/events/actions/systemd-default
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								root/etc/e-smith/events/actions/systemd-default
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| #!/usr/bin/perl -w | ||||
|  | ||||
| use strict; | ||||
| use Errno; | ||||
| use esmith::ConfigDB; | ||||
| use File::Temp; | ||||
| use esmith::templates; | ||||
| use File::Basename; | ||||
| use Cwd 'abs_path'; | ||||
|  | ||||
| my $conf = esmith::ConfigDB->open_ro; | ||||
|  | ||||
|  | ||||
| my $event = $ARGV [0]; | ||||
| my $second = $ARGV [1]; | ||||
|  | ||||
| my @servicedirpaths = ("/usr/lib/systemd/system/","/etc/systemd/system/"); | ||||
| my @presetdirpaths = ("/usr/lib/systemd/system-preset/","/etc/systemd/system-preset/"); | ||||
| my $filename = "/etc/systemd/system-preset/49-koozali.preset"; | ||||
| my $filename2 = "/usr/lib/systemd/system/sme-server.target.d/50koozali.conf"; | ||||
| my %services; | ||||
| my %files; | ||||
| my @WantedBy; | ||||
|  | ||||
| # expand preset file | ||||
| esmith::templates::processTemplate({ | ||||
|                 MORE_DATA => { }, | ||||
|                 TEMPLATE_PATH => $filename, | ||||
|                 OUTPUT_FILENAME => $filename, | ||||
|             }); | ||||
| # expand content of sme-server.target.d | ||||
| esmith::templates::processTemplate({ | ||||
|                 MORE_DATA => { }, | ||||
|                 TEMPLATE_PATH => $filename2, | ||||
|                 OUTPUT_FILENAME => $filename2, | ||||
|             }); | ||||
|  | ||||
| # make sure our target is enabled | ||||
| system("/usr/bin/systemctl  enable sme-server.target"); | ||||
| # force the main default target in /usr/lib | ||||
| #ln -fs sme-server.target /lib/systemd/system/default.target | ||||
| my $old_qfn = "sme-server.target"; | ||||
| my $new_qfn = "/lib/systemd/system/default.target"; | ||||
| if (!symlink($old_qfn, $new_qfn)) { | ||||
|    if ($!{EEXIST}) { | ||||
|       unlink($new_qfn) | ||||
|          or die("Can't remove \"$new_qfn\": $!\n"); | ||||
|       symlink($old_qfn, $new_qfn) | ||||
|          or die("Can't create symlink \"$new_qfn\": $!\n"); | ||||
|    } else { | ||||
|       die("Can't create symlink \"$new_qfn\": $!\n"); | ||||
|    } | ||||
| } | ||||
|  | ||||
| # we let the dedicated systemd command tryin to do what we will do later in this script | ||||
| # as up to systemd 236 it is bugged see: | ||||
| #  https://github.com/systemd/systemd/pull/7158 and https://github.com/systemd/systemd/pull/7289 | ||||
| system("/usr/bin/systemctl  preset-all"); | ||||
| # in case preset-all messed up  with our default target | ||||
| system("/usr/bin/systemctl  set-default sme-server.target"); | ||||
|  | ||||
| # list both preset directories | ||||
| # seek files to be removed from usr/lib if same basename exist  | ||||
| foreach my $d (@presetdirpaths) { | ||||
| 	opendir my $dir, "$d" or die "Cannot open directory: $!"; | ||||
| 	my @dirfiles = readdir $dir; | ||||
| 	closedir $dir; | ||||
| 	foreach my $fi (@dirfiles) { | ||||
| 	        next unless ($fi =~ /.preset$/); | ||||
| 		$files{$fi}="$d$fi" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| # list wanted services in the sme-server.target | ||||
| #Wants=acpid.service atd.service auditd.service avahi-daemon.service brandbot.path crond.service irqbalance.service nfs-client.target remote-fs.target rhel-configure.service rsyslog.service smartd.service yum-cron.service | ||||
| my $smewants = `grep -P '^Wants=' /usr/lib/systemd/system/sme-server.target -rs`; | ||||
| chomp $smewants; | ||||
| my @smematches = ( $smewants =~ /([a-zA-Z0-9\-_]+\.service)/g ); | ||||
|   | ||||
|  | ||||
| # parse all files on reverse order : lower number take precedence | ||||
| # we ignore joker lines * | ||||
| # we ignore @ lines | ||||
| # we ignore multiple in one line | ||||
| # our default at the end is to disable if not listed | ||||
| foreach my $filen (reverse sort keys %files) {  | ||||
| #print "==============> $filen : ".$files{$filen} ."\n"; | ||||
| 	# parsing $filename  content | ||||
| 	# should end with hash with 2 possible value : enable and disable | ||||
| 	# ignore lines starting with # or empty character | ||||
| 	open(FILE, '<', $files{$filen}) or die $!; | ||||
| 	while (<FILE>)	{ | ||||
| 	    chomp; # remove newlines | ||||
| 	    next if (/^\s+$/); | ||||
| 	    next if (/^#/); | ||||
| 	    s/^\s+//;  # remove leading whitespace | ||||
| 	    s/\s+$//; # remove trailing whitespace | ||||
| 	    next unless length; # next rec unless anything left | ||||
| #           print $_ ."\n"; | ||||
| 	    next unless (/^(enable|disable)\s+([a-zA-Z0-9\-_.@]+\.service)/); | ||||
| 	    my $service=$2; | ||||
| 	    my $stats=$1; | ||||
| #	    print $_ ."\n";  | ||||
| 	    #ignore service that does not exists ! | ||||
| 	    my $multiple = $service; | ||||
| 	    ($multiple = $service ) =~ s/([a-zA-Z0-9\-_.]+@)(.*)/$1.service/ if ( $service =~ /@/ ); | ||||
| 	    #print "$stats $service $multiple\n"; | ||||
| 	    next unless ( -e "/usr/lib/systemd/system/$service" or -e "/etc/lib/systemd/system/$service" or -e "/usr/lib/systemd/system/$multiple"); | ||||
| 	    # eliminate duplicates, this way we keep only the last entry of the lowest file as we do it in reverse order of file, | ||||
| 	    # but from top to bottom of file. | ||||
| 	    $services{$service}=$stats; | ||||
|  | ||||
| 	    # list all Services explicitely listed in preset that are also in Wants= or with WantedBy= sme-server.target  | ||||
| 	    next if (/^$service$/ ~~ @WantedBy); | ||||
| 	    if (  /^$service$/ ~~ @smematches ) { | ||||
|                 push(@WantedBy, $service); | ||||
| 		#print "want $service \n"; | ||||
|             } | ||||
|             else { | ||||
|                 my $wanted = `grep -P '^WantedBy=.*sme-server.target' /usr/lib/systemd/system/$service*  /etc/systemd/system/$service* -rsh` ; | ||||
|                 chomp $wanted; | ||||
|                 push(@WantedBy , $service)  unless ( $wanted eq "") ; | ||||
| 		#print "want $service \n" unless ( $wanted eq "") ; | ||||
|             } | ||||
|  | ||||
| 	} | ||||
| } | ||||
|  | ||||
| # then check content of /etc/systemd/system/sme-server.target.wants/ | ||||
| # remove what is not in enable | ||||
| my $d = "/etc/systemd/system/sme-server.target.wants/"; | ||||
| opendir my $dir, "$d" or die "Cannot open directory: $!"; | ||||
| my @dirfiles = readdir $dir; | ||||
| closedir $dir; | ||||
| foreach my $fi (@dirfiles) { | ||||
|         # we ignore . and .. | ||||
|         next if $fi =~ /\.+$/; | ||||
|         # for the moment we only consider service  files and ignore target, mount, device, socket... | ||||
|         next unless ($fi =~ /.service$/); | ||||
| 	# remove if file but not a link | ||||
| 	unless ( -l "$d$fi") { | ||||
| 		print "remove $d$fi : not a link\n"; | ||||
| 		unlink "$d$fi"; | ||||
| 		next; | ||||
| 	} | ||||
| 	# remove if also un /usr/lib .. not as preset-all does not care | ||||
| 	#if ( -l "/usr/lib/systemd/system/sme-server.target.wants/$fi") { | ||||
| 	#	print "remove $d$fi : also in /usr/lib/systemd/system/sme-server.target.wants/\n"; | ||||
| 	#	unlink "$d$fi"; | ||||
| 	#	next; | ||||
| 	#} | ||||
| 	# remove if link is not to an existing file # we should also check if pointing to an authorized path! | ||||
|         my $multiple = $fi; | ||||
|         ($multiple = $fi ) =~ s/([a-zA-Z0-9\-_.]+@)(.*)/$1.service/ if ( $fi =~ /@/ ); | ||||
| 	my $absFilePath = abs_path("$d$fi") ; | ||||
| 	if ( ! -f "$absFilePath" or ( ! -f "/etc/systemd/system/$fi" and ! -f "/usr/lib/systemd/system/$fi" and ! -f "/usr/lib/systemd/system/$multiple") ) { | ||||
| 		print "remove $d$fi target '$absFilePath' does not exist or is not regular file in expected path\n";	 | ||||
| 		unlink "$d$fi"; | ||||
| 		next; | ||||
| 	} | ||||
|         # is not enable in preset : remove | ||||
|         #print "==$fi \n"; | ||||
|         if ( ! defined $services{$fi} or $services{$fi} ne "enable") { | ||||
|                 print "remove $d$fi as not enabled in preset\n"; | ||||
|                 unlink "$d$fi"; | ||||
| 		next; | ||||
|         } | ||||
| 	# if not wanted remove | ||||
| 	unless ( /^$fi$/ ~~ @WantedBy) { | ||||
| 		print "remove $d$fi as not declared as WantedBy or in Wants for sme-server.target\n"; | ||||
| 		unlink "$d$fi"; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| # and we add wanted enabled services  | ||||
| # we only do it for sme-server.target, ignoring the remaining of WantedBy | ||||
| foreach my $service (sort keys %services) { | ||||
| 	my $wanted= "not"; | ||||
| 	$wanted = "want" if (  /^$service$/ ~~ @WantedBy );  | ||||
| 	my $status = $services{$service}; | ||||
| 	my $linkedU = ( -e "/usr/lib/systemd/system/sme-server.target.wants/$service" ) ? "linked" : "not"; | ||||
| 	my $linkedE = ( -e "/etc/systemd/system/sme-server.target.wants/$service" ) ? "linked" : "not";  | ||||
| 	my $linkedD = ( -e "/etc/systemd/system/default.target.wants/$service" or -e "/usr/lib/systemd/system/default.target.wants/$service" ) ? "linked" : "not";  | ||||
| 	## adding link if needed in /etc/systemd/system/sme-server.target.wants | ||||
| 	## readd event if present in usr/lib as preste-all does not care about that. | ||||
| 	if ( $status eq "enable" and $linkedE eq "not" and $linkedD eq "not"  and $wanted eq "want" and ( $service !~ /\@\.service$/ ) ){ | ||||
| 		#print "systemctl add-wants sme-server.target $service\n"; | ||||
| 		`/usr/bin/systemctl add-wants sme-server.target $service `; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| # do something about /usr/lib/systemd/system/sme-server.target.wants/ | ||||
| # we check for rpm owned and not rpm owned | ||||
| # we only inform there, we do not do anything else | ||||
| $d = "/usr/lib/systemd/system/sme-server.target.wants/"; | ||||
| opendir $dir, "$d" or die "Cannot open directory: $!"; | ||||
| @dirfiles = readdir $dir; | ||||
| closedir $dir; | ||||
| foreach my $fi (@dirfiles) { | ||||
|         # we ignore . and .. | ||||
|         next if $fi =~ /\.+$/; | ||||
|         # for the moment we only consider service  files and ignore target, mount, device, socket... | ||||
|         next unless ($fi =~ /.service$/); | ||||
|         # remove if file but not a link | ||||
|         print "$d$fi is not a link\n" unless ( -l "$d$fi"); | ||||
|         # remove if link is not to an existing file | ||||
|         my $absFilePath = abs_path("$d$fi") ; | ||||
|         print "$d$fi target '$absFilePath' does not exist or is not regular file\n" unless ( -f "$absFilePath"); | ||||
|         # check if owned by rpm | ||||
| 	my $rpmowned = `rpm -qf $d$fi`; | ||||
| 	chomp $rpmowned; | ||||
| 	if ($rpmowned ne "" ) { | ||||
| 		#print "$d$fi is owned by $rpmowned\n"; | ||||
| 		#next; | ||||
| 	} else { | ||||
| 		print "$d$fi has been manually added\n"; | ||||
| 	} | ||||
| 	if ( ! defined $services{$fi} or $services{$fi} ne "enable") { | ||||
|                 print "$d$fi is not enabled in preset\n"; | ||||
|         } | ||||
|         # if not wanted remove | ||||
| 	# need to check its own files also here | ||||
| 	my $service = $fi; | ||||
| 	my $wanted = `grep -P '^WantedBy=.*sme-server.target' /usr/lib/systemd/system/$service*  /etc/systemd/system/$service* -rsh` ; | ||||
| 	chomp $wanted; | ||||
|         #unless (  /^$fi$/ ~~ @WantedBy  ) { | ||||
|         unless (grep(/^$fi$/, @WantedBy  ) ) { | ||||
|                 print "$d$fi is not declared as WantedBy or in Wants for sme-server.target\n"; | ||||
|         } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user