Statistics
| Branch: | Tag: | Revision:

root / autotools / build-bash-completion @ e7b61bb0

History | View | Annotate | Download (17.8 kB)

1 4f3d5b76 Michael Hanselmann
#!/usr/bin/python
2 4f3d5b76 Michael Hanselmann
#
3 4f3d5b76 Michael Hanselmann
4 4f3d5b76 Michael Hanselmann
# Copyright (C) 2009 Google Inc.
5 4f3d5b76 Michael Hanselmann
#
6 4f3d5b76 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 4f3d5b76 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 4f3d5b76 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 4f3d5b76 Michael Hanselmann
# (at your option) any later version.
10 4f3d5b76 Michael Hanselmann
#
11 4f3d5b76 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 4f3d5b76 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 4f3d5b76 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 4f3d5b76 Michael Hanselmann
# General Public License for more details.
15 4f3d5b76 Michael Hanselmann
#
16 4f3d5b76 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 4f3d5b76 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 4f3d5b76 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 4f3d5b76 Michael Hanselmann
# 02110-1301, USA.
20 4f3d5b76 Michael Hanselmann
21 4f3d5b76 Michael Hanselmann
22 b4086ce8 Michael Hanselmann
"""Script to generate bash_completion script for Ganeti.
23 b4086ce8 Michael Hanselmann
24 b4086ce8 Michael Hanselmann
"""
25 b4086ce8 Michael Hanselmann
26 b4086ce8 Michael Hanselmann
# pylint: disable-msg=C0103
27 b4086ce8 Michael Hanselmann
# [C0103] Invalid name build-bash-completion
28 b4086ce8 Michael Hanselmann
29 4f3d5b76 Michael Hanselmann
import os
30 4f3d5b76 Michael Hanselmann
import re
31 4f3d5b76 Michael Hanselmann
from cStringIO import StringIO
32 4f3d5b76 Michael Hanselmann
33 4f3d5b76 Michael Hanselmann
from ganeti import constants
34 4f3d5b76 Michael Hanselmann
from ganeti import cli
35 4f3d5b76 Michael Hanselmann
from ganeti import utils
36 e948770c Michael Hanselmann
from ganeti import build
37 4f3d5b76 Michael Hanselmann
38 4f3d5b76 Michael Hanselmann
# _autoconf shouldn't be imported from anywhere except constants.py, but we're
39 4f3d5b76 Michael Hanselmann
# making an exception here because this script is only used at build time.
40 4f3d5b76 Michael Hanselmann
from ganeti import _autoconf
41 4f3d5b76 Michael Hanselmann
42 4f3d5b76 Michael Hanselmann
43 4f3d5b76 Michael Hanselmann
class ShellWriter:
44 4f3d5b76 Michael Hanselmann
  """Helper class to write scripts with indentation.
45 4f3d5b76 Michael Hanselmann
46 4f3d5b76 Michael Hanselmann
  """
47 4f3d5b76 Michael Hanselmann
  INDENT_STR = "  "
48 4f3d5b76 Michael Hanselmann
49 4f3d5b76 Michael Hanselmann
  def __init__(self, fh):
50 4f3d5b76 Michael Hanselmann
    self._fh = fh
51 4f3d5b76 Michael Hanselmann
    self._indent = 0
52 4f3d5b76 Michael Hanselmann
53 4f3d5b76 Michael Hanselmann
  def IncIndent(self):
54 4f3d5b76 Michael Hanselmann
    """Increase indentation level by 1.
55 4f3d5b76 Michael Hanselmann
56 4f3d5b76 Michael Hanselmann
    """
57 4f3d5b76 Michael Hanselmann
    self._indent += 1
58 4f3d5b76 Michael Hanselmann
59 4f3d5b76 Michael Hanselmann
  def DecIndent(self):
60 4f3d5b76 Michael Hanselmann
    """Decrease indentation level by 1.
61 4f3d5b76 Michael Hanselmann
62 4f3d5b76 Michael Hanselmann
    """
63 4f3d5b76 Michael Hanselmann
    assert self._indent > 0
64 4f3d5b76 Michael Hanselmann
    self._indent -= 1
65 4f3d5b76 Michael Hanselmann
66 4f3d5b76 Michael Hanselmann
  def Write(self, txt, *args):
67 4f3d5b76 Michael Hanselmann
    """Write line to output file.
68 4f3d5b76 Michael Hanselmann
69 4f3d5b76 Michael Hanselmann
    """
70 4f3d5b76 Michael Hanselmann
    self._fh.write(self._indent * self.INDENT_STR)
71 4f3d5b76 Michael Hanselmann
72 4f3d5b76 Michael Hanselmann
    if args:
73 4f3d5b76 Michael Hanselmann
      self._fh.write(txt % args)
74 4f3d5b76 Michael Hanselmann
    else:
75 4f3d5b76 Michael Hanselmann
      self._fh.write(txt)
76 4f3d5b76 Michael Hanselmann
77 4f3d5b76 Michael Hanselmann
    self._fh.write("\n")
78 4f3d5b76 Michael Hanselmann
79 4f3d5b76 Michael Hanselmann
80 4f3d5b76 Michael Hanselmann
def WritePreamble(sw):
81 4f3d5b76 Michael Hanselmann
  """Writes the script preamble.
82 4f3d5b76 Michael Hanselmann
83 4f3d5b76 Michael Hanselmann
  Helper functions should be written here.
84 4f3d5b76 Michael Hanselmann
85 4f3d5b76 Michael Hanselmann
  """
86 4f3d5b76 Michael Hanselmann
  sw.Write("# This script is automatically generated at build time.")
87 4f3d5b76 Michael Hanselmann
  sw.Write("# Do not modify manually.")
88 4f3d5b76 Michael Hanselmann
89 5b0ca9d4 Michael Hanselmann
  sw.Write("_ganeti_dbglog() {")
90 5b0ca9d4 Michael Hanselmann
  sw.IncIndent()
91 5b0ca9d4 Michael Hanselmann
  try:
92 5b0ca9d4 Michael Hanselmann
    sw.Write("if [[ -n \"$GANETI_COMPL_LOG\" ]]; then")
93 5b0ca9d4 Michael Hanselmann
    sw.IncIndent()
94 5b0ca9d4 Michael Hanselmann
    try:
95 5b0ca9d4 Michael Hanselmann
      sw.Write("{")
96 5b0ca9d4 Michael Hanselmann
      sw.IncIndent()
