Statistics
| Branch: | Tag: | Revision:

root / autotools / build-bash-completion @ 49283373

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