Revision 7a1ecaed

b/daemons/ganeti-masterd
166 166
    if operation == "submit":
167 167
      return self.put(args)
168 168
    elif operation == "query":
169
      path = args["object"]
170
      if path == "instances":
171
        return self.query(args)
169
      return self.query(args)
172 170
    else:
173 171
      raise ValueError("Invalid operation")
174 172

  
......
183 181
    names = args["names"]
184 182
    if path == "instances":
185 183
      opclass = opcodes.OpQueryInstances
184
    elif path == "jobs":
185
      # early exit because job query-ing is special (not via opcodes)
186
      return self.query_jobs(fields, names)
186 187
    else:
187 188
      raise ValueError("Invalid object %s" % path)
188 189

  
......
191 192
    result = cpu.ExecOpCode(op)
192 193
    return result
193 194

  
194
  def query_job(self, rid):
195
    rid = int(data)
196
    job = self.server.queue.query(rid)
197
    return job
195
  def query_jobs(self, fields, names):
196
    return self.server.queue.query_jobs(fields, names)
198 197

  
199 198

  
200 199
def JobRunner(proc, job):
b/lib/jqueue.py
25 25
import Queue
26 26

  
27 27
from ganeti import opcodes
28
from ganeti import errors
28 29

  
29 30
class JobObject:
30 31
  """In-memory job representation.
......
90 91
    result = self.job_queue.get(rid, None)
91 92
    self.lock.release()
92 93
    return result
94

  
95
  def query_jobs(self, fields, names):
96
    """Query all jobs.
97

  
98
    The fields and names parameters are similar to the ones passed to
99
    the OpQueryInstances.
100

  
101
    """
102
    result = []
103
    self.lock.acquire()
104
    try:
105
      for jobj in self.job_queue.itervalues():
106
        row = []
107
        jdata = jobj.data
108
        for fname in fields:
109
          if fname == "id":
110
            row.append(jdata.job_id)
111
          elif fname == "status":
112
            row.append(jdata.status)
113
          elif fname == "opcodes":
114
            row.append(",".join([op.OP_ID for op in jdata.op_list]))
115
          else:
116
            raise errors.OpExecError("Invalid job query field '%s'" %
117
                                           fname)
118
        result.append(row)
119
    finally:
120
      self.lock.release()
121
    return result
b/scripts/Makefile.am
1
dist_sbin_SCRIPTS = gnt-instance gnt-cluster gnt-node gnt-os gnt-backup gnt-debug
1
dist_sbin_SCRIPTS = gnt-instance gnt-cluster gnt-node gnt-os gnt-backup gnt-debug gnt-job
b/scripts/gnt-job
1
#!/usr/bin/python
2
#
3

  
4
# Copyright (C) 2006, 2007 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

  
21

  
22
import sys
23
import os
24
import itertools
25
from optparse import make_option
26
from cStringIO import StringIO
27

  
28
from ganeti.cli import *
29
from ganeti import opcodes
30
from ganeti import logger
31
from ganeti import constants
32
from ganeti import utils
33
from ganeti import errors
34

  
35

  
36
def ListJobs(opts, args):
37
  """List the jobs
38

  
39
  """
40
  if opts.output is None:
41
    selected_fields = ["id", "status"]
42
  else:
43
    selected_fields = opts.output.split(",")
44

  
45
  query = {
46
    "object": "jobs",
47
    "fields": selected_fields,
48
    "names": [],
49
    }
50

  
51
  output = SubmitQuery(query)
52
  if not opts.no_headers:
53
    headers = {
54
      "id": "ID",
55
      "status": "Status",
56
      "opcodes": "OpCodes",
57
      }
58
  else:
59
    headers = None
60

  
61
  # we don't have yet unitfields here
62
  unitfields = None
63
  numfields = ["id"]
64

  
65
  # change raw values to nicer strings
66
  for row in output:
67
    for idx, field in enumerate(selected_fields):
68
      val = row[idx]
69
      if field == "status":
70
        if val == opcodes.Job.STATUS_PENDING:
71
          val = "pending"
72
        elif val == opcodes.Job.STATUS_RUNNING:
73
          val = "running"
74
        elif val == opcodes.Job.STATUS_FINISHED:
75
          val = "finished"
76
        else:
77
          raise errors.ProgrammerError("Unknown job status code '%s'" % val)
78

  
79
      row[idx] = str(val)
80

  
81
  data = GenerateTable(separator=opts.separator, headers=headers,
82
                       fields=selected_fields, unitfields=unitfields,
83
                       numfields=numfields, data=output)
84
  for line in data:
85
    print line
86

  
87
  return 0
88

  
89

  
90
commands = {
91
  'list': (ListJobs, ARGS_NONE,
92
            [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT],
93
            "", "List the jobs and their status. The available fields are"
94
           " (see the man page for details): id, status, opcodes."
95
           " The default field"
96
           " list is (in order): id, status."),
97
  }
98

  
99

  
100
if __name__ == '__main__':
101
  sys.exit(GenericMain(commands))

Also available in: Unified diff