97 5b0ca9d4 Michael Hanselmann
      try:
98 5b0ca9d4 Michael Hanselmann
        sw.Write("echo ---")
99 5b0ca9d4 Michael Hanselmann
        sw.Write("echo \"$@\"")
100 5b0ca9d4 Michael Hanselmann
        sw.Write("echo")
101 5b0ca9d4 Michael Hanselmann
      finally:
102 5b0ca9d4 Michael Hanselmann
        sw.DecIndent()
103 5b0ca9d4 Michael Hanselmann
      sw.Write("} >> $GANETI_COMPL_LOG")
104 5b0ca9d4 Michael Hanselmann
    finally:
105 5b0ca9d4 Michael Hanselmann
      sw.DecIndent()
106 5b0ca9d4 Michael Hanselmann
    sw.Write("fi")
107 5b0ca9d4 Michael Hanselmann
  finally:
108 5b0ca9d4 Michael Hanselmann
    sw.DecIndent()
109 5b0ca9d4 Michael Hanselmann
  sw.Write("}")
110 5b0ca9d4 Michael Hanselmann
111 4f3d5b76 Michael Hanselmann
  sw.Write("_ganeti_nodes() {")
112 4f3d5b76 Michael Hanselmann
  sw.IncIndent()
113 4f3d5b76 Michael Hanselmann
  try:
114 4f3d5b76 Michael Hanselmann
    node_list_path = os.path.join(constants.DATA_DIR, "ssconf_node_list")
115 5a78e2e7 Michael Hanselmann
    sw.Write("cat %s 2>/dev/null || :", utils.ShellQuote(node_list_path))
116 4f3d5b76 Michael Hanselmann
  finally:
117 4f3d5b76 Michael Hanselmann
    sw.DecIndent()
118 4f3d5b76 Michael Hanselmann
  sw.Write("}")
119 4f3d5b76 Michael Hanselmann
120 4f3d5b76 Michael Hanselmann
  sw.Write("_ganeti_instances() {")
121 4f3d5b76 Michael Hanselmann
  sw.IncIndent()
122 4f3d5b76 Michael Hanselmann
  try:
123 4f3d5b76 Michael Hanselmann
    instance_list_path = os.path.join(constants.DATA_DIR,
124 4f3d5b76 Michael Hanselmann
                                      "ssconf_instance_list")
125 5a78e2e7 Michael Hanselmann
    sw.Write("cat %s 2>/dev/null || :", utils.ShellQuote(instance_list_path))
126 4f3d5b76 Michael Hanselmann
  finally:
127 4f3d5b76 Michael Hanselmann
    sw.DecIndent()
128 4f3d5b76 Michael Hanselmann
  sw.Write("}")
129 4f3d5b76 Michael Hanselmann
130 4f3d5b76 Michael Hanselmann
  sw.Write("_ganeti_jobs() {")
131 4f3d5b76 Michael Hanselmann
  sw.IncIndent()
132 4f3d5b76 Michael Hanselmann
  try:
133 4f3d5b76 Michael Hanselmann
    # FIXME: this is really going into the internals of the job queue
134 5a78e2e7 Michael Hanselmann
    sw.Write(("local jlist=$( shopt -s nullglob &&"
135 5a78e2e7 Michael Hanselmann
              " cd %s 2>/dev/null && echo job-* || : )"),
136 4f3d5b76 Michael Hanselmann
             utils.ShellQuote(constants.QUEUE_DIR))
137 5a78e2e7 Michael Hanselmann
    sw.Write('echo "${jlist//job-/}"')
138 4f3d5b76 Michael Hanselmann
  finally:
139 4f3d5b76 Michael Hanselmann
    sw.DecIndent()
140 4f3d5b76 Michael Hanselmann
  sw.Write("}")
141 4f3d5b76 Michael Hanselmann
142 30d44392 Michael Hanselmann
  for (fnname, paths) in [
143 30d44392 Michael Hanselmann
      ("os", constants.OS_SEARCH_PATH),
144 30d44392 Michael Hanselmann
      ("iallocator", constants.IALLOCATOR_SEARCH_PATH),
145 30d44392 Michael Hanselmann
      ]:
146 30d44392 Michael Hanselmann
    sw.Write("_ganeti_%s() {", fnname)
147 30d44392 Michael Hanselmann
    sw.IncIndent()
148 30d44392 Michael Hanselmann
    try:
149 30d44392 Michael Hanselmann
      # FIXME: Make querying the master for all OSes cheap
150 30d44392 Michael Hanselmann
      for path in paths:
151 30d44392 Michael Hanselmann
        sw.Write("( shopt -s nullglob && cd %s 2>/dev/null && echo * || : )",
152 30d44392 Michael Hanselmann
                 utils.ShellQuote(path))
153 30d44392 Michael Hanselmann
    finally:
154 30d44392 Michael Hanselmann
      sw.DecIndent()
155 30d44392 Michael Hanselmann
    sw.Write("}")
156 4f3d5b76 Michael Hanselmann
157 4f3d5b76 Michael Hanselmann
  # Params: <offset> <options with values> <options without values>
158 4f3d5b76 Michael Hanselmann
  # Result variable: $first_arg_idx
159 4f3d5b76 Michael Hanselmann
  sw.Write("_ganeti_find_first_arg() {")
160 4f3d5b76 Michael Hanselmann
  sw.IncIndent()
161 4f3d5b76 Michael Hanselmann
  try:
162 4f3d5b76 Michael Hanselmann
    sw.Write("local w i")
163 4f3d5b76 Michael Hanselmann
164 4f3d5b76 Michael Hanselmann
    sw.Write("first_arg_idx=")
165 4f3d5b76 Michael Hanselmann
    sw.Write("for (( i=$1; i < COMP_CWORD; ++i )); do")
166 4f3d5b76 Michael Hanselmann
    sw.IncIndent()
167 4f3d5b76 Michael Hanselmann
    try:
168 4f3d5b76 Michael Hanselmann
      sw.Write("w=${COMP_WORDS[$i]}")
169 4f3d5b76 Michael Hanselmann
170 4f3d5b76 Michael Hanselmann
      # Skip option value
171 4f3d5b76 Michael Hanselmann
      sw.Write("""if [[ -n "$2" && "$w" == @($2) ]]; then let ++i""")
172 4f3d5b76 Michael Hanselmann
173 4f3d5b76 Michael Hanselmann
      # Skip
174 4f3d5b76 Michael Hanselmann
      sw.Write("""elif [[ -n "$3" && "$w" == @($3) ]]; then :""")
