Statistics
| Branch: | Tag: | Revision:

root / lib / luxi.py @ b3fc101f

History | View | Annotate | Download (8.1 kB)

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

24 8d5b316c Iustin Pop
This module implements the local unix socket protocol. You only need
25 c2a03789 Iustin Pop
this module and the opcodes module in the client program in order to
26 c2a03789 Iustin Pop
communicate with the master.
27 c2a03789 Iustin Pop

28 7577196d Guido Trotter
The module is also used by the master daemon.
29 c2a03789 Iustin Pop

30 c2a03789 Iustin Pop
"""
31 c2a03789 Iustin Pop
32 ceab32dd Iustin Pop
from ganeti import constants
33 d36e433d Petr Pudlak
from ganeti import pathutils
34 28b71a76 Michael Hanselmann
from ganeti import objects
35 912b2278 Petr Pudlak
import ganeti.rpc.client as cl
36 1dec44b2 Klaus Aehlig
from ganeti.rpc.errors import RequestError
37 912b2278 Petr Pudlak
from ganeti.rpc.transport import Transport
38 ff1012ef Petr Pudlak
39 ff1012ef Petr Pudlak
__all__ = [
40 ff1012ef Petr Pudlak
  # classes:
41 ff1012ef Petr Pudlak
  "Client"
42 ff1012ef Petr Pudlak
  ]
43 c2a03789 Iustin Pop
44 fbb05686 Jose A. Lopes
REQ_SUBMIT_JOB = constants.LUXI_REQ_SUBMIT_JOB
45 fbb05686 Jose A. Lopes
REQ_SUBMIT_JOB_TO_DRAINED_QUEUE = constants.LUXI_REQ_SUBMIT_JOB_TO_DRAINED_QUEUE
46 fbb05686 Jose A. Lopes
REQ_SUBMIT_MANY_JOBS = constants.LUXI_REQ_SUBMIT_MANY_JOBS
47 a4417db4 Thomas Thrainer
REQ_PICKUP_JOB = constants.LUXI_REQ_PICKUP_JOB
48 fbb05686 Jose A. Lopes
REQ_WAIT_FOR_JOB_CHANGE = constants.LUXI_REQ_WAIT_FOR_JOB_CHANGE
49 fbb05686 Jose A. Lopes
REQ_CANCEL_JOB = constants.LUXI_REQ_CANCEL_JOB
50 fbb05686 Jose A. Lopes
REQ_ARCHIVE_JOB = constants.LUXI_REQ_ARCHIVE_JOB
51 fbb05686 Jose A. Lopes
REQ_CHANGE_JOB_PRIORITY = constants.LUXI_REQ_CHANGE_JOB_PRIORITY
52 fbb05686 Jose A. Lopes
REQ_AUTO_ARCHIVE_JOBS = constants.LUXI_REQ_AUTO_ARCHIVE_JOBS
53 fbb05686 Jose A. Lopes
REQ_QUERY = constants.LUXI_REQ_QUERY
54 fbb05686 Jose A. Lopes
REQ_QUERY_FIELDS = constants.LUXI_REQ_QUERY_FIELDS
55 fbb05686 Jose A. Lopes
REQ_QUERY_JOBS = constants.LUXI_REQ_QUERY_JOBS
56 fbb05686 Jose A. Lopes
REQ_QUERY_INSTANCES = constants.LUXI_REQ_QUERY_INSTANCES
57 fbb05686 Jose A. Lopes
REQ_QUERY_NODES = constants.LUXI_REQ_QUERY_NODES
58 fbb05686 Jose A. Lopes
REQ_QUERY_GROUPS = constants.LUXI_REQ_QUERY_GROUPS
59 fbb05686 Jose A. Lopes
REQ_QUERY_NETWORKS = constants.LUXI_REQ_QUERY_NETWORKS
60 fbb05686 Jose A. Lopes
REQ_QUERY_EXPORTS = constants.LUXI_REQ_QUERY_EXPORTS
61 fbb05686 Jose A. Lopes
REQ_QUERY_CONFIG_VALUES = constants.LUXI_REQ_QUERY_CONFIG_VALUES
62 fbb05686 Jose A. Lopes
REQ_QUERY_CLUSTER_INFO = constants.LUXI_REQ_QUERY_CLUSTER_INFO
63 fbb05686 Jose A. Lopes
REQ_QUERY_TAGS = constants.LUXI_REQ_QUERY_TAGS
64 fbb05686 Jose A. Lopes
REQ_SET_DRAIN_FLAG = constants.LUXI_REQ_SET_DRAIN_FLAG
65 fbb05686 Jose A. Lopes
REQ_SET_WATCHER_PAUSE = constants.LUXI_REQ_SET_WATCHER_PAUSE
66 fbb05686 Jose A. Lopes
REQ_ALL = constants.LUXI_REQ_ALL
67 fbb05686 Jose A. Lopes
68 fbb05686 Jose A. Lopes
DEF_RWTO = constants.LUXI_DEF_RWTO
69 fbb05686 Jose A. Lopes
WFJC_TIMEOUT = constants.LUXI_WFJC_TIMEOUT
70 793a8f7c Michael Hanselmann
71 c2a03789 Iustin Pop
72 912b2278 Petr Pudlak
class Client(cl.AbstractClient):
73 c2a03789 Iustin Pop
  """High-level client implementation.
74 c2a03789 Iustin Pop

75 c2a03789 Iustin Pop
  This uses a backing Transport-like class on top of which it
76 c2a03789 Iustin Pop
  implements data serialization/deserialization.
77 c2a03789 Iustin Pop

78 c2a03789 Iustin Pop
  """
79 912b2278 Petr Pudlak
  def __init__(self, address=None, timeouts=None, transport=Transport):
80 c2a03789 Iustin Pop
    """Constructor for the Client class.
81 c2a03789 Iustin Pop

82 912b2278 Petr Pudlak
    Arguments are the same as for L{AbstractClient}.
83 3d8548c4 Michael Hanselmann

84 231db3a5 Michael Hanselmann
    """
85 d36e433d Petr Pudlak
    super(Client, self).__init__(timeouts, transport)
86 cda215a9 Petr Pudlak
    # Override the version of the protocol:
87 cda215a9 Petr Pudlak
    self.version = constants.LUXI_VERSION
88 d36e433d Petr Pudlak
    # Store the socket address
89 d36e433d Petr Pudlak
    if address is None:
90 d36e433d Petr Pudlak
      address = pathutils.QUERY_SOCKET
91 d36e433d Petr Pudlak
    self.address = address
92 d36e433d Petr Pudlak
    self._InitTransport()
93 d36e433d Petr Pudlak
94 d36e433d Petr Pudlak
  def _GetAddress(self):
95 d36e433d Petr Pudlak
    return self.address
96 c2a03789 Iustin Pop
97 3ccafd0e Iustin Pop
  def SetQueueDrainFlag(self, drain_flag):
98 83c046a2 Iustin Pop
    return self.CallMethod(REQ_SET_DRAIN_FLAG, (drain_flag, ))
99 3ccafd0e Iustin Pop
100 05e50653 Michael Hanselmann
  def SetWatcherPause(self, until):
101 a629ecb9 Iustin Pop
    return self.CallMethod(REQ_SET_WATCHER_PAUSE, (until, ))
102 05e50653 Michael Hanselmann
103 d9d1e541 Klaus Aehlig
  def PickupJob(self, job):
104 d9d1e541 Klaus Aehlig
    return self.CallMethod(REQ_PICKUP_JOB, (job,))
105 d9d1e541 Klaus Aehlig
106 0bbe448c Michael Hanselmann
  def SubmitJob(self, ops):
107 a5efec93 Santi Raffa
    ops_state = map(lambda op: op.__getstate__()
108 a5efec93 Santi Raffa
                               if not isinstance(op, objects.ConfigObject)
109 a5efec93 Santi Raffa
                               else op.ToDict(_with_private=True), ops)
110 734a2a7c René Nussbaumer
    return self.CallMethod(REQ_SUBMIT_JOB, (ops_state, ))
111 0bbe448c Michael Hanselmann
112 346c3037 Klaus Aehlig
  def SubmitJobToDrainedQueue(self, ops):
113 346c3037 Klaus Aehlig
    ops_state = map(lambda op: op.__getstate__(), ops)
114 346c3037 Klaus Aehlig
    return self.CallMethod(REQ_SUBMIT_JOB_TO_DRAINED_QUEUE, (ops_state, ))
115 346c3037 Klaus Aehlig
116 2971c913 Iustin Pop
  def SubmitManyJobs(self, jobs):
117 2971c913 Iustin Pop
    jobs_state = []
118 2971c913 Iustin Pop
    for ops in jobs:
119 2971c913 Iustin Pop
      jobs_state.append([op.__getstate__() for op in ops])
120 734a2a7c René Nussbaumer
    return self.CallMethod(REQ_SUBMIT_MANY_JOBS, (jobs_state, ))
121 2971c913 Iustin Pop
122 7f97eb93 Hrvoje Ribicic
  @staticmethod
123 7f97eb93 Hrvoje Ribicic
  def _PrepareJobId(request_name, job_id):
124 7f97eb93 Hrvoje Ribicic
    try:
125 7f97eb93 Hrvoje Ribicic
      return int(job_id)
126 7f97eb93 Hrvoje Ribicic
    except ValueError:
127 7f97eb93 Hrvoje Ribicic
      raise RequestError("Invalid parameter passed to %s as job id: "
128 7f97eb93 Hrvoje Ribicic
                         " expected integer, got value %s" %
129 7f97eb93 Hrvoje Ribicic
                         (request_name, job_id))
130 7f97eb93 Hrvoje Ribicic
131 0bbe448c Michael Hanselmann
  def CancelJob(self, job_id):
132 7f97eb93 Hrvoje Ribicic
    job_id = Client._PrepareJobId(REQ_CANCEL_JOB, job_id)
133 a629ecb9 Iustin Pop
    return self.CallMethod(REQ_CANCEL_JOB, (job_id, ))
134 0bbe448c Michael Hanselmann
135 0bbe448c Michael Hanselmann
  def ArchiveJob(self, job_id):
136 7f97eb93 Hrvoje Ribicic
    job_id = Client._PrepareJobId(REQ_ARCHIVE_JOB, job_id)
137 a629ecb9 Iustin Pop
    return self.CallMethod(REQ_ARCHIVE_JOB, (job_id, ))
138 0bbe448c Michael Hanselmann
139 f63ffb37 Michael Hanselmann
  def ChangeJobPriority(self, job_id, priority):
140 7f97eb93 Hrvoje Ribicic
    job_id = Client._PrepareJobId(REQ_CHANGE_JOB_PRIORITY, job_id)
141 f63ffb37 Michael Hanselmann
    return self.CallMethod(REQ_CHANGE_JOB_PRIORITY, (job_id, priority))
142 f63ffb37 Michael Hanselmann
143 07cd723a Iustin Pop
  def AutoArchiveJobs(self, age):
144 f8ad5591 Michael Hanselmann
    timeout = (DEF_RWTO - 1) / 2
145 83c046a2 Iustin Pop
    return self.CallMethod(REQ_AUTO_ARCHIVE_JOBS, (age, timeout))
146 07cd723a Iustin Pop
147 f4484122 Michael Hanselmann
  def WaitForJobChangeOnce(self, job_id, fields,
148 793a8f7c Michael Hanselmann
                           prev_job_info, prev_log_serial,
149 793a8f7c Michael Hanselmann
                           timeout=WFJC_TIMEOUT):
150 793a8f7c Michael Hanselmann
    """Waits for changes on a job.
151 793a8f7c Michael Hanselmann

152 793a8f7c Michael Hanselmann
    @param job_id: Job ID
153 793a8f7c Michael Hanselmann
    @type fields: list
154 793a8f7c Michael Hanselmann
    @param fields: List of field names to be observed
155 793a8f7c Michael Hanselmann
    @type prev_job_info: None or list
156 793a8f7c Michael Hanselmann
    @param prev_job_info: Previously received job information
157 793a8f7c Michael Hanselmann
    @type prev_log_serial: None or int/long
158 793a8f7c Michael Hanselmann
    @param prev_log_serial: Highest log serial number previously received
159 793a8f7c Michael Hanselmann
    @type timeout: int/float
160 793a8f7c Michael Hanselmann
    @param timeout: Timeout in seconds (values larger than L{WFJC_TIMEOUT} will
161 793a8f7c Michael Hanselmann
                    be capped to that value)
162 793a8f7c Michael Hanselmann

163 793a8f7c Michael Hanselmann
    """
164 793a8f7c Michael Hanselmann
    assert timeout >= 0, "Timeout can not be negative"
165 f4484122 Michael Hanselmann
    return self.CallMethod(REQ_WAIT_FOR_JOB_CHANGE,
166 f4484122 Michael Hanselmann
                           (job_id, fields, prev_job_info,
167 793a8f7c Michael Hanselmann
                            prev_log_serial,
168 793a8f7c Michael Hanselmann
                            min(WFJC_TIMEOUT, timeout)))
169 f4484122 Michael Hanselmann
170 f4484122 Michael Hanselmann
  def WaitForJobChange(self, job_id, fields, prev_job_info, prev_log_serial):
171 7f97eb93 Hrvoje Ribicic
    job_id = Client._PrepareJobId(REQ_WAIT_FOR_JOB_CHANGE, job_id)
172 5c735209 Iustin Pop
    while True:
173 f4484122 Michael Hanselmann
      result = self.WaitForJobChangeOnce(job_id, fields,
174 f4484122 Michael Hanselmann
                                         prev_job_info, prev_log_serial)
175 5c735209 Iustin Pop
      if result != constants.JOB_NOTCHANGED:
176 5c735209 Iustin Pop
        break
177 5c735209 Iustin Pop
    return result
178 dfe57c22 Michael Hanselmann
179 2e5c33db Iustin Pop
  def Query(self, what, fields, qfilter):
180 28b71a76 Michael Hanselmann
    """Query for resources/items.
