Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
78770f52
Commit
78770f52
authored
Nov 16, 2011
by
Stephen Morris
Browse files
Merge branch 'master' into trac1330
parents
eb53cae4
498677a8
Changes
101
Expand all
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
78770f52
317. [func] vorner
datasrc: the getUpdater method of DataSourceClient supports an optional
'journaling' parameter to indicate the generated updater to store diffs.
The database based derived class implements this extension.
(Trac #1331, git 713160c9bed3d991a00b2ea5e7e3e7714d79625d)
316. [func]* vorner
The configuration of what parts of the system run is more flexible now.
Everything that should run must have an entry in Boss/components.
(Trac #213, git 08e1873a3593b4fa06754654d22d99771aa388a6)
315. [func] tomek
libdhcp: Support for DHCPv4 packet manipulation is now implemented.
All fixed fields are now supported. Generic support for DHCPv4
options is available (both parsing and assembly). There is no code
that uses this new functionality yet, so it is not usable directly
at this time. This code will be used by upcoming b10-dhcp4 daemon.
(Trac #1228, git 31d5a4f66b18cca838ca1182b9f13034066427a7)
314. [bug] jelte
b10-xfrin would previously initiate incoming transfers upon
receiving NOTIFY messages from any address (if the zone was
known to b10-xfrin, and using the configured address). It now
only starts a transfer if the source address from the NOTIFY
packet matches the configured master address and port. This was
really already fixed in release bind10-devel-20111014, but there
were some deferred cleanups to add.
(Trac #1298, git 1177bfe30e17a76bea6b6447e14ae9be9e1ca8c2)
313. [func] jinmei
datasrc: Added C++ API for adding zone differences to database
based data sources. It's intended to be used for the support for
IXFR-in and dynamic update (so they can subsequently be retrieved
for IXFR-out). The addRecordDiff method of the DatabaseAccessor
defines the interface, and a concrete implementation for SQLite3
was provided.
(Trac #1329, git 1aa233fab1d74dc776899df61181806679d14013)
312. [func] jelte
Added an initial framework for doing system tests using the
cucumber-based BDD tool Lettuce. A number of general steps are
included, for instance running bind10 with specific
configurations, sending queries, and inspecting query answers. A
few very basic tests are included as well.
(Trac #1290, git 6b75c128bcdcefd85c18ccb6def59e9acedd4437)
311. [bug] jelte
Fixed a bug in bindctl where tab-completion for names that
contain a hyphen resulted in unexpected behaviour, such as
...
...
@@ -25,7 +71,7 @@
given using the '--with-botan=' flag
(Trac #1194, git dc491833cf75ac1481ba1475795b0f266545013d)
307. [func]
vorner
307. [func]
vorner
When zone transfer in fails with IXFR, it is retried with AXFR
automatically.
(Trac #1279, git cd3588c9020d0310f949bfd053c4d3a4bd84ef88)
...
...
@@ -444,7 +490,7 @@ bind10-devel-20110705 released on July 05, 2011
(Trac #542, git 1aa773d84cd6431aa1483eb34a7f4204949a610f)
243. [func]* feng
Add optional hmac algorithm SHA224/384/
8
12.
Add optional hmac algorithm SHA224/384/
5
12.
(Trac #782, git 77d792c9d7c1a3f95d3e6a8b721ac79002cd7db1)
bind10-devel-20110519 released on May 19, 2011
...
...
configure.ac
View file @
78770f52
...
...
@@ -107,6 +107,12 @@ case "$host" in
SET_ENV_LIBRARY_PATH=yes
ENV_LIBRARY_PATH=DYLD_LIBRARY_PATH
;;
*-freebsd*)
SET_ENV_LIBRARY_PATH=yes
;;
*-netbsd*)
SET_ENV_LIBRARY_PATH=yes
;;
esac
AM_CONDITIONAL(SET_ENV_LIBRARY_PATH, test $SET_ENV_LIBRARY_PATH = yes)
AC_SUBST(SET_ENV_LIBRARY_PATH)
...
...
@@ -991,6 +997,7 @@ AC_OUTPUT([doc/version.ent
src/lib/util/python/mkpywrapper.py
src/lib/util/python/gen_wiredata.py
src/lib/server_common/tests/data_path.h
tests/lettuce/setup_intree_bind10.sh
tests/system/conf.sh
tests/system/run.sh
tests/system/glue/setup.sh
...
...
src/bin/bind10/TODO
View file @
78770f52
- Read msgq configuration from configuration manager (Trac #213)
https://bind10.isc.org/ticket/213
- Provide more administrator options:
- Get process list
- Get information on a process (returns list of times started & stopped,
plus current information such as PID)
- Add a component (not necessary for parking lot, but...)
- Stop a component
- Force-stop a component
- Mechanism to wait for child to start before continuing
- Way to ask a child to die politely
- Start statistics daemon
- Statistics interaction (?)
- Use .spec file to define comands
- Rename "c-channel" stuff to msgq for clarity
- Use logger
- Reply to shutdown message?
- Some sort of group creation so termination signals can be sent to
children of children processes (if any)
...
...
src/bin/bind10/bind10_messages.mes
View file @
78770f52
...
...
@@ -20,18 +20,72 @@ The boss process is starting up and will now check if the message bus
daemon is already running. If so, it will not be able to start, as it
needs a dedicated message bus.
% BIND10_CONFIGURATION_START_AUTH start authoritative server: %1
This message shows whether or not the authoritative server should be
started according to the configuration.
% BIND10_CONFIGURATION_START_RESOLVER start resolver: %1
This message shows whether or not the resolver should be
started according to the configuration.
% BIND10_INVALID_STATISTICS_DATA invalid specification of statistics data specified
An error was encountered when the boss module specified
statistics data which is invalid for the boss specification file.
% BIND10_COMPONENT_FAILED component %1 (pid %2) failed with %3 exit status
The process terminated, but the bind10 boss didn't expect it to, which means
it must have failed.
% BIND10_COMPONENT_RESTART component %1 is about to restart
The named component failed previously and we will try to restart it to provide
as flawless service as possible, but it should be investigated what happened,
as it could happen again.
% BIND10_COMPONENT_START component %1 is starting
The named component is about to be started by the boss process.
% BIND10_COMPONENT_START_EXCEPTION component %1 failed to start: %2
An exception (mentioned in the message) happened during the startup of the
named component. The componet is not considered started and further actions
will be taken about it.
% BIND10_COMPONENT_STOP component %1 is being stopped
A component is about to be asked to stop willingly by the boss.
% BIND10_COMPONENT_UNSATISFIED component %1 is required to run and failed
A component failed for some reason (see previous messages). It is either a core
component or needed component that was just started. In any case, the system
can't continue without it and will terminate.
% BIND10_CONFIGURATOR_BUILD building plan '%1' -> '%2'
A debug message. This indicates that the configurator is building a plan
how to change configuration from the older one to newer one. This does no
real work yet, it just does the planning what needs to be done.
% BIND10_CONFIGURATOR_PLAN_INTERRUPTED configurator plan interrupted, only %1 of %2 done
There was an exception during some planned task. The plan will not continue and
only some tasks of the plan were completed. The rest is aborted. The exception
will be propagated.
% BIND10_CONFIGURATOR_RECONFIGURE reconfiguring running components
A different configuration of which components should be running is being
installed. All components that are no longer needed will be stopped and
newly introduced ones started. This happens at startup, when the configuration
is read the first time, or when an operator changes configuration of the boss.
% BIND10_CONFIGURATOR_RUN running plan of %1 tasks
A debug message. The configurator is about to execute a plan of actions it
computed previously.
% BIND10_CONFIGURATOR_START bind10 component configurator is starting up
The part that cares about starting and stopping the right component from the
boss process is starting up. This happens only once at the startup of the
boss process. It will start the basic set of processes now (the ones boss
needs to read the configuration), the rest will be started after the
configuration is known.
% BIND10_CONFIGURATOR_STOP bind10 component configurator is shutting down
The part that cares about starting and stopping processes in the boss is
shutting down. All started components will be shut down now (more precisely,
asked to terminate by their own, if they fail to comply, other parts of
the boss process will try to force them).
% BIND10_CONFIGURATOR_TASK performing task %1 on %2
A debug message. The configurator is about to perform one task of the plan it
is currently executing on the named component.
% BIND10_INVALID_USER invalid user: %1
The boss process was started with the -u option, to drop root privileges
and continue running as the specified user, but the user is unknown.
...
...
@@ -51,27 +105,15 @@ old process was not shut down correctly, and needs to be killed, or
another instance of BIND10, with the same msgq domain socket, is
running, which needs to be stopped.
% BIND10_MSGQ_DAEMON_ENDED b10-msgq process died, shutting down
The message bus daemon has died. This is a fatal error, since it may
leave the system in an inconsistent state. BIND10 will now shut down.
% BIND10_MSGQ_DISAPPEARED msgq channel disappeared
While listening on the message bus channel for messages, it suddenly
disappeared. The msgq daemon may have died. This might lead to an
inconsistent state of the system, and BIND 10 will now shut down.
% BIND10_PROCESS_ENDED_NO_EXIT_STATUS process %1 (PID %2) died: exit status not available
The given process ended unexpectedly, but no exit status is
available. See BIND10_PROCESS_ENDED_WITH_EXIT_STATUS for a longer
description.
% BIND10_PROCESS_ENDED_WITH_EXIT_STATUS process %1 (PID %2) terminated, exit status = %3
The given process ended unexpectedly with the given exit status.
Depending on which module it was, it may simply be restarted, or it
may be a problem that will cause the boss module to shut down too.
The latter happens if it was the message bus daemon, which, if it has
died suddenly, may leave the system in an inconsistent state. BIND10
will also shut down now if it has been run with --brittle.
% BIND10_PROCESS_ENDED process %2 of %1 ended with status %3
This indicates a process started previously terminated. The process id
and component owning the process are indicated, as well as the exit code.
This doesn't distinguish if the process was supposed to terminate or not.
% BIND10_READING_BOSS_CONFIGURATION reading boss configuration
The boss process is starting up, and will now process the initial
...
...
@@ -107,6 +149,9 @@ The boss module is sending a SIGKILL signal to the given process.
% BIND10_SEND_SIGTERM sending SIGTERM to %1 (PID %2)
The boss module is sending a SIGTERM signal to the given process.
% BIND10_SETUID setting UID to %1
The boss switches the user it runs as to the given UID.
% BIND10_SHUTDOWN stopping the server
The boss process received a command or signal telling it to shut down.
It will send a shutdown command to each process. The processes that do
...
...
@@ -125,11 +170,6 @@ which failed is unknown (not one of 'S' for socket or 'B' for bind).
The boss requested a socket from the creator, but the answer is unknown. This
looks like a programmer error.
% BIND10_SOCKCREATOR_CRASHED the socket creator crashed
The socket creator terminated unexpectedly. It is not possible to restart it
(because the boss already gave up root privileges), so the system is going
to terminate.
% BIND10_SOCKCREATOR_EOF eof while expecting data from socket creator
There should be more data from the socket creator, but it closed the socket.
It probably crashed.
...
...
@@ -208,8 +248,15 @@ During the startup process, a number of messages are exchanged between the
Boss process and the processes it starts. This error is output when a
message received by the Boss process is not recognised.
% BIND10_START_AS_NON_ROOT starting %1 as a user, not root. This might fail.
The given module is being started or restarted without root privileges.
% BIND10_START_AS_NON_ROOT_AUTH starting b10-auth as a user, not root. This might fail.
The authoritative server is being started or restarted without root privileges.
If the module needs these privileges, it may have problems starting.
Note that this issue should be resolved by the pending 'socket-creator'
process; once that has been implemented, modules should not need root
privileges anymore. See tickets #800 and #801 for more information.
% BIND10_START_AS_NON_ROOT_RESOLVER starting b10-resolver as a user, not root. This might fail.
The resolver is being started or restarted without root privileges.
If the module needs these privileges, it may have problems starting.
Note that this issue should be resolved by the pending 'socket-creator'
process; once that has been implemented, modules should not need root
...
...
src/bin/bind10/bind10_src.py.in
View file @
78770f52
This diff is collapsed.
Click to expand it.
src/bin/bind10/bob.spec
View file @
78770f52
...
...
@@ -4,16 +4,71 @@
"module_description": "Master process",
"config_data": [
{
"item_name": "
start_auth
",
"item_type": "
boolean
",
"item_name": "
components
",
"item_type": "
named_set
",
"item_optional": false,
"item_default": true
},
{
"item_name": "start_resolver",
"item_type": "boolean",
"item_optional": false,
"item_default": false
"item_default": {
"b10-auth": { "special": "auth", "kind": "needed", "priority": 10 },
"setuid": {
"special": "setuid",
"priority": 5,
"kind": "dispensable"
},
"b10-xfrin": { "special": "xfrin", "kind": "dispensable" },
"b10-xfrout": { "special": "xfrout", "kind": "dispensable" },
"b10-zonemgr": { "address": "Zonemgr", "kind": "dispensable" },
"b10-stats": { "address": "Stats", "kind": "dispensable" },
"b10-stats-httpd": {
"address": "StatsHttpd",
"kind": "dispensable"
},
"b10-cmdctl": { "special": "cmdctl", "kind": "needed" }
},
"named_set_item_spec": {
"item_name": "component",
"item_type": "map",
"item_optional": false,
"item_default": { },
"map_item_spec": [
{
"item_name": "special",
"item_optional": true,
"item_type": "string"
},
{
"item_name": "process",
"item_optional": true,
"item_type": "string"
},
{
"item_name": "kind",
"item_optional": false,
"item_type": "string",
"item_default": "dispensable"
},
{
"item_name": "address",
"item_optional": true,
"item_type": "string"
},
{
"item_name": "params",
"item_optional": true,
"item_type": "list",
"list_item_spec": {
"item_name": "param",
"item_optional": false,
"item_type": "string",
"item_default": ""
}
},
{
"item_name": "priority",
"item_optional": true,
"item_type": "integer"
}
]
}
}
],
"commands": [
...
...
src/bin/bind10/run_bind10.sh.in
View file @
78770f52
...
...
@@ -45,6 +45,5 @@ export B10_FROM_BUILD
BIND10_MSGQ_SOCKET_FILE
=
@abs_top_builddir@/msgq_socket
export
BIND10_MSGQ_SOCKET_FILE
cd
${
BIND10_PATH
}
exec
${
PYTHON_EXEC
}
-O
bind10
"
$@
"
exec
${
PYTHON_EXEC
}
-O
${
BIND10_PATH
}
/bind10
"
$@
"
src/bin/bind10/tests/bind10_test.py.in
View file @
78770f52
This diff is collapsed.
Click to expand it.
src/bin/bindctl/bindcmd.py
View file @
78770f52
...
...
@@ -71,21 +71,21 @@ Type \"<module_name> <command_name> help\" for help on the specific command.
\n
Available module names: """
class
ValidatedHTTPSConnection
(
http
.
client
.
HTTPSConnection
):
'''Overrides HTTPSConnection to support certification
'''Overrides HTTPSConnection to support certification
validation. '''
def
__init__
(
self
,
host
,
ca_certs
):
http
.
client
.
HTTPSConnection
.
__init__
(
self
,
host
)
self
.
ca_certs
=
ca_certs
def
connect
(
self
):
''' Overrides the connect() so that we do
''' Overrides the connect() so that we do
certificate validation. '''
sock
=
socket
.
create_connection
((
self
.
host
,
self
.
port
),
self
.
timeout
)
if
self
.
_tunnel_host
:
self
.
sock
=
sock
self
.
_tunnel
()
req_cert
=
ssl
.
CERT_NONE
if
self
.
ca_certs
:
req_cert
=
ssl
.
CERT_REQUIRED
...
...
@@ -95,7 +95,7 @@ class ValidatedHTTPSConnection(http.client.HTTPSConnection):
ca_certs
=
self
.
ca_certs
)
class
BindCmdInterpreter
(
Cmd
):
"""simple bindctl example."""
"""simple bindctl example."""
def
__init__
(
self
,
server_port
=
'localhost:8080'
,
pem_file
=
None
,
csv_file_dir
=
None
):
...
...
@@ -128,29 +128,33 @@ class BindCmdInterpreter(Cmd):
socket
.
gethostname
())).
encode
())
digest
=
session_id
.
hexdigest
()
return
digest
def
run
(
self
):
'''Parse commands from user and send them to cmdctl. '''
try
:
if
not
self
.
login_to_cmdctl
():
return
return
1
self
.
cmdloop
()
print
(
'
\n
Exit from bindctl'
)
return
0
except
FailToLogin
as
err
:
# error already printed when this was raised, ignoring
pass
return
1
except
KeyboardInterrupt
:
print
(
'
\n
Exit from bindctl'
)
return
0
except
socket
.
error
as
err
:
print
(
'Failed to send request, the connection is closed'
)
return
1
except
http
.
client
.
CannotSendRequest
:
print
(
'Can not send request, the connection is busy'
)
return
1
def
_get_saved_user_info
(
self
,
dir
,
file_name
):
''' Read all the available username and password pairs saved in
''' Read all the available username and password pairs saved in
file(path is "dir + file_name"), Return value is one list of elements
['name', 'password'], If get information failed, empty list will be
['name', 'password'], If get information failed, empty list will be
returned.'''
if
(
not
dir
)
or
(
not
os
.
path
.
exists
(
dir
)):
return
[]
...
...
@@ -176,7 +180,7 @@ class BindCmdInterpreter(Cmd):
if
not
os
.
path
.
exists
(
dir
):
os
.
mkdir
(
dir
,
0o700
)
csvfilepath
=
dir
+
file_name
csvfilepath
=
dir
+
file_name
csvfile
=
open
(
csvfilepath
,
'w'
)
os
.
chmod
(
csvfilepath
,
0o600
)
writer
=
csv
.
writer
(
csvfile
)
...
...
@@ -190,7 +194,7 @@ class BindCmdInterpreter(Cmd):
return
True
def
login_to_cmdctl
(
self
):
'''Login to cmdctl with the username and password inputted
'''Login to cmdctl with the username and password inputted
from user. After the login is sucessful, the username and
password will be saved in 'default_user.csv', when run the next
time, username and password saved in 'default_user.csv' will be
...
...
@@ -256,14 +260,14 @@ class BindCmdInterpreter(Cmd):
if
self
.
login_to_cmdctl
():
# successful, so try send again
status
,
reply_msg
=
self
.
_send_message
(
url
,
body
)
if
reply_msg
:
return
json
.
loads
(
reply_msg
.
decode
())
else
:
return
{}
def
send_POST
(
self
,
url
,
post_param
=
None
):
def
send_POST
(
self
,
url
,
post_param
=
None
):
'''Send POST request to cmdctl, session id is send with the name
'cookie' in header.
Format: /module_name/command_name
...
...
@@ -322,12 +326,12 @@ class BindCmdInterpreter(Cmd):
def
_validate_cmd
(
self
,
cmd
):
'''validate the parameters and merge some parameters together,
merge algorithm is based on the command line syntax, later, if
a better command line syntax come out, this function should be
updated first.
a better command line syntax come out, this function should be
updated first.
'''
if
not
cmd
.
module
in
self
.
modules
:
raise
CmdUnknownModuleSyntaxError
(
cmd
.
module
)
module_info
=
self
.
modules
[
cmd
.
module
]
if
not
module_info
.
has_command_with_name
(
cmd
.
command
):
raise
CmdUnknownCmdSyntaxError
(
cmd
.
module
,
cmd
.
command
)
...
...
@@ -335,17 +339,17 @@ class BindCmdInterpreter(Cmd):
command_info
=
module_info
.
get_command_with_name
(
cmd
.
command
)
manda_params
=
command_info
.
get_mandatory_param_names
()
all_params
=
command_info
.
get_param_names
()
# If help is entered, don't do further parameter validation.
for
val
in
cmd
.
params
.
keys
():
if
val
==
"help"
:
return
params
=
cmd
.
params
.
copy
()
if
not
params
and
manda_params
:
raise
CmdMissParamSyntaxError
(
cmd
.
module
,
cmd
.
command
,
manda_params
[
0
])
params
=
cmd
.
params
.
copy
()
if
not
params
and
manda_params
:
raise
CmdMissParamSyntaxError
(
cmd
.
module
,
cmd
.
command
,
manda_params
[
0
])
elif
params
and
not
all_params
:
raise
CmdUnknownParamSyntaxError
(
cmd
.
module
,
cmd
.
command
,
raise
CmdUnknownParamSyntaxError
(
cmd
.
module
,
cmd
.
command
,
list
(
params
.
keys
())[
0
])
elif
params
:
param_name
=
None
...
...
@@ -376,7 +380,7 @@ class BindCmdInterpreter(Cmd):
param_name
=
command_info
.
get_param_name_by_position
(
name
,
param_count
)
cmd
.
params
[
param_name
]
=
cmd
.
params
[
name
]
del
cmd
.
params
[
name
]
elif
not
name
in
all_params
:
raise
CmdUnknownParamSyntaxError
(
cmd
.
module
,
cmd
.
command
,
name
)
...
...
@@ -385,7 +389,7 @@ class BindCmdInterpreter(Cmd):
if
not
name
in
params
and
not
param_nr
in
params
:
raise
CmdMissParamSyntaxError
(
cmd
.
module
,
cmd
.
command
,
name
)
param_nr
+=
1
# Convert parameter value according parameter spec file.
# Ignore check for commands belongs to module 'config'
if
cmd
.
module
!=
CONFIG_MODULE_NAME
:
...
...
@@ -394,9 +398,9 @@ class BindCmdInterpreter(Cmd):
try
:
cmd
.
params
[
param_name
]
=
isc
.
config
.
config_data
.
convert_type
(
param_spec
,
cmd
.
params
[
param_name
])
except
isc
.
cc
.
data
.
DataTypeError
as
e
:
raise
isc
.
cc
.
data
.
DataTypeError
(
'Invalid parameter value for
\"
%s
\"
, the type should be
\"
%s
\"
\n
'
raise
isc
.
cc
.
data
.
DataTypeError
(
'Invalid parameter value for
\"
%s
\"
, the type should be
\"
%s
\"
\n
'
%
(
param_name
,
param_spec
[
'item_type'
])
+
str
(
e
))
def
_handle_cmd
(
self
,
cmd
):
'''Handle a command entered by the user'''
if
cmd
.
command
==
"help"
or
(
"help"
in
cmd
.
params
.
keys
()):
...
...
@@ -418,7 +422,7 @@ class BindCmdInterpreter(Cmd):
def
add_module_info
(
self
,
module_info
):
'''Add the information about one module'''
self
.
modules
[
module_info
.
name
]
=
module_info
def
get_module_names
(
self
):
'''Return the names of all known modules'''
return
list
(
self
.
modules
.
keys
())
...
...
@@ -450,15 +454,15 @@ class BindCmdInterpreter(Cmd):
subsequent_indent
=
" "
+
" "
*
CONST_BINDCTL_HELP_INDENT_WIDTH
,
width
=
70
))
def
onecmd
(
self
,
line
):
if
line
==
'EOF'
or
line
.
lower
()
==
"quit"
:
self
.
conn
.
close
()
return
True
if
line
==
'h'
:
line
=
'help'
Cmd
.
onecmd
(
self
,
line
)
def
remove_prefix
(
self
,
list
,
prefix
):
...
...
@@ -486,7 +490,7 @@ class BindCmdInterpreter(Cmd):
cmd
=
BindCmdParse
(
cur_line
)
if
not
cmd
.
params
and
text
:
hints
=
self
.
_get_command_startswith
(
cmd
.
module
,
text
)
else
:
else
:
hints
=
self
.
_get_param_startswith
(
cmd
.
module
,
cmd
.
command
,
text
)
if
cmd
.
module
==
CONFIG_MODULE_NAME
:
...
...
@@ -502,8 +506,8 @@ class BindCmdInterpreter(Cmd):
except
CmdMissCommandNameFormatError
as
e
:
if
not
text
.
strip
():
# command name is empty
hints
=
self
.
modules
[
e
.
module
].
get_command_names
()
else
:
hints
=
self
.
modules
[
e
.
module
].
get_command_names
()
else
:
hints
=
self
.
_get_module_startswith
(
text
)
except
CmdCommandNameFormatError
as
e
:
...
...
@@ -523,36 +527,37 @@ class BindCmdInterpreter(Cmd):
else
:
return
None
def
_get_module_startswith
(
self
,
text
):
def
_get_module_startswith
(
self
,
text
):
return
[
module
for
module
in
self
.
modules
for
module
in
self
.
modules
if
module
.
startswith
(
text
)]
def
_get_command_startswith
(
self
,
module
,
text
):
if
module
in
self
.
modules
:
if
module
in
self
.
modules
:
return
[
command
for
command
in
self
.
modules
[
module
].
get_command_names
()
for
command
in
self
.
modules
[
module
].
get_command_names
()
if
command
.
startswith
(
text
)]
return
[]
def
_get_param_startswith
(
self
,
module
,
command
,
text
):
return
[]
def
_get_param_startswith
(
self
,
module
,
command
,
text
):
if
module
in
self
.
modules
:
module_info
=
self
.
modules
[
module
]
if
command
in
module_info
.
get_command_names
():
module_info
=
self
.
modules
[
module
]
if
command
in
module_info
.
get_command_names
():
cmd_info
=
module_info
.
get_command_with_name
(
command
)
params
=
cmd_info
.
get_param_names
()
params
=
cmd_info
.
get_param_names
()
hint
=
[]
if
text
:
if
text
:
hint
=
[
val
for
val
in
params
if
val
.
startswith
(
text
)]
else
:
hint
=
list
(
params
)
if
len
(
hint
)
==
1
and
hint
[
0
]
!=
"help"
:
hint
[
0
]
=
hint
[
0
]
+
" ="
hint
[
0
]
=
hint
[
0
]
+
" ="
return
hint
return
[]
...
...
@@ -569,24 +574,24 @@ class BindCmdInterpreter(Cmd):
self
.
_print_correct_usage
(
err
)
except
isc
.
cc
.
data
.
DataTypeError
as
err
:
print
(
"Error! "
,
err
)
def
_print_correct_usage
(
self
,
ept
):
def
_print_correct_usage
(
self
,
ept
):