175 4f3d5b76 Michael Hanselmann
176 4f3d5b76 Michael Hanselmann
      # Ah, we found the first argument
177 4f3d5b76 Michael Hanselmann
      sw.Write("else first_arg_idx=$i; break;")
178 4f3d5b76 Michael Hanselmann
      sw.Write("fi")
179 4f3d5b76 Michael Hanselmann
    finally:
180 4f3d5b76 Michael Hanselmann
      sw.DecIndent()
181 4f3d5b76 Michael Hanselmann
    sw.Write("done")
182 4f3d5b76 Michael Hanselmann
  finally:
183 4f3d5b76 Michael Hanselmann
    sw.DecIndent()
184 4f3d5b76 Michael Hanselmann
  sw.Write("}")
185 4f3d5b76 Michael Hanselmann
186 4f3d5b76 Michael Hanselmann
  # Params: <list of options separated by space>
187 4f3d5b76 Michael Hanselmann
  # Input variable: $first_arg_idx
188 4f3d5b76 Michael Hanselmann
  # Result variables: $arg_idx, $choices
189 4f3d5b76 Michael Hanselmann
  sw.Write("_ganeti_list_options() {")
190 4f3d5b76 Michael Hanselmann
  sw.IncIndent()
191 4f3d5b76 Michael Hanselmann
  try:
192 4f3d5b76 Michael Hanselmann
    sw.Write("""if [[ -z "$first_arg_idx" ]]; then""")
193 4f3d5b76 Michael Hanselmann
    sw.IncIndent()
194 4f3d5b76 Michael Hanselmann
    try:
195 4f3d5b76 Michael Hanselmann
      sw.Write("arg_idx=0")
196 4f3d5b76 Michael Hanselmann
      # Show options only if the current word starts with a dash
197 4f3d5b76 Michael Hanselmann
      sw.Write("""if [[ "$cur" == -* ]]; then""")
198 4f3d5b76 Michael Hanselmann
      sw.IncIndent()
199 4f3d5b76 Michael Hanselmann
      try:
200 4f3d5b76 Michael Hanselmann
        sw.Write("choices=$1")
201 4f3d5b76 Michael Hanselmann
      finally:
202 4f3d5b76 Michael Hanselmann
        sw.DecIndent()
203 4f3d5b76 Michael Hanselmann
      sw.Write("fi")
204 4f3d5b76 Michael Hanselmann
      sw.Write("return")
205 4f3d5b76 Michael Hanselmann
    finally:
206 4f3d5b76 Michael Hanselmann
      sw.DecIndent()
207 4f3d5b76 Michael Hanselmann
    sw.Write("fi")
208 4f3d5b76 Michael Hanselmann
209 4f3d5b76 Michael Hanselmann
    # Calculate position of current argument
210 4f3d5b76 Michael Hanselmann
    sw.Write("arg_idx=$(( COMP_CWORD - first_arg_idx ))")
211 4f3d5b76 Michael Hanselmann
    sw.Write("choices=")
212 4f3d5b76 Michael Hanselmann
  finally:
213 4f3d5b76 Michael Hanselmann
    sw.DecIndent()
214 4f3d5b76 Michael Hanselmann
  sw.Write("}")
215 4f3d5b76 Michael Hanselmann
216 d4b94fe8 Michael Hanselmann
  # Params: <long options with equal sign> <all options>
217 d4b94fe8 Michael Hanselmann
  # Result variable: $optcur
218 d4b94fe8 Michael Hanselmann
  sw.Write("_ganeti_checkopt() {")
219 d4b94fe8 Michael Hanselmann
  sw.IncIndent()
220 d4b94fe8 Michael Hanselmann
  try:
221 d4b94fe8 Michael Hanselmann
    sw.Write("""if [[ -n "$1" && "$cur" == @($1) ]]; then""")
222 d4b94fe8 Michael Hanselmann
    sw.IncIndent()
223 d4b94fe8 Michael Hanselmann
    try:
224 d4b94fe8 Michael Hanselmann
      sw.Write("optcur=\"${cur#--*=}\"")
225 d4b94fe8 Michael Hanselmann
      sw.Write("return 0")
226 d4b94fe8 Michael Hanselmann
    finally:
227 d4b94fe8 Michael Hanselmann
      sw.DecIndent()
228 d4b94fe8 Michael Hanselmann
    sw.Write("""elif [[ -n "$2" && "$prev" == @($2) ]]; then""")
229 d4b94fe8 Michael Hanselmann
    sw.IncIndent()
230 d4b94fe8 Michael Hanselmann
    try:
231 d4b94fe8 Michael Hanselmann
      sw.Write("optcur=\"$cur\"")
232 d4b94fe8 Michael Hanselmann
      sw.Write("return 0")
233 d4b94fe8 Michael Hanselmann
    finally:
234 d4b94fe8 Michael Hanselmann
      sw.DecIndent()
235 d4b94fe8 Michael Hanselmann
    sw.Write("fi")
236 d4b94fe8 Michael Hanselmann
237 5b0ca9d4 Michael Hanselmann
    sw.Write("_ganeti_dbglog optcur=\"'$optcur'\"")
238 5b0ca9d4 Michael Hanselmann
239 d4b94fe8 Michael Hanselmann
    sw.Write("return 1")
240 d4b94fe8 Michael Hanselmann
  finally:
241 d4b94fe8 Michael Hanselmann
    sw.DecIndent()
242 d4b94fe8 Michael Hanselmann
  sw.Write("}")
243 d4b94fe8 Michael Hanselmann
244 a10caf87 Michael Hanselmann
  # Params: <compgen options>
245 a10caf87 Michael Hanselmann
  # Result variable: $COMPREPLY
246 a10caf87 Michael Hanselmann
  sw.Write("_ganeti_compgen() {")
247 a10caf87 Michael Hanselmann
  sw.IncIndent()
248 a10caf87 Michael Hanselmann
  try:
249 a10caf87 Michael Hanselmann
    sw.Write("""COMPREPLY=( $(compgen "$@") )""")
250 a10caf87 Michael Hanselmann
    sw.Write("_ganeti_dbglog COMPREPLY=\"${COMPREPLY[@]}\"")
251 a10caf87 Michael Hanselmann
  finally:
252 a10caf87 Michael Hanselmann
    sw.DecIndent()
253 a10caf87 Michael Hanselmann
  sw.Write("}")
254 a10caf87 Michael Hanselmann
255 4f3d5b76 Michael Hanselmann
256 632d5090 Michael Hanselmann
def WriteCompReply(sw, args, cur="\"$cur\""):
257 a10caf87 Michael Hanselmann
  sw.Write("_ganeti_compgen %s -- %s", args, cur)
258 4f3d5b76 Michael Hanselmann
  sw.Write("return")
259 4f3d5b76 Michael Hanselmann
260 4f3d5b76 Michael Hanselmann
261 4f3d5b76 Michael Hanselmann
class CompletionWriter:
262 4f3d5b76 Michael Hanselmann
  """Command completion writer class.
263 4f3d5b76 Michael Hanselmann
264 4f3d5b76 Michael Hanselmann
  """
265 4f3d5b76 Michael Hanselmann
  def __init__(self, arg_offset, opts, args):
266 4f3d5b76 Michael Hanselmann
    self.arg_offset = arg_offset
267 4f3d5b76 Michael Hanselmann
    self.opts = opts
268 4f3d5b76 Michael Hanselmann
    self.args = args
269 4f3d5b76 Michael Hanselmann
270 4f3d5b76 Michael Hanselmann
    for opt in opts:
271 f59418db Michael Hanselmann
      # While documented, these variables aren't seen as public attributes by
272 f59418db Michael Hanselmann
      # pylint. pylint: disable-msg=W0212
273 4f3d5b76 Michael Hanselmann
      opt.all_names = sorted(opt._short_opts + opt._long_opts)
274 4f3d5b76 Michael Hanselmann
275 4f3d5b76 Michael Hanselmann
  def _FindFirstArgument(self, sw):
276 4f3d5b76 Michael Hanselmann
    ignore = []
277 4f3d5b76 Michael Hanselmann
    skip_one = []
278 4f3d5b76 Michael Hanselmann
279 4f3d5b76 Michael Hanselmann
    for opt in self.opts:
280 4f3d5b76 Michael Hanselmann
      if opt.takes_value():
281 4f3d5b76 Michael Hanselmann
        # Ignore value
282 4f3d5b76 Michael Hanselmann
        for i in opt.all_names:
283 580ef58d Michael Hanselmann
          if i.startswith("--"):
284 580ef58d Michael Hanselmann
            ignore.append("%s=*" % utils.ShellQuote(i))
285 4f3d5b76 Michael Hanselmann
          skip_one.append(utils.ShellQuote(i))
286 4f3d5b76 Michael Hanselmann
      else:
287 4f3d5b76 Michael Hanselmann
        ignore.extend([utils.ShellQuote(i) for i in opt.all_names])
288 4f3d5b76 Michael Hanselmann
289 4f3d5b76 Michael Hanselmann
    ignore = sorted(utils.UniqueSequence(ignore))
290 4f3d5b76 Michael Hanselmann
    skip_one = sorted(utils.UniqueSequence(skip_one))
291 4f3d5b76 Michael Hanselmann
292 4f3d5b76 Michael Hanselmann
    if ignore or skip_one:
293 4f3d5b76 Michael Hanselmann
      # Try to locate first argument
294 4f3d5b76 Michael Hanselmann
      sw.Write("_ganeti_find_first_arg %s %s %s",
295 4f3d5b76 Michael Hanselmann
               self.arg_offset + 1,
296 4f3d5b76 Michael Hanselmann
               utils.ShellQuote("|".join(skip_one)),
297 4f3d5b76 Michael Hanselmann
               utils.ShellQuote("|".join(ignore)))
298 4f3d5b76 Michael Hanselmann
    else:
299 4f3d5b76 Michael Hanselmann
      # When there are no options the first argument is always at position
300 4f3d5b76 Michael Hanselmann
      # offset + 1
301 4f3d5b76 Michael Hanselmann
      sw.Write("first_arg_idx=%s", self.arg_offset + 1)
302 4f3d5b76 Michael Hanselmann
303 4f3d5b76 Michael Hanselmann
  def _CompleteOptionValues(self, sw):
304 4f3d5b76 Michael Hanselmann
    # Group by values
305 4f3d5b76 Michael Hanselmann
    # "values" -> [optname1, optname2, ...]
306 4f3d5b76 Michael Hanselmann
    values = {}
307 4f3d5b76 Michael Hanselmann
308 4f3d5b76 Michael Hanselmann
    for opt in self.opts:
309 4f3d5b76 Michael Hanselmann
      if not opt.takes_value():
310 4f3d5b76 Michael Hanselmann
        continue
311 4f3d5b76 Michael Hanselmann
312 4f3d5b76 Michael Hanselmann
      # Only static choices implemented so far (e.g. no node list)
313 4f3d5b76 Michael Hanselmann
      suggest = getattr(opt, "completion_suggest", None)
314 4f3d5b76 Michael Hanselmann
315 e7b61bb0 Iustin Pop
      # our custom option type
316 e7b61bb0 Iustin Pop
      if opt.type == "bool":
317 e7b61bb0 Iustin Pop
        suggest = ["yes", "no"]
318 e7b61bb0 Iustin Pop
319 4f3d5b76 Michael Hanselmann
      if not suggest:
320 4f3d5b76 Michael Hanselmann
        suggest = opt.choices
321 4f3d5b76 Michael Hanselmann
322 63d44c55 Michael Hanselmann
      if (isinstance(suggest, (int, long)) and
323 63d44c55 Michael Hanselmann
          suggest in cli.OPT_COMPL_ALL):
324 63d44c55 Michael Hanselmann
        key = suggest
325 63d44c55 Michael Hanselmann
      elif suggest:
326 63d44c55 Michael Hanselmann
        key = " ".join(sorted(suggest))
327 4f3d5b76 Michael Hanselmann
      else:
328 63d44c55 Michael Hanselmann
        key = ""
329 4f3d5b76 Michael Hanselmann
330 63d44c55 Michael Hanselmann
      values.setdefault(key, []).extend(opt.all_names)
331 4f3d5b76 Michael Hanselmann
332 4f3d5b76 Michael Hanselmann
    # Don't write any code if there are no option values
333 4f3d5b76 Michael Hanselmann
    if not values:
334 4f3d5b76 Michael Hanselmann
      return
335 4f3d5b76 Michael Hanselmann
336 d4b94fe8 Michael Hanselmann
    cur = "\"$optcur\""
337 d4b94fe8 Michael Hanselmann
338 d4b94fe8 Michael Hanselmann
    wrote_opt = False
