BIND 10 master, updated. e4fe372ea63d2115ca2e15866f0ef032fb05e0ca [master] Update changelog for merge of #2305

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Nov 14 14:22:30 UTC 2012


The branch, master has been updated
       via  e4fe372ea63d2115ca2e15866f0ef032fb05e0ca (commit)
       via  c4b0294b5bf4a9d32fb18ab62ca572f492788d72 (commit)
       via  10d9112a1eefa19109036da9e4a39bc4ba836021 (commit)
       via  8872c15e883710475348463a87916d589c428031 (commit)
       via  3d71b86e777c7280043a1191bbeb0bb115f88078 (commit)
       via  56f0319afe0f63710358a2fd123e9865f1a13758 (commit)
       via  45088a0f850de1724eff8daff9fdc2303887ee13 (commit)
       via  65dd63b2c9e72794b0029c5071e9fbf948321ccd (commit)
       via  9478cb0fdc9896568928701bda3101b0a2fbcf16 (commit)
       via  d2103c888085b93e48731258fb7900c01a921734 (commit)
      from  470aa3b8ecb855b0a9f6ad75b44c4f30bf35de8a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit e4fe372ea63d2115ca2e15866f0ef032fb05e0ca
Author: Jelte Jansen <jelte at isc.org>
Date:   Wed Nov 14 15:22:18 2012 +0100

    [master] Update changelog for merge of #2305

