You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2014/04/23 14:42:35 UTC

svn commit: r1589391 - in /qpid/trunk/qpid: cpp/etc/CMakeLists.txt cpp/etc/qpidd-primary.in cpp/etc/qpidd.in tools/src/py/qpid-ha tools/src/py/qpidtoollibs/config.py

Author: aconway
Date: Wed Apr 23 12:42:35 2014
New Revision: 1589391

URL: http://svn.apache.org/r1589391
Log:
QPID-5711: HA cannot promote primary if SASL security is enabled.

Updated the qpid-ha tool and qpidd init scripts to handle SASL authentication.
The qpid-ha script as as called by the qpidd-primary init script now reads
authentication settings from the qpidd.conf file and uses them to connect to the local broker.

- qpidd-primary script respects prefix: use installed location for qpidd script, not "service" call
- qpid-ha added --config option qpid-ha options to use qpidd.conf for local broker connection.
- qpid-ha --all use user/pass for each broker.

Added:
    qpid/trunk/qpid/tools/src/py/qpidtoollibs/config.py   (with props)
Modified:
    qpid/trunk/qpid/cpp/etc/CMakeLists.txt
    qpid/trunk/qpid/cpp/etc/qpidd-primary.in
    qpid/trunk/qpid/cpp/etc/qpidd.in
    qpid/trunk/qpid/tools/src/py/qpid-ha

Modified: qpid/trunk/qpid/cpp/etc/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/etc/CMakeLists.txt?rev=1589391&r1=1589390&r2=1589391&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/etc/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/etc/CMakeLists.txt Wed Apr 23 12:42:35 2014
@@ -19,11 +19,12 @@
 
 if (UNIX)
 
-  # Use automake variable names as these files are also configured by automake.
   # Use absolute paths as these are substituted into init scripts.
   set_absolute_install_path (bindir ${QPID_INSTALL_BINDIR})
   set_absolute_install_path (sysconfdir ${SYSCONF_INSTALL_DIR})
   set_absolute_install_path (sbindir ${QPID_INSTALL_SBINDIR})