339 d4b94fe8 Michael Hanselmann
340 d4b94fe8 Michael Hanselmann
    for (suggest, allnames) in values.iteritems():
341 d4b94fe8 Michael Hanselmann
      longnames = [i for i in allnames if i.startswith("--")]
342 d4b94fe8 Michael Hanselmann
343 d4b94fe8 Michael Hanselmann
      if wrote_opt:
344 d4b94fe8 Michael Hanselmann
        condcmd = "elif"
345 d4b94fe8 Michael Hanselmann
      else:
346 d4b94fe8 Michael Hanselmann
        condcmd = "if"
347 d4b94fe8 Michael Hanselmann
348 d4b94fe8 Michael Hanselmann
      sw.Write("%s _ganeti_checkopt %s %s; then", condcmd,
349 d4b94fe8 Michael Hanselmann
               utils.ShellQuote("|".join(["%s=*" % i for i in longnames])),
350 d4b94fe8 Michael Hanselmann
               utils.ShellQuote("|".join(allnames)))
351 d4b94fe8 Michael Hanselmann
      sw.IncIndent()
352 d4b94fe8 Michael Hanselmann
      try:
353 63d44c55 Michael Hanselmann
        if suggest == cli.OPT_COMPL_MANY_NODES:
354 63d44c55 Michael Hanselmann
          # TODO: Implement comma-separated values
355 63d44c55 Michael Hanselmann
          WriteCompReply(sw, "-W ''", cur=cur)
356 63d44c55 Michael Hanselmann
        elif suggest == cli.OPT_COMPL_ONE_NODE:
357 63d44c55 Michael Hanselmann
          WriteCompReply(sw, "-W \"$(_ganeti_nodes)\"", cur=cur)
358 63d44c55 Michael Hanselmann
        elif suggest == cli.OPT_COMPL_ONE_INSTANCE:
359 63d44c55 Michael Hanselmann
          WriteCompReply(sw, "-W \"$(_ganeti_instances)\"", cur=cur)
360 63d44c55 Michael Hanselmann
        elif suggest == cli.OPT_COMPL_ONE_OS:
361 63d44c55 Michael Hanselmann
          WriteCompReply(sw, "-W \"$(_ganeti_os)\"", cur=cur)
362 63d44c55 Michael Hanselmann
        elif suggest == cli.OPT_COMPL_ONE_IALLOCATOR:
363 63d44c55 Michael Hanselmann
          WriteCompReply(sw, "-W \"$(_ganeti_iallocator)\"", cur=cur)
364 2d3ed64b Michael Hanselmann
        elif suggest == cli.OPT_COMPL_INST_ADD_NODES:
365 2d3ed64b Michael Hanselmann
          sw.Write("local tmp= node1= pfx= curvalue=\"${optcur#*:}\"")
366 2d3ed64b Michael Hanselmann
367 2d3ed64b Michael Hanselmann
          sw.Write("if [[ \"$optcur\" == *:* ]]; then")
368 2d3ed64b Michael Hanselmann
          sw.IncIndent()
369 2d3ed64b Michael Hanselmann
          try:
370 2d3ed64b Michael Hanselmann
            sw.Write("node1=\"${optcur%%:*}\"")
371 2d3ed64b Michael Hanselmann
372 2d3ed64b Michael Hanselmann
            sw.Write("if [[ \"$COMP_WORDBREAKS\" != *:* ]]; then")
373 2d3ed64b Michael Hanselmann
            sw.IncIndent()
374 2d3ed64b Michael Hanselmann
            try:
375 2d3ed64b Michael Hanselmann
              sw.Write("pfx=\"$node1:\"")
376 2d3ed64b Michael Hanselmann
            finally:
377 2d3ed64b Michael Hanselmann
              sw.DecIndent()
378 2d3ed64b Michael Hanselmann
            sw.Write("fi")
379 2d3ed64b Michael Hanselmann
          finally:
380 2d3ed64b Michael Hanselmann
            sw.DecIndent()
381 2d3ed64b Michael Hanselmann
          sw.Write("fi")
382 2d3ed64b Michael Hanselmann
383 2d3ed64b Michael Hanselmann
          sw.Write("_ganeti_dbglog pfx=\"'$pfx'\" curvalue=\"'$curvalue'\""
384 2d3ed64b Michael Hanselmann
                   " node1=\"'$node1'\"")
385 2d3ed64b Michael Hanselmann
386 2d3ed64b Michael Hanselmann
          sw.Write("for i in $(_ganeti_nodes); do")
387 2d3ed64b Michael Hanselmann
          sw.IncIndent()
388 2d3ed64b Michael Hanselmann
          try:
389 2d3ed64b Michael Hanselmann
            sw.Write("if [[ -z \"$node1\" ]]; then")
390 2d3ed64b Michael Hanselmann
            sw.IncIndent()
391 2d3ed64b Michael Hanselmann
            try:
392 2d3ed64b Michael Hanselmann
              sw.Write("tmp=\"$tmp $i $i:\"")
393 2d3ed64b Michael Hanselmann
            finally:
394 2d3ed64b Michael Hanselmann
              sw.DecIndent()
395 2d3ed64b Michael Hanselmann
            sw.Write("elif [[ \"$i\" != \"$node1\" ]]; then")
396 2d3ed64b Michael Hanselmann
            sw.IncIndent()
397 2d3ed64b Michael Hanselmann
            try:
398 2d3ed64b Michael Hanselmann
              sw.Write("tmp=\"$tmp $i\"")
399 2d3ed64b Michael Hanselmann
            finally:
400 2d3ed64b Michael Hanselmann
              sw.DecIndent()
401 2d3ed64b Michael Hanselmann
            sw.Write("fi")
402 2d3ed64b Michael Hanselmann
          finally:
403 2d3ed64b Michael Hanselmann
            sw.DecIndent()
404 2d3ed64b Michael Hanselmann
          sw.Write("done")
405 2d3ed64b Michael Hanselmann
406 2d3ed64b Michael Hanselmann
          WriteCompReply(sw, "-P \"$pfx\" -W \"$tmp\"", cur="\"$curvalue\"")
407 63d44c55 Michael Hanselmann
        else:
408 63d44c55 Michael Hanselmann
          WriteCompReply(sw, "-W %s" % utils.ShellQuote(suggest), cur=cur)
409 d4b94fe8 Michael Hanselmann
      finally:
410 d4b94fe8 Michael Hanselmann
        sw.DecIndent()
411 d4b94fe8 Michael Hanselmann
412 d4b94fe8 Michael Hanselmann
      wrote_opt = True
413 d4b94fe8 Michael Hanselmann
414 d4b94fe8 Michael Hanselmann
    if wrote_opt:
415 d4b94fe8 Michael Hanselmann
      sw.Write("fi")
416 d4b94fe8 Michael Hanselmann
417 d4b94fe8 Michael Hanselmann
    return
418 632d5090 Michael Hanselmann
419 4f3d5b76 Michael Hanselmann
  def _CompleteArguments(self, sw):
420 4f3d5b76 Michael Hanselmann
    if not (self.opts or self.args):
421 4f3d5b76 Michael Hanselmann
      return
422 4f3d5b76 Michael Hanselmann
423 4f3d5b76 Michael Hanselmann
    all_option_names = []
424 4f3d5b76 Michael Hanselmann
    for opt in self.opts:
425 4f3d5b76 Michael Hanselmann
      all_option_names.extend(opt.all_names)
426 4f3d5b76 Michael Hanselmann
    all_option_names.sort()
427 4f3d5b76 Michael Hanselmann
428 4f3d5b76 Michael Hanselmann
    # List options if no argument has been specified yet
429 4f3d5b76 Michael Hanselmann
    sw.Write("_ganeti_list_options %s",
430 4f3d5b76 Michael Hanselmann
             utils.ShellQuote(" ".join(all_option_names)))
431 4f3d5b76 Michael Hanselmann
432 4f3d5b76 Michael Hanselmann
    if self.args:
433 4f3d5b76 Michael Hanselmann
      last_idx = len(self.args) - 1
434 4f3d5b76 Michael Hanselmann
      last_arg_end = 0
435 4f3d5b76 Michael Hanselmann
      varlen_arg_idx = None
436 4f3d5b76 Michael Hanselmann
      wrote_arg = False
437 4f3d5b76 Michael Hanselmann
438 4f3d5b76 Michael Hanselmann
      # Write some debug comments
439 4f3d5b76 Michael Hanselmann
      for idx, arg in enumerate(self.args):
440 4f3d5b76 Michael Hanselmann
        sw.Write("# %s: %r", idx, arg)
441 4f3d5b76 Michael Hanselmann
442 4f3d5b76 Michael Hanselmann
      sw.Write("compgenargs=")
443 4f3d5b76 Michael Hanselmann
444 4f3d5b76 Michael Hanselmann
      for idx, arg in enumerate(self.args):
445 4f3d5b76 Michael Hanselmann
        assert arg.min is not None and arg.min >= 0
446 4f3d5b76 Michael Hanselmann
        assert not (idx < last_idx and arg.max is None)
447 4f3d5b76 Michael Hanselmann
448 4f3d5b76 Michael Hanselmann
        if arg.min != arg.max or arg.max is None:
449 4f3d5b76 Michael Hanselmann
          if varlen_arg_idx is not None:
450 4f3d5b76 Michael Hanselmann
            raise Exception("Only one argument can have a variable length")
451 4f3d5b76 Michael Hanselmann
          varlen_arg_idx = idx
452 4f3d5b76 Michael Hanselmann
453 4f3d5b76 Michael Hanselmann
        compgenargs = []
454 4f3d5b76 Michael Hanselmann
455 4f3d5b76 Michael Hanselmann
        if isinstance(arg, cli.ArgUnknown):
456 4f3d5b76 Michael Hanselmann
          choices = ""
457 4f3d5b76 Michael Hanselmann
        elif isinstance(arg, cli.ArgSuggest):
458 4f3d5b76 Michael Hanselmann
          choices = utils.ShellQuote(" ".join(arg.choices))
459 4f3d5b76 Michael Hanselmann
        elif isinstance(arg, cli.ArgInstance):
460 4f3d5b76 Michael Hanselmann
          choices = "$(_ganeti_instances)"
461 4f3d5b76 Michael Hanselmann
        elif isinstance(arg, cli.ArgNode):
462 4f3d5b76 Michael Hanselmann
          choices = "$(_ganeti_nodes)"
463 4f3d5b76 Michael Hanselmann
        elif isinstance(arg, cli.ArgJobId):
464 4f3d5b76 Michael Hanselmann
          choices = "$(_ganeti_jobs)"
465 f9faf9c3 René Nussbaumer
        elif isinstance(arg, cli.ArgOs):
466 f9faf9c3 René Nussbaumer
          choices = "$(_ganeti_os)"
467 4f3d5b76 Michael Hanselmann
        elif isinstance(arg, cli.ArgFile):
468 4f3d5b76 Michael Hanselmann
          choices = ""
469 4f3d5b76 Michael Hanselmann
          compgenargs.append("-f")
470 4f3d5b76 Michael Hanselmann
        elif isinstance(arg, cli.ArgCommand):
471 4f3d5b76 Michael Hanselmann
          choices = ""
472 4f3d5b76 Michael Hanselmann
          compgenargs.append("-c")
473 83ec7961 Michael Hanselmann
        elif isinstance(arg, cli.ArgHost):
474 83ec7961 Michael Hanselmann
          choices = ""
475 83ec7961 Michael Hanselmann
          compgenargs.append("-A hostname")
476 4f3d5b76 Michael Hanselmann
        else:
477 4f3d5b76 Michael Hanselmann
          raise Exception("Unknown argument type %r" % arg)
478 4f3d5b76 Michael Hanselmann
479 4f3d5b76 Michael Hanselmann
        if arg.min == 1 and arg.max == 1:
480 4f3d5b76 Michael Hanselmann
          cmpcode = """"$arg_idx" == %d""" % (last_arg_end)
481 8adfb141 Michael Hanselmann
        elif arg.max is None:
482 8adfb141 Michael Hanselmann
          cmpcode = """"$arg_idx" -ge %d""" % (last_arg_end)
483 5431eff1 Michael Hanselmann
        elif arg.min <= arg.max:
484 4f3d5b76 Michael Hanselmann
          cmpcode = (""""$arg_idx" -ge %d && "$arg_idx" -lt %d""" %
485 4f3d5b76 Michael Hanselmann
                     (last_arg_end, last_arg_end + arg.max))
486 4f3d5b76 Michael Hanselmann
        else:
487 4f3d5b76 Michael Hanselmann
          raise Exception("Unable to generate argument position condition")
488 4f3d5b76 Michael Hanselmann
489 4f3d5b76 Michael Hanselmann
        last_arg_end += arg.min
490 4f3d5b76 Michael Hanselmann
491 4f3d5b76 Michael Hanselmann
        if choices or compgenargs:
492 4f3d5b76 Michael Hanselmann
          if wrote_arg:
493 4f3d5b76 Michael Hanselmann
            condcmd = "elif"
494 4f3d5b76 Michael Hanselmann
          else:
495 4f3d5b76 Michael Hanselmann
            condcmd = "if"
496 4f3d5b76 Michael Hanselmann
497 4f3d5b76 Michael Hanselmann
          sw.Write("""%s [[ %s ]]; then""", condcmd, cmpcode)
498 4f3d5b76 Michael Hanselmann
          sw.IncIndent()
499 4f3d5b76 Michael Hanselmann
          try:
500 4f3d5b76 Michael Hanselmann
            if choices:
501 4f3d5b76 Michael Hanselmann
              sw.Write("""choices="$choices "%s""", choices)
502 4f3d5b76 Michael Hanselmann
            if compgenargs:
503 8adfb141 Michael Hanselmann
              sw.Write("compgenargs=%s",
504 8adfb141 Michael Hanselmann
                       utils.ShellQuote(" ".join(compgenargs)))
505 4f3d5b76 Michael Hanselmann
          finally:
506 4f3d5b76 Michael Hanselmann
            sw.DecIndent()
507 4f3d5b76 Michael Hanselmann
508 4f3d5b76 Michael Hanselmann
          wrote_arg = True
509 4f3d5b76 Michael Hanselmann
510 4f3d5b76 Michael Hanselmann
      if wrote_arg:
511 4f3d5b76 Michael Hanselmann
        sw.Write("fi")
512 4f3d5b76 Michael Hanselmann
513 4f3d5b76 Michael Hanselmann
    if self.args:
514 4f3d5b76 Michael Hanselmann
      WriteCompReply(sw, """-W "$choices" $compgenargs""")
515 4f3d5b76 Michael Hanselmann
    else:
516 4f3d5b76 Michael Hanselmann
      # $compgenargs exists only if there are arguments
517 4f3d5b76 Michael Hanselmann
      WriteCompReply(sw, '-W "$choices"')
518 4f3d5b76 Michael Hanselmann
519 4f3d5b76 Michael Hanselmann
  def WriteTo(self, sw):
520 4f3d5b76 Michael Hanselmann
    self._FindFirstArgument(sw)
521 4f3d5b76 Michael Hanselmann
    self._CompleteOptionValues(sw)
522 4f3d5b76 Michael Hanselmann
    self._CompleteArguments(sw)
523 4f3d5b76 Michael Hanselmann
524 4f3d5b76 Michael Hanselmann
525 4f3d5b76 Michael Hanselmann
def WriteCompletion(sw, scriptname, funcname,
526 4f3d5b76 Michael Hanselmann
                    commands=None,
527 4f3d5b76 Michael Hanselmann
                    opts=None, args=None):
528 4f3d5b76 Michael Hanselmann
  """Writes the completion code for one command.
529 4f3d5b76 Michael Hanselmann
530 4f3d5b76 Michael Hanselmann
  @type sw: ShellWriter
531 4f3d5b76 Michael Hanselmann
  @param sw: Script writer
532 4f3d5b76 Michael Hanselmann
  @type scriptname: string
533 4f3d5b76 Michael Hanselmann
  @param scriptname: Name of command line program
534 4f3d5b76 Michael Hanselmann
  @type funcname: string
535 4f3d5b76 Michael Hanselmann
  @param funcname: Shell function name
536 4f3d5b76 Michael Hanselmann
  @type commands: list
537 4f3d5b76 Michael Hanselmann
  @param commands: List of all subcommands in this program
538 4f3d5b76 Michael Hanselmann
539 4f3d5b76 Michael Hanselmann
  """
540 4f3d5b76 Michael Hanselmann
  sw.Write("%s() {", funcname)
541 4f3d5b76 Michael Hanselmann
  sw.IncIndent()
542 4f3d5b76 Michael Hanselmann
  try:
543 580ef58d Michael Hanselmann
    sw.Write("local "
544 632d5090 Michael Hanselmann
             ' cur="${COMP_WORDS[COMP_CWORD]}"'
545 580ef58d Michael Hanselmann
             ' prev="${COMP_WORDS[COMP_CWORD-1]}"'
546 d4b94fe8 Michael Hanselmann
             ' i first_arg_idx choices compgenargs arg_idx optcur')
547 580ef58d Michael Hanselmann
548 5b0ca9d4 Michael Hanselmann
    sw.Write("_ganeti_dbglog cur=\"$cur\" prev=\"$prev\"")
549 5b0ca9d4 Michael Hanselmann
    sw.Write("[[ -n \"$GANETI_COMPL_LOG\" ]] &&"
550 5b0ca9d4 Michael Hanselmann
             " _ganeti_dbglog \"$(set | grep ^COMP_)\"")
551 4f3d5b76 Michael Hanselmann
552 4f3d5b76 Michael Hanselmann
    sw.Write("COMPREPLY=()")
553 4f3d5b76 Michael Hanselmann
554 4f3d5b76 Michael Hanselmann
    if opts is not None and args is not None:
555 4f3d5b76 Michael Hanselmann
      assert not commands
556 4f3d5b76 Michael Hanselmann
      CompletionWriter(0, opts, args).WriteTo(sw)
557 4f3d5b76 Michael Hanselmann
558 4f3d5b76 Michael Hanselmann
    else:
559 4f3d5b76 Michael Hanselmann
      sw.Write("""if [[ "$COMP_CWORD" == 1 ]]; then""")
560 4f3d5b76 Michael Hanselmann
      sw.IncIndent()
561 4f3d5b76 Michael Hanselmann
      try:
562 4f3d5b76 Michael Hanselmann
        # Complete the command name
563 4f3d5b76 Michael Hanselmann
        WriteCompReply(sw,
564 4f3d5b76 Michael Hanselmann
                       ("-W %s" %
565 4f3d5b76 Michael Hanselmann
                        utils.ShellQuote(" ".join(sorted(commands.keys())))))
566 4f3d5b76 Michael Hanselmann
      finally:
567 4f3d5b76 Michael Hanselmann
        sw.DecIndent()
568 4f3d5b76 Michael Hanselmann
      sw.Write("fi")
569 4f3d5b76 Michael Hanselmann
570 4f3d5b76 Michael Hanselmann
      # We're doing options and arguments to commands