181 28b71a76 Michael Hanselmann

182 abd66bf8 Michael Hanselmann
    @param what: One of L{constants.QR_VIA_LUXI}
183 28b71a76 Michael Hanselmann
    @type fields: List of strings
184 28b71a76 Michael Hanselmann
    @param fields: List of requested fields
185 2e5c33db Iustin Pop
    @type qfilter: None or list
186 2e5c33db Iustin Pop
    @param qfilter: Query filter
187 28b71a76 Michael Hanselmann
    @rtype: L{objects.QueryResponse}
188 28b71a76 Michael Hanselmann

189 28b71a76 Michael Hanselmann
    """
190 a629ecb9 Iustin Pop
    result = self.CallMethod(REQ_QUERY, (what, fields, qfilter))
191 28b71a76 Michael Hanselmann
    return objects.QueryResponse.FromDict(result)
192 28b71a76 Michael Hanselmann
193 28b71a76 Michael Hanselmann
  def QueryFields(self, what, fields):
194 28b71a76 Michael Hanselmann
    """Query for available fields.
195 28b71a76 Michael Hanselmann

196 abd66bf8 Michael Hanselmann
    @param what: One of L{constants.QR_VIA_LUXI}
197 28b71a76 Michael Hanselmann
    @type fields: None or list of strings
198 28b71a76 Michael Hanselmann
    @param fields: List of requested fields
199 28b71a76 Michael Hanselmann
    @rtype: L{objects.QueryFieldsResponse}
200 28b71a76 Michael Hanselmann

201 28b71a76 Michael Hanselmann
    """
202 a629ecb9 Iustin Pop
    result = self.CallMethod(REQ_QUERY_FIELDS, (what, fields))
203 28b71a76 Michael Hanselmann
    return objects.QueryFieldsResponse.FromDict(result)
204 28b71a76 Michael Hanselmann
205 0bbe448c Michael Hanselmann
  def QueryJobs(self, job_ids, fields):
206 0bbe448c Michael Hanselmann
    return self.CallMethod(REQ_QUERY_JOBS, (job_ids, fields))
207 3d8548c4 Michael Hanselmann
208 ec79568d Iustin Pop
  def QueryInstances(self, names, fields, use_locking):
209 ec79568d Iustin Pop
    return self.CallMethod(REQ_QUERY_INSTANCES, (names, fields, use_locking))
210 ee6c7b94 Michael Hanselmann
211 ec79568d Iustin Pop
  def QueryNodes(self, names, fields, use_locking):
212 ec79568d Iustin Pop
    return self.CallMethod(REQ_QUERY_NODES, (names, fields, use_locking))
213 02f7fe54 Michael Hanselmann
214 a79ef2a5 Adeodato Simo
  def QueryGroups(self, names, fields, use_locking):
215 a79ef2a5 Adeodato Simo
    return self.CallMethod(REQ_QUERY_GROUPS, (names, fields, use_locking))
216 a79ef2a5 Adeodato Simo
217 306bed0e Apollon Oikonomopoulos
  def QueryNetworks(self, names, fields, use_locking):
218 306bed0e Apollon Oikonomopoulos
    return self.CallMethod(REQ_QUERY_NETWORKS, (names, fields, use_locking))
219 306bed0e Apollon Oikonomopoulos
220 ec79568d Iustin Pop
  def QueryExports(self, nodes, use_locking):
221 ec79568d Iustin Pop
    return self.CallMethod(REQ_QUERY_EXPORTS, (nodes, use_locking))
222 32f93223 Michael Hanselmann
223 66baeccc Iustin Pop
  def QueryClusterInfo(self):
224 66baeccc Iustin Pop
    return self.CallMethod(REQ_QUERY_CLUSTER_INFO, ())
225 66baeccc Iustin Pop
226 ae5849b5 Michael Hanselmann
  def QueryConfigValues(self, fields):
227 a629ecb9 Iustin Pop
    return self.CallMethod(REQ_QUERY_CONFIG_VALUES, (fields, ))
228 ae5849b5 Michael Hanselmann
229 7699c3af Iustin Pop
  def QueryTags(self, kind, name):
230 7699c3af Iustin Pop
    return self.CallMethod(REQ_QUERY_TAGS, (kind, name))