[svn] commit: r3092 - /branches/trac300/src/bin/bind10/bind10.py.in

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Sep 30 20:06:58 UTC 2010


Author: vorner
Date: Thu Sep 30 20:06:58 2010
New Revision: 3092

Log:
BoB uses rollback transaction to kill processes

If we are unable to start properly, we need to kill all processes that
we already started. The old code used except and explicit lists of
processes to kill. It now uses isc.utils.rollback.Transaction and adds
the kill actions to it.

Modified:
    branches/trac300/src/bin/bind10/bind10.py.in

Modified: branches/trac300/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac300/src/bin/bind10/bind10.py.in (original)
+++ branches/trac300/src/bin/bind10/bind10.py.in Thu Sep 30 20:06:58 2010
@@ -61,9 +61,11 @@
 import io
 import pwd
 import posix
+import traceback
 
 import isc.cc
 import isc.utils.process
+import isc.utils.rollback
 
 # Assign this process some longer name
 isc.utils.process.rename(sys.argv[0])
@@ -283,168 +285,158 @@
         if self.verbose:
             if self.msgq_socket_file:
                 sys.stdout.write("[bind10] Starting b10-msgq\n")
+
+        err_prefix = None
         try:
-            c_channel = ProcessInfo("b10-msgq", ["b10-msgq"], c_channel_env,
-                                    True, not self.verbose, uid=self.uid,
-                                    username=self.username)
+            with isc.utils.rollback.Transaction() as rollback:
+                err_prefix = 'Unable to start b10-msgq'
+                c_channel = ProcessInfo("b10-msgq", ["b10-msgq"],
+                    c_channel_env, True, not self.verbose, uid=self.uid,
+                    username=self.username)
+                err_prefix = None
+                rollback.add(c_channel.process.kill)
+                self.processes[c_channel.pid] = c_channel
+                if self.verbose:
+                    sys.stdout.write("[bind10] Started b10-msgq (PID %d)\n" %
+                        c_channel.pid)
+
+                # now connect to the c-channel
+                cc_connect_start = time.time()
+                while self.cc_session is None:
+                    # if we have been trying for "a while" give up
+                    if (time.time() - cc_connect_start) > 5:
+                        raise Exception(
+                            "Unable to connect to c-channel after 5 seconds")
+                    # try to connect, and if we can't wait a short while
+                    try:
+                        self.cc_session = isc.cc.Session(self.msgq_socket_file)
+                    except isc.cc.session.SessionError:
+                        time.sleep(0.1)
+
+                # start the configuration manager
+                if self.verbose:
+                    sys.stdout.write("[bind10] Starting b10-cfgmgr\n")
+                err_prefix = 'Unable to start b10-cfgmgr'
+                bind_cfgd = ProcessInfo("b10-cfgmgr", ["b10-cfgmgr"],
+                    c_channel_env, uid=self.uid, username=self.username)
+                rollback.add(bind_cfgd.process.kill)
+                self.processes[bind_cfgd.pid] = bind_cfgd
+                if self.verbose:
+                    sys.stdout.write("[bind10] Started b10-cfgmgr (PID %d)\n" %
+                        bind_cfgd.pid)
+
+                # sleep until b10-cfgmgr is fully up and running, this is
+                # a good place to have a (short) timeout on synchronized
+                # groupsend/receive.
+                # TODO: replace the sleep by a listen for ConfigManager
+                # started message
+                err_prefix = None
+                time.sleep(1)
+                if self.verbose:
+                    sys.stdout.write("[bind10] starting ccsession\n")
+                self.ccs = isc.config.ModuleCCSession(SPECFILE_LOCATION,
+                    self.config_handler, self.command_handler)
+                self.ccs.start()
+                if self.verbose:
+                    sys.stdout.write("[bind10] ccsession started\n")
+
+                # start b10-auth
+                # XXX: this must be read from the configuration manager in
+                # the future
+                authargs = ['b10-auth', '-p', str(self.auth_port)]
+                if self.address:
+                    authargs += ['-a', str(self.address)]
+                if self.nocache:
+                    authargs += ['-n']
+                if self.uid:
+                    authargs += ['-u', str(self.uid)]
+                if self.verbose:
+                    authargs += ['-v']
+                    sys.stdout.write("Starting b10-auth using port %d" %
+                        self.auth_port)
+                    if self.address:
+                        sys.stdout.write(" on %s" % str(self.address))
+                    sys.stdout.write("\n")
+                err_prefix = 'Unable to start b10-auth'
+                auth = ProcessInfo("b10-auth", authargs, c_channel_env)
+                rollback.add(auth.process.kill)
+                self.processes[auth.pid] = auth
+                if self.verbose:
+                    sys.stdout.write("[bind10] Started b10-auth (PID %d)\n" %
+                        auth.pid)
+
+                err_prefix = None
+
+                # everything after the authoritative server can run as non-root
+                if self.uid is not None:
+                    posix.setuid(self.uid)
+
+                # FIXME: This comment suggests that this should be above the
+                # auth, however, it is below, because of the setuid thing.
+                # What is correct?
+                #
+                # start the xfrout before auth-server, to make sure every
+                # xfr-query can be processed properly.
+                xfrout_args = ['b10-xfrout']
+                if self.verbose:
+                    sys.stdout.write("[bind10] Starting b10-xfrout\n")
+                    xfrout_args += ['-v']
+                err_prefix = 'Unable to start b10-xfrout'
+                xfrout = ProcessInfo("b10-xfrout", xfrout_args, c_channel_env)
+                rollback.add(xfrout.process.kill)
+                self.processes[xfrout.pid] = xfrout
+                if self.verbose:
+                    sys.stdout.write("[bind10] Started b10-xfrout (PID %d)\n" %
+                        xfrout.pid)
+
+                # start b10-xfrin
+                xfrin_args = ['b10-xfrin']
+                if self.verbose:
+                    sys.stdout.write("[bind10] Starting b10-xfrin\n")
+                    xfrin_args += ['-v']
+                err_prefix = 'Unable to start b10-xfrin'
+                xfrind = ProcessInfo("b10-xfrin", xfrin_args, c_channel_env)
+                rollback.add(xfrind.process.kill)
+                self.processes[xfrind.pid] = xfrind
+                if self.verbose:
+                    sys.stdout.write("[bind10] Started b10-xfrin (PID %d)\n" %
+                        xfrind.pid)
+
+                # start b10-zonemgr
+                zonemgr_args = ['b10-zonemgr']
+                if self.verbose:
+                    sys.stdout.write("[bind10] Starting b10-zonemgr\n")
+                    zonemgr_args += ['-v']
+                err_prefix = 'Unable to start b10-zonemgr'
+                zonemgr = ProcessInfo("b10-zonemgr", zonemgr_args,
+                    c_channel_env)
+                rollback.add(zonemgr.process.kill)
+                self.processes[zonemgr.pid] = zonemgr
+                if self.verbose:
+                    sys.stdout.write("[bind10] Started b10-zonemgr(PID %d)\n" %
+                        zonemgr.pid)
+
+                # start the b10-cmdctl
+                # XXX: we hardcode port 8080
+                cmdctl_args = ['b10-cmdctl']
+                if self.verbose:
+                    sys.stdout.write(
+                        "[bind10] Starting b10-cmdctl on port 8080\n")
+                    cmdctl_args += ['-v']
+                err_prefix = 'Unable to start b10-cmdctl'
+                cmd_ctrld = ProcessInfo("b10-cmdctl", cmdctl_args,
+                    c_channel_env)
+                rollback.add(cmd_ctrld.process.kill)
+                self.processes[cmd_ctrld.pid] = cmd_ctrld
+                if self.verbose:
+                    sys.stdout.write("[bind10] Started b10-cmdctl (PID %d)\n" %
+                        cmd_ctrld.pid)
+
         except Exception as e:
