|
|
@@ -0,0 +1,551 @@
|
|
|
+#! /usr/bin/python2
|
|
|
+
|
|
|
+# Authors:
|
|
|
+# Thierry Bordaz <[email protected]>
|
|
|
+#
|
|
|
+# Copyright (C) 2015 Red Hat
|
|
|
+# see file 'COPYING' for use and warranty information
|
|
|
+#
|
|
|
+# This program is free software; you can redistribute it and/or modify
|
|
|
+# it under the terms of the GNU General Public License as published by
|
|
|
+# the Free Software Foundation, either version 3 of the License, or
|
|
|
+# (at your option) any later version.
|
|
|
+#
|
|
|
+# This program is distributed in the hope that it will be useful,
|
|
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
+# GNU General Public License for more details.
|
|
|
+#
|
|
|
+# You should have received a copy of the GNU General Public License
|
|
|
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
+
|
|
|
+import sys
|
|
|
+import os
|
|
|
+import argparse
|
|
|
+import pdb
|
|
|
+import tempfile
|
|
|
+import time
|
|
|
+import pwd
|
|
|
+import grp
|
|
|
+import platform
|
|
|
+import socket
|
|
|
+import shutil
|
|
|
+from subprocess import Popen, PIPE, STDOUT
|
|
|
+import string
|
|
|
+
|
|
|
+SETUP_DS = "/sbin/setup-ds.pl"
|
|
|
+REMOVE_DS = "/sbin/remove-ds.pl"
|
|
|
+INITCONFIGDIR = ".dirsrv"
|
|
|
+SCRIPT_START = "start-slapd"
|
|
|
+SCRIPT_STOP = "stop-slapd"
|
|
|
+SCRIPT_RESTART = "restart-slapd"
|
|
|
+ENVIRON_SERVERID = '389-SERVER-ID'
|
|
|
+ENVIRON_USER = '389-USER'
|
|
|
+ENVIRON_GROUP = '389-GROUP'
|
|
|
+ENVIRON_DIRECTORY = '389-DIRECTORY'
|
|
|
+ENVIRON_PORT = '389-PORT'
|
|
|
+ENVIRON_SECURE_PORT = '389-SECURE-PORT'
|
|
|
+DEFAULT_PORT_ROOT = str(389)
|
|
|
+DEFAULT_PORT_NON_ROOT = str(1389)
|
|
|
+DEFAULT_SECURE_PORT_ROOT = str(636)
|
|
|
+DEFAULT_SECURE_PORT_NON_ROOT = str(1636)
|
|
|
+DEFAULT_USER = 'nobody'
|
|
|
+DEFAULT_GROUP = 'nobody'
|
|
|
+DEFAULT_ROOT_DN = 'cn=Directory Manager'
|
|
|
+DEFAULT_HOSTNAME = socket.gethostname()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def validate_user(user):
|
|
|
+ '''
|
|
|
+ If a user is provided it returns its username
|
|
|
+ else it returns the current username.
|
|
|
+ It checks that the userId or userName exists
|
|
|
+
|
|
|
+ :param: user (optional) can be a userName or userId
|
|
|
+ :return: userName of the provided user, if none is provided, it returns current user name
|
|
|
+ '''
|
|
|
+ assert(user)
|
|
|
+ if user.isdigit():
|
|
|
+ try:
|
|
|
+ username = pwd.getpwuid(int(user)).pw_name
|
|
|
+ except KeyError:
|
|
|
+ raise KeyError('Unknown userId %d' % user)
|
|
|
+ return username
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ pwd.getpwnam(user).pw_uid
|
|
|
+ except KeyError:
|
|
|
+ raise KeyError('Unknown userName %s' % user)
|
|
|
+ return user
|
|
|
+
|
|
|
+def get_default_user():
|
|
|
+ user = os.environ.get(ENVIRON_USER, None)
|
|
|
+ if not user:
|
|
|
+ user = os.getuid()
|
|
|
+ return str(user)
|
|
|
+
|
|
|
+def get_default_group():
|
|
|
+ '''
|
|
|
+ If a group is provided it returns its groupname
|
|
|
+ else it returns the current groupname.
|
|
|
+ It checks that the groupId or groupName exists
|
|
|
+
|
|
|
+ :param: group (optional) can be a groupName or groupId
|
|
|
+ :return: groupName of the provided group, if none is provided, it returns current group name
|
|
|
+ '''
|
|
|
+ group = os.environ.get(ENVIRON_GROUP, None)
|
|
|
+ if not group:
|
|
|
+ return pwd.getpwuid(os.getuid()).pw_name
|
|
|
+ return group
|
|
|
+
|
|
|
+def validate_group(group):
|
|
|
+ assert(group)
|
|
|
+ if str(group).isdigit():
|
|
|
+ try:
|
|
|
+ groupname = grp.getgrgid(group).gr_name
|
|
|
+ return groupname
|
|
|
+ except:
|
|
|
+ raise KeyError('Unknown groupId %d' % group)
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ groupname = grp.getgrnam(group).gr_name
|
|
|
+ return groupname
|
|
|
+ except:
|
|
|
+ raise KeyError('Unknown groupName %s' % group)
|
|
|
+
|
|
|
+def test_get_group():
|
|
|
+ try:
|
|
|
+ grpname = get_default_group()
|
|
|
+ print 'get_group: %s' % grpname
|
|
|
+ except:
|
|
|
+ raise
|
|
|
+ print "Can not find user group"
|
|
|
+ pass
|
|
|
+ try:
|
|
|
+ grpname = get_default_group(group='tbordaz')
|
|
|
+ print 'get_group: %s' % grpname
|
|
|
+ except:
|
|
|
+ raise
|
|
|
+ print "Can not find user group"
|
|
|
+ pass
|
|
|
+ try:
|
|
|
+ grpname = get_default_group(group='coucou')
|
|
|
+ print 'get_group: %s' % grpname
|
|
|
+ except:
|
|
|
+ print "Can not find user group coucou"
|
|
|
+ pass
|
|
|
+ try:
|
|
|
+ grpname = get_default_group('thierry')
|
|
|
+ print 'get_group: %s' % grpname
|
|
|
+ except:
|
|
|
+ raise
|
|
|
+ print "Can not find user group thierry"
|
|
|
+ pass
|
|
|
+ try:
|
|
|
+ grpname = get_default_group(1000)
|
|
|
+ print 'get_group: %s' % grpname
|
|
|
+ except:
|
|
|
+ raise
|
|
|
+ print "Can not find user group 1000"
|
|
|
+ pass
|
|
|
+ try:
|
|
|
+ grpname = get_default_group(20532)
|
|
|
+ print 'get_group: %s' % grpname
|
|
|
+ except:
|
|
|
+ raise
|
|
|
+ print "Can not find user group 20532"
|
|
|
+ pass
|
|
|
+ try:
|
|
|
+ grpname = get_default_group(123)
|
|
|
+ print 'get_group: %s' % grpname
|
|
|
+ except:
|
|
|
+ print "Can not find user group 123"
|
|
|
+ pass
|
|
|
+
|
|
|
+def get_default_port():
|
|
|
+ port = os.environ.get(ENVIRON_PORT, None)
|
|
|
+ if port:
|
|
|
+ return port
|
|
|
+
|
|
|
+ if os.getuid() == 0:
|
|
|
+ return DEFAULT_PORT_ROOT
|
|
|
+ else:
|
|
|
+ return DEFAULT_PORT_NON_ROOT
|
|
|
+
|
|
|
+def validate_port(port):
|
|
|
+ assert port
|
|
|
+ if not port.isdigit() or int(port) <= 0 :
|
|
|
+ raise Exception("port number is invalid: %s" % port)
|
|
|
+
|
|
|
+def get_default_directory():
|
|
|
+ directory = os.environ.get(ENVIRON_DIRECTORY, None)
|
|
|
+ if not directory:
|
|
|
+ directory = os.getcwd()
|
|
|
+ return directory
|
|
|
+
|
|
|
+def validate_directory(directory):
|
|
|
+ assert directory
|
|
|
+ if not os.path.isdir(directory):
|
|
|
+ raise Exception("Supplied directory path is not a directory")
|
|
|
+
|
|
|
+ if not os.access(directory, os.W_OK):
|
|
|
+ raise Exception("Supplied directory is not writable")
|
|
|
+
|
|
|
+def get_default_serverid():
|
|
|
+ serverid = os.environ.get(ENVIRON_SERVERID, None)
|
|
|
+ if not serverid:
|
|
|
+ serverid = socket.gethostname().split('.')[0]
|
|
|
+ return serverid
|
|
|
+
|
|
|
+def validate_serverid(serverid):
|
|
|
+ if not serverid:
|
|
|
+ raise Exception("Server id is not defined")
|
|
|
+ return serverid
|
|
|
+
|
|
|
+
|
|
|
+def get_inst_dir(serverid):
|
|
|
+ assert serverid
|
|
|
+ home = os.getenv("HOME")
|
|
|
+ inst_initconfig_file = "%s/%s/dirsrv-%s" % (home, INITCONFIGDIR, serverid)
|
|
|
+ if not os.path.isfile(inst_initconfig_file):
|
|
|
+ raise Exception("%s config file not found" % inst_initconfig_file)
|
|
|
+ f = open(inst_initconfig_file, "r")
|
|
|
+ for line in f:
|
|
|
+ if line.startswith("INST_DIR"):
|
|
|
+ inst_dir = line.split("=")[1]
|
|
|
+ inst_dir = inst_dir.replace("\r", "")
|
|
|
+ inst_dir = inst_dir.replace("\n", "")
|
|
|
+ return inst_dir
|
|
|
+
|
|
|
+def sanity_check():
|
|
|
+ if os.getuid() == 0:
|
|
|
+ raise Exception("Not tested for root user.. sorry")
|
|
|
+
|
|
|
+ home = os.getenv("HOME")
|
|
|
+ inst_initconfig_dir = "%s/%s" % (home, INITCONFIGDIR)
|
|
|
+ if not os.path.isdir(inst_initconfig_dir):
|
|
|
+ raise Exception("Please create the directory \'%s\' and retry." % inst_initconfig_dir )
|
|
|
+
|
|
|
+class DSadmCmd(object):
|
|
|
+ def __init__(self):
|
|
|
+ self.version = '0.1'
|
|
|
+
|
|
|
+ def _start_subparser(self, subparsers):
|
|
|
+ start_parser = subparsers.add_parser(
|
|
|
+ 'start',
|
|
|
+ help='Start a Directory Server Instance')
|
|
|
+ start_parser.add_argument('-I', '--server-id', dest='server_id', type=str, nargs='?',
|
|
|
+ metavar='SERVER-ID',
|
|
|
+ help='Server Identifier (Default: %s) ' % get_default_serverid())
|
|
|
+ start_parser.set_defaults(func=self.start_action)
|
|
|
+
|
|
|
+ def _stop_subparser(self, subparsers):
|
|
|
+ start_parser = subparsers.add_parser(
|
|
|
+ 'stop',
|
|
|
+ help='Stop a Directory Server Instance')
|
|
|
+ start_parser.add_argument('-I', '--server-id', dest='server_id', type=str, nargs='?',
|
|
|
+ metavar='SERVER-ID',
|
|
|
+ help='Server Identifier (Default: %s) ' % get_default_serverid())
|
|
|
+ start_parser.set_defaults(func=self.stop_action)
|
|
|
+
|
|
|
+ def _restart_subparser(self, subparsers):
|
|
|
+ start_parser = subparsers.add_parser(
|
|
|
+ 'restart',
|
|
|
+ help='Retart a Directory Server Instance')
|
|
|
+ start_parser.add_argument('-I', '--server-id', dest='server_id', type=str, nargs='?',
|
|
|
+ metavar='SERVER-ID',
|
|
|
+ help='Server Identifier (Default: %s) ' % get_default_serverid())
|
|
|
+ start_parser.set_defaults(func=self.restart_action)
|
|
|
+
|
|
|
+ def _delete_subparser(self, subparsers):
|
|
|
+ delete_parser = subparsers.add_parser(
|
|
|
+ 'delete',
|
|
|
+ help='Delete a Directory Server Instance')
|
|
|
+ delete_parser.add_argument('-I', '--server-id', dest='server_id', type=str, nargs='?',
|
|
|
+ metavar='SERVER-ID',
|
|
|
+ help='Server Identifier (Default: %s) ' % get_default_serverid())
|
|
|
+ delete_parser.add_argument('-debug', '--debug', dest='debug_level', type=int, nargs='?',
|
|
|
+ metavar='DEBUG_LEVEL',
|
|
|
+ help='Debug level (Default: 0)')
|
|
|
+ delete_parser.set_defaults(func=self.delete_action)
|
|
|
+
|
|
|
+ def _create_subparser(self, subparsers):
|
|
|
+ create_parser = subparsers.add_parser(
|
|
|
+ 'create',
|
|
|
+ help='Create a Directory Server Instance')
|
|
|
+ create_parser.add_argument('-I', '--server-id', dest='server_id', type=str, nargs='?',
|
|
|
+ metavar='SERVER-ID',
|
|
|
+ help='Server Identifier (Default: %s) ' % get_default_serverid())
|
|
|
+ create_parser.add_argument('-s', '--suffix', dest='suffix', type=str, nargs='?',
|
|
|
+ metavar='SUFFIX-DN',
|
|
|
+ help='Suffix (Default: create no suffix)')
|
|
|
+ create_parser.add_argument('-p', '--port', dest='port', type=int, nargs='?',
|
|
|
+ metavar='NON-SECURE-PORT',
|
|
|
+ help='Normal Port to listen (Default: %s(root)/%s(non-root)) ' % (DEFAULT_PORT_ROOT, DEFAULT_PORT_NON_ROOT))
|
|
|
+
|
|
|
+ create_parser.add_argument('-P', '--secure-port', dest='secure_port', type=int, nargs='?',
|
|
|
+ metavar='SECURE-PORT',
|
|
|
+ help='Secure Port to listen (Default: %s(root)/%s(non-root))' % (DEFAULT_SECURE_PORT_ROOT, DEFAULT_SECURE_PORT_NON_ROOT))
|
|
|
+
|
|
|
+ create_parser.add_argument('-D', '--rootDN', dest='root_dn', type=str, nargs='?',
|
|
|
+ metavar='ROOT-DN',
|
|
|
+ help='Uses DN as Directory Manager DN (Default: \'%s\')' % (DEFAULT_ROOT_DN))
|
|
|
+
|
|
|
+ create_parser.add_argument('-u', '--user-name', dest='user_name', type=str, nargs='?',
|
|
|
+ metavar='USER-NAME',
|
|
|
+ help='User name of the instance owner (Default: %s)' % DEFAULT_USER)
|
|
|
+
|
|
|
+ create_parser.add_argument('-g', '--group-name', dest='group_name', type=str, nargs='?',
|
|
|
+ metavar='GROUP-NAME',
|
|
|
+ help='Group name of the instance owner (Default: %s)' % DEFAULT_GROUP)
|
|
|
+
|
|
|
+ create_parser.add_argument('-d', '--directory-path', dest='directory_path', type=str, nargs='?',
|
|
|
+ metavar='DIRECTORY-PATH',
|
|
|
+ help='Installation directory path (Default: %s)' % get_default_directory())
|
|
|
+ create_parser.add_argument('-debug', '--debug', dest='debug_level', type=int, nargs='?',
|
|
|
+ metavar='DEBUG_LEVEL',
|
|
|
+ help='Debug level (Default: 0)')
|
|
|
+ create_parser.add_argument('-k', '--keep_template', dest='keep_template', type=str, nargs='?',
|
|
|
+ help='Keep template file')
|
|
|
+
|
|
|
+ create_parser.set_defaults(func=self.create_action)
|
|
|
+
|
|
|
+ #
|
|
|
+ # common function for start/stop/restart actions
|
|
|
+ #
|
|
|
+ def script_action(self, args, script, action_str):
|
|
|
+ args = vars(args)
|
|
|
+ serverid = args.get('server_id', None)
|
|
|
+ if not serverid:
|
|
|
+ serverid = get_default_serverid()
|
|
|
+
|
|
|
+ script_file = "%s/%s" % (get_inst_dir(serverid), script)
|
|
|
+ if not os.path.isfile(script_file):
|
|
|
+ raise Exception("%s not found" % script_file)
|
|
|
+
|
|
|
+ if not os.access(script_file, os.X_OK):
|
|
|
+ raise Exception("%s not executable" % script_file)
|
|
|
+
|
|
|
+ env = os.environ.copy()
|
|
|
+ prog = [ script_file ]
|
|
|
+ pipe = Popen(prog, cwd=os.getcwd(), env=env,
|
|
|
+ stdin=PIPE, stdout=PIPE, stderr=STDOUT)
|
|
|
+ child_stdin = pipe.stdin
|
|
|
+ child_stdout = pipe.stdout
|
|
|
+ for line in child_stdout:
|
|
|
+ sys.stdout.write(line)
|
|
|
+ child_stdout.close()
|
|
|
+ child_stdin.close()
|
|
|
+
|
|
|
+ rc = pipe.wait()
|
|
|
+ if rc == 0:
|
|
|
+ print "Directory %s %s" % (serverid, action_str)
|
|
|
+ else:
|
|
|
+ print "Failure: directory %s not %s (%s)" % (serverid, action_str, rc)
|
|
|
+ return
|
|
|
+
|
|
|
+ def start_action(self, args):
|
|
|
+ self.script_action(args, SCRIPT_START, "started")
|
|
|
+
|
|
|
+
|
|
|
+ def stop_action(self, args):
|
|
|
+ self.script_action(args, SCRIPT_STOP, "stopped")
|
|
|
+
|
|
|
+
|
|
|
+ def restart_action(self, args):
|
|
|
+
|
|
|
+ self.script_action(args, SCRIPT_RESTART, "restarted")
|
|
|
+
|
|
|
+ def delete_action(self, args):
|
|
|
+ args = vars(args)
|
|
|
+ serverid = args.get('server_id', None)
|
|
|
+ if not serverid:
|
|
|
+ serverid = get_default_serverid()
|
|
|
+
|
|
|
+ #prepare the remove-ds options
|
|
|
+ debug_level = args.get('debug_level', None)
|
|
|
+ if debug_level:
|
|
|
+ debug_str = ['-d']
|
|
|
+ for i in range(1, int(debug_level)):
|
|
|
+ debug_str.append('d')
|
|
|
+ debug_str = ''.join(debug_str)
|
|
|
+
|
|
|
+ env = os.environ.copy()
|
|
|
+ prog = [REMOVE_DS]
|
|
|
+ if debug_level:
|
|
|
+ prog.append(debug_str)
|
|
|
+ prog.append("-i")
|
|
|
+ prog.append("slapd-%s" % serverid)
|
|
|
+
|
|
|
+ # run the REMOVE_DS command and print the possible output
|
|
|
+ pipe = Popen(prog, cwd=os.getcwd(), env=env,
|
|
|
+ stdin=PIPE, stdout=PIPE, stderr=STDOUT)
|
|
|
+ child_stdin = pipe.stdin
|
|
|
+ child_stdout = pipe.stdout
|
|
|
+ for line in child_stdout:
|
|
|
+ if debug_level:
|
|
|
+ sys.stdout.write(line)
|
|
|
+ child_stdout.close()
|
|
|
+ child_stdin.close()
|
|
|
+
|
|
|
+ rc = pipe.wait()
|
|
|
+ if rc == 0:
|
|
|
+ print "Directory server \'%s\' successfully deleted" % serverid
|
|
|
+ else:
|
|
|
+ print "Fail to delete directory \'%s\': %d" % (serverid, rc)
|
|
|
+ return
|
|
|
+
|
|
|
+ #
|
|
|
+ # used by create subcommand to build the template file
|
|
|
+ #
|
|
|
+ def _create_setup_ds_file(self, args, user=None, group=None):
|
|
|
+ # Get/checks the argument with the following order
|
|
|
+ # - parameter
|
|
|
+ # - Environment
|
|
|
+ # - default
|
|
|
+ serverid = args.get('server_id', None)
|
|
|
+ if not serverid:
|
|
|
+ serverid = get_default_serverid()
|
|
|
+ serverid = validate_serverid(serverid)
|
|
|
+
|
|
|
+ username = args.get('user_name', None)
|
|
|
+ if not username:
|
|
|
+ username = get_default_user()
|
|
|
+ username = validate_user(username)
|
|
|
+
|
|
|
+ groupname = args.get('group_name', None)
|
|
|
+ if not groupname:
|
|
|
+ groupname = get_default_group()
|
|
|
+ groupname = validate_group(groupname)
|
|
|
+
|
|
|
+ directoryname = args.get('directory_path', None)
|
|
|
+ if not directoryname:
|
|
|
+ directoryname = get_default_directory()
|
|
|
+ validate_directory(directoryname)
|
|
|
+
|
|
|
+ portnumber = args.get('port', None)
|
|
|
+ if not portnumber:
|
|
|
+ portnumber = get_default_port()
|
|
|
+ validate_port(portnumber)
|
|
|
+
|
|
|
+ suffix = args.get('suffix', None)
|
|
|
+
|
|
|
+ tempf = tempfile.NamedTemporaryFile(delete=False)
|
|
|
+
|
|
|
+ tempf.write('[General]\n')
|
|
|
+ tempf.write('FullMachineName=%s\n' % DEFAULT_HOSTNAME)
|
|
|
+ tempf.write('SuiteSpotUserID=%s\n' % username)
|
|
|
+ tempf.write('SuiteSpotGroup=%s\n' % groupname)
|
|
|
+ tempf.write('ServerRoot=%s\n' % directoryname)
|
|
|
+ tempf.write('\n')
|
|
|
+ tempf.write('[slapd]\n')
|
|
|
+ tempf.write('ServerPort=1389\n')
|
|
|
+ tempf.write('ServerIdentifier=%s\n' % serverid)
|
|
|
+ if suffix:
|
|
|
+ tempf.write('Suffix=%s\n' % suffix)
|
|
|
+ tempf.write('RootDN=cn=Directory Manager\n')
|
|
|
+ tempf.write('RootDNPwd=Secret12\n')
|
|
|
+ tempf.write('sysconfdir=%s/etc\n' % directoryname)
|
|
|
+ tempf.write('localstatedir=%s/var\n' % directoryname)
|
|
|
+ tempf.write('inst_dir=%s/lib/dirsrv/slapd-%s\n'% (directoryname, serverid))
|
|
|
+ tempf.write('config_dir=%s/etc/dirsrv/slapd-%s\n' % (directoryname, serverid))
|
|
|
+ tempf.close()
|
|
|
+
|
|
|
+ keep_template = args.get('keep_template', None)
|
|
|
+ if keep_template:
|
|
|
+ shutil.copy(tempf.name, keep_template)
|
|
|
+
|
|
|
+
|
|
|
+ return tempf
|
|
|
+
|
|
|
+ #
|
|
|
+ # It silently creates an instance.
|
|
|
+ # After creation the instance is started
|
|
|
+ #
|
|
|
+ def create_action(self, args):
|
|
|
+ args = vars(args)
|
|
|
+
|
|
|
+ # retrieve the serverid here just to log the final status
|
|
|
+ serverid = args.get('server_id', None)
|
|
|
+ if not serverid:
|
|
|
+ serverid = get_default_serverid()
|
|
|
+
|
|
|
+ # prepare the template file
|
|
|
+ tempf = self._create_setup_ds_file(args)
|
|
|
+
|
|
|
+ #prepare the setup-ds options
|
|
|
+ debug_level = args.get('debug_level', None)
|
|
|
+ if debug_level:
|
|
|
+ debug_str = ['-d']
|
|
|
+ for i in range(1, int(debug_level)):
|
|
|
+ debug_str.append('d')
|
|
|
+ debug_str = ''.join(debug_str)
|
|
|
+
|
|
|
+ #
|
|
|
+ # run the SETUP_DS command and print the possible output
|
|
|
+ #
|
|
|
+ env = os.environ.copy()
|
|
|
+ prog = [SETUP_DS]
|
|
|
+ if debug_level:
|
|
|
+ prog.append(debug_str)
|
|
|
+ prog.append("--silent")
|
|
|
+ prog.append("--file=%s" % tempf.name)
|
|
|
+ tempf.close()
|
|
|
+
|
|
|
+ pipe = Popen(prog, cwd=os.getcwd(), env=env,
|
|
|
+ stdin=PIPE, stdout=PIPE, stderr=STDOUT)
|
|
|
+ child_stdin = pipe.stdin
|
|
|
+ child_stdout = pipe.stdout
|
|
|
+ for line in child_stdout:
|
|
|
+ if debug_level:
|
|
|
+ sys.stdout.write(line)
|
|
|
+ child_stdout.close()
|
|
|
+ child_stdin.close()
|
|
|
+
|
|
|
+ os.unlink(tempf.name)
|
|
|
+ rc = pipe.wait()
|
|
|
+ if rc == 0:
|
|
|
+ print "Directory server \'%s\' successfully created" % serverid
|
|
|
+ else:
|
|
|
+ print "Fail to create directory \'%s\': %d" % (serverid, rc)
|
|
|
+ return
|
|
|
+
|
|
|
+ #
|
|
|
+ # parser of the main command. It contains subcommands
|
|
|
+ #
|
|
|
+ def get_parser(self, argv):
|
|
|
+
|
|
|
+
|
|
|
+ parser = argparse.ArgumentParser(
|
|
|
+ description='Managing a local directory server instance')
|
|
|
+
|
|
|
+ subparsers = parser.add_subparsers(
|
|
|
+ metavar='SUBCOMMAND',
|
|
|
+ help='The action to perform')
|
|
|
+
|
|
|
+ #pdb.set_trace()
|
|
|
+ # subcommands
|
|
|
+ self._create_subparser(subparsers)
|
|
|
+ self._delete_subparser(subparsers)
|
|
|
+ self._start_subparser(subparsers)
|
|
|
+ self._stop_subparser(subparsers)
|
|
|
+ self._restart_subparser(subparsers)
|
|
|
+
|
|
|
+ # Sanity check that the debug level is valid
|
|
|
+ args = vars(parser.parse_args(argv))
|
|
|
+ debug_level = args.get('debug_level', None)
|
|
|
+ if debug_level and (int(debug_level) < 1 or int(debug_level > 5)):
|
|
|
+ raise Exception("invalid debug level: range 1..5")
|
|
|
+
|
|
|
+ return parser
|
|
|
+
|
|
|
+ def main(self, argv):
|
|
|
+ sanity_check()
|
|
|
+ parser = self.get_parser(argv)
|
|
|
+ args = parser.parse_args(argv)
|
|
|
+ args.func(args)
|
|
|
+ return
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ DSadmCmd().main(sys.argv[1:])
|