This file is indexed.

/usr/share/doc/ganeti/html/design-node-add.html is in ganeti-doc 2.16.0~rc2-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Design for adding a node to a cluster &#8212; Ganeti 2.16.0~rc2 documentation</title>
    <link rel="stylesheet" href="_static/style.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    './',
        VERSION:     '2.16.0~rc2',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true,
        SOURCELINK_SUFFIX: '.txt'
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Improvements of Node Security" href="design-node-security.html" />
    <link rel="prev" title="Network management" href="design-network.html" /> 
  </head>
  <body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="design-node-security.html" title="Improvements of Node Security"
             accesskey="N">next</a></li>
        <li class="right" >
          <a href="design-network.html" title="Network management"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Ganeti 2.16.0~rc2 documentation</a> &#187;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="design-for-adding-a-node-to-a-cluster">
<h1><a class="toc-backref" href="#id1">Design for adding a node to a cluster</a><a class="headerlink" href="#design-for-adding-a-node-to-a-cluster" title="Permalink to this headline"></a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Created:</th><td class="field-body">2012-Oct-16</td>
</tr>
<tr class="field-even field"><th class="field-name">Status:</th><td class="field-body">Implemented</td>
</tr>
<tr class="field-odd field"><th class="field-name">Ganeti-Version:</th><td class="field-body">2.7.0</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#design-for-adding-a-node-to-a-cluster" id="id1">Design for adding a node to a cluster</a><ul>
<li><a class="reference internal" href="#note" id="id2">Note</a></li>
<li><a class="reference internal" href="#current-state-and-shortcomings" id="id3">Current state and shortcomings</a></li>
<li><a class="reference internal" href="#proposed-changes" id="id4">Proposed changes</a><ul>
<li><a class="reference internal" href="#ssh" id="id5">SSH</a></li>
<li><a class="reference internal" href="#node-daemon" id="id6">Node daemon</a></li>
</ul>
</li>
<li><a class="reference internal" href="#data-structures" id="id7">Data structures</a><ul>
<li><a class="reference internal" href="#json-structure-for-ssh-setup" id="id8">JSON structure for SSH setup</a></li>
<li><a class="reference internal" href="#json-structure-for-node-daemon-setup" id="id9">JSON structure for node daemon setup</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="note">
<h2><a class="toc-backref" href="#id2">Note</a><a class="headerlink" href="#note" title="Permalink to this headline"></a></h2>
<p>Closely related to this design is the more recent design
<a class="reference internal" href="design-node-security.html"><span class="doc">node security</span></a> which extends and changes
some of the aspects mentioned in this document. Make sure that you
read the more recent design as well to get an up to date picture of
Ganeti’s procedure for adding new nodes.</p>
</div>
<div class="section" id="current-state-and-shortcomings">
<h2><a class="toc-backref" href="#id3">Current state and shortcomings</a><a class="headerlink" href="#current-state-and-shortcomings" title="Permalink to this headline"></a></h2>
<p>Before a node can be added to a cluster, its SSH daemon must be
re-configured to use the cluster-wide SSH host key. Ganeti 2.3.0 changed
the way this is done by moving all related code to a separate script,
<code class="docutils literal"><span class="pre">tools/setup-ssh</span></code>, using Paramiko. Before all such configuration was
done from <code class="docutils literal"><span class="pre">lib/bootstrap.py</span></code> using the system’s own SSH client and a
shell script given to said client through parameters.</p>
<p>Both solutions controlled all actions on the connecting machine; the
newly added node was merely executing commands. This implies and
requires a tight coupling and equality between nodes (e.g. paths to
files being the same). Most of the logic and error handling is also done
on the connecting machine.</p>
<p>Once a node’s SSH daemon has been configured, more than 25 files need to
be copied using <code class="docutils literal"><span class="pre">scp</span></code> before the node daemon can be started. No
verification is being done before files are copied. Once the node daemon
is started, an opcode is submitted to the master daemon, which will then
copy more files, such as the configuration and job queue for master
candidates, using RPC. This process is somewhat fragile and requires
initiating many SSH connections.</p>
</div>
<div class="section" id="proposed-changes">
<h2><a class="toc-backref" href="#id4">Proposed changes</a><a class="headerlink" href="#proposed-changes" title="Permalink to this headline"></a></h2>
<div class="section" id="ssh">
<h3><a class="toc-backref" href="#id5">SSH</a><a class="headerlink" href="#ssh" title="Permalink to this headline"></a></h3>
<p>The main goal is to move more logic to the newly added node. Instead of
having a relatively large script executed on the master node, most of it
is moved over to the added node.</p>
<p>A new script named <code class="docutils literal"><span class="pre">prepare-node-join</span></code> is added. It receives a JSON
data structure (defined <a class="reference internal" href="#prepare-node-join-json"><span class="std std-ref">below</span></a>) on its
standard input. Once the data has been successfully decoded, it proceeds
to configure the local node’s SSH daemon and root’s SSH settings, after
which the SSH daemon is restarted.</p>
<p>All the master node has to do to add a new node is to gather all
required data, build the data structure, and invoke the script on the
node to be added. This will enable us to once again use the system’s own
SSH client and to drop the dependency on Paramiko for Ganeti itself
(<code class="docutils literal"><span class="pre">ganeti-listrunner</span></code> is going to continue using Paramiko).</p>
<p>Eventually <code class="docutils literal"><span class="pre">setup-ssh</span></code> can be removed.</p>
</div>
<div class="section" id="node-daemon">
<h3><a class="toc-backref" href="#id6">Node daemon</a><a class="headerlink" href="#node-daemon" title="Permalink to this headline"></a></h3>
<p>Similar to SSH setup changes, the process of copying files and starting
the node daemon will be moved into a dedicated program. On its standard
input it will receive a standardized JSON structure (defined <a class="reference internal" href="#node-daemon-setup-json"><span class="std std-ref">below</span></a>). Once the input data has been successfully
decoded and the received values were verified for sanity, the program
proceeds to write the values to files and then starts the node daemon
(<code class="docutils literal"><span class="pre">ganeti-noded</span></code>).</p>
<p>To add a new node to the cluster, the master node will have to gather
all values, build the data structure, and then invoke the newly added
<code class="docutils literal"><span class="pre">node-daemon-setup</span></code> program via SSH. In this way only a single SSH
connection is needed and the values can be verified before being written
to files.</p>
<p>If the program exits successfully, the node is ready to be added to the
master daemon’s configuration. The node daemon will be running, but
<code class="docutils literal"><span class="pre">OpNodeAdd</span></code> needs to be run before it becomes a full node. The opcode
will copy more files, such as the <a class="reference internal" href="rapi.html"><span class="doc">RAPI certificate</span></a>.</p>
</div>
</div>
<div class="section" id="data-structures">
<h2><a class="toc-backref" href="#id7">Data structures</a><a class="headerlink" href="#data-structures" title="Permalink to this headline"></a></h2>
<div class="section" id="json-structure-for-ssh-setup">
<span id="prepare-node-join-json"></span><h3><a class="toc-backref" href="#id8">JSON structure for SSH setup</a><a class="headerlink" href="#json-structure-for-ssh-setup" title="Permalink to this headline"></a></h3>
<p>The data is given in an object containing the keys described below.
Unless specified otherwise, all entries are optional.</p>
<dl class="docutils">
<dt><code class="docutils literal"><span class="pre">cluster_name</span></code></dt>
<dd>Required string with the cluster name. If a local cluster name is
found, the join process is aborted unless the passed cluster name
matches the local name.</dd>
<dt><code class="docutils literal"><span class="pre">node_daemon_certificate</span></code></dt>
<dd>Public part of cluster’s node daemon certificate in PEM format. If a
local node certificate and key is found, the join process is aborted
unless this passed public part can be verified with the local key.</dd>
<dt><code class="docutils literal"><span class="pre">ssh_host_key</span></code></dt>
<dd>List containing public and private parts of SSH host key. See below
for definition.</dd>
<dt><code class="docutils literal"><span class="pre">ssh_root_key</span></code></dt>
<dd>List containing public and private parts of root’s key for SSH
authorization. See below for definition.</dd>
</dl>
<p>Lists of SSH keys use a tuple with three values. The first describes the
key variant (<code class="docutils literal"><span class="pre">rsa</span></code> or <code class="docutils literal"><span class="pre">dsa</span></code>). The second and third are the private
and public part of the key. Example:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span></span><span class="p">[</span>
  <span class="p">(</span><span class="s2">&quot;rsa&quot;</span><span class="p">,</span> <span class="s2">&quot;-----BEGIN RSA PRIVATE KEY-----...&quot;</span><span class="p">,</span> <span class="s2">&quot;ssh-rss AAAA...&quot;</span><span class="p">),</span>
  <span class="p">(</span><span class="s2">&quot;dsa&quot;</span><span class="p">,</span> <span class="s2">&quot;-----BEGIN DSA PRIVATE KEY-----...&quot;</span><span class="p">,</span> <span class="s2">&quot;ssh-dss AAAA...&quot;</span><span class="p">),</span>
<span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="json-structure-for-node-daemon-setup">
<span id="node-daemon-setup-json"></span><h3><a class="toc-backref" href="#id9">JSON structure for node daemon setup</a><a class="headerlink" href="#json-structure-for-node-daemon-setup" title="Permalink to this headline"></a></h3>
<p>The data is given in an object containing the keys described below.
Unless specified otherwise, all entries are optional.</p>
<dl class="docutils">
<dt><code class="docutils literal"><span class="pre">cluster_name</span></code></dt>
<dd>Required string with the cluster name. If a local cluster name is
found, the join process is aborted unless the passed cluster name
matches the local name. The cluster name is also included in the
dictionary given via the <code class="docutils literal"><span class="pre">ssconf</span></code> entry.</dd>
<dt><code class="docutils literal"><span class="pre">node_daemon_certificate</span></code></dt>
<dd>Public and private part of cluster’s node daemon certificate in PEM
format. If a local node certificate is found, the process is aborted
unless it matches.</dd>
<dt><code class="docutils literal"><span class="pre">ssconf</span></code></dt>
<dd><p class="first">Dictionary with ssconf names and their values. Both are strings.
Example:</p>
<div class="last highlight-javascript"><div class="highlight"><pre><span></span><span class="p">{</span>
  <span class="s2">&quot;cluster_name&quot;</span><span class="o">:</span> <span class="s2">&quot;cluster.example.com&quot;</span><span class="p">,</span>
  <span class="s2">&quot;master_ip&quot;</span><span class="o">:</span> <span class="s2">&quot;192.168.2.1&quot;</span><span class="p">,</span>
  <span class="s2">&quot;master_netdev&quot;</span><span class="o">:</span> <span class="s2">&quot;br0&quot;</span><span class="p">,</span>
  <span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</dd>
<dt><code class="docutils literal"><span class="pre">start_node_daemon</span></code></dt>
<dd>Boolean denoting whether the node daemon should be started (or
restarted if it was running for some reason).</dd>
</dl>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Design for adding a node to a cluster</a><ul>
<li><a class="reference internal" href="#note">Note</a></li>
<li><a class="reference internal" href="#current-state-and-shortcomings">Current state and shortcomings</a></li>
<li><a class="reference internal" href="#proposed-changes">Proposed changes</a><ul>
<li><a class="reference internal" href="#ssh">SSH</a></li>
<li><a class="reference internal" href="#node-daemon">Node daemon</a></li>
</ul>
</li>
<li><a class="reference internal" href="#data-structures">Data structures</a><ul>
<li><a class="reference internal" href="#json-structure-for-ssh-setup">JSON structure for SSH setup</a></li>
<li><a class="reference internal" href="#json-structure-for-node-daemon-setup">JSON structure for node daemon setup</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="design-network.html"
                        title="previous chapter">Network management</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="design-node-security.html"
                        title="next chapter">Improvements of Node Security</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/design-node-add.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <div><input type="text" name="q" /></div>
      <div><input type="submit" value="Go" /></div>
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="design-node-security.html" title="Improvements of Node Security"
             >next</a></li>
        <li class="right" >
          <a href="design-network.html" title="Network management"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Ganeti 2.16.0~rc2 documentation</a> &#187;</li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2018, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Google Inc..
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.7.
    </div>
  </body>
</html>