coren has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/89416


Change subject: Tool Labs: completely rejigger the lighttpd setup
......................................................................

Tool Labs: completely rejigger the lighttpd setup

Make the port granting reliable, and allow endusers to start
their own httpd.

Change-Id: I3d55430f3df83644fa158d1f54654675e4d7ed95
---
A modules/toollabs/files/lighttpd-starter
A modules/toollabs/files/portgrabber
A modules/toollabs/files/portgranter
A modules/toollabs/files/portgranter.conf
M modules/toollabs/files/tool-lighttpd
M modules/toollabs/manifests/exec_environ.pp
M modules/toollabs/manifests/webnode.pp
7 files changed, 325 insertions(+), 135 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/puppet 
refs/changes/16/89416/1

diff --git a/modules/toollabs/files/lighttpd-starter 
b/modules/toollabs/files/lighttpd-starter
new file mode 100755
index 0000000..64507db
--- /dev/null
+++ b/modules/toollabs/files/lighttpd-starter
@@ -0,0 +1,105 @@
+#! /bin/bash
+#
+#  Copyright © 2013 Marc-André Pelletier <[email protected]>
+#
+#  Permission to use, copy, modify, and/or distribute this software for any
+#  purpose with or without fee is hereby granted, provided that the above
+#  copyright notice and this permission notice appear in all copies.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+tool="$1"
+port="$2"
+user="local-$tool"
+home=$(getent passwd $user | cut -d : -f 6 | sed -e 's/\/$//')
+if [ "$(getent group $user | cut -d : -f 1)" != "$user" ]; then
+  echo "$0: $1 does not appear to be a tool" >&2
+  exit 1
+fi
+spool="/var/run/lighttpd"
+runbase="$spool/$tool"
+
+if [ "$home" = "" -o ! -d "$home/public_html" ]; then
+  echo "$1 does not have a public_html" >&2
+  exit 1
+fi
+
+cat <<EOF >$runbase.conf~
+server.modules = (
+  "mod_access",
+  "mod_accesslog",
+  "mod_alias",
+  "mod_compress",
+  "mod_redirect",
+  "mod_rewrite",
+  "mod_fastcgi",
+  "mod_cgi",
+)
+
+server.port = $port
+server.use-ipv6 = "disable"
+server.username = "local-$tool"
+server.groupname = "local-$tool"
+server.core-files = "disable"
+server.document-root = "$home/public_html"
+server.pid-file = "$runbase.pid"
+server.errorlog = "$home/error.log"
+server.breakagelog = "$home/error.log"
+server.follow-symlink = "enable"
+server.max-connections = 20
+server.max-keep-alive-idle = 60
+server.max-worker = 5
+server.stat-cache-engine = "fam"
+ssl.engine = "disable"
+
+alias.url = ( "/$tool" => "$home/public_html/" )
+
+index-file.names = ( "index.php", "index.html", "index.htm" )
+dir-listing.encoding = "utf-8"
+server.dir-listing = "disable"
+url.access-deny = ( "~", ".inc" )
+static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
+
+accesslog.use-syslog = "disable"
+accesslog.filename = "$home/access.log"
+
+cgi.assign = (
+  ".pl" => "/usr/bin/perl",
+  ".py" => "/usr/bin/python",
+  ".pyc" => "/usr/bin/python",
+)
+
+fastcgi.server += ( ".php" =>
+        ((
+                "bin-path" => "/usr/bin/php-cgi",
+                "socket" => "/tmp/php.socket.$tool",
+                "max-procs" => 1,
+                "bin-environment" => (
+                        "PHP_FCGI_CHILDREN" => "4",
+                        "PHP_FCGI_MAX_REQUESTS" => "10000"
+                ),
+                "bin-copy-environment" => (
+                        "PATH", "SHELL", "USER"
+                ),
+                "broken-scriptfilename" => "enable"
+        ))
+)
+
+EOF
+
+/usr/share/lighttpd/create-mime.assign.pl >>$runbase.conf~
+if [ -r $home/.lighttpd.conf ]; then
+  cat $home/.lighttpd.conf >>$runbase.conf~
+fi
+
+mv $runbase.conf~ $runbase.conf
+
+exec /usr/sbin/lighttpd -f $runbase.conf -D >>$home/error.log 2>&1
+
diff --git a/modules/toollabs/files/portgrabber 
b/modules/toollabs/files/portgrabber
new file mode 100755
index 0000000..b4d8baf
--- /dev/null
+++ b/modules/toollabs/files/portgrabber
@@ -0,0 +1,30 @@
+#!/usr/bin/perl -w
+#
+#  Copyright © 2013 Marc-André Pelletier <[email protected]>
+#
+#  Permission to use, copy, modify, and/or distribute this software for any
+#  purpose with or without fee is hereby granted, provided that the above
+#  copyright notice and this permission notice appear in all copies.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+use Socket;
+
+my $tool = shift;
+my $line;
+
+socket(SOCK, PF_UNIX, SOCK_STREAM, 0)     || die "socket: $!";
+connect(SOCK, sockaddr_un("/tmp/sock.portgranter"))   || die "connect: $!";
+$| = 1;
+syswrite SOCK, "$tool\n";
+my $port = 0+<SOCK>;
+
+exec @ARGV, $port;
+
diff --git a/modules/toollabs/files/portgranter 
b/modules/toollabs/files/portgranter
new file mode 100755
index 0000000..11d356e
--- /dev/null
+++ b/modules/toollabs/files/portgranter
@@ -0,0 +1,141 @@
+#!/usr/bin/perl -w
+#
+#  Copyright © 2013 Marc-André Pelletier <[email protected]>
+#
+#  Permission to use, copy, modify, and/or distribute this software for any
+#  purpose with or without fee is hereby granted, provided that the above
+#  copyright notice and this permission notice appear in all copies.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+use Socket;
+use File::NFSLock;
+use Fcntl qw(LOCK_EX LOCK_NB);
+
+my $scoreboard = "/tmp/dynamic";
+my $sockname = "/tmp/sock.portgranter";
+my $uaddr = sockaddr_un($sockname);
+
+unlink($sockname);
+socket(Server, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!";
+bind  (Server, $uaddr)                  || die "bind: $!";
+chmod 0666, $sockname;
+listen(Server, SOMAXCONN)               || die "listen: $!";
+
+sub spawn {
+    my $sock = shift;
+    my $coderef = shift;
+    my $pid = fork();
+
+    if($pid>0 or not defined $pid) {
+        close $sock;
+        return $pid;
+    }
+
+    exit($coderef->($sock));
+}
+
+my $hostname = `hostname`; chomp $hostname;
+my %clients;
+my @ports;
+my $reap = 0;
+my $update = 1;
+
+use POSIX ":sys_wait_h";
+sub REAPER {
+    $reap = 1;
+    $SIG{CHLD} = \&REAPER;  # loathe SysV
+}
+
+$SIG{CHLD} = \&REAPER;
+
+
+for(my $i=4000; $i<5000; $i++) {
+    push @ports, $i;
+}
+
+$| = 1;
+for(;;)
+{
+    if($reap) {
+        $reap = 0;
+        my $child;
+        while( ($child = waitpid(-1, WNOHANG)) > 0 ) {
+            if(defined $clients{$child}) {
+                my $c = $clients{$child};
+                delete $clients{$child};
+                $update = 1;
+                unshift @ports, $c->{'port'};
+            }
+        }
+    }
+
+    if($update) {
+        if(my $lock = new File::NFSLock {
+            file               => "$scoreboard.new",
+            lock_type          => LOCK_EX,
+            blocking_timeout   => 10,
+            stale_lock_timeout => 120,
+        }) {
+            my @scoreboard;
+            if(open SB, "<$scoreboard") {
+                while(<SB>) {
+                    if(m/^\S+ ([^:]+):[0-9]+$/) {
+                        next if $1 eq $hostname;
+                    }
+                    push @scoreboard, $_;
+                }
+                close SB;
+            }
+            foreach my $c (values %clients) {
+                push @scoreboard, "$c->{'tool'} $hostname:$c->{'port'}\n";
+            }
+
+            if(open SB, ">$scoreboard.new") {
+                print SB join '', @scoreboard;
+                if(rename "$scoreboard.new", $scoreboard) {
+                    $update = 0;
+                } else {
+                    unlink "$scoreboard.new";
+                }
+                close SB;
+            }
+        }
+    }
+
+    if($#ports < 0) {
+        sleep 1;
+        next;
+    }
+
+    my $client;
+    next unless accept($client, Server);
+
+    my $tool = <$client>;
+    my $port = shift @ports;
+    chomp $tool;
+    print $client "$port\n";
+
+    my $pid = spawn $client, sub {
+        my $sock = shift;
+        scalar <$sock>;
+        close $sock;
+        return 0;
+    };
+    if(defined $pid) {
+        $clients{$pid} = {
+            pid => $pid,
+            tool => $tool,
+            port => $port,
+        };
+        $update = 1;
+    }
+}
+
diff --git a/modules/toollabs/files/portgranter.conf 
b/modules/toollabs/files/portgranter.conf
new file mode 100644
index 0000000..5851a8d
--- /dev/null
+++ b/modules/toollabs/files/portgranter.conf
@@ -0,0 +1,13 @@
+# portgranter - grant ports dynamically for daemons
+
+description "Portgranter"
+
+start on runlevel [2345]
+stop on runlevel [!2345]
+
+respawn
+
+console log
+
+exec /usr/local/sbin/portgranter
+
diff --git a/modules/toollabs/files/tool-lighttpd 
b/modules/toollabs/files/tool-lighttpd
index 309b481..357b2b0 100755
--- a/modules/toollabs/files/tool-lighttpd
+++ b/modules/toollabs/files/tool-lighttpd
@@ -15,137 +15,5 @@
 #  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
 
-tool="$1"
-user="local-$tool"
-home=$(getent passwd $user | cut -d : -f 6 | sed -e 's/\/$//')
-if [ "$(getent group $user | cut -d : -f 1)" != "$user" ]; then
-  echo "$0: $1 does not appear to be a tool" >&2
-  exit 1
-fi
-spool="/var/run/lighttpd"
-runbase="$spool/$tool"
-scoreboard="/data/project/.system/dynamic"
-
-if [ "$home" = "" -o ! -d "$home/public_html" ]; then
-  echo "$1 does not have a public_html" >&2
-  exit 1
-fi
-
-export llock="/tmp/toollock.$tool"
-export lock="/tmp/toollock.lock"
-
-trap "rm -f $llock" 0
-touch $llock
-while [ -f $llock ]; do
-  mv -n $llock $lock
-  sleep 1
-done
-trap "rm -f $lock $scoreboard.tmp" 0
-port=4000
-past="$(grep "^$tool " $scoreboard)"
-if [ "$past" != "" ]; then
-  port=$(echo "$past" | sed -e 's/.*://')
-fi
-grep -v "^$tool " $scoreboard >$scoreboard.tmp
-while grep -q ":$port$" $scoreboard.tmp; do
-  port=$[$port+1]
-done
-echo "$tool $(hostname):$port" >>$scoreboard.tmp
-mv $scoreboard.tmp $scoreboard
-rm -f $lock
-trap "" 0
-
-cat <<EOF >$runbase.conf~
-server.modules = (
-  "mod_access",
-  "mod_accesslog",
-  "mod_alias",
-  "mod_compress",
-  "mod_redirect",
-  "mod_rewrite",
-  "mod_fastcgi",
-  "mod_cgi",
-)
-
-server.port = $port
-server.use-ipv6 = "disable"
-server.username = "local-$tool"
-server.groupname = "local-$tool"
-server.core-files = "disable"
-server.document-root = "$home/public_html"
-server.pid-file = "$runbase.pid"
-server.errorlog = "$home/error.log"
-server.breakagelog = "$home/error.log"
-server.follow-symlink = "enable"
-server.max-connections = 20
-server.max-keep-alive-idle = 60
-server.max-worker = 5
-server.stat-cache-engine = "fam"
-ssl.engine = "disable"
-
-alias.url = ( "/$tool" => "$home/public_html/" )
-
-index-file.names = ( "index.php", "index.html", "index.htm" )
-dir-listing.encoding = "utf-8"
-server.dir-listing = "disable"
-url.access-deny = ( "~", ".inc" )
-static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
-
-accesslog.use-syslog = "disable"
-accesslog.filename = "$home/access.log"
-
-cgi.assign = (
-  ".pl" => "/usr/bin/perl",
-  ".py" => "/usr/bin/python",
-  ".pyc" => "/usr/bin/python",
-)
-
-fastcgi.server += ( ".php" =>
-        ((
-                "bin-path" => "/usr/bin/php-cgi",
-                "socket" => "/tmp/php.socket.$tool",
-                "max-procs" => 1,
-                "bin-environment" => (
-                        "PHP_FCGI_CHILDREN" => "4",
-                        "PHP_FCGI_MAX_REQUESTS" => "10000"
-                ),
-                "bin-copy-environment" => (
-                        "PATH", "SHELL", "USER"
-                ),
-                "broken-scriptfilename" => "enable"
-        ))
-)
-
-EOF
-
-/usr/share/lighttpd/create-mime.assign.pl >>$runbase.conf~
-if [ -r $home/.lighttpd.conf ]; then
-  grep '^\s*server.dir_listing\s*=' $home/.lighttpd.conf >>$runbase.conf~
-  sed -e 's/server\s*\./var./g' $home/.lighttpd.conf >>$runbase.conf~
-fi
-
-chown $user:$user $runbase.conf~
-mv $runbase.conf~ $runbase.conf
-
-
-cleanup() {
-  trap "rm -f $llock" 0
-  touch $llock
-  while [ -f $llock ]; do
-    mv -n $llock $lock
-    sleep 1
-  done
-  trap "rm -f $lock $scoreboard.tmp" 0
-  grep -v "^$tool " $scoreboard >$scoreboard.tmp
-  mv $scoreboard.tmp $scoreboard
-  rm -f $lock
-  trap "" 0
-}
-
-trap "cleanup;exit 0" 15
-
-/bin/su -c "/usr/sbin/lighttpd -f $runbase.conf -D >>$home/error.log 2>&1" - 
"$user"
-/bin/su -c "/bin/date >$home/lighttpd.STOPPED" - "$user"
-
-cleanup
-exit 1
+tool=$(/usr/bin/id -nu|sed -e 's/^local-//')
+exec /usr/local/sbin/portgrabber "$tool" /usr/local/sbin/lighttpd-starter 
"$tool"
diff --git a/modules/toollabs/manifests/exec_environ.pp 
b/modules/toollabs/manifests/exec_environ.pp
index 816a360..a4566ae 100644
--- a/modules/toollabs/manifests/exec_environ.pp
+++ b/modules/toollabs/manifests/exec_environ.pp
@@ -50,6 +50,7 @@
       'libdbi-perl',
       'libdigest-crc-perl',
       'libdigest-hmac-perl',
+      'libfile-nfslock-perl',
       'libhtml-html5-entities-perl',
       'libhtml-parser-perl',
       'libhttp-message-perl',
diff --git a/modules/toollabs/manifests/webnode.pp 
b/modules/toollabs/manifests/webnode.pp
index 6747b9b..56bd874 100644
--- a/modules/toollabs/manifests/webnode.pp
+++ b/modules/toollabs/manifests/webnode.pp
@@ -82,9 +82,41 @@
     ensure => file,
     owner => 'root',
     group => 'root',
-    mode => '0755',
+    mode => '0555',
     source => "puppet:///modules/toollabs/tool-lighttpd",
   }
 
+  file { "/usr/local/sbin/lighttpd-starter":
+    ensure => file,
+    owner => 'root',
+    group => 'root',
+    mode => '0555',
+    source => "puppet:///modules/toollabs/lighttpd-starter",
+  }
+
+  file { "/usr/local/sbin/portgrabber":
+    ensure => file,
+    owner => 'root',
+    group => 'root',
+    mode => '0555',
+    source => "puppet:///modules/toollabs/portgrabber",
+  }
+
+  file { "/usr/local/sbin/portgranter":
+    ensure => file,
+    owner => 'root',
+    group => 'root',
+    mode => '0555',
+    source => "puppet:///modules/toollabs/portgranter",
+  }
+
+  file { "/etc/init/portgranter.conf":
+    ensure => file,
+    owner => 'root',
+    group => 'root',
+    mode => '0444',
+    source => "puppet:///modules/toollabs/portgranter.conf",
+  }
+
 }
 

-- 
To view, visit https://gerrit.wikimedia.org/r/89416
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3d55430f3df83644fa158d1f54654675e4d7ed95
Gerrit-PatchSet: 1
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: coren <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to