commit c4b0294b5bf4a9d32fb18ab62ca572f492788d72
Merge: 470aa3b 10d9112
Author: Jelte Jansen <jelte at isc.org>
Date:   Wed Nov 14 15:19:32 2012 +0100

    [master] Merge branch 'trac2305'

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                     |    5 +
 doc/guide/bind10-guide.xml    |  604 ++++++++++++++++++++++++++++++++++++++++-
 src/bin/bindctl/moduleinfo.py |    3 +-
 3 files changed, 597 insertions(+), 15 deletions(-)

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 631c33c..087f5af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+506.	[doc]		jelte
+	Added a chapter about the use of the bindctl command tool to
+	to the BIND 10 guide.
+	(Trac #2305, git c4b0294b5bf4a9d32fb18ab62ca572f492788d72)
+
 505.	[bug]		jelte
 	Fixed a bug in b10-xfrin where a wrong call was made during the
 	final check of a TSIG-signed transfer, incorrectly rejecting the
diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml
index 6065616..e0266e1 100644
--- a/doc/guide/bind10-guide.xml
+++ b/doc/guide/bind10-guide.xml
@@ -1275,6 +1275,14 @@ TODO
       configuring BIND 10.
     </para></note>
 
+    <note><para>
+      <command>bindctl</command> has an internal command history, as
+      well as tab-completion for most of the commands and arguments.
+      However, these are only enabled if the python readline module
+      is available on the system. If not, neither of these
+      features will be supported.
+    </para></note>
+
     <para>
       The <command>bindctl</command> tool provides an interactive
       prompt for configuring, controlling, and querying the BIND 10
@@ -1284,22 +1292,590 @@ TODO
       communicate to any other components directly.
     </para>
 
-<!-- TODO: explain and show interface -->
+    <section id="bindctl_commandline_options">
+        <title>bindctl command-line options</title>
+        <variablelist>
+          <varlistentry>
+            <term>-a <replaceable><address></replaceable>, --address=<replaceable><address></replaceable></term>
+            <listitem>
+              <simpara>
+                  IP address that BIND 10's <command>b10-cmdctl</command>
+                  module is listening on. By default, this is 127.0.0.1.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>-c <replaceable><certificate file></replaceable>, --certificate-chain=<replaceable><certificate file></replaceable></term>
+            <listitem>
+              <simpara>
+                  PEM-formatted server certificate file. When this option is
+                  given, <command>bindctl</command> will verify the server
+                  certificate using the given file as the root of the
+                  certificate chain. If not specified, <command>bindctl
+                  </command> does not validate the certificate.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>--csv-file-dir=<replaceable><csv file></replaceable></term>
+            <listitem>
+              <simpara>
+                  <command>bindctl</command> stores the username and
+                  password for logging in in a file called
+                  <filename>default_user.csv</filename>;
+                  this option specifies the directory where this file is
+                  stored and read from. When not specified,
+                  <filename>~/.bind10/</filename> is used.
+                  <note>Currently, this file contains an unencrypted password.</note>
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>-h, --help</term>
+            <listitem>
+              <simpara>
+                  Shows a short overview of the command-line options of
+                  <command>bindctl</command>, and exits.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>--version</term>
+            <listitem>
+              <simpara>
+                  Shows the version of <command>bindctl</command>, and exits.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>-p <replaceable><port number></replaceable>, --port=<replaceable><port number></replaceable></term>
+            <listitem>
+              <simpara>
+                  Port number that BIND 10's <command>b10-cmdctl</command>
+                  module is listening on. By default, this is port 8080.
+              </simpara>
+            </listitem>
+          </varlistentry>
+        </variablelist>
+    </section>
 
-    <para>
-      Configuration changes are actually commands to
-      <command>b10-cfgmgr</command>. So when <command>bindctl</command>
-      sends a configuration, it is sent to <command>b10-cmdctl</command>
-      (over a HTTPS connection); then <command>b10-cmdctl</command>
-      sends the command (over a <command>b10-msgq</command> command
-      channel) to <command>b10-cfgmgr</command> which then stores
-      the details and relays (over a <command>b10-msgq</command> command
-      channel) the configuration on to the specified module.
-    </para>
+    <section id="bindctl_general_syntax">
+        <title>General syntax of bindctl commands</title>
+        The <command>bindctl</command> tool is an interactive
+        command-line tool, with dynamic commands depending on the
+        BIND 10 modules that are running. There are a number of
+        fixed commands that have no module and that are always
+        available.
 
-    <para>
-    </para>
+        The general syntax of a command is
+
+        <screen><userinput><module> <command> <replaceable>[argument(s)]</replaceable></userinput></screen>
+
+        For example, the Boss module has a 'shutdown' command to shut down
+        BIND 10, with an optional argument 'help':
+
+        <screen><userinput>> Boss shutdown help</userinput>
+Command  shutdown 	(Shut down BIND 10)
+		help (Get help for command)
+This command has no parameters
+        </screen>
+        There are no mandatory arguments, only the optional 'help'.
+    </section>
+
+    <section id="bindctl_help">
+        <title>Bindctl help</title>
+        <command>help</command> is both a command and an option that is available to all other commands. When run as a command directly, it shows the available modules.
+        <screen>> <userinput>help</userinput>
+usage: <module name> <command name> [param1 = value1 [, param2 = value2]]
+Type Tab character to get the hint of module/command/parameters.
+Type "help(? h)" for help on bindctl.
+Type "<module_name> help" for help on the specific module.
+Type "<module_name> <command_name> help" for help on the specific command.
+
+Available module names:
+<emphasis>(list of modules)</emphasis>
+        </screen>
+
+        When 'help' is used as a command to a module, it shows the supported commands for the module; for example:
+        <screen>> <userinput>Boss help</userinput>
+Module  Boss 	Master process
+Available commands:
+    help        Get help for module.
+    shutdown    Shut down BIND 10
+    ping        Ping the boss process
+    show_processes
+            List the running BIND 10 processes
+        </screen>
+
+    And when added to a module command, it shows the description and parameters of that specific command; for example:
+    <screen>> <userinput>Auth loadzone help</userinput>
+Command  loadzone 	((Re)load a specified zone)
+		help (Get help for command)
+Parameters:
+    class (string, optional)
+    origin (string, mandatory)
+    </screen>
+
+    </section>
 
+    <section id="bindctl_command_arguments">
+        <title>Command arguments</title>
+        <simpara>
+            Commands can have arguments, which can be either optional or
+            mandatory. They can be specified by name
+            (e.g. <command><replaceable><command></replaceable> <replaceable><argument name>=<argument value></replaceable></command>), or positionally,
+            (e.g. <command><replaceable><command></replaceable> <replaceable><argument value 1></replaceable> <replaceable><argument value 2></replaceable></command>).
+        </simpara>
+        <simpara>
+            <command><replaceable><command></replaceable> <replaceable>help</replaceable></command>
+            shows the arguments a command supports and which of those are
+            mandatory, and in which order the arguments are expected if
+            positional arguments are used.
+        </simpara>
+        <simpara>
+            For example, the <command>loadzone</command> command of the Auth
+            module, as shown in the last example of the previous section, has
+            two arguments, one of which is optional. The positional arguments in
+            this case are class first and origin second; for example:
+            <screen>> <userinput>Auth loadzone IN example.com.</userinput></screen>
+            But since the class is optional (defaulting to IN), leaving it out
+            works as well:
+            <screen>> <userinput>Auth loadzone example.com.</userinput></screen>
+        </simpara>
+        <simpara>
+            The arguments can also be provided with their names, in which
+            case the order does not matter:
+            <screen>> <userinput>Auth loadzone origin="example.com." class="IN"</userinput></screen>
+        </simpara>
+    </section>
+
+    <section id="bindctl_module_commands">
+        <title>Module commands</title>
+        Each module has its own set of commands (if any), which will only be
+        available if the module is running. For instance, the
+        Auth module has a <command>loadzone</command> command.
+        The commands a module provides are documented in
+        this guide in the section of that module or in the module's
+        corresponding manual page.
+    </section>
+
+    <section>
+        <title>Configuration commands</title>
+        Configuration commands are used to view and change the configuration
+        of BIND 10 and its modules. Module configuration is only shown if
+        that module is running, but similar to commands, there are a number
+        of top-level configuration items that are always available (for
+        instance <varname>tsig_keys</varname> and
+        <varname>data_sources</varname>).
+
+        Configuration changes (set, unset, add and remove) are done locally
+        first, and have no immediate effect. The changes can be viewed with
+        <command>config diff</command>, and either reverted
+        (<command>config revert</command>), or committed
+        (<command>config commit</command>).
+        In the latter case, all local changes are submitted
+        to the configuration manager, which verifies them, and if they are
+        accepted, applied and saved in persistent storage.
+
+        When identifying items in configuration commands, the format is
+        <screen><userinput>Module/example/item</userinput></screen>
+        Sub-elements of names, lists and sets (see <xref linkend=
+        "bindctl_configuration_data_types"/>) are separated with the '/'
+        character, and list indices are identified with [<replaceable><index></replaceable>]; for example:
+
+        <screen><userinput>Module/example/list[2]/foo</userinput></screen>
+
+        <section id="bindctl_configuration_command_list">
+        <title>List of configuration commands</title>
+        The following configuration commands are available:
+        <variablelist>
+          <varlistentry>
+            <term>show [all] [item name]</term>
+            <listitem>
+              <simpara>
+                Shows the current configuration of the given item. If 'all'
+                is given, it will recurse through the entire set, and show
+                every nested value.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>show_json [item name]</term>
+            <listitem>
+              <simpara>
+                Shows the full configuration of the given item in JSON format.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>add <item name> [value]</term>
+            <listitem>
+              <simpara>
+                Add an entry to configuration list or a named set (see <xref
+                linkend="bindctl_configuration_data_types"/>).
+                When adding to a list, the command has one optional
+                argument, a value to add to the list. The value must
+                be in correct JSON and complete. When adding to a
+                named set, it has one mandatory parameter (the name to
+                add), and an optional parameter value, similar to when
+                adding to a list. In either case, when no value is
+                given, an entry will be constructed with default
+                values.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>remove</term>
+            <listitem>
+              <simpara>
+                Remove an item from a configuration list or a named set.
+                When removing an item for a list, either the index needs to
+                be specified, or the complete value of the element to remove
+                must be specified (in JSON format).
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>set <item name> <value></term>
+            <listitem>
+              <simpara>
+                  Directly set the value of the given item to the given value.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>unset <item name></term>
+            <listitem>
+              <simpara>
+                  Remove any user-specified value for the given item.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>diff</term>
+            <listitem>
+              <simpara>
+                  Show all current local changes that have not been
+                  committed yet.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>revert</term>
+            <listitem>
+              <simpara>
+                  Revert all local changes without committing them.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>commit</term>
+            <listitem>
+              <simpara>
+                  Send all local changes to the configuration manager, which
+                  will validate them, and apply them if validation succeeds.
+              </simpara>
+            </listitem>
+          </varlistentry>
+          <varlistentry>
+            <term>go</term>
+            <listitem>
+              <simpara>
+                  Go to a specific configuration part, similar to the 'cd'
+                  command in a shell.
+                  <note>There are a number of problems with the current
+                  implementation of go within <command>bindctl</command>,
+                  and we recommend not using it for general cases.</note>
+              </simpara>
+            </listitem>
+          </varlistentry>
+        </variablelist>
+      </section>
+
+      <section id="bindctl_configuration_data_types">
+        <title>Configuration data types</title>
+        Configuration data can be of different types, which can be modified
+        in ways that depend on the types. There are a few syntax
+        restrictions on these types, but only basic ones. Modules may impose
+        additional restrictions on the values of elements.
+        <variablelist>
+            <varlistentry>
+                <term>integer</term>
+                <listitem>
+                    <simpara>
+                        A basic integer; can be set directly with <command>config set</command>, to any integer value.
+                    </simpara>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>real</term>
+                <listitem>
+                    <simpara>
+                        A basic floating point number; can be set directly with <command>config set</command>, to any floating point value.
+                    </simpara>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>boolean</term>
+                <listitem>
+                    <simpara>
+                        A basic boolean value; can be set directly with <command>config set</command>, to either <command>true</command> or <command>false</command>.
+                    </simpara>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>string</term>
+                <listitem>
+                    <simpara>
+                        A basic string value; can be set directly with <command>config set,</command> so any string. Double quotation marks are optional.
+                    </simpara>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>null</term>
+                <listitem>
+                    <simpara>
+                        This is a special type representing 'no value at all'; usable in compound structures that have optional elements that are not set.
+                    </simpara>
+                </listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term>maps</term>
+                <listitem>
+                    <simpara>
+                        Maps are (pre-defined) compound collections of other
+                        elements of any other type. They are not usually
+                        modified directly, but their elements are. Every
+                        top-level element for a module is a map containing
+                        the configuration values for that map, which can
+                        themselves be maps again. For instance, the Auth
+                        module configuration is a map containing the
+                        elements '<varname>listen_on</varname>' (list) and '<varname>tcp_recv_timeout</varname>'
+                        (integer). When changing one of its values, they can
+                        be modified directly with <command>config set
+                        Auth/tcp_recv_timeout 3000</command>.
+                    </simpara>
+                    <simpara>
+                        Some map entries are optional. If they are, and
+                        currently have a value, the value can be unset by
+                        using either <command>config unset
+                        <replaceable><item name></replaceable>
+                        </command> or <command>config set
+                        <replaceable><item name></replaceable>
+                        null</command>.
+
+                    </simpara>
+                    <simpara>
+                        Maps <emphasis>can</emphasis> be modified as a whole,
+                        but using the full JSON representation of
+                        the entire map to set.
+
+                        Since this involves a lot of text, this is usually
+                        not recommended.
+                    </simpara>
+                    <simpara>
+                        Another example is the Logging virtual module, which
+                        is, like any module, a map, but it only contains one
+                        element: a list of loggers. Normally, an
+                        administrator would only modify that list (or its
+                        elements) directly, but it is possible to set the
+                        entire map in one command; for example:
+                        <command> config set Logging { "loggers": [] } </command>
+                    </simpara>
+                </listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term>list</term>
+                <listitem>
+                    <simpara>
+                        A list is a compound list of other elements of the
+                        same type. Elements can be added with <command>config
+                        add <replaceable><list name> [value]</replaceable></command>, and removed with
+                        <command>config remove <replaceable><list name> [value]</replaceable></command> or
+                        <command>config remove <replaceable><list name></replaceable><replaceable><index></replaceable></command>.
+                        The index is of the form <emphasis>square bracket, number,
+                        square bracket</emphasis> (e.g.
+                        <command>[0]</command>), and it immediately follows
+                        the list name (there is no separator or space
+                        between them). List indices start with 0 for the
+                        first element.
+                    </simpara>
+                    <simpara>
+                        For addition, if the value is omitted, an entry with
+                        default values will be added. For removal, either
+                        the index or the full value (in JSON format) needs
+                        to be specified.
+                    </simpara>
+                    <simpara>
+                        Lists can also be used with
+                        <command>config set</command>,
+                        but like maps, only by specifying the
+                        entire list value in JSON format.
+                    </simpara>
+                    <simpara>
+                        For example, this command shows the port number used for the second element of the list <varname>listen_on</varname> in the Auth module:
+                        <command> config show Auth/listen_on[1]/port</command>
+                    </simpara>
+                </listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term>named set</term>
+                <listitem>
+                    <simpara>
+                        Named sets are similar to lists, in that they are
+                        sets of elements of the same type, but they are not
+                        indexed by numbers, but by strings.
+                    </simpara>
+                    <simpara>
+                        Values can be added with
+                        <command>config add <replaceable><item name> <string> [value]</replaceable></command>
+                        where 'string' is the name of the element. If 'value'
+                        is ommitted, default values will be used. Elements
+                        can be removed with <command>config remove
+                        <replaceable><item
+                        name> <string></replaceable></command>
+                    </simpara>
+                    <simpara>
+                        Elements in a named set can be addressed similarly
+                        to maps.
+                    </simpara>
+                    <simpara>
+                        For example, the <command>Boss/components</command>
+                        elements is a named set;
+                        adding, showing, and then removing an element
+                        can be done with the following three commands (note
+                        the '/'-character versus the space before
+                        'example_module'):
+                    </simpara>
+                    <simpara>
+                        <command>config add Boss/components example_module</command>
+                    </simpara>
+                    <simpara>
+                        <command>config show Boss/components/example_module</command>
+                    </simpara>
+                    <simpara>
+                        <command>config remove Boss/components example_module</command>
+                    </simpara>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>any</term>
+                <listitem>
+                    <simpara>
+                        The 'any' type is a special type that can have any
+                        form. Apart from that, it must consist of elements as
+                        described in this chapter, there is no restriction
+                        on which element types are used. This type is used
+                        in places where different data formats could be
+                        used. Element modification commands depend on the
+                        actual type of the value. For instance, if the value
+                        of an 'any' element is a list, <command>config add
+                        </command> and <command>config remove</command> work
+                        as for other lists.
+                    </simpara>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+      </section>
+    </section>
+
+    <section>
+        <title>The execute command</title>
+        The <command>execute</command> command executes a set of commands,
+        either from a file
+        or from a pre-defined set. Currently, the only predefined set is
+        <command>init_authoritative_server</command>, which adds
+        <command>b10-auth</command>, <command>b10-xfrin</command>, and
+        <command>b10-xfrout</command> to the set of components to be
+        started by BIND 10. This
+        pre-defined set does not commit the changes, so these modules do not
+        show up for commands or configuration until the user enters
+        <command>config commit</command> after
+        <command>execute init_authoritative_server</command>. For example:
+
+        <screen>> <userinput>execute init_authoritative_server</userinput></screen>
+
+        <screen>> <userinput>execute file /tmp/example_commands</userinput></screen>
+
+        The optional argument <command>show</command> displays the exact set of
+        commands that would be executed; for example:
+
+        <screen>> <userinput>execute init_authoritative_server show</userinput>
+!echo adding Authoritative server component
+config add /Boss/components b10-auth
+config set /Boss/components/b10-auth/kind needed
+config set /Boss/components/b10-auth/special auth
+!echo adding Xfrin component
+config add /Boss/components b10-xfrin
+config set /Boss/components/b10-xfrin/address Xfrin
+config set /Boss/components/b10-xfrin/kind dispensable
+!echo adding Xfrout component
+config add /Boss/components b10-xfrout
+config set /Boss/components/b10-xfrout/address Xfrout
+config set /Boss/components/b10-xfrout/kind dispensable
+!echo adding Zone Manager component
+config add /Boss/components b10-zonemgr
+config set /Boss/components/b10-zonemgr/address Zonemgr
+config set /Boss/components/b10-zonemgr/kind dispensable
+!echo Components added. Please enter "config commit" to
+!echo finalize initial setup and run the components.
+        </screen>
+
+        The optional <command>show</command> argument may also be used when
+        executing a script from a file; for example:
+
+        <screen><userinput>> execute file /tmp/example_commands show</userinput></screen>
+
+        <section id="bindctl_execute_directives">
+            <title>Execute directives</title>
+            Within sets of commands to be run with the <command>execute</command>
+            command, a number of directives are supported:
+            <variablelist>
+              <varlistentry>
+                <term>!echo <replaceable><string></replaceable></term>
+                <listitem>
+                  <simpara>
+                      Prints the given string to <command>bindctl</command>'s
+                      output.
+                  </simpara>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term>!verbose on</term>
+                <listitem>
+                  <simpara>
+                      Enables verbose mode; all following commands that are to
+                      be executed are also printed.
+                  </simpara>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term>!verbose off</term>
+                <listitem>
+                  <simpara>
+                      Disables verbose mode; following commands that are to
+                      be executed are no longer printed.
+                  </simpara>
+                </listitem>
+              </varlistentry>
+            </variablelist>
+        </section>
+
+        <section id="bindctl_execute_notes">
+            <title>Notes on execute scripts</title>
+            Within scripts, you can add or remove modules with the normal
+            configuration commands for <command>Boss/components</command>.
+            However, as module
+            configuration and commands do not show up until the module is
+            running, it is currently not possible to add a module and set
+            its configuration in one script. This will be addressed in the
+            future, but for now the only option is to add and configure
+            modules in separate commands and execute scripts.
+        </section>
+    </section>
   </chapter>
 
   <chapter id="common">
@@ -2990,7 +3566,7 @@ Dhcp6/subnet6	         []     list    (default)</screen>
         enclosed in square brackets, even though only one range of addresses
         is specified.</para>
         <para>It is possible to define more than one pool in a
-        subnet: continuing the previous example, further assume that 
+        subnet: continuing the previous example, further assume that
         2001:db8:1:0:5::/80 should be also be managed by the server. It could be written as
         2001:db8:1:0:5:: to 2001:db8:1::5:ffff:ffff:ffff, but typing so many 'f's
         is cumbersome. It can be expressed more simply as 2001:db8:1:0:5::/80. Both
diff --git a/src/bin/bindctl/moduleinfo.py b/src/bin/bindctl/moduleinfo.py
index 6c3a304..33114d8 100644
--- a/src/bin/bindctl/moduleinfo.py
+++ b/src/bin/bindctl/moduleinfo.py
@@ -221,7 +221,8 @@ class ModuleInfo:
 
     def module_help(self):
         """Prints the help info for this module to stdout"""
-        print("Module ", self, "\nAvailable commands:")
+        print("Module " + str(self))
+        print("Available commands:")
         for k in self.commands.values():
             n = k.get_name()
             if len(n) >= CONST_BINDCTL_HELP_INDENT_WIDTH:



More information about the bind10-changes mailing list