From 24df8b4256e7409cb43d463b07e55ecf10f445b4 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Mon, 3 Jul 2023 18:29:11 +0200 Subject: [PATCH] mxstartup: Import files form source repository Import files from b51f29e5 ("Merge pull request #10 from mariux64/fix-su-option") of github.molgen.mpg.de:mariux64/mxstartup.git into repository. It is just cumbersome to have these n a seperate repository with releases and bee installation. The mxstartup bee package should be deinstalled if this is merged. --- install.sh | 5 + mxstartup/mxservicectl | 150 +++++++++++++++++++ mxstartup/mxstartup.service | 14 ++ mxstartup/mxstartup2mxconfig | 277 +++++++++++++++++++++++++++++++++++ mxstartup/mxstartupctl | 30 ++++ mxstartup/mxvipctl | 217 +++++++++++++++++++++++++++ 6 files changed, 693 insertions(+) create mode 100755 mxstartup/mxservicectl create mode 100644 mxstartup/mxstartup.service create mode 100755 mxstartup/mxstartup2mxconfig create mode 100755 mxstartup/mxstartupctl create mode 100755 mxstartup/mxvipctl diff --git a/install.sh b/install.sh index 02c77af7..aa636876 100755 --- a/install.sh +++ b/install.sh @@ -269,6 +269,11 @@ install_data misc_etc_files/modprobe.d/disable-i915.conf "$DESTDIR$sysconfdir/m install_data misc_systemd_units/i915.service "$DESTDIR$systemdunitdir/i915.service" install_data misc_systemd_units/mxstartup.service.d/fix-tmp.conf \ "$DESTDIR$systemdunitdir/mxstartup.service.d/fix-tmp.conf" +install_exec mxstartup/mxservicectl "$DESTDIR$usr_sbindir/mxservicectl" +install_exec mxstartup/mxstartup2mxconfig "$DESTDIR$usr_sbindir/mxstartup2mxconfig" +install_exec mxstartup/mxstartupctl "$DESTDIR$usr_sbindir/mxstartupctl" +install_exec mxstartup/mxvipctl "$DESTDIR$usr_sbindir/mxvipctl" +install_data mxstartup/mxstartup.service "$DESTDIR$systemdunitdir/mxstartup.service" postinstall exit diff --git a/mxstartup/mxservicectl b/mxstartup/mxservicectl new file mode 100755 index 00000000..1808f652 --- /dev/null +++ b/mxstartup/mxservicectl @@ -0,0 +1,150 @@ +#!/bin/bash + +CMD_IP="/sbin/ip" +CMD_MXS2MXSRV="/usr/sbin/mxstartup2mxconfig" + +RUNDIR="/run/mariux" + +# expands *-pattern in pathnames to null if no matching files are found.. +shopt -s nullglob + +# exit on any error +set -e + +function mxsrv_start_one() { + local cfg=$1 + local -i i mip mfwd + + echo "starting ${cfg} .." + + . ${cfg} + + test "$MX_SRV_USER" = "-" && MX_SRV_USER="root" + + case "${MX_SRV_SCRIPT}" in + *.service) + systemctl start "${MX_SRV_SCRIPT}" || true + ;; + *) + su - ${MX_SRV_USER} -c "${MX_SRV_SCRIPT} start" & + ;; + esac + + mv ${cfg}{,.r} + + unset -v MX_SRV_USER MX_SRV_SCRIPT +} + +function mxsrv_stop_one() { + local cfg=$1 + local -i i mip mfwd + + echo "stopping ${cfg} .." + + . ${cfg} + + test "$MX_SRV_USER" = "-" && MX_SRV_USER="root" + + case "${MX_SRV_SCRIPT}" in + *.service) + systemctl stop "${MX_SRV_SCRIPT}" || true + ;; + *) + su - ${MX_SRV_USER} -c "${MX_SRV_SCRIPT} stop" & + ;; + esac + + rm ${cfg} + + unset -v MX_SRV_USER MX_SRV_SCRIPT +} + +function mxsrv_start() { + local cfg + local pattern=$1 + + : ${pattern:=*} + + for cfg in ${RUNDIR}/mxservice.${pattern}.cfg ; do + if [ -e ${cfg}.r ] ; then + echo >&2 "skipping $cfg: already running.." + continue + fi + + if [ ! -r ${cfg} ] ; then + echo >&2 "skipping $cfg: can't read file" + continue + fi + + if [ ! -O ${cfg} ] ; then + echo >&2 "skipping $cfg: possible hack attempt?" + continue + fi + + mxsrv_start_one ${cfg} + + done +} + +function mxsrv_stop() { + local cfg + local pattern=$1 + + : ${pattern:=*} + + for cfg in ${RUNDIR}/mxservice.${pattern}.cfg.r ; do + if [ ! -r ${cfg} ] ; then + echo >&2 "skipping $cfg: can't read file" + continue + fi + + if [ ! -O ${cfg} ] ; then + echo >&2 "skipping $cfg: possible hack attempt?" + continue + fi + + mxsrv_stop_one ${cfg} + + done +} + + +function create_run_dir_if_not_exists() { + if [ ! -d ${RUNDIR} ] ; then + mkdir -m 0700 ${RUNDIR} + fi + + if [ ! -O ${RUNDIR} ] ; then + echo >&2 "${RUNDIR}: wrong owner: possible hack attempt? exiting.." + exit 1 + fi +} + +function create_mxservice() { + ${CMD_MXS2MXSRV} ${RUNDIR} >/dev/null +} + + +############################################################################## + +create_run_dir_if_not_exists + +case "${1}" in + start) + create_mxservice + mxsrv_start $2 + ;; + stop) + mxsrv_stop $2 + ;; + restart) + mxsrv_stop $2 + create_mxservice + mxsrv_start $2 + ;; + *) + echo >&2 "$0 start|stop" + ;; +esac + + diff --git a/mxstartup/mxstartup.service b/mxstartup/mxstartup.service new file mode 100644 index 00000000..b76807d9 --- /dev/null +++ b/mxstartup/mxstartup.service @@ -0,0 +1,14 @@ +[Unit] +Description=Mariux mxstartup classic +After=mxmount.service network.target +Requires=mxmount.service + +[Service] +Type=oneshot +ExecStart=/usr/sbin/mxstartupctl start +ExecStop=/usr/sbin/mxstartupctl stop +RemainAfterExit=yes +StandardOutput=syslog + +[Install] +WantedBy=multi-user.target diff --git a/mxstartup/mxstartup2mxconfig b/mxstartup/mxstartup2mxconfig new file mode 100755 index 00000000..b1b20101 --- /dev/null +++ b/mxstartup/mxstartup2mxconfig @@ -0,0 +1,277 @@ +#!/usr/bin/perl + +use Sys::Hostname; +use Data::Dumper; +use Socket; + +######################################## + +my $configfile = "/etc/mxstartups"; +my $rundir = "/run/mariux"; + +######################################## + +my $fullhostname = hostname; +my ($hostname) = $fullhostname =~ /^(.*?)\./; + +my $packed_ip; + +# wait till hostname is resolvable.. +while(!($packed_ip=gethostbyname($fullhostname))) { + sleep 1; +} + +my $hostip = inet_ntoa($packed_ip); + +if(defined $ARGV[0]) { + $rundir = $ARGV[0]; +} + +unless(-d $rundir and -w $rundir) { + print STDERR "can't write to directory $rundir\n"; + exit 1; +} + +@lines = read_file($configfile); + +my ($host, $user, $script, $ip); + +LINE: foreach(@lines) { + unless(($name, $host, $user, $script, $ip) = /^(\S+) (\S+) (\S+) (\S+)\s*(.*?)$/) { + print "format error: '$_'\n"; + next; + } + + my @hosts = split /[;,]/,$host; + + @hosts = expand_hosts(@hosts); + + my $match=undef; + foreach my $host (@hosts) { + if($host eq $hostname or $host eq $fullhostname or $hostname =~ /^$host$/ or $fullhostname =~ /^$host$/) { + $match=$host; + } + } + + next LINE unless(defined $match); + + save_config_mxservice($name, $user, $script); + + my @ips = split /\s*[,; ]\s*/,$ip; + my $pip = parse_ips(@ips); + print_ips_cfg($pip); + +} + + + +sub read_file { + my $file = shift; + open F, "$file" or die "can't open $file: $!\n"; + + my @lines=(); + my $line=""; + my $cont=0; + + while() { + chomp; + next if(/^\s*#/ or /^\s*$/); + + $cont=0; + + s/#.*$//; # remove comments.. + + $_ = $line . $_; + + if(s/\\\s*$//) { + # line continous in next line.. + $cont=1; + } + + $line = $_; + + unless($cont) { + $line =~ s/\s+/ /g; + push @lines, $line; + $line=""; + } + } + return @lines; +} + +sub eth_to_net_if_not_exists { + my $dev = shift; + my $net; + my $num; + + $dev !~ /^eth/ and return $dev; + + -d "/sys/class/net/${dev}" and return $dev; + + ($num) = $dev =~ /^eth(\d+)$/; + $net = sprintf "net%02d", $num; + + -d "/sys/class/net/${net}" and return $net; + + return $dev; +} + +sub parse_ips { + local $_; + + my $H = {}; + my $default_device = 'eth0'; + + foreach(@_) { + my $device = $default_device; + my %ports = (); + my $ip = "-"; + my $_todest = undef; + my $addressprefix; + + if(/\{(\S+)\}(\S+)/) { # extract device "{device}ip[d:t][..]" + $device = $1; + $_=$2; + } + + while((/(\S+)\[(\d+):(\d+)\]/)) { # extract ports + $ports{$3}=$2; + $_=$1; + } + + if($_ =~ /(\S+)\:(\S+)/) { + $_todest = $2; + $_ = $1; + } + + if (/(\S+)\/(\S+)/) { + $_=$1; + $addressprefix=$2; + } else { + $addressprefix=20; + } + + if("$_" eq "-") { + $_ = $fullhostname; + } + + unless (defined $_todest) { + $_todest=$_; + } + + +# printf "ip = $_\n"; +# printf "todest = $_todest\n"; + + if (! ($tmphostname = gethostbyname($_)) ) { + printf STDERR "mxvip::$name *ERROR* Can't resolve '$_'. Skipping.\n"; + next; + } + $ip = inet_ntoa($tmphostname); + + if (! ($tmphostname = gethostbyname($_todest)) ) { + printf STDERR "mxvip::$name *ERROR* Can't resolve '$_'. Skipping.\n"; + next; + } + $_todest = inet_ntoa($tmphostname); + + $device = eth_to_net_if_not_exists($device); + + $H->{$ip} = { device => $device, addressprefix => $addressprefix, ports => {%ports}, todest => $_todest }; + } + + return $H; +} + + + +############################################################################## + +sub save_config_mxservice { + my ($service, $user, $script) = @_; + + my $config = "$rundir/mxservice.$name.cfg"; + + printf "mxservice::$name creating service-config: $config\n"; + + open SCRIPT, ">", "$config" or die "can't open $config: $!"; + print SCRIPT qq(MX_SRV_USER="$user"\n); + print SCRIPT qq(MX_SRV_SCRIPT="$script"\n); + close SCRIPT or die "can't close $script: $!"; +} + +############################################################################## + +sub print_ips_cfg { + my $H = shift; + + my %up = (); + + my $i=0; + my $r=0; + + my $script = "$rundir/mxvip.$name.cfg"; + + printf "mxvip::$name creating start script: $script\n"; + + open SCRIPT, ">", "$script" or die "can't open $script: $!"; + + foreach my $ip (keys %$H) { + if("$ip" ne "$hostip") { + + my $broadcast=join('.',unpack('C*',pack('N',unpack('N',pack('C*',split '\.',$ip)) | (1<<(32-$H->{$ip}->{addressprefix}))-1 ))); + + print SCRIPT qq(# ip $i\n); + print SCRIPT qq(MX_IP_ADDRESS[$i]="$ip"\n); + print SCRIPT qq(MX_IP_ADDRESSPREFIX[$i]="$H->{$ip}->{addressprefix}"\n); + print SCRIPT qq(MX_IP_BROADCAST[$i]="$broadcast"\n); + print SCRIPT qq(MX_IP_DEVICE[$i]="$H->{$ip}->{device}"\n); + $i++; + + $up{$H->{$ip}->{device}}=1; + } + + my $j=$i-1; + foreach my $port (keys %{$H->{$ip}->{ports}}) { + print SCRIPT qq(# forward $i :: $r\n); + print SCRIPT qq(MX_FWD_IP[$r]="$j"\n); + print SCRIPT qq(MX_FWD_SRC_IP[$r]="$ip"\n); + print SCRIPT qq(MX_FWD_SRC_PORT[$r]="$H->{$ip}->{ports}->{$port}"\n); + print SCRIPT qq(MX_FWD_DST_IP[$r]="$H->{$ip}->{todest}"\n); + print SCRIPT qq(MX_FWD_DST_PORT[$r]="$port"\n); + $r++; + } + } + + close SCRIPT or die "can't close $script: $!"; +} + +############################################################################## + +sub hostconfig_list { + my $tag = shift; + $_=`/usr/sbin/hostconfig --list $tag 2>/dev/null`; + return ( split ); +} + + +sub expand_hosts { + my @oh = @_; + my @hosts = (); + + + foreach my $host (@oh) { + if($host =~ /^\@(\S+)/) { + push @hosts, hostconfig_list($1); + } + elsif ($host =~ /^(\/\S+)/) { + next unless(-r $1); + push @hosts, expand_hosts(read_file($1)); + } else { + push @hosts, $host; + } + } + return @hosts; +} + +__DATA__ diff --git a/mxstartup/mxstartupctl b/mxstartup/mxstartupctl new file mode 100755 index 00000000..8dbaf94b --- /dev/null +++ b/mxstartup/mxstartupctl @@ -0,0 +1,30 @@ +#!/bin/bash + +remoteuser=molgen + + +case "${1}" in + start) + while ! id ${remoteuser} >/dev/null 2>&1 ; do + echo >&2 "WARNING: Waiting for NIS (failed to resolve remote user ${remoteuser})" + sleep 1 + done + mxvipctl start $2 + mxservicectl start $2 + ;; + stop) + mxservicectl stop $2 + mxvipctl stop $2 + ;; + restart) + mxservicectl stop $2 + mxvipctl stop $2 + mxvipctl start $2 + mxservicectl start $2 + ;; + *) + echo >&2 "$0 start|stop|restart " + ;; +esac + + diff --git a/mxstartup/mxvipctl b/mxstartup/mxvipctl new file mode 100755 index 00000000..0939c0a6 --- /dev/null +++ b/mxstartup/mxvipctl @@ -0,0 +1,217 @@ +#!/bin/bash + +CMD_IP="/sbin/ip" +CMD_IPTABLES="/usr/sbin/iptables" +CMD_MXS2MXVIP="/usr/sbin/mxstartup2mxconfig" + +RUNDIR="/run/mariux" + +# expands *-pattern in pathnames to null if no matching files are found.. +shopt -s nullglob + +function mxvip_start_one() { + local vip=$1 + local -i i mip mfwd + + echo "starting ${vip} .." + + . ${vip} + + mip=${#MX_IP_ADDRESS[*]} + mfwd=${#MX_FWD_IP[*]} + +# echo "ip addresses found: ${mip}" + + #MX_FWD_DST_IP=([0]="141.14.30.222" [1]="141.14.20.135" [2]="141.14.27.44" [3]="141.14.27.44") + #MX_FWD_DST_PORT=([0]="8080" [1]="9191" [2]="9090" [3]="6789") + #MX_FWD_IP=([0]="-1" [1]="0" [2]="1" [3]="1") + #MX_FWD_SRC_IP=([0]="141.14.30.222" [1]="141.14.20.135" [2]="141.14.27.44" [3]="141.14.27.44") + #MX_FWD_SRC_PORT=([0]="80" [1]="91" [2]="90" [3]="80") + #MX_IP_ADDRESS=([0]="141.14.20.135" [1]="141.14.27.44") + #MX_IP_ADDRESSPREFIX=([0]="20" [1]="20") + #MX_IP_BROADCAST=([0]="141.14.31.255" [1]="141.14.31.255") + #MX_IP_DEVICE=([0]="eth0" [1]="eth0") + + i=0 + while [ ${i} -lt ${mip} ] ; do +# echo " $i -> ${MX_IP_ADDRESS[$i]}" + + echo "adding ip ${MX_IP_ADDRESS[$i]}/${MX_IP_ADDRESSPREFIX[$i]} broadcast ${MX_IP_BROADCAST[$i]} to ${MX_IP_DEVICE[$i]}" + + ${CMD_IP} addr add ${MX_IP_ADDRESS[$i]}/${MX_IP_ADDRESSPREFIX[$i]} broadcast ${MX_IP_BROADCAST[$i]} dev ${MX_IP_DEVICE[$i]} + ${CMD_IP} link set up dev ${MX_IP_DEVICE[$i]} + + i=i+1 + done + +# echo "fwds found: ${mfwd}" + + i=0 + while [ ${i} -lt ${mfwd} ] ; do + echo "adding forward ${MX_FWD_SRC_IP[$i]}:${MX_FWD_SRC_PORT[$i]} <-> ${MX_FWD_DST_IP[$i]}:${MX_FWD_DST_PORT[$i]}" + + ${CMD_IPTABLES} -t nat -A PREROUTING -p tcp -j DNAT -d ${MX_FWD_SRC_IP[$i]} --dport ${MX_FWD_SRC_PORT[$i]} --to-destination ${MX_FWD_DST_IP[$i]}:${MX_FWD_DST_PORT[$i]} + ${CMD_IPTABLES} -t nat -A OUTPUT -p tcp -j DNAT -d ${MX_FWD_SRC_IP[$i]} --dport ${MX_FWD_SRC_PORT[$i]} --to-destination ${MX_FWD_DST_IP[$i]}:${MX_FWD_DST_PORT[$i]} + ${CMD_IPTABLES} -t nat -A POSTROUTING -p tcp -j SNAT --dst ${MX_FWD_DST_IP[$i]} --dport ${MX_FWD_SRC_PORT[$i]} --to-source ${MX_FWD_SRC_IP[$i]} + + i=i+1 + done + + unset ${!MX_IP_*} + unset ${!MX_FWD_*} + + mv ${vip}{,.r} +} + +function mxvip_stop_one() { + local vip=$1 + local -i i mip mfwd + + echo "stopping ${vip} .." + + . ${vip} + + mip=${#MX_IP_ADDRESS[*]} + mfwd=${#MX_FWD_IP[*]} + +# echo "ip addresses found: ${mip}" + + #MX_FWD_DST_IP=([0]="141.14.30.222" [1]="141.14.20.135" [2]="141.14.27.44" [3]="141.14.27.44") + #MX_FWD_DST_PORT=([0]="8080" [1]="9191" [2]="9090" [3]="6789") + #MX_FWD_IP=([0]="-1" [1]="0" [2]="1" [3]="1") + #MX_FWD_SRC_IP=([0]="141.14.30.222" [1]="141.14.20.135" [2]="141.14.27.44" [3]="141.14.27.44") + #MX_FWD_SRC_PORT=([0]="80" [1]="91" [2]="90" [3]="80") + #MX_IP_ADDRESS=([0]="141.14.20.135" [1]="141.14.27.44") + #MX_IP_ADDRESSPREFIX=([0]="20" [1]="20") + #MX_IP_BROADCAST=([0]="141.14.31.255" [1]="141.14.31.255") + #MX_IP_DEVICE=([0]="eth0" [1]="eth0") + +# echo "fwds found: ${mfwd}" + + i=0 + while [ ${i} -lt ${mfwd} ] ; do + echo "removing forward ${MX_FWD_SRC_IP[$i]}:${MX_FWD_SRC_PORT[$i]} <-> ${MX_FWD_DST_IP[$i]}:${MX_FWD_DST_PORT[$i]}" + + ${CMD_IPTABLES} -t nat -D PREROUTING -p tcp -j DNAT -d ${MX_FWD_SRC_IP[$i]} --dport ${MX_FWD_SRC_PORT[$i]} --to-destination ${MX_FWD_DST_IP[$i]}:${MX_FWD_DST_PORT[$i]} + ${CMD_IPTABLES} -t nat -D OUTPUT -p tcp -j DNAT -d ${MX_FWD_SRC_IP[$i]} --dport ${MX_FWD_SRC_PORT[$i]} --to-destination ${MX_FWD_DST_IP[$i]}:${MX_FWD_DST_PORT[$i]} + ${CMD_IPTABLES} -t nat -D POSTROUTING -p tcp -j SNAT --dst ${MX_FWD_DST_IP[$i]} --dport ${MX_FWD_SRC_PORT[$i]} --to-source ${MX_FWD_SRC_IP[$i]} + + i=i+1 + done + + i=0 + while [ ${i} -lt ${mip} ] ; do +# echo " $i -> ${MX_IP_ADDRESS[$i]}" + + dev=${MX_IP_DEVICE[$i]} + + if [ ! -d "/sys/class/net/${dev}" -a "${dev:0:3}" = "eth" ] ; then + net=$(printf "net%02d" "${dev:3}") + if [ -d "/sys/class/net/${net}" ] ; then + MX_IP_DEVICE[$i]=$net + fi + fi + + echo "removing ip ${MX_IP_ADDRESS[$i]}/${MX_IP_ADDRESSPREFIX[$i]} broadcast ${MX_IP_BROADCAST[$i]} to ${MX_IP_DEVICE[$i]}" + + ${CMD_IP} addr del ${MX_IP_ADDRESS[$i]}/${MX_IP_ADDRESSPREFIX[$i]} broadcast ${MX_IP_BROADCAST[$i]} dev ${MX_IP_DEVICE[$i]} +# echo "${CMD_IP} link set up dev ${MX_IP_DEVICE[$i]}" + + i=i+1 + done + + unset ${!MX_IP_*} + unset ${!MX_FWD_*} + + rm ${vip} +} + +function mxvip_start() { + local vip + local pattern=$1 + + : ${pattern:=*} + + for vip in ${RUNDIR}/mxvip.${pattern}.cfg ; do + if [ -e ${vip}.r ] ; then + echo >&2 "skipping $vip: already running.." + continue + fi + + if [ ! -r ${vip} ] ; then + echo >&2 "skipping $vip: can't read file" + continue + fi + + if [ ! -O ${vip} ] ; then + echo >&2 "skipping $vip: possible hack attempt?" + continue + fi + + mxvip_start_one ${vip} + + done +} + +function mxvip_stop() { + local vip + local pattern=$1 + + : ${pattern:=*} + + for vip in ${RUNDIR}/mxvip.${pattern}.cfg.r ; do + if [ ! -r ${vip} ] ; then + echo >&2 "skipping $vip: can't read file" + continue + fi + + if [ ! -O ${vip} ] ; then + echo >&2 "skipping $vip: possible hack attempt?" + continue + fi + + mxvip_stop_one ${vip} + + done +} + + +function create_run_dir_if_not_exists() { + if [ ! -d ${RUNDIR} ] ; then + mkdir -m 0700 ${RUNDIR} + fi + + if [ ! -O ${RUNDIR} ] ; then + echo >&2 "${RUNDIR}: wrong owner: possible hack attempt? exiting.." + exit 1 + fi +} + +function create_mxvip() { + ${CMD_MXS2MXVIP} ${RUNDIR} >/dev/null +} + + +############################################################################## + +create_run_dir_if_not_exists + +case "${1}" in + start) + create_mxvip + mxvip_start $2 + ;; + stop) + mxvip_stop $2 + ;; + restart) + mxvip_stop $2 + create_mxvip + mxvip_start $2 + ;; + *) + echo >&2 "$0 start|stop" + ;; +esac + +