+  set_absolute_install_path (initdir ${QPID_INSTALL_INITDDIR})
+  set_absolute_install_path (confdir ${QPID_INSTALL_CONFDIR})
 
   configure_file(qpidd.in
     ${CMAKE_CURRENT_BINARY_DIR}/qpidd

Modified: qpid/trunk/qpid/cpp/etc/qpidd-primary.in
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/etc/qpidd-primary.in?rev=1589391&r1=1589390&r2=1589391&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/etc/qpidd-primary.in (original)
+++ qpid/trunk/qpid/cpp/etc/qpidd-primary.in Wed Apr 23 12:42:35 2014
@@ -37,27 +37,28 @@
 
 prog=qpidd
 
-# Source function library.
-. /etc/rc.d/init.d/functions
+# The following variables can be overridden in @sysconfdir@/sysconfig/$prog
+QPID_INIT=@initdir@/$prog
+QPID_CONFIG=@confdir@/qpidd.conf
+QPID_HA=@bindir@/qpid-ha
+QPID_HA_OPTIONS="--config $QPID_CONFIG"
+
+# Source configuration
+test -f @sysconfdir@/sysconfig/$prog && source @sysconfdir@/sysconfig/$prog
+
+# Check presence of executables/scripts
+for f in $QPID_INIT $QPID_HA; do
+    test -x $f || { echo "$f not found or not executable"; exit 5; }
+done
 
-if [ -f @sysconfdir@/sysconfig/$prog ] ; then
-    . @sysconfdir@/sysconfig/$prog
-fi
+QPID_HA="$QPID_HA $QPID_HA_OPTIONS"
 
-# The following variables can be overridden in @sysconfdir@/sysconfig/$prog
-[[ $QPID_PORT ]] || QPID_PORT=5672
-[[ $QPID_HA ]]   || QPID_HA=@bindir@/qpid-ha
-export QPID_PORT
+source /etc/rc.d/init.d/functions
 
 RETVAL=0
 
-#ensure binary is present and executable
-if [[ !(-x $QPID_HA) ]]; then
-    echo "qpid-ha executable not found or not executable"
-fi
-
 status() {
-    if $QPID_HA -b localhost:$QPID_PORT status --is-primary ; then
+    if $QPID_HA status --is-primary ; then
 	echo "qpidd is primary"
     else
 	echo "qpidd is not primary"
@@ -66,14 +67,14 @@ status() {
 }
 
 start() {
-    service qpidd start
+    $QPID_INIT start
     echo -n $"Promoting qpid daemon to cluster primary: "
-    $QPID_HA -b localhost:$QPID_PORT promote
+    $QPID_HA promote
     [ "$?" -eq 0 ] && success || failure
 }
 
 stop() {
-    service qpidd stop
+    $QPID_INIT stop
 }
 
 reload() {
@@ -82,7 +83,7 @@ reload() {
 }
 
 restart() {
-    service qpidd restart && start
+    $QPID_INIT restart && start
 }
 
 # See how we were called.

Modified: qpid/trunk/qpid/cpp/etc/qpidd.in
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/etc/qpidd.in?rev=1589391&r1=1589390&r2=1589391&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/etc/qpidd.in (original)
+++ qpid/trunk/qpid/cpp/etc/qpidd.in Wed Apr 23 12:42:35 2014
@@ -39,6 +39,11 @@ prog=qpidd
 lockfile=/var/lock/subsys/$prog
 pidfile=/var/run/qpidd.pid
 
+# The following variables can be overridden in @sysconfdir@/sysconfig/$prog
+QPID_BIN=@sbindir@/$prog
+QPID_CONFIG=@confdir@/qpidd.conf
+QPID_DATA_DIR=/var/lib/qpidd
+
 # Source configuration
 if [ -f @sysconfdir@/sysconfig/$prog ] ; then
 	. @sysconfdir@/sysconfig/$prog
@@ -63,9 +68,8 @@ if [ $RETVAL = 4 ]; then
 fi
 
 start() {
-        [[ $QPID_DATA_DIR ]] || QPID_DATA_DIR=/var/lib/qpidd
         echo -n $"Starting Qpid AMQP daemon: "
-	daemon --pidfile $pidfile --check $prog --user qpidd @sbindir@/$prog --data-dir $QPID_DATA_DIR --daemon $QPIDD_OPTIONS
+	daemon --pidfile $pidfile --check $prog --user qpidd $QPID_BIN --config $QPID_CONFIG --data-dir $QPID_DATA_DIR --daemon $QPIDD_OPTIONS
 	RETVAL=$?
 	echo
 	[ $RETVAL = 0 ] && touch $lockfile
@@ -73,7 +77,7 @@ start() {
 	    touch $pidfile
 	    chown qpidd.qpidd $pidfile
             [ -x /sbin/restorecon ] && /sbin/restorecon $pidfile
-	    runuser - -s /bin/sh qpidd -c "@sbindir@/$prog --check > $pidfile"
+	    runuser - -s /bin/sh qpidd -c "$QPID_BIN --check > $pidfile"
 	fi
 	return $RETVAL
 }

Modified: qpid/trunk/qpid/tools/src/py/qpid-ha
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/py/qpid-ha?rev=1589391&r1=1589390&r2=1589391&view=diff
==============================================================================
--- qpid/trunk/qpid/tools/src/py/qpid-ha (original)
+++ qpid/trunk/qpid/tools/src/py/qpid-ha Wed Apr 23 12:42:35 2014
@@ -23,6 +23,7 @@ import optparse, sys, time, os, re
 from qpid.messaging import Connection
 from qpid.messaging import Message as QpidMessage
 from qpidtoollibs.broker import BrokerAgent
+from qpidtoollibs.config import parse_qpidd_conf
 try:
     from uuid import uuid4
 except ImportError:
@@ -48,17 +49,24 @@ class Command:
         usage="%s [options] %s\n\n%s"%(name, " ".join(arg_names), help)
         self.help = help
         self.op=optparse.OptionParser(usage)
-        self.op.add_option("--sasl-mechanism", action="store", type="string", metavar="<mech>", help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD5, DIGEST-MD5, GSSAPI). SASL automatically picks the most secure available mechanism - use this option to override.")
+        self.op.add_option("-b", "--broker", action="store", type="string", default="localhost:5672", metavar="<address>", help="Address of qpidd broker with syntax: [username/password@] hostname | ip-address [:<port>]")
+        self.op.add_option("--sasl-mechanism", metavar="<mech>", help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD5, DIGEST-MD5, GSSAPI). SASL automatically picks the most secure available mechanism - use this option to override.")
         self.op.add_option("--ssl-certificate", action="store", type="string", metavar="<cert>", help="Client SSL certificate (PEM Format)")
         self.op.add_option("--ssl-key", action="store", type="string", metavar="<key>", help="Client SSL private key (PEM Format)")
-        self.op.add_option("-b", "--broker", action="store", type="string", default="localhost:5672", metavar="<address>", help="Address of qpidd broker with syntax: [username/password@] hostname | ip-address [:<port>]")
+        self.op.add_option("--config", metavar="<path/to/qpidd.conf>", help="Connect to the local qpidd by reading its configuration file.")
 
     def connect(self, opts):
         conn_options = {}
-        if opts.sasl_mechanism:
-            conn_options['sasl_mechanisms'] = opts.sasl_mechanism
-        if opts.ssl_certificate:
-            conn_options['ssl_certfile'] = opts.ssl_certificate
+        if opts.config:         # Use broker config file.
+            config = parse_qpidd_conf(opts.config)
+            def joinif(separator, items): return separator.join(filter(None, items))
+            userpass = joinif("/", [config.get("ha-username"), config.get("ha-password")])
+            hostport = joinif(":", ["localhost", config.get("port")])
+            opts.broker = joinif("@", [userpass, hostport])
+            opts.sasl_mechanism = config.get("ha-mechanism")
+
+        if opts.sasl_mechanism: conn_options['sasl_mechanisms'] = opts.sasl_mechanism
+        if opts.ssl_certificate: conn_options['ssl_certfile'] = opts.ssl_certificate
         if opts.ssl_key:
             if not opts.ssl_certificate:
                 self.op.error("missing '--ssl-certificate' (required by '--ssl-key')")
@@ -109,8 +117,11 @@ class StatusCmd(Command):
         brokers = filter(None, re.sub(r'(^amqps?:)|(tcp:)', "", ha_broker.brokersUrl).split(","))
         if opts.all and brokers:
             opts.all=False
+            if "@" in opts.broker: userpass = opts.broker.split("@")[0]
+            else: userpass = None
             for b in brokers:
-                opts.broker = b
+                if userpass and not "@" in b: opts.broker = userpass+"@"+b
+                else: opts.broker = b
                 try:
                     connection, qmf_broker, ha_broker = self.connect(opts)
                     print b, ha_broker.status

Added: qpid/trunk/qpid/tools/src/py/qpidtoollibs/config.py
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/py/qpidtoollibs/config.py?rev=1589391&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/py/qpidtoollibs/config.py (added)
+++ qpid/trunk/qpid/tools/src/py/qpidtoollibs/config.py Wed Apr 23 12:42:35 2014
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+"""Utilities for managing configuration files"""
+import os
+
+QPID_ENV_PREFIX="QPID_"
+
+def parse_qpidd_conf(config_file):
+    """Parse a qpidd.conf configuration file into a dictionary"""
+    with open(config_file) as f:
+        clean = filter(None, [line.split("#")[0].strip() for line in f]) # Strip comments and blanks
+        def item(line): return [x.strip() for x in line.split("=")]
+        config = dict(item(line) for line in clean if "=" in line)
+    def name(env_name): return env_name[len(QPID_ENV_PREFIX):].lower()
+    env = dict((name(i[0]), i[1]) for i in os.environ.iteritems() if i[0].startswith(QPID_ENV_PREFIX))
+    config.update(env)          # Environment takes precedence
+    return config

Propchange: qpid/trunk/qpid/tools/src/py/qpidtoollibs/config.py
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org