-            return "Unable to start b10-msgq; " + str(e)
-        self.processes[c_channel.pid] = c_channel
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-msgq (PID %d)\n" % 
-                             c_channel.pid)
-
-        # now connect to the c-channel
-        cc_connect_start = time.time()
-        while self.cc_session is None:
-            # if we have been trying for "a while" give up
-            if (time.time() - cc_connect_start) > 5:
-                c_channel.process.kill()
-                return "Unable to connect to c-channel after 5 seconds"
-            # try to connect, and if we can't wait a short while
-            try:
-                self.cc_session = isc.cc.Session(self.msgq_socket_file)
-            except isc.cc.session.SessionError:
-                time.sleep(0.1)
-
-        # start the configuration manager
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-cfgmgr\n")
-        try:
-            bind_cfgd = ProcessInfo("b10-cfgmgr", ["b10-cfgmgr"],
-                                    c_channel_env, uid=self.uid,
-                                    username=self.username)
-        except Exception as e:
-            c_channel.process.kill()
-            return "Unable to start b10-cfgmgr; " + str(e)
-        self.processes[bind_cfgd.pid] = bind_cfgd
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-cfgmgr (PID %d)\n" % 
-                             bind_cfgd.pid)
-
-        # sleep until b10-cfgmgr is fully up and running, this is a good place
-        # to have a (short) timeout on synchronized groupsend/receive
-        # TODO: replace the sleep by a listen for ConfigManager started
-        # message
-        time.sleep(1)
-        if self.verbose:
-            sys.stdout.write("[bind10] starting ccsession\n")
-        self.ccs = isc.config.ModuleCCSession(SPECFILE_LOCATION, 
-                                      self.config_handler, self.command_handler)
-        self.ccs.start()
-        if self.verbose:
-            sys.stdout.write("[bind10] ccsession started\n")
-
-        # start b10-auth
-        # XXX: this must be read from the configuration manager in the future
-        authargs = ['b10-auth', '-p', str(self.auth_port)]
-        if self.address:
-            authargs += ['-a', str(self.address)]
-        if self.nocache:
-            authargs += ['-n']
-        if self.uid:
-            authargs += ['-u', str(self.uid)]
-        if self.verbose:
-            authargs += ['-v']
-            sys.stdout.write("Starting b10-auth using port %d" %
-                             self.auth_port)
-            if self.address:
-                sys.stdout.write(" on %s" % str(self.address))
-            sys.stdout.write("\n")
-        try:
-            auth = ProcessInfo("b10-auth", authargs,
-                               c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            return "Unable to start b10-auth; " + str(e)
-        self.processes[auth.pid] = auth
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-auth (PID %d)\n" % auth.pid)
-
-        # everything after the authoritative server can run as non-root
-        if self.uid is not None:
-            posix.setuid(self.uid)
-
-        # start the xfrout before auth-server, to make sure every xfr-query can
-        # be processed properly.
-        xfrout_args = ['b10-xfrout']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-xfrout\n")
-            xfrout_args += ['-v']
-        try:
-            xfrout = ProcessInfo("b10-xfrout", xfrout_args, 
-                                 c_channel_env )
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            return "Unable to start b10-xfrout; " + str(e)
-        self.processes[xfrout.pid] = xfrout
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-xfrout (PID %d)\n" % 
-                             xfrout.pid)
-
-        # start b10-xfrin
-        xfrin_args = ['b10-xfrin']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-xfrin\n")
-            xfrin_args += ['-v']
-        try:
-            xfrind = ProcessInfo("b10-xfrin", xfrin_args,
-                                 c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            auth.process.kill()
-            return "Unable to start b10-xfrin; " + str(e)
-        self.processes[xfrind.pid] = xfrind
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-xfrin (PID %d)\n" % 
-                             xfrind.pid)
-
-        # start b10-zonemgr
-        zonemgr_args = ['b10-zonemgr']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-zonemgr\n")
-            zonemgr_args += ['-v']
-        try:
-            zonemgr = ProcessInfo("b10-zonemgr", zonemgr_args,
-                                 c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            auth.process.kill()
-            xfrind.process.kill()
-            return "Unable to start b10-zonemgr; " + str(e)
-        self.processes[zonemgr.pid] = zonemgr 
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-zonemgr(PID %d)\n" % 
-                             zonemgr.pid)
-
-        # start the b10-cmdctl
-        # XXX: we hardcode port 8080
-        cmdctl_args = ['b10-cmdctl']
-        if self.verbose:
-            sys.stdout.write("[bind10] Starting b10-cmdctl on port 8080\n")
-            cmdctl_args += ['-v']
-        try:
-            cmd_ctrld = ProcessInfo("b10-cmdctl", cmdctl_args,
-                                    c_channel_env)
-        except Exception as e:
-            c_channel.process.kill()
-            bind_cfgd.process.kill()
-            xfrout.process.kill()
-            auth.process.kill()
-            xfrind.process.kill()
-            zonemgr.process.kill()
-            return "Unable to start b10-cmdctl; " + str(e)
-        self.processes[cmd_ctrld.pid] = cmd_ctrld
-        if self.verbose:
-            sys.stdout.write("[bind10] Started b10-cmdctl (PID %d)\n" % 
-                             cmd_ctrld.pid)
+            if err_prefix is None:
+                return traceback.format_exc()
+            else:
+                return err_prefix + '; ' + str(e)
 
         self.runnable = True
 




More information about the bind10-changes mailing list