571 4f3d5b76 Michael Hanselmann
      sw.Write("""case "${COMP_WORDS[1]}" in""")
572 4f3d5b76 Michael Hanselmann
      for cmd, (_, argdef, optdef, _, _) in commands.iteritems():
573 4f3d5b76 Michael Hanselmann
        if not (argdef or optdef):
574 4f3d5b76 Michael Hanselmann
          continue
575 4f3d5b76 Michael Hanselmann
576 4f3d5b76 Michael Hanselmann
        # TODO: Group by arguments and options
577 4f3d5b76 Michael Hanselmann
        sw.Write("%s)", utils.ShellQuote(cmd))
578 4f3d5b76 Michael Hanselmann
        sw.IncIndent()
579 4f3d5b76 Michael Hanselmann
        try:
580 4f3d5b76 Michael Hanselmann
          CompletionWriter(1, optdef, argdef).WriteTo(sw)
581 4f3d5b76 Michael Hanselmann
        finally:
582 4f3d5b76 Michael Hanselmann
          sw.DecIndent()
583 4f3d5b76 Michael Hanselmann
584 4f3d5b76 Michael Hanselmann
        sw.Write(";;")
585 4f3d5b76 Michael Hanselmann
      sw.Write("esac")
586 4f3d5b76 Michael Hanselmann
  finally:
587 4f3d5b76 Michael Hanselmann
    sw.DecIndent()
588 4f3d5b76 Michael Hanselmann
  sw.Write("}")
589 4f3d5b76 Michael Hanselmann
590 4f3d5b76 Michael Hanselmann
  sw.Write("complete -F %s -o filenames %s",
591 4f3d5b76 Michael Hanselmann
           utils.ShellQuote(funcname),
592 4f3d5b76 Michael Hanselmann
           utils.ShellQuote(scriptname))
593 4f3d5b76 Michael Hanselmann
594 4f3d5b76 Michael Hanselmann
595 4f3d5b76 Michael Hanselmann
def GetFunctionName(name):
596 4f3d5b76 Michael Hanselmann
  return "_" + re.sub(r"[^a-z0-9]+", "_", name.lower())
597 4f3d5b76 Michael Hanselmann
598 4f3d5b76 Michael Hanselmann
599 4f3d5b76 Michael Hanselmann
def GetCommands(filename, module):
600 4f3d5b76 Michael Hanselmann
  """Returns the commands defined in a module.
601 4f3d5b76 Michael Hanselmann
602 4f3d5b76 Michael Hanselmann
  Aliases are also added as commands.
603 4f3d5b76 Michael Hanselmann
604 4f3d5b76 Michael Hanselmann
  """
605 4f3d5b76 Michael Hanselmann
  try:
606 4f3d5b76 Michael Hanselmann
    commands = getattr(module, "commands")
607 f59418db Michael Hanselmann
  except AttributeError:
608 4f3d5b76 Michael Hanselmann
    raise Exception("Script %s doesn't have 'commands' attribute" %
609 4f3d5b76 Michael Hanselmann
                    filename)
610 4f3d5b76 Michael Hanselmann
611 1f4e391b Michael Hanselmann
  # Add the implicit "--help" option
612 1f4e391b Michael Hanselmann
  help_option = cli.cli_option("-h", "--help", default=False,
613 1f4e391b Michael Hanselmann
                               action="store_true")
614 1f4e391b Michael Hanselmann
615 1f4e391b Michael Hanselmann
  for (_, _, optdef, _, _) in commands.itervalues():
616 1f4e391b Michael Hanselmann
    if help_option not in optdef:
617 1f4e391b Michael Hanselmann
      optdef.append(help_option)
618 064c21f8 Iustin Pop
    if cli.DEBUG_OPT not in optdef:
619 064c21f8 Iustin Pop
      optdef.append(cli.DEBUG_OPT)
620 1f4e391b Michael Hanselmann
621 4f3d5b76 Michael Hanselmann
  # Use aliases
622 4f3d5b76 Michael Hanselmann
  aliases = getattr(module, "aliases", {})
623 4f3d5b76 Michael Hanselmann
  if aliases:
624 4f3d5b76 Michael Hanselmann
    commands = commands.copy()
625 4f3d5b76 Michael Hanselmann
    for name, target in aliases.iteritems():
626 4f3d5b76 Michael Hanselmann
      commands[name] = commands[target]
627 4f3d5b76 Michael Hanselmann
628 4f3d5b76 Michael Hanselmann
  return commands
629 4f3d5b76 Michael Hanselmann
630 4f3d5b76 Michael Hanselmann
631 4f3d5b76 Michael Hanselmann
def main():
632 4f3d5b76 Michael Hanselmann
  buf = StringIO()
633 4f3d5b76 Michael Hanselmann
  sw = ShellWriter(buf)
634 4f3d5b76 Michael Hanselmann
635 4f3d5b76 Michael Hanselmann
  WritePreamble(sw)
636 4f3d5b76 Michael Hanselmann
637 4f3d5b76 Michael Hanselmann
  # gnt-* scripts
638 4f3d5b76 Michael Hanselmann
  for scriptname in _autoconf.GNT_SCRIPTS:
639 4f3d5b76 Michael Hanselmann
    filename = "scripts/%s" % scriptname
640 4f3d5b76 Michael Hanselmann
641 4f3d5b76 Michael Hanselmann
    WriteCompletion(sw, scriptname,
642 4f3d5b76 Michael Hanselmann
                    GetFunctionName(scriptname),
643 d6f5892b Michael Hanselmann
                    commands=GetCommands(filename,
644 e948770c Michael Hanselmann
                                         build.LoadModule(filename)))
645 4f3d5b76 Michael Hanselmann
646 4f3d5b76 Michael Hanselmann
  # Burnin script
647 e948770c Michael Hanselmann
  burnin = build.LoadModule("tools/burnin")
648 4f3d5b76 Michael Hanselmann
  WriteCompletion(sw, "%s/burnin" % constants.TOOLSDIR, "_ganeti_burnin",
649 4f3d5b76 Michael Hanselmann
                  opts=burnin.OPTIONS, args=burnin.ARGUMENTS)
650 4f3d5b76 Michael Hanselmann
651 4f3d5b76 Michael Hanselmann
  print buf.getvalue()
652 4f3d5b76 Michael Hanselmann
653 4f3d5b76 Michael Hanselmann
654 4f3d5b76 Michael Hanselmann
if __name__ == "__main__":
655 4f3d5b76 Michael Hanselmann
  main()