root / doc / design-query2.rst @ e5a246df
History | View | Annotate | Download (8.3 kB)
1 | e5a246df | Michael Hanselmann | ====================== |
---|---|---|---|
2 | e5a246df | Michael Hanselmann | Query version 2 design |
3 | e5a246df | Michael Hanselmann | ====================== |
4 | e5a246df | Michael Hanselmann | |
5 | e5a246df | Michael Hanselmann | .. contents:: :depth: 4 |
6 | e5a246df | Michael Hanselmann | .. highlight:: python |
7 | e5a246df | Michael Hanselmann | |
8 | e5a246df | Michael Hanselmann | Current state and shortcomings |
9 | e5a246df | Michael Hanselmann | ============================== |
10 | e5a246df | Michael Hanselmann | |
11 | e5a246df | Michael Hanselmann | Queries are used to retrieve information about the cluster, e.g. a list |
12 | e5a246df | Michael Hanselmann | of instances or nodes. For historical reasons they use a simple data |
13 | e5a246df | Michael Hanselmann | structure for their result. The client submits the fields it would like |
14 | e5a246df | Michael Hanselmann | to receive and the query returns a list for each item (instance, node, |
15 | e5a246df | Michael Hanselmann | etc.) available. Each item consists of another list representing the |
16 | e5a246df | Michael Hanselmann | fields' values. |
17 | e5a246df | Michael Hanselmann | |
18 | e5a246df | Michael Hanselmann | This data structure has a few drawbacks. It can't associate a status |
19 | e5a246df | Michael Hanselmann | (e.g. “node offline”) with fields as using special values can lead to |
20 | e5a246df | Michael Hanselmann | ambiguities. Additionally it can't mark fields as “not found” as the |
21 | e5a246df | Michael Hanselmann | list of returned columns must match the fields requested. |
22 | e5a246df | Michael Hanselmann | |
23 | e5a246df | Michael Hanselmann | Example:: |
24 | e5a246df | Michael Hanselmann | |
25 | e5a246df | Michael Hanselmann | >>> cli.GetClient().QueryNodes([], ["name", "pip", "mfree"], False) |
26 | e5a246df | Michael Hanselmann | [ |
27 | e5a246df | Michael Hanselmann | ['node1.example.com', '192.0.2.18', 14800], |
28 | e5a246df | Michael Hanselmann | ['node2.example.com', '192.0.2.19', 31280] |
29 | e5a246df | Michael Hanselmann | ] |
30 | e5a246df | Michael Hanselmann | |
31 | e5a246df | Michael Hanselmann | There is no way for clients to determine the list of possible fields, |
32 | e5a246df | Michael Hanselmann | meaning they have to be hardcoded. Selecting unknown fields raises |
33 | e5a246df | Michael Hanselmann | an exception:: |
34 | e5a246df | Michael Hanselmann | |
35 | e5a246df | Michael Hanselmann | >>> cli.GetClient().QueryNodes([], ["name", "UnknownField"], False) |
36 | e5a246df | Michael Hanselmann | ganeti.errors.OpPrereqError: (u'Unknown output fields selected: UnknownField', u'wrong_input') |
37 | e5a246df | Michael Hanselmann | |
38 | e5a246df | Michael Hanselmann | The client must also know each fields' kind, that is whether a field is |
39 | e5a246df | Michael Hanselmann | numeric, boolean, describes a storage size, etc. Centralizing this |
40 | e5a246df | Michael Hanselmann | information in one place, the master daemon, is desirable. |
41 | e5a246df | Michael Hanselmann | |
42 | e5a246df | Michael Hanselmann | |
43 | e5a246df | Michael Hanselmann | Proposed changes |
44 | e5a246df | Michael Hanselmann | ---------------- |
45 | e5a246df | Michael Hanselmann | |
46 | e5a246df | Michael Hanselmann | The current query result format can not be changed as it's being used in |
47 | e5a246df | Michael Hanselmann | various places. Changing the format from one Ganeti version to another |
48 | e5a246df | Michael Hanselmann | would cause too much disruption. For this reason the ability to |
49 | e5a246df | Michael Hanselmann | explicitly request a new result format must be added while the old |
50 | e5a246df | Michael Hanselmann | format stays the default. |
51 | e5a246df | Michael Hanselmann | |
52 | e5a246df | Michael Hanselmann | The implementation of query filters is planned for the future. To avoid |
53 | e5a246df | Michael Hanselmann | having to change the calls again, a (hopefully) future-compatible |
54 | e5a246df | Michael Hanselmann | interface will be implemented now. |
55 | e5a246df | Michael Hanselmann | |
56 | e5a246df | Michael Hanselmann | In Python code, the objects described below will be implemented using |
57 | e5a246df | Michael Hanselmann | subclasses of ``objects.ConfigObject``, providing existing facilities |
58 | e5a246df | Michael Hanselmann | for de-/serializing. |
59 | e5a246df | Michael Hanselmann | |
60 | e5a246df | Michael Hanselmann | .. _query-request: |
61 | e5a246df | Michael Hanselmann | |
62 | e5a246df | Michael Hanselmann | Query request |
63 | e5a246df | Michael Hanselmann | +++++++++++++ |
64 | e5a246df | Michael Hanselmann | |
65 | e5a246df | Michael Hanselmann | Each query operation will take a single parameter, a query request |
66 | e5a246df | Michael Hanselmann | dictionary with the following properties: |
67 | e5a246df | Michael Hanselmann | |
68 | e5a246df | Michael Hanselmann | ``kind`` |
69 | e5a246df | Michael Hanselmann | Denotes request kind. One of the following strings: |
70 | e5a246df | Michael Hanselmann | |
71 | e5a246df | Michael Hanselmann | ``query`` |
72 | e5a246df | Michael Hanselmann | Execute a query on items, optionally filtered (see below). For a |
73 | e5a246df | Michael Hanselmann | description of the result see :ref:`query-result`. |
74 | e5a246df | Michael Hanselmann | ``fields`` |
75 | e5a246df | Michael Hanselmann | Return list of supported fields as :ref:`field definitions |
76 | e5a246df | Michael Hanselmann | <field-def>`. For a complete description of the result see |
77 | e5a246df | Michael Hanselmann | :ref:`fields-result`. |
78 | e5a246df | Michael Hanselmann | |
79 | e5a246df | Michael Hanselmann | ``filter`` |
80 | e5a246df | Michael Hanselmann | This will be used to filter queries. In this implementation only names |
81 | e5a246df | Michael Hanselmann | can be filtered to replace the previous ``names`` parameter to |
82 | e5a246df | Michael Hanselmann | queries. An empty filter (``None``) will return all items. To retrieve |
83 | e5a246df | Michael Hanselmann | specific names, the filter must be specified as follows, with the |
84 | e5a246df | Michael Hanselmann | inner part repeated for each name:: |
85 | e5a246df | Michael Hanselmann | |
86 | e5a246df | Michael Hanselmann | ["|", ["=", "name", "node1"], ["=", "name", "node2"], …] |
87 | e5a246df | Michael Hanselmann | |
88 | e5a246df | Michael Hanselmann | Filters consist of S-expressions (``["operator", <operants…>]``) and |
89 | e5a246df | Michael Hanselmann | extensions will be made in the future to allow for more operators and |
90 | e5a246df | Michael Hanselmann | fields. Such extensions might include a Python-style "in" operator, |
91 | e5a246df | Michael Hanselmann | but for simplicity only "=" is supported in this implementation. |
92 | e5a246df | Michael Hanselmann | |
93 | e5a246df | Michael Hanselmann | To reiterate: Filters for this implementation must consist of exactly |
94 | e5a246df | Michael Hanselmann | one OR expression (``["|", …]``) and one or more name equality filters |
95 | e5a246df | Michael Hanselmann | (``["=", "name", "…"]``). |
96 | e5a246df | Michael Hanselmann | |
97 | e5a246df | Michael Hanselmann | Support for synchronous queries, currently available in the interface |
98 | e5a246df | Michael Hanselmann | but disabled in the master daemon, will be dropped. Direct calls to |
99 | e5a246df | Michael Hanselmann | opcodes have to be used instead. |
100 | e5a246df | Michael Hanselmann | |
101 | e5a246df | Michael Hanselmann | .. _query-result: |
102 | e5a246df | Michael Hanselmann | |
103 | e5a246df | Michael Hanselmann | New query result format |
104 | e5a246df | Michael Hanselmann | +++++++++++++++++++++++ |
105 | e5a246df | Michael Hanselmann | |
106 | e5a246df | Michael Hanselmann | The result is a dictionary with the following entries: |
107 | e5a246df | Michael Hanselmann | |
108 | e5a246df | Michael Hanselmann | ``fields`` |
109 | e5a246df | Michael Hanselmann | In-order list of a :ref:`field definition <field-def>` for each |
110 | e5a246df | Michael Hanselmann | requested field, unknown fields are returned with the kind |
111 | e5a246df | Michael Hanselmann | ``unknown``. Length must be equal to number of requested fields. |
112 | e5a246df | Michael Hanselmann | ``data`` |
113 | e5a246df | Michael Hanselmann | A list of lists, one list for each item found. Each item's list must |
114 | e5a246df | Michael Hanselmann | have one entry for each field listed in ``fields``. Each field entry |
115 | e5a246df | Michael Hanselmann | is a tuple of ``(status, value)``. ``status`` must be one of the |
116 | e5a246df | Michael Hanselmann | following values: |
117 | e5a246df | Michael Hanselmann | |
118 | e5a246df | Michael Hanselmann | Normal (numeric 0) |
119 | e5a246df | Michael Hanselmann | Value is available and matches the kind in the :ref:`field |
120 | e5a246df | Michael Hanselmann | definition <field-def>`. |
121 | e5a246df | Michael Hanselmann | Value unavailable (numeric 1) |
122 | e5a246df | Michael Hanselmann | Exact meaning depends on query, e.g. node is unreachable or marked |
123 | e5a246df | Michael Hanselmann | offline. Value must be ``None``. |
124 | e5a246df | Michael Hanselmann | Unknown field (numeric 2) |
125 | e5a246df | Michael Hanselmann | Field for this column is not known. Value must be ``None``. |
126 | e5a246df | Michael Hanselmann | |
127 | e5a246df | Michael Hanselmann | Example:: |
128 | e5a246df | Michael Hanselmann | |
129 | e5a246df | Michael Hanselmann | { |
130 | e5a246df | Michael Hanselmann | "fields": [ |
131 | e5a246df | Michael Hanselmann | { "name": "name", "title": "Name", "kind": "text", }, |
132 | e5a246df | Michael Hanselmann | { "name": "mfree", "title": "MemFree", "kind": "unit", }, |
133 | e5a246df | Michael Hanselmann | # Unknown field |
134 | e5a246df | Michael Hanselmann | { "name": "xyz", "title": None, "kind": "unknown", }, |
135 | e5a246df | Michael Hanselmann | { "name": "mtotal", "title": "MemTotal", "kind": "unit", }, |
136 | e5a246df | Michael Hanselmann | ], |
137 | e5a246df | Michael Hanselmann | |
138 | e5a246df | Michael Hanselmann | "data": [ |
139 | e5a246df | Michael Hanselmann | [(0, "node1"), (0, 128), (2, None), (0, 4096)], |
140 | e5a246df | Michael Hanselmann | # Node not available |
141 | e5a246df | Michael Hanselmann | [(0, "node2"), (1, None), (2, None), (1, None)], |
142 | e5a246df | Michael Hanselmann | ], |
143 | e5a246df | Michael Hanselmann | } |
144 | e5a246df | Michael Hanselmann | |
145 | e5a246df | Michael Hanselmann | .. _fields-result: |
146 | e5a246df | Michael Hanselmann | |
147 | e5a246df | Michael Hanselmann | Field query result format |
148 | e5a246df | Michael Hanselmann | +++++++++++++++++++++++++ |
149 | e5a246df | Michael Hanselmann | |
150 | e5a246df | Michael Hanselmann | The result is a dictionary with the following entries: |
151 | e5a246df | Michael Hanselmann | |
152 | e5a246df | Michael Hanselmann | ``fields`` |
153 | e5a246df | Michael Hanselmann | List of :ref:`field definitions <field-def>` for each available field. |
154 | e5a246df | Michael Hanselmann | |
155 | e5a246df | Michael Hanselmann | Example:: |
156 | e5a246df | Michael Hanselmann | |
157 | e5a246df | Michael Hanselmann | { |
158 | e5a246df | Michael Hanselmann | "fields": [ |
159 | e5a246df | Michael Hanselmann | { "name": "name", "title": "Name", "kind": "text", }, |
160 | e5a246df | Michael Hanselmann | { "name": "mfree", "title": "MemFree", "kind": "unit", }, |
161 | e5a246df | Michael Hanselmann | { "name": "mtotal", "title": "MemTotal", "kind": "unit", }, |
162 | e5a246df | Michael Hanselmann | ] |
163 | e5a246df | Michael Hanselmann | } |
164 | e5a246df | Michael Hanselmann | |
165 | e5a246df | Michael Hanselmann | .. _field-def: |
166 | e5a246df | Michael Hanselmann | |
167 | e5a246df | Michael Hanselmann | Field definition |
168 | e5a246df | Michael Hanselmann | ++++++++++++++++ |
169 | e5a246df | Michael Hanselmann | |
170 | e5a246df | Michael Hanselmann | A field definition is a dictionary with the following entries: |
171 | e5a246df | Michael Hanselmann | |
172 | e5a246df | Michael Hanselmann | ``name`` |
173 | e5a246df | Michael Hanselmann | The field name as a regular expression. The latter is necessary to |
174 | e5a246df | Michael Hanselmann | represent dynamic fields (e.g. NIC 3 of an instance). |
175 | e5a246df | Michael Hanselmann | ``title`` |
176 | e5a246df | Michael Hanselmann | Human-readable title to use in output. Must not contain whitespace. |
177 | e5a246df | Michael Hanselmann | ``kind`` |
178 | e5a246df | Michael Hanselmann | Field type, one of the following: |
179 | e5a246df | Michael Hanselmann | |
180 | e5a246df | Michael Hanselmann | .. TODO: Investigate whether there are fields with floating point |
181 | e5a246df | Michael Hanselmann | .. numbers |
182 | e5a246df | Michael Hanselmann | |
183 | e5a246df | Michael Hanselmann | ``unknown`` |
184 | e5a246df | Michael Hanselmann | Unknown field (only used for :ref:`data queries <query-request>`) |
185 | e5a246df | Michael Hanselmann | ``text`` |
186 | e5a246df | Michael Hanselmann | String |
187 | e5a246df | Michael Hanselmann | ``bool`` |
188 | e5a246df | Michael Hanselmann | Boolean, true/false |
189 | e5a246df | Michael Hanselmann | ``number`` |
190 | e5a246df | Michael Hanselmann | Numeric |
191 | e5a246df | Michael Hanselmann | ``unit`` |
192 | e5a246df | Michael Hanselmann | Numeric, in megabytes |
193 | e5a246df | Michael Hanselmann | ``other`` |
194 | e5a246df | Michael Hanselmann | Free-form type, depending on query |
195 | e5a246df | Michael Hanselmann | |
196 | e5a246df | Michael Hanselmann | More types can be added in the future, so clients should default to |
197 | e5a246df | Michael Hanselmann | formatting any unknown types the same way as "other", which should be |
198 | e5a246df | Michael Hanselmann | a string representation in most cases. |
199 | e5a246df | Michael Hanselmann | |
200 | e5a246df | Michael Hanselmann | Example 1 (item name):: |
201 | e5a246df | Michael Hanselmann | |
202 | e5a246df | Michael Hanselmann | { |
203 | e5a246df | Michael Hanselmann | "name": "name", |
204 | e5a246df | Michael Hanselmann | "title": "Name", |
205 | e5a246df | Michael Hanselmann | "kind": "text", |
206 | e5a246df | Michael Hanselmann | } |
207 | e5a246df | Michael Hanselmann | |
208 | e5a246df | Michael Hanselmann | Example 2 (free memory):: |
209 | e5a246df | Michael Hanselmann | |
210 | e5a246df | Michael Hanselmann | { |
211 | e5a246df | Michael Hanselmann | "name": "mfree", |
212 | e5a246df | Michael Hanselmann | "title": "MemFree", |
213 | e5a246df | Michael Hanselmann | "kind": "unit", |
214 | e5a246df | Michael Hanselmann | } |
215 | e5a246df | Michael Hanselmann | |
216 | e5a246df | Michael Hanselmann | Example 3 (list of primary instances):: |
217 | e5a246df | Michael Hanselmann | |
218 | e5a246df | Michael Hanselmann | { |
219 | e5a246df | Michael Hanselmann | "name": "pinst", |
220 | e5a246df | Michael Hanselmann | "title": "PrimaryInstances", |
221 | e5a246df | Michael Hanselmann | "kind": "other", |
222 | e5a246df | Michael Hanselmann | } |
223 | e5a246df | Michael Hanselmann | |
224 | e5a246df | Michael Hanselmann | .. _old-result-format: |
225 | e5a246df | Michael Hanselmann | |
226 | e5a246df | Michael Hanselmann | Old result format |
227 | e5a246df | Michael Hanselmann | +++++++++++++++++ |
228 | e5a246df | Michael Hanselmann | |
229 | e5a246df | Michael Hanselmann | To limit the amount of code necessary, the :ref:`new result format |
230 | e5a246df | Michael Hanselmann | <query-result>` will be converted for older clients. Unavailable values |
231 | e5a246df | Michael Hanselmann | are set to ``None``. If unknown fields were requested, the whole query |
232 | e5a246df | Michael Hanselmann | fails as the client expects exactly the fields it requested. |
233 | e5a246df | Michael Hanselmann | |
234 | e5a246df | Michael Hanselmann | LUXI |
235 | e5a246df | Michael Hanselmann | ++++ |
236 | e5a246df | Michael Hanselmann | |
237 | e5a246df | Michael Hanselmann | Currently query calls take a number of parameters, e.g. names, fields |
238 | e5a246df | Michael Hanselmann | and whether to use locking. These will continue to work and return the |
239 | e5a246df | Michael Hanselmann | :ref:`old result format <old-result-format>`. To use the new query |
240 | e5a246df | Michael Hanselmann | requests, the same calls must be invoked with a single parameter as the |
241 | e5a246df | Michael Hanselmann | :ref:`query object <query-request>`. Only clients using the new call |
242 | e5a246df | Michael Hanselmann | syntax will be able to make use of new features such as filters. |
243 | e5a246df | Michael Hanselmann | |
244 | e5a246df | Michael Hanselmann | Python |
245 | e5a246df | Michael Hanselmann | ++++++ |
246 | e5a246df | Michael Hanselmann | |
247 | e5a246df | Michael Hanselmann | The LUXI API is more or less mapped directly into Python. In addition to |
248 | e5a246df | Michael Hanselmann | the existing stub functions new ones will be added for the new query |
249 | e5a246df | Michael Hanselmann | requests. |
250 | e5a246df | Michael Hanselmann | |
251 | e5a246df | Michael Hanselmann | RAPI |
252 | e5a246df | Michael Hanselmann | ++++ |
253 | e5a246df | Michael Hanselmann | |
254 | e5a246df | Michael Hanselmann | The RAPI interface already returns dictionaries for each item, but to |
255 | e5a246df | Michael Hanselmann | not break compatibility no changes should be made to the structure (e.g. |
256 | e5a246df | Michael Hanselmann | to include field definitions). The proposal here is to add a new |
257 | e5a246df | Michael Hanselmann | parameter to allow clients to execute the requests described in this |
258 | e5a246df | Michael Hanselmann | proposal directly and to receive the unmodified result. The new formats |
259 | e5a246df | Michael Hanselmann | are a lot more verbose, flexible and extensible. |
260 | e5a246df | Michael Hanselmann | |
261 | e5a246df | Michael Hanselmann | |
262 | e5a246df | Michael Hanselmann | Other discussed solutions |
263 | e5a246df | Michael Hanselmann | ------------------------- |
264 | e5a246df | Michael Hanselmann | |
265 | e5a246df | Michael Hanselmann | Another solution discussed was to add an additional column for each |
266 | e5a246df | Michael Hanselmann | non-static field containing the status. Clients interested in the status |
267 | e5a246df | Michael Hanselmann | could explicitely query for it. |
268 | e5a246df | Michael Hanselmann | |
269 | e5a246df | Michael Hanselmann | .. vim: set textwidth=72 : |
270 | e5a246df | Michael Hanselmann | .. Local Variables: |
271 | e5a246df | Michael Hanselmann | .. mode: rst |
272 | e5a246df | Michael Hanselmann | .. fill-column: 72 |
273 | e5a246df | Michael Hanselmann | .. End: |