Fix verify config if a node has no instances
[ganeti-local] / doc / design-reason-trail.rst
1 ===================
2 Ganeti reason trail
3 ===================
4
5 .. contents:: :depth: 2
6
7 This is a design document detailing the implementation of a way for Ganeti to
8 track the origin and the reason of every executed command, from its starting
9 point (command line, remote API, some htool, etc.) to its actual execution
10 time.
11
12 Current state and shortcomings
13 ==============================
14
15 There is currently no way to track why a job and all the operations part of it
16 were executed, and who or what triggered the execution.
17 This is an inconvenience in general, and also it makes impossible to have
18 certain information, such as finding the reason why an instance last changed its
19 status (i.e.: why it was started/stopped/rebooted/etc.), or distinguishing
20 an admin request from a scheduled maintenance or an automated tool's work.
21
22 Proposed changes
23 ================
24
25 We propose to introduce a new piece of information, that will be called "reason
26 trail", to track the path from the issuing of a command to its execution.
27
28 The reason trail will be a list of 3-tuples ``(source, reason, timestamp)``,
29 with:
30
31 ``source``
32   The entity deciding to perform (or forward) a command.
33   It is represented by an arbitrary string, but strings prepended by "gnt:"
34   are reserved for Ganeti components, and they will be refused by the
35   interfaces towards the external world.
36
37 ``reason``
38   The reason why the entity decided to perform the operation.
39   It is represented by an arbitrary string. The string might possibly be empty,
40   because certain components of the system might just "pass on" the operation
41   (therefore wanting to be recorded in the trail) but without an explicit
42   reason.
43
44 ``timestamp``
45   The time when the element was added to the reason trail. It has to be
46   expressed in nanoseconds since the unix epoch (0:00:00 January 01, 1970).
47   If not enough precision is available (or needed) it can be padded with
48   zeroes.
49
50 The reason trail will be attached at the OpCode level. When it has to be
51 serialized externally (such as on the RAPI interface), it will be serialized in
52 JSON format. Specifically, it will be serialized as a list of elements.
53 Each element will be a list with two strings (for ``source`` and ``reason``)
54 and one integer number (the ``timestamp``).
55
56 Any component the operation goes through is allowed (but not required) to append
57 it's own reason to the list. Other than this, the list shouldn't be modified.
58
59 As an example here is the reason trail for a shutdown operation invoked from
60 the command line through the gnt-instance tool::
61
62   [("user", "Cleanup of unused instances", 1363088484000000000),
63    ("gnt:client:gnt-instance", "stop", 1363088484020000000),
64    ("gnt:opcode:shutdown", "job=1234;index=0", 1363088484026000000),
65    ("gnt:daemon:noded:shutdown", "", 1363088484135000000)]
66
67 where the first 3-tuple is determined by a user-specified message, passed to
68 gnt-instance through a command line parameter.
69
70 The same operation, launched by an external GUI tool, and executed through the
71 remote API, would have a reason trail like::
72
73   [("user", "Cleanup of unused instances", 1363088484000000000),
74    ("other-app:tool-name", "gui:stop", 1363088484000300000),
75    ("gnt:client:rapi:shutdown", "", 1363088484020000000),
76    ("gnt:library:rlib2:shutdown", "", 1363088484023000000),
77    ("gnt:opcode:shutdown", "job=1234;index=0", 1363088484026000000),
78    ("gnt:daemon:noded:shutdown", "", 1363088484135000000)]
79
80 Implementation
81 ==============
82
83 The OpCode base class will be modified to include a new parameter, "reason".
84 This will receive the reason trail as built by all the previous steps.
85
86 When an OpCode is added to a job (in jqueue.py) the job number and the opcode
87 index will be recorded as the reason for the existence of that opcode.
88
89 From the command line tools down to the opcodes, the implementation of this
90 design will be shared by all the components of the system. After the opcodes
91 have been enqueued in a job queue and are dispatched for execution, the
92 implementation will have to be OpCode specific because of the current
93 structure of the ganeti backend.
94
95 The implementation of opcode-specific parts will start from the operations that
96 affect the instance status (as required by the design document about the
97 monitoring daemon, for the instance status data collector). Such opcodes will
98 be changed so that the "reason" is passed to them and they will then export
99 the reason trail on a file.
100
101 The implementation for other opcodes will follow when required.
102
103 .. vim: set textwidth=72 :
104 .. Local Variables:
105 .. mode: rst
106 .. fill-column: 72
